@orioro/react-maplibre-util 0.3.2 → 0.5.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/CHANGELOG.md +17 -0
- package/README.md +0 -1
- package/dist/Controls/InspectControl/InspectControl.d.ts +0 -1
- package/dist/CustomSprite/CustomSprite.d.ts +5 -0
- package/dist/CustomSprite/index.d.ts +1 -0
- package/dist/DynamicImages/DynamicImages.d.ts +7 -0
- package/dist/DynamicImages/index.d.ts +2 -0
- package/dist/DynamicImages/svgImages/assets.d.ts +1 -0
- package/dist/DynamicImages/svgImages/index.d.ts +32 -0
- package/dist/LayeredMap/LayeredMap.d.ts +1 -0
- package/dist/LayeredMap/index.d.ts +1 -0
- package/dist/LayeredMap/layeredMapOnClickHandler.d.ts +16 -0
- package/dist/LayeredMap/parseMapViews.d.ts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +210 -14
- package/dist/types.d.ts +2 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# @orioro/react-maplibre-util
|
2
2
|
|
3
|
+
## 0.5.0
|
4
|
+
|
5
|
+
### Minor Changes
|
6
|
+
|
7
|
+
- implement onClick handler on LayeredMap layers; implement DynamicImage component and CustomSprite
|
8
|
+
|
9
|
+
## 0.4.0
|
10
|
+
|
11
|
+
### Minor Changes
|
12
|
+
|
13
|
+
- implement proof-of-concept of hover interaction on legend
|
14
|
+
|
15
|
+
### Patch Changes
|
16
|
+
|
17
|
+
- Updated dependencies
|
18
|
+
- @orioro/react-chart-util@0.2.0
|
19
|
+
|
3
20
|
## 0.3.2
|
4
21
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
# Template react lib
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './CustomSprite';
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { Map, MapStyleImageMissingEvent, StyleImageMetadata } from 'maplibre-gl';
|
2
|
+
type OnGenerateImageRes = Parameters<Map['addImage']>[1] | [Parameters<Map['addImage']>[1], Partial<StyleImageMetadata>];
|
3
|
+
type DynamicImagesProps = {
|
4
|
+
onGenerateImage: (imageId: string, event: MapStyleImageMissingEvent) => OnGenerateImageRes | Promise<OnGenerateImageRes>;
|
5
|
+
};
|
6
|
+
export declare function DynamicImages({ onGenerateImage }: DynamicImagesProps): null;
|
7
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const MARKER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg fill=\"#000000\" width=\"800px\" height=\"800px\" viewBox=\"-64 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0z\"/></svg>";
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { StyleImageMetadata } from 'maplibre-gl';
|
2
|
+
type IconPathToSvgOptions = {
|
3
|
+
size?: number;
|
4
|
+
fill?: string;
|
5
|
+
stroke?: string;
|
6
|
+
strokeWidth?: string | number;
|
7
|
+
viewBox?: string;
|
8
|
+
style?: string;
|
9
|
+
};
|
10
|
+
export declare function iconPathToSvg(path: string, { size, fill, stroke, strokeWidth, viewBox, style, }?: IconPathToSvgOptions): string;
|
11
|
+
/**
|
12
|
+
* Renders an SVG string onto a canvas and returns an object compatible with maplibre `addImage`.
|
13
|
+
*
|
14
|
+
* @param svgString - The SVG markup as a string
|
15
|
+
* @param pixelRatio - (Optional) device pixel ratio, defaults to window.devicePixelRatio
|
16
|
+
* @returns Promise resolving to { width, height, data, pixelRatio }
|
17
|
+
*/
|
18
|
+
export declare function svgToMaplibreImage(svgString: string, pixelRatio?: number): Promise<[
|
19
|
+
{
|
20
|
+
width: number;
|
21
|
+
height: number;
|
22
|
+
data: Uint8ClampedArray;
|
23
|
+
},
|
24
|
+
Partial<StyleImageMetadata>
|
25
|
+
]>;
|
26
|
+
export declare function svgIconId(iconId: string, options?: IconPathToSvgOptions): string;
|
27
|
+
export declare function svgIconGenerator(iconPathsById: Record<string, string>): (imageId: string) => Promise<[{
|
28
|
+
width: number;
|
29
|
+
height: number;
|
30
|
+
data: Uint8ClampedArray;
|
31
|
+
}, Partial<StyleImageMetadata>]>;
|
32
|
+
export {};
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
2
2
|
import { MapInstance } from 'react-map-gl/maplibre';
|
3
3
|
import { LayeredMapProps } from '../types';
|
4
4
|
import { augmentFeature, getSrcLayer, getSrcViewByLayerId } from './parseMapViews';
|
5
|
+
export declare function useLayeredMap(): null;
|
5
6
|
export declare const LayeredMap: React.ForwardRefExoticComponent<Omit<LayeredMapProps, "ref"> & React.RefAttributes<{
|
6
7
|
map: MapInstance;
|
7
8
|
augmentFeature: (feature: Parameters<typeof augmentFeature>[1]) => ReturnType<typeof augmentFeature>;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { MapGeoJSONFeature, MapMouseEvent } from 'maplibre-gl';
|
2
|
+
import { Merge } from 'type-fest';
|
3
|
+
type ClickableFeature = Merge<MapGeoJSONFeature, {
|
4
|
+
layer: {
|
5
|
+
id: string;
|
6
|
+
onClick: (feature: MapGeoJSONFeature, event: AugmentedMouseEvent) => any;
|
7
|
+
};
|
8
|
+
}>;
|
9
|
+
type AugmentedMouseEvent = Merge<MapMouseEvent, {
|
10
|
+
features: ClickableFeature[];
|
11
|
+
}>;
|
12
|
+
type LayeredMapOnClickHandlerProps = {
|
13
|
+
resolveTargetFeature?: (features: AugmentedMouseEvent['features'], event: AugmentedMouseEvent) => ClickableFeature | Promise<ClickableFeature>;
|
14
|
+
};
|
15
|
+
export declare function layeredMapOnClickHandler({ resolveTargetFeature, }?: LayeredMapOnClickHandlerProps): (e: AugmentedMouseEvent) => Promise<void>;
|
16
|
+
export {};
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { AnyLayer } from 'react-map-gl/dist/esm/exports-maplibre';
|
2
2
|
import { MapView, MapViewLayer, MapViewSource } from '../types';
|
3
|
+
import { MapMouseEvent } from 'maplibre-gl';
|
3
4
|
type ParsedSource = MapViewSource & {
|
4
5
|
id: string;
|
5
6
|
viewId: string;
|
@@ -7,6 +8,7 @@ type ParsedSource = MapViewSource & {
|
|
7
8
|
type ParsedLayer = MapViewLayer & {
|
8
9
|
id: string;
|
9
10
|
viewId: string;
|
11
|
+
onClick?: (feature: GeoJSON.Feature, event: MapMouseEvent) => any;
|
10
12
|
};
|
11
13
|
export type MapViewsParseResult = {
|
12
14
|
srcMapViews: MapView[];
|
@@ -41,5 +43,6 @@ export declare function augmentFeature(parsed: MapViewsParseResult, feature: Geo
|
|
41
43
|
properties: import("geojson").GeoJsonProperties;
|
42
44
|
bbox?: import("geojson").BBox | undefined;
|
43
45
|
};
|
46
|
+
export declare function fmtLayerAbsoluteId(viewId: string, layerRelativeId: string): string;
|
44
47
|
export declare function parseMapViews(orderedViews: MapView[], { existingLayers }?: ParseMapViewsOptions): MapViewsParseResult;
|
45
48
|
export {};
|
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
import { __assign, __spreadArray, __rest, __makeTemplateObject } from 'tslib';
|
2
|
-
import React, { forwardRef, useRef, useMemo, useImperativeHandle, useState, useCallback, useLayoutEffect, useEffect, createRef } from 'react';
|
1
|
+
import { __assign, __spreadArray, __rest, __awaiter, __generator, __makeTemplateObject } from 'tslib';
|
2
|
+
import React, { forwardRef, useContext, createContext, useRef, useMemo, useImperativeHandle, useState, useCallback, useLayoutEffect, useEffect, createRef } from 'react';
|
3
3
|
import { Map, Source, Layer, useMap, useControl } from 'react-map-gl/maplibre';
|
4
4
|
import { isPlainObject, uniq, uniqBy, pick, omit } from 'lodash-es';
|
5
5
|
import { Flex, useRefByKey, useLocalState, DropdownMenu } from '@orioro/react-ui-core';
|
6
6
|
import styled from 'styled-components';
|
7
7
|
import { usePrevious } from 'react-use';
|
8
8
|
import { mergeRefs } from 'react-merge-refs';
|
9
|
+
import { strExpr } from '@orioro/util';
|
9
10
|
import { ckmeans } from 'simple-statistics';
|
10
11
|
import { schemeYlOrRd } from 'd3-scale-chromatic';
|
11
12
|
import { maxIndex, range, variance, sum } from 'd3';
|
@@ -17,7 +18,6 @@ import { Tooltip } from '@radix-ui/themes';
|
|
17
18
|
import maplibregl from 'maplibre-gl';
|
18
19
|
import mlcontour from 'maplibre-contour';
|
19
20
|
import MaplibreInspect from '@maplibre/maplibre-gl-inspect';
|
20
|
-
import '@maplibre/maplibre-gl-inspect/dist/maplibre-gl-inspect.css';
|
21
21
|
|
22
22
|
function sortLayers(layers, _a) {
|
23
23
|
var existingLayers = _a.existingLayers;
|
@@ -53,7 +53,9 @@ function sortLayers(layers, _a) {
|
|
53
53
|
}).map(function (layer, index, sortedLayers) {
|
54
54
|
if (index === sortedLayers.length - 1) {
|
55
55
|
// is last layer
|
56
|
-
return layer
|
56
|
+
return __assign(__assign({}, layer), {
|
57
|
+
beforeId: null
|
58
|
+
});
|
57
59
|
} else {
|
58
60
|
var beforeId = sortedLayers[index + 1].id;
|
59
61
|
//
|
@@ -99,6 +101,9 @@ function augmentFeature(parsed, feature) {
|
|
99
101
|
mapView: mapView
|
100
102
|
});
|
101
103
|
}
|
104
|
+
function fmtLayerAbsoluteId(viewId, layerRelativeId) {
|
105
|
+
return "".concat(viewId, "__").concat(layerRelativeId);
|
106
|
+
}
|
102
107
|
function parseMapViews(orderedViews, _a) {
|
103
108
|
var _b = _a === void 0 ? {} : _a,
|
104
109
|
existingLayers = _b.existingLayers;
|
@@ -120,9 +125,10 @@ function parseMapViews(orderedViews, _a) {
|
|
120
125
|
if (!layer) {
|
121
126
|
return acc;
|
122
127
|
}
|
123
|
-
var layerId = layer.absoluteId ? layer.absoluteId :
|
128
|
+
var layerId = layer.absoluteId ? layer.absoluteId : fmtLayerAbsoluteId(viewId, layerRelativeId);
|
129
|
+
// : `${viewId}__${layerRelativeId}`
|
124
130
|
return {
|
125
|
-
interactiveLayerIds: layer.interactive ? __spreadArray(__spreadArray([], acc.interactiveLayerIds, true), [layerId], false) : acc.interactiveLayerIds,
|
131
|
+
interactiveLayerIds: layer.interactive || typeof layer.onClick === 'function' ? __spreadArray(__spreadArray([], acc.interactiveLayerIds, true), [layerId], false) : acc.interactiveLayerIds,
|
126
132
|
_layers: __spreadArray(__spreadArray([], acc._layers, true), [__assign(__assign({}, layer), {
|
127
133
|
viewId: viewId,
|
128
134
|
id: layerId,
|
@@ -173,6 +179,10 @@ var VIEW_AUGMENTED_EVENT_HANDLERS = ['onMouseDown', 'onMouseUp', 'onMouseOver',
|
|
173
179
|
// 'onMouseEnter',
|
174
180
|
// 'onMouseLeave',
|
175
181
|
'onMouseMove', 'onMouseOut', 'onClick', 'onDblClick', 'onContextMenu'];
|
182
|
+
var LayeredMapContext = /*#__PURE__*/createContext(null);
|
183
|
+
function useLayeredMap() {
|
184
|
+
return useContext(LayeredMapContext);
|
185
|
+
}
|
176
186
|
function useViewAugmentedEventHandlers(props, parsedMapViews) {
|
177
187
|
var handlers = Object.fromEntries(VIEW_AUGMENTED_EVENT_HANDLERS.map(function (handlerName) {
|
178
188
|
return typeof props[handlerName] === 'function' ? [handlerName, function (evt) {
|
@@ -209,7 +219,7 @@ var LayeredMap = /*#__PURE__*/forwardRef(function LayeredMapInner(_a, layeredMap
|
|
209
219
|
};
|
210
220
|
}, [views, mapRef.current]);
|
211
221
|
var evtHandlers = useViewAugmentedEventHandlers(mapProps, parsed);
|
212
|
-
|
222
|
+
var imperativeHandle = useMemo(function () {
|
213
223
|
return {
|
214
224
|
map: mapRef.current,
|
215
225
|
augmentFeature: augmentFeature.bind(null, parsed),
|
@@ -217,10 +227,15 @@ var LayeredMap = /*#__PURE__*/forwardRef(function LayeredMapInner(_a, layeredMap
|
|
217
227
|
getSrcLayer: getSrcLayer.bind(null, parsed)
|
218
228
|
};
|
219
229
|
}, [mapRef.current, parsed]);
|
230
|
+
useImperativeHandle(layeredMapRef, function () {
|
231
|
+
return imperativeHandle;
|
232
|
+
}, [imperativeHandle]);
|
220
233
|
return /*#__PURE__*/React.createElement(Map, __assign({
|
221
234
|
ref: mapRef,
|
222
235
|
interactiveLayerIds: __spreadArray(__spreadArray([], interactiveLayerIdsInput, true), parsed.interactiveLayerIds, true)
|
223
|
-
}, mapProps, evtHandlers),
|
236
|
+
}, mapProps, evtHandlers), /*#__PURE__*/React.createElement(LayeredMapContext.Provider, {
|
237
|
+
value: imperativeHandle
|
238
|
+
}, children, parsed.sources.map(function (_a) {
|
224
239
|
var id = _a.id;
|
225
240
|
_a.viewId;
|
226
241
|
var source = __rest(_a, ["id", "viewId"]);
|
@@ -235,9 +250,48 @@ var LayeredMap = /*#__PURE__*/forwardRef(function LayeredMapInner(_a, layeredMap
|
|
235
250
|
key: id,
|
236
251
|
id: id
|
237
252
|
}, layer));
|
238
|
-
}));
|
253
|
+
})));
|
239
254
|
});
|
240
255
|
|
256
|
+
function selectFirstClickableFeature(features) {
|
257
|
+
return features[0];
|
258
|
+
}
|
259
|
+
function layeredMapOnClickHandler(_a) {
|
260
|
+
var _b = _a === void 0 ? {} : _a,
|
261
|
+
_c = _b.resolveTargetFeature,
|
262
|
+
resolveTargetFeature = _c === void 0 ? selectFirstClickableFeature : _c;
|
263
|
+
return function onClick(e) {
|
264
|
+
return __awaiter(this, void 0, void 0, function () {
|
265
|
+
var features, clickableFeatures, targetFeature, _a;
|
266
|
+
return __generator(this, function (_b) {
|
267
|
+
switch (_b.label) {
|
268
|
+
case 0:
|
269
|
+
features = e.features || [];
|
270
|
+
clickableFeatures = features.filter(function (feature) {
|
271
|
+
var _a;
|
272
|
+
return typeof ((_a = feature.layer) === null || _a === void 0 ? void 0 : _a.onClick) === 'function';
|
273
|
+
});
|
274
|
+
if (!(clickableFeatures.length > 0)) return [3 /*break*/, 4];
|
275
|
+
if (!(clickableFeatures.length === 1)) return [3 /*break*/, 1];
|
276
|
+
_a = clickableFeatures[0];
|
277
|
+
return [3 /*break*/, 3];
|
278
|
+
case 1:
|
279
|
+
return [4 /*yield*/, resolveTargetFeature(clickableFeatures, e)];
|
280
|
+
case 2:
|
281
|
+
_a = _b.sent();
|
282
|
+
_b.label = 3;
|
283
|
+
case 3:
|
284
|
+
targetFeature = _a;
|
285
|
+
targetFeature.layer.onClick(targetFeature, e);
|
286
|
+
_b.label = 4;
|
287
|
+
case 4:
|
288
|
+
return [2 /*return*/];
|
289
|
+
}
|
290
|
+
});
|
291
|
+
});
|
292
|
+
};
|
293
|
+
}
|
294
|
+
|
241
295
|
var Container = styled.div(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["\n pointer-events: none;\n position: absolute;\n z-index: 2;\n\n background: rgba(0, 0, 0, 0.5);\n border-radius: 16px;\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(5px);\n -webkit-backdrop-filter: blur(5px);\n border: 1px solid rgba(0, 0, 0, 0.3);\n\n // background-color: black;\n color: white;\n border-radius: 5px;\n font-size: 0.9rem;\n\n max-width: 300px;\n\n hyphens: auto;\n word-break: break-word; /* Avoids overflow */\n overflow-wrap: break-word; /* Ensures long words break */\n white-space: normal;\n"], ["\n pointer-events: none;\n position: absolute;\n z-index: 2;\n\n background: rgba(0, 0, 0, 0.5);\n border-radius: 16px;\n box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(5px);\n -webkit-backdrop-filter: blur(5px);\n border: 1px solid rgba(0, 0, 0, 0.3);\n\n // background-color: black;\n color: white;\n border-radius: 5px;\n font-size: 0.9rem;\n\n max-width: 300px;\n\n hyphens: auto;\n word-break: break-word; /* Avoids overflow */\n overflow-wrap: break-word; /* Ensures long words break */\n white-space: normal;\n"])));
|
242
296
|
var DataSectionHeading = styled.h3(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n margin: 0;\n line-height: 1.2;\n font-size: 1rem;\n"], ["\n margin: 0;\n line-height: 1.2;\n font-size: 1rem;\n"])));
|
243
297
|
var DataSectionContainer = styled(Flex)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n padding: 15px 10px;\n"], ["\n padding: 15px 10px;\n"])));
|
@@ -491,14 +545,12 @@ function mapSetFeaturesState(map, features, state) {
|
|
491
545
|
return;
|
492
546
|
}
|
493
547
|
features.forEach(function (feat) {
|
494
|
-
if (feat.id) {
|
548
|
+
if (typeof feat.id === 'number' || typeof feat.id === 'string') {
|
495
549
|
map.setFeatureState({
|
496
550
|
source: feat.source,
|
497
551
|
sourceLayer: feat.sourceLayer,
|
498
552
|
id: feat.id
|
499
553
|
}, state);
|
500
|
-
} else {
|
501
|
-
console.warn("could not get feature id", feat);
|
502
554
|
}
|
503
555
|
});
|
504
556
|
}
|
@@ -565,7 +617,10 @@ function useHover(props, deps) {
|
|
565
617
|
onMouseOut: onMouseOut,
|
566
618
|
onDragStart: onDragStart,
|
567
619
|
onDragEnd: onDragEnd,
|
568
|
-
cursor: isDragging ? 'grabbing' : ((_a = hoverInfo === null || hoverInfo === void 0 ? void 0 : hoverInfo.features) === null || _a === void 0 ? void 0 : _a.length) > 0 ?
|
620
|
+
cursor: isDragging ? 'grabbing' : (((_a = hoverInfo === null || hoverInfo === void 0 ? void 0 : hoverInfo.features) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0 ? hoverInfo.features.some(function (feat) {
|
621
|
+
var _a;
|
622
|
+
return typeof ((_a = feat.layer) === null || _a === void 0 ? void 0 : _a.onClick) === 'function';
|
623
|
+
}) ? 'pointer' : 'default' : 'grab',
|
569
624
|
children: isDragging ? null : /*#__PURE__*/React.createElement(React.Fragment, null, tooltip)
|
570
625
|
}, hoverInfo, isDragging];
|
571
626
|
}
|
@@ -842,6 +897,147 @@ var SyncedMaps = makeSyncedMaps({
|
|
842
897
|
});
|
843
898
|
var templateObject_1;
|
844
899
|
|
900
|
+
function DynamicImages(_a) {
|
901
|
+
var _this = this;
|
902
|
+
var onGenerateImage = _a.onGenerateImage;
|
903
|
+
var map = useMap().current;
|
904
|
+
useEffect(function () {
|
905
|
+
if (!map) return function () {};
|
906
|
+
var handler = function handler(event) {
|
907
|
+
return __awaiter(_this, void 0, void 0, function () {
|
908
|
+
var imageId, result, err_1;
|
909
|
+
return __generator(this, function (_a) {
|
910
|
+
switch (_a.label) {
|
911
|
+
case 0:
|
912
|
+
imageId = event.id;
|
913
|
+
if (map.hasImage(imageId)) return [2 /*return*/];
|
914
|
+
_a.label = 1;
|
915
|
+
case 1:
|
916
|
+
_a.trys.push([1, 3,, 4]);
|
917
|
+
return [4 /*yield*/, onGenerateImage(imageId, event)];
|
918
|
+
case 2:
|
919
|
+
result = _a.sent();
|
920
|
+
if (!map.hasImage(imageId)) {
|
921
|
+
if (Array.isArray(result)) {
|
922
|
+
map.addImage(imageId, result[0], result[1]);
|
923
|
+
} else {
|
924
|
+
map.addImage(imageId, result);
|
925
|
+
}
|
926
|
+
}
|
927
|
+
return [3 /*break*/, 4];
|
928
|
+
case 3:
|
929
|
+
err_1 = _a.sent();
|
930
|
+
console.error("Failed to generate image for \"".concat(imageId, "\""), err_1);
|
931
|
+
return [3 /*break*/, 4];
|
932
|
+
case 4:
|
933
|
+
return [2 /*return*/];
|
934
|
+
}
|
935
|
+
});
|
936
|
+
});
|
937
|
+
};
|
938
|
+
map.on('styleimagemissing', handler);
|
939
|
+
return function () {
|
940
|
+
return map.off('styleimagemissing', handler);
|
941
|
+
};
|
942
|
+
}, [map, onGenerateImage]);
|
943
|
+
return null;
|
944
|
+
}
|
945
|
+
|
946
|
+
function iconPathToSvg(path, _a) {
|
947
|
+
var _b = _a === void 0 ? {} : _a,
|
948
|
+
_c = _b.size,
|
949
|
+
size = _c === void 0 ? 24 : _c,
|
950
|
+
_d = _b.fill,
|
951
|
+
fill = _d === void 0 ? 'black' : _d,
|
952
|
+
stroke = _b.stroke,
|
953
|
+
strokeWidth = _b.strokeWidth,
|
954
|
+
_e = _b.viewBox,
|
955
|
+
viewBox = _e === void 0 ? '0 0 24 24' : _e,
|
956
|
+
style = _b.style;
|
957
|
+
if (path.startsWith('<svg')) {
|
958
|
+
return path;
|
959
|
+
}
|
960
|
+
var svgAttrs = ["xmlns=\"http://www.w3.org/2000/svg\"", "width=\"".concat(size, "\""), "height=\"".concat(size, "\""), "viewBox=\"".concat(viewBox, "\""), stroke ? "stroke=\"".concat(stroke, "\"") : '', strokeWidth ? "stroke-width=\"".concat(strokeWidth, "\"") : ''].filter(Boolean).join(' ');
|
961
|
+
var pathAttrs = ["fill=\"".concat(fill, "\""), style ? "style=\"".concat(style, "\"") : ''].filter(Boolean).join(' ');
|
962
|
+
return "<svg ".concat(svgAttrs, "><path ").concat(pathAttrs, " d=\"").concat(path, "\" /></svg>");
|
963
|
+
}
|
964
|
+
/**
|
965
|
+
* Renders an SVG string onto a canvas and returns an object compatible with maplibre `addImage`.
|
966
|
+
*
|
967
|
+
* @param svgString - The SVG markup as a string
|
968
|
+
* @param pixelRatio - (Optional) device pixel ratio, defaults to window.devicePixelRatio
|
969
|
+
* @returns Promise resolving to { width, height, data, pixelRatio }
|
970
|
+
*/
|
971
|
+
function svgToMaplibreImage(svgString_1) {
|
972
|
+
return __awaiter(this, arguments, void 0, function (svgString, pixelRatio) {
|
973
|
+
if (pixelRatio === void 0) {
|
974
|
+
pixelRatio = typeof window !== 'undefined' ? window.devicePixelRatio : 1;
|
975
|
+
}
|
976
|
+
return __generator(this, function (_a) {
|
977
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
978
|
+
var svgBlob = new Blob([svgString], {
|
979
|
+
type: 'image/svg+xml'
|
980
|
+
});
|
981
|
+
var url = URL.createObjectURL(svgBlob);
|
982
|
+
var img = new Image();
|
983
|
+
img.onload = function () {
|
984
|
+
var width = img.width * pixelRatio;
|
985
|
+
var height = img.height * pixelRatio;
|
986
|
+
var canvas = document.createElement('canvas');
|
987
|
+
canvas.width = width;
|
988
|
+
canvas.height = height;
|
989
|
+
var ctx = canvas.getContext('2d');
|
990
|
+
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
991
|
+
ctx.drawImage(img, 0, 0);
|
992
|
+
var imageData = ctx.getImageData(0, 0, width, height);
|
993
|
+
URL.revokeObjectURL(url);
|
994
|
+
resolve([{
|
995
|
+
width: width,
|
996
|
+
height: height,
|
997
|
+
data: imageData.data
|
998
|
+
}, {
|
999
|
+
pixelRatio: pixelRatio
|
1000
|
+
}]);
|
1001
|
+
};
|
1002
|
+
img.onerror = function () {
|
1003
|
+
URL.revokeObjectURL(url);
|
1004
|
+
reject(new Error('Failed to load SVG as image'));
|
1005
|
+
};
|
1006
|
+
img.src = url;
|
1007
|
+
})];
|
1008
|
+
});
|
1009
|
+
});
|
1010
|
+
}
|
1011
|
+
function svgIconId(iconId, options) {
|
1012
|
+
return options ? "".concat(iconId, "(").concat(JSON.stringify(options), ")") : iconId;
|
1013
|
+
}
|
1014
|
+
function svgIconGenerator(iconPathsById) {
|
1015
|
+
var fns = Object.fromEntries(Object.entries(iconPathsById).map(function (_a) {
|
1016
|
+
var iconId = _a[0],
|
1017
|
+
iconPath = _a[1];
|
1018
|
+
return [iconId, function (options) {
|
1019
|
+
if (options === void 0) {
|
1020
|
+
options = {};
|
1021
|
+
}
|
1022
|
+
return function () {
|
1023
|
+
return iconPathToSvg(iconPath, options);
|
1024
|
+
};
|
1025
|
+
}];
|
1026
|
+
}));
|
1027
|
+
var expr = strExpr({
|
1028
|
+
expressions: fns
|
1029
|
+
});
|
1030
|
+
return function onGenerateSvgImage(imageId) {
|
1031
|
+
return __awaiter(this, void 0, void 0, function () {
|
1032
|
+
var svg;
|
1033
|
+
return __generator(this, function (_a) {
|
1034
|
+
svg = expr.apply(imageId, undefined);
|
1035
|
+
return [2 /*return*/, svgToMaplibreImage(svg)];
|
1036
|
+
});
|
1037
|
+
});
|
1038
|
+
};
|
1039
|
+
}
|
1040
|
+
|
845
1041
|
var DEFAULT_MIN_K = 3;
|
846
1042
|
var DEFAULT_MAX_K = 9;
|
847
1043
|
//
|
@@ -1361,4 +1557,4 @@ function InspectControl(props) {
|
|
1361
1557
|
return null;
|
1362
1558
|
}
|
1363
1559
|
|
1364
|
-
export { $naturalBreaks, ControlContainer, HoverTooltip, InspectControl, LayeredMap, MapWindow, SyncedMaps, TerrainControl, applyReactStyle, augmentFeature, ensureAddLayer, ensureAddSource, ensureRemoveLayer, ensureRemoveSource, fitGeometry, getSrcLayer, getSrcViewByLayerId, hoverParseEvent, makeSyncedMaps, mapSetFeaturesState, naturalBreakBounds, parseMapViews, scaleNaturalBreaks, sortLayers, useClientRect, useHover, withHover };
|
1560
|
+
export { $naturalBreaks, ControlContainer, DynamicImages, HoverTooltip, InspectControl, LayeredMap, MapWindow, SyncedMaps, TerrainControl, applyReactStyle, augmentFeature, ensureAddLayer, ensureAddSource, ensureRemoveLayer, ensureRemoveSource, fitGeometry, fmtLayerAbsoluteId, getSrcLayer, getSrcViewByLayerId, hoverParseEvent, iconPathToSvg, layeredMapOnClickHandler, makeSyncedMaps, mapSetFeaturesState, naturalBreakBounds, parseMapViews, scaleNaturalBreaks, sortLayers, svgIconGenerator, svgIconId, svgToMaplibreImage, useClientRect, useHover, useLayeredMap, withHover };
|
package/dist/types.d.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Map } from 'react-map-gl/maplibre';
|
2
2
|
import type { AnyLayer, AnySource } from 'react-map-gl/dist/esm/exports-maplibre';
|
3
|
+
import { MapGeoJSONFeature, MapMouseEvent } from 'maplibre-gl';
|
3
4
|
export type MapViewSource = AnySource & {
|
4
5
|
absoluteId?: string;
|
5
6
|
};
|
@@ -9,6 +10,7 @@ export type MapViewLayer = Omit<AnyLayer, 'id'> & {
|
|
9
10
|
source?: string;
|
10
11
|
absoluteSourceId?: string;
|
11
12
|
zIndex?: number;
|
13
|
+
onClick?: (feature: MapGeoJSONFeature, event: MapMouseEvent) => any;
|
12
14
|
};
|
13
15
|
type MapViewLegend = {
|
14
16
|
type: string;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orioro/react-maplibre-util",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0",
|
4
4
|
"packageManager": "yarn@4.0.2",
|
5
5
|
"type": "module",
|
6
6
|
"main": "dist/index.mjs",
|
@@ -50,11 +50,12 @@
|
|
50
50
|
"@maplibre/maplibre-gl-inspect": "^1.7.1",
|
51
51
|
"@mdi/js": "^7.4.47",
|
52
52
|
"@mdi/react": "^1.6.1",
|
53
|
-
"@orioro/react-chart-util": "^0.
|
53
|
+
"@orioro/react-chart-util": "^0.2.0",
|
54
54
|
"@orioro/react-select": "^3.0.2",
|
55
55
|
"@orioro/react-ui-core": "^0.0.6",
|
56
56
|
"@orioro/resolve": "^0.1.2",
|
57
57
|
"@orioro/scale-util": "^0.0.2",
|
58
|
+
"@orioro/util": "^0.13.0",
|
58
59
|
"@turf/turf": "^7.2.0",
|
59
60
|
"d3": "^7.9.0",
|
60
61
|
"d3-scale-chromatic": "^3.1.0",
|