Update des 13-jährigen Imports der swissBOUNDARIES3D-Grenzen

Thanks habi.

We are nearing the end of the year, with other words “its municipality merger time!” :grinning: @Loremo

So any actual conflation/updates will need to wait till swisstopo has caught up with us and the BfS, at least for municipalities that we know are going to change, but having the comparison page running before as @Branko_Kokanovic suggest would likely make sense in any case.

Mein bisher grösstes Changeset:

Entschuldigt die grosse BBox, mein Gedanken dahinter war, alle Änderungen in ein CS zu packen, so dass man es einfach revertieren kann, falls doch nicht gewünscht.

Ich habe einige natural=ridge von den Grenzways entfernt. Habe aber gleichzeitig den originalen Way kopiert und einige Pixel entfernt wieder eingefügt.

@Branko_Kokanovic I’m struggling to get your tool to produce ‘sensible’ output.

Is it OK for you if I pester you with questions about it here, publicly?

I got to run the the tool (on both macOS and Linux), and it successfully queries the Swiss Overpass Instance, but the output doesn’t make sense to me…

Here’s the steps I took:

  • cd ~/Dev && git clone https://gitlab.com/osm-serbia/prostorne-jedinice-import.git
  • Make a conda environment, install python=3.9 and run python -m pip install -r requirements.txt in the repository folder. This sets up everything correctly, I think. [1]
  • mkdir swiss && cd swiss && wget https://data.geo.admin.ch/ch.swisstopo.swissboundaries3d/swissboundaries3d_2025-04/swissboundaries3d_2025-04_2056_5728.shp.zip && unzip *.zip to download the data from swisstopo as Shapefiles.
    Here’s the first insecurity for me: As written in Adapt measure_quality_naselja-swiss.py (!2) · Merge requests · OSM Serbia / prostorne-jedinice-import · GitLab, I’ve converted the .shp-files to .csv-files, but I don’t think that’s necessary…
  • cd .. & python measure_quality_naselja-swiss.py which seems to run just fine and produces error-free output in both the console and in swiss/swiss-measurements.csv

Now, when I look at the produced file (a copy is available here), the “interesting” column area_diff contains only some -1 (for 21 relations not found) and 0 for all the other relations.
This is very different to the file that you’ve sent me a long while ago (and I don’t think that’s because @SimonPoole updated a lot of Gemeindegrenzen in lakes recently).

@Branko_Kokanovic , can you give me some input on what’s going wrong?


  1. There’s a bit more to is, but I’ve documented everything on my machine and will submit PRs once I get a step further. ↩︎

Als ich jetzt durch schon erfasste swisstopo:BFS_NUMMERn durchging, fielen mir die 511 Stück swisstopo:BFS_NUMMER=338 auf.

Ein Teil davon wurde mal korrigiert, hat aber zu einer User-Sperre geführt. Wenn hier kein Widerspruch kommt, halte ich den Kein-Widerspruch hier für eine erfolgte Diskussion und werde die BFS-Nummer 338 auf allen Gebäuden entfernen, OK?

1 Like

No matter how good @SimonPoole updated boundaries, those rounded results are not OK :slight_smile: (it should always be 0.999… or so). I also doubt it is about dependencies. I tried running it, but I cannot find swiss/swissBOUNDARIES3D_1_5_TLM_HOHEITSGEBIET.shp.csv. Can you (privately) send it to me (or link to it)? Other than that (if you don’t want to wait for me), I would take one relation and see geometry (in cadastre and in OSM) and debug from there. I can also take a look (once I can repro it properly)

That’s part of the issue :wink:
The .shp-file can be downloaded from Swisstopo, the .shp.csv-file was made with for i in *.shp; do ogr2ogr -f CSV $i.csv $i -lco GEOMETRY=AS_WKT;done.

I think that the tool can ingest .shp files directly, or does it need the versions converted to .csv?

Just there are no misunderstanding; the import way back simplified the boundaries quite substantially for practical reasons (I didn’t do any work on the import itself btw I was far too much a a newbie, I just organised the permission to use the data).

And naturally the updates over the years didn’t help as particularly retaining old boundaries and the merging will have led to lots of splits in different places (is that even supported?).

Conflating the swisstopo boundaries with the ones present in OSM is a step further down the road.
As far as I understand it, this should be possbile with the tool, we’ll get there whenever we’re there…

At the moment I want to get the report online in a reproducible fashion, so that we might see which boundaries are in most desperate need of fixing/conflating.

1 Like

