def transform_geometry(geom, crs=wgs84, to_crs=wgs84): """Reprojects a shapely geometry. Parameters ---------- geom : shapely geometry the geometry to transform crs : crs the geometry's crs to_crs : crs the crs into which the geometry must be transformed Returns ------- A reprojected geometry """ from_crs = check_crs(crs) to_crs = check_crs(to_crs) if isinstance(to_crs, pyproj.Proj) and isinstance(from_crs, pyproj.Proj): project = partial(transform_proj, from_crs, to_crs) elif isinstance(to_crs, Grid): project = partial(to_crs.transform, crs=from_crs) else: raise NotImplementedError() return shapely_transform(project, geom)
def reproject_geometry( geom, # type: BaseGeometry source_proj, # type: str dest_proj # type: str ): # type: (...) -> BaseGeometry partial_transform = partial(transform, source_proj, dest_proj) return shapely_transform(partial_transform, geom)
def build_items(index_geom): """ index_geom: fioan readable file (ex, shapefile) Build the STAC items """ with fiona.open(index_geom) as src: src_crs = Proj(src.crs) dest_crs = Proj("WGS84") extent = box(*src.bounds) project = Transformer.from_proj(src_crs, dest_crs) catalog_bbox = shapely_transform(project.transform, extent) # build spatial extent for collection ortho_collection = GeobaseSTAC.get_child("canada_spot_orthoimages") ortho_collection.extent.spatial = SpatialExtent( [list(catalog_bbox.bounds)]) geobase = GeobaseSpotFTP() count = 0 for f in src: feature_out = f.copy() new_coords = transform_geom(src_crs, dest_crs, f["geometry"]["coordinates"]) feature_out["geometry"]["coordinates"] = new_coords name = feature_out["properties"]["NAME"] sensor = SPOT_SENSOR[name[:2]] new_item = create_item(name, feature_out, ortho_collection) for f in geobase.list_contents(name): # Add data to the asset spot_file = Asset(href=f, title=None, media_type="application/zip") file_key = f[-13:-4] # image type new_item.add_asset(file_key, spot_file) # Add the thumbnail asset new_item.add_asset( key="thumbnail", asset=Asset( href=geobase.get_thumbnail(name), title=None, media_type=MediaType.JPEG, ), ) ortho_collection.add_item(new_item) count += 1 print(f"{count}... {new_item.id}")
def transform(self, epsg: int) -> "GeoPolygon": if self.epsg == epsg: raise UserWarning(f'Polygon already in {epsg} EPSG') projection = partial(transform, Proj(init=f'epsg:{self.epsg}'), Proj(init=f'epsg:{epsg}')) return GeoPolygon(shapely_transform(projection, self.polygon), epsg)
def point_buffer(self, lat: float, lng: float, kilometres: float, initial_epsg: int = 4326): aeqd_projection = f'+proj=aeqd +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0' beginning_projection = pyproj.CRS.from_epsg(initial_epsg) transformed_projection = partial(pyproj.transform, pyproj.Proj(aeqd_projection), beginning_projection) buffer_point = Point(0, 0).buffer(kilometres * 1000) # converts distance to metres buffer_polygon = Polygon(shapely_transform(transformed_projection, buffer_point).exterior.coords[:]) return buffer_polygon
def transform(transformer, fp): js = geojson.load(fp) # check type of geojson if js['type'] == 'Feature': js['geometry'] = shapely_transform(transformer, shape(js['geometry'])).__geo_interface__ elif js['type'] == 'FeatureCollection': for feat in js['features']: feat['geometry'] = shapely_transform(transformer, shape(feat['geometry'])).__geo_interface__ elif js['type'] == 'GeometryCollection': for i, geom in enumerate(js['geometries']): js['geometries'][i] = shapely_transform(transformer, shape(geom)).__geo_interface__ else: #point, linestring, polygon, multis, geometry collection js = shapely_transform(transformer, shape(js)).__geo_interface__ output = StringIO() geojson.dump(js, output) output.seek(0) return output
def centroids(self, size: int = 300) -> List[Point]: """ It generates the Centroids of a LineString. It walks the LineString generating centroids every buffer distance passed as parameter until the envelope of the buffer does not intersects twice with the road. This avoids getting envelopes where road finishing inside. Parameters: size (int): the desired size of the image. 300m as default Returns: MultiPoint: MultiPoint generated with all centroids in EPSG:4326 """ _first = 0 centroids = [] wgs84_to_mercator = pyproj.Transformer.from_crs('EPSG:4326', 'EPSG:3857', always_xy=True) mercator_to_wgs84 = pyproj.Transformer.from_crs('EPSG:3857', 'EPSG:4326', always_xy=True) road_3857 = shapely_transform(wgs84_to_mercator.transform, self.path) size_3857 = size / math.cos(math.pi * self.path.centroid.y / 180) distance_3857 = size_3857 / 2 max_distance_3857 = road_3857.length - distance_3857 if size_3857 > road_3857.length: centroids.append( Centroid( shapely_transform(mercator_to_wgs84.transform, road_3857.centroid))) while distance_3857 <= max_distance_3857: centroid_3857 = road_3857.interpolate(distance_3857) centroids.append( Centroid( shapely_transform(mercator_to_wgs84.transform, centroid_3857))) distance_3857 += size_3857 return centroids
def get_poly_area_geo(poly): """ Calculates the area in meters squared of the individual polygon """ minx, miny, maxx, maxy = poly.bounds #reproject polygon to get area reprojected_for_area = Proj( "+proj=aea +lat_1={0} +lat_1={1} +lat_0={2} +lon_0={3}".format( miny, maxy, (miny + maxy) / 2.0, (minx + maxx) / 2.0)) geographic_proj = Proj(init='epsg:4326') project_func = partial(transform, geographic_proj, reprojected_for_area) reprojected_poly = shapely_transform(project_func, poly) return reprojected_poly.area
def get_poly_area_geo(poly): """ Calculates the area in meters squared of the individual polygon """ minx, miny, maxx, maxy = poly.bounds #reproject polygon to get area reprojected_for_area = Proj("+proj=aea +lat_1={0} +lat_1={1} +lat_0={2} +lon_0={3}".format(miny, maxy, (miny+maxy)/2.0, (minx+maxx)/2.0)) geographic_proj = Proj(init='epsg:4326') project_func = partial(transform, geographic_proj, reprojected_for_area) reprojected_poly = shapely_transform(project_func, poly) return reprojected_poly.area
def transform_geopandas(gdf, to_crs=wgs84, inplace=False): """Reprojects a geopandas dataframe. Parameters ---------- gdf : geopandas.DataFrame the dataframe to transform (must have a crs attribute) to_crs : crs the crs into which the dataframe must be transformed inplace : bool the original dataframe will be overwritten (default: False) Returns ------- A projected dataframe """ from_crs = check_crs(gdf.crs) to_crs = check_crs(to_crs) if inplace: out = gdf else: out = gdf.copy() if isinstance(to_crs, pyproj.Proj) and isinstance(from_crs, pyproj.Proj): project = partial(transform_proj, from_crs, to_crs) elif isinstance(to_crs, Grid): project = partial(to_crs.transform, crs=from_crs) elif isinstance(from_crs, Grid): project = partial(from_crs.ij_to_crs, crs=to_crs) else: raise NotImplementedError() # Do the job and set the new attributes result = out.geometry.apply(lambda geom: shapely_transform(project, geom)) result.__class__ = gpd.GeoSeries result.crs = to_crs out.geometry = result out.crs = to_crs out['min_x'] = [g.bounds[0] for g in out.geometry] out['max_x'] = [g.bounds[2] for g in out.geometry] out['min_y'] = [g.bounds[1] for g in out.geometry] out['max_y'] = [g.bounds[3] for g in out.geometry] return out
def transform_geopandas(gdf, to_crs=wgs84, inplace=False): """Reprojects a geopandas dataframe. Parameters ---------- gdf : geopandas.DataFrame the dataframe to transform (must have a crs attribute) to_crs : crs the crs into which the dataframe must be transformed inplace : bool the original dataframe will be overwritten (default: False) Returns ------- A projected dataframe """ from_crs = check_crs(gdf.crs) to_crs = check_crs(to_crs) if inplace: out = gdf else: out = gdf.copy() if isinstance(to_crs, pyproj.Proj) and isinstance(from_crs, pyproj.Proj): project = partial(transform_proj, from_crs, to_crs) elif isinstance(to_crs, Grid): project = partial(to_crs.transform, crs=from_crs) else: raise NotImplementedError() # Do the job and set the new attributes result = out.geometry.apply(lambda geom: shapely_transform(project, geom)) result.__class__ = gpd.GeoSeries result.crs = to_crs out.geometry = result out.crs = to_crs return out
def convert_to_vector_format(crs, output_dir, resolution, input_file, output_crs, url, layer_name): """Convert raster to vector format (GPKG and GeoJSON) File names are based on the raster file name. :const float SMOOTHING_FACTOR: constant used for adjusting smoothing of the result. Factor affects to the size of the smoothing kernel, which is calculated from the smaller side of the result. Final kernel size is rouded value of size * SMOOTHING_FACTOR, so the factor can be interpreted as a proportion of the image size. If the smoothing kernel is lower than 1 pixel or bigger than the smaller side of image, smoothing is skipped. Experimentally good value is 0.03. Value must be between 0 and 1. :const float SIMPLIFICATION_FACTOR: constant used for calculating tolerance for Douglas-Peucker simplification to simplify the result data. Final tolerance is resolution * SIMPLIFICATION_FACTOR. The bigger the factor, the rougher the output. Experimentally good value is 0.3. Value must be positive. :param CRS object crs: Contains information related to CRS :param str output_dir: Path leading to directory where outputs are created :param int resolution: Default resolution of the raster :param str input_file: Path to the binary raster created in algorithm.solve :param str output_crs: Coordinate system to be used for output file :param str url: URL that is added as an attribute :param str layer_name: layer_name that is added as an attribute :return tuple: spatial extent of the data """ dst_layername = input_file.split('/')[-1].rsplit('.', 1)[0] with rasterio.open(input_file, driver='GTiff', mode='r') as src: image = src.read(1) # Smooth output with median filter SMOOTHING_FACTOR = 0.03 smooth_kernel_size = round( min(image.shape) * SMOOTHING_FACTOR ) if smooth_kernel_size > 1 and smooth_kernel_size < min(image.shape): pixels = scipy.ndimage.median_filter(image, (smooth_kernel_size, smooth_kernel_size), mode='constant') else: pixels = image # Mask value is 1, which means data mask = pixels == 1 # Tolerance for douglas peucker simplification SIMPLIFICATION_FACTOR = 0.3 if SIMPLIFICATION_FACTOR > 0: tol = resolution / SIMPLIFICATION_FACTOR else: tol = 0 # Transformation initialization if crs != output_crs: tr = Transformer.from_crs(crs, output_crs, always_xy=is_first_axis_east(output_crs)).transform else: tr = None # Transformation and convertion from shapely shape to geojson-like object for fiona. feats = [] feats_original_crs = [] for (s, v) in shapes(pixels, mask=mask, transform=src.transform): shp = shape(s).simplify(tol) feats_original_crs.append(shp) if tr: shp = shapely_transform(tr, shp) feats.append(shp) # Create multipolygon and add properties to it. feature = MultiPolygon(feats) result = {'geometry': mapping(feature), 'properties': {'resolution': resolution, 'url': url, 'layer_name': layer_name}} results_gpkg = ({'geometry': mapping(f), 'properties': {}} for f in feats) # Geojson output with fiona.open( output_dir + dst_layername + ".geojson", 'w', driver="GeoJSON", crs=fiona.crs.from_string(output_crs.to_proj4()) if output_crs else src.crs, schema={'geometry': feature.type, 'properties': {'resolution': 'int', 'url': 'str', 'layer_name': 'str'}}, VALIDATE_OPEN_OPTIONS=False) as dst: # GPKG output with fiona.open( output_dir + dst_layername + ".gpkg", 'w', driver="GPKG", crs=fiona.crs.from_string(output_crs.to_proj4()) if output_crs else src.crs, schema={'geometry': 'Polygon', 'properties': {}}) as gpkg_dst: # Write datasets if len(feats) > 0: dst.write(result) gpkg_dst.writerecords(results_gpkg) return MultiPolygon(feats_original_crs).bounds
def to_webmercator(pol): return shapely_transform(webmercator_project, pol)
projection='merc', ellps='WGS84', lat_0=60.789785, lon_0=-145.996703, llcrnrlon=-169.49, llcrnrlat=49.4, urcrnrlon=-116.4, urcrnrlat=71.63) water = 'lightskyblue' earth = 'cornsilk' coast = mm.drawcoastlines() continents = mm.fillcontinents(color=earth, lake_color=water) bound = mm.drawmapboundary(fill_color=water) countries = mm.drawcountries() #merid = mm.drawmeridians(np.arange(-180, 180, 2), labels=[False, False, False, True]) #parall = mm.drawparallels(np.arange(0, 80), labels=[True, True, False, False]) juneau_lon, juneau_lat = -134.4167, 58.3 x, y = mm(juneau_lon, juneau_lat) juneau = mm.scatter(x, y, 80, label="Juneau", color='red', zorder=10) # construct a collection of polygon patches from shape points district_patches = [] for district_shape in district_shapes: transformed_points = transform_projection(district_shape.points, '3338') y, x = zip(*transformed_points) poly = Polygon(list(zip(x, y))) mpoly = shapely_transform(mm, poly) district_patches.append(PolygonPatch(mpoly)) ax.add_collection(PatchCollection(district_patches, match_original=True)) plt.show()
def _transform_shapely(self, target, from_proj, to_proj): project = self.get_transformation_function(from_proj, to_proj) return shapely_transform(project, target)