@@ -189,19 +189,39 @@ static std::vector<std::pair<S2CellId, bool>> cover_polygon(const std::vector<st
189189 }
190190 }
191191
192+ // Only mark a cell as interior if all its neighbors are also interior.
193+ // This erodes the interior by one cell from the border, avoiding
194+ // false positives from spherical/flat geometry mismatch near edges.
195+ std::unordered_set<uint64_t > safe_interior;
196+ for (uint64_t id : interior_set) {
197+ S2CellId cell (id);
198+ S2CellId neighbors[4 ];
199+ cell.GetEdgeNeighbors (neighbors);
200+ bool all_interior = true ;
201+ for (const auto & n : neighbors) {
202+ if (interior_set.count (n.id ()) == 0 ) {
203+ all_interior = false ;
204+ break ;
205+ }
206+ }
207+ if (all_interior) {
208+ safe_interior.insert (id);
209+ }
210+ }
211+
192212 // Normalize all covering cells to kAdminCellLevel
193213 std::vector<std::pair<S2CellId, bool >> result;
194214 for (const auto & cell : covering.cell_ids ()) {
195215 if (cell.level () <= kAdminCellLevel ) {
196216 auto begin = cell.range_min ().parent (kAdminCellLevel );
197217 auto end = cell.range_max ().parent (kAdminCellLevel );
198218 for (auto c = begin; c != end; c = c.next ()) {
199- result.emplace_back (c, interior_set .count (c.id ()) > 0 );
219+ result.emplace_back (c, safe_interior .count (c.id ()) > 0 );
200220 }
201- result.emplace_back (end, interior_set .count (end.id ()) > 0 );
221+ result.emplace_back (end, safe_interior .count (end.id ()) > 0 );
202222 } else {
203223 auto parent = cell.parent (kAdminCellLevel );
204- result.emplace_back (parent, interior_set .count (parent.id ()) > 0 );
224+ result.emplace_back (parent, safe_interior .count (parent.id ()) > 0 );
205225 }
206226 }
207227
@@ -364,8 +384,9 @@ static void add_addr_point(double lat, double lng, const char* housenumber, cons
364384static void add_admin_polygon (const std::vector<std::pair<double ,double >>& vertices,
365385 const char * name, uint8_t admin_level,
366386 const char * country_code) {
367- // Simplify large polygons
368- auto simplified = simplify_polygon (vertices, 500 );
387+ // Simplify large polygons (proportional to preserve border accuracy)
388+ size_t max_vertices = std::clamp (vertices.size () / 5 , size_t (500 ), size_t (65000 ));
389+ auto simplified = simplify_polygon (vertices, max_vertices);
369390 if (simplified.size () < 3 ) return ;
370391
371392 uint32_t poly_id = static_cast <uint32_t >(admin_polygons.size ());
@@ -471,6 +492,8 @@ class BuildHandler : public osmium::handler::Handler {
471492 const char * country_code = (admin_level == 2 )
472493 ? area.tags ()[" ISO3166-1:alpha2" ]
473494 : nullptr ;
495+ if (admin_level == 2 && !country_code) return ;
496+
474497 // Extract outer ring vertices
475498 for (const auto & outer_ring : area.outer_rings ()) {
476499 std::vector<std::pair<double ,double >> vertices;
0 commit comments