Ich habe in diesem Changeset bei ca. 500 Gebäuden die mit swisstopo:BFS_NUMMER=338 erfasst waren, diese Nummer (und addr:country=CH) entfernt.
Und die Gebäude teilweise an MOPUBE angepasst sowie so vielen Gebäuden wie möglich die Dachflächendetails nach den swisstopo Bildern erfasst.

2 Likes

Dasselbe habe ich in

  • diesem Changeset für 14 Gebäude mit swisstopo:BFS_NUMMER=333 gemacht…
  • diesem Changeset für die 7 Gebäude (eines davon ein Multipolygon) mit swisstopo:BFS_NUMMER=955 gemacht
  • diesem Changeset für 6 Gebäude mit swisstopo:BFS_NUMMER=332 gemacht
  • diesem Changeset für 2 Gebäude mit swisstopo:BFS_NUMMER=956 gemacht

This was easier than I thought:) It was simple error with projection (isn’t it always :smiley: ). Convert .shp or .csv to EPSG:4326 and it should work. Output for me is something like:

Using 1 threads
Processed 1/2141
Processing settlement Adliswil (bezirk 106)
relations found for swisstopo:BFS_NUMMER=131: 1
polygons found 1
106 Adliswil Adliswil 99.93537298910333 0.0010129728750985652
Processed 2/2141
Processing settlement Rheinwald (bezirk 1851)
relations found for swisstopo:BFS_NUMMER=3714: 1
polygons found 1
1851 Rheinwald Rheinwald 99.96437380963374 0.0006599022761262004
...

I can send you reprojected files, if needed.

Yes, .shp should be OK too!

Additional note - tool writes progress to file swiss-measurements.csv and reads from it when started (to continue where it left). Do not forget to delete this file during testing (I forgot about this now, it left me confused a bit:D)

1 Like

Here’s what I did, mostly just as a note to myself

  • head swiss/*.pjr, leading to
==> swiss/swissBOUNDARIES3D_1_5_TLM_HOHEITSGRENZE.prj <==
PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM"
Using 1 threads
Processed 1/2141
Processing settlement Adliswil (bezirk 106)
relations found for maticni_broj 131: 1
polygons found 1
106 Adliswil Adliswil 99.93528649516497 0.0010175327477582048
Processed 2/2141
Processing settlement Rheinwald (bezirk 1851)
relations found for maticni_broj 3714: 1
polygons found 1
1851 Rheinwald Rheinwald 99.96475327460777 0.0006523222616341042
Processed 3/2141
Processing settlement Grens (bezirk 2228)
relations found for maticni_broj 5722: 1
polygons found 1
2228 Grens Grens 99.58796334039015 0.005415683457102389
  • Go to bed let my computer continue
1 Like

Just to increase visibility (it was mentioned on the SWISS IRC, too): The produced output is now online as a Github Gist.

It immediately lead to questions on why some boundaries were not found, e.g. old merged boundaries duplicating their BFS_NUMMER and boundaries in Liechtenstein, see my post in the Austrian Forum here: Grenzen Liechtenstein

(The work to periodically automatically produce such a report on a VM provided by SOSM is continuing.)

1 Like

@habi could you give us a quick summary what the area_diff and the area_not_shared numbers actually imply/mean? I thought I understood them, but after closer inspection I’m not quite sure any more :slight_smile:

If A is OSM polygon and B is cadastre data, then:

  • area_diff is (A ∩ B) / B,
  • area_not_shared is ((A\B) ∪ (B\A)) / (A∪B)

area_not_shared is very weird way to have IoU where IoU=(A ∩ B) / (A ∪ B) = 1 - area_not_shared. So, just substract 1 and you get familiar IoU. In my defense, when I was crafting these metrics, I didn’t know about IoU, so I just reinvented it…in a convoluted way :slight_smile:

Thanks @Branko_Kokanovic

Here are the slightly changed and explanded lines from @Branko_Kokanovic’s code, where settlement comes from swisstopoBOUNDARIES3D and overpass_settlement is what is mapped in OSM.

  • area_diff = settlement.intersection(overpass_settlement).area / settlement.area, where intersection and area are shapely-functions.

  • and

    a_minus_b = settlement.difference(overpass_settlement)
    b_minus_a = overpass_settlement.difference(settlement)
    a_minus_b_union_b_minus_a = a_minus_b.union(b_minus_a)
    a_union_b = settlement.union(overpass_settlement)
    area_not_shared = a_minus_b_union_b_minus_a.area / a_union_b.area

which is what’s written above, too :slight_smile: