def test_is_valid_geom_point(geojson_point): """Properly formed GeoJSON Point is valid""" assert is_valid_geom(geojson_point) # Empty coordinates are invalid geojson_point['coordinates'] = [] assert not is_valid_geom(geojson_point)
def test_is_valid_geom_invalid_inputs(): """Improperly formed GeoJSON objects should fail""" assert not is_valid_geom('type') assert not is_valid_geom(['type']) assert not is_valid_geom({'type': 'Invalid'}) # wrong type assert not is_valid_geom({'type': 'Point'}) # Missing coordinates
def test_is_valid_geom_geomcollection(geojson_geomcollection): """Properly formed GeoJSON GeometryCollection is valid""" assert is_valid_geom(geojson_geomcollection) # Empty GeometryCollection is invalid geom = deepcopy(geojson_geomcollection) geom['geometries'] = [] assert not is_valid_geom(geom)
def test_is_valid_geom_multipoint(geojson_multipoint): """Properly formed GeoJSON MultiPoint is valid""" assert is_valid_geom(geojson_multipoint) # Empty iterable is invalid geom = deepcopy(geojson_multipoint) geom['coordinates'] = [] assert not is_valid_geom(geom) # Empty first coordinate is invalid geom = deepcopy(geojson_multipoint) geom['coordinates'] = [[]]
def test_is_valid_geom_line(geojson_line): """Properly formed GeoJSON LineString is valid""" assert is_valid_geom(geojson_line) # Empty iterable is invalid geom = deepcopy(geojson_line) geom['coordinates'] = [] assert not is_valid_geom(geom) # Empty first coordinate is invalid geom = deepcopy(geojson_line) geom['coordinates'] = [[]]
def test_is_valid_geom_ring(geojson_polygon): """Properly formed GeoJSON LinearRing is valid""" geojson_ring = deepcopy(geojson_polygon) geojson_ring['type'] = 'LinearRing' # take first ring from polygon as sample geojson_ring['coordinates'] = geojson_ring['coordinates'][0] assert is_valid_geom(geojson_ring) # Empty iterables are invalid geom = deepcopy(geojson_ring) geom['coordinates'] = [] assert not is_valid_geom(geom) geom = deepcopy(geojson_ring) geom['coordinates'] = [[]] assert not is_valid_geom(geom)
def test_is_valid_geom_polygon(geojson_polygon): """Properly formed GeoJSON Polygon is valid""" assert is_valid_geom(geojson_polygon) # Empty iterables are invalid geom = deepcopy(geojson_polygon) geom['coordinates'] = [] assert not is_valid_geom(geom) geom = deepcopy(geojson_polygon) geom['coordinates'] = [[]] assert not is_valid_geom(geom) # Empty first coordinate is invalid geom = deepcopy(geojson_polygon) geom['coordinates'] = [[[]]] assert not is_valid_geom(geom)
def test_is_valid_geom_multiline(geojson_line): """Properly formed GeoJSON MultiLineString is valid""" assert is_valid_geom(geojson_line) # Empty iterables are invalid geom = deepcopy(geojson_line) geom['coordinates'] = [] assert not is_valid_geom(geom) geom = deepcopy(geojson_line) geom['coordinates'] = [[]] assert not is_valid_geom(geom) # Empty first coordinate is invalid geom = deepcopy(geojson_line) geom['coordinates'] = [[[]]] assert not is_valid_geom(geom)
def build_nuts_border_raster(self): for level in range(0, 4): self.load_nuts_border_shapefile(level=level) in_rst_fn = self.filepath.root_work_path + self.get_layer_fn('dem') if in_rst_fn not in self.raster_metadata: self.load_raster_metadata(in_rst_fn) out_rst_fn = self.filepath.root_work_path + self.get_layer_fn( 'nuts', level=level) self.output_files.append(self.get_layer_fn('nuts', level=level)) with rasterio.open(out_rst_fn, 'w+', **self.raster_metadata[in_rst_fn]) as out_rst: out_rst_data = out_rst.read(1) shapes = ((geom, value) for geom, value in zip( self.nuts_borders[level].geometry, self.nuts_borders[level].shape[0] * [1]) if features.is_valid_geom(geom)) burned = features.rasterize(shapes=shapes, fill=0, out=out_rst_data, transform=out_rst.transform, all_touched=True, merge_alg=MergeAlg.replace) out_rst.write_band(1, burned) shapes = ((geom, value) for geom, value in zip( self.nuts_borders[level].geometry, self.nuts_borders[level].shape[0] * [1]) if features.is_valid_geom(geom)) burned = features.rasterize(shapes=shapes, fill=0, out=out_rst_data, transform=out_rst.transform, all_touched=True, merge_alg=MergeAlg.add) out_rst.write_band(1, burned) return
def create_cutline( src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT], geometry: Dict, geometry_crs: CRS = None, ) -> str: """ Create WKT Polygon Cutline for GDALWarpOptions. Ref: https://gdal.org/api/gdalwarp_cpp.html?highlight=vrt#_CPPv415GDALWarpOptions Args: src_dst (rasterio.io.DatasetReader or rasterio.io.DatasetWriter or rasterio.vrt.WarpedVRT): Rasterio dataset. geometry (dict): GeoJSON feature or GeoJSON geometry. By default the cordinates are considered to be in the dataset CRS. Use `geometry_crs` to set a specific CRS. geometry_crs (rasterio.crs.CRS, optional): Input geometry Coordinate Reference System Returns: str: WKT geometry in form of `POLYGON ((x y, x y, ...))) """ if "geometry" in geometry: geometry = geometry["geometry"] if not is_valid_geom(geometry): raise RioTilerError("Invalid geometry") geom_type = geometry["type"] if geom_type not in ["Polygon", "MultiPolygon"]: raise RioTilerError( "Invalid geometry type: {geom_type}. Should be Polygon or MultiPolygon" ) if geometry_crs: geometry = transform_geom(geometry_crs, src_dst.crs, geometry) polys = [] geom = ( [geometry["coordinates"]] if geom_type == "Polygon" else geometry["coordinates"] ) for p in geom: xs, ys = zip(*coords(p)) src_y, src_x = rowcol(src_dst.transform, xs, ys) src_x = [max(0, min(src_dst.width, x)) for x in src_x] src_y = [max(0, min(src_dst.height, y)) for y in src_y] poly = ", ".join([f"{x} {y}" for x, y in list(zip(src_x, src_y))]) polys.append(f"(({poly}))") str_poly = ",".join(polys) return ( f"POLYGON {str_poly}" if geom_type == "Polygon" else f"MULTIPOLYGON ({str_poly})" )
def validate_features_from_gpkg(gpkg: Union[str, Path], attribute_name: str): """ Validate features in gpkg file :param gpkg: (str or Path) path to gpkg file :param attribute_name: name of the value field representing the required classes in the vector image file """ # TODO: test this with invalid features. invalid_features_list = [] # Validate vector features to burn in the raster image with fiona.open(gpkg, 'r') as src: # TODO: refactor as independent function lst_vector = [vector for vector in src] shapes = lst_ids(list_vector=lst_vector, attr_name=attribute_name) for index, item in enumerate(tqdm([v for vecs in shapes.values() for v in vecs], leave=False, position=1)): # geom must be a valid GeoJSON geometry type and non-empty geom, value = item geom = getattr(geom, '__geo_interface__', None) or geom if not is_valid_geom(geom): if lst_vector[index]["id"] not in invalid_features_list: # ignore if feature is already appended invalid_features_list.append(lst_vector[index]["id"]) return invalid_features_list
def test_is_valid_geo_interface(geojson_point): """Properly formed Point object with geo interface is valid""" assert is_valid_geom(MockGeoInterface(geojson_point))
def test_is_valid_geom_invalid_inputs(geom): """Improperly formed GeoJSON objects should fail""" assert not is_valid_geom(geom)