def _get_quadrant_tiles(tile):
    """Return indicies of tiles at one higher zoom (in TMS tiling scheme)"""
    ul = (tile.tms[0] * 2, tile.tms[1] * 2)

    return [Tile.from_tms(ul[0], ul[1], tile.zoom + 1),           # UL
            Tile.from_tms(ul[0], ul[1] + 1, tile.zoom + 1),       # LL
            Tile.from_tms(ul[0] + 1, ul[1], tile.zoom + 1),       # UR
            Tile.from_tms(ul[0] + 1, ul[1] + 1, tile.zoom + 1)]   # LR
Пример #2
0
def get_tiles_bbox(tms_bbox: Tuple[int, int, int, int], zoom: int) -> Tuple[float, float, float, float]:
    # language=rst
    """
    Returns bbox of geo coordinates for tiles from tms_bbox area
    :param tms_bbox: area of the tms coordinates in the form of:
     `(min_x, min_y, max_x, max_y)`
    :param zoom:
    :return: bbox of geo coordinates in the form: `(min_lat, min_lon, max_lat, max_lon)`
    """
    points = Tile.from_tms(*tms_bbox[:2], zoom).bounds + Tile.from_tms(*tms_bbox[2:], zoom).bounds
    latitudes, longitudes = zip(*(p.latitude_longitude for p in points))
    return min(latitudes), min(longitudes), max(latitudes), max(longitudes)
Пример #3
0
    def test_finding_child_tiles(self):
        """Check if 4 correct child tiles can be found from a parent tile."""

        parent_tile = Tile.from_tms(1412, 3520, 17)
        ground_truth = [
            Tile.from_tms(x, y, z)
            for x, y, z in [(2825, 7041, 18), (2825, 7040,
                                               18), (2824, 7041,
                                                     18), (2824, 7040, 18)]
        ]
        children_tiles = _get_quadrant_tiles(parent_tile)
        self.assertCountEqual(ground_truth, children_tiles)
Пример #4
0
def _merge_tiles(path: Union[Path, str], tiles_dir: Union[Path, str],
                 tms_bbox: Tuple[int, int, int, int], zoom: int,
                 tiles_format: ImageFormat) -> None:
    # language=rst
    """
    Merge tiles from `tms_bbox` area from `tiles_dir` with `zoom` zoomlevel and `tiles_format` image format
    in image file with `path` without georeference
    :param path:
    :param tiles_dir:
    :param tms_bbox: area of the tms coordinates in the form of:
     `(min_x, min_y, max_x, max_y)`
    :param zoom:
    :param tiles_format:
    :return:
    """
    min_x, min_y, max_x, max_y = tms_bbox

    rows = list()
    for y in range(max_y, min_y - 1, -1):
        row = list()
        for x in range(min_x, max_x + 1):
            tile_path = get_filename(Tile.from_tms(x, y, zoom), tiles_format,
                                     tiles_dir)
            row.append(cv2.imread(str(tile_path)))

        row_img = cv2.hconcat(row)
        rows.append(row_img)
    data = cv2.vconcat(rows)

    cv2.imwrite(path, data)
Пример #5
0
def test_assert_tms_y(tms_y, zoom):
    tms_x = 0

    with pytest.raises(AssertionError) as assertion_info:
        _ = Tile.from_tms(tms_x=tms_x, tms_y=tms_y, zoom=zoom)

    assert 'TMS Y needs to be a value between 0 and (2^zoom) -1.' in str(
        assertion_info.value)
Пример #6
0
def test_georeference():
    tile = Tile.from_tms(139423, 171197, 18)
    img_path = os.path.join(os.getcwd(), "test", "data", "18_139423_171197.tif")
    m = MarchingSquares.from_file(img_path)
    points = m.find_contour()
    geo_points = georeference(points, tile)
    p = geometry.Polygon(geo_points)
    print(p.wkt)
    assert p.wkt == "POLYGON ((11.46890044212341 48.1641425687818, 11.46890580654145 48.1641425687818, 11.46890580654145 48.16404238298088, 11.46879851818085 48.16404238298088, 11.46879851818085 48.16413899072083, 11.46890044212341 48.16413899072083, 11.46890044212341 48.1641425687818))"
Пример #7
0
def test_roundtrip():
    zoom_level = 18
    t = Tile.from_tms(139423, 171197, zoom_level)
    minx, maxy = t.bounds[0].pixels(zoom_level)
    maxx, miny = t.bounds[1].pixels(zoom_level)
    p = Point.from_pixel(maxx, maxy, zoom=zoom_level)
    mx, my = p.meters
    t2 = Tile.for_meters(mx, my, zoom_level)
    assert t.quad_tree == t2.quad_tree
Пример #8
0
def getTMSBBox(x, y, zoom):
    tile = Tile.from_tms(tms_x=x, tms_y=y, zoom=zoom)
    bounds = tile.bounds
    minLong = bounds[0].longitude
    minLat = bounds[0].latitude
    maxLong = bounds[1].longitude
    maxLat = bounds[1].latitude

    minLong, minLat = pointTo3857(minLong, minLat)
    maxLong, maxLat = pointTo3857(maxLong, maxLat)

    return np.array([minLong, maxLong, minLat, maxLat])
Пример #9
0
def test_predict():
    weights_path = os.path.join(os.getcwd(), "model", "mask_rcnn_osm_0030.h5")
    assert os.path.isfile(weights_path)

    img_path = os.path.join(os.getcwd(), "test", "data",
                            "18_139423_171197.tiff")
    p = Predictor(weights_path)
    polygon_points = p.predict_path(img_path=img_path,
                                    tile=Tile.from_tms(139423, 171197, 18))
    for points in polygon_points:
        p = Polygon(points)
        print(p.wkt)
    assert 1 == 1
Пример #10
0
def get_tile_gen(bbox: Tuple[float, float, float, float], zoom: int) -> Generator[Tile, None, None]:
    # language=rst
    """
    :param bbox: area of the geo coordinates in the form of:
     `(min_lat, min_lon, max_lat, max_lon)`
    :param zoom:
    :return: generator of tiles, which area intersects with bbox area
    """
    min_x, min_y, max_x, max_y = get_bbox_in_tms(bbox, zoom)

    for x in range(min_x, max_x + 1):
        for y in range(min_y, max_y + 1):
            yield Tile.from_tms(x, y, zoom)
Пример #11
0
def get_tile_pyramid(top_tile_dict, max_zoom=18, ret_format='{z}-{x}-{y}'):
    """Get all children of a tile at a specific zoom.

    Parameters:
    ----------
    top_tile_dict: dict
        Tile for which to get children down to some zoom level. 'x', 'y', 'z'
        should be defined keys corresponding to TMS coordinates.
    max_zoom: int
        Zoom at which to terminate file search
    ret_format: str
        Return format for strings

    Returns:
    -------
    tile_inds: list of str
        All tiles at the specified zoom that underly the top tile
    """

    # Initialize queue and add input tile
    stack = LifoQueue()
    stack.put(
        Tile.from_tms(top_tile_dict['x'], top_tile_dict['y'],
                      top_tile_dict['z']))

    # Depth-first search on tile indices
    desired_tiles = []
    while not stack.empty():

        # Pop the top tile in the stack
        temp_tile = stack.get()

        # Check if desired zoom has been reached
        if temp_tile.zoom >= max_zoom:
            # If at max zoom, save tile
            tile_dict = dict(x=temp_tile.tms[0],
                             y=temp_tile.tms[1],
                             z=temp_tile.zoom)
            desired_tiles.append(ret_format.format(**tile_dict))

        # Otherwise, zoom in one increment, find children tiles, add to stack
        else:
            for rt in _get_quadrant_tiles(temp_tile):
                stack.put(rt)

    return desired_tiles
Пример #12
0
def open_tile(filename, outdir='./'):
    """ Open a tile image and assign projection and geotransform """
    img = gippy.GeoImage(filename)
    z, x, y = map(int, img.basename().split('-'))
    tile = Tile.from_tms(tms_x=x, tms_y=y, zoom=z)
    img[0] = (img[0] == 255)
    fout = os.path.join(outdir, img.basename() + '.tif')
    geoimg = img.save(fout, options={'COMPRESS': 'DEFLATE'})
    geoimg.set_srs('EPSG:3857')
    minpt = tile.bounds[0].meters
    maxpt = tile.bounds[1].meters
    affine = np.array(
        [
            minpt[0], (maxpt[0]-minpt[0])/geoimg.xsize(), 0.0,
            abs(minpt[1]), 0.0, -(maxpt[1]-minpt[1])/geoimg.ysize()
        ])
    geoimg.set_affine(affine)
    return geoimg
Пример #13
0
def open_tile(filename, outdir='./'):
    """ Open a tile image and assign projection and geotransform """
    img = gippy.GeoImage(filename)
    z, x, y = map(int, img.basename().split('-'))
    tile = Tile.from_tms(tms_x=x, tms_y=y, zoom=z)
    img[0] = (img[0] == 255)
    fout = os.path.join(outdir, img.basename() + '.tif')
    geoimg = img.save(fout, options={'COMPRESS': 'DEFLATE'})
    geoimg.set_srs('EPSG:3857')
    minpt = tile.bounds[0].meters
    maxpt = tile.bounds[1].meters
    affine = np.array(
        [
            minpt[0], (maxpt[0]-minpt[0])/geoimg.xsize(), 0.0,
            abs(minpt[1]), 0.0, -(maxpt[1]-minpt[1])/geoimg.ysize()
        ])
    geoimg.set_affine(affine)
    return geoimg
def x2bbox(xt_min, xt_max, yt_min, yt_max, zoom=19):
    south = 90.0
    north = -90.0
    east = -180.0
    west = 180.0

    for x in range(xt_min, xt_max + 1):
        for y in range(yt_min, yt_max + 1):
            tile = Tile.from_tms(tms_x=x, tms_y=y, zoom=zoom)
            b = tile.bounds
            for i in range(2):
                lat = b[i].latitude_longitude[0]
                lon = b[i].latitude_longitude[1]
                south = min(south, -lat)
                north = max(north, -lat)
                east = max(east, lon)
                west = min(west, lon)

    return east, west, north, south
Пример #15
0
    def _tiles_from_bbox(bbox, zoom_level):
        """
         * Returns all tiles for the specified bounding box
        """

        if isinstance(bbox, dict):
            point_min = Point.from_latitude_longitude(latitude=bbox['tl'],
                                                      longitude=bbox['tr'])
            point_max = Point.from_latitude_longitude(latitude=bbox['bl'],
                                                      longitude=bbox['br'])
        elif isinstance(bbox, list):
            point_min = Point.from_latitude_longitude(latitude=bbox[1],
                                                      longitude=bbox[0])
            point_max = Point.from_latitude_longitude(latitude=bbox[3],
                                                      longitude=bbox[2])
        else:
            raise RuntimeError("bbox must bei either a dict or a list")
        tile_min = Tile.for_point(point_min, zoom_level)
        tile_max = Tile.for_point(point_max, zoom_level)
        tiles = []
        for x in range(tile_min.tms_x, tile_max.tms_x + 1):
            for y in range(tile_min.tms_y, tile_max.tms_y + 1):
                tiles.append(Tile.from_tms(tms_x=x, tms_y=y, zoom=zoom_level))
        return tiles
Пример #16
0
def test_tile_bounds(tms_x, tms_y, zoom, expected_min, expected_max):
    tile = Tile.from_tms(tms_x=tms_x, tms_y=tms_y, zoom=zoom)
    point_min, point_max = tile.bounds

    assert point_min.latitude_longitude == pytest.approx(expected_min, abs=0.1)
    assert point_max.latitude_longitude == pytest.approx(expected_max, abs=0.1)
Пример #17
0
def test_from_tms(tms, zoom):
    tms_x, tms_y = tms

    tile = Tile.from_tms(tms_x=tms_x, tms_y=tms_y, zoom=zoom)

    assert tile.tms == tms
Пример #18
0
def cog_windowed_read(image_path, tile_ind, chan_inds=(1, ), final_proj=None):
    """Get raster data from a cloud-optimized-geotiff using a tile's bounds.

    Parameters
    ----------
    image_path: str
        COG file path as local file or path to remote image.
    tile_ind: dict or str
        Dictionary with keys `z`, `x`, `y` defined or str in `z-x-y` format.
    chan_inds: tuple of int
        Channel indicies to grab from COG. Usually, `(1)` for L and `(1, 2, 3)`
        for RGB.
    final_proj: str
        Output projection for data if a projection different from the COG is
        needed.

    Returns
    -------
    window_data: np.ndarray
        Array containing data values requested in tile_ind.
    """

    if isinstance(tile_ind, dict):
        tile = Tile.from_tms(tile_ind['x'], tile_ind['y'], tile_ind['z'])
    elif isinstance(tile_ind, str):
        z, x, y = [int(val) for val in tile_ind.split('-')]
        tile = Tile.from_tms(x, y, z)
    else:
        raise ValueError(
            'Could not parse `tile_ind` as string or dict: {}'.format(
                tile_ind))

    with rasterio.open(image_path) as cog_image:

        p1 = Proj({'init': 'epsg:4326'})
        p2 = Proj(**cog_image.crs)

        # Convert tile lat/lon bounds to COG ref frame
        #   (pygeotile bounds are (LL, UR))
        window_bounds = dict()
        window_bounds['west'], window_bounds['north'] = \
            transform(p1, p2, tile.bounds[0].longitude, tile.bounds[1].latitude)
        window_bounds['east'], window_bounds['south'] = \
            transform(p1, p2, tile.bounds[1].longitude, tile.bounds[0].latitude)

        # Get image origin point and resolution from the COG
        tif_bounds = dict(north=cog_image.bounds.top,
                          west=cog_image.bounds.left)
        x_res, y_res = cog_image.transform[0], cog_image.transform[4]

        # Calculate the pixel indices of the window
        top = int((window_bounds['north'] - tif_bounds['north']) / y_res)
        left = int((window_bounds['west'] - tif_bounds['west']) / x_res)
        bottom = int((window_bounds['south'] - tif_bounds['north']) / y_res)
        right = int((window_bounds['east'] - tif_bounds['west']) / x_res)

        window_pixels = ((top, bottom), (left, right))

        # Access the pixels of TIF image
        # XXX Seems to force data to the output shape
        window_data = np.empty((len(chan_inds), 256, 256),
                               cog_image.profile['dtype'])
        for ci in chan_inds:
            cog_image.read(ci,
                           window=window_pixels,
                           out=window_data[ci - 1],
                           boundless=True)

        # If user wants a specific transform, do that now
        if final_proj is not None:
            profile = cog_image.profile
            dst_crs = crs.from_string(final_proj)

            # Calculate the ideal dimensions and transformation in the new crs
            # XXX Possible to define resolution here
            dst_affine, dst_width, dst_height = calculate_default_transform(
                cog_image.crs,
                dst_crs,
                256,
                256,
                left=left,
                bottom=bottom,
                right=right,
                top=top)

            profile.update({
                'crs': dst_crs,
                'transform': dst_affine,
                'affine': dst_affine,
                'width': dst_width,
                'height': dst_height
            })

            # Create an array for the projected window
            window_data_proj = np.empty(
                (len(chan_inds), dst_height, dst_width),
                cog_image.profile['dtype'])
            reproject(source=window_data,
                      src_crs=cog_image.crs,
                      src_transform=cog_image.affine,
                      destination=window_data_proj,
                      dst_transform=dst_affine,
                      dst_crs=dst_crs,
                      resampling=Resampling.nearest)

            return np.moveaxis(window_data_proj, 0, -1)

        return np.moveaxis(window_data, 0, -1)
Пример #19
0
def test_no_assert_tms_y(tms_y, zoom):
    tms_x = 0
    _ = Tile.from_tms(tms_x=tms_x, tms_y=tms_y, zoom=zoom)
    assert "No assertion raise :)"
Пример #20
0
from pygeotile.tile import Tile

tms_x, tms_y, zoom = 134494, 329369, 19
tile = Tile.from_tms(tms_x=tms_x, tms_y=tms_y,
                     zoom=19)  # Tile Map Service (TMS) X Y and zoom

print('QuadTree: ', tile.quad_tree)  # QuadTree:  0302222310303211330
print('Google: ', tile.google)  # Google:  (134494, 194918)