def list_tiles_for_bounds(image, s2p, paper_width_pt, paper_height_pt, north, west, south, east): """ Return a list of coordinates and scan-to-coord functions for a full set of zoom levels. Internal work is done by list_tiles_for_bounds_zoom(). """ osm = OpenStreetMapProvider() coords = [] for zoom in range(19): # # Coordinates of three print corners # ul = osm.locationCoordinate(Location(north, west)).zoomTo(zoom) ur = osm.locationCoordinate(Location(north, east)).zoomTo(zoom) lr = osm.locationCoordinate(Location(south, east)).zoomTo(zoom) # # Matching points in print and coordinate spaces # ul_pt = Point(1 * ptpin - paper_width_pt, 1.5 * ptpin - paper_height_pt) ul_co = Point(ul.column, ul.row) ur_pt = Point(0, 1.5 * ptpin - paper_height_pt) ur_co = Point(ur.column, ur.row) lr_pt = Point(0, 0) lr_co = Point(lr.column, lr.row) scan_dim = hypot(image.size[0], image.size[1]) zoom_dim = hypot((lr_co.x - ul_co.x) * 256, (lr_co.y - ul_co.y) * 256) if zoom_dim / scan_dim < .05: # too zoomed-out continue if zoom_dim / scan_dim > 3.: # too zoomed-in break # # scan2coord by way of scan2print and print2coord # p2c = triangle2triangle(ul_pt, ul_co, ur_pt, ur_co, lr_pt, lr_co) s2c = s2p.multiply(p2c) coords += list_tiles_for_bounds_zoom(image, s2c, zoom) return coords
def list_tiles_for_bounds(image, s2p, paper_width_pt, paper_height_pt, north, west, south, east): """ Return a list of coordinates and scan-to-coord functions for a full set of zoom levels. Internal work is done by list_tiles_for_bounds_zoom(). """ osm = OpenStreetMapProvider() coords = [] for zoom in range(19): # # Coordinates of three print corners # ul = osm.locationCoordinate(Location(north, west)).zoomTo(zoom) ur = osm.locationCoordinate(Location(north, east)).zoomTo(zoom) lr = osm.locationCoordinate(Location(south, east)).zoomTo(zoom) # # Matching points in print and coordinate spaces # ul_pt = Point(1 * ptpin - paper_width_pt, 1.5 * ptpin - paper_height_pt) ul_co = Point(ul.column, ul.row) ur_pt = Point(0, 1.5 * ptpin - paper_height_pt) ur_co = Point(ur.column, ur.row) lr_pt = Point(0, 0) lr_co = Point(lr.column, lr.row) scan_dim = hypot(image.size[0], image.size[1]) zoom_dim = hypot((lr_co.x - ul_co.x) * 256, (lr_co.y - ul_co.y) * 256) if zoom_dim/scan_dim < .05: # too zoomed-out continue if zoom_dim/scan_dim > 3.: # too zoomed-in break # # scan2coord by way of scan2print and print2coord # p2c = triangle2triangle(ul_pt, ul_co, ur_pt, ur_co, lr_pt, lr_co) s2c = s2p.multiply(p2c) coords += list_tiles_for_bounds_zoom(image, s2c, zoom) return coords
def retrieve_zoom_features(loc, zoom): ''' Retrieve all features enclosing a given point location at a zoom level. Requests TopoJSON tile from forever.codeforamerica.org spatial index, decodes bounding boxes and geometries if necessary, then yields a stream of any feature feature whose geometry covers the requested point. ''' osm = Provider() point = Point(loc.lon, loc.lat) coord = osm.locationCoordinate(loc).zoomTo(zoom) path = '%(zoom)d/%(column)d/%(row)d' % coord.__dict__ url = 'http://forever.codeforamerica.org/Census-API/by-tile/%s.topojson.gz' % path resp = get(url) topo = resp.json() print >> stderr, 'request took', resp.elapsed, 'from', url, 'in', hex( get_ident()) start = time() assert topo['type'] == 'Topology' bbox_fails, shape_fails = 0, 0 for layer in topo['objects']: if zoom == 8: assert layer in ('state', 'county', 'place', 'cbsa') elif zoom == 10: assert layer in ('zcta510', 'tract') else: raise Exception('Unknown layer %d' % zoom) for object in topo['objects'][layer]['geometries']: x_, y_, _x, _y = object['bbox'] obj_box = Polygon([(x_, y_), (x_, _y), (_x, _y), (_x, y_), (x_, y_)]) if not point.within(obj_box): # object failed a simple bounding box check and can be discarded. bbox_fails += 1 continue obj_shp = decode(object, topo) if not point.within(obj_shp): # object failed a point-in-polygon check and can be discarded. shape_fails += 1 continue p = object['properties'] yield p.get('NAME', None), p.get('NAMELSAD', None), p.get( 'GEOID', None), p.get('GEOID10', None) print >> stderr, 'check took', (time() - start), 'seconds', 'in', hex( get_ident( )), 'with', bbox_fails, 'bbox fails and', shape_fails, 'shape fails'
def tilelist(data,zooms): if (data["filetype"]): coordinates = MBTiles.list_tiles(data["filename"]) else: lat1, lon1, lat2, lon2 = data["bbox"] south, west = min(lat1, lat2), min(lon1, lon2) north, east = max(lat1, lat2), max(lon1, lon2) northwest = Location(north, west) southeast = Location(south, east) osm = Provider() ul = osm.locationCoordinate(northwest) lr = osm.locationCoordinate(southeast) for (i, zoom) in enumerate(zooms): if not zoom.isdigit(): raise KnownUnknown('"%s" is not a valid numeric zoom level.' % zoom) zooms[i] = int(zoom) if data["padding"] < 0: raise KnownUnknown('A negative padding will not work.') coordinates = generateCoordinates(ul, lr, zooms, data["padding"]) return coordinates
def retrieve_zoom_features(loc, zoom, include_geom, layer_names): ''' Retrieve all features enclosing a given point location at a zoom level. Requests TopoJSON tile from forever.codeforamerica.org spatial index, decodes bounding boxes and geometries if necessary, then yields a stream of any feature feature whose geometry covers the requested point. ''' osm = Provider() point = Point(loc.lon, loc.lat) coord = osm.locationCoordinate(loc).zoomTo(zoom) path = '%(zoom)d/%(column)d/%(row)d' % coord.__dict__ url = census_url + 'by-tile/%s.topojson.gz' % path resp = get(url) topo = resp.json() debug('request took %.3fs from %s in %s' % (resp.elapsed.total_seconds(), url, hex(get_ident()))) start = time() assert topo['type'] == 'Topology' bbox_fails, shape_fails = 0, 0 for layer in topo['objects']: if layer_names is not None and layer not in layer_names: continue if zoom in zoom_layers: assert layer in zoom_layers[zoom] else: raise Exception('Unknown layer %d' % zoom) for object in topo['objects'][layer]['geometries']: x_, y_, _x, _y = object['bbox'] obj_box = Polygon([(x_, y_), (x_, _y), (_x, _y), (_x, y_), (x_, y_)]) if not point.within(obj_box): # object failed a simple bounding box check and can be discarded. bbox_fails += 1 continue obj_shp = decode(object, topo) if not point.within(obj_shp): # object failed a point-in-polygon check and can be discarded. shape_fails += 1 continue feature = {'type': 'Feature', 'properties': object['properties']} if include_geom: feature['geometry'] = obj_shp.__geo_interface__ yield feature debug('check took %.3fs in %s with %d bbox fails and %d shape fails' % (time() - start, hex(get_ident()), bbox_fails, shape_fails))
def iterate_squares(ds, zoom): ''' ''' xoff, xstride, _, yoff, _, ystride = ds.GetGeoTransform() minlon, maxlat = xoff, yoff maxlon = xoff + ds.RasterXSize * xstride minlat = yoff + ds.RasterYSize * ystride if zoom > 11: maxlat = min(58, maxlat) osm = Provider() ul = osm.locationCoordinate(Location(maxlat, minlon)).zoomTo(zoom) lr = osm.locationCoordinate(Location(minlat, maxlon)).zoomTo(zoom) #lr = osm.locationCoordinate(Location(20, -60)).zoomTo(zoom) row = int(ul.row) while row < lr.row: lat = osm.coordinateLocation(Coordinate(row, 0, zoom)).lat print >> sys.stderr, 'lat:', round(lat, 2) col = int(ul.column) while col < lr.column: coord = Coordinate(row, col, zoom) sw = osm.coordinateLocation(coord.down()) ne = osm.coordinateLocation(coord.right()) west = max(minlon, sw.lon) north = min(maxlat, ne.lat) east = min(maxlon, ne.lon) south = max(minlat, sw.lat) left = round((west - xoff) / xstride) top = round((north - yoff) / ystride) width = round((east - xoff) / xstride) - left height = round((south - yoff) / ystride) - top yield (coord, south, north, int(left), int(top), int(width), int(height)) col += 1 row += 1 return x = xmin while x < xmax: print >> sys.stderr, 'lon:', x y = ymin while y < ymax: left = round((x - xoff) / xstride) top = round((y + size - yoff) / ystride) width, height = round(size / xstride), round(size / -ystride) yield (round(x, 2), round(y, 2), int(left), int(top), int(width), int(height)) y += size x += size
def retrieve_zoom_features(loc, zoom): ''' Retrieve all features enclosing a given point location at a zoom level. Requests TopoJSON tile from forever.codeforamerica.org spatial index, decodes bounding boxes and geometries if necessary, then yields a stream of any feature feature whose geometry covers the requested point. ''' osm = Provider() point = Point(loc.lon, loc.lat) coord = osm.locationCoordinate(loc).zoomTo(zoom) path = '%(zoom)d/%(column)d/%(row)d' % coord.__dict__ url = 'http://forever.codeforamerica.org/Census-API/by-tile/%s.topojson.gz' % path resp = get(url) topo = resp.json() print >> stderr, 'request took', resp.elapsed, 'from', url, 'in', hex(get_ident()) start = time() assert topo['type'] == 'Topology' bbox_fails, shape_fails = 0, 0 for layer in topo['objects']: if zoom == 8: assert layer in ('state', 'county', 'place', 'cbsa') elif zoom == 10: assert layer in ('zcta510', 'tract') else: raise Exception('Unknown layer %d' % zoom) for object in topo['objects'][layer]['geometries']: x_, y_, _x, _y = object['bbox'] obj_box = Polygon([(x_, y_), (x_, _y), (_x, _y), (_x, y_), (x_, y_)]) if not point.within(obj_box): # object failed a simple bounding box check and can be discarded. bbox_fails += 1 continue obj_shp = decode(object, topo) if not point.within(obj_shp): # object failed a point-in-polygon check and can be discarded. shape_fails += 1 continue p = object['properties'] yield p.get('NAME', None), p.get('NAMELSAD', None), p.get('GEOID', None), p.get('GEOID10', None) print >> stderr, 'check took', (time() - start), 'seconds', 'in', hex(get_ident()), 'with', bbox_fails, 'bbox fails and', shape_fails, 'shape fails'
def invalidate_feature_cache(layer_key, features): """ invaldiates the cached tiles that contain the features @:param features: array of feature objects :return: """ logger.info("Invalidating features: {0}".format(features)) # get bbox of features dj_config = Config.objects.get() config = dj_config.tilestache_config_object logger.info("Config Cache: {0}".format(config.cache)) from TileStache.Caches import S3, Test if isinstance(config.cache, Test): return osm = Provider() try: ts_layer = config.layers[layer_key] except IndexError: logger.exception('Cannot invalidate %r', layer_key) return cleared = 0 keys = [] for f in features: lon1, lat1, lon2, lat2 = f.wkb_geometry.extent south, west = min(lat1, lat2), min(lon1, lon2) north, east = max(lat1, lat2), max(lon1, lon2) northwest = Location(north, west) southeast = Location(south, east) ul = osm.locationCoordinate(northwest) lr = osm.locationCoordinate(southeast) for coord in generate_coordinates(ul, lr, range(4, 19), padding=0): if isinstance(config.cache, S3.Cache): keys.append( S3.tile_key(ts_layer, coord, 'png', config.cache.path)) else: logger.info("ts_layer: {0}, coord: {1}".format( ts_layer, coord)) config.cache.remove(ts_layer, coord, 'png') cleared += 1 if keys: config.cache.bucket.delete_keys(keys) logger.info("cleared {0} TILES".format(cleared))
def invalidate_feature_cache(layer_key, features): """ invaldiates the cached tiles that contain the features @:param features: array of feature objects :return: """ logger.info("Invalidating features: {0}".format(features)) # get bbox of features dj_config = Config.objects.get() config = dj_config.tilestache_config_object logger.info("Config Cache: {0}".format(config.cache)) from TileStache.Caches import S3, Test if isinstance(config.cache, Test): return osm = Provider() try: ts_layer = config.layers[layer_key] except IndexError: logger.exception('Cannot invalidate %r', layer_key) return cleared = 0 keys = [] for f in features: lon1, lat1, lon2, lat2 = f.wkb_geometry.extent south, west = min(lat1, lat2), min(lon1, lon2) north, east = max(lat1, lat2), max(lon1, lon2) northwest = Location(north, west) southeast = Location(south, east) ul = osm.locationCoordinate(northwest) lr = osm.locationCoordinate(southeast) for coord in generate_coordinates(ul, lr, range(4, 19), padding=0): if isinstance(config.cache, S3.Cache): keys.append(S3.tile_key(ts_layer, coord, 'png', config.cache.path)) else: logger.info("ts_layer: {0}, coord: {1}".format(ts_layer, coord)) config.cache.remove(ts_layer, coord, 'png') cleared += 1 if keys: config.cache.bucket.delete_keys(keys) logger.info("cleared {0} TILES".format(cleared))
def location_point(lat, lon, zoom): """ Return a point that maps to pixels at the requested zoom level for 2^8 tile size. """ try: osm = Provider() location = Location(float(lat), float(lon)) coord = osm.locationCoordinate(location).zoomTo(zoom + 8) point = Point(coord.column, coord.row) return location, point except ValueError: raise Exception((lat, lon, zoom))
def starting_tiles(buildings): ''' Get tile coordinates at min_zoom for a list of buildings. ''' minlat = min([b['latitude'] for b in buildings]) minlon = min([b['longitude'] for b in buildings]) maxlat = max([b['latitude'] for b in buildings]) maxlon = max([b['longitude'] for b in buildings]) osm = Provider() ul = osm.locationCoordinate(Location(maxlat, minlon)).zoomTo(min_zoom).container() lr = osm.locationCoordinate(Location(minlat, maxlon)).zoomTo(min_zoom).container() rows, cols = range(int(ul.row), int(lr.row+1)), range(int(ul.column), int(lr.column+1)) coords = [Coordinate(row, col, min_zoom) for (row, col) in product(rows, cols)] return coords
options, zooms = parser.parse_args() if bool(options.mbtiles_input): coordinates = MBTiles.list_tiles(options.mbtiles_input) else: lat1, lon1, lat2, lon2 = options.bbox south, west = min(lat1, lat2), min(lon1, lon2) north, east = max(lat1, lat2), max(lon1, lon2) northwest = Location(north, west) southeast = Location(south, east) osm = Provider() ul = osm.locationCoordinate(northwest) lr = osm.locationCoordinate(southeast) for (i, zoom) in enumerate(zooms): if not zoom.isdigit(): raise KnownUnknown('"%s" is not a valid numeric zoom level.' % zoom) zooms[i] = int(zoom) if options.padding < 0: raise KnownUnknown('A negative padding will not work.') coordinates = generateCoordinates(ul, lr, zooms, options.padding) for coord in coordinates: print('%(zoom)d/%(column)d/%(row)d' % coord.__dict__)
('buildings', 15), ('buildings', 16), ('pois', 9), ('pois', 10), ('pois', 11), ('pois', 12), ('pois', 13), ('pois', 14), ('pois', 15), ('pois', 16), ('pois', 17), ('pois', 18), ] for (layer, zoom) in stuff: coord = osm.locationCoordinate(loc).zoomTo(zoom) tile = '%(zoom)d/%(column)d/%(row)d' % coord.__dict__ path = '/%(layer)s/%(tile)s.json' % locals() print path, '?' mime, body = requestHandler('tilestache.cfg', path, None) assert '/json' in mime, 'Bad mime-type: %s' % mime data = loads(body) assert data['type'] == 'FeatureCollection', 'Bad data: %s' % body assert 'id' in data['features'][0], 'Bad data: %s' % body