Example #1
0
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
Example #2
0
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
Example #3
0
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')
Example #4
0
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
Example #5
0
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
Example #6
0
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)
Example #7
0
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