Skip to content

Add geofileops to speed test? #1

Description

@theroggy

Hello!

I encountered this repo by coincidence: really interesting excercise.

You might also be interested in having a look at geofileops. At the bottom of the readme of the repo there are also some benchmarks. As you can see, intersection isn't the operation where the most spectacular speed improvements are to be expected because it isn't the "heaviest" spatial operation but...

It works different compared to the tools you already tested because it works file-based rather than in-memory... GPKG has some specific properties that make this possible, so for spatial operations the files should be in GPKG. I've never really looked optimized to get memory usage explicitly low, but because files are not taken in memory even really large files (larger than memory available) should work fine.

For illustration, I wrote a rough "geofileops" version of your test and ran it on my ~desktop: a windows virtual machine with 8 virtual CPU's and 32 GB RAM:

  • Because your inputs are in many files seperate files, they are first merged in a single gpkg file: this took 190 seconds.
  • Then to actually calculate the intersection the load/intersection/save are in one go, and this took 105 seconds.
"""Test the speed of intersection with geofileops."""

import logging
import time
import warnings
from pathlib import Path

import geofileops as gfo

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    warnings.filterwarnings("ignore")

    start = time.time()

    building_cols = [
        "oid",
        "aktualit",
        "gebnutzbez",
        "funktion",
        "anzahlgs",
        "gmdschl",
        "lagebeztxt",
        # "geometry",
    ]
    parcels_cols = [
        "oid", "aktualit", "nutzart", "bez", "flstkennz", # "geometry"
    ]

    alkis_dir = Path("H:/temp/ALKIS")
    buildings_paths = list(alkis_dir.glob("./*/GebauedeBauwerk.shp"))
    parcels_paths = list(alkis_dir.glob("./*/NutzungFlurstueck.shp"))

    buildings_path = alkis_dir / "GebauedeBauwerk.gpkg"
    if not buildings_path.exists():
        for path in buildings_paths:
            gfo.copy_layer(src=path, dst=buildings_path, dst_layer=buildings_path.stem, append=True, create_spatial_index=False)
        gfo.create_spatial_index(buildings_path)

    parcels_path = alkis_dir / "NutzungFlurstueck.gpkg"
    if not parcels_path.exists():
        for path in parcels_paths:
            gfo.copy_layer(src=path, dst=parcels_path, dst_layer=parcels_path.stem, append=True, create_spatial_index=False)
        gfo.create_spatial_index(parcels_path)

    # buildings_gdf = buildings_gdf.drop_duplicates(subset="oid", keep="first")
    # parcels_gdf = parcels_gdf.drop_duplicates(subset="oid", keep="first")
    print(f"geofileops: Prepare data duration: {(time.time() - start):.0f} s.")

    start_intersection = time.time()
    buildings_with_parcels_path = alkis_dir / "buildings_with_parcels.gpkg"
    gfo.intersection(buildings_path, parcels_path, buildings_with_parcels_path, input1_columns=building_cols, input2_columns=parcels_cols)
    print(f"geofileops: Load, intersection, save takes: {(time.time() - start_intersection):.0f} s.")

    print(f"geofileops: Total duration: {(time.time() - start):.0f} s.")

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions