Beispiel #1
0
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
Beispiel #2
0
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'
Beispiel #4
0
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
Beispiel #5
0
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))
Beispiel #6
0
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'
Beispiel #8
0
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))
Beispiel #9
0
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))
Beispiel #10
0
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
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
Beispiel #13
0
    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__)
    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__)
Beispiel #15
0
    ('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
    ('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