Design software exports a 3D model as a KML Placemark holding a <MultiGeometry> of the model's facets. The importer treats every facet as a mapped area, so one modelled object becomes hundreds of features. Two such files on one production record account for 136,591 of its 136,769 features.
A facet of a 3D model is not a boundary. The system should say so and skip those placemarks, the way it already does for a map image, rather than importing a structure model's triangles as areas of interest.
The file is mixed, so file-level detection is not an option
These files are not wholly models. Grouping one of them by its top-level folders:
| Folder |
Placemarks |
Parts each |
Contents |
Degenerate |
| 0 |
23 |
1.0 |
points only |
0.0% |
| 1 |
1,183 |
64.4 |
75,407 polygons, plus lines and points |
39.4% |
| 2 |
136 |
1.0 |
points only |
0.0% |
| 3 |
1,043 |
72.9 |
the same model, nested |
39.4% |
| 4 |
27 |
1.0 |
points only |
0.0% |
186 single-point placemarks across three folders are ordinary survey locations, and are very likely the thing the submitter meant to send. They sit beside two folders holding the model.
Any rule that acts on the file — an exporter's marker asset, the filename, a naming convention — discards those 186 legitimate placemarks along with the mesh. That is a correctness problem rather than a tuning one, and it is what forces the test to be per-placemark. The cheaper file-level signals described below cannot replace it.
What distinguishes a model from geometry that simply is not clamped to the ground
The signal is plan-view degeneracy: a 3D model has walls, and a wall projects to zero area when flattened. A mapped area never does, however high off the ground it sits.
Polygon parts whose plan-view area falls at or below each threshold:
| File |
Parts |
≤0 m² |
≤1e-6 |
≤1e-3 |
≤0.01 |
≤1 m² |
| CAD structure model |
75,407 |
39.4% |
39.4% |
39.4% |
91.3% |
99.8% |
| CAD structure model, second file |
59,004 |
40.6% |
40.6% |
40.6% |
91.2% |
99.6% |
| Conceptual route centrelines |
223 |
0.0% |
0.0% |
0.0% |
0.0% |
0.0% |
| Boundary polygon |
2 |
0.0% |
0.0% |
0.0% |
0.0% |
0.0% |
Exactly-zero area is the robust form of the test: around 40% of a model's facets are precisely degenerate, and the figure is stable from 0 through 1e-3, so it does not depend on picking a tolerance. The legitimate files score 0.0% at every threshold up to a square metre, so the margin is wide rather than marginal.
Altitude is not the signal. Both models carry non-zero altitudes, but so does any geometry a submitter drew without clamping it to the ground, and a polygon floating at 500 m is still a real area in plan view. Testing altitude produces false positives exactly where degeneracy produces none.
Corroborating, and individually insufficient:
| File |
Parts per Placemark |
Vertices per part |
| CAD structure model |
102.7 |
4.68 |
| CAD structure model, second file |
64.8 |
4.32 |
| CAD model exported as lines |
228.8 |
5.03 |
| Conceptual route centrelines |
1.0 |
12.5 – 28.6 |
| Boundary polygon |
1.0 |
926.00 |
Parts per Placemark separates cleanly here but would misfire on its own: a submitter can legitimately put two hundred disjoint cutblocks in one Placemark, and those score 0% degenerate. Vertices per part is the same story from the other side — mesh facets are triangles and quads, real boundaries are not four-vertex — but a genuinely coarse polygon exists. Degeneracy is what separates them; these two corroborate it.
Provenance: cheaper, and available earlier, but it can only inform
The archives announce what produced them. The three model files each carry a marker image asset belonging to a transmission-line design package (plsp.gif), which the legitimate file does not, and their documents carry folder names in that exporter's structure-numbering convention and a <name> holding a file:// anchor to a .xyz model. Worth recording that this was the cheaper signal and was visible in the first archive listing, before any geometry was measured.
It is not a substitute, for three reasons. It is file-level, and the section above shows the file is mixed. It identifies one vendor's exporter, so a mesh from a different CAD package carries none of it. And a legitimately centreline-only export from that same exporter would carry the markers with nothing to skip.
Note also that the atom:link naming the authoring application is not a discriminator: every file here names Google Earth Pro, including the legitimate one.
So: provenance flags the file, geometry decides the placemark. Provenance is confident, cheap and non-exhaustive; the geometric test is correctly scoped and heuristic. Each covers the other's weakness.
Why this is worth doing beyond the files themselves
Detection is a prerequisite for #68 landing cleanly.
That issue groups a Placemark's parts into one feature. For legitimate multipart geometry that is lossless — disjoint parts parse as a valid MultiPolygon, are never repaired, and lose no vertices:
two disjoint parcels valid=true vertices 10 -> 10 MultiPolygon
three disjoint parcels valid=true vertices 15 -> 15 MultiPolygon
two overlapping valid=false vertices 10 -> 9 Polygon
Only overlapping mesh facets are invalid, and repairing them dissolves the mesh into its footprint. So #68's mesh-versus-footprint question exists only because models are imported as geometry at all. With detection in place, grouping is what it appears to be: the same shapes in fewer rows, with no geometry change.
Handling: the same shape as a map image
Importers::KML#kml_document already runs a Nokogiri pre-pass that removes NetworkLinks and overlays and records a warning naming what was skipped, which reaches the user through feature_update_warnings:
Skipped 1 map image: […]. A map image is a picture laid over the map, not a marked area, so there is no boundary to import from it.
A CAD model is the same category of mistake — a file that is not a boundary, uploaded where a boundary was expected — so it should reuse that machinery and that voice rather than introduce a mechanism. The argument for skipping rather than collapsing: the submitter is told to send a boundary, instead of the system silently inventing one from a drill rig's outline.
Scoring is cheap enough to sit in that pre-pass. The plan-view area of a ring is a shoelace sum over its coordinates, so it needs no database: scoring all 75,407 polygons of a 33.8 MB file takes 1.59s in Ruby.
Two things to settle before any of this gates an upload
1. The thresholds are not established. Five files from two records show the signals separate; they do not tell us where to cut.
A fleet-wide sweep should score every existing spatial file across deployments. Splitting those scores by whether the file carries exporter markers turns it from threshold-guessing into calibration against known positives, and it answers three questions rather than one:
- The degeneracy distribution, split by provenance. Thresholds come off the observed distribution of marker-carrying files against everything else, rather than off two clusters.
- How many mesh-like files carry no marker. This is the number that says whether provenance is worth encoding at all. If it is near zero, the cheap signal covers the fleet and the geometric test is a backstop; if it is large, the geometric test is doing the real work and provenance is a convenience.
- The false-positive check. Whether any file that is unambiguously a boundary scores high enough to be caught, which is the risk that matters most since this can refuse a submitter's upload.
That sweep has not been run — it is a new scope of production access across 38 deployments and needs authorisation first. It is the identified next step, and it should happen before a rule rejects anything.
2. The line case is much weaker. A model exported as lines scores 31.4% zero-length parts against 0.0% for real centrelines — a real separation, but nothing like the polygon case, and measured against a length tolerance rather than exact zero. A line-dominant export sits closest to any threshold and is the case most likely to be misclassified in either direction. A deployment is carrying one of these now.
Whatever the sweep shows, a misclassification should be recoverable: a warning a submitter can act on, and an override for staff, rather than a silent refusal.
🤖 Generated with Claude Code
https://claude.ai/code/session_012b7n8NbLAd6s7c3atii4Mv
Design software exports a 3D model as a KML Placemark holding a
<MultiGeometry>of the model's facets. The importer treats every facet as a mapped area, so one modelled object becomes hundreds of features. Two such files on one production record account for 136,591 of its 136,769 features.A facet of a 3D model is not a boundary. The system should say so and skip those placemarks, the way it already does for a map image, rather than importing a structure model's triangles as areas of interest.
The file is mixed, so file-level detection is not an option
These files are not wholly models. Grouping one of them by its top-level folders:
186 single-point placemarks across three folders are ordinary survey locations, and are very likely the thing the submitter meant to send. They sit beside two folders holding the model.
Any rule that acts on the file — an exporter's marker asset, the filename, a naming convention — discards those 186 legitimate placemarks along with the mesh. That is a correctness problem rather than a tuning one, and it is what forces the test to be per-placemark. The cheaper file-level signals described below cannot replace it.
What distinguishes a model from geometry that simply is not clamped to the ground
The signal is plan-view degeneracy: a 3D model has walls, and a wall projects to zero area when flattened. A mapped area never does, however high off the ground it sits.
Polygon parts whose plan-view area falls at or below each threshold:
Exactly-zero area is the robust form of the test: around 40% of a model's facets are precisely degenerate, and the figure is stable from 0 through 1e-3, so it does not depend on picking a tolerance. The legitimate files score 0.0% at every threshold up to a square metre, so the margin is wide rather than marginal.
Altitude is not the signal. Both models carry non-zero altitudes, but so does any geometry a submitter drew without clamping it to the ground, and a polygon floating at 500 m is still a real area in plan view. Testing altitude produces false positives exactly where degeneracy produces none.
Corroborating, and individually insufficient:
Parts per Placemark separates cleanly here but would misfire on its own: a submitter can legitimately put two hundred disjoint cutblocks in one Placemark, and those score 0% degenerate. Vertices per part is the same story from the other side — mesh facets are triangles and quads, real boundaries are not four-vertex — but a genuinely coarse polygon exists. Degeneracy is what separates them; these two corroborate it.
Provenance: cheaper, and available earlier, but it can only inform
The archives announce what produced them. The three model files each carry a marker image asset belonging to a transmission-line design package (
plsp.gif), which the legitimate file does not, and their documents carry folder names in that exporter's structure-numbering convention and a<name>holding afile://anchor to a.xyzmodel. Worth recording that this was the cheaper signal and was visible in the first archive listing, before any geometry was measured.It is not a substitute, for three reasons. It is file-level, and the section above shows the file is mixed. It identifies one vendor's exporter, so a mesh from a different CAD package carries none of it. And a legitimately centreline-only export from that same exporter would carry the markers with nothing to skip.
Note also that the
atom:linknaming the authoring application is not a discriminator: every file here names Google Earth Pro, including the legitimate one.So: provenance flags the file, geometry decides the placemark. Provenance is confident, cheap and non-exhaustive; the geometric test is correctly scoped and heuristic. Each covers the other's weakness.
Why this is worth doing beyond the files themselves
Detection is a prerequisite for #68 landing cleanly.
That issue groups a Placemark's parts into one feature. For legitimate multipart geometry that is lossless — disjoint parts parse as a valid MultiPolygon, are never repaired, and lose no vertices:
Only overlapping mesh facets are invalid, and repairing them dissolves the mesh into its footprint. So #68's mesh-versus-footprint question exists only because models are imported as geometry at all. With detection in place, grouping is what it appears to be: the same shapes in fewer rows, with no geometry change.
Handling: the same shape as a map image
Importers::KML#kml_documentalready runs a Nokogiri pre-pass that removes NetworkLinks and overlays and records a warning naming what was skipped, which reaches the user throughfeature_update_warnings:A CAD model is the same category of mistake — a file that is not a boundary, uploaded where a boundary was expected — so it should reuse that machinery and that voice rather than introduce a mechanism. The argument for skipping rather than collapsing: the submitter is told to send a boundary, instead of the system silently inventing one from a drill rig's outline.
Scoring is cheap enough to sit in that pre-pass. The plan-view area of a ring is a shoelace sum over its coordinates, so it needs no database: scoring all 75,407 polygons of a 33.8 MB file takes 1.59s in Ruby.
Two things to settle before any of this gates an upload
1. The thresholds are not established. Five files from two records show the signals separate; they do not tell us where to cut.
A fleet-wide sweep should score every existing spatial file across deployments. Splitting those scores by whether the file carries exporter markers turns it from threshold-guessing into calibration against known positives, and it answers three questions rather than one:
That sweep has not been run — it is a new scope of production access across 38 deployments and needs authorisation first. It is the identified next step, and it should happen before a rule rejects anything.
2. The line case is much weaker. A model exported as lines scores 31.4% zero-length parts against 0.0% for real centrelines — a real separation, but nothing like the polygon case, and measured against a length tolerance rather than exact zero. A line-dominant export sits closest to any threshold and is the case most likely to be misclassified in either direction. A deployment is carrying one of these now.
Whatever the sweep shows, a misclassification should be recoverable: a warning a submitter can act on, and an override for staff, rather than a silent refusal.
🤖 Generated with Claude Code
https://claude.ai/code/session_012b7n8NbLAd6s7c3atii4Mv