@kystverket/styrbord-kart 0.0.7 → 0.0.9
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 +12 -8
- package/dist/src/components/CoordinateDirectionField/CoordinateDirectionField.d.ts +9 -0
- package/dist/src/components/{CoordinateDirectionPicker/CoordinateDirectionPicker.stories.d.ts → CoordinateDirectionField/CoordinateDirectionField.stories.d.ts} +8 -2
- package/dist/src/components/{CoordinateDirectionPicker/CoordinateDirectionPicker.types.d.ts → CoordinateDirectionField/CoordinateDirectionField.types.d.ts} +3 -3
- package/dist/src/components/CoordinateField/CoordinateField.d.ts +9 -0
- package/dist/src/components/{CoordinatePicker/CoordinatePicker.stories.d.ts → CoordinateField/CoordinateField.stories.d.ts} +8 -2
- package/dist/src/components/{CoordinatePicker/CoordinatePicker.types.d.ts → CoordinateField/CoordinateField.types.d.ts} +3 -3
- package/dist/src/components/GeoJsonEditor/GeoJsonEditor.d.ts +4 -1
- package/dist/src/components/GeoJsonEditor/GeoJsonEditor.stories.d.ts +39 -3
- package/dist/src/components/GeoJsonEditor/GeoJsonEditor.types.d.ts +45 -1
- package/dist/src/components/GeoJsonEditor/useDirectionalPoints.d.ts +38 -0
- package/dist/src/components/GeoJsonEditor/useTerraDraw.d.ts +21 -3
- package/dist/src/components/GeoJsonViewer/GeoJsonViewer.d.ts +4 -1
- package/dist/src/components/GeoJsonViewer/GeoJsonViewer.stories.d.ts +5 -0
- package/dist/src/components/GeoJsonViewer/GeoJsonViewer.types.d.ts +35 -0
- package/dist/src/components/GeoJsonViewer/GeoJsonViewer.utils.d.ts +26 -0
- package/dist/src/components/GeoJsonViewer/GeoJsonViewerHoverPopup.d.ts +22 -0
- package/dist/src/components/LayerToggle/LayerToggle.d.ts +1 -1
- package/dist/src/components/shared/MapCenterAction.d.ts +22 -0
- package/dist/src/components/shared/MapPicker.types.d.ts +8 -1
- package/dist/src/hooks/useCompassMarker.d.ts +1 -1
- package/dist/src/hooks/useFeatureInteraction.d.ts +51 -0
- package/dist/src/hooks/useMaplibreMap.d.ts +9 -2
- package/dist/src/hooks/useWmsFeatureInfo.d.ts +24 -0
- package/dist/src/main.d.ts +11 -4
- package/dist/src/translations.d.ts +6 -0
- package/dist/src/utility/compassMarker.d.ts +33 -0
- package/dist/src/utility/wmsCatalogLayersContext.d.ts +4 -0
- package/dist/src/utility/wmsGetFeatureInfo.d.ts +42 -0
- package/dist/style.css +1 -1
- package/dist/style.js +9084 -7561
- package/dist/style.umd.cjs +15 -15
- package/package.json +1 -1
- package/dist/src/components/CoordinateDirectionPicker/CoordinateDirectionPicker.d.ts +0 -9
- package/dist/src/components/CoordinatePicker/CoordinatePicker.d.ts +0 -9
package/README.md
CHANGED
|
@@ -10,8 +10,8 @@ Komponentene er laget for å passe sammen med `@kystverket/styrbord`.
|
|
|
10
10
|
|
|
11
11
|
Biblioteket eksporterer blant annet:
|
|
12
12
|
|
|
13
|
-
- `
|
|
14
|
-
- `
|
|
13
|
+
- `CoordinateDirectionField`
|
|
14
|
+
- `CoordinateField`
|
|
15
15
|
- `GeoJsonViewer`
|
|
16
16
|
- `GeoJsonEditor`
|
|
17
17
|
- `GeoJsonAnnotater`
|
|
@@ -31,24 +31,28 @@ I tillegg eksporteres hooks, context-providers og hjelpefunksjoner for lagoppset
|
|
|
31
31
|
Det holder å importere CSS globalt en gang.
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
import
|
|
35
|
-
import
|
|
34
|
+
import "@kystverket/styrbord/style.css";
|
|
35
|
+
import "@kystverket/styrbord-kart/style.css";
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Importering av enkeltkomponenter.
|
|
39
39
|
|
|
40
40
|
```js
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
GeoJsonViewer,
|
|
43
|
+
GeoJsonEditor,
|
|
44
|
+
CoordinateField,
|
|
45
|
+
} from "@kystverket/styrbord-kart";
|
|
42
46
|
```
|
|
43
47
|
|
|
44
48
|
Et enkelt eksempel med visning av GeoJSON.
|
|
45
49
|
|
|
46
50
|
```tsx
|
|
47
|
-
import type { FeatureCollection } from
|
|
48
|
-
import { GeoJsonViewer } from
|
|
51
|
+
import type { FeatureCollection } from "geojson";
|
|
52
|
+
import { GeoJsonViewer } from "@kystverket/styrbord-kart";
|
|
49
53
|
|
|
50
54
|
const data: FeatureCollection = {
|
|
51
|
-
type:
|
|
55
|
+
type: "FeatureCollection",
|
|
52
56
|
features: [],
|
|
53
57
|
};
|
|
54
58
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CoordinateDirectionFieldProps } from "./CoordinateDirectionField.types";
|
|
2
|
+
/**
|
|
3
|
+
* CoordinateDirectionField — select a geographic coordinate and a facing
|
|
4
|
+
* direction (0–360°) via an interactive map or manual input fields.
|
|
5
|
+
*
|
|
6
|
+
* Internally delegates to GeoJsonEditor in single-feature directional-point mode.
|
|
7
|
+
*/
|
|
8
|
+
export declare function CoordinateDirectionField({ value, onChange, error, disabled, className, height, showCenterAction, }: CoordinateDirectionFieldProps): React.JSX.Element;
|
|
9
|
+
export default CoordinateDirectionField;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { CoordinateDirectionField } from "./CoordinateDirectionField";
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
|
-
component: typeof
|
|
5
|
+
component: typeof CoordinateDirectionField;
|
|
6
6
|
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn) => React.JSX.Element)[];
|
|
7
7
|
tags: string[];
|
|
8
8
|
parameters: {
|
|
9
9
|
layout: string;
|
|
10
|
+
docs: {
|
|
11
|
+
story: {
|
|
12
|
+
inline: boolean;
|
|
13
|
+
iframeHeight: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
10
16
|
};
|
|
11
17
|
};
|
|
12
18
|
export default meta;
|
|
@@ -15,9 +15,9 @@ export type CoordinateDirectionGeoJSON = CoordinateGeoJSON & {
|
|
|
15
15
|
direction: number;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
|
-
export interface
|
|
18
|
+
export interface CoordinateDirectionFieldProps extends MapPickerBaseProps {
|
|
19
19
|
/** Controlled value. */
|
|
20
|
-
value
|
|
20
|
+
value: CoordinateDirectionGeoJSON | undefined;
|
|
21
21
|
/** Called when the user changes the coordinate or direction. */
|
|
22
|
-
onChange
|
|
22
|
+
onChange: (value: CoordinateDirectionGeoJSON) => void;
|
|
23
23
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CoordinateFieldProps } from "./CoordinateField.types";
|
|
2
|
+
/**
|
|
3
|
+
* CoordinateField — select a geographic coordinate via an interactive map
|
|
4
|
+
* or manual input fields.
|
|
5
|
+
*
|
|
6
|
+
* Internally delegates to GeoJsonEditor in single-feature point mode.
|
|
7
|
+
*/
|
|
8
|
+
export declare function CoordinateField({ value, onChange, error, disabled, className, height, showCenterAction, }: CoordinateFieldProps): React.JSX.Element;
|
|
9
|
+
export default CoordinateField;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { CoordinateField } from "./CoordinateField";
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
|
-
component: typeof
|
|
5
|
+
component: typeof CoordinateField;
|
|
6
6
|
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn) => React.JSX.Element)[];
|
|
7
7
|
tags: string[];
|
|
8
8
|
parameters: {
|
|
9
9
|
layout: string;
|
|
10
|
+
docs: {
|
|
11
|
+
story: {
|
|
12
|
+
inline: boolean;
|
|
13
|
+
iframeHeight: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
10
16
|
};
|
|
11
17
|
};
|
|
12
18
|
export default meta;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { CoordinateGeoJSON } from "~/utility/types";
|
|
2
2
|
import type { MapPickerBaseProps } from "~/components/shared/MapPicker.types";
|
|
3
|
-
export interface
|
|
3
|
+
export interface CoordinateFieldProps extends MapPickerBaseProps {
|
|
4
4
|
/** Controlled value — a GeoJSON Point Feature. */
|
|
5
|
-
value
|
|
5
|
+
value: CoordinateGeoJSON | undefined;
|
|
6
6
|
/** Called when the user places or changes the coordinate. */
|
|
7
|
-
onChange
|
|
7
|
+
onChange: (value: CoordinateGeoJSON) => void;
|
|
8
8
|
}
|
|
@@ -5,6 +5,9 @@ import type { GeoJsonEditorProps } from "./GeoJsonEditor.types";
|
|
|
5
5
|
*
|
|
6
6
|
* Uses terra-draw for interactive drawing and editing. Emits the full
|
|
7
7
|
* FeatureCollection via `onChange` on every change.
|
|
8
|
+
*
|
|
9
|
+
* Supports feature hover (with customizable content per type) and selection
|
|
10
|
+
* callbacks when using terra-draw's select mode.
|
|
8
11
|
*/
|
|
9
|
-
export declare function GeoJsonEditor({ value, onChange, modes, editable, deletable, fitBounds, fitBoundsPadding, showLayerToggle, height, className, disabled, }: GeoJsonEditorProps): React.JSX.Element;
|
|
12
|
+
export declare function GeoJsonEditor({ value, onChange, modes, editable, deletable, fitBounds, fitBoundsPadding, showLayerToggle, height, className, disabled, hoverable, onHover, onSelect, hoverContent, onCoordinateClick, showCenterAction, singleFeature, }: GeoJsonEditorProps): React.JSX.Element;
|
|
10
13
|
export default GeoJsonEditor;
|
|
@@ -7,16 +7,52 @@ declare const meta: {
|
|
|
7
7
|
tags: string[];
|
|
8
8
|
parameters: {
|
|
9
9
|
layout: string;
|
|
10
|
+
docs: {
|
|
11
|
+
story: {
|
|
12
|
+
inline: boolean;
|
|
13
|
+
iframeHeight: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
10
16
|
};
|
|
11
17
|
};
|
|
12
18
|
export default meta;
|
|
13
19
|
type Story = StoryObj<typeof meta>;
|
|
20
|
+
/**
|
|
21
|
+
* The default state: an empty map with all drawing tools available.
|
|
22
|
+
* Use the toolbar to draw points, lines, and polygons.
|
|
23
|
+
*/
|
|
14
24
|
export declare const Default: Story;
|
|
25
|
+
/**
|
|
26
|
+
* The editor pre-loaded with a FeatureCollection containing a polygon (Ålesund
|
|
27
|
+
* Havn), a point (Kråkenes Fyr) and a linestring (Hovedled Sør–Nord).
|
|
28
|
+
* `fitBounds` zooms the map to fit all features on mount.
|
|
29
|
+
*/
|
|
15
30
|
export declare const WithInitialData: Story;
|
|
31
|
+
export declare const Controlled: Story;
|
|
32
|
+
/** Only the point tool is available in the toolbar. */
|
|
16
33
|
export declare const PointsOnly: Story;
|
|
34
|
+
/** Only the linestring tool is available in the toolbar. */
|
|
17
35
|
export declare const LinesOnly: Story;
|
|
36
|
+
/** Only the polygon tool is available in the toolbar. */
|
|
18
37
|
export declare const PolygonsOnly: Story;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Only directional-point mode. Each placed point stores a `direction` angle
|
|
40
|
+
* (0–360°) that can be used to represent headings, bearings, etc.
|
|
41
|
+
*/
|
|
42
|
+
export declare const DirectionalPointsOnly: Story;
|
|
43
|
+
export declare const DirectionalControlled: Story;
|
|
44
|
+
/**
|
|
45
|
+
* `disabled` removes the toolbar and all interaction. Use this to display
|
|
46
|
+
* GeoJSON data without allowing any edits.
|
|
47
|
+
*/
|
|
48
|
+
export declare const ReadOnly: Story;
|
|
49
|
+
export declare const WithHoverContent: Story;
|
|
50
|
+
/**
|
|
51
|
+
* Shows the built-in layer toggle control. Requires the full layer context
|
|
52
|
+
* stack (`ViewBoundsProvider`, `BaseLayersProvider`, etc.).
|
|
53
|
+
*/
|
|
22
54
|
export declare const WithLayerToggle: Story;
|
|
55
|
+
export declare const SingleFeaturePoint: Story;
|
|
56
|
+
export declare const SingleFeatureDirectionalPoint: Story;
|
|
57
|
+
/** `singleFeature` with `polygon` mode — only one polygon at a time. */
|
|
58
|
+
export declare const SingleFeaturePolygon: Story;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Feature, FeatureCollection, GeoJsonProperties, Geometry } from "geojson";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type maplibregl from "maplibre-gl";
|
|
2
4
|
import type { MapBaseProps } from "../shared/MapPicker.types";
|
|
5
|
+
import type { InteractiveFeature } from "~/hooks/useFeatureInteraction";
|
|
6
|
+
import type { CoordinateClickResult } from "~/utility/wmsGetFeatureInfo";
|
|
3
7
|
/** Drawing modes available in the editor toolbar. */
|
|
4
|
-
export type DrawMode = "point" | "linestring" | "polygon";
|
|
8
|
+
export type DrawMode = "point" | "linestring" | "polygon" | "directional-point";
|
|
5
9
|
export interface GeoJsonEditorProps extends MapBaseProps {
|
|
6
10
|
/** Current GeoJSON value (controlled). Accepts a Feature or FeatureCollection. */
|
|
7
11
|
value?: Feature<Geometry, GeoJsonProperties> | FeatureCollection<Geometry, GeoJsonProperties>;
|
|
@@ -25,4 +29,44 @@ export interface GeoJsonEditorProps extends MapBaseProps {
|
|
|
25
29
|
fitBoundsPadding?: number;
|
|
26
30
|
/** Whether to show the layer toggle control on the map. Defaults to `false`. */
|
|
27
31
|
showLayerToggle?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Whether features can be hovered to show tooltips. Defaults to `true`.
|
|
34
|
+
*/
|
|
35
|
+
hoverable?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Called when the hovered feature changes.
|
|
38
|
+
* Receives the feature and the original mouse event, or null when hover ends.
|
|
39
|
+
*/
|
|
40
|
+
onHover?: (feature: InteractiveFeature | null, event: maplibregl.MapMouseEvent | null) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Called when the selection changes (via click or terra-draw selection).
|
|
43
|
+
* Receives array of selected features, or null when selection is cleared.
|
|
44
|
+
*/
|
|
45
|
+
onSelect?: (features: InteractiveFeature[] | null) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Custom render functions for hover content based on the feature's `type` property.
|
|
48
|
+
* Keys are the `properties.type` values; the function receives the hovered feature
|
|
49
|
+
* and returns the content to display in the hover popup.
|
|
50
|
+
*
|
|
51
|
+
* If a feature's type is not in this map, the default content (type name) is shown.
|
|
52
|
+
*/
|
|
53
|
+
hoverContent?: Record<string, (feature: InteractiveFeature) => ReactNode>;
|
|
54
|
+
/**
|
|
55
|
+
* Called when the user clicks on the map (while not actively drawing).
|
|
56
|
+
* The result includes the clicked coordinate and WMS GetFeatureInfo
|
|
57
|
+
* results for all visible WMS catalog layers.
|
|
58
|
+
*/
|
|
59
|
+
onCoordinateClick?: (result: CoordinateClickResult) => void;
|
|
60
|
+
/**
|
|
61
|
+
* When `true`, only one feature can exist at a time. The feature type is
|
|
62
|
+
* determined by `modes[0]` (which should contain exactly one mode).
|
|
63
|
+
*
|
|
64
|
+
* - The toolbar is hidden and drawing mode is auto-activated.
|
|
65
|
+
* - Placing a new feature automatically replaces the existing one.
|
|
66
|
+
*
|
|
67
|
+
* This allows GeoJsonEditor to be used as a drop-in replacement for
|
|
68
|
+
* `CoordinateField` (with `modes: ['point']`) or
|
|
69
|
+
* `CoordinateDirectionField` (with `modes: ['directional-point']`).
|
|
70
|
+
*/
|
|
71
|
+
singleFeature?: boolean;
|
|
28
72
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { MutableRefObject } from "react";
|
|
2
|
+
import type { Map as MaplibreMap } from "maplibre-gl";
|
|
3
|
+
import type { Feature, Point } from "geojson";
|
|
4
|
+
export interface DirectionalPointFeature extends Feature<Point> {
|
|
5
|
+
properties: {
|
|
6
|
+
id: string;
|
|
7
|
+
direction: number;
|
|
8
|
+
mode: "directional-point";
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface UseDirectionalPointsOptions {
|
|
13
|
+
mapRef: MutableRefObject<MaplibreMap | null>;
|
|
14
|
+
/** Must be `true` before the click handler is installed (set by `useMaplibreMap`). */
|
|
15
|
+
mapReady: boolean;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
/** Current active editor mode — the hook only places points when this is 'directional-point'. */
|
|
18
|
+
activeMode: string;
|
|
19
|
+
/** When true, only one directional point is allowed — new points replace existing ones. */
|
|
20
|
+
singleFeature?: boolean;
|
|
21
|
+
onChange?: () => void;
|
|
22
|
+
onSelect?: (feature: DirectionalPointFeature | null) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface UseDirectionalPointsResult {
|
|
25
|
+
/** Whether a directional point is currently selected. */
|
|
26
|
+
hasSelection: boolean;
|
|
27
|
+
/** Delete the currently selected directional point. */
|
|
28
|
+
deleteSelected: () => void;
|
|
29
|
+
/** Get all directional-point features for merging into the emitted FeatureCollection. */
|
|
30
|
+
getFeatures: () => DirectionalPointFeature[];
|
|
31
|
+
/** Load initial directional-point features (called once on mount). */
|
|
32
|
+
loadFeatures: (features: DirectionalPointFeature[]) => void;
|
|
33
|
+
/** Replace all directional-point features (clears existing markers before loading). */
|
|
34
|
+
replaceFeatures: (features: DirectionalPointFeature[]) => void;
|
|
35
|
+
/** Deselect any selected directional point. */
|
|
36
|
+
deselect: () => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function useDirectionalPoints({ mapRef, mapReady, disabled, activeMode, singleFeature, onChange, onSelect, }: UseDirectionalPointsOptions): UseDirectionalPointsResult;
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import type { MutableRefObject } from "react";
|
|
2
2
|
import type { Map as MaplibreMap } from "maplibre-gl";
|
|
3
|
-
import type { FeatureCollection } from "geojson";
|
|
3
|
+
import type { FeatureCollection, Feature, Geometry, GeoJsonProperties } from "geojson";
|
|
4
4
|
import type { DrawMode } from "./GeoJsonEditor.types";
|
|
5
|
+
/** Drawing modes that terra-draw handles natively. */
|
|
6
|
+
type TerraDrawableMode = Exclude<DrawMode, "directional-point">;
|
|
5
7
|
export interface UseTerraDrawOptions {
|
|
6
8
|
mapRef: MutableRefObject<MaplibreMap | null>;
|
|
7
|
-
|
|
9
|
+
/** Must be `true` before terra-draw will initialise (set by `useMaplibreMap`). */
|
|
10
|
+
mapReady: boolean;
|
|
11
|
+
modes: TerraDrawableMode[];
|
|
8
12
|
editable: boolean;
|
|
9
13
|
deletable: boolean;
|
|
10
14
|
disabled: boolean;
|
|
15
|
+
/** When true, only one feature is allowed — new features replace existing ones. */
|
|
16
|
+
singleFeature?: boolean;
|
|
11
17
|
onChange?: (data: FeatureCollection) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Called when selection changes (features selected or deselected).
|
|
20
|
+
* Receives array of selected features, or null when selection is cleared.
|
|
21
|
+
*/
|
|
22
|
+
onSelect?: (features: Feature<Geometry, GeoJsonProperties>[] | null) => void;
|
|
12
23
|
}
|
|
13
24
|
export interface UseTerraDrawResult {
|
|
14
25
|
activeMode: string;
|
|
15
26
|
setActiveMode: (mode: string) => void;
|
|
16
27
|
deleteSelected: () => void;
|
|
17
28
|
hasSelection: boolean;
|
|
29
|
+
/** Currently selected features. */
|
|
30
|
+
selectedFeatures: Feature<Geometry, GeoJsonProperties>[];
|
|
31
|
+
/** Get the current snapshot of all features. */
|
|
32
|
+
getSnapshot: () => Feature<Geometry, GeoJsonProperties>[];
|
|
33
|
+
/** True once terra-draw has been initialised and is ready to accept features. */
|
|
34
|
+
isReady: boolean;
|
|
18
35
|
}
|
|
19
|
-
export declare function useTerraDraw({ mapRef, modes, editable, deletable, disabled, onChange, }: UseTerraDrawOptions): UseTerraDrawResult;
|
|
36
|
+
export declare function useTerraDraw({ mapRef, mapReady, modes, editable, deletable, disabled, singleFeature, onChange, onSelect, }: UseTerraDrawOptions): UseTerraDrawResult;
|
|
37
|
+
export {};
|
|
@@ -4,6 +4,9 @@ import type { GeoJsonViewerProps } from "./GeoJsonViewer.types";
|
|
|
4
4
|
*
|
|
5
5
|
* Renders Point, LineString, Polygon (and their Multi-variants) using
|
|
6
6
|
* MapLibre GL layers. The map auto-fits to the data bounds by default.
|
|
7
|
+
*
|
|
8
|
+
* Supports feature hover (with customizable content per type) and selection
|
|
9
|
+
* (single or multi-select with Ctrl/Cmd).
|
|
7
10
|
*/
|
|
8
|
-
export declare function GeoJsonViewer({ data, fitBounds, fitBoundsPadding, geoJsonStyle: styleProp, showLayerToggle, height, className, disabled, }: GeoJsonViewerProps): React.JSX.Element;
|
|
11
|
+
export declare function GeoJsonViewer({ data, fitBounds, fitBoundsPadding, geoJsonStyle: styleProp, showLayerToggle, height, className, disabled, hoverable, selectable, onHover, onSelect, hoverContent, onCoordinateClick, showCenterAction, }: GeoJsonViewerProps): React.JSX.Element;
|
|
9
12
|
export default GeoJsonViewer;
|
|
@@ -18,3 +18,8 @@ export declare const CustomStyle: Story;
|
|
|
18
18
|
export declare const TallMap: Story;
|
|
19
19
|
export declare const ComplexMultiType: Story;
|
|
20
20
|
export declare const WithLayerToggle: Story;
|
|
21
|
+
export declare const Interactive: Story;
|
|
22
|
+
export declare const SelectionDemo: Story;
|
|
23
|
+
export declare const HoverOnly: Story;
|
|
24
|
+
export declare const NonInteractive: Story;
|
|
25
|
+
export declare const CoordinateClick: Story;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Feature, FeatureCollection, GeoJsonProperties, Geometry } from "geojson";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type maplibregl from "maplibre-gl";
|
|
2
4
|
import { MapBaseProps } from "../shared/MapPicker.types";
|
|
5
|
+
import type { InteractiveFeature } from "~/hooks/useFeatureInteraction";
|
|
6
|
+
import type { CoordinateClickResult } from "~/utility/wmsGetFeatureInfo";
|
|
3
7
|
/**
|
|
4
8
|
* Styling options for the GeoJSON layers rendered on the map.
|
|
5
9
|
*/
|
|
@@ -35,4 +39,35 @@ export interface GeoJsonViewerProps extends MapBaseProps {
|
|
|
35
39
|
className?: string;
|
|
36
40
|
/** Whether to show the layer toggle control on the map. Defaults to `false`. */
|
|
37
41
|
showLayerToggle?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Whether features can be hovered to show tooltips. Defaults to `true`.
|
|
44
|
+
*/
|
|
45
|
+
hoverable?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether features can be clicked to select them. Defaults to `true`.
|
|
48
|
+
*/
|
|
49
|
+
selectable?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Called when the hovered feature changes.
|
|
52
|
+
* Receives the feature and the original mouse event, or null when hover ends.
|
|
53
|
+
*/
|
|
54
|
+
onHover?: (feature: InteractiveFeature | null, event: maplibregl.MapMouseEvent | null) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Called when the selection changes.
|
|
57
|
+
* Receives array of selected features, or null when selection is cleared.
|
|
58
|
+
*/
|
|
59
|
+
onSelect?: (features: InteractiveFeature[] | null) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Custom render functions for hover content based on the feature's `type` property.
|
|
62
|
+
* Keys are the `properties.type` values; the function receives the hovered feature
|
|
63
|
+
* and returns the content to display in the hover popup.
|
|
64
|
+
*
|
|
65
|
+
* If a feature's type is not in this map, the default content (type name) is shown.
|
|
66
|
+
*/
|
|
67
|
+
hoverContent?: Record<string, (feature: InteractiveFeature) => ReactNode>;
|
|
68
|
+
/**
|
|
69
|
+
* Called when the user clicks on the map. The result includes the clicked
|
|
70
|
+
* coordinate and WMS GetFeatureInfo results for all visible WMS catalog layers.
|
|
71
|
+
*/
|
|
72
|
+
onCoordinateClick?: (result: CoordinateClickResult) => void;
|
|
38
73
|
}
|
|
@@ -8,6 +8,17 @@ export declare const LINE_LAYER = "geojson-line";
|
|
|
8
8
|
export declare const POINT_STROKE_LAYER = "geojson-point-stroke";
|
|
9
9
|
export declare const POINT_LAYER = "geojson-point";
|
|
10
10
|
export declare const ALL_LAYERS: string[];
|
|
11
|
+
export declare const HOVER_FILL_LAYER = "geojson-hover-fill";
|
|
12
|
+
export declare const HOVER_LINE_LAYER = "geojson-hover-line";
|
|
13
|
+
export declare const HOVER_POINT_LAYER = "geojson-hover-point";
|
|
14
|
+
export declare const SELECTED_FILL_LAYER = "geojson-selected-fill";
|
|
15
|
+
export declare const SELECTED_LINE_LAYER = "geojson-selected-line";
|
|
16
|
+
export declare const SELECTED_POINT_LAYER = "geojson-selected-point";
|
|
17
|
+
export declare const HIGHLIGHT_LAYERS: string[];
|
|
18
|
+
export declare const INTERACTIVE_LAYERS: string[];
|
|
19
|
+
export declare const HOVER_COLOR = "rgba(0, 98, 186, 0.4)";
|
|
20
|
+
export declare const SELECTED_COLOR = "#0062ba";
|
|
21
|
+
export declare const SELECTED_GLOW_COLOR = "rgba(0, 98, 186, 0.5)";
|
|
11
22
|
/**
|
|
12
23
|
* Normalise a Feature or FeatureCollection into a **clean** FeatureCollection.
|
|
13
24
|
*
|
|
@@ -18,3 +29,18 @@ export declare const ALL_LAYERS: string[];
|
|
|
18
29
|
export declare function toFeatureCollection(data: GeoJsonViewerProps["data"]): FeatureCollection;
|
|
19
30
|
/** Remove all GeoJSON layers and the source from the map, ignoring errors. */
|
|
20
31
|
export declare function removeLayers(map: maplibregl.Map): void;
|
|
32
|
+
/**
|
|
33
|
+
* Add highlight layers for hover and selection effects.
|
|
34
|
+
* These layers use filters to show only specific features.
|
|
35
|
+
*/
|
|
36
|
+
export declare function addHighlightLayers(map: maplibregl.Map, style: Required<GeoJsonStyle>): void;
|
|
37
|
+
/**
|
|
38
|
+
* Update the filter on hover highlight layers to show only the specified feature.
|
|
39
|
+
* Pass null to hide all hover highlights.
|
|
40
|
+
*/
|
|
41
|
+
export declare function updateHoverHighlight(map: maplibregl.Map, featureId: string | number | null): void;
|
|
42
|
+
/**
|
|
43
|
+
* Update the filter on selection highlight layers to show only the specified features.
|
|
44
|
+
* Pass empty array to hide all selection highlights.
|
|
45
|
+
*/
|
|
46
|
+
export declare function updateSelectionHighlight(map: maplibregl.Map, featureIds: (string | number)[]): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { InteractiveFeature } from "~/hooks/useFeatureInteraction";
|
|
3
|
+
export interface GeoJsonViewerHoverPopupProps {
|
|
4
|
+
/** The feature currently being hovered. */
|
|
5
|
+
feature: InteractiveFeature;
|
|
6
|
+
/** Position of the popup relative to the map container. */
|
|
7
|
+
position: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Custom render functions for hover content based on the feature's `type` property.
|
|
13
|
+
* Keys are the `properties.type` values; the function receives the hovered feature
|
|
14
|
+
* and returns the content to display.
|
|
15
|
+
*/
|
|
16
|
+
hoverContent?: Record<string, (feature: InteractiveFeature) => ReactNode>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Popup component that displays when hovering over a map feature.
|
|
20
|
+
* Content is customizable per feature type via the `hoverContent` prop.
|
|
21
|
+
*/
|
|
22
|
+
export declare function GeoJsonViewerHoverPopup({ feature, position, hoverContent, }: GeoJsonViewerHoverPopupProps): React.JSX.Element;
|
|
@@ -15,4 +15,4 @@ import type { LayerToggleProps } from "./LayerToggle.types";
|
|
|
15
15
|
* </div>
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
export declare function LayerToggle({ className, defaultOpen, }: LayerToggleProps): React.JSX.Element;
|
|
18
|
+
export declare function LayerToggle({ className, defaultOpen, }: LayerToggleProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import type maplibregl from "maplibre-gl";
|
|
3
|
+
export interface MapCenterActionProps {
|
|
4
|
+
/** Ref to the MapLibre map instance. */
|
|
5
|
+
mapRef: RefObject<maplibregl.Map | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Controls visibility.
|
|
8
|
+
* - `true` — always visible
|
|
9
|
+
* - `false` — always hidden
|
|
10
|
+
* - `undefined` — auto-detect (visible on touch devices)
|
|
11
|
+
*/
|
|
12
|
+
visible?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* MapCenterAction — renders a crosshair at the map center and a button
|
|
16
|
+
* that triggers a synthetic click at the center of the map.
|
|
17
|
+
*
|
|
18
|
+
* Shown by default on touch-primary devices (pointer: coarse).
|
|
19
|
+
* Can be overridden with the `visible` prop.
|
|
20
|
+
*/
|
|
21
|
+
export declare function MapCenterAction({ mapRef, visible }: MapCenterActionProps): React.JSX.Element | null;
|
|
22
|
+
export default MapCenterAction;
|
|
@@ -8,10 +8,17 @@ export interface MapBaseProps {
|
|
|
8
8
|
className?: string;
|
|
9
9
|
/** Height of the map container. Defaults to `"400px"`. */
|
|
10
10
|
height?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Show a crosshair at the map center with a button to trigger a click there.
|
|
13
|
+
* - `true` — always visible
|
|
14
|
+
* - `false` — always hidden
|
|
15
|
+
* - `undefined` — auto-detect (visible on touch devices)
|
|
16
|
+
*/
|
|
17
|
+
showCenterAction?: boolean;
|
|
11
18
|
}
|
|
12
19
|
/**
|
|
13
20
|
* Common props shared by all map-based picker components
|
|
14
|
-
* (
|
|
21
|
+
* (CoordinateField, CoordinateDirectionField, etc.).
|
|
15
22
|
*/
|
|
16
23
|
export interface MapPickerBaseProps extends MapBaseProps {
|
|
17
24
|
/** Label displayed above the component. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import maplibregl from "maplibre-gl";
|
|
2
|
-
import type { CoordinateDirectionValue } from "~/components/
|
|
2
|
+
import type { CoordinateDirectionValue } from "~/components/CoordinateDirectionField/CoordinateDirectionField.types";
|
|
3
3
|
export interface UseCompassMarkerOptions {
|
|
4
4
|
/** The MapLibre map instance to attach the marker to. */
|
|
5
5
|
mapRef: React.RefObject<maplibregl.Map | null>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Feature, GeoJsonProperties, Geometry } from "geojson";
|
|
2
|
+
import type maplibregl from "maplibre-gl";
|
|
3
|
+
/**
|
|
4
|
+
* A GeoJSON feature with an optional numeric ID for MapLibre compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export type InteractiveFeature = Feature<Geometry, GeoJsonProperties> & {
|
|
7
|
+
id?: string | number;
|
|
8
|
+
};
|
|
9
|
+
export interface UseFeatureInteractionOptions {
|
|
10
|
+
/** Reference to the MapLibre map instance. */
|
|
11
|
+
mapRef: React.RefObject<maplibregl.Map | null>;
|
|
12
|
+
/** Layer IDs to query for features. */
|
|
13
|
+
layerIds: string[];
|
|
14
|
+
/** Source ID for the GeoJSON data. */
|
|
15
|
+
sourceId: string;
|
|
16
|
+
/** Whether feature interaction is enabled. Defaults to `true`. */
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
/** Whether hover interaction is enabled. Defaults to `true`. */
|
|
19
|
+
hoverable?: boolean;
|
|
20
|
+
/** Whether click/selection interaction is enabled. Defaults to `true`. */
|
|
21
|
+
selectable?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Called when hovered feature changes.
|
|
24
|
+
* Receives the feature and the original mouse event, or null when hover ends.
|
|
25
|
+
*/
|
|
26
|
+
onHover?: (feature: InteractiveFeature | null, event: maplibregl.MapMouseEvent | null) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Called when selection changes.
|
|
29
|
+
* Receives array of selected features, or null when selection is cleared.
|
|
30
|
+
*/
|
|
31
|
+
onSelect?: (features: InteractiveFeature[] | null) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface UseFeatureInteractionResult {
|
|
34
|
+
/** Currently hovered feature, or null. */
|
|
35
|
+
hoveredFeature: InteractiveFeature | null;
|
|
36
|
+
/** Currently selected features. */
|
|
37
|
+
selectedFeatures: InteractiveFeature[];
|
|
38
|
+
/** Whether any feature is currently selected. */
|
|
39
|
+
hasSelection: boolean;
|
|
40
|
+
/** Programmatically clear the selection. */
|
|
41
|
+
clearSelection: () => void;
|
|
42
|
+
/** Programmatically select features by their IDs. */
|
|
43
|
+
selectByIds: (ids: (string | number)[]) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Hook for managing feature hover and selection interactions on a MapLibre map.
|
|
47
|
+
*
|
|
48
|
+
* Features are queried using `queryRenderedFeatures` when the user hovers or clicks.
|
|
49
|
+
* Supports multi-selection via Ctrl/Cmd modifier keys.
|
|
50
|
+
*/
|
|
51
|
+
export declare function useFeatureInteraction({ mapRef, layerIds, sourceId, enabled, hoverable, selectable, onHover, onSelect, }: UseFeatureInteractionOptions): UseFeatureInteractionResult;
|
|
@@ -14,10 +14,17 @@ export interface UseMaplibreMapOptions {
|
|
|
14
14
|
/**
|
|
15
15
|
* Manages a MapLibre GL map instance.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* The map is created lazily — only once the container div enters the viewport.
|
|
18
|
+
* This prevents "Too many active WebGL contexts" warnings when many map
|
|
19
|
+
* components are rendered off-screen simultaneously (e.g. Storybook Docs).
|
|
20
|
+
*
|
|
21
|
+
* Returns refs for the container element and the map, plus a `mapReady` flag
|
|
22
|
+
* that is `true` once the map instance has been created. Callers that set up
|
|
23
|
+
* map event handlers or layers must include `mapReady` in their effect
|
|
24
|
+
* dependency arrays so those effects re-run once the map is available.
|
|
19
25
|
*/
|
|
20
26
|
export declare function useMaplibreMap({ initialCoordinate, disabled, onMapClick, height, }?: UseMaplibreMapOptions): {
|
|
21
27
|
mapContainerRef: React.RefObject<HTMLDivElement | null>;
|
|
22
28
|
mapRef: React.RefObject<maplibregl.Map | null>;
|
|
29
|
+
mapReady: boolean;
|
|
23
30
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type maplibregl from "maplibre-gl";
|
|
2
|
+
import type { Coordinate } from "~/utility/types";
|
|
3
|
+
import type { CoordinateClickResult } from "~/utility/wmsGetFeatureInfo";
|
|
4
|
+
export interface UseWmsFeatureInfoOptions {
|
|
5
|
+
/** Ref to the MapLibre map instance (needed for bounds / size). */
|
|
6
|
+
mapRef: React.RefObject<maplibregl.Map | null>;
|
|
7
|
+
/** The coordinate to query. Set to `null` when no query is pending. */
|
|
8
|
+
coordinate: Coordinate | null;
|
|
9
|
+
/** Whether the hook is active. Defaults to `true`. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface UseWmsFeatureInfoResult {
|
|
13
|
+
/** Whether a GetFeatureInfo query is currently in flight. */
|
|
14
|
+
loading: boolean;
|
|
15
|
+
/** The latest result, or null if no query has been made yet. */
|
|
16
|
+
result: CoordinateClickResult | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Hook that queries WMS GetFeatureInfo for all visible WMS catalog layers
|
|
20
|
+
* when a coordinate is provided.
|
|
21
|
+
*
|
|
22
|
+
* Automatically cancels in-flight requests when a new coordinate is set.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useWmsFeatureInfo({ mapRef, coordinate, enabled, }: UseWmsFeatureInfoOptions): UseWmsFeatureInfoResult;
|