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-final9 && mkdir -p /tmp/de-par-final9 && /tmp/traccar-geocoder/build/build-index /tmp/de-par-final9 ~/pbf/germany.osm.pbf --parallel-admin 2>&1 | grep -E 'polygon|Done|closed way|Dedup'" 2>&1

Build with cross-relation deduplication


[ 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)...
  Deduplicated 3509 cross-relation duplicate rings.
  Parallel admin assembly complete: 39676 polygon rings from 40080 relations.
Done reading:
  39713 admin polygon rings
Waiting for admin polygon S2 covering to complete...
Admin polygon S2 covering complete (6103 cells).
Deduplicating...
admin index: 6103 cells, 39713 polygons
Done.


3509 is way too many. The ring key is matching rings that shouldn't match. Let me use the unsimplified ring coordinates directly (not grid-rounded) for exact dedup.


Edit

                        auto ring_key = [](const std::vector<std::pair<double,double>>& verts) -> std::string {
                            std::vector<std::pair<int,int>> grid;
                            for (auto& v : verts) {
                                grid.push_back({(int)(v.first * 1e7 + (v.first >= 0 ? 0.5 : -0.5)),
                                                (int)(v.second * 1e7 + (v.second >= 0 ? 0.5 : -0.5))});
                            }
                            std::sort(grid.begin(), grid.end());
                            std::string key;
                            for (auto& g : grid) {
                                key += std::to_string(g.first) + "," + std::to_string(g.second) + ";";
                            }
                            return key;
                        };

                        // Use exact raw bytes of sorted coordinates as key
                        // Only rings with identical coordinate sets will match
                        auto ring_key = [](const std::vector<std::pair<double,double>>& verts) -> std::string {
                            // Sort by raw coordinate values for order-independent comparison
                            std::vector<std::pair<double,double>> sorted = verts;
                            std::sort(sorted.begin(), sorted.end());
                            std::string key;
                            key.resize(sorted.size() * sizeof(std::pair<double,double>));
                            memcpy(key.data(), sorted.data(), key.size());
                            return key;
                        };