def prepare_test_file( path: Path, tmp_dir: Path, suffix: str, crs_epsg: Optional[int] = None) -> Path: # If sufixx the same, copy to tmp_dir, if not, convert new_path = tmp_dir / f"{path.stem}{suffix}" if path.suffix == suffix: gfo.copy(path, new_path) else: gfo.convert(path, new_path) path = new_path # If crs_epsg specified and test input file in wrong crs_epsg, reproject if crs_epsg is not None: input_layerinfo = gfo.get_layerinfo(path) assert input_layerinfo.crs is not None if input_layerinfo.crs.to_epsg() != crs_epsg: new_path = tmp_dir / f"{path.stem}_{crs_epsg}{suffix}" if new_path.exists() is False: test_gdf = gfo.read_file(path) test_gdf = test_gdf.to_crs(crs_epsg) assert isinstance(test_gdf, gpd.GeoDataFrame) gfo.to_file(test_gdf, new_path) path = new_path return path
def test_copy(tmpdir): # Prepare test data + run tests tmp_dir = Path(tmpdir) for suffix in test_helper.get_test_suffix_list(): # If test input file is in wrong format, convert it src = test_helper.prepare_test_file( path=test_helper.TestFiles.polygons_parcels_gpkg, tmp_dir=tmp_dir, suffix=suffix) # Copy to dest file dst = Path(tmpdir) / f"polygons_parcels_output{suffix}" gfo.copy(src, dst) assert src.exists() == True assert dst.exists() == True if suffix == ".shp": assert dst.with_suffix(".shx").exists() == True # Copy to dest dir dst_dir = Path(tmpdir) / "dest_dir" dst_dir.mkdir(parents=True, exist_ok=True) gfo.copy(src, dst_dir) dst = dst_dir / src.name assert src.exists() == True assert dst.exists() == True if suffix == ".shp": assert dst.with_suffix(".shx").exists() == True
def test_execute_sql(tmpdir): # First copy test file to tmpdir src = test_helper.TestFiles.polygons_parcels_gpkg tmppath = Path(tmpdir) / 'polygons_parcels.gpkg' gfo.copy(src, tmppath) ### Test using execute_sql for creating/dropping indexes ### # Create index gfo.execute_sql( path=tmppath, sql_stmt='CREATE INDEX idx_parcels_oidn ON "parcels"("oidn")') # Drop index gfo.execute_sql(path=tmppath, sql_stmt='DROP INDEX idx_parcels_oidn')
def test_update_column(tmpdir): # First copy test file to tmpdir # Now add area column src = test_helper.TestFiles.polygons_parcels_gpkg tmppath = Path(tmpdir) / 'polygons_parcels.gpkg' gfo.copy(src, tmppath) # The area column shouldn't be in the test file yet layerinfo = gfo.get_layerinfo(path=tmppath, layer='parcels') assert 'area' not in layerinfo.columns ### Add + update area column ### #with test_helper.GdalBin(gdal_installation='gdal_default'): gfo.add_column(tmppath, layer='parcels', name='AREA', type='real', expression='ST_area(geom)') gfo.update_column(tmppath, name='AreA', expression='ST_area(geom)') layerinfo = gfo.get_layerinfo(path=tmppath, layer='parcels') assert 'AREA' in layerinfo.columns gdf = gfo.read_file(tmppath) assert round(gdf['AREA'].astype('float')[0], 1) == round(gdf['OPPERVL'].astype('float')[0], 1) ### Update column for rows where area > 5 ### gfo.update_column(tmppath, name="AreA", expression="-1", where="area > 4000") gdf = gfo.read_file(tmppath) gdf_filtered = gdf[gdf["AREA"] == -1] assert len(gdf_filtered) == 20 ### Trying to remove column that doesn't exist should raise ValueError ### assert "not_existing column" not in layerinfo.columns try: gfo.update_column(tmppath, name="not_existing column", expression="ST_area(geom)") exception_raised = False except ValueError: exception_raised = True assert exception_raised is True
def test_cmp(tmpdir): # Prepare test data + run tests tmp_dir = Path(tmpdir) for suffix in test_helper.get_test_suffix_list(): # If test input file is in wrong format, convert it src = test_helper.prepare_test_file( path=test_helper.TestFiles.polygons_parcels_gpkg, tmp_dir=tmp_dir, suffix=suffix) src2 = test_helper.prepare_test_file( path=test_helper.TestFiles.polygons_invalid_geometries_gpkg, tmp_dir=tmp_dir, suffix=suffix) # Copy test file to tmpdir dst = Path(tmpdir) / f"polygons_parcels_output{suffix}" gfo.copy(src, dst) # Now compare source and dst files assert gfo.cmp(src, dst) == True assert gfo.cmp(src2, dst) == False
def test_add_column(tmpdir): # First copy test file to tmpdir # Now add area column src = test_helper.TestFiles.polygons_parcels_gpkg tmppath = Path(tmpdir) / src.name gfo.copy(src, tmppath) # The area column shouldn't be in the test file yet layerinfo = gfo.get_layerinfo(path=tmppath, layer='parcels') assert 'AREA' not in layerinfo.columns ### Add area column ### #with test_helper.GdalBin(gdal_installation='gdal_default'): gfo.add_column(tmppath, layer='parcels', name='AREA', type='real', expression='ST_area(geom)') layerinfo = gfo.get_layerinfo(path=tmppath, layer='parcels') assert 'AREA' in layerinfo.columns gdf = gfo.read_file(tmppath) assert round(gdf['AREA'].astype('float')[0], 1) == round(gdf['OPPERVL'].astype('float')[0], 1) ### Add perimeter column ### #with test_helper.GdalBin(gdal_installation='gdal_default'): gfo.add_column(tmppath, layer='parcels', name='PERIMETER', type=gfo.DataType.REAL, expression='ST_perimeter(geom)') layerinfo = gfo.get_layerinfo(path=tmppath, layer='parcels') assert 'AREA' in layerinfo.columns gdf = gfo.read_file(tmppath) assert round(gdf['AREA'].astype('float')[0], 1) == round(gdf['OPPERVL'].astype('float')[0], 1)
def test_simplify_ext_keep_points_on(tmpdir): #### Test if keep_points_on works properly #### ## First init some stuff ## # Read the test data input_path = test_helper.TestFiles.polygons_simplify_onborder_testcase_gpkg gfo.copy(input_path, tmpdir / input_path.name) input_gdf = gfo.read_file(input_path) # Create geometry where we want the points kept grid_gdf = grid_util.create_grid( total_bounds=(210431.875-1000, 176640.125-1000, 210431.875+1000, 176640.125+1000), nb_columns=2, nb_rows=2, crs='epsg:31370') gfo.to_file(grid_gdf, tmpdir / "grid.gpkg") grid_coords = [tile.exterior.coords for tile in grid_gdf['geometry']] grid_lines_geom = sh_geom.MultiLineString(grid_coords) ## Test rdp (ramer–douglas–peucker) ## # Without keep_points_on, the following point that is on the test data + # on the grid is removed by rdp point_on_input_and_border = sh_geom.Point(210431.875, 176599.375) tolerance_rdp = 0.5 # Determine the number of intersects with the input test data nb_intersects_with_input = len(input_gdf[input_gdf.intersects(point_on_input_and_border)]) assert nb_intersects_with_input > 0 # Test if intersects > 0 assert len(input_gdf[grid_gdf.intersects(point_on_input_and_border)]) > 0 # Without keep_points_on the number of intersections changes simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.RAMER_DOUGLAS_PEUCKER, tolerance=tolerance_rdp)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_rdp{tolerance_rdp}.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) != nb_intersects_with_input # With keep_points_on specified, the number of intersections stays the same simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.RAMER_DOUGLAS_PEUCKER, tolerance=tolerance_rdp, keep_points_on=grid_lines_geom)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_rdp{tolerance_rdp}_keep_points_on.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) == nb_intersects_with_input ## Test vw (visvalingam-whyatt) ## # Without keep_points_on, the following point that is on the test data + # on the grid is removed by vw point_on_input_and_border = sh_geom.Point(210430.125, 176640.125) tolerance_vw = 16*0.25*0.25 # 1m² # Determine the number of intersects with the input test data nb_intersects_with_input = len(input_gdf[input_gdf.intersects(point_on_input_and_border)]) assert nb_intersects_with_input > 0 # Test if intersects > 0 assert len(input_gdf[grid_gdf.intersects(point_on_input_and_border)]) > 0 # Without keep_points_on the number of intersections changes simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.VISVALINGAM_WHYATT, tolerance=tolerance_vw)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_vw{tolerance_vw}.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) != nb_intersects_with_input # With keep_points_on specified, the number of intersections stays the same simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.VISVALINGAM_WHYATT, tolerance=tolerance_vw, keep_points_on=grid_lines_geom)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_vw{tolerance_vw}_keep_points_on.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) == nb_intersects_with_input ## Test lang ## # Without keep_points_on, the following point that is on the test data + # on the grid is removed by lang point_on_input_and_border = sh_geom.Point(210431.875,176606.125) tolerance_lang = 0.25 step_lang = 8 # Determine the number of intersects with the input test data nb_intersects_with_input = len(input_gdf[input_gdf.intersects(point_on_input_and_border)]) assert nb_intersects_with_input > 0 # Test if intersects > 0 assert len(input_gdf[grid_gdf.intersects(point_on_input_and_border)]) > 0 # Without keep_points_on the number of intersections changes simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.LANG, tolerance=tolerance_lang, lookahead=step_lang)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_lang;{tolerance_lang};{step_lang}.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) != nb_intersects_with_input # With keep_points_on specified, the number of intersections stays the same simplified_gdf = input_gdf.copy() # assert to evade pyLance warning assert isinstance(simplified_gdf, gpd.GeoDataFrame) simplified_gdf.geometry = input_gdf.geometry.apply( lambda geom: geometry_util.simplify_ext( geom, algorithm=geometry_util.SimplifyAlgorithm.LANG, tolerance=tolerance_lang, lookahead=step_lang, keep_points_on=grid_lines_geom)) gfo.to_file(simplified_gdf, tmpdir / f"simplified_lang;{tolerance_lang};{step_lang}_keep_points_on.gpkg") assert len(simplified_gdf[simplified_gdf.intersects(point_on_input_and_border)]) == nb_intersects_with_input