Exemplo n.º 1
0
def make_transform(tilerange, zoom):
    ulx, uly = mercantile.xy(*mercantile.ul(tilerange['x']['min'], tilerange['y']['min'], zoom))
    lrx, lry = mercantile.xy(*mercantile.ul(tilerange['x']['max'], tilerange['y']['max'], zoom))
    xcell = (lrx - ulx) / float(tilerange['x']['max'] - tilerange['x']['min'])
    ycell = (uly - lry) / float(tilerange['y']['max'] - tilerange['y']['min'])
    return Affine(xcell, 0, ulx,
        0, -ycell, uly)
Exemplo n.º 2
0
def union(inputtiles, parsenames):

    tiles = sutils.tile_parser(inputtiles, parsenames)

    xmin, xmax, ymin, ymax = sutils.get_range(tiles)

    zoom = sutils.get_zoom(tiles)

    # make an array of shape (xrange + 3, yrange + 3)
    burn = sutils.burnXYZs(tiles, xmin, xmax, ymin, ymax, 0)

    nw = mercantile.xy(*mercantile.ul(xmin, ymin, zoom))

    se = mercantile.xy(*mercantile.ul(xmax + 1, ymax + 1, zoom))

    aff = Affine(((se[0] - nw[0]) / float(xmax - xmin + 1)), 0.0, nw[0],
        0.0, -((nw[1] - se[1]) / float(ymax - ymin + 1)), nw[1])

    unprojecter = sutils.Unprojecter()

    unionedTiles = [
        {
            'geometry': unprojecter.unproject(feature),
            'properties': {},
            'type': 'Feature'
        } for feature, shapes in features.shapes(np.asarray(np.flipud(np.rot90(burn)).astype(np.uint8), order='C'), transform=aff) if shapes == 1
    ]

    return unionedTiles
Exemplo n.º 3
0
def tilebbox(dist, lon, lat, bdim=BASE_DIM, buffer=4, format=None):
    """
    dist     @float : Search distance.
    lon      @float : Center longitude.
    lat      @float : Center latitude.
    bdim     @float : Base time dimention in meters.
    buffer @integer : Buffer dimention in times of bdim.
    format  @string : Output format

    returns:
        upper left corner coordinates and bottom right cooodinates in terms of
        * [[minlon, maxlat], [maxlon, minlat]]
        * {'w': minlon, 's': minlat, 'e': maxlon, 'n': maxlat} in case OSM format is required
    """

    bt, _ = get_base_tile(lon, lat, bdim)

    nn = __get_box_dim(bt, dist)

    ul = mc.ul(bt.x-(nn+buffer), bt.y-(nn+buffer), bt.z)
    br = mc.ul(bt.x+(nn+buffer)+1, bt.y+(nn+buffer)+1, bt.z)

    if format is None:
        return Bbox(ul.lng, br.lat, br.lng, ul.lat)
    elif format == 'osm':
        keys = ('w', 's', 'e', 'n')
        return dict(zip(keys, map(str, (ul.lng, br.lat, br.lng, ul.lat,)))) # minx, miny, maxx, maxy
    else:
        raise NotImplementedError
def make_transform(tilerange, zoom):
    ulx, uly = mercantile.xy(*mercantile.ul(tilerange['x']['min'], tilerange['y']['min'], zoom))
    lrx, lry = mercantile.xy(*mercantile.ul(tilerange['x']['max'], tilerange['y']['max'], zoom))
    xcell = (lrx - ulx) / float(tilerange['x']['max'] - tilerange['x']['min'])
    ycell = (uly - lry) / float(tilerange['y']['max'] - tilerange['y']['min'])
    return Affine(xcell, 0, ulx,
                  0, -ycell, uly)
Exemplo n.º 5
0
    def _write((tile, data)):
        if not contains_data((tile, data)):
            return

        print("Writing", tile)

        # Get the bounds of the tile.
        ulx, uly = mercantile.xy(
            *mercantile.ul(tile.x, tile.y, tile.z))
        lrx, lry = mercantile.xy(
            *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

        # TODO constantize
        tmp_path = "/vsimem/tile"

        # create GeoTIFF
        meta = creation_options.copy()
        meta["count"] = 1
        meta["nodata"] = data.fill_value
        meta["dtype"] = data.dtype
        meta["width"] = CHUNK_SIZE
        meta["height"] = CHUNK_SIZE
        meta["transform"] = from_bounds(ulx, lry, lrx, uly, CHUNK_SIZE, CHUNK_SIZE)

        with rasterio.drivers():
            with rasterio.open(tmp_path, "w", **meta) as tmp:
                tmp.write(data, 1)

        # write out
        output_uri = urlparse(out_dir)
        contents = bytearray(virtual_file_to_buffer(tmp_path))

        if output_uri.scheme == "s3":
            # TODO use mapPartitions so that the client only needs to be
            # instantiated once per partition
            client = boto3.client("s3")

            bucket = output_uri.netloc
            # TODO strip out trailing slashes on the path if necessary
            key = "%s/%d/%d/%d.tif" % (output_uri.path[1:], tile.z, tile.x, tile.y)

            response = client.put_object(
                ACL="public-read",
                Body=bytes(contents),
                Bucket=bucket,
                # CacheControl="TODO",
                ContentType="image/tiff",
                Key=key
            )
        else:
            output_path = os.path.join(out_dir, "%d/%d/%d.tif" % (tile.z, tile.x, tile.y))
            mkdir_p(os.path.dirname(output_path))

            f = open(output_path, "w")
            f.write(contents)
            f.close()
Exemplo n.º 6
0
def make_transform(tilerange, zoom):
    ulx, uly = mercantile.xy(
        *mercantile.ul(tilerange["x"]["min"], tilerange["y"]["min"], zoom)
    )
    lrx, lry = mercantile.xy(
        *mercantile.ul(tilerange["x"]["max"], tilerange["y"]["max"], zoom)
    )
    xcell = (lrx - ulx) / float(tilerange["x"]["max"] - tilerange["x"]["min"])
    ycell = (uly - lry) / float(tilerange["y"]["max"] - tilerange["y"]["min"])
    return Affine(xcell, 0, ulx, 0, -ycell, uly)
Exemplo n.º 7
0
 def _f(tile):
     x, y, z = tile
     ulx, uly = mercantile.ul(x, y, z)
     lrx, lry = mercantile.ul(x + 1, y + 1, zoom)
     return (
         (bounds[0] < ulx < bounds[2])
         and (bounds[1] < uly < bounds[3])
         and (bounds[0] < lrx < bounds[2])
         and (bounds[1] < lry < bounds[3])
     )
Exemplo n.º 8
0
    def __init__(self, center, bbox, zoom, basemap, opacity, size=None):

        self._configure_event_loop()
        point = center['geometry']['coordinates']
        if size is None:
            size = IMAGE_SIZE

        self.num_tiles = [
            math.ceil(size[x] / TILE_SIZE[x]) + 1 for x in (0, 1)
        ]
        center_tile = mercantile.tile(point[0], point[1], zoom)

        mercator = Proj(init='epsg:3857')
        wgs84 = Proj(init='epsg:4326')

        center_tile_bbox = BBox(mercantile.bounds(*center_tile),
                                projection=wgs84).project(mercator,
                                                          edge_points=0)
        center_to_image = world_to_image(center_tile_bbox, TILE_SIZE)
        center_to_world = image_to_world(center_tile_bbox, TILE_SIZE)
        center_point_px = center_to_image(*mercantile.xy(*point))

        self.ul_tile = mercantile.tile(*transform(
            mercator, wgs84,
            *center_to_world(center_point_px[0] -
                             math.ceil(IMAGE_SIZE[0] / 2), center_point_px[1] -
                             math.ceil(IMAGE_SIZE[1] / 2)), zoom))

        lr_tile = mercantile.Tile(x=min(2**zoom,
                                        self.ul_tile.x + self.num_tiles[0]),
                                  y=min(2**zoom,
                                        self.ul_tile.y + self.num_tiles[1]),
                                  z=zoom)

        ul = mercantile.xy(*mercantile.ul(*self.ul_tile))
        lr = mercantile.xy(*mercantile.ul(*lr_tile))

        self.image_bbox = BBox((ul[0], lr[1], lr[0], ul[1]))
        self.image_size = (TILE_SIZE[0] * self.num_tiles[0],
                           TILE_SIZE[1] * self.num_tiles[1])

        self.to_image = world_to_image(self.image_bbox, self.image_size)
        self.to_world = image_to_world(self.image_bbox, self.image_size)

        self.point_px = [
            round(x) for x in self.to_image(*mercantile.xy(*point))
        ]

        self.target_size = size
        self.point = point
        self.zoom = zoom
        self.basemap = basemap
        self._basemap_image = None
        self.opacity = opacity
Exemplo n.º 9
0
    def get_bbox(self, zoom=18):
        tile = self.get_tile(zoom)

        ne = mercantile.bounds(
            mercantile.tile(*mercantile.ul(tile.x + 1, tile.y + 1, zoom),
                            zoom=zoom))
        sw = mercantile.bounds(
            mercantile.tile(*mercantile.ul(tile.x - 1, tile.y - 1, zoom),
                            zoom=zoom))

        return sw.west, sw.south, ne.east, ne.north
Exemplo n.º 10
0
def tiles_to_bounds(tiles: List[mercantile.Tile]) -> Tuple[float, float, float, float]:
    """Get bounds from a set of mercator tiles."""
    zoom = tiles[0].z
    xyz = numpy.array([[t.x, t.y, t.z] for t in tiles])
    extrema = {
        "x": {"min": xyz[:, 0].min(), "max": xyz[:, 0].max() + 1},
        "y": {"min": xyz[:, 1].min(), "max": xyz[:, 1].max() + 1},
    }
    ulx, uly = mercantile.ul(extrema["x"]["min"], extrema["y"]["min"], zoom)
    lrx, lry = mercantile.ul(extrema["x"]["max"], extrema["y"]["max"], zoom)
    return (ulx, lry, lrx, uly)
Exemplo n.º 11
0
def process_tile(tile):
    """Process a single MBTiles tile

    Parameters
    ----------
    tile : mercantile.Tile

    Returns:
    tile : mercantile.Tile
        The input tile.
    bytes : bytearray
        Image bytes corresponding to the tile.
    """
    global base_kwds, resampling, src
    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(
        *mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(
        *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds['transform'] = from_bounds(ulx, lry, lrx, uly, 256, 256)
    src_nodata = kwds.pop('src_nodata', None)
    dst_nodata = kwds.pop('dst_nodata', None)

    with rasterio.open('/vsimem/tileimg', 'w', **kwds) as tmp:
        reproject(rasterio.band(src, src.indexes),
                  rasterio.band(tmp, tmp.indexes),
                  src_nodata=src_nodata,
                  dst_nodata=dst_nodata,
                  num_threads=1,
                  resampling=resampling)

    data = bytearray(virtual_file_to_buffer('/vsimem/tileimg'))

    # Workaround for https://bugs.python.org/issue23349.
    if sys.version_info[0] == 2 and sys.version_info[2] < 10:
        # Check for backported bug fix before re-ordering
	if kwds['driver'] == 'PNG' and data[0:8] == png_header:
            # Properly constructed PNG, no need to re-order bytes
            pass
	elif kwds['driver'] == 'JPEG' and data[0:4] == jpeg_header:
            # Properly constructed JPEG, no need to re-order bytes
            pass
	else:
            data[:] = data[-1:] + data[:-1]

    return tile, data
Exemplo n.º 12
0
def pred_2geojson(csv_file, keyword, threshold):
    features = list()
    with open(csv_file, 'r') as csvfile:
        reader = csv.reader(csvfile)
        next(reader)
        for row in tqdm(reader):
            pred = json.loads(row[1])
            pred_red = list(map(lambda x: round(x, 2), pred))
            pred_obj = dict(
                zip(map(lambda x: 'p%s' % x, range(len(pred_red))), pred_red))
            if keyword == "point":
                pred_j = ul(*[int(t) for t in row[0].split('-')])
                feature_collection = Feature(geometry=dict(
                    type='Point', coordinates=[pred_j.lng, pred_j.lat]),
                                             properties=pred_obj)
            else:
                pred_j = feature(Tile(*[int(t) for t in row[0].split('-')]))
                feature_ = Feature(geometry=pred_j['geometry'],
                                   properties=pred_obj)
            if pred_obj['p1'] >= float(threshold):
                features.append(feature_)
    feature_collection = FeatureCollection(features)
    with open('results_{}_{}.geojson'.format(keyword, threshold),
              'w') as results:
        json.dump(feature_collection, results)
Exemplo n.º 13
0
def test_xy_tile():
    """x, y for the 486-332-10 tile is correctly calculated"""
    ul = mercantile.ul(486, 332, 10)
    xy = mercantile.xy(*ul)
    expected = (-1017529.7205322663, 7044436.526761846)
    for a, b in zip(expected, xy):
        assert round(a - b, 7) == 0
Exemplo n.º 14
0
def test_ul():
    expected = (-9.140625, 53.33087298301705)
    lnglat = mercantile.ul(486, 332, 10)
    for a, b in zip(expected, lnglat):
        assert round(a-b, 7) == 0
    assert lnglat[0] == lnglat.lng
    assert lnglat[1] == lnglat.lat
Exemplo n.º 15
0
def test_ul_tile_roundtrip(t):
    """ul and tile roundtrip"""
    lnglat = mercantile.ul(t)
    tile = mercantile.tile(lnglat.lng, lnglat.lat, t.z)
    assert tile.z == t.z
    assert tile.x == t.x
    assert tile.y == t.y
Exemplo n.º 16
0
def find_bbox_from_tiles(tiles):
    """
    Returns a dictionary of mercantile.LngLatBbox named tuples for each
    zoom level in tiles
    """
    xyz = np.array([(t.x, t.y, t.z) for t in tiles])
    zooms = np.unique(xyz[:, 2])
    out_dict = {}
    for z in zooms:
        idx = np.where(xyz[:, 2] == z)[0]
        ul = xyz[idx, 0:2].min(0)
        ll = xyz[idx, 0:2].max(0) + 1
        a = mercantile.ul(ul[0], ul[1], z)
        b = mercantile.ul(ll[0], ll[1], z)
        out_dict[z] = mercantile.LngLatBbox(a[0], b[1], b[0], a[1])
    return out_dict
Exemplo n.º 17
0
def test_xy_tile():
    """x, y for the 486-332-10 tile is correctly calculated"""
    ul = mercantile.ul(486, 332, 10)
    xy = mercantile.xy(*ul)
    expected = (-1017529.7205322663, 7044436.526761846)
    for a, b in zip(expected, xy):
        assert round(a - b, 7) == 0
Exemplo n.º 18
0
def get_tile(tx, ty, zoom):
    print tx, ty, zoom
    bounds = mercantile.bounds(tx, ty, zoom)
    print bounds

    lat1 = int(bounds.north)
    lat2 = int(bounds.south)
    lon1 = int(bounds.west)
    lon2 = int(bounds.east)

    tile = np.zeros((256, 256))

    tile_base = mercantile.xy(*mercantile.ul(tx, ty, zoom))
    print tile_base

    for lat in range(lat2, lat1 + 1):
        for lon in range(lon1, lon2 + 1):
            key = "meshmap:block:%d:%d" % (lat, lon)
            block = np.frombuffer(redis.get(key), dtype=np.uint8)
            block = block.reshape((120, 80))

            blat1 = min(lat + 1, bounds.north)
            blat2 = max(lat, bounds.south)
            blon1 = max(lon, bounds.west)
            blon2 = min(lon + 1, bounds.east)

            print blat1, blat2, blon1, blon2

            p1 = mercantile.xy(blon1, blat1)
            p2 = mercantile.xy(blon2, blat2)

            print p1, p2

            print p1[0] - tile_base[0], p1[1] - tile_base[1]
Exemplo n.º 19
0
def test_ul(args):
    expected = (-9.140625, 53.33087298301705)
    lnglat = mercantile.ul(*args)
    for a, b in zip(expected, lnglat):
        assert round(a - b, 7) == 0
    assert lnglat[0] == lnglat.lng
    assert lnglat[1] == lnglat.lat
Exemplo n.º 20
0
def process_tile(tile):
    """Process a single MBTiles tile."""
    global base_kwds, src
    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(*mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(*mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds["transform"] = from_bounds(ulx, lry, lrx, uly, 256, 256)

    with rasterio.open("/vsimem/tileimg", "w", **kwds) as tmp:
        # Reproject the src dataset into image tile.
        for bidx in tmp.indexes:
            reproject(rasterio.band(src, bidx), rasterio.band(tmp, bidx))

    # Get contents of the virtual file.
    contents = bytearray(virtual_file_to_buffer("/vsimem/tileimg"))
    return tile, contents
Exemplo n.º 21
0
def process_tile(tile):
    """Process a single MBTiles tile."""
    global base_kwds, src
    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(*mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(*mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds['transform'] = from_bounds(ulx, lry, lrx, uly, 256, 256)

    with rasterio.open('/vsimem/tileimg', 'w', **kwds) as tmp:
        # Reproject the src dataset into image tile.
        for bidx in tmp.indexes:
            reproject(rasterio.band(src, bidx), rasterio.band(tmp, bidx))

    # Get contents of the virtual file and repair it.
    contents = bytearray(virtual_file_to_buffer('/vsimem/tileimg'))
    return tile, contents[-1:] + contents[:-1]
Exemplo n.º 22
0
def _tile_worker(tile):
    """
    For each tile, and given an open rasterio src, plus a`global_args` dictionary
    with attributes of `base_val`, `interval`, and a `writer_func`,
    warp a continous single band raster to a 512 x 512 mercator tile,
    then encode this tile into RGB.

    Parameters
    -----------
    tile: list
        [x, y, z] indices of tile

    Returns
    --------
    tile, buffer
        tuple with the input tile, and a bytearray with the data encoded into
        the format created in the `writer_func`

    """
    x, y, z = tile

    bounds = [
        c for i in (
            mercantile.xy(*mercantile.ul(x, y + 1, z)),
            mercantile.xy(*mercantile.ul(x + 1, y, z)),
        ) for c in i
    ]

    toaffine = transform.from_bounds(*bounds + [512, 512])

    out = np.empty((512, 512), dtype=src.meta["dtype"])

    reproject(
        rasterio.band(src, 1),
        out,
        dst_transform=toaffine,
        dst_crs="epsg:3857",
        resampling=Resampling.bilinear,
    )

    out = data_to_rgb(out, global_args["base_val"], global_args["interval"])

    return tile, global_args["writer_func"](out, global_args["kwargs"].copy(),
                                            toaffine)
Exemplo n.º 23
0
def process_chunk(tile, input, creation_options, resampling):
    """Process a single tile."""

    from rasterio.warp import RESAMPLING

    input = input.replace("s3://", "/vsicurl/http://s3.amazonaws.com/")

    print("Chunking initial image for", tile)

    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(
        *mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(
        *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    tmp_path = "/vsimem/tile"

    with rasterio.drivers():
        with rasterio.open(input, "r") as src:
            meta = src.meta.copy()
            meta.update(creation_options)
            meta["height"] = CHUNK_SIZE
            meta["width"] = CHUNK_SIZE
            meta["transform"] = from_bounds(ulx, lry, lrx, uly, CHUNK_SIZE, CHUNK_SIZE)

            # write to a tmp file to allow GDAL to handle the transform
            with rasterio.open(tmp_path, "w", **meta) as tmp:
                # Reproject the src dataset into image tile.
                for bidx in src.indexes:
                    reproject(
                        source=rasterio.band(src, bidx),
                        destination=rasterio.band(tmp, bidx),
                        resampling=getattr(RESAMPLING, resampling),
                        num_threads=multiprocessing.cpu_count(),
                    )

                # check for chunks containing only NODATA
                data = tmp.read(masked=True)

            if data.mask.all():
                return

            # TODO hard-coded for the first band
            return (tile, data[0])
Exemplo n.º 24
0
def test_xy():
    ul = mercantile.ul(486, 332, 10)
    xy = mercantile.xy(*ul)
    expected = (-1017529.7205322663, 7044436.526761846)
    for a, b in zip(expected, xy):
        assert round(a-b, 7) == 0
    xy = mercantile.xy(0.0, 0.0)
    expected = (0.0, 0.0)
    for a, b in zip(expected, xy):
        assert round(a-b, 7) == 0
Exemplo n.º 25
0
def downsample((tile, data)):
    if data is None:
        return

    print("Downsampling", tile)

    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(
        *mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(
        *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    # TODO constantize
    tmp_path = "/vsimem/tile"

    # create GeoTIFF
    meta = {
        "driver": "GTiff",
        "crs": "EPSG:3857",
        "nodata": data.fill_value,
        "count": 1,
        "dtype": data.dtype,
        "width": CHUNK_SIZE,
        "height": CHUNK_SIZE,
        "transform": from_bounds(ulx, lry, lrx, uly, CHUNK_SIZE, CHUNK_SIZE),
    }

    with rasterio.drivers():
        with rasterio.open(tmp_path, "w", **meta) as tmp:
            # use GDAL to resample by writing an ndarray and immediately reading
            # it out into a smaller array
            tmp.write(data, 1)
            resampled = tmp.read(
                indexes=1,
                masked=True,
                out=ma.array(np.empty((CHUNK_SIZE / 2, CHUNK_SIZE / 2), data.dtype)),
            )

            if resampled.mask.all():
                return

            corner = CORNERS[(tile.x % 2, tile.y % 2)]
            return (mercantile.parent(tile), (corner, resampled))
Exemplo n.º 26
0
def test_xy():
    ul = mercantile.ul(486, 332, 10)
    xy = mercantile.xy(*ul)
    expected = (-1017529.7205322663, 7044436.526761846)
    for a, b in zip(expected, xy):
        assert round(a - b, 7) == 0
    xy = mercantile.xy(0.0, 0.0)
    expected = (0.0, 0.0)
    for a, b in zip(expected, xy):
        assert round(a - b, 7) == 0
Exemplo n.º 27
0
def get_and_store_file(tile_ind, list_format=('x', 'y', 'z')):
    """Fetch tile from internet and store on local drive"""

    # Only download a certain percentage of tiles
    # if random() > down_p['download_prob']:
    #
    #     return 0
    tile_ind = tile_ind.rstrip('\n').split()
    #####################################
    # Construct url to image
    #####################################
    # Allow for other x/y/z orders
    ind_pos = [list_format.index(letter) for letter in ['x', 'y', 'z']]
    ind_dict = dict(x=tile_ind[ind_pos[0]],
                    y=tile_ind[ind_pos[1]],
                    z=tile_ind[ind_pos[2]])
    #url = down_p['url_template'].format(**ind_dict)

    service = Static(down_p['token'])
    coords = mercantile.ul(int(tile_ind[ind_pos[0]]), int(tile_ind[ind_pos[1]]), int(tile_ind[ind_pos[2]]))

    response = service.image('mapbox.satellite', lon=coords.lng, lat=coords.lat, z=tile_ind[ind_pos[2]], image_format='jpg', width=256, height=256)

    ##############################################
    # Setup file paths
    ##############################################
    # Check if tile exists already
    tile_fname = op.join(down_p['storage_dir'],
                        '{x}-{y}-{z}.jpg'.format(**ind_dict))

    ####################################################
    # Download to storage if file doesn't exist
    ####################################################
    if not op.exists(tile_fname):
        repeat_try = 10
        while repeat_try:
            try:
                print("status code", response.status_code)
                if response.status_code == 200:
                    with open(tile_fname, 'wb') as output:
                        _ = output.write(response.content)
                    print('Successfully saved', tile_fname)
                    return 200
                elif response.status_code == 429:
                    print('URL Error')
                    return 429
            except response.status_code != 200:
                repeat_try -= 1

        if repeat_try == 0:
            print('Too many repeats, quitting on {}'.format(tile_fname))
            return
    else:
        print('File exists: {}'.format(tile_fname))
        return 0
Exemplo n.º 28
0
def merc2xy(x, y, z, sgeom):
    """ Apply some affine transformations to input shapely geometry for coordinates
    transformation from Mercatore to local tile pixels.

    sgeom @shapely.geom : Input polygon

    Returns a brand new shapely polygon in the new coordinates.
    """

    MVT_EXTENT = 4096

    X_min, Y_max = mercantile.xy(*mercantile.ul(x, y, z))
    X_max, Y_min = mercantile.xy(*mercantile.ul(x + 1, y - 1, z))

    geom_3857 = transform(transformer.transform, sgeom)
    tx, ty = -X_min, -2 * Y_max + Y_min
    geom_XY = translate(geom_3857, tx, ty)
    x_scale_factor = MVT_EXTENT / (X_max - X_min)
    y_scale_factor = -MVT_EXTENT / (Y_max - Y_min)
    geom_xy = scale(geom_XY, x_scale_factor, y_scale_factor, origin=(0, 0, 0))
    return geom_xy
Exemplo n.º 29
0
def union(inputtiles, parsenames):

    tiles = sutils.tile_parser(inputtiles, parsenames)

    xmin, xmax, ymin, ymax = sutils.get_range(tiles)

    zoom = sutils.get_zoom(tiles)

    # make an array of shape (xrange + 3, yrange + 3)
    burn = sutils.burnXYZs(tiles, xmin, xmax, ymin, ymax, 0)

    nw = mercantile.xy(*mercantile.ul(xmin, ymin, zoom))

    se = mercantile.xy(*mercantile.ul(xmax + 1, ymax + 1, zoom))

    aff = Affine(
        ((se[0] - nw[0]) / float(xmax - xmin + 1)),
        0.0,
        nw[0],
        0.0,
        -((nw[1] - se[1]) / float(ymax - ymin + 1)),
        nw[1],
    )

    unprojecter = sutils.Unprojecter()

    unionedTiles = [
        {
            "geometry": unprojecter.unproject(feature),
            "properties": {},
            "type": "Feature",
        }
        for feature, shapes in features.shapes(
            np.asarray(np.flipud(np.rot90(burn)).astype(np.uint8), order="C"),
            transform=aff,
        )
        if shapes == 1
    ]

    return unionedTiles
Exemplo n.º 30
0
    def handle(self, *args, **options):
        # the mission
        ul = (-122.424130, 37.764861)
        br = (-122.404819, 37.749389)
        ZOOM = 19

        ul_tile = mercantile.tile(*ul + (ZOOM, ))
        br_tile = mercantile.tile(*br + (ZOOM, ))

        for x in range(ul_tile.x, br_tile.x + 1):
            for y in range(ul_tile.y, br_tile.y + 1):
                lng, lat = mercantile.ul(x, y, ZOOM)
                Tile.objects.get_or_create(pt=Point(lng, lat))
Exemplo n.º 31
0
def process_tile(tile):
    """Process a single MBTiles tile

    Parameters
    ----------
    tile : mercantile.Tile

    Returns:
    tile : mercantile.Tile
        The input tile.
    bytes : bytearray
        Image bytes corresponding to the tile.
    """
    global base_kwds, src
    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(*mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(*mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds['transform'] = from_bounds(ulx, lry, lrx, uly, 256, 256)
    src_nodata = kwds.pop('src_nodata', None)
    dst_nodata = kwds.pop('dst_nodata', None)

    with rasterio.open('/vsimem/tileimg', 'w', **kwds) as tmp:
        reproject(rasterio.band(src, src.indexes),
                  rasterio.band(tmp, tmp.indexes),
                  src_nodata=src_nodata,
                  dst_nodata=dst_nodata,
                  num_threads=1)

    data = bytearray(virtual_file_to_buffer('/vsimem/tileimg'))

    # Workaround for https://bugs.python.org/issue23349.
    if sys.version_info[0] == 2 and sys.version_info[2] < 10:
        data[:] = data[-1:] + data[:-1]

    return tile, data
Exemplo n.º 32
0
def _tile_worker(tile):
    """
    For each tile, and given an open rasterio src, plus a`global_args` dictionary
    with attributes of `base_val`, `interval`, and a `writer_func`,
    warp a continous single band raster to a 512 x 512 mercator tile,
    then encode this tile into RGB.

    Parameters
    -----------
    tile: list
        [x, y, z] indices of tile

    Returns
    --------
    tile, buffer
        tuple with the input tile, and a bytearray with the data encoded into
        the format created in the `writer_func`

    """
    x, y, z = tile

    bounds = [c for i in (mercantile.xy(*mercantile.ul(x, y + 1, z)),
            mercantile.xy(*mercantile.ul(x + 1, y, z))) for c in i]

    toaffine = transform.from_bounds(*bounds + [512, 512])

    out = np.empty((512, 512), dtype=src.meta['dtype'])

    reproject(
        rasterio.band(src, 1), out,
        dst_transform=toaffine,
        dst_crs="epsg:3857",
        resampling=RESAMPLING.bilinear)

    out = data_to_rgb(out, global_args['base_val'], global_args['interval'])

    return tile, global_args['writer_func'](out, global_args['kwargs'].copy(), toaffine)
Exemplo n.º 33
0
def assemble_tif(out_path, zoom, tiles, tiles_url, extrema, tilesize):
    # Define Output COG parameters
    width = (extrema["x"]["max"] - extrema["x"]["min"]) * tilesize
    height = (extrema["y"]["max"] - extrema["y"]["min"]) * tilesize
    w, n = mercantile.xy(
        *mercantile.ul(extrema["x"]["min"], extrema["y"]["min"], zoom))
    res = _meters_per_pixel(zoom, 0, tilesize=tilesize)

    params = {
        'driver': "GTiff",
        'dtype': "uint8",
        'count': 3,
        'width': width,
        'height': height,
        'crs': "epsg:3857",
        'transform': Affine(res, 0, w, 0, -res, n),
        'nodata': 0,
        'tiled': True,
        'blockxsize': tilesize,
        'blockysize': tilesize,
    }
    output_profile = cog_profiles.get("deflate")

    with rasterio.Env():
        with MemoryFile() as memfile:
            with memfile.open(**params) as mem:
                with futures.ThreadPoolExecutor(max_workers=50) as executor:
                    future_work = [
                        executor.submit(_call_tile_endpoint, tile, tiles_url,
                                        extrema, tilesize) for tile in tiles
                    ]

                    for f in tqdm(futures.as_completed(future_work),
                                  total=len(future_work)):
                        pass

                for f in _filter_futures(future_work):
                    window, img = f
                    with rasterio.open(BytesIO(img.content)) as src_dst:
                        mem.write(src_dst.read(indexes=(1, 2, 3)),
                                  window=window)

                cog_translate(
                    mem,
                    out_path,
                    output_profile,
                    config=dict(GDAL_NUM_THREADS="ALL_CPUS",
                                GDAL_TIFF_OVR_BLOCKSIZE="128"),
                )
Exemplo n.º 34
0
def tile_affine(tile_row, tile_col, level):
    '''
    a = width of a pixel
    b = row rotation (typically zero)
    c = x-coordinate of the upper-left corner of the upper-left pixel
    d = column rotation (typically zero)
    e = height of a pixel (typically negative)
    f = y-coordinate of the of the upper-left corner of the upper-left pixel

    reference: https://www.perrygeo.com/python-affine-transforms.html

    Arguments:
        tile_row {int} -- or y in Cartesian coordinate system
        tile_col {int} -- or x in Cartesian coordinate system
    '''
    a = LEVEL_RESLUTION[level]
    b = 0
    c, f = mercantile.xy(*mercantile.ul(tile_col, tile_row, level))
    d = 0
    e = -LEVEL_RESLUTION[level]

    return Affine(a, b, c, d, e, f)
Exemplo n.º 35
0
def main(args):

    parser = argparse.ArgumentParser()
    parser.add_argument("-d", "--debug", action="store_true")
    parsed = parser.parse_args(args)
    global debug
    debug = parsed.debug
    scriptdir = os.path.dirname(os.path.realpath(__file__))

    testdata_directory = os.path.join(scriptdir, "testdata")
    outdata_directory = os.path.join(testdata_directory, "out")
    wgs84 = TilePyramid("geodetic")
    wgs84_meta = MetaTilePyramid(wgs84, 16)

    # TilePyramid
    #===========

    # tiles per zoomlevel
    try:
        matrix_width = wgs84.matrix_width(5)
        matrix_height = wgs84.matrix_height(5)
        assert (matrix_width, matrix_height) == (64, 32)
        print "tiles per zoomlevel OK"
    except:
        print "tiles per zoomlevel FAILED"
        raise


    # top left coordinate
    try:
        tile = wgs84.tile(5, 3, 3)
        tl = (tile.left,tile.top)
        assert tl == (-163.125, 73.125)
        print "top left coordinate OK"
    except:
        print "top left coordinate FAILED"
        print tl
        raise


    # tile bounding box
    try:
        tile = wgs84.tile(5, 3, 3)
        bbox = tile.bbox()
        testpolygon = Polygon([[-163.125, 73.125], [-157.5, 73.125],
            [-157.5, 67.5], [-163.125, 67.5], [-163.125, 73.125]])
        assert bbox.equals(testpolygon)
        print "tile bounding box OK"
    except:
        print "tile bounding box FAILED"
        raise


    # tile bounding box with buffer
    try:
        tile = wgs84.tile(5, 3, 3)
        bbox = tile.bbox(1)
        testpolygon = Polygon([[-163.14697265625, 73.14697265625],
            [-157.47802734375, 73.14697265625],
            [-157.47802734375, 67.47802734375],
            [-163.14697265625, 67.47802734375],
            [-163.14697265625, 73.14697265625]])
        assert bbox.equals(testpolygon)
        print "tile bounding box with buffer OK"
    except:
        print "tile bounding box with buffer FAILED"
        print bbox
        raise


    # tile bounds
    try:
        tile = wgs84.tile(5, 3, 3)
        bounds = tile.bounds()
        testbounds = (-163.125, 67.5, -157.5, 73.125)
        assert bounds == testbounds
        print "tile bounds OK"
    except:
        print "tile bounds FAILED"
        raise


    # tile bounds buffer
    try:
        tile = wgs84.tile(5, 3, 3)
        bounds = tile.bounds(1)
        testbounds = (-163.14697265625, 67.47802734375, -157.47802734375,
            73.14697265625)
        assert bounds == testbounds
        print "tile bounds with buffer OK"
    except:
        print "tile bounds wigh buffer FAILED"
        raise


    # test bounding box
    bbox_location = os.path.join(testdata_directory, "bbox.geojson")
    tiled_out = os.path.join(outdata_directory, "bbox_tiles.geojson")
    zoom = 5
    testtiles = [(5, 5, 33), (5, 6, 33), (5, 7, 33), (5, 8, 33), (5, 9, 33), (5, 10, 33),
        (5, 5, 34), (5, 6, 34), (5, 7, 34), (5, 8, 34), (5, 9, 34), (5, 10, 34), (5, 5, 35),
        (5, 6, 35), (5, 7, 35), (5, 8, 35), (5, 9, 35), (5, 10, 35),(5, 5, 36), (5, 6, 36),
        (5, 7, 36), (5, 8, 36), (5, 9, 36), (5, 10, 36), (5, 5, 37), (5, 6, 37), (5, 7, 37),
        (5, 8, 37), (5, 9, 37), (5, 10, 37),(5, 5, 38), (5, 6, 38), (5, 7, 38), (5, 8, 38),
        (5, 9, 38), (5, 10, 38), (5, 5, 39), (5, 6, 39), (5, 7, 39), (5, 8, 39), (5, 9, 39),
        (5, 10, 39), (5, 5, 40), (5, 6, 40), (5, 7, 40), (5, 8, 40), (5, 9, 40), (5, 10, 40),
        (5, 5, 41), (5, 6, 41), (5, 7, 41), (5, 8, 41), (5, 9, 41), (5, 10, 41)]
    with fiona.open(bbox_location) as bbox_file:
        try:
            bbox_tiles = [
                (tile.zoom, tile.row, tile.col)
                for tile in wgs84.tiles_from_bbox(bbox_file, zoom)
            ]
            assert len(set(bbox_tiles).symmetric_difference(set(testtiles))) == 0
            print "bounding box OK"
        except:
            print "bounding box FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in bbox_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)


    # tiles from Point
    point_location = os.path.join(testdata_directory, "point.geojson")
    tiled_out = os.path.join(outdata_directory, "point_tiles.geojson")
    zoom = 6
    testtile = [(6, 14, 69)]
    with fiona.open(point_location) as point_file:
        point = shape(point_file[0]["geometry"])
        try:
            point_tile = [
                (tile.zoom, tile.row, tile.col)
                for tile in wgs84.tiles_from_geom(point, zoom)
            ]
            assert point_tile == testtile
            print "Point OK"
        except:
            print point_tile, testtile
            print "Point FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            zoom, row, col = point_tile[0]
            feature = {}
            feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
            feature['properties'] = {}
            feature['properties']['col'] = col
            feature['properties']['row'] = row
            sink.write(feature)

    # tiles from MultiPoint
    multipoint_location = os.path.join(testdata_directory,
        "multipoint.geojson")
    tiled_out = os.path.join(outdata_directory, "multipoint_tiles.geojson")
    zoom = 9
    testtiles = [(9, 113, 553), (9, 118, 558)]
    with fiona.open(multipoint_location) as multipoint_file:
        multipoint = shape(multipoint_file[0]["geometry"])
        try:
            multipoint_tiles = [
                (tile.zoom, tile.row, tile.col)
                for tile in wgs84.tiles_from_geom(multipoint, zoom)
            ]
            assert multipoint_tiles == testtiles
            print "MultiPoint OK"
        except:
            print "MultiPoint FAILED"
            print multipoint_tiles
            print testtiles
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in multipoint_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

    # tiles from LineString
    linestring_location = os.path.join(testdata_directory,
        "linestring.geojson")
    tiled_out = os.path.join(outdata_directory, "linestring_tiles.geojson")
    zoom = 6
    testtiles = [(6, 14, 66), (6, 14, 67), (6, 14, 68), (6, 14, 69), (6, 14, 70), (6, 15, 70),
        (6, 15, 71), (6, 16, 71), (6, 16, 72), (6, 15, 73), (6, 16, 73), (6, 15, 74)]
    with fiona.open(linestring_location) as linestring_file:
        linestring = shape(linestring_file[0]["geometry"])
        try:
            linestring_tiles = [
                (tile.zoom, tile.row, tile.col)
                for tile in wgs84.tiles_from_geom(linestring, zoom)
                ]
            assert len(set(linestring_tiles).symmetric_difference(set(testtiles))) == 0
            print "LineString OK"
        except:
            print "LineString FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in linestring_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

    # tiles from MultiLineString
    multilinestring_location = os.path.join(testdata_directory,
        "multilinestring.geojson")
    tiled_out = os.path.join(outdata_directory,
        "multilinestring_tiles.geojson")
    zoom = 6
    testtiles = [(6, 14, 66), (6, 14, 67), (6, 14, 68), (6, 14, 69), (6, 14, 70), (6, 15, 70),
       (6, 15, 71), (6, 16, 71), (6, 16, 72), (6, 15, 73), (6, 16, 73), (6, 15, 74), (6, 21, 74),
       (6, 22, 74), (6, 24, 74), (6, 25, 74), (6, 28, 74), (6, 29, 74), (6, 20, 75), (6, 21, 75),
       (6, 22, 75), (6, 23, 75), (6, 24, 75), (6, 25, 75), (6, 26, 75), (6, 27, 75), (6, 28, 75),
       (6, 29, 75), (6, 30, 75), (6, 31, 75), (6, 25, 76)]
    with fiona.open(multilinestring_location) as multilinestring_file:
        multilinestring = shape(multilinestring_file[0]["geometry"])
        try:
            multilinestring_tiles = [
                (tile.zoom, tile.row, tile.col)
                for tile in wgs84.tiles_from_geom(multilinestring, zoom)
                ]
            assert len(set(multilinestring_tiles).symmetric_difference(set(testtiles))) == 0
            print "MultiLineString OK"
        except:
            print "MultiLineString FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in multilinestring_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

    # tiles from Polygon
    polygon_location = os.path.join(testdata_directory,
        "polygon.geojson")
    tiled_out = os.path.join(outdata_directory, "polygon_tiles.geojson")
    zoom = 8
    testtiles = [(8, 60, 269), (8, 61, 269), (8, 60, 270), (8, 61, 270), (8, 60, 271),
        (8, 61, 271), (8, 60, 272), (8, 61, 272), (8, 60, 273), (8, 61, 273), (8, 59, 274),
        (8, 60, 274), (8, 61, 274), (8, 58, 275), (8, 59, 275), (8, 60, 275), (8, 61, 275),
        (8, 58, 276), (8, 59, 276), (8, 60, 276), (8, 61, 276), (8, 62, 276), (8, 58, 277),
        (8, 59, 277), (8, 60, 277), (8, 61, 277), (8, 58, 278), (8, 59, 278), (8, 60, 278),
        (8, 61, 278), (8, 58, 279), (8, 59, 279), (8, 60, 279), (8, 61, 279), (8, 58, 280),
        (8, 59, 280), (8, 60, 280)]
    with fiona.open(polygon_location) as polygon_file:
        polygon = shape(polygon_file[0]["geometry"])
        polygon_tiles = [
            (tile.zoom, tile.row, tile.col)
            for tile in wgs84.tiles_from_geom(polygon, zoom)
            ]
        try:
            assert len(set(polygon_tiles).symmetric_difference(set(testtiles))) == 0
            print "Polygon OK"
        except:
            print "Polygon FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in polygon_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

    # tiles from MultiPolygon
    multipolygon_location = os.path.join(testdata_directory,
        "multipolygon.geojson")
    tiled_out = os.path.join(outdata_directory, "multipolygon_tiles.geojson")
    zoom = 10
    testtiles = [(10, 243, 1081), (10, 244, 1081), (10, 245, 1081), (10, 242, 1082),
        (10, 243, 1082), (10, 244, 1082), (10, 245, 1082), (10, 241, 1083), (10, 242, 1083),
        (10, 243, 1083), (10, 244, 1083), (10, 245, 1083), (10, 241, 1084), (10, 242, 1084),
        (10, 243, 1084), (10, 244, 1084), (10, 245, 1084), (10, 241, 1085), (10, 242, 1085),
        (10, 243, 1085), (10, 244, 1085), (10, 245, 1085), (10, 241, 1086), (10, 242, 1086),
        (10, 243, 1086), (10, 244, 1086), (10, 245, 1086), (10, 242, 1087), (10, 243, 1087),
        (10, 244, 1087), (10, 245, 1087), (10, 241, 1088), (10, 242, 1088), (10, 243, 1088),
        (10, 244, 1088), (10, 241, 1089), (10, 242, 1089), (10, 243, 1089), (10, 244, 1089),
        (10, 241, 1090), (10, 242, 1090), (10, 243, 1090), (10, 244, 1090), (10, 241, 1091),
        (10, 242, 1091), (10, 243, 1091), (10, 244, 1091), (10, 241, 1092), (10, 242, 1092),
        (10, 243, 1092), (10, 244, 1092), (10, 240, 1093), (10, 241, 1093), (10, 242, 1093),
        (10, 244, 1093), (10, 245, 1093), (10, 240, 1094), (10, 241, 1094), (10, 242, 1094),
        (10, 243, 1094), (10, 244, 1094), (10, 245, 1094), (10, 246, 1094), (10, 240, 1095),
        (10, 241, 1095), (10, 242, 1095), (10, 243, 1095), (10, 244, 1095), (10, 245, 1095),
        (10, 246, 1095), (10, 241, 1096), (10, 244, 1096), (10, 245, 1096), (10, 246, 1096),
        (10, 245, 1097), (10, 246, 1097)]
    with fiona.open(multipolygon_location) as multipolygon_file:
        multipolygon = shape(multipolygon_file[0]["geometry"])
        multipolygon_tiles = [
            (tile.zoom, tile.row, tile.col)
            for tile in wgs84.tiles_from_geom(multipolygon, zoom)
            ]
        try:
            assert len(set(multipolygon_tiles).symmetric_difference(set(testtiles))) == 0
            print "MultiPolygon OK"
        except:
            print "MultiPolygon FAILED"
            raise
    if debug:
        ## write debug output
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in multipolygon_tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)


    if debug:
        # writing output test files
        col, row = 2, 2
        zoom = 5
        metatiling = 2
        wgs84_meta = MetaTilePyramid(wgs84, metatiling)
        antimeridian_location = os.path.join(testdata_directory,
            "antimeridian.geojson")
        with fiona.open(antimeridian_location) as antimeridian_file:
            geometries = []
            for feature in antimeridian_file:
                geometries.append(shape(feature["geometry"]))
        antimeridian = cascaded_union(geometries)
        print "top left tile coordinates:"
        print "metaTilePyramid: %s" %([wgs84_meta.top_left_tile_coords(zoom, row, col)])
        print "tile bounding box"
        print "metaTilePyramid: %s" %([mapping(wgs84.tile_bbox(zoom, row, col))])
        print "tile bounds"
        print "metaTilePyramid: %s" %([wgs84_meta.tile_bounds(zoom, row, col)])
        print "tiles from bbox"
        #print "metaTilePyramid: %s" %([wgs84_meta.tiles_from_bbox(antimeridian, zoom)])
        print "tiles from geometry"

        ## write debug output
        tiled_out = os.path.join(outdata_directory, "tile_antimeridian_tiles.geojson")
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(tiled_out)
        except:
            pass
        tiles = wgs84.tiles_from_geom(antimeridian, zoom)
        print "TilePyramid: %s" %(len(tiles))
        with fiona.open(tiled_out, 'w', 'GeoJSON', schema) as sink:
            for tile in tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)
        ## write debug output
        metatiled_out = os.path.join(outdata_directory, "metatile_antimeridian_tiles.geojson")
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(metatiled_out)
        except:
            pass
        metatiles = wgs84_meta.tiles_from_geom(antimeridian, zoom)
        print "metaTilePyramid: %s" %(len(metatiles))
        with fiona.open(metatiled_out, 'w', 'GeoJSON', schema) as sink:
            for metatile in metatiles:
                zoom, row, col = metatile
                feature = {}
                feature['geometry'] = mapping(wgs84_meta.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)


    for metatiling in (1, 2, 4, 8, 16):
        wgs84_meta = MetaTilePyramid(wgs84, metatiling)
        for zoom in range(22):
            tilepyramid_width = wgs84.matrix_width(zoom)
            tilepyramid_height = wgs84.matrix_height(zoom)
            metatilepyramid_width = wgs84_meta.matrix_width(zoom)
            metatilepyramid_height = wgs84_meta.matrix_height(zoom)
            control_width = int(math.ceil(
                float(tilepyramid_width)/float(metatiling)
            ))
            control_height = int(math.ceil(
                float(tilepyramid_height)/float(metatiling)
            ))
            try:
                assert metatilepyramid_width == control_width
                assert metatilepyramid_height == control_height
            except:
                print "ERROR: metatile number"
                print "metatiling, zoom:", metatiling, zoom
                print "width:", metatilepyramid_width, control_width
                print "height:", metatilepyramid_height, control_height
                raise


    for metatiling in (1, 2, 4, 8, 16):
        wgs84_meta = MetaTilePyramid(wgs84, metatiling)
        for zoom in range(21):
            # check tuple
            assert isinstance(wgs84_meta.matrix_width(zoom), int)
            assert isinstance(wgs84_meta.matrix_height(zoom), int)

            # check metatile size
            metatile_x_size = round(wgs84_meta.metatile_x_size(zoom), ROUND)
            metatile_y_size = round(wgs84_meta.metatile_y_size(zoom), ROUND)
            # assert metatile size equals TilePyramid width and height at zoom 0
            if zoom == 0:
                try:
                    if metatiling == 1:
                        assert (metatile_x_size * 2) == wgs84.x_size
                    else:
                        assert metatile_x_size == wgs84.x_size
                    assert metatile_y_size == wgs84.y_size
                except:
                    print "ERROR: zoom 0 metatile size not correct"
                    print "metatiling, zoom:", metatiling, zoom
                    print "metatile_x_size:", wgs84_meta.metatiling, metatile_x_size, wgs84.x_size
                    print "metatile_y_size:", metatile_y_size, wgs84.y_size
                    raise
            ## assert metatile size within TilePyramid bounds
            try:
                assert (metatile_x_size > 0.0) and (
                    metatile_x_size <= wgs84.x_size)
                assert (metatile_y_size > 0.0) and (
                    metatile_y_size <= wgs84.y_size)
            except:
                print "ERROR: metatile size"
                print zoom
                print "metatile_x_size:", metatile_x_size, wgs84_meta.x_size
                print "metatile_y_size:", metatile_y_size, wgs84_meta.x_size
                raise
            ## calculate control size from tiles
            tile_x_size = wgs84.tile_x_size(zoom)
            tile_y_size = wgs84.tile_y_size(zoom)
            we_control_size = round(tile_x_size * float(metatiling), ROUND)
            if we_control_size > wgs84.x_size:
                we_control_size = wgs84.x_size
            ns_control_size = round(tile_y_size * float(metatiling), ROUND)

            if ns_control_size > wgs84.y_size:
                ns_control_size = wgs84.y_size
            try:
                assert metatile_x_size == we_control_size
                assert metatile_y_size == ns_control_size
            except:
                print "ERROR: metatile size and control sizes"
                print "zoom, metatiling:", zoom, metatiling
                print metatile_x_size, we_control_size
                print metatile_y_size, ns_control_size
                raise

            # check metatile pixelsize (resolution)
            pixel_x_size = round(wgs84.pixel_x_size(zoom), ROUND)
            ctr_pixel_x_size = round(wgs84_meta.pixel_x_size(zoom), ROUND)
            pixel_y_size = round(wgs84.pixel_y_size(zoom), ROUND)
            ctr_pixel_y_size = round(wgs84_meta.pixel_y_size(zoom), ROUND)
            try:
                assert pixel_x_size == ctr_pixel_x_size
                assert pixel_y_size == ctr_pixel_y_size
            except:
                print "ERROR: metatile pixel size"
                print "zoom, metatiling:", zoom, metatiling
                print "pixel_x_size:", pixel_x_size, ctr_pixel_x_size
                print "pixel_y_size:", pixel_y_size, ctr_pixel_y_size
                raise

    if debug:
        fiji_borders = os.path.join(testdata_directory, "fiji.geojson")
        with fiona.open(fiji_borders, "r") as fiji:
            geometries = []
            for feature in fiji:
                geometry = shape(feature['geometry'])
                geometries.append(geometry)
        union = cascaded_union(geometries)
        # tiles
        fiji_tiles = os.path.join(outdata_directory, "fiji_tiles.geojson")
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(fiji_tiles)
        except:
            pass
        metatiling = 4
        zoom = 10
        tiles = wgs84.tiles_from_geom(union, zoom)
        with fiona.open(fiji_tiles, 'w', 'GeoJSON', schema) as sink:
            for tile in tiles:
                zoom, row, col = tile
                feature = {}
                feature['geometry'] = mapping(wgs84.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

        # metatiles
        fiji_metatiles = os.path.join(outdata_directory, "fiji_metatiles.geojson")
        schema = {
            'geometry': 'Polygon',
            'properties': {'col': 'int', 'row': 'int'}
        }
        try:
            os.remove(fiji_metatiles)
        except:
            pass
        wgs84_meta = MetaTilePyramid(wgs84, metatiling)
        metatiles = wgs84_meta.tiles_from_geom(union, zoom)
        with fiona.open(fiji_metatiles, 'w', 'GeoJSON', schema) as sink:
            for metatile in metatiles:
                zoom, row, col = metatile
                feature = {}
                feature['geometry'] = mapping(wgs84_meta.tile_bbox(zoom, row, col))
                feature['properties'] = {}
                feature['properties']['col'] = col
                feature['properties']['row'] = row
                sink.write(feature)

    ## test get neighbors
    metatiling = 1
    wgs84_meta = MetaTilePyramid(wgs84, metatiling)
    tile = wgs84_meta.tile(5, 4, 3)
    assert len(tile.get_neighbors()) == 8

    ## test tile <--> metatile conversion
    metatile = [(10, 44, 33)]
    metatiling = 4
    wgs84_meta = MetaTilePyramid(wgs84, metatiling)
    small_tile = wgs84_meta.tilepyramid.tile(10, 178, 133)
    test_metatile = [
        (tile.zoom, tile.row, tile.col)
        for tile in wgs84_meta.tiles_from_bbox(
            small_tile.bbox(),
            10
        )
    ]
    try:
        assert metatile == test_metatile
        print "OK: metatile <-> tile conversion"
    except:
        print metatile, test_metatile
        raise
        print "ERROR: metatile <-> tile conversion"

    # test mercator tile pyramid
    tile_pyramid = TilePyramid("mercator")
    assert tile_pyramid.srid == 3857
    try:
        for zoom in range(15):
            assert (
                (tile_pyramid.matrix_width(zoom), tile_pyramid.matrix_height(zoom)
                ) == (2**zoom, 2**zoom)
            )
        print "OK: mercator tile matrix widths"
    except:
        print "ERROR: mercator tile matrix widths"


    from shapely.ops import transform
    from functools import partial
    import pyproj
    import mercantile

    example_tiles = [
        (12, 1024, 512),
        (6, 32, 16),
        (0, 0, 0),
        ]

    for tile_idx in example_tiles:
        (zoom, row, col) = tile_idx
        mercantile_ul = Point(
            mercantile.ul(col, row, zoom).lng,
            mercantile.ul(col, row, zoom).lat,
            )
        m_bounds = mercantile.bounds(col, row, zoom)
        mercantile_bbox = box(*m_bounds)
        project = partial(
            pyproj.transform,
            pyproj.Proj({"init": "epsg:3857"}),
            pyproj.Proj({"init": "epsg:4326"})
        )
        tilematrix_ul = transform(
            project,
            Point(
                Tile(tile_pyramid, zoom, row, col).left,
                Tile(tile_pyramid, zoom, row, col).top,
                )
            )
        tilematrix_bbox = transform(
            project,
            Tile(tile_pyramid, zoom, row, col).bbox()
            )

        try:
            assert mercantile_ul.almost_equals(
                tilematrix_ul,
                decimal=GEOM_EQUALS_ROUND
                )
            assert mercantile_bbox.almost_equals(
                tilematrix_bbox,
                decimal=GEOM_EQUALS_ROUND
                )
            print "OK: mercator tile coordinates"
        except AssertionError:
            print "ERROR: mercator tile coordinates"
            print tile_idx, mercantile_ul, tilematrix_ul
            print tile_idx, mercantile_bbox, tilematrix_bbox


    tile_idx = (12, 1024, 512)
    tile = Tile(tile_pyramid, *tile_idx)
    for child in tile.get_children():
        try:
            assert child.get_parent().id == tile.id
            print "OK: tile children and parent"
        except AssertionError:
            print child.parent.id, tile.id
            print "ERROR: tile children and parent"

    # get tiles over antimeridian:
    tile_pyramid = TilePyramid("geodetic")
    tile = tile_pyramid.tile(5, 0, 63)
    target_tiles = set(
        target_tile.id
        for target_tile in tile_pyramid.tiles_from_bounds(tile.bounds(256), 5)
    )
    control_tiles = set(
        [
            # tiles west of antimeridian
            (5, 0, 62),
            (5, 0, 63),
            (5, 1, 62),
            (5, 1, 63),
            # tiles east of antimeridian
            (5, 0, 0),
            (5, 1, 0)
        ]
    )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: tiles over antimeridian"
    except AssertionError:
        print "ERROR: tiles over antimeridian"
        print diff
    tile = tile_pyramid.tile(5, 0, 0)
    target_tiles = set(
        target_tile.id
        for target_tile in tile_pyramid.tiles_from_bounds(tile.bounds(256), 5)
    )
    control_tiles = set(
        [
            # tiles west of antimeridian
            (5, 0, 63),
            (5, 1, 63),
            # tiles east of antimeridian
            (5, 0, 0),
            (5, 1, 0),
            (5, 0, 1),
            (5, 1, 1)
        ]
    )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: tiles over antimeridian"
    except AssertionError:
        print "ERROR: tiles over antimeridian"
        print diff

    # get tiles over antimeridian:
    tile_pyramid = TilePyramid("mercator")
    tile = tile_pyramid.tile(5, 0, 31)
    target_tiles = set(
        target_tile.id
        for target_tile in tile_pyramid.tiles_from_bounds(tile.bounds(256), 5)
    )
    control_tiles = set(
        [
            # tiles west of antimeridian
            (5, 0, 30),
            (5, 0, 31),
            (5, 1, 30),
            (5, 1, 31),
            # tiles east of antimeridian
            (5, 0, 0),
            (5, 1, 0)
        ]
    )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: tiles over antimeridian"
    except AssertionError:
        print "ERROR: tiles over antimeridian"
        print diff
    tile = tile_pyramid.tile(5, 0, 0)
    target_tiles = set(
        target_tile.id
        for target_tile in tile_pyramid.tiles_from_bounds(tile.bounds(256), 5)
    )
    control_tiles = set(
        [
            # tiles west of antimeridian
            (5, 0, 31),
            (5, 1, 31),
            # tiles east of antimeridian
            (5, 0, 0),
            (5, 1, 0),
            (5, 0, 1),
            (5, 1, 1)
        ]
    )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: tiles over antimeridian"
    except AssertionError:
        print "ERROR: tiles over antimeridian"
        print diff

    # geometry over antimeridian
    tile_pyramid = TilePyramid("geodetic")
    geometry = loads("POLYGON ((184.375 90, 190 90, 180 84.375, 174.375 84.375, 184.375 90))")
    target_tiles = set(
        tile.id
        for tile in tile_pyramid.tiles_from_geom(geometry, 6)
        )
    control_tiles = set(
        [
            (6, 0, 127),
            (6, 1, 126),
            (6, 1, 127),
            (6, 0, 0),
            (6, 0, 1),
            (6, 0, 2),
            (6, 0, 3),
            (6, 1, 0),
            (6, 1, 1)
        ]
        )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: geometry over antimeridian"
    except AssertionError:
        print "ERROR: geometry over antimeridian"
        print diff

    tile_pyramid = TilePyramid("mercator")
    geometry = loads("POLYGON ((-22037508.3427892 20037508.3427892, -20785164.07136488 20037508.3427892, -18785164.07136488 18785164.07136488, -20037508.3427892 18785164.07136488, -22037508.3427892 20037508.3427892))")
    target_tiles = set(
        tile.id
        for tile in tile_pyramid.tiles_from_geom(geometry, 6)
        )
    tile_pyramid_bbox = box(
        tile_pyramid.left,
        tile_pyramid.bottom,
        tile_pyramid.right,
        tile_pyramid.top
    )
    for tile in target_tiles:
        assert tile_pyramid.tile(*tile).bbox().within(tile_pyramid_bbox)
    control_tiles = set(
        [
            # west of antimeridian
            (6, 0, 60),
            (6, 0, 61),
            (6, 0, 62),
            (6, 0, 63),
            (6, 1, 62),
            (6, 1, 63),
            # east of antimeridian
            (6, 0, 0),
            (6, 1, 0),
            (6, 1, 1)
        ]
        )
    try:
        diff = control_tiles.difference(target_tiles)
        assert len(diff) == 0
        print "OK: geometry over antimeridian"
    except AssertionError:
        print "ERROR: geometry over antimeridian"
        print target_tiles
        print diff

    # tile shapes
    tile_pyramid = TilePyramid("mercator")
    col, row = (0, 0)
    for zoom in range(10):
        tile = Tile(tile_pyramid, zoom, col, row)
        assert tile.shape() == (256, 256)
    metatile_pyramid = MetaTilePyramid(tile_pyramid, metatiles=8)
    control_shapes = [
        (256, 256),
        (512, 512),
        (1024, 1024),
        (2048, 2048),
        (2048, 2048),
        (2048, 2048),
        (2048, 2048),
        (2048, 2048),
        (2048, 2048),
        (2048, 2048)
        ]
    for zoom, control_shape in zip(range(9), control_shapes):
        tile = Tile(metatile_pyramid, zoom, col, row)
        try:
            assert tile.shape() == control_shape
            print "OK: metatile shape at zoom ", zoom
        except AssertionError:
            print "ERROR: metatile shape at zoom", zoom
            print tile.id, tile.shape(), control_shape
            raise

    # tile shapes with pixelbuffer
    tile_pyramid = TilePyramid("mercator")
    test_tiles = [
        (0, 0, 0),
        (1, 0, 0), # top left
        (2, 0, 1), # top middle
        (2, 0, 3), # top right
        (2, 3, 3), # bottom right
        (2, 3, 0), # bottom left
        (2, 3, 2), # bottom middle
        (2, 2, 0), # left middle
        (2, 2, 3), # right middle
        ]
    pixelbuffer = 2
    tile_size = tile_pyramid.tile_size
    control_shapes = [
        (tile_size, tile_size+2*pixelbuffer),
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # top left
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # top middle
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # top right
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # bottom right
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # bottom left
        (tile_size+1*pixelbuffer, tile_size+2*pixelbuffer),  # bottom middle
        (tile_size+2*pixelbuffer, tile_size+2*pixelbuffer),  # left middle
        (tile_size+2*pixelbuffer, tile_size+2*pixelbuffer),  # right middle
        ]
    for test_tile, control_shape in zip(test_tiles, control_shapes):
        tile = Tile(tile_pyramid, *test_tile)
        try:
            assert tile.shape(pixelbuffer) == control_shape
            print "OK: tile pixelbuffer shape for tile ", test_tile
        except AssertionError:
            print "ERROR: tile pixelbuffer shape for tile", test_tile
            print tile.id, tile.shape(pixelbuffer), control_shape
    # metatile shapes with pixelbuffer
    pixelbuffer = 2
    metatiling = 8
    metatile_pyramid = MetaTilePyramid(tile_pyramid, metatiles=metatiling)
    tile_size = tile_pyramid.tile_size
    test_tiles = [
        (0, 0, 0),
        (1, 0, 0),
        (2, 0, 0),
        (3, 0, 0),
        (4, 0, 0),
        (5, 0, 0),  # top left
        (5, 0, 1),  # top middle
        (5, 0, 3),  # top right
        (5, 3, 3),  # bottom right
        (5, 3, 0),  # bottom left
        (5, 3, 2),  # bottom middle
        (5, 2, 0),  # left middle
        (5, 2, 3),  # right middle
        ]
    for test_tile in test_tiles:
        tile = Tile(metatile_pyramid, *test_tile)
        left, bottom, right, top = tile.bounds(pixelbuffer)
        control_shape = (
            int(round((top-bottom)/tile.pixel_y_size)),
            int(round((right-left)/tile.pixel_x_size))
            )
        try:
            assert tile.shape(pixelbuffer) == control_shape
            print "OK: tile pixelbuffer shape for metatile ", test_tile
        except AssertionError:
            print "ERROR: tile pixelbuffer shape for metatile", test_tile
            print tile.id, tile.shape(pixelbuffer), control_shape

    """intersecting function"""
    try:
        # equal metatiling:
        tile = Tile(TilePyramid("geodetic", metatiling=1), 3, 4, 5)
        pyramid = TilePyramid("geodetic", metatiling=1)
        assert len(tile.intersecting(pyramid)) == 1
        assert tile.intersecting(pyramid)[0].id == tile.id

        # different metatiling:
        tile = Tile(TilePyramid("geodetic", metatiling=1), 3, 4, 5)
        pyramid_metatiling = 2
        pyramid = TilePyramid("geodetic", metatiling=pyramid_metatiling)
        assert len(tile.intersecting(pyramid)) == 1
        intersect = tile.intersecting(pyramid)[0]
        assert tile.bbox().within(intersect.bbox())
        tile = Tile(TilePyramid("geodetic", metatiling=8), 13, 4, 5)
        pyramid_metatiling = 2
        pyramid = TilePyramid("geodetic", metatiling=pyramid_metatiling)
        assert len(tile.intersecting(pyramid)) == 16
        for intersect in tile.intersecting(pyramid):
            assert intersect.bbox().within(tile.bbox())
        tile_list = set(
            tile.id
            for tile in tile.intersecting(pyramid)
        )
        reversed_list = set(
            tile.id
            for tile in pyramid.intersecting(tile)
        )
        assert not len(tile_list.symmetric_difference(reversed_list))
        print "OK: intersecting function"
    except:
        print "ERROR: intersecting function"
        raise

    """affine objects"""
    try:
        for metatiling in [1, 2, 4, 8, 16]:
            pyramid = TilePyramid("geodetic", metatiling=metatiling)
            for zoom in range(22):
                tile = pyramid.tile(zoom, 0, 0)
                assert tile.pixel_x_size == tile.pixel_y_size
                assert tile.affine()[0] == -tile.affine()[4]
                assert tile.affine(pixelbuffer=10)[0] == \
                    -tile.affine(pixelbuffer=10)[4]
        print "OK: Affine objects"
    except:
        print "ERROR: Affine objects"
        raise
Exemplo n.º 36
0
def z_key(tile):
    if tile.z > 1:
        return quadtree.encode(*list(reversed(mercantile.ul(*tile))), precision=tile.z)
    else:
        return ""
Exemplo n.º 37
0
    meta.update(
        driver='GTiff',
        dtype=rasterio.uint8,
        compress="deflate",
        predictor=1,
        nodata=None,
        tiled=True,
        sparse_ok=True,
        blockxsize=DST_BLOCK_SIZE,
        blockysize=DST_BLOCK_SIZE,
        height=DST_TILE_HEIGHT,
        width=DST_TILE_WIDTH,
    )

    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(*mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(*mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    meta["affine"] = src.window_transform(window)

    ls = LightSource()
    hs = ls.hillshade(data,
        dx=dx,
        dy=dy,
    )
    hs = (255.0 * hs).astype(np.uint8)

    with rasterio.open("windowed.tif", "w", **meta) as dst:
        # ignore the border pixels when writing
        dst.write(hs[BUFFER:-BUFFER, BUFFER:-BUFFER], 1)
Exemplo n.º 38
0
def tile2degree(xtile, ytile, zoom):
    n = 2.0**zoom
    lng = xtile / n * 360.0 - 180.0
    lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
    lat = math.degrees(lat_rad)
    return (lng, lat)


zoom = 22
# chongqing
lng, lat = 106.516034, 29.543124
print(lng, lat)
tile = mercantile.tile(lng, lat, zoom)
print(tile)
print(mercantile.ul(*tile))
box = mercantile.bounds(*tile)
print(box)
distance = great_circle((lat, box.west), (lat, box.east))
print(distance.meters, 'm')
distance = great_circle((box.north, lng), (box.south, lng))
print(distance.meters, 'm')

# beijing
lng, lat = 116.324662, 39.961028
xtile, ytile = degree2tile(lng, lat, zoom)
print(lng, lat)
print(xtile, ytile)
print(tile2degree(xtile, ytile, zoom))
box = mercantile.bounds(xtile, ytile, zoom)
print(box)
Exemplo n.º 39
0
def _get_buffered_bounds(minlon, minlat, maxlon, maxlat, zoom=18, classic=True):
    """
    minlon, minlat, maxlon, maxlat @float : Bbox limits;
    zoon @integer : Square tile zoom level or hexagonal tile resolution;
    classic @boolean : Whether to use classic square tiles or Uber H3 hexagonal ones.

    Returns the bbox limits that fits to the tiles touched by the bbox area introduced.
    In this way you are sure to fetch all the inolved points.
    """

    resolution = zoom
    if classic:
        # resolution = zoom
        ultile = mt.tile(minlon, maxlat, zoom)
        left, top = mt.ul(*ultile)
        rbtile = mt.tile(maxlon, minlat, zoom)
        brtile = lambda x, y, z: (x+1, y+1, z)
        right, bottom = mt.ul(*brtile(*rbtile))
        # get_tile = lambda lon, lat: mt.tile(lon, lat, zoom)
    else:
        # ultile = h3.geo_to_h3(maxlat, minlon, zoom)
        # resolution = min(12, zoom)

        ultile = h3.geo_to_h3(maxlat, minlon, resolution)
        ulboundary = h3.h3_to_geo_boundary(ultile)

        P1 = Point(ulboundary[0][::-1])
        P3 = Point(ulboundary[3][::-1])

        P1_3857 = transform(transformer.transform, P1)
        P3_3857 = transform(transformer.transform, P3)

        buffer = P1_3857.distance(P3_3857)

        ul_3857_ = transform(transformer.transform, Point((minlon, maxlat,)))

        ul_3857 = translate(ul_3857_, -buffer, buffer)

        br_3857_ = transform(transformer.transform, Point((maxlon, minlat,)))

        br_3857 = translate(br_3857_, buffer, -buffer)

        left, top = to3857(*ul_3857.coords[0], inverse=True)
        right, bottom = to3857(*br_3857.coords[0], inverse=True)

        # import pdb; pdb.set_trace()
        #
        # bltile = h3.geo_to_h3(minlat, minlon, resolution)
        # blboundary = h3.h3_to_geo_boundary(bltile)
        #
        # brtile = h3.geo_to_h3(minlat, maxlon, resolution)
        # brboundary = h3.h3_to_geo_boundary(brtile)
        #
        # urtile = h3.geo_to_h3(maxlat, maxlon, resolution)
        # urboundary = h3.h3_to_geo_boundary(urtile)
        #
        # lats, lons = zip(*chain(ulboundary, brboundary, blboundary, urboundary))
        # left, right = min(lons), max(lons)
        # top, bottom = max(lats), min(lats)

    return left, bottom, right, top, resolution,
Exemplo n.º 40
0
def process_tile(tile):
    """Process a single MBTiles tile

    Parameters
    ----------
    tile : mercantile.Tile

    Returns
    -------

    tile : mercantile.Tile
        The input tile.
    bytes : bytearray
        Image bytes corresponding to the tile.

    """
    global base_kwds, resampling, src

    # Get the bounds of the tile.
    ulx, uly = mercantile.xy(
        *mercantile.ul(tile.x, tile.y, tile.z))
    lrx, lry = mercantile.xy(
        *mercantile.ul(tile.x + 1, tile.y + 1, tile.z))

    kwds = base_kwds.copy()
    kwds['transform'] = transform_from_bounds(ulx, lry, lrx, uly,
                                              kwds['width'], kwds['height'])
    src_nodata = kwds.pop('src_nodata', None)
    dst_nodata = kwds.pop('dst_nodata', None)

    warnings.simplefilter('ignore')

    with MemoryFile() as memfile:

        with memfile.open(**kwds) as tmp:

            # determine window of source raster corresponding to the tile
            # image, with small buffer at edges
            try:
                west, south, east, north = transform_bounds(TILES_CRS, src.crs, ulx, lry, lrx, uly)
                tile_window = window_from_bounds(west, south, east, north, transform=src.transform)
                adjusted_tile_window = Window(
                    tile_window.col_off - 1, tile_window.row_off - 1,
                    tile_window.width + 2, tile_window.height + 2)
                tile_window = adjusted_tile_window.round_offsets().round_shape()

                # if no data in window, skip processing the tile
                if not src.read_masks(1, window=tile_window).any():
                    return tile, None

            except ValueError:
                log.info("Tile %r will not be skipped, even if empty. This is harmless.", tile)

            reproject(rasterio.band(src, tmp.indexes),
                      rasterio.band(tmp, tmp.indexes),
                      src_nodata=src_nodata,
                      dst_nodata=dst_nodata,
                      num_threads=1,
                      resampling=resampling)

        return tile, memfile.read()
Exemplo n.º 41
0
def tile2degree(xtile, ytile, zoom):
    n = 2.0 ** zoom
    lng = xtile / n * 360.0 - 180.0
    lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
    lat = math.degrees(lat_rad)
    return (lng, lat)


zoom = 22
# chongqing
lng, lat = 106.516034, 29.543124
print lng, lat
tile = mercantile.tile(lng, lat, zoom)
print tile
print mercantile.ul(*tile)
box = mercantile.bounds(*tile)
print box
distance = great_circle((lat, box.west), (lat, box.east))
print distance.meters, 'm'
distance = great_circle((box.north, lng), (box.south, lng))
print distance.meters, 'm'

# beijing
lng, lat = 116.324662, 39.961028
xtile, ytile = degree2tile(lng, lat, zoom)
print lng, lat
print xtile, ytile
print tile2degree(xtile, ytile, zoom)
box = mercantile.bounds(xtile, ytile, zoom)
print box
Exemplo n.º 42
0
    # https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/get-a-static-map 
    # https://discourse.metabase.com/t/satellite-map/7969
    # https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/imagery-metadata

    count = 0

    for i in range(meta_data["begin_x"],meta_data["end_x"]+1):
        for j in range(meta_data["begin_y"], meta_data["end_y"]+1):

            # Fetching the map-tile for satellite image
            # im_s = ts.tile_as_image(i,j,meta_data["zoom_level"])

            print("The current count : ",count)

            # Finding the lat long
            co_ordinates = mercantile.ul(i, j, meta_data["zoom_level"])
            print(co_ordinates.lng , co_ordinates.lat)

            # Storing the data
            my_data["Sector"].append("sector"+str(count))
            my_data["Lat"].append(co_ordinates.lat)
            my_data["Long"].append(co_ordinates.lng)
            my_data["Name"].append(getName(co_ordinates.lat, co_ordinates.lng))
            my_data["Greenery"].append(0)


            # Saving the images/satellite
            # path_s = os.path.join("images","roadmap","sector"+str(count)+".png")
            # im_s.save(path_s)

Exemplo n.º 43
0
def create_overview_cogs(
    mosaic_path: str,
    output_profile: Dict,
    prefix: str = "mosaic_ovr",
    max_overview_level: int = 6,
    method: str = "first",
    config: Dict = None,
    threads=1,
    in_memory: bool = True,
) -> None:
    """
    Create Low resolution mosaic image from a mosaicJSON.

    The output will be a web optimized COG with bounds matching the mosaicJSON bounds and
    with its resolution matching the mosaic MinZoom - 1.

    Attributes
    ----------
    mosaic_path : str, required
        Mosaic definition path.
    output_profile : dict, required
    prefix : str
    max_overview_level : int
    method: str, optional
        pixel_selection method name (default is 'first').
    config : dict
        Rasterio Env options.
    threads: int, optional
        maximum number of threads to use (default is 1).
    in_memory: bool, optional
        Force COG creation in memory (default is True).

    """
    pixel_method = PIXSEL_METHODS[method]

    with MosaicBackend(mosaic_path) as mosaic:
        base_zoom = mosaic.metadata["minzoom"] - 1
        mosaic_quadkey_zoom = mosaic.quadkey_zoom
        bounds = mosaic.metadata["bounds"]
        mosaic_quadkeys = set(mosaic._quadkeys)

        # Select a random quakey/asset and get dataset info
        tile = mercantile.quadkey_to_tile(random.sample(mosaic_quadkeys, 1)[0])
        assets = mosaic.assets_for_tile(*tile)
        info = _get_info(assets[0])

        extrema = tile_extrema(bounds, base_zoom)
        tilesize = 256
        resolution = _meters_per_pixel(base_zoom, 0, tilesize=tilesize)

        # Create multiples files if coverage is too big
        extremas = _split_extrema(extrema, max_ovr=max_overview_level)
        for ix, extrema in enumerate(extremas):
            click.echo(f"Part {1 + ix}/{len(extremas)}", err=True)
            output_path = f"{prefix}_{ix}.tif"

            blocks = list(_get_blocks(extrema, tilesize))
            random.shuffle(blocks)

            width = (extrema["x"]["max"] - extrema["x"]["min"]) * tilesize
            height = (extrema["y"]["max"] - extrema["y"]["min"]) * tilesize
            w, n = mercantile.xy(*mercantile.ul(
                extrema["x"]["min"], extrema["y"]["min"], base_zoom))

            params = dict(
                driver="GTiff",
                dtype=info["dtype"],
                count=len(info["band_descriptions"]),
                width=width,
                height=height,
                crs="epsg:3857",
                transform=Affine(resolution, 0, w, 0, -resolution, n),
                nodata=info["nodata_value"],
            )
            params.update(**output_profile)

            config = config or {}
            with rasterio.Env(**config):
                with ExitStack() as ctx:
                    if in_memory:
                        tmpfile = ctx.enter_context(MemoryFile())
                        tmp_dst = ctx.enter_context(tmpfile.open(**params))
                    else:
                        tmpfile = ctx.enter_context(
                            TemporaryRasterFile(output_path))
                        tmp_dst = ctx.enter_context(
                            rasterio.open(tmpfile.name, "w", **params))

                    def _get_tile(wind):
                        idx, window = wind
                        x = extrema["x"]["min"] + idx[1]
                        y = extrema["y"]["min"] + idx[0]
                        t = mercantile.Tile(x, y, base_zoom)

                        kds = set(find_quadkeys(t, mosaic_quadkey_zoom))
                        if not mosaic_quadkeys.intersection(kds):
                            return window, None, None

                        try:
                            (tile, mask), _ = mosaic.tile(
                                t.x,
                                t.y,
                                t.z,
                                tilesize=tilesize,
                                pixel_selection=pixel_method(),
                            )
                        except NoAssetFoundError:
                            return window, None, None

                        return window, tile, mask

                    with futures.ThreadPoolExecutor(
                            max_workers=threads) as executor:
                        future_work = [
                            executor.submit(_get_tile, item) for item in blocks
                        ]
                        with click.progressbar(
                                futures.as_completed(future_work),
                                length=len(future_work),
                                show_percent=True,
                                label="Loading tiles",
                        ) as future:
                            for res in future:
                                pass

                    for f in _filter_futures(future_work):
                        window, tile, mask = f
                        if tile is None:
                            continue

                        tmp_dst.write(tile, window=window)
                        if info["nodata_type"] == "Mask":
                            tmp_dst.write_mask(mask.astype("uint8"),
                                               window=window)

                    min_tile_size = tilesize = min(
                        int(output_profile["blockxsize"]),
                        int(output_profile["blockysize"]),
                    )
                    overview_level = get_maximum_overview_level(
                        tmp_dst.width, tmp_dst.height, minsize=min_tile_size)
                    overviews = [2**j for j in range(1, overview_level + 1)]
                    tmp_dst.build_overviews(overviews)
                    copy(tmp_dst,
                         output_path,
                         copy_src_overviews=True,
                         **params)
Exemplo n.º 44
0
    def to_mbtiles(self,
                   filename,
                   zoom=None,
                   tile_bounds=False,
                   drop_empty=False):
        """
        Export tile package to mbtiles v1.1 file, optionally limited to zoom
        levels.  If filename exists, it will be overwritten.  If filename
        does not include the suffix '.mbtiles' it will be added.

        Parameters
        ----------
        filename: string
            name of mbtiles file
        zoom: int or list-like of ints, default: None (all tiles exported)
            zoom levels to export to mbtiles
        tile_bounds: bool
            if True, will use the tile bounds of the highest zoom level exported to determine tileset bounds
        drop_empty: bool, default False
            if True, tiles that are empty will not be output
        """

        if self.format.lower() == "mixed":
            raise ValueError(
                "Mixed format tiles are not supported for export to mbtiles")

        if not filename.endswith(".mbtiles"):
            filename = "{0}.mbtiles".format(filename)

        with MBtiles(filename, "w") as mbtiles:
            if zoom is None:
                zoom = self.zoom_levels
            elif isinstance(zoom, int):
                zoom = [zoom]

            zoom = list(zoom)
            zoom.sort()

            tiles = (tile for tile in self.read_tiles(zoom, flip_y=True)
                     if not (drop_empty and hashlib.sha1(
                         tile.data).hexdigest() in EMPTY_TILES))

            mbtiles.write_tiles(tiles)

            if tile_bounds:
                # Calculate bounds based on maximum zoom to be exported
                highest_zoom = zoom[-1]
                min_row, max_row = mbtiles.row_range(highest_zoom)
                min_col, max_col = mbtiles.col_range(highest_zoom)

                # get upper left coordinate
                xmin, ymax = mercantile.ul(min_col, min_row, highest_zoom)

                # get bottom right coordinate
                # since we are using ul(), we need to go 1 tile beyond the range to get the right side of the
                # tiles we have
                xmax, ymin = mercantile.ul(max_col + 1, max_row + 1,
                                           highest_zoom)

                bounds = (xmin, ymin, xmax, ymax)

            else:
                bounds = self.bounds

            # Center zoom level is middle zoom level
            center = "{0:4f},{1:4f},{2}".format(
                bounds[0] + (bounds[2] - bounds[0]) / 2.0,
                bounds[1] + (bounds[3] - bounds[1]) / 2.0,
                (zoom[0] + zoom[-1]) // 2,
            )

            mbtiles.meta.update({
                "name":
                self.name,
                "description":
                self.summary,  # not description, which is optional
                "version":
                self.version,
                "attribution":
                self.attribution,
                "tags":
                self.tags,
                "credits":
                self.credits,
                "use_constraints":
                self.use_constraints,
                "type":
                "overlay",
                "format":
                self.format.lower().replace("jpeg", "jpg")[:3],
                "bounds":
                ",".join("{0:4f}".format(v) for v in bounds),
                "center":
                center,
                "minzoom":
                zoom[0],
                "maxzoom":
                zoom[-1],
                "legend":
                json.dumps(self.legend) if self.legend else "",
            })