@mailwoman/react 10.0.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -16
- package/fonts.css +97 -22
- package/lib/common/About.tsx +7 -7
- package/lib/common/ClientOnly.tsx +2 -14
- package/lib/common/CopyButton.tsx +3 -1
- package/lib/common/LoadingIndicator.tsx +4 -2
- package/lib/common/PresetChips.tsx +9 -8
- package/lib/common/confidence-tiers.ts +7 -6
- package/lib/common/cx.ts +3 -1
- package/lib/common/text-tokens.ts +7 -4
- package/lib/common/useBuildInfo.ts +54 -0
- package/lib/common/useClipboard.ts +2 -11
- package/lib/common.ts +22 -0
- package/lib/index.ts +27 -17
- package/lib/map/AppIdentity.tsx +85 -0
- package/lib/map/BackendControl.tsx +9 -10
- package/lib/map/CompareToggle.tsx +8 -31
- package/lib/map/DebugInfo.tsx +88 -0
- package/lib/map/Geocoder.tsx +60 -46
- package/lib/map/GeocoderControls.tsx +430 -134
- package/lib/map/GraticuleLayer.tsx +54 -0
- package/lib/map/MapCanvas.tsx +23 -12
- package/lib/map/MapChipRow.tsx +4 -8
- package/lib/map/MapCompass.tsx +15 -24
- package/lib/map/MapControlStack.tsx +8 -9
- package/lib/map/MapFooter.tsx +2 -16
- package/lib/map/MapProgressBar.tsx +10 -13
- package/lib/map/MapSearchBar.tsx +31 -17
- package/lib/map/MapSheet.tsx +24 -15
- package/lib/map/OverlayLayers.tsx +1 -1
- package/lib/map/PlaceAutocomplete.tsx +10 -21
- package/lib/map/PlaceMarker.tsx +4 -2
- package/lib/map/ResolvedPlaceLayers.tsx +5 -14
- package/lib/map/ResultCamera.tsx +8 -31
- package/lib/map/ResultOverlay.tsx +2 -12
- package/lib/map/ResultPanel.tsx +1 -20
- package/lib/map/VersionPicker.tsx +10 -19
- package/lib/map/fake-runtime.ts +10 -12
- package/lib/map/geometry.ts +14 -47
- package/lib/map/graticule.ts +80 -0
- package/lib/map/map-debug.ts +1 -1
- package/lib/map/place-render.ts +28 -60
- package/lib/map/types.ts +58 -104
- package/lib/map/useCompareState.ts +5 -4
- package/lib/map/useGeocode.ts +7 -5
- package/lib/map/useMapBearing.ts +13 -13
- package/lib/map/useMapLabelPick.ts +21 -30
- package/lib/map/useMapPlaceRender.ts +2 -6
- package/lib/map/usePlaceAutocomplete.ts +44 -50
- package/lib/map.ts +95 -0
- package/lib/pipeline/CandidatePicker.tsx +13 -5
- package/lib/pipeline/ConfidenceCell.tsx +1 -1
- package/lib/pipeline/FailureDiagnostic.tsx +8 -2
- package/lib/pipeline/QueryForm.tsx +5 -2
- package/lib/pipeline/ResolvedPlace.tsx +1 -1
- package/lib/pipeline/SpanHighlight.tsx +7 -5
- package/lib/pipeline/TimingPanel.tsx +1 -1
- package/lib/pipeline/TreeView.tsx +1 -1
- package/lib/pipeline/copy.ts +22 -25
- package/lib/pipeline/presets.ts +15 -13
- package/lib/pipeline/types.ts +21 -14
- package/lib/pipeline/useParsePipeline.ts +16 -13
- package/lib/pipeline.ts +36 -0
- package/lib/poi/AbstainPanel.tsx +1 -1
- package/lib/poi/LiveResultsBlock.tsx +2 -1
- package/lib/poi/POIExplorer.tsx +24 -15
- package/lib/poi/QueryInput.tsx +1 -1
- package/lib/poi/SubjectPanel.tsx +4 -3
- package/lib/poi/runtime.ts +5 -16
- package/lib/poi/types.ts +39 -27
- package/lib/poi/usePOISearch.ts +39 -44
- package/lib/poi.ts +39 -0
- package/lib/runtime/useReleaseRuntime.ts +125 -74
- package/lib/search/SearchModal.tsx +317 -0
- package/lib/search/search.css +144 -0
- package/lib/search/types.ts +67 -0
- package/lib/search.ts +11 -0
- package/out/common/About.d.ts +5 -5
- package/out/common/About.d.ts.map +1 -1
- package/out/common/About.js +1 -1
- package/out/common/About.js.map +1 -1
- package/out/common/ClientOnly.d.ts +2 -11
- package/out/common/ClientOnly.d.ts.map +1 -1
- package/out/common/ClientOnly.js +1 -13
- package/out/common/ClientOnly.js.map +1 -1
- package/out/common/CopyButton.d.ts +3 -1
- package/out/common/CopyButton.d.ts.map +1 -1
- package/out/common/CopyButton.js.map +1 -1
- package/out/common/LoadingIndicator.d.ts +4 -2
- package/out/common/LoadingIndicator.d.ts.map +1 -1
- package/out/common/LoadingIndicator.js.map +1 -1
- package/out/common/PresetChips.d.ts +9 -8
- package/out/common/PresetChips.d.ts.map +1 -1
- package/out/common/PresetChips.js.map +1 -1
- package/out/common/confidence-tiers.d.ts +7 -6
- package/out/common/confidence-tiers.d.ts.map +1 -1
- package/out/common/confidence-tiers.js +7 -6
- package/out/common/confidence-tiers.js.map +1 -1
- package/out/common/cx.d.ts +3 -1
- package/out/common/cx.d.ts.map +1 -1
- package/out/common/cx.js +3 -1
- package/out/common/cx.js.map +1 -1
- package/out/common/text-tokens.d.ts +4 -3
- package/out/common/text-tokens.d.ts.map +1 -1
- package/out/common/text-tokens.js +6 -3
- package/out/common/text-tokens.js.map +1 -1
- package/out/common/useBuildInfo.d.ts +27 -0
- package/out/common/useBuildInfo.d.ts.map +1 -0
- package/out/common/useBuildInfo.js +32 -0
- package/out/common/useBuildInfo.js.map +1 -0
- package/out/common/useClipboard.d.ts +1 -3
- package/out/common/useClipboard.d.ts.map +1 -1
- package/out/common/useClipboard.js +2 -11
- package/out/common/useClipboard.js.map +1 -1
- package/out/common.d.ts +22 -0
- package/out/common.d.ts.map +1 -0
- package/out/common.js +15 -0
- package/out/common.js.map +1 -0
- package/out/index.d.ts +26 -16
- package/out/index.d.ts.map +1 -1
- package/out/index.js +21 -15
- package/out/index.js.map +1 -1
- package/out/map/AppIdentity.d.ts +42 -0
- package/out/map/AppIdentity.d.ts.map +1 -0
- package/out/map/AppIdentity.js +16 -0
- package/out/map/AppIdentity.js.map +1 -0
- package/out/map/BackendControl.d.ts +9 -10
- package/out/map/BackendControl.d.ts.map +1 -1
- package/out/map/BackendControl.js +1 -1
- package/out/map/BackendControl.js.map +1 -1
- package/out/map/CompareToggle.d.ts +8 -31
- package/out/map/CompareToggle.d.ts.map +1 -1
- package/out/map/CompareToggle.js +4 -1
- package/out/map/CompareToggle.js.map +1 -1
- package/out/map/DebugInfo.d.ts +34 -0
- package/out/map/DebugInfo.d.ts.map +1 -0
- package/out/map/DebugInfo.js +39 -0
- package/out/map/DebugInfo.js.map +1 -0
- package/out/map/Geocoder.d.ts +41 -30
- package/out/map/Geocoder.d.ts.map +1 -1
- package/out/map/Geocoder.js +20 -36
- package/out/map/Geocoder.js.map +1 -1
- package/out/map/GeocoderControls.d.ts +14 -42
- package/out/map/GeocoderControls.d.ts.map +1 -1
- package/out/map/GeocoderControls.js +250 -38
- package/out/map/GeocoderControls.js.map +1 -1
- package/out/map/GraticuleLayer.d.ts +28 -0
- package/out/map/GraticuleLayer.d.ts.map +1 -0
- package/out/map/GraticuleLayer.js +25 -0
- package/out/map/GraticuleLayer.js.map +1 -0
- package/out/map/MapCanvas.d.ts +23 -12
- package/out/map/MapCanvas.d.ts.map +1 -1
- package/out/map/MapCanvas.js +5 -2
- package/out/map/MapCanvas.js.map +1 -1
- package/out/map/MapChipRow.d.ts +4 -8
- package/out/map/MapChipRow.d.ts.map +1 -1
- package/out/map/MapChipRow.js.map +1 -1
- package/out/map/MapCompass.d.ts +11 -20
- package/out/map/MapCompass.d.ts.map +1 -1
- package/out/map/MapCompass.js +5 -1
- package/out/map/MapCompass.js.map +1 -1
- package/out/map/MapControlStack.d.ts +8 -9
- package/out/map/MapControlStack.d.ts.map +1 -1
- package/out/map/MapControlStack.js +4 -1
- package/out/map/MapControlStack.js.map +1 -1
- package/out/map/MapFooter.d.ts +2 -15
- package/out/map/MapFooter.d.ts.map +1 -1
- package/out/map/MapFooter.js +0 -14
- package/out/map/MapFooter.js.map +1 -1
- package/out/map/MapProgressBar.d.ts +10 -13
- package/out/map/MapProgressBar.d.ts.map +1 -1
- package/out/map/MapProgressBar.js.map +1 -1
- package/out/map/MapSearchBar.d.ts +16 -17
- package/out/map/MapSearchBar.d.ts.map +1 -1
- package/out/map/MapSearchBar.js +6 -0
- package/out/map/MapSearchBar.js.map +1 -1
- package/out/map/MapSheet.d.ts +15 -12
- package/out/map/MapSheet.d.ts.map +1 -1
- package/out/map/MapSheet.js +8 -12
- package/out/map/MapSheet.js.map +1 -1
- package/out/map/OverlayLayers.d.ts +1 -1
- package/out/map/OverlayLayers.js +1 -1
- package/out/map/PlaceAutocomplete.d.ts +10 -21
- package/out/map/PlaceAutocomplete.d.ts.map +1 -1
- package/out/map/PlaceAutocomplete.js +2 -1
- package/out/map/PlaceAutocomplete.js.map +1 -1
- package/out/map/PlaceMarker.d.ts +4 -2
- package/out/map/PlaceMarker.d.ts.map +1 -1
- package/out/map/PlaceMarker.js +3 -1
- package/out/map/PlaceMarker.js.map +1 -1
- package/out/map/ResolvedPlaceLayers.d.ts +5 -14
- package/out/map/ResolvedPlaceLayers.d.ts.map +1 -1
- package/out/map/ResolvedPlaceLayers.js +1 -1
- package/out/map/ResolvedPlaceLayers.js.map +1 -1
- package/out/map/ResultCamera.d.ts +8 -31
- package/out/map/ResultCamera.d.ts.map +1 -1
- package/out/map/ResultCamera.js +3 -28
- package/out/map/ResultCamera.js.map +1 -1
- package/out/map/ResultOverlay.d.ts +2 -12
- package/out/map/ResultOverlay.d.ts.map +1 -1
- package/out/map/ResultOverlay.js +1 -2
- package/out/map/ResultOverlay.js.map +1 -1
- package/out/map/ResultPanel.d.ts +1 -20
- package/out/map/ResultPanel.d.ts.map +1 -1
- package/out/map/ResultPanel.js.map +1 -1
- package/out/map/VersionPicker.d.ts +7 -19
- package/out/map/VersionPicker.d.ts.map +1 -1
- package/out/map/VersionPicker.js +5 -2
- package/out/map/VersionPicker.js.map +1 -1
- package/out/map/fake-runtime.d.ts +9 -11
- package/out/map/fake-runtime.d.ts.map +1 -1
- package/out/map/fake-runtime.js +9 -12
- package/out/map/fake-runtime.js.map +1 -1
- package/out/map/geometry.d.ts +13 -34
- package/out/map/geometry.d.ts.map +1 -1
- package/out/map/geometry.js +9 -34
- package/out/map/geometry.js.map +1 -1
- package/out/map/graticule.d.ts +17 -0
- package/out/map/graticule.d.ts.map +1 -0
- package/out/map/graticule.js +67 -0
- package/out/map/graticule.js.map +1 -0
- package/out/map/map-debug.d.ts +1 -1
- package/out/map/map-debug.js +1 -1
- package/out/map/place-render.d.ts +23 -43
- package/out/map/place-render.d.ts.map +1 -1
- package/out/map/place-render.js +4 -39
- package/out/map/place-render.js.map +1 -1
- package/out/map/types.d.ts +58 -102
- package/out/map/types.d.ts.map +1 -1
- package/out/map/types.js +1 -10
- package/out/map/types.js.map +1 -1
- package/out/map/useCompareState.d.ts +5 -4
- package/out/map/useCompareState.d.ts.map +1 -1
- package/out/map/useCompareState.js +3 -3
- package/out/map/useCompareState.js.map +1 -1
- package/out/map/useGeocode.d.ts +5 -3
- package/out/map/useGeocode.d.ts.map +1 -1
- package/out/map/useGeocode.js +4 -4
- package/out/map/useGeocode.js.map +1 -1
- package/out/map/useMapBearing.d.ts +11 -11
- package/out/map/useMapBearing.d.ts.map +1 -1
- package/out/map/useMapBearing.js +6 -11
- package/out/map/useMapBearing.js.map +1 -1
- package/out/map/useMapLabelPick.d.ts +4 -14
- package/out/map/useMapLabelPick.d.ts.map +1 -1
- package/out/map/useMapLabelPick.js +21 -30
- package/out/map/useMapLabelPick.js.map +1 -1
- package/out/map/useMapPlaceRender.d.ts +2 -6
- package/out/map/useMapPlaceRender.d.ts.map +1 -1
- package/out/map/useMapPlaceRender.js +2 -6
- package/out/map/useMapPlaceRender.js.map +1 -1
- package/out/map/usePlaceAutocomplete.d.ts +30 -28
- package/out/map/usePlaceAutocomplete.d.ts.map +1 -1
- package/out/map/usePlaceAutocomplete.js +6 -33
- package/out/map/usePlaceAutocomplete.js.map +1 -1
- package/out/map.d.ts +69 -0
- package/out/map.d.ts.map +1 -0
- package/out/map.js +46 -0
- package/out/map.js.map +1 -0
- package/out/pipeline/CandidatePicker.d.ts +12 -2
- package/out/pipeline/CandidatePicker.d.ts.map +1 -1
- package/out/pipeline/CandidatePicker.js +1 -1
- package/out/pipeline/CandidatePicker.js.map +1 -1
- package/out/pipeline/ConfidenceCell.d.ts +1 -1
- package/out/pipeline/ConfidenceCell.js +1 -1
- package/out/pipeline/FailureDiagnostic.d.ts +8 -2
- package/out/pipeline/FailureDiagnostic.d.ts.map +1 -1
- package/out/pipeline/FailureDiagnostic.js +3 -0
- package/out/pipeline/FailureDiagnostic.js.map +1 -1
- package/out/pipeline/QueryForm.d.ts +5 -2
- package/out/pipeline/QueryForm.d.ts.map +1 -1
- package/out/pipeline/QueryForm.js.map +1 -1
- package/out/pipeline/SpanHighlight.d.ts +4 -3
- package/out/pipeline/SpanHighlight.d.ts.map +1 -1
- package/out/pipeline/SpanHighlight.js +3 -2
- package/out/pipeline/SpanHighlight.js.map +1 -1
- package/out/pipeline/TimingPanel.d.ts +1 -1
- package/out/pipeline/TreeView.d.ts +1 -1
- package/out/pipeline/copy.d.ts +1 -1
- package/out/pipeline/copy.d.ts.map +1 -1
- package/out/pipeline/copy.js +4 -3
- package/out/pipeline/copy.js.map +1 -1
- package/out/pipeline/presets.d.ts +5 -4
- package/out/pipeline/presets.d.ts.map +1 -1
- package/out/pipeline/presets.js +15 -13
- package/out/pipeline/presets.js.map +1 -1
- package/out/pipeline/types.d.ts +21 -14
- package/out/pipeline/types.d.ts.map +1 -1
- package/out/pipeline/types.js +2 -4
- package/out/pipeline/types.js.map +1 -1
- package/out/pipeline/useParsePipeline.d.ts +14 -9
- package/out/pipeline/useParsePipeline.d.ts.map +1 -1
- package/out/pipeline/useParsePipeline.js +7 -8
- package/out/pipeline/useParsePipeline.js.map +1 -1
- package/out/pipeline.d.ts +33 -0
- package/out/pipeline.d.ts.map +1 -0
- package/out/pipeline.js +21 -0
- package/out/pipeline.js.map +1 -0
- package/out/poi/AbstainPanel.d.ts +1 -1
- package/out/poi/LiveResultsBlock.d.ts +2 -1
- package/out/poi/LiveResultsBlock.d.ts.map +1 -1
- package/out/poi/LiveResultsBlock.js.map +1 -1
- package/out/poi/POIExplorer.d.ts +22 -12
- package/out/poi/POIExplorer.d.ts.map +1 -1
- package/out/poi/POIExplorer.js +9 -8
- package/out/poi/POIExplorer.js.map +1 -1
- package/out/poi/QueryInput.d.ts +1 -1
- package/out/poi/SubjectPanel.d.ts +2 -2
- package/out/poi/SubjectPanel.d.ts.map +1 -1
- package/out/poi/SubjectPanel.js +2 -1
- package/out/poi/SubjectPanel.js.map +1 -1
- package/out/poi/runtime.d.ts +5 -14
- package/out/poi/runtime.d.ts.map +1 -1
- package/out/poi/runtime.js +5 -16
- package/out/poi/runtime.js.map +1 -1
- package/out/poi/types.d.ts +39 -27
- package/out/poi/types.d.ts.map +1 -1
- package/out/poi/types.js +2 -4
- package/out/poi/types.js.map +1 -1
- package/out/poi/usePOISearch.d.ts +28 -17
- package/out/poi/usePOISearch.d.ts.map +1 -1
- package/out/poi/usePOISearch.js +6 -32
- package/out/poi/usePOISearch.js.map +1 -1
- package/out/poi.d.ts +23 -0
- package/out/poi.d.ts.map +1 -0
- package/out/poi.js +15 -0
- package/out/poi.js.map +1 -0
- package/out/runtime/useReleaseRuntime.d.ts +64 -65
- package/out/runtime/useReleaseRuntime.d.ts.map +1 -1
- package/out/runtime/useReleaseRuntime.js +31 -26
- package/out/runtime/useReleaseRuntime.js.map +1 -1
- package/out/{runtime/index.d.ts → runtime.d.ts} +1 -1
- package/out/runtime.d.ts.map +1 -0
- package/out/{runtime/index.js → runtime.js} +1 -1
- package/out/runtime.js.map +1 -0
- package/out/search/SearchModal.d.ts +33 -0
- package/out/search/SearchModal.d.ts.map +1 -0
- package/out/search/SearchModal.js +187 -0
- package/out/search/SearchModal.js.map +1 -0
- package/out/search/types.d.ts +64 -0
- package/out/search/types.d.ts.map +1 -0
- package/out/search/types.js +13 -0
- package/out/search/types.js.map +1 -0
- package/out/search.d.ts +11 -0
- package/out/search.d.ts.map +1 -0
- package/out/search.js +9 -0
- package/out/search.js.map +1 -0
- package/package.json +60 -142
- package/styles.css +482 -266
- package/tokens/index.css +24 -6
- package/tokens/tokens.json +114 -6
- package/lib/common/index.ts +0 -22
- package/lib/map/index.ts +0 -95
- package/lib/pipeline/index.ts +0 -36
- package/lib/poi/index.ts +0 -39
- package/out/common/index.d.ts +0 -22
- package/out/common/index.d.ts.map +0 -1
- package/out/common/index.js +0 -15
- package/out/common/index.js.map +0 -1
- package/out/map/index.d.ts +0 -69
- package/out/map/index.d.ts.map +0 -1
- package/out/map/index.js +0 -46
- package/out/map/index.js.map +0 -1
- package/out/pipeline/index.d.ts +0 -33
- package/out/pipeline/index.d.ts.map +0 -1
- package/out/pipeline/index.js +0 -21
- package/out/pipeline/index.js.map +0 -1
- package/out/poi/index.d.ts +0 -23
- package/out/poi/index.d.ts.map +0 -1
- package/out/poi/index.js +0 -15
- package/out/poi/index.js.map +0 -1
- package/out/runtime/index.d.ts.map +0 -1
- package/out/runtime/index.js.map +0 -1
- package/styleframe.config.ts +0 -329
- package/vitest.node.config.ts +0 -20
- /package/lib/{runtime/index.ts → runtime.ts} +0 -0
package/lib/map/ResultCamera.tsx
CHANGED
|
@@ -2,21 +2,6 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* `<ResultCamera>` — applies the {@link MapCameraTarget} a {@link MapPlaceRenderSpec} computes, by
|
|
7
|
-
* animating the live map to it. This is the ONE deliberately-imperative touch in the phase-2 overlays,
|
|
8
|
-
* and it is justified: maplibre exposes animated camera moves (`flyTo`) and viewport-fitting
|
|
9
|
-
* (`fitBounds`, which needs the map's PIXEL dimensions + padding) ONLY imperatively — react-map-gl has
|
|
10
|
-
* no declarative prop for "animate to these bounds". It is applied the v8-idiomatic way, through
|
|
11
|
-
* `useMap()` (exactly as `DashboardMap`/`GeoJSONClipboardLayer` reach the map), never a threaded handle.
|
|
12
|
-
*
|
|
13
|
-
* A consumer that prefers a hard, declarative jump can instead feed the target through
|
|
14
|
-
* {@link cameraToViewState} into a controlled `<MapCanvas viewState>` and skip this component — the
|
|
15
|
-
* `center` case has that declarative path; only `bounds` strictly requires this. Renders nothing.
|
|
16
|
-
*
|
|
17
|
-
* `target` is expected to be the STABLE, memoized `camera` off a `useMapPlaceRender` spec, so listing it
|
|
18
|
-
* as the effect dependency re-runs the camera move exactly when the resolved place changes — no
|
|
19
|
-
* value-key dance, no dependency-lint suppression.
|
|
20
5
|
*/
|
|
21
6
|
|
|
22
7
|
import type { FitBoundsOptions } from "maplibre-gl"
|
|
@@ -26,38 +11,30 @@ import { useMap } from "react-map-gl/maplibre"
|
|
|
26
11
|
import type { MapCameraTarget } from "#map/place-render"
|
|
27
12
|
|
|
28
13
|
/**
|
|
29
|
-
*
|
|
30
|
-
* at the call site.
|
|
14
|
+
* Builds `fitBounds` options without an undefined `duration` key.
|
|
31
15
|
*
|
|
32
|
-
*
|
|
33
|
-
* `Camera.flyTo` (which `fitBounds` funnels into via `_fitInternal`) branches on `'duration' in options`, not on the
|
|
34
|
-
* value: an explicitly-passed `duration: undefined` therefore survives the key test and is coerced with `+undefined` →
|
|
35
|
-
* `NaN`. Every ease frame then computes `k = easing(elapsed / NaN)` → `NaN`, the flight-path math yields a `NaN` world
|
|
36
|
-
* coordinate, and the FIRST frame throws `Invalid LngLat object: (NaN, NaN)` out of the RAF loop — before the map has
|
|
37
|
-
* moved at all, and with no `move` event to notice it by.
|
|
38
|
-
*
|
|
39
|
-
* Measured 2026-08-05 against maplibre-gl 5.24.0, same bounds and same map: `{padding: 40, duration: undefined}` →
|
|
40
|
-
* `map._easeOptions.duration = NaN` + the throw; `{padding: 40}` → `3937.7 ms` + a normal flight. So pass the key or
|
|
41
|
-
* don't — never pass it holding `undefined`.
|
|
16
|
+
* MapLibre checks for existence and can turn into a NaN camera move.
|
|
42
17
|
*/
|
|
43
18
|
export function fitBoundsOptionsFor(padding: number, animate: boolean): FitBoundsOptions {
|
|
44
19
|
return animate ? { padding } : { padding, duration: 0 }
|
|
45
20
|
}
|
|
46
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Props for {@link ResultCamera}.
|
|
24
|
+
*/
|
|
47
25
|
export interface ResultCameraProps {
|
|
48
26
|
/**
|
|
49
|
-
* The camera target
|
|
27
|
+
* The camera target; `null` leaves the camera where it is.
|
|
50
28
|
*/
|
|
51
29
|
target: MapCameraTarget | null
|
|
52
30
|
/**
|
|
53
|
-
*
|
|
54
|
-
* target still uses `fitBounds` (no instantaneous fit exists) but with `duration: 0`.
|
|
31
|
+
* Whether to animate the move. @default true
|
|
55
32
|
*/
|
|
56
33
|
animate?: boolean
|
|
57
34
|
}
|
|
58
35
|
|
|
59
36
|
/**
|
|
60
|
-
*
|
|
37
|
+
* Moves the map to `target`; mount it as a child of `<Map>`.
|
|
61
38
|
*/
|
|
62
39
|
export function ResultCamera({ target, animate = true }: ResultCameraProps): ReactNode {
|
|
63
40
|
const map = useMap()
|
|
@@ -2,15 +2,6 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* `<ResultOverlay>` — the resolved-place outline (crisp admin polygon, or an approximate/exact-radius
|
|
7
|
-
* circle) as a declarative `<Source>` + fill/line `<Layer>`s. This replaces the demo's imperative
|
|
8
|
-
* `setPlaceOutline` / `drawApproxCircle` / `drawPlaceGeometry` / `clearBbox` helpers and their
|
|
9
|
-
* `whenStyleReady` guard: react-map-gl owns the "add source/layer once the style is loaded, remove on
|
|
10
|
-
* unmount" lifecycle, so the hand-rolled `isStyleLoaded()` / `styledata` races disappear.
|
|
11
|
-
*
|
|
12
|
-
* Pass the `outline` straight from a {@link MapPlaceRenderSpec}; a `null` outline renders nothing (the
|
|
13
|
-
* bare-point case). NODE-IMPORT SAFETY: imports `react-map-gl/maplibre` — `@mailwoman/react/map` only.
|
|
14
5
|
*/
|
|
15
6
|
|
|
16
7
|
import type { ReactNode } from "react"
|
|
@@ -25,7 +16,7 @@ const OUTLINE_COLOR = "#e0367c"
|
|
|
25
16
|
|
|
26
17
|
export interface ResultOverlayProps {
|
|
27
18
|
/**
|
|
28
|
-
* The outline geometry to draw, or `null` to draw
|
|
19
|
+
* The outline geometry to draw, or `null` to draw no geometry (the bare-point result).
|
|
29
20
|
*/
|
|
30
21
|
outline: PlaceGeometry | null
|
|
31
22
|
/**
|
|
@@ -47,8 +38,7 @@ export interface ResultOverlayProps {
|
|
|
47
38
|
}
|
|
48
39
|
|
|
49
40
|
/**
|
|
50
|
-
* Render the resolved-place outline.
|
|
51
|
-
* `<Layer>` — the same two layers the imperative `setPlaceOutline` created, now declarative and self-cleaning.
|
|
41
|
+
* Render the resolved-place outline.
|
|
52
42
|
*/
|
|
53
43
|
export function ResultOverlay({
|
|
54
44
|
outline,
|
package/lib/map/ResultPanel.tsx
CHANGED
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* `<ResultPanel>` — the demo's parse+resolve result block, assembled from the SHARED pipeline
|
|
7
|
-
* presentational units (it does not re-implement any of them): `KindBadge`, `ComponentTable`,
|
|
8
|
-
* `ResolvedPlace`, `CandidatePicker`, plus the `CopyButton` + `buildParsePayload` copy affordance. This
|
|
9
|
-
* is the standalone, story-testable unit the demo's floating panel renders (the map analogue of the
|
|
10
|
-
* result block PipelineExplorer inlines), so `Geocoder` composes ONE panel instead of duplicating
|
|
11
|
-
* the marker/table/candidate glue. Heavy host visualizers (span highlight, tree, timing) slot in via
|
|
12
|
-
* `extras`; the no-resolve diagnostic via `failure`.
|
|
13
|
-
*
|
|
14
|
-
* NODE-SAFE: pure React + the shared units, no maplibre.
|
|
15
5
|
*/
|
|
16
6
|
|
|
17
7
|
import type { ParseResult, ResolvedPlaceView } from "@mailwoman/core/pipeline/client-result"
|
|
@@ -26,28 +16,19 @@ import { ComponentTable } from "../pipeline/ComponentTable.tsx"
|
|
|
26
16
|
import { ResolvedPlace } from "../pipeline/ResolvedPlace.tsx"
|
|
27
17
|
|
|
28
18
|
export interface ResultPanelProps {
|
|
29
|
-
/**
|
|
30
|
-
* The parse+resolve result to render.
|
|
31
|
-
*/
|
|
32
19
|
result: ParseResult
|
|
33
20
|
/**
|
|
34
21
|
* The selected candidate (falls back to the first), used for the resolved-place detail + copy payload.
|
|
35
22
|
*/
|
|
36
23
|
selectedCandidate: ResolvedPlaceView | null
|
|
37
|
-
/**
|
|
38
|
-
* The selected candidate index, for the picker's active state.
|
|
39
|
-
*/
|
|
40
24
|
selectedCandidateIndex: number
|
|
41
|
-
/**
|
|
42
|
-
* Fired when a candidate in the picker is chosen.
|
|
43
|
-
*/
|
|
44
25
|
onSelectCandidate: (index: number) => void
|
|
45
26
|
/**
|
|
46
27
|
* Host-injected heavy visualizers (span highlight, tree, timing, …), rendered from the result.
|
|
47
28
|
*/
|
|
48
29
|
extras?: (result: ParseResult) => ReactNode
|
|
49
30
|
/**
|
|
50
|
-
* Host-injected no-resolve diagnostic, rendered when
|
|
31
|
+
* Host-injected no-resolve diagnostic, rendered when no place resolved.
|
|
51
32
|
*/
|
|
52
33
|
failure?: (result: ParseResult) => ReactNode
|
|
53
34
|
}
|
|
@@ -3,44 +3,32 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* as a dumb presentational unit: the available bundles + current selection come in as props, the choice
|
|
8
|
-
* goes out through `onSelect`. No load state, no manifest fetch — the host (via `useReleaseRuntime`) owns
|
|
9
|
-
* that. Renders nothing when there is fewer than two versions to choose between.
|
|
10
|
-
*
|
|
11
|
-
* NODE-SAFE: pure React + a `<select>`, no maplibre. It rides the `@mailwoman/react/map` subpath only
|
|
12
|
-
* because it is a demo-specific control, not because it needs WebGL.
|
|
6
|
+
* Renders a selector for the available model versions. The host owns loading and selection.
|
|
13
7
|
*/
|
|
14
8
|
|
|
15
9
|
import type { ReactNode } from "react"
|
|
16
10
|
|
|
17
11
|
import type { VersionOption } from "#map/types"
|
|
18
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Props for {@link VersionPicker}.
|
|
15
|
+
*/
|
|
19
16
|
export interface VersionPickerProps {
|
|
20
|
-
/**
|
|
21
|
-
* The selectable model bundles.
|
|
22
|
-
*/
|
|
23
17
|
versions: ReadonlyArray<VersionOption>
|
|
24
|
-
/**
|
|
25
|
-
* The currently-selected version tag.
|
|
26
|
-
*/
|
|
27
18
|
selected: string | null
|
|
28
|
-
/**
|
|
29
|
-
* Fired with the chosen version tag.
|
|
30
|
-
*/
|
|
31
19
|
onSelect: (version: string) => void
|
|
32
20
|
/**
|
|
33
|
-
*
|
|
21
|
+
* Disables the control, for example while a parse runs.
|
|
34
22
|
*/
|
|
35
23
|
disabled?: boolean
|
|
36
24
|
/**
|
|
37
|
-
*
|
|
25
|
+
* @default "Model version"
|
|
38
26
|
*/
|
|
39
27
|
label?: string
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
/**
|
|
43
|
-
*
|
|
31
|
+
* Renders the model version selector, or `null` when fewer than two versions exist.
|
|
44
32
|
*/
|
|
45
33
|
export function VersionPicker({
|
|
46
34
|
versions,
|
|
@@ -62,6 +50,9 @@ export function VersionPicker({
|
|
|
62
50
|
value={selected ?? ""}
|
|
63
51
|
onChange={(e) => onSelect(e.target.value)}
|
|
64
52
|
disabled={disabled}
|
|
53
|
+
// The title shows the full label.
|
|
54
|
+
// The field may clip it.
|
|
55
|
+
title={versions.find((v) => v.version === selected)?.label ?? selected ?? undefined}
|
|
65
56
|
>
|
|
66
57
|
{versions.map((v) => (
|
|
67
58
|
<option key={v.version} value={v.version}>
|
package/lib/map/fake-runtime.ts
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* A fake geocoder runtime: canned parse + resolve, an offline stub map style, canned autocomplete, a version list.
|
|
7
|
-
* No network, no ONNX, no maplibre at run time — everything is data. It is what the stories and component tests
|
|
8
|
-
* mount, and what a host mounts to show the UI without the model.
|
|
9
5
|
*/
|
|
10
6
|
|
|
11
7
|
import type { ParseResult } from "@mailwoman/core/pipeline/client-result"
|
|
@@ -17,7 +13,8 @@ import type { PipelineRuntime } from "#pipeline/types"
|
|
|
17
13
|
import type { MapCanvasStyle } from "./MapCanvas.tsx"
|
|
18
14
|
|
|
19
15
|
/**
|
|
20
|
-
*
|
|
16
|
+
* Defines an offline map style with a single background layer and no sources,
|
|
17
|
+
* so it renders in headless Storybook without network access.
|
|
21
18
|
*/
|
|
22
19
|
export const STUB_MAP_STYLE: MapCanvasStyle = {
|
|
23
20
|
version: 8,
|
|
@@ -36,11 +33,11 @@ export const FAKE_SUGGESTIONS: Suggestion[] = [
|
|
|
36
33
|
]
|
|
37
34
|
|
|
38
35
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
36
|
+
* Creates an offline {@link GeocoderRuntime} that extends {@link makePipelineRuntime}
|
|
37
|
+
* with the stub style, canned suggestions and versions.
|
|
38
|
+
*
|
|
39
|
+
* It also provides `resolveMapPlace` that gives the candidate a bounding box so overlays draw.
|
|
40
|
+
* The fake ignores the bias passed to `runParseWithBias`.
|
|
44
41
|
*/
|
|
45
42
|
export function makeFakeGeocoderRuntime(overrides: Partial<GeocoderRuntime> = {}): GeocoderRuntime {
|
|
46
43
|
const base = makePipelineRuntime()
|
|
@@ -64,7 +61,7 @@ export function makeFakeGeocoderRuntime(overrides: Partial<GeocoderRuntime> = {}
|
|
|
64
61
|
activeBackend: "webgpu (28 MB int8)",
|
|
65
62
|
forceWASM: false,
|
|
66
63
|
setForceWASM: () => {},
|
|
67
|
-
|
|
64
|
+
|
|
68
65
|
resolveMapPlace: (candidate): ResolvedMapPlace => ({
|
|
69
66
|
...candidate,
|
|
70
67
|
bbox: {
|
|
@@ -79,7 +76,8 @@ export function makeFakeGeocoderRuntime(overrides: Partial<GeocoderRuntime> = {}
|
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
/**
|
|
82
|
-
*
|
|
79
|
+
* Creates a fixed, fully populated parse-and-resolve result for the given input,
|
|
80
|
+
* shared by the fake pipeline runtime and result-panel fixtures.
|
|
83
81
|
*/
|
|
84
82
|
export function makeFakeParseResult(input = "350 5th Ave, New York, NY 10118"): ParseResult {
|
|
85
83
|
return {
|
package/lib/map/geometry.ts
CHANGED
|
@@ -2,28 +2,12 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* Pure map geometry for the geocoder demo — the resolved-place outline math, lifted verbatim from the
|
|
7
|
-
* docs demo's `_map-helpers.ts`. Zero imports: no React, no `react-map-gl`, no `maplibre-gl`, no DOM.
|
|
8
|
-
* Every function takes plain numbers and returns plain GeoJSON, so the whole module runs (and is
|
|
9
|
-
* tested) under bare node — see `geometry.node.test.ts`.
|
|
10
|
-
*
|
|
11
|
-
* WHY NOT `@mailwoman/spatial`: the only truly-spatial primitive here is the bbox half-diagonal (a
|
|
12
|
-
* great-circle-ish distance). `@mailwoman/spatial` exposes `haversineKm`, but ONLY via its root barrel,
|
|
13
|
-
* which pulls `@mailwoman/core` + `h3-js` + `wkx` — a heavy, partly node-only graph — into what must
|
|
14
|
-
* stay a lightweight, browser-only map bundle (the `@mailwoman/react/map` subpath). The original
|
|
15
|
-
* `_map-helpers.ts` made the same call: a planar `kmPerDeg` approximation, local, no dependency. We
|
|
16
|
-
* preserve it so the ported behavior is byte-identical and the browser graph stays clean.
|
|
17
5
|
*/
|
|
18
6
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*/
|
|
7
|
+
import type { LatLonBounds } from "@mailwoman/spatial"
|
|
8
|
+
|
|
22
9
|
const CIRCLE_SEGMENTS = 64
|
|
23
10
|
|
|
24
|
-
/**
|
|
25
|
-
* Mean km per degree of latitude (WGS84 average).
|
|
26
|
-
*/
|
|
27
11
|
const KM_PER_DEG_LAT = 111.32
|
|
28
12
|
|
|
29
13
|
/**
|
|
@@ -33,31 +17,15 @@ export type PlaceGeometry =
|
|
|
33
17
|
| { type: "Polygon"; coordinates: number[][][] }
|
|
34
18
|
| { type: "MultiPolygon"; coordinates: number[][][][] }
|
|
35
19
|
|
|
36
|
-
/**
|
|
37
|
-
* A place bounding box in the demo's object form (the WOF points DB carries only these four numbers).
|
|
38
|
-
*/
|
|
39
|
-
export interface PlaceBBox {
|
|
40
|
-
minLat: number
|
|
41
|
-
maxLat: number
|
|
42
|
-
minLon: number
|
|
43
|
-
maxLon: number
|
|
44
|
-
}
|
|
45
|
-
|
|
46
20
|
/**
|
|
47
21
|
* A `[west, south, east, north]` → `[[minLon, minLat], [maxLon, maxLat]]` pair, the shape `fitBounds` wants.
|
|
48
22
|
*/
|
|
49
23
|
export type BoundsTuple = [[number, number], [number, number]]
|
|
50
24
|
|
|
51
|
-
/**
|
|
52
|
-
* Km per degree of longitude at a given latitude — the meridians converge toward the poles.
|
|
53
|
-
*/
|
|
54
25
|
function kmPerDegLon(lat: number): number {
|
|
55
26
|
return KM_PER_DEG_LAT * Math.cos((lat * Math.PI) / 180)
|
|
56
27
|
}
|
|
57
28
|
|
|
58
|
-
/**
|
|
59
|
-
* A closed 64-segment (65-point) GeoJSON ring of `radiusKM` around `[lon, lat]`, with latitude correction.
|
|
60
|
-
*/
|
|
61
29
|
function circleRing(lat: number, lon: number, radiusKM: number): number[][] {
|
|
62
30
|
const perLon = kmPerDegLon(lat)
|
|
63
31
|
const ring: number[][] = []
|
|
@@ -72,11 +40,10 @@ function circleRing(lat: number, lon: number, radiusKM: number): number[][] {
|
|
|
72
40
|
}
|
|
73
41
|
|
|
74
42
|
/**
|
|
75
|
-
*
|
|
76
|
-
* half
|
|
77
|
-
* poles. With no bbox (anchor-centroid postcodes carry no extent) it defaults to a ~ZIP-sized 3 km radius.
|
|
43
|
+
* Returns a circle approximating the extent of a place that has no polygon, with a radius
|
|
44
|
+
* of half the bbox diagonal clamped to 0.5–50 km, or 3 km when there is no bbox.
|
|
78
45
|
*/
|
|
79
|
-
export function approxCircleGeometry(lat: number, lon: number, bbox?:
|
|
46
|
+
export function approxCircleGeometry(lat: number, lon: number, bbox?: LatLonBounds): PlaceGeometry {
|
|
80
47
|
const halfDiagKm = bbox
|
|
81
48
|
? Math.hypot((bbox.maxLat - bbox.minLat) * KM_PER_DEG_LAT, (bbox.maxLon - bbox.minLon) * kmPerDegLon(lat)) / 2
|
|
82
49
|
: 3
|
|
@@ -87,9 +54,8 @@ export function approxCircleGeometry(lat: number, lon: number, bbox?: PlaceBBox)
|
|
|
87
54
|
}
|
|
88
55
|
|
|
89
56
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* honors small radii so an exact building reads as a tight dot (an ~8 m floor keeps a 10 m situs circle visible).
|
|
57
|
+
* Returns a circle with the given radius in meters for street-level uncertainty, floored at 8 m
|
|
58
|
+
* so that a precise point stays visible, unlike {@link approxCircleGeometry}'s 0.5 km floor.
|
|
93
59
|
*/
|
|
94
60
|
export function radiusCircleGeometry(lat: number, lon: number, radiusM: number): PlaceGeometry {
|
|
95
61
|
const radiusKM = Math.max(0.008, radiusM / 1000)
|
|
@@ -98,11 +64,12 @@ export function radiusCircleGeometry(lat: number, lon: number, radiusM: number):
|
|
|
98
64
|
}
|
|
99
65
|
|
|
100
66
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
67
|
+
* Returns the bounding box of a Polygon or MultiPolygon for `fitBounds`.
|
|
68
|
+
*
|
|
69
|
+
* Geometry that crosses the antimeridian gets a naive min/max box, so callers
|
|
70
|
+
* that need a wrapped box must handle it themselves.
|
|
104
71
|
*/
|
|
105
|
-
export function geomBounds(geometry: PlaceGeometry):
|
|
72
|
+
export function geomBounds(geometry: PlaceGeometry): LatLonBounds {
|
|
106
73
|
let minLon = Infinity
|
|
107
74
|
let minLat = Infinity
|
|
108
75
|
let maxLon = -Infinity
|
|
@@ -145,9 +112,9 @@ export function geomBounds(geometry: PlaceGeometry): PlaceBBox {
|
|
|
145
112
|
}
|
|
146
113
|
|
|
147
114
|
/**
|
|
148
|
-
* Reshape a {@link
|
|
115
|
+
* Reshape a {@link LatLonBounds} into the `[[minLon, minLat], [maxLon, maxLat]]` pair `fitBounds` expects.
|
|
149
116
|
*/
|
|
150
|
-
export function bboxToBounds(bbox:
|
|
117
|
+
export function bboxToBounds(bbox: LatLonBounds): BoundsTuple {
|
|
151
118
|
return [
|
|
152
119
|
[bbox.minLon, bbox.minLat],
|
|
153
120
|
[bbox.maxLon, bbox.maxLat],
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The graticule's geometry, apart from its component — the same split `place-render.ts` keeps from
|
|
7
|
+
* `ResolvedPlaceLayers.tsx`. Pure and node-testable; `#*` resolves `.ts` only, so this is also the file the test can
|
|
8
|
+
* import.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { FeatureCollection, MultiLineString } from "geojson"
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Degrees between grid lines. 15° is one hour of longitude — twelve meridians and eleven
|
|
15
|
+
* parallels, dense enough to read as a globe and sparse enough not to read as graph paper.
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_STEP_DEGREES = 15
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Degrees between vertices along each line.
|
|
21
|
+
*
|
|
22
|
+
* A meridian drawn as two points is a straight chord through the sphere under a globe projection.
|
|
23
|
+
* It has to be densified to curve. 2° keeps the longest line under 100 vertices.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The antimeridian, in degrees.
|
|
27
|
+
*
|
|
28
|
+
* Longitude runs [-180, 180]; meridians are drawn from the first bound up to but not including
|
|
29
|
+
* the second, because -180 and 180 are the same line and drawing both puts two strokes on one pixel.
|
|
30
|
+
*/
|
|
31
|
+
const MAX_LONGITUDE = 180
|
|
32
|
+
|
|
33
|
+
const VERTEX_STEP_DEGREES = 2
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The latitude the parallels stop at.
|
|
37
|
+
*
|
|
38
|
+
* Past ~85° the meridians have converged close enough that more rings read as a smudge at the pole.
|
|
39
|
+
* Web Mercator's own limit is 85.051129.
|
|
40
|
+
*/
|
|
41
|
+
const MAX_LATITUDE = 85
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Build the graticule as one MultiLineString.
|
|
45
|
+
*
|
|
46
|
+
* Pure — same step, same geometry — so it is built once at module scope and never rebuilt for a render.
|
|
47
|
+
*/
|
|
48
|
+
export function buildGraticule(stepDegrees: number = DEFAULT_STEP_DEGREES): FeatureCollection<MultiLineString> {
|
|
49
|
+
const lines: number[][][] = []
|
|
50
|
+
|
|
51
|
+
// Meridians: constant longitude, walking latitude pole to pole.
|
|
52
|
+
for (let lon = -MAX_LONGITUDE; lon < MAX_LONGITUDE; lon += stepDegrees) {
|
|
53
|
+
const line: number[][] = []
|
|
54
|
+
|
|
55
|
+
for (let lat = -MAX_LATITUDE; lat <= MAX_LATITUDE; lat += VERTEX_STEP_DEGREES) {
|
|
56
|
+
line.push([lon, lat])
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
line.push([lon, MAX_LATITUDE])
|
|
60
|
+
lines.push(line)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Parallels: constant latitude, walking longitude all the way round.
|
|
64
|
+
// The equator is included.
|
|
65
|
+
// The poles are not.
|
|
66
|
+
for (let lat = -MAX_LATITUDE + stepDegrees; lat < MAX_LATITUDE; lat += stepDegrees) {
|
|
67
|
+
const line: number[][] = []
|
|
68
|
+
|
|
69
|
+
for (let lon = -MAX_LONGITUDE; lon <= MAX_LONGITUDE; lon += VERTEX_STEP_DEGREES) {
|
|
70
|
+
line.push([lon, lat])
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
lines.push(line)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
type: "FeatureCollection",
|
|
78
|
+
features: [{ type: "Feature", properties: {}, geometry: { type: "MultiLineString", coordinates: lines } }],
|
|
79
|
+
}
|
|
80
|
+
}
|
package/lib/map/map-debug.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @file The bare MapLibre control both debug panels portal into.
|
|
6
6
|
*
|
|
7
7
|
* `DashboardMap`'s inspector and the demo page's `_debug.tsx` panel each need an `IControl` whose
|
|
8
|
-
* only job is to own a container element for `createPortal`. The class was duplicated in both
|
|
8
|
+
* only job is to own a container element for `createPortal`. The class was duplicated in both.
|
|
9
9
|
* the position and container class are the only differences, so they are parameters here.
|
|
10
10
|
*/
|
|
11
11
|
|