@mapcomponents/ra-geospatial 1.0.3 → 1.5.0-2

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.
Files changed (37) hide show
  1. package/.babelrc +12 -0
  2. package/.storybook/main.ts +25 -0
  3. package/.storybook/manager.js +6 -0
  4. package/.storybook/mapcomponents_logo.png +0 -0
  5. package/.storybook/preview.ts +27 -0
  6. package/.storybook/style.css +20 -0
  7. package/.storybook/wheregroupTheme.js +9 -0
  8. package/README.md +71 -1
  9. package/assets/ra_geospatial_screenshots.png +0 -0
  10. package/eslint.config.cjs +3 -0
  11. package/package.json +21 -35
  12. package/project.json +14 -0
  13. package/src/components/GeospatialInput.stories.tsx +83 -0
  14. package/src/components/GeospatialInput.tsx +14 -17
  15. package/src/components/GeospatialInputMap.tsx +175 -164
  16. package/src/components/GeospatialShow.stories.tsx +84 -0
  17. package/src/components/GeospatialShow.tsx +14 -17
  18. package/src/components/GeospatialShowMap.tsx +54 -50
  19. package/src/contexts/DataContext.jsx +66 -0
  20. package/src/contexts/dataProvider.tsx +30 -0
  21. package/src/contexts/lsDataProvider.js +138 -0
  22. package/src/decorators/ReactAdminDefaultDecorator.tsx +40 -0
  23. package/src/index.ts +2 -2
  24. package/src/layout/GisLayout.jsx +90 -0
  25. package/src/ra_components/Poi.tsx +42 -0
  26. package/src/ra_components/Property.tsx +42 -0
  27. package/src/ra_components/Route.tsx +42 -0
  28. package/src/ra_components/raGeospatialProps.ts +5 -0
  29. package/src/ra_components/raGeospatialWebGisProps.ts +5 -0
  30. package/src/types.d.ts +3 -2
  31. package/tsconfig.json +7 -101
  32. package/tsconfig.lib.json +29 -0
  33. package/vite.config.ts +49 -0
  34. package/dist/index.esm.js +0 -160
  35. package/dist/index.esm.js.map +0 -1
  36. package/package-lock.json +0 -16564
  37. package/rollup.config.js +0 -50
@@ -1,176 +1,187 @@
1
- import React, { useContext, useEffect, useRef, useState } from "react";
2
- import { InputProps, useInput, useRecordContext } from "react-admin";
3
- import {
4
- stringify as wellknownStringify,
5
- parse as wellknownParse,
6
- GeoJSONGeometry,
7
- GeoJSONFeature,
8
- GeoJSONPoint,
9
- } from "wellknown";
1
+ import React, { useEffect, useState } from 'react';
2
+ import { InputProps, useInput, useRecordContext } from 'react-admin';
3
+ import { parse as wellknownParse, stringify as wellknownStringify } from 'wellknown';
4
+
10
5
  import {
11
- useMap,
12
- MapLibreMap,
13
- MlFeatureEditor,
14
- MlGeoJsonLayer,
15
- } from "@mapcomponents/react-maplibre";
16
- import { LngLatLike } from "maplibre-gl";
17
- import { feature, centroid } from "@turf/turf";
18
- import { Feature } from "@turf/helpers";
6
+ MapLibreMap,
7
+ MlFeatureEditor,
8
+ MlGeoJsonLayer,
9
+ useMap,
10
+ } from '@mapcomponents/react-maplibre';
11
+ import { LngLatLike } from 'maplibre-gl';
12
+ import { centroid, feature } from '@turf/turf';
13
+ import { Feature } from '@turf/helpers';
14
+ import { Geometry } from 'geojson';
19
15
 
20
16
  export interface GeospatialInputMapProps extends InputProps<any> {
21
- MapLibreMapProps?: unknown;
22
- geometrytype?: "point" | "line" | "polygon";
23
- embeddedMap?: boolean;
24
- mapId?: string;
17
+ MapLibreMapProps?: React.ComponentProps<typeof MapLibreMap>;
18
+ geometrytype?: 'point' | 'line' | 'polygon';
19
+ embeddedMap?: boolean;
20
+ mapId?: string;
25
21
  }
26
22
 
27
23
  function GeospatialInputMap(props: GeospatialInputMapProps) {
28
- const source = props?.source;
29
- const record = useRecordContext();
30
- const mapHook = useMap({mapId:props?.mapId});
31
-
32
- const [geojson, setGeojson] = useState<typeof feature>();
33
- const [oldGeoJson, setOldGeoJson] = useState<typeof feature>();
34
- const {
35
- field: { name, onChange, ...rest },
36
- fieldState,
37
- formState,
38
- isRequired,
39
- } = useInput(props);
40
-
41
- useEffect(() => {
42
- if (typeof record === "undefined" || !record[source]) return;
43
-
44
- let _geoJson = {
45
- type: "Feature",
46
- properties: {},
47
- geometry: wellknownParse(record[source]),
48
- };
49
-
50
- setGeojson(_geoJson as unknown as typeof feature);
51
- setOldGeoJson(_geoJson as unknown as typeof feature);
52
- }, [record, props.source]);
53
-
54
- useEffect(() => {
55
- if (!mapHook.map) return;
56
-
57
- if (typeof record !== "undefined" && record[source]) {
58
- const _center = centroid(
59
- wellknownParse(record[source]) as typeof Feature
60
- );
61
-
62
- if (_center?.geometry?.coordinates) {
63
- mapHook.map.setCenter(_center.geometry.coordinates as LngLatLike);
64
- }
65
- }
66
- }, [mapHook.map]);
67
-
68
- return (
69
- <>
70
- {props.embeddedMap && (
71
- <MapLibreMap
72
- options={{
73
- zoom: 14.5,
74
- style:
75
- "https://wms.wheregroup.com/tileserver/style/klokantech-basic.json",
76
- center: [7.0851268, 50.73884],
77
- }}
78
- style={{ width: "100%", height: "400px" }}
79
- />
80
- )}
81
-
82
- {props.type === "point" && (
83
- <>
84
- {oldGeoJson && (
85
- <MlGeoJsonLayer
86
- mapId={props?.mapId}
87
- geojson={oldGeoJson as typeof feature}
88
- paint={{
89
- "circle-radius": 8,
90
- "circle-color": "#6f6f96",
91
- "circle-stroke-color": "white",
92
- "circle-stroke-width": 3,
93
- "circle-opacity": 0.8,
94
- }}
95
- type="circle"
96
- insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
97
- />
98
- )}
99
-
100
- <MlFeatureEditor
101
- mapId={props?.mapId}
102
- geojson={geojson as typeof feature}
103
- mode={geojson ? "custom_select" : "draw_point"}
104
- onChange={(_geojson) => {
105
- if (typeof _geojson[0] !== "undefined") {
106
- onChange(wellknownStringify(_geojson[0] as GeoJSONGeometry));
107
- }
108
- }}
109
- />
110
- </>
111
- )}
112
- {props.type === "polygon" && (
113
- <>
114
- {oldGeoJson && (
115
- <MlGeoJsonLayer
116
- mapId={props?.mapId}
117
- geojson={oldGeoJson as typeof feature}
118
- paint={{
119
- "fill-color": "#6f6f96",
120
- "fill-opacity": 0.6,
121
- }}
122
- type="fill"
123
- insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
124
- />
125
- )}
126
-
127
- <MlFeatureEditor
128
- mapId={props?.mapId}
129
- geojson={geojson as typeof feature}
130
- mode={geojson ? "custom_select" : "draw_polygon"}
131
- onChange={(_geojson) => {
132
- if (typeof _geojson[0] !== "undefined") {
133
- onChange(wellknownStringify(_geojson[0] as GeoJSONGeometry));
134
- }
135
- }}
136
- />
137
- </>
138
- )}
139
- {props.type === "line" && (
140
- <>
141
- {oldGeoJson && (
142
- <MlGeoJsonLayer
143
- mapId={props?.mapId}
144
- geojson={oldGeoJson as typeof feature}
145
- paint={{
146
- "line-width": 6,
147
- "line-color": "#6f6f96",
148
- "line-opacity": 0.6,
149
- }}
150
- type="line"
151
- insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
152
- />
153
- )}
154
-
155
- <MlFeatureEditor
156
- mapId={props?.mapId}
157
- geojson={geojson as typeof feature}
158
- mode={geojson ? "custom_select" : "draw_line_string"}
159
- onChange={(_geojson) => {
160
- if (typeof _geojson[0] !== "undefined") {
161
- onChange(wellknownStringify(_geojson[0] as GeoJSONGeometry));
162
- }
163
- }}
164
- />
165
- </>
166
- )}
167
- </>
168
- );
24
+ const source = props?.source;
25
+ const record = useRecordContext();
26
+ const mapHook = useMap({ mapId: props?.mapId });
27
+
28
+ const [geojson, setGeojson] = useState<typeof feature>();
29
+ const [oldGeoJson, setOldGeoJson] = useState<typeof feature>();
30
+ const input = useInput(props);
31
+
32
+ const {
33
+ field: { onChange },
34
+ } = input;
35
+
36
+ useEffect(() => {
37
+ if (typeof record === 'undefined' || !record[source]) return;
38
+
39
+ const _geoJson = {
40
+ type: 'Feature',
41
+ properties: {},
42
+ geometry: wellknownParse(record[source]),
43
+ };
44
+
45
+ setGeojson(_geoJson as unknown as typeof feature);
46
+ setOldGeoJson(_geoJson as unknown as typeof feature);
47
+ }, [record, props.source]);
48
+
49
+ useEffect(() => {
50
+ if (!mapHook.map) return;
51
+
52
+ if (typeof record !== 'undefined' && record[source]) {
53
+ const _center = centroid(wellknownParse(record[source]) as typeof Feature);
54
+
55
+ if (_center?.geometry?.coordinates) {
56
+ mapHook.map.setCenter(_center.geometry.coordinates as LngLatLike);
57
+ }
58
+ }
59
+ }, [mapHook.map]);
60
+
61
+ return (
62
+ <>
63
+ {props.embeddedMap && (
64
+ <MapLibreMap
65
+ {...props?.MapLibreMapProps}
66
+ options={{
67
+ zoom: 14,
68
+ style: 'https://wms.wheregroup.com/tileserver/style/klokantech-basic.json',
69
+ center:
70
+ Array.isArray(props?.MapLibreMapProps?.options?.center) &&
71
+ props.MapLibreMapProps.options.center.length === 2
72
+ ? [
73
+ props.MapLibreMapProps.options.center[0],
74
+ props.MapLibreMapProps.options.center[1],
75
+ ]
76
+ : [0, 0],
77
+ ...props?.MapLibreMapProps?.options,
78
+ }}
79
+ style={{
80
+ width: '100%',
81
+ height: '400px',
82
+ ...props?.MapLibreMapProps?.style,
83
+ }}
84
+ />
85
+ )}
86
+
87
+ {props.type === 'point' && (
88
+ <>
89
+ {oldGeoJson && (
90
+ <MlGeoJsonLayer
91
+ mapId={props?.mapId}
92
+ geojson={oldGeoJson as typeof feature}
93
+ options={{
94
+ paint: {
95
+ 'circle-radius': 8,
96
+ 'circle-color': '#6f6f96',
97
+ 'circle-stroke-color': 'white',
98
+ 'circle-stroke-width': 3,
99
+ 'circle-opacity': 0.8,
100
+ },
101
+ }}
102
+ type="circle"
103
+ insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
104
+ />
105
+ )}
106
+
107
+ <MlFeatureEditor
108
+ mapId={props?.mapId}
109
+ geojson={geojson as typeof feature}
110
+ mode={geojson ? 'simple_select' : 'draw_point'}
111
+ onChange={(_geojson) => {
112
+ if (typeof _geojson[0] !== 'undefined') {
113
+ onChange(wellknownStringify(_geojson[0] as unknown as Geometry));
114
+ }
115
+ }}
116
+ />
117
+ </>
118
+ )}
119
+ {props.type === 'polygon' && (
120
+ <>
121
+ {oldGeoJson && (
122
+ <MlGeoJsonLayer
123
+ mapId={props?.mapId}
124
+ geojson={oldGeoJson as typeof feature}
125
+ options={{
126
+ paint: {
127
+ 'fill-color': '#6f6f96',
128
+ 'fill-opacity': 0.6,
129
+ },
130
+ }}
131
+ type="fill"
132
+ insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
133
+ />
134
+ )}
135
+
136
+ <MlFeatureEditor
137
+ mapId={props?.mapId}
138
+ geojson={geojson as typeof feature}
139
+ mode={geojson ? 'simple_select' : 'draw_polygon'}
140
+ onChange={(_geojson) => {
141
+ if (typeof _geojson[0] !== 'undefined') {
142
+ onChange(wellknownStringify(_geojson[0] as unknown as Geometry));
143
+ }
144
+ }}
145
+ />
146
+ </>
147
+ )}
148
+ {props.type === 'line' && (
149
+ <>
150
+ {oldGeoJson && (
151
+ <MlGeoJsonLayer
152
+ mapId={props?.mapId}
153
+ geojson={oldGeoJson as typeof feature}
154
+ options={{
155
+ paint: {
156
+ 'line-width': 6,
157
+ 'line-color': '#6f6f96',
158
+ 'line-opacity': 0.6,
159
+ },
160
+ }}
161
+ type="line"
162
+ insertBeforeLayer="gl-draw-polygon-fill-inactive.cold"
163
+ />
164
+ )}
165
+
166
+ <MlFeatureEditor
167
+ mapId={props?.mapId}
168
+ geojson={geojson as typeof feature}
169
+ mode={geojson ? 'simple_select' : 'draw_line_string'}
170
+ onChange={(_geojson) => {
171
+ if (typeof _geojson[0] !== 'undefined') {
172
+ onChange(wellknownStringify(_geojson[0] as unknown as Geometry));
173
+ }
174
+ }}
175
+ />
176
+ </>
177
+ )}
178
+ </>
179
+ );
169
180
  }
170
181
 
171
182
  GeospatialInputMap.defaultProps = {
172
- type: "point",
173
- embeddedMap: true,
183
+ type: 'point',
184
+ embeddedMap: true,
174
185
  };
175
186
 
176
187
  export default GeospatialInputMap;
@@ -0,0 +1,84 @@
1
+ import type { Meta } from '@storybook/react-vite';
2
+ import GeospatialShow from './GeospatialShow';
3
+ import { ReactAdminDefaultDecorator } from '../decorators/ReactAdminDefaultDecorator';
4
+ import { PoiShow, PoiShowWebGis } from '../ra_components/Poi';
5
+ import { PropertyShow, PropertyShowWebGis } from '../ra_components/Property';
6
+ import { RouteShow, RouteShowWebGis } from '../ra_components/Route';
7
+ import GisLayout from '../layout/GisLayout';
8
+
9
+ const meta = {
10
+ component: GeospatialShow,
11
+ title: 'MapComponents/GeospatialShow',
12
+ decorators: [ReactAdminDefaultDecorator],
13
+ } satisfies Meta<typeof GeospatialShow>;
14
+
15
+ export default meta;
16
+
17
+ export const PoisShow = PoiShow.bind({});
18
+
19
+ PoisShow.args = {
20
+ primary: true,
21
+ embeddedMap: true,
22
+ };
23
+
24
+ PoisShow.parameters = {
25
+ name: 'pois',
26
+ };
27
+
28
+ export const PropertiesShow = PropertyShow.bind({});
29
+
30
+ PropertiesShow.args = {
31
+ primary: true,
32
+ embeddedMap: true,
33
+ };
34
+
35
+ PropertiesShow.parameters = {
36
+ name: 'properties',
37
+ };
38
+
39
+ export const RoutesShow = RouteShow.bind({});
40
+
41
+ RoutesShow.args = {
42
+ primary: true,
43
+ embeddedMap: true,
44
+ };
45
+
46
+ RoutesShow.parameters = {
47
+ name: 'routes',
48
+ };
49
+
50
+ export const PoisShowGIS = PoiShowWebGis.bind({});
51
+
52
+ PoisShowGIS.args = {
53
+ primary: true,
54
+ embeddedMap: false,
55
+ };
56
+
57
+ PoisShowGIS.parameters = {
58
+ name: 'pois',
59
+ layout: GisLayout,
60
+ };
61
+
62
+ export const PropertiesShowGIS = PropertyShowWebGis.bind({});
63
+
64
+ PropertiesShowGIS.args = {
65
+ primary: true,
66
+ embeddedMap: false,
67
+ };
68
+
69
+ PropertiesShowGIS.parameters = {
70
+ name: 'properties',
71
+ layout: GisLayout,
72
+ };
73
+
74
+ export const RoutesShowGIS = RouteShowWebGis.bind({});
75
+
76
+ RoutesShowGIS.args = {
77
+ primary: true,
78
+ embeddedMap: false,
79
+ };
80
+
81
+ RoutesShowGIS.parameters = {
82
+ name: 'routes',
83
+ layout: GisLayout,
84
+ };
@@ -1,24 +1,21 @@
1
- import React from "react";
2
- import { MapComponentsProvider } from "@mapcomponents/react-maplibre";
3
- import GeometryShowMap, {
4
- GeospatialShowMapProps,
5
- } from "./GeospatialShowMap.js";
1
+ import { MapComponentsProvider } from '@mapcomponents/react-maplibre';
2
+ import GeometryShowMap, { GeospatialShowMapProps } from './GeospatialShowMap.js';
6
3
 
7
4
  function GeospatialShow(props: GeospatialShowMapProps) {
8
- return (
9
- <>
10
- {props.embeddedMap ? (
11
- <MapComponentsProvider>
12
- <GeometryShowMap {...props} />
13
- </MapComponentsProvider>
14
- ) : (
15
- <GeometryShowMap {...props} />
16
- )}
17
- </>
18
- );
5
+ return (
6
+ <>
7
+ {props.embeddedMap ? (
8
+ <MapComponentsProvider>
9
+ <GeometryShowMap {...props} />
10
+ </MapComponentsProvider>
11
+ ) : (
12
+ <GeometryShowMap {...props} />
13
+ )}
14
+ </>
15
+ );
19
16
  }
20
17
  GeospatialShow.defaultProps = {
21
- embeddedMap: true,
18
+ embeddedMap: true,
22
19
  };
23
20
 
24
21
  export default GeospatialShow;
@@ -1,65 +1,69 @@
1
- import React, { useEffect, useState } from "react";
2
- import { InputProps, useRecordContext } from "react-admin";
3
- import { parse as wellknownParse, GeoJSONPoint } from "wellknown";
4
- import {
5
- MapLibreMap,
6
- MlGeoJsonLayer,
7
- useMap,
8
- } from "@mapcomponents/react-maplibre";
9
- import { LngLatLike } from "maplibre-gl";
10
- import { feature, centroid } from "@turf/turf";
11
- import { Feature } from "@turf/helpers";
1
+ import React, { useEffect, useState } from 'react';
2
+ import { InputProps, useRecordContext } from 'react-admin';
3
+ import { parse as wellknownParse } from 'wellknown';
4
+ import { MapLibreMap, MlGeoJsonLayer, useMap } from '@mapcomponents/react-maplibre';
5
+ import { LngLatLike } from 'maplibre-gl';
6
+ import { feature, centroid } from '@turf/turf';
7
+ import { Feature } from '@turf/helpers';
12
8
 
13
9
  export interface GeospatialShowMapProps extends InputProps<any> {
14
- embeddedMap?: boolean;
15
- mapId?: string;
10
+ MapLibreMapProps?: React.ComponentProps<typeof MapLibreMap>;
11
+ embeddedMap?: boolean;
12
+ mapId?: string;
16
13
  }
17
14
 
18
15
  function GeospatialShowMap(props: GeospatialShowMapProps) {
19
- const source = props.source;
20
- const record = useRecordContext();
21
- const mapHook = useMap();
16
+ const source = props.source;
17
+ const record = useRecordContext();
18
+ const mapHook = useMap();
22
19
 
23
- const [geojson, setGeojson] = useState<typeof feature>();
24
- useEffect(() => {
25
- if (typeof record === "undefined") return;
20
+ const [geojson, setGeojson] = useState<typeof feature>();
21
+ useEffect(() => {
22
+ if (!record?.[source]) return;
26
23
 
27
- setGeojson({
28
- type: "Feature",
29
- properties: {},
30
- geometry: wellknownParse(record[source]),
31
- } as unknown as typeof feature);
32
- //console.log(record)
33
- //onChange({target:{value:"POINT(7.083199846086359 50.73716918021759)"}});
34
- }, [record]);
24
+ const _geometry = wellknownParse(record[source]);
35
25
 
36
- useEffect(() => {
37
- if (!mapHook.map) return;
26
+ if (_geometry) {
27
+ setGeojson({
28
+ type: 'Feature',
29
+ properties: {},
30
+ geometry: _geometry,
31
+ } as unknown as typeof feature);
32
+ }
33
+ }, [record]);
38
34
 
39
- const _center = centroid(wellknownParse(record[source]) as typeof Feature);
35
+ useEffect(() => {
36
+ if (!mapHook.map || !geojson) return;
40
37
 
41
- if (_center?.geometry?.coordinates) {
42
- mapHook.map.setCenter(_center.geometry.coordinates as LngLatLike);
43
- }
44
- }, [mapHook.map]);
38
+ const _center = centroid(geojson as typeof Feature);
45
39
 
46
- return (
47
- <>
48
- {props.embeddedMap && (
49
- <MapLibreMap
50
- options={{
51
- zoom: 14.5,
52
- style:
53
- "https://wms.wheregroup.com/tileserver/style/klokantech-basic.json",
54
- center: [0, 0],
55
- }}
56
- style={{ width: "100%", height: "400px" }}
57
- />
58
- )}
40
+ if (_center?.geometry?.coordinates) {
41
+ mapHook.map.setCenter(_center.geometry.coordinates as LngLatLike);
42
+ }
43
+ }, [mapHook.map, geojson]);
59
44
 
60
- {geojson && <MlGeoJsonLayer geojson={geojson}></MlGeoJsonLayer>}
61
- </>
62
- );
45
+ return (
46
+ <>
47
+ {props.embeddedMap && (
48
+ <MapLibreMap
49
+ {...props?.MapLibreMapProps}
50
+ options={{
51
+ zoom: 14,
52
+ style: 'https://wms.wheregroup.com/tileserver/style/klokantech-basic.json',
53
+ center: [0, 0],
54
+ ...props?.MapLibreMapProps?.options,
55
+ }}
56
+ style={{
57
+ width: '100%',
58
+ height: '400px',
59
+ ...props?.MapLibreMapProps?.style,
60
+ }}
61
+ />
62
+ )}
63
+
64
+ {geojson && <MlGeoJsonLayer geojson={geojson}></MlGeoJsonLayer>}
65
+ </>
66
+ );
63
67
  }
64
68
 
65
69
  export default GeospatialShowMap;
@@ -0,0 +1,66 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { parse as wellknownParse } from 'wellknown';
3
+ import { feature, featureCollection } from '@turf/helpers';
4
+ import { defaultData } from './dataProvider';
5
+
6
+ export const DataContext = React.createContext();
7
+
8
+ export default function DataContextProvider(props) {
9
+ const [data, setData] = useState({});
10
+
11
+ useEffect(() => {
12
+ refreshData();
13
+ const _eventHandler = () => {
14
+ console.log('refreshing data from localStorage');
15
+ refreshData();
16
+ };
17
+ window.addEventListener('storageItemUpdated', _eventHandler);
18
+ return () => {
19
+ window.removeEventListener('storageItemUpdated', _eventHandler);
20
+ };
21
+ }, []);
22
+
23
+ const refreshData = () => {
24
+ const storageDataTmp = localStorage.getItem('ra-data-local-storage');
25
+ if (storageDataTmp) {
26
+ const storageData = JSON.parse(storageDataTmp);
27
+ const _data = Object.keys(storageData).map((el) => {
28
+ const features = storageData[el].map((entry) => {
29
+ return feature(wellknownParse(entry.geom));
30
+ });
31
+ return {
32
+ name: el,
33
+ featureCollection: features?.[0] ? featureCollection(features) : undefined,
34
+ };
35
+ });
36
+
37
+ setData(_data);
38
+ } else {
39
+ const features = [];
40
+ let counter = 0;
41
+ Object.values(defaultData).map((geomArray) => {
42
+ features.push({
43
+ name: counter === 0 ? 'pois' : counter === 1 ? 'properties' : 'routes',
44
+ featureCollection: {
45
+ type: 'FeatureCollection',
46
+ features: geomArray.map((geom) => {
47
+ return {
48
+ type: 'Feature',
49
+ properties: {},
50
+ geometry: wellknownParse(geom.geom),
51
+ };
52
+ }),
53
+ },
54
+ });
55
+ counter++;
56
+ });
57
+ setData(features);
58
+ }
59
+ };
60
+ const value = {
61
+ data,
62
+ refreshData,
63
+ };
64
+
65
+ return <DataContext.Provider value={value}>{props.children}</DataContext.Provider>;
66
+ }