Bash

cat /root/traccar-geocoder/builder/src/build_index.cpp | ssh node3 "cat > /tmp/traccar-geocoder/builder/src/build_index.cpp" && ssh node3 "cd /tmp/traccar-geocoder/build && make -j\$(nproc) 2>&1 | tail -3 && rm -rf /tmp/de-par-final7 && mkdir -p /tmp/de-par-final7 && /tmp/traccar-geocoder/build/build-index /tmp/de-par-final7 ~/pbf/germany.osm.pbf --parallel-admin 2>&1 | grep -E 'polygon|Done|closed way'" 2>&1

Build with micro-polygon filter


[ 50%] Building CXX object CMakeFiles/build-index.dir/src/build_index.cpp.o
[100%] Linking CXX executable build-index
[100%] Built target build-index
  Added 37 admin polygons from closed ways.
  Assembling admin polygons in parallel (40080 relations, 112858 way geometries)...
  Parallel admin assembly complete: 42506 polygon rings from 40080 relations.
Done reading:
  42543 admin polygon rings
Waiting for admin polygon S2 covering to complete...
Admin polygon S2 covering complete (6103 cells).
admin index: 6103 cells, 42543 polygons
Done.


Too aggressive — removed 681 rings (43,187 → 42,506). The 0.01% threshold relative to the largest ring removes legitimate small rings when the relation has one very large ring. Let me use an absolute threshold instead.


Edit

        // Find the largest ring's area
        double max_area = 0;
        for (auto& ring : rings) {
            double a = compute_area(ring);
            if (a > max_area) max_area = a;
        }

        // Remove rings that are < 0.01% of the largest ring's area
        // These are boundary artifacts at shared-way junctions
        if (max_area > 0) {
            double threshold = max_area * 0.0001;
            rings.erase(std::remove_if(rings.begin(), rings.end(),
                [&](const std::vector<std::pair<double,double>>& ring) {
                    return compute_area(ring) < threshold;
                }), rings.end());
        }

        // Remove rings with area below ~5 sq meters (5e-7 sq degrees).
        // These are degenerate boundary artifacts at shared-way junctions.
        // Osmium's assembler either rejects or assigns them differently.
        constexpr double MIN_RING_AREA = 5e-7; // ~5 sq meters at mid-latitudes
        rings.erase(std::remove_if(rings.begin(), rings.end(),
            [&](const std::vector<std::pair<double,double>>& ring) {
                return compute_area(ring) < MIN_RING_AREA;
            }), rings.end());