@reventlessdev/reventless-map 0.1.0-alpha.1
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 +62 -0
- package/package.json +39 -0
- package/rescript.json +13 -0
- package/src/GeoInput.res +177 -0
- package/src/GeoInput.res.mjs +216 -0
- package/src/Geocoder.res +41 -0
- package/src/Geocoder.res.mjs +45 -0
- package/src/MapData.res +107 -0
- package/src/MapData.res.mjs +159 -0
- package/src/MapMode.res +109 -0
- package/src/MapMode.res.mjs +134 -0
- package/src/MapView.res +182 -0
- package/src/MapView.res.mjs +221 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js";
|
|
5
|
+
import * as Js_json from "@rescript/runtime/lib/es6/Js_json.js";
|
|
6
|
+
import * as MaplibreGl from "maplibre-gl";
|
|
7
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
8
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
10
|
+
import * as JsxRuntime from "react/jsx-runtime";
|
|
11
|
+
import * as MapData$ReventlessMap from "./MapData.res.mjs";
|
|
12
|
+
import * as AutoModes$ReventlessUi from "@reventlessdev/reventless-ui/src/auto/AutoModes.res.mjs";
|
|
13
|
+
|
|
14
|
+
function sourceId(idx) {
|
|
15
|
+
return "autoui-src-" + idx.toString();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function clusterLayerId(idx) {
|
|
19
|
+
return "autoui-clusters-" + idx.toString();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function pointLayerId(idx) {
|
|
23
|
+
return "autoui-points-" + idx.toString();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function json(prim) {
|
|
27
|
+
return JSON.parse(prim);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function clusterSourceSpec(data) {
|
|
31
|
+
return Js_dict.fromArray([
|
|
32
|
+
[
|
|
33
|
+
"type",
|
|
34
|
+
"geojson"
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"data",
|
|
38
|
+
data
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"cluster",
|
|
42
|
+
true
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
"clusterRadius",
|
|
46
|
+
40.0
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
"clusterMaxZoom",
|
|
50
|
+
14.0
|
|
51
|
+
]
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function clusterLayerSpec(idx, color) {
|
|
56
|
+
return JSON.parse(`{
|
|
57
|
+
"id": "` + clusterLayerId(idx) + `",
|
|
58
|
+
"type": "circle",
|
|
59
|
+
"source": "` + sourceId(idx) + `",
|
|
60
|
+
"filter": ["has", "point_count"],
|
|
61
|
+
"paint": {
|
|
62
|
+
"circle-color": "` + color + `",
|
|
63
|
+
"circle-opacity": 0.6,
|
|
64
|
+
"circle-radius": ["step", ["get", "point_count"], 12, 10, 16, 50, 22]
|
|
65
|
+
}
|
|
66
|
+
}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function pointLayerSpec(idx, color) {
|
|
70
|
+
return JSON.parse(`{
|
|
71
|
+
"id": "` + pointLayerId(idx) + `",
|
|
72
|
+
"type": "circle",
|
|
73
|
+
"source": "` + sourceId(idx) + `",
|
|
74
|
+
"filter": ["!", ["has", "point_count"]],
|
|
75
|
+
"paint": {
|
|
76
|
+
"circle-color": "` + color + `",
|
|
77
|
+
"circle-radius": 6,
|
|
78
|
+
"circle-stroke-width": 1.5,
|
|
79
|
+
"circle-stroke-color": "#ffffff"
|
|
80
|
+
}
|
|
81
|
+
}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function featureRowKey(e) {
|
|
85
|
+
return Stdlib_Option.flatMap(Stdlib_Option.flatMap(Primitive_option.fromNullable(e.features), fs => fs[0]), f => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Js_json.decodeObject(f.properties), o => Js_dict.get(o, "rowKey")), Js_json.decodeString));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function MapView(props) {
|
|
89
|
+
let mapStyle = props.mapStyle;
|
|
90
|
+
let sources = props.sources;
|
|
91
|
+
let containerRef = React.useRef(null);
|
|
92
|
+
let mapRef = React.useRef(undefined);
|
|
93
|
+
let match = React.useState(() => false);
|
|
94
|
+
let setLoaded = match[1];
|
|
95
|
+
let loaded = match[0];
|
|
96
|
+
let sourcesRef = React.useRef(sources);
|
|
97
|
+
sourcesRef.current = sources;
|
|
98
|
+
let didFit = React.useRef(false);
|
|
99
|
+
let installedSources = React.useRef([]);
|
|
100
|
+
React.useEffect(() => {
|
|
101
|
+
let el = containerRef.current;
|
|
102
|
+
if (el == null) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let map = new MaplibreGl.Map({
|
|
106
|
+
container: el,
|
|
107
|
+
style: mapStyle,
|
|
108
|
+
center: [
|
|
109
|
+
0.0,
|
|
110
|
+
20.0
|
|
111
|
+
],
|
|
112
|
+
zoom: 1.5
|
|
113
|
+
});
|
|
114
|
+
map.addControl(new MaplibreGl.NavigationControl());
|
|
115
|
+
map.on("load", () => setLoaded(param => true));
|
|
116
|
+
mapRef.current = Primitive_option.some(map);
|
|
117
|
+
return () => {
|
|
118
|
+
mapRef.current = undefined;
|
|
119
|
+
map.remove();
|
|
120
|
+
};
|
|
121
|
+
}, []);
|
|
122
|
+
React.useEffect(() => {
|
|
123
|
+
let match = mapRef.current;
|
|
124
|
+
if (match !== undefined && loaded) {
|
|
125
|
+
let map = Primitive_option.valFromOption(match);
|
|
126
|
+
sources.forEach((source, idx) => {
|
|
127
|
+
let points = MapData$ReventlessMap.pointsOf(source);
|
|
128
|
+
let data = MapData$ReventlessMap.featureCollection(points);
|
|
129
|
+
let id = sourceId(idx);
|
|
130
|
+
let geo = map.getSource(id);
|
|
131
|
+
if (geo == null) {
|
|
132
|
+
if (installedSources.current.includes(id)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
installedSources.current.push(id);
|
|
136
|
+
map.addSource(id, clusterSourceSpec(data));
|
|
137
|
+
let color = MapData$ReventlessMap.layerColor(source, idx);
|
|
138
|
+
map.addLayer(clusterLayerSpec(idx, color));
|
|
139
|
+
map.addLayer(pointLayerSpec(idx, color));
|
|
140
|
+
map.on("click", pointLayerId(idx), e => Stdlib_Option.forEach(featureRowKey(e), k => Stdlib_Option.forEach(sourcesRef.current[idx], source => Stdlib_Option.forEach(AutoModes$ReventlessUi.prepareRows(source).find(r => r.key === k), r => source.onOpenRow(r.key, r.json)))));
|
|
141
|
+
map.on("click", clusterLayerId(idx), e => {
|
|
142
|
+
map.flyTo({
|
|
143
|
+
center: [
|
|
144
|
+
e.lngLat.lng,
|
|
145
|
+
e.lngLat.lat
|
|
146
|
+
],
|
|
147
|
+
zoom: map.getZoom() + 2.0
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
geo.setData(data);
|
|
153
|
+
});
|
|
154
|
+
if (!didFit.current) {
|
|
155
|
+
let allPoints = sources.flatMap(MapData$ReventlessMap.pointsOf);
|
|
156
|
+
let b = MapData$ReventlessMap.bounds(allPoints);
|
|
157
|
+
if (b !== undefined) {
|
|
158
|
+
didFit.current = true;
|
|
159
|
+
map.fitBounds(b, {
|
|
160
|
+
padding: 48,
|
|
161
|
+
maxZoom: 12.0,
|
|
162
|
+
duration: 0
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}, [
|
|
168
|
+
sources,
|
|
169
|
+
loaded
|
|
170
|
+
]);
|
|
171
|
+
let total = Stdlib_Array.reduce(sources, 0, (n, s) => n + s.rows.length | 0);
|
|
172
|
+
return JsxRuntime.jsxs("div", {
|
|
173
|
+
children: [
|
|
174
|
+
JsxRuntime.jsx("div", {
|
|
175
|
+
ref: Primitive_option.some(containerRef),
|
|
176
|
+
style: {
|
|
177
|
+
bottom: "0",
|
|
178
|
+
left: "0",
|
|
179
|
+
overflow: "hidden",
|
|
180
|
+
position: "absolute",
|
|
181
|
+
right: "0",
|
|
182
|
+
top: "0",
|
|
183
|
+
borderRadius: "8px"
|
|
184
|
+
}
|
|
185
|
+
}),
|
|
186
|
+
JsxRuntime.jsx("span", {
|
|
187
|
+
children: `Showing the ` + total.toString() + ` loaded item(s)`,
|
|
188
|
+
style: {
|
|
189
|
+
background: "rgba(255,255,255,0.8)",
|
|
190
|
+
bottom: "4px",
|
|
191
|
+
fontSize: "11px",
|
|
192
|
+
left: "8px",
|
|
193
|
+
padding: "1px 6px",
|
|
194
|
+
position: "absolute",
|
|
195
|
+
opacity: "0.7",
|
|
196
|
+
borderRadius: "4px"
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
],
|
|
200
|
+
style: {
|
|
201
|
+
height: "520px",
|
|
202
|
+
position: "relative",
|
|
203
|
+
width: "100%"
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let make = MapView;
|
|
209
|
+
|
|
210
|
+
export {
|
|
211
|
+
sourceId,
|
|
212
|
+
clusterLayerId,
|
|
213
|
+
pointLayerId,
|
|
214
|
+
json,
|
|
215
|
+
clusterSourceSpec,
|
|
216
|
+
clusterLayerSpec,
|
|
217
|
+
pointLayerSpec,
|
|
218
|
+
featureRowKey,
|
|
219
|
+
make,
|
|
220
|
+
}
|
|
221
|
+
/* react Not a pure module */
|