mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 22:32:19 +00:00
Plan KML and KMZ drawing in one pure function, checked against Cesium
src/data/geoImportPlan.js decides what an imported file draws and with what: raised or clamped geometry, rings and holes, rotation near the poles and across 360 degrees, absolute and relative altitudes, draw order, canvas budgets and the vertex and ring limits, with no engine and no DOM. drawImportedFile draws that plan through the globe contract and keeps pin placement, yielding and cancellation. Every limit of the import lives in src/data/geoImportLimits.js with what it protects. scripts/fixtures/geo-import holds 13 files covering those cases, and reference.json what Cesium's own KML and GeoJSON data sources make of them; scripts/qa-geo-import-reference.mjs records it and compares the plan with it. Property tests on seeded random polygons check area, bounds, ring closure and winding. Writing the plan fixed three cases: overlays below the ellipsoid kept a negative height, raised plain-colour overlays now draw, and the vertex limit no longer depends on whether a ring repeats its first point.
This commit is contained in:
1 parent
9c2a2d6951
commit
9ae7dea918
32 files changed
+103263
-458
No files matched your search
@@ -6703,8 +6703,9 @@ request viewbox and continues searching without that geographic preference.
|
||||
### Import Your Own Files (October 2026)
|
||||
|
||||
- UTILITIES ▸ **Import** reads GeoJSON (`.geojson`/`.json`), KML, KMZ and GPX from the picker or a file drop anywhere in the app. Each file gets show/hide, Fly-to and Remove controls. GeoJSON and GPX use the row's color; KML/KMZ retain their styles and show a hatched swatch. The file bytes remain on the device for the page session. Rendered overlays can appear in map screenshots sent through voice or other existing screenshot tools.
|
||||
- **Planning and limits.** `geoImportPlan.js` turns plain records and supplied image dimensions into drawing plans and undrawn counts without a DOM or engine. `geoImportDisplay.js` loads images, applies the plan through the globe contract and owns the drawings; `geoImportLimits.js` holds the shared reader, image, drawing and scheduling budgets.
|
||||
- **Ground and height.** GeoJSON XYZ coordinates become ground footprints. `geoFileImport.js` and `geoImportKml.js` produce plain records; one `geoImportDisplay.js` draws them on ground, movers, lines and imagery on every engine, without loading Cesium. Ground paths follow great circles and retain segment gaps. Pins use square sprite canvases preserving Cesium's icon placement and styles; a file's icon looks share a budget of 16 million canvas pixels, so many distinct styles draw at the same size from lower-resolution textures. A KML heading turns with the camera's heading, staying measured from north. Ground and relative pins sample loaded terrain and, at camera heights below 250 km with a tile surface, `engine.surface.clampToHeight` for the pins in the window; absolute pins keep their height. The first sampling and every refresh run in batches of 256 that yield between them; refreshes go through the controller's serial queue after camera/map changes and terrain completion, retaining the last available height on misses; on a tile surface a pin outside the window keeps its last tile height, which the window test also uses. Ground pins ignore scene depth and are horizon-culled. Removal destroys every owned drawing set.
|
||||
- **Drawing limits.** Raised polygons draw their fills (meshes triangulated in the plane tangent to the Earth, as Cesium's perPositionHeight) and outlines at their vertices' heights; a raised polygon of more than 128 rings is not drawn, and one of more than 4,096 vertices draws only its outlines (both counted as undrawn). Ground overlays take their colour's tint and alpha and stack by KML `drawOrder`, then document order (a file imported later draws over); a rotated one is turned on a canvas over the box around it; a file's tinted and turned canvases share a budget of 16 million pixels and equal ones are drawn once; an absolute image overlay is a textured mesh fixed at its altitude, as Cesium's rectangle at a height (a relative one drapes, as on Cesium). Wall fills, extruded prisms, `gx:LatLonQuad`, a rotated overlay whose box passes a pole and a raised plain-colour overlay are counted as undrawn; wall top edges and polygon top geometry remain. Rhumb edges become great circles. Packed image overlays draw on both engines. A GeoJSON line of one point or a polygon of fewer than three distinct corners is not a record, so a file of only those is refused as having nothing to draw. A hole of fewer than three distinct corners is dropped; a ground polygon the ground contract still refuses is counted as undrawn.
|
||||
- **Drawing limits.** Raised polygons draw their fills (meshes triangulated in the plane tangent to the Earth, as Cesium's perPositionHeight) and outlines at their vertices' heights; a raised polygon of more than 128 rings is not drawn, and one of more than 32,768 vertices draws only its outlines (both counted as undrawn). Repeated closing vertices do not consume the fill budget. Ground overlays take their colour's tint and alpha and stack by KML `drawOrder`, then document order (a file imported later draws over); a rotated one is turned on a canvas over the box around it; a file's tinted and turned canvases share a budget of 16 million pixels and equal ones are drawn once; an absolute image or plain-colour overlay is a mesh fixed at its altitude, including negative heights, as Cesium's rectangle at a height (a relative one drapes, as on Cesium). Wall fills, extruded prisms, `gx:LatLonQuad` and a rotated overlay whose box passes a pole are counted as undrawn; wall top edges and polygon top geometry remain. Rhumb edges become great circles. Packed image overlays draw on both engines. A GeoJSON line of one point or a polygon of fewer than three distinct corners is not a record, so a file of only those is refused as having nothing to draw. A hole of fewer than three distinct corners is dropped; a ground polygon the ground contract still refuses is counted as undrawn.
|
||||
- **Navigation.** Row Fly-to uses `runImmediateNavigation('file', …)`; Cockpit can refuse it and existing follow/track ownership is released first. Automatic Fly-to is stamped when a batch is submitted and reasserted before flying. Pointer/wheel gestures and newer navigation supersede it, including time spent in the queue. Framing uses every finite visible point/path/polygon-hole/wall vertex plus rectangular overlay bounds, with viewport-aware range and a nadir view. The target uses available terrain/cached ground height and the ground guard on arrival. Empty footprints never fall back to deferred `viewer.flyTo`.
|
||||
- **Clock.** Imports expose no source clock and no entity availability. KML times/view metadata are removed before loading; recorded tracks become static lines. GPX segments remain separate and GPX times are ignored. The shared clock stays unchanged.
|
||||
- **Input handling.** Coordinates and GeoJSON geometry types are checked before drawing allocation. Only short plain names reach the record model; file IDs, custom CRS and styling properties are removed. KML feature/geometry IDs are removed while Style/StyleMap references remain. Local style references are trimmed, incomplete style pairs removed, hidden-folder flags normalized to the import's show control, and unsupported prototype-named elements removed. UTF-16 BOMs and common KML namespace export defects are handled. Empty drawable content is refused. A loader failure or timeout does not hold the next file indefinitely; teardown aborts pending waits.
|
||||
@@ -6712,6 +6713,7 @@ request viewbox and continues searching without that geographic preference.
|
||||
- **Bounds.** File size ≤50 MiB; inflated KMZ ≤120 MiB; ≤20,000 drawable records (including multipart children); ≤250,000 positions; ≤2,000 normalized style definitions and distinct image links; ≤12 files per session. Exact repeated styles share definitions without changing inheritance or inline overrides. Files of 20–30 MB fit the byte budget, subject to geometry/image limits. Refusals name a reason and batches continue; with multiple failures the hint shows the first reason.
|
||||
- **Lifecycle and keyboard.** `createApplicationTools` wires `initGeoFileImport` with the scene engine, navigation, ground services and map-source subscription. Detach destroys drawings and revokes packed-image URLs; reattach reparses the retained file bytes and restores visibility. Destroy aborts pending work, unsubscribes, removes drawings, revokes blob URLs, removes document/canvas listeners and releases `window.__gevGeoImport`. List rebuilds retain keyboard focus; removing a row hands focus to the next row, else the previous row, else Import.
|
||||
- **Validation.** `node scripts/qa-geo-import.mjs` covers all four formats and real painted show/hide. Run `node scripts/qa-geo-import-regressions.mjs` against both dev and preview for XYZ/track heights, failure recovery, namespace/BOM support, portrait framing and panel drops. `node scripts/qa-geo-import-large.mjs [--file /absolute/path/sample.kml] [--expect-local-pins]` checks a 27.6 MB repeated-style file, effective style equivalence against a native Cesium control, large-file painted output and frame times. It records the WebGL renderer; software-rendered runs do not establish GPU performance. Unit tests live beside the data/controller/framing modules.
|
||||
- **Reference corpus.** `scripts/fixtures/geo-import/` holds 13 KML/KMZ/GeoJSON fixtures covering heights, rotations, poles, the dateline, holes, ordering, styles, packed images and a 20,000-vertex polygon. `node scripts/qa-geo-import-reference.mjs` compares planned geometry and styles with Cesium 1.138.0 DataSources in Node; `--record` recreates the reference offline with canvas pins stubbed and KMZ images resolved locally. Pixel composition and ordering between primitive families remain browser checks.
|
||||
|
||||
### Recent Imagery (September 2026)
|
||||
|
||||
|
||||
Reference in new issue
Block a user