Source code for rastervision.core.data.vector_transformer.shift_transformer

from typing import TYPE_CHECKING, Optional
import numpy as np

from shapely.ops import transform

from rastervision.core.data.crs_transformer import RasterioCRSTransformer
from rastervision.core.data.utils.geojson import (
    pixel_to_map_coords, map_to_pixel_coords, map_geoms)
from rastervision.core.data.vector_transformer import VectorTransformer

if TYPE_CHECKING:
    from rastervision.core.data import CRSTransformer

METERS_PER_DEGREE = 111319.5
RADIANS_PER_DEGREE = np.pi / 180


[docs]class ShiftTransformer(VectorTransformer): """Shift geometries by some distance specified in meters."""
[docs] def __init__(self, x_shift: float = 0., y_shift: float = 0., round_pixels: bool = True): """Constructor. Args: """ self.x_shift = x_shift self.y_shift = y_shift self.round_pixels = round_pixels
[docs] def transform(self, geojson: dict, crs_transformer: Optional['CRSTransformer'] = None) -> dict: # https://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters # noqa def shift(x, y, z=None): lon, lat = x, y lat_radians = RADIANS_PER_DEGREE * lat dlon = self.x_shift / (METERS_PER_DEGREE * np.cos(lat_radians)) dlat = self.y_shift / METERS_PER_DEGREE return lon + dlon, lat + dlat wgs84_transformer = self.make_wgs84_transformer(crs_transformer) geojson_pixel = geojson geojson_wgs84 = pixel_to_map_coords(geojson_pixel, wgs84_transformer) geojson_wgs84_shifted = map_geoms(lambda g, **kw: transform(shift, g), geojson_wgs84) geojson_pixel_shifted = map_to_pixel_coords(geojson_wgs84_shifted, wgs84_transformer) return geojson_pixel_shifted
[docs] def make_wgs84_transformer(self, crs_transformer: 'CRSTransformer'): wgs84_transformer = RasterioCRSTransformer( transform=crs_transformer.transform, image_crs=crs_transformer.image_crs, map_crs='epsg:4326', round_pixels=self.round_pixels) return wgs84_transformer