@osm-editor-kit/street-imagery-react 0.1.0-alpha.12 → 0.1.0-alpha.14
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 +54 -2
- package/dist/MapillaryPanel-SOHGB7JA.js +3 -0
- package/dist/PanoramaxPanel-NAKCJHT5.js +3 -0
- package/dist/StreetLevelImageryViewer.d.ts +8 -2
- package/dist/{chunk-6EMFFIL2.js → chunk-3DFVM6VK.js} +57 -13
- package/dist/{chunk-XQXYV6SR.js → chunk-BZGY6BZC.js} +338 -139
- package/dist/{chunk-25UGGXIE.js → chunk-GYUS2JVV.js} +24 -4
- package/dist/chunk-LZR5SZDS.js +498 -0
- package/dist/chunk-XLBFXACK.js +56 -0
- package/dist/filters/PhotoDateRangeFilter.d.ts +4 -1
- package/dist/filters/dateSliderPointer.d.ts +21 -0
- package/dist/hooks/useMapViewportBbox.d.ts +3 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3958 -1606
- package/dist/panels/MapillaryPanel.d.ts +7 -2
- package/dist/panels/PanoramaxPanel.d.ts +7 -2
- package/dist/panels/PanoramaxWebViewerPanel.d.ts +7 -2
- package/dist/panels/panoramaxItem.d.ts +2 -0
- package/dist/panels/photoView.d.ts +19 -0
- package/dist/panoramax-web-viewer.js +297 -93
- package/dist/photo-details.js +222 -151
- package/dist/viewer-panels.js +4 -3
- package/dist/viewpoints/FloatingPhotoViewer.d.ts +22 -7
- package/dist/viewpoints/floatingViewerPosition.d.ts +18 -0
- package/dist/viewpoints/usePhotosLookingAt.d.ts +26 -0
- package/package.json +5 -2
- package/dist/MapillaryPanel-FAXVZH37.js +0 -2
- package/dist/PanoramaxPanel-TWKTSOXM.js +0 -2
- package/dist/chunk-SGIB7AVC.js +0 -309
|
@@ -17,9 +17,29 @@ var useViewerStore = create()((set) => ({
|
|
|
17
17
|
reset: () => set(initialState)
|
|
18
18
|
}
|
|
19
19
|
}));
|
|
20
|
-
var useViewerBearing = () =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var
|
|
20
|
+
var useViewerBearing = () => {
|
|
21
|
+
return useViewerStore(_temp);
|
|
22
|
+
};
|
|
23
|
+
var useViewerHfov = () => {
|
|
24
|
+
return useViewerStore(_temp2);
|
|
25
|
+
};
|
|
26
|
+
var useViewerLngLat = () => {
|
|
27
|
+
return useViewerStore(_temp3);
|
|
28
|
+
};
|
|
29
|
+
var useViewerActions = () => {
|
|
30
|
+
return useViewerStore(_temp4);
|
|
31
|
+
};
|
|
32
|
+
function _temp(state) {
|
|
33
|
+
return state.bearing;
|
|
34
|
+
}
|
|
35
|
+
function _temp2(state) {
|
|
36
|
+
return state.hfov;
|
|
37
|
+
}
|
|
38
|
+
function _temp3(state) {
|
|
39
|
+
return state.lngLat;
|
|
40
|
+
}
|
|
41
|
+
function _temp4(state) {
|
|
42
|
+
return state.actions;
|
|
43
|
+
}
|
|
24
44
|
|
|
25
45
|
export { useViewerActions, useViewerBearing, useViewerHfov, useViewerLngLat };
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { watchMapillaryJsView } from './chunk-XLBFXACK.js';
|
|
2
|
+
import { useViewerActions } from './chunk-GYUS2JVV.js';
|
|
3
|
+
import { c } from 'react/compiler-runtime';
|
|
4
|
+
import { viewFromOutline, SIGN_TARGET, viewFromFlatCamera, cameraPitch, panoX, bearingDeg, viewFromLocation, getStreetImageryConfig, fetchImageDetections } from '@osm-editor-kit/street-imagery';
|
|
5
|
+
import 'mapillary-js/dist/mapillary.css';
|
|
6
|
+
import { OutlineTag, PolygonGeometry, Viewer } from 'mapillary-js';
|
|
7
|
+
import { useRef, useEffectEvent, useEffect } from 'react';
|
|
8
|
+
import { jsx } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var isSpherical = (image) => image.cameraType === "spherical" || image.cameraType === "equirectangular";
|
|
11
|
+
var mapillaryViewFor = async (viewer, image, {
|
|
12
|
+
lngLat,
|
|
13
|
+
shape = SIGN_TARGET,
|
|
14
|
+
outline
|
|
15
|
+
}) => {
|
|
16
|
+
const spherical = isSpherical(image);
|
|
17
|
+
if (outline?.length) {
|
|
18
|
+
return viewFromOutline(outline, spherical, shape.maxZoom);
|
|
19
|
+
}
|
|
20
|
+
const position = image.lngLat ?? image.originalLngLat;
|
|
21
|
+
const imageLngLat = [position.lng, position.lat];
|
|
22
|
+
const compass = image.computedCompassAngle ?? image.compassAngle;
|
|
23
|
+
if (!spherical) {
|
|
24
|
+
const focal = image.cameraParameters?.[0];
|
|
25
|
+
return focal ? viewFromFlatCamera({
|
|
26
|
+
focal,
|
|
27
|
+
width: image.width,
|
|
28
|
+
height: image.height,
|
|
29
|
+
compassAngle: compass,
|
|
30
|
+
pitch: cameraPitch(image.rotation)
|
|
31
|
+
}, imageLngLat, lngLat, shape) : void 0;
|
|
32
|
+
}
|
|
33
|
+
let x = panoX(bearingDeg(imageLngLat, lngLat), compass);
|
|
34
|
+
try {
|
|
35
|
+
viewer.setCenter([x, 0.5]);
|
|
36
|
+
const pixel = await viewer.project({
|
|
37
|
+
lng: lngLat[0],
|
|
38
|
+
lat: lngLat[1]
|
|
39
|
+
});
|
|
40
|
+
const basic = pixel ? await viewer.unprojectToBasic(pixel) : null;
|
|
41
|
+
const projected = basic?.[0];
|
|
42
|
+
if (projected != null && projected >= 0 && projected <= 1) {
|
|
43
|
+
x = projected;
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
return viewFromLocation(x, {
|
|
48
|
+
lngLat: imageLngLat,
|
|
49
|
+
isPano: true
|
|
50
|
+
}, lngLat, shape);
|
|
51
|
+
};
|
|
52
|
+
var xDistance = (a, b, spherical) => {
|
|
53
|
+
const distance = Math.abs(a - b);
|
|
54
|
+
return spherical ? Math.min(distance, 1 - distance) : distance;
|
|
55
|
+
};
|
|
56
|
+
var findOwnDetection = async (image, value, estimate) => {
|
|
57
|
+
const spherical = isSpherical(image);
|
|
58
|
+
const candidates = await fetchImageDetections(image.id, {
|
|
59
|
+
filter: (v) => v === value
|
|
60
|
+
}).catch(() => []);
|
|
61
|
+
const centerX = (detection) => viewFromOutline(detection.outline, spherical)?.center[0] ?? 0.5;
|
|
62
|
+
return candidates.sort((a, b) => estimate ? xDistance(centerX(a), estimate.center[0], spherical) - xDistance(centerX(b), estimate.center[0], spherical) : 0)[0];
|
|
63
|
+
};
|
|
64
|
+
var turnMapillaryViewerTo = async (viewer, image, lookAt) => {
|
|
65
|
+
let outline = lookAt.outline?.length ? lookAt.outline : void 0;
|
|
66
|
+
let outlineId = `look-at-${image.id}`;
|
|
67
|
+
let view;
|
|
68
|
+
if (!outline) {
|
|
69
|
+
view = await mapillaryViewFor(viewer, image, lookAt);
|
|
70
|
+
const own = lookAt.value ? await findOwnDetection(image, lookAt.value, view) : void 0;
|
|
71
|
+
if (own) {
|
|
72
|
+
outline = own.outline;
|
|
73
|
+
outlineId = own.id;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (outline) {
|
|
77
|
+
view = viewFromOutline(outline, isSpherical(image), (lookAt.shape ?? SIGN_TARGET).maxZoom);
|
|
78
|
+
}
|
|
79
|
+
if (!view) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
viewer.setCenter(view.center);
|
|
83
|
+
viewer.setZoom(view.zoom);
|
|
84
|
+
return outline ? {
|
|
85
|
+
id: outlineId,
|
|
86
|
+
outline,
|
|
87
|
+
label: lookAt.label
|
|
88
|
+
} : null;
|
|
89
|
+
};
|
|
90
|
+
var setMapillaryViewerOutlines = (viewer, outlines) => {
|
|
91
|
+
const tags = viewer.getComponent("tag");
|
|
92
|
+
tags.removeAll();
|
|
93
|
+
tags.add(outlines.filter(({
|
|
94
|
+
outline
|
|
95
|
+
}) => outline.length >= 3).map(({
|
|
96
|
+
id,
|
|
97
|
+
outline,
|
|
98
|
+
label,
|
|
99
|
+
color = 16776960
|
|
100
|
+
}) => {
|
|
101
|
+
const first = outline[0];
|
|
102
|
+
const last = outline[outline.length - 1];
|
|
103
|
+
const closed = first[0] === last[0] && first[1] === last[1] ? outline : [...outline, first];
|
|
104
|
+
return new OutlineTag(id, new PolygonGeometry(closed), {
|
|
105
|
+
text: label,
|
|
106
|
+
textColor: color,
|
|
107
|
+
lineColor: color,
|
|
108
|
+
lineWidth: 2,
|
|
109
|
+
fillColor: color,
|
|
110
|
+
fillOpacity: 0.3
|
|
111
|
+
});
|
|
112
|
+
}));
|
|
113
|
+
};
|
|
114
|
+
var panoCenterX = (bearing, compassAngle) => ((0.5 + (bearing - compassAngle) / 360) % 1 + 1) % 1;
|
|
115
|
+
var MapillaryPanel = (t0) => {
|
|
116
|
+
const $ = c(49);
|
|
117
|
+
const {
|
|
118
|
+
photo,
|
|
119
|
+
onPhotoSelected,
|
|
120
|
+
onEaseMapToPoint,
|
|
121
|
+
onViewerPhoto,
|
|
122
|
+
onViewerView,
|
|
123
|
+
lookAtBearing,
|
|
124
|
+
lookAt,
|
|
125
|
+
outlines,
|
|
126
|
+
hideAttribution: t1
|
|
127
|
+
} = t0;
|
|
128
|
+
const hideAttribution = t1 === void 0 ? false : t1;
|
|
129
|
+
const containerRef = useRef(null);
|
|
130
|
+
const viewerRef = useRef(null);
|
|
131
|
+
const navigableRef = useRef(false);
|
|
132
|
+
const pendingImageIdRef = useRef(null);
|
|
133
|
+
const lastViewerPhotoIdRef = useRef(null);
|
|
134
|
+
const bearingRafRef = useRef(null);
|
|
135
|
+
const pendingBearingRef = useRef(null);
|
|
136
|
+
const actions = useViewerActions();
|
|
137
|
+
const initialPhotoIdRef = useRef(photo.photoId);
|
|
138
|
+
const initialHideAttributionRef = useRef(hideAttribution);
|
|
139
|
+
const emitPhotoSelected = useEffectEvent(onPhotoSelected);
|
|
140
|
+
const emitEaseMapToPoint = useEffectEvent(onEaseMapToPoint);
|
|
141
|
+
let t2;
|
|
142
|
+
if ($[0] !== lookAt || $[1] !== lookAtBearing || $[2] !== outlines || $[3] !== photo.photoId) {
|
|
143
|
+
t2 = (viewer, image) => {
|
|
144
|
+
if (image.id !== photo.photoId) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (lookAt) {
|
|
148
|
+
turnMapillaryViewerTo(viewer, image, lookAt).then((aimedAt) => {
|
|
149
|
+
if (aimedAt && !outlines && lastViewerPhotoIdRef.current === image.id) {
|
|
150
|
+
setMapillaryViewerOutlines(viewer, [aimedAt]);
|
|
151
|
+
}
|
|
152
|
+
}).catch(_temp);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const spherical = image.cameraType === "spherical" || image.cameraType === "equirectangular";
|
|
156
|
+
const compass = image.computedCompassAngle ?? image.compassAngle;
|
|
157
|
+
if (lookAtBearing != null && spherical && compass != null) {
|
|
158
|
+
viewer.setCenter([panoCenterX(lookAtBearing, compass), 0.5]);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
$[0] = lookAt;
|
|
162
|
+
$[1] = lookAtBearing;
|
|
163
|
+
$[2] = outlines;
|
|
164
|
+
$[3] = photo.photoId;
|
|
165
|
+
$[4] = t2;
|
|
166
|
+
} else {
|
|
167
|
+
t2 = $[4];
|
|
168
|
+
}
|
|
169
|
+
const turnToWantedBearing = useEffectEvent(t2);
|
|
170
|
+
let t3;
|
|
171
|
+
if ($[5] !== outlines) {
|
|
172
|
+
t3 = (viewer_0) => {
|
|
173
|
+
setMapillaryViewerOutlines(viewer_0, outlines ?? []);
|
|
174
|
+
};
|
|
175
|
+
$[5] = outlines;
|
|
176
|
+
$[6] = t3;
|
|
177
|
+
} else {
|
|
178
|
+
t3 = $[6];
|
|
179
|
+
}
|
|
180
|
+
const drawOutlines = useEffectEvent(t3);
|
|
181
|
+
let t4;
|
|
182
|
+
if ($[7] !== onViewerPhoto) {
|
|
183
|
+
t4 = (viewerPhoto) => onViewerPhoto?.(viewerPhoto);
|
|
184
|
+
$[7] = onViewerPhoto;
|
|
185
|
+
$[8] = t4;
|
|
186
|
+
} else {
|
|
187
|
+
t4 = $[8];
|
|
188
|
+
}
|
|
189
|
+
const emitViewerPhoto = useEffectEvent(t4);
|
|
190
|
+
let t5;
|
|
191
|
+
if ($[9] !== actions) {
|
|
192
|
+
t5 = function resetViewerStoreOnProviderChange() {
|
|
193
|
+
return () => {
|
|
194
|
+
actions.reset();
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
$[9] = actions;
|
|
198
|
+
$[10] = t5;
|
|
199
|
+
} else {
|
|
200
|
+
t5 = $[10];
|
|
201
|
+
}
|
|
202
|
+
let t6;
|
|
203
|
+
if ($[11] !== actions || $[12] !== photo.providerId) {
|
|
204
|
+
t6 = [actions, photo.providerId];
|
|
205
|
+
$[11] = actions;
|
|
206
|
+
$[12] = photo.providerId;
|
|
207
|
+
$[13] = t6;
|
|
208
|
+
} else {
|
|
209
|
+
t6 = $[13];
|
|
210
|
+
}
|
|
211
|
+
useEffect(t5, t6);
|
|
212
|
+
let t7;
|
|
213
|
+
if ($[14] !== actions || $[15] !== drawOutlines || $[16] !== emitEaseMapToPoint || $[17] !== emitPhotoSelected || $[18] !== emitViewerPhoto || $[19] !== turnToWantedBearing) {
|
|
214
|
+
t7 = function mountMapillaryViewer() {
|
|
215
|
+
const container = containerRef.current;
|
|
216
|
+
if (!container) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const viewer_1 = new Viewer({
|
|
220
|
+
accessToken: getStreetImageryConfig().mapillaryToken,
|
|
221
|
+
container,
|
|
222
|
+
imageId: initialPhotoIdRef.current,
|
|
223
|
+
component: {
|
|
224
|
+
attribution: !initialHideAttributionRef.current,
|
|
225
|
+
cover: false,
|
|
226
|
+
sequence: {
|
|
227
|
+
visible: true
|
|
228
|
+
},
|
|
229
|
+
tag: true
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
viewerRef.current = viewer_1;
|
|
233
|
+
lastViewerPhotoIdRef.current = initialPhotoIdRef.current;
|
|
234
|
+
const flushPendingMove = () => {
|
|
235
|
+
const pendingId = pendingImageIdRef.current;
|
|
236
|
+
if (!pendingId) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
pendingImageIdRef.current = null;
|
|
240
|
+
viewer_1.moveTo(pendingId).catch(_temp2);
|
|
241
|
+
};
|
|
242
|
+
const onNavigable = (event) => {
|
|
243
|
+
navigableRef.current = event.navigable;
|
|
244
|
+
if (event.navigable) {
|
|
245
|
+
flushPendingMove();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
const onImage = (event_0) => {
|
|
249
|
+
const {
|
|
250
|
+
image: image_0
|
|
251
|
+
} = event_0;
|
|
252
|
+
lastViewerPhotoIdRef.current = image_0.id;
|
|
253
|
+
turnToWantedBearing(viewer_1, image_0);
|
|
254
|
+
drawOutlines(viewer_1);
|
|
255
|
+
emitPhotoSelected({
|
|
256
|
+
provider: "mapillary",
|
|
257
|
+
sequenceId: image_0.sequenceId,
|
|
258
|
+
photoId: image_0.id
|
|
259
|
+
});
|
|
260
|
+
const position = image_0.lngLat ?? image_0.originalLngLat;
|
|
261
|
+
if (!position) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
emitViewerPhoto({
|
|
265
|
+
providerId: "mapillary",
|
|
266
|
+
photoId: image_0.id,
|
|
267
|
+
sequenceId: image_0.sequenceId,
|
|
268
|
+
capturedAt: image_0.capturedAt,
|
|
269
|
+
isPano: image_0.cameraType === "spherical" || image_0.cameraType === "equirectangular",
|
|
270
|
+
heading: image_0.computedCompassAngle ?? image_0.compassAngle,
|
|
271
|
+
lngLat: [position.lng, position.lat],
|
|
272
|
+
...image_0.creatorUsername ? {
|
|
273
|
+
creatorName: image_0.creatorUsername
|
|
274
|
+
} : {}
|
|
275
|
+
});
|
|
276
|
+
const isFlat = image_0.cameraType !== "spherical" && image_0.cameraType !== "equirectangular";
|
|
277
|
+
const compass_0 = image_0.computedCompassAngle ?? image_0.compassAngle;
|
|
278
|
+
actions.setPov({
|
|
279
|
+
lngLat: [position.lng, position.lat],
|
|
280
|
+
...isFlat && compass_0 != null ? {
|
|
281
|
+
bearing: compass_0
|
|
282
|
+
} : {}
|
|
283
|
+
});
|
|
284
|
+
emitEaseMapToPoint(position.lng, position.lat);
|
|
285
|
+
};
|
|
286
|
+
const flushBearing = () => {
|
|
287
|
+
bearingRafRef.current = null;
|
|
288
|
+
if (pendingBearingRef.current != null) {
|
|
289
|
+
actions.setPov({
|
|
290
|
+
bearing: pendingBearingRef.current
|
|
291
|
+
});
|
|
292
|
+
pendingBearingRef.current = null;
|
|
293
|
+
}
|
|
294
|
+
viewer_1.getFieldOfView().then((fov) => {
|
|
295
|
+
actions.setPov({
|
|
296
|
+
hfov: fov
|
|
297
|
+
});
|
|
298
|
+
}).catch(_temp3);
|
|
299
|
+
};
|
|
300
|
+
const onBearing = (event_1) => {
|
|
301
|
+
pendingBearingRef.current = event_1.bearing;
|
|
302
|
+
if (bearingRafRef.current == null) {
|
|
303
|
+
bearingRafRef.current = requestAnimationFrame(flushBearing);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
viewer_1.on("navigable", onNavigable);
|
|
307
|
+
viewer_1.on("image", onImage);
|
|
308
|
+
viewer_1.on("bearing", onBearing);
|
|
309
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
310
|
+
viewer_1.resize();
|
|
311
|
+
});
|
|
312
|
+
resizeObserver.observe(container);
|
|
313
|
+
return () => {
|
|
314
|
+
if (bearingRafRef.current != null) {
|
|
315
|
+
cancelAnimationFrame(bearingRafRef.current);
|
|
316
|
+
bearingRafRef.current = null;
|
|
317
|
+
}
|
|
318
|
+
resizeObserver.disconnect();
|
|
319
|
+
viewer_1.off("navigable", onNavigable);
|
|
320
|
+
viewer_1.off("image", onImage);
|
|
321
|
+
viewer_1.off("bearing", onBearing);
|
|
322
|
+
viewer_1.remove();
|
|
323
|
+
viewerRef.current = null;
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
$[14] = actions;
|
|
327
|
+
$[15] = drawOutlines;
|
|
328
|
+
$[16] = emitEaseMapToPoint;
|
|
329
|
+
$[17] = emitPhotoSelected;
|
|
330
|
+
$[18] = emitViewerPhoto;
|
|
331
|
+
$[19] = turnToWantedBearing;
|
|
332
|
+
$[20] = t7;
|
|
333
|
+
} else {
|
|
334
|
+
t7 = $[20];
|
|
335
|
+
}
|
|
336
|
+
let t8;
|
|
337
|
+
if ($[21] !== actions) {
|
|
338
|
+
t8 = [actions];
|
|
339
|
+
$[21] = actions;
|
|
340
|
+
$[22] = t8;
|
|
341
|
+
} else {
|
|
342
|
+
t8 = $[22];
|
|
343
|
+
}
|
|
344
|
+
useEffect(t7, t8);
|
|
345
|
+
let t9;
|
|
346
|
+
if ($[23] !== onViewerView) {
|
|
347
|
+
t9 = (view) => onViewerView?.(view);
|
|
348
|
+
$[23] = onViewerView;
|
|
349
|
+
$[24] = t9;
|
|
350
|
+
} else {
|
|
351
|
+
t9 = $[24];
|
|
352
|
+
}
|
|
353
|
+
const emitViewerView = useEffectEvent(t9);
|
|
354
|
+
const reportsView = onViewerView !== void 0;
|
|
355
|
+
let t10;
|
|
356
|
+
if ($[25] !== emitViewerView || $[26] !== reportsView) {
|
|
357
|
+
t10 = function reportViewInPhoto() {
|
|
358
|
+
const viewer_2 = viewerRef.current;
|
|
359
|
+
if (!viewer_2 || !reportsView) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const read = async () => {
|
|
363
|
+
const [image_1, t112, zoom] = await Promise.all([viewer_2.getImage(), viewer_2.getCenter(), viewer_2.getZoom()]);
|
|
364
|
+
const [t122, t132] = t112;
|
|
365
|
+
const x = t122 === void 0 ? 0.5 : t122;
|
|
366
|
+
const y = t132 === void 0 ? 0.5 : t132;
|
|
367
|
+
return {
|
|
368
|
+
providerId: "mapillary",
|
|
369
|
+
photoId: image_1.id,
|
|
370
|
+
x,
|
|
371
|
+
y,
|
|
372
|
+
zoom
|
|
373
|
+
};
|
|
374
|
+
};
|
|
375
|
+
return watchMapillaryJsView(viewer_2, read, (view_0) => emitViewerView(view_0));
|
|
376
|
+
};
|
|
377
|
+
$[25] = emitViewerView;
|
|
378
|
+
$[26] = reportsView;
|
|
379
|
+
$[27] = t10;
|
|
380
|
+
} else {
|
|
381
|
+
t10 = $[27];
|
|
382
|
+
}
|
|
383
|
+
let t11;
|
|
384
|
+
if ($[28] !== actions || $[29] !== reportsView) {
|
|
385
|
+
t11 = [actions, reportsView];
|
|
386
|
+
$[28] = actions;
|
|
387
|
+
$[29] = reportsView;
|
|
388
|
+
$[30] = t11;
|
|
389
|
+
} else {
|
|
390
|
+
t11 = $[30];
|
|
391
|
+
}
|
|
392
|
+
useEffect(t10, t11);
|
|
393
|
+
let t12;
|
|
394
|
+
let t13;
|
|
395
|
+
if ($[31] !== actions || $[32] !== photo.photoId) {
|
|
396
|
+
t12 = function syncExternalPhotoSelection() {
|
|
397
|
+
const viewer_3 = viewerRef.current;
|
|
398
|
+
if (!viewer_3 || photo.photoId === lastViewerPhotoIdRef.current) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
actions.reset();
|
|
402
|
+
lastViewerPhotoIdRef.current = photo.photoId;
|
|
403
|
+
if (navigableRef.current) {
|
|
404
|
+
viewer_3.moveTo(photo.photoId).catch(_temp4);
|
|
405
|
+
} else {
|
|
406
|
+
pendingImageIdRef.current = photo.photoId;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
t13 = [actions, photo.photoId];
|
|
410
|
+
$[31] = actions;
|
|
411
|
+
$[32] = photo.photoId;
|
|
412
|
+
$[33] = t12;
|
|
413
|
+
$[34] = t13;
|
|
414
|
+
} else {
|
|
415
|
+
t12 = $[33];
|
|
416
|
+
t13 = $[34];
|
|
417
|
+
}
|
|
418
|
+
useEffect(t12, t13);
|
|
419
|
+
let t14;
|
|
420
|
+
if ($[35] !== lookAt || $[36] !== lookAtBearing) {
|
|
421
|
+
t14 = lookAt ? `${lookAt.lngLat.join(",")}|${lookAt.outline?.length ?? 0}|${lookAt.value ?? ""}` : String(lookAtBearing);
|
|
422
|
+
$[35] = lookAt;
|
|
423
|
+
$[36] = lookAtBearing;
|
|
424
|
+
$[37] = t14;
|
|
425
|
+
} else {
|
|
426
|
+
t14 = $[37];
|
|
427
|
+
}
|
|
428
|
+
const lookAtKey = t14;
|
|
429
|
+
let t15;
|
|
430
|
+
if ($[38] !== photo.photoId || $[39] !== turnToWantedBearing) {
|
|
431
|
+
t15 = function turnToTargetOnChange() {
|
|
432
|
+
const viewer_4 = viewerRef.current;
|
|
433
|
+
if (!viewer_4 || lastViewerPhotoIdRef.current !== photo.photoId) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
viewer_4.getImage().then((image_2) => turnToWantedBearing(viewer_4, image_2)).catch(_temp5);
|
|
437
|
+
};
|
|
438
|
+
$[38] = photo.photoId;
|
|
439
|
+
$[39] = turnToWantedBearing;
|
|
440
|
+
$[40] = t15;
|
|
441
|
+
} else {
|
|
442
|
+
t15 = $[40];
|
|
443
|
+
}
|
|
444
|
+
let t16;
|
|
445
|
+
if ($[41] !== lookAtKey || $[42] !== photo.photoId) {
|
|
446
|
+
t16 = [lookAtKey, photo.photoId];
|
|
447
|
+
$[41] = lookAtKey;
|
|
448
|
+
$[42] = photo.photoId;
|
|
449
|
+
$[43] = t16;
|
|
450
|
+
} else {
|
|
451
|
+
t16 = $[43];
|
|
452
|
+
}
|
|
453
|
+
useEffect(t15, t16);
|
|
454
|
+
let t17;
|
|
455
|
+
if ($[44] !== drawOutlines) {
|
|
456
|
+
t17 = function redrawOutlinesOnChange() {
|
|
457
|
+
const viewer_5 = viewerRef.current;
|
|
458
|
+
if (viewer_5 && navigableRef.current) {
|
|
459
|
+
drawOutlines(viewer_5);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
$[44] = drawOutlines;
|
|
463
|
+
$[45] = t17;
|
|
464
|
+
} else {
|
|
465
|
+
t17 = $[45];
|
|
466
|
+
}
|
|
467
|
+
let t18;
|
|
468
|
+
if ($[46] !== outlines) {
|
|
469
|
+
t18 = [outlines];
|
|
470
|
+
$[46] = outlines;
|
|
471
|
+
$[47] = t18;
|
|
472
|
+
} else {
|
|
473
|
+
t18 = $[47];
|
|
474
|
+
}
|
|
475
|
+
useEffect(t17, t18);
|
|
476
|
+
let t19;
|
|
477
|
+
if ($[48] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
478
|
+
t19 = /* @__PURE__ */ jsx("div", { ref: containerRef, className: "min-h-48 overflow-hidden rounded-lg border border-slate-200 bg-slate-900", style: {
|
|
479
|
+
aspectRatio: "4 / 3"
|
|
480
|
+
} });
|
|
481
|
+
$[48] = t19;
|
|
482
|
+
} else {
|
|
483
|
+
t19 = $[48];
|
|
484
|
+
}
|
|
485
|
+
return t19;
|
|
486
|
+
};
|
|
487
|
+
function _temp() {
|
|
488
|
+
}
|
|
489
|
+
function _temp2() {
|
|
490
|
+
}
|
|
491
|
+
function _temp3() {
|
|
492
|
+
}
|
|
493
|
+
function _temp4() {
|
|
494
|
+
}
|
|
495
|
+
function _temp5() {
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export { MapillaryPanel, mapillaryViewFor, setMapillaryViewerOutlines, turnMapillaryViewerTo };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/panels/photoView.ts
|
|
2
|
+
var REPORT_DELAY_MS = 200;
|
|
3
|
+
var PANORAMAX_MIN_FOV = 5;
|
|
4
|
+
var PANORAMAX_MAX_FOV = 90;
|
|
5
|
+
var tanOfHalf = (degrees) => Math.tan(degrees * Math.PI / 360);
|
|
6
|
+
var panoramaxZoomLevel = (verticalFov, horizontalFovOfPicture) => {
|
|
7
|
+
const maxFov = Math.min(horizontalFovOfPicture * 3 / 4, PANORAMAX_MAX_FOV);
|
|
8
|
+
const fov = horizontalFovOfPicture >= 360 ? verticalFov : tanOfHalf(verticalFov) / tanOfHalf(horizontalFovOfPicture) * horizontalFovOfPicture;
|
|
9
|
+
const level = (maxFov - fov) / (maxFov - PANORAMAX_MIN_FOV) * 100;
|
|
10
|
+
return Math.min(100, Math.max(0, level));
|
|
11
|
+
};
|
|
12
|
+
var viewKey = (view) => JSON.stringify(view, (_, value) => typeof value === "number" ? Number(value.toFixed(4)) : value);
|
|
13
|
+
var createPhotoViewReporter = (read, report, delayMs = REPORT_DELAY_MS) => {
|
|
14
|
+
let timer;
|
|
15
|
+
let last = null;
|
|
16
|
+
let stopped = false;
|
|
17
|
+
const send = () => {
|
|
18
|
+
void read().then((view) => {
|
|
19
|
+
if (view && !stopped && viewKey(view) !== last) {
|
|
20
|
+
last = viewKey(view);
|
|
21
|
+
report(view);
|
|
22
|
+
}
|
|
23
|
+
}).catch(() => {
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
viewChanged: () => {
|
|
28
|
+
clearTimeout(timer);
|
|
29
|
+
timer = setTimeout(send, delayMs);
|
|
30
|
+
},
|
|
31
|
+
stop: () => {
|
|
32
|
+
stopped = true;
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
var watchMapillaryJsView = (viewer, read, report) => {
|
|
38
|
+
const reporter = createPhotoViewReporter(read, report);
|
|
39
|
+
const {
|
|
40
|
+
viewChanged
|
|
41
|
+
} = reporter;
|
|
42
|
+
viewer.on("image", viewChanged);
|
|
43
|
+
viewer.on("pov", viewChanged);
|
|
44
|
+
viewer.on("fov", viewChanged);
|
|
45
|
+
viewer.on("moveend", viewChanged);
|
|
46
|
+
viewChanged();
|
|
47
|
+
return () => {
|
|
48
|
+
reporter.stop();
|
|
49
|
+
viewer.off("image", viewChanged);
|
|
50
|
+
viewer.off("pov", viewChanged);
|
|
51
|
+
viewer.off("fov", viewChanged);
|
|
52
|
+
viewer.off("moveend", viewChanged);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export { createPhotoViewReporter, panoramaxZoomLevel, watchMapillaryJsView };
|
|
@@ -10,7 +10,10 @@ export type PhotoDateMarker = {
|
|
|
10
10
|
export type PhotoDateRangeFilterProps = {
|
|
11
11
|
/** The chosen range, days as `YYYY-MM-DD`. No `from` and no `to`: all dates. */
|
|
12
12
|
value: DateRange;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Called when a handle is released, the chart is clicked, a year label is clicked or a date
|
|
15
|
+
* input changes.
|
|
16
|
+
*/
|
|
14
17
|
onChange: (range: DateRange) => void;
|
|
15
18
|
/**
|
|
16
19
|
* Capture times (ms) of the photos to show as marks above the slider, usually all photos in
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DateSliderPositions } from '@osm-editor-kit/street-imagery';
|
|
2
|
+
export type DateSliderHandle = 'from' | 'to';
|
|
3
|
+
/** Size of one step of the slider, in positions: about a day to a month, depending on the age. */
|
|
4
|
+
export declare const DATE_SLIDER_STEP = 0.001;
|
|
5
|
+
/** The handles as they show. */
|
|
6
|
+
export declare const HANDLE_PX = 16;
|
|
7
|
+
/** Position of a point `leftPx` from the start of the track, in steps like the native handles. */
|
|
8
|
+
export declare const positionOnTrack: (leftPx: number, widthPx: number) => number;
|
|
9
|
+
/**
|
|
10
|
+
* The handle a press takes. `null` when the handles overlap under the press: they can only move
|
|
11
|
+
* apart, so the direction of the drag decides (`handleOfDrag`), also when both are at one end.
|
|
12
|
+
*/
|
|
13
|
+
export declare const pressedHandle: (positions: DateSliderPositions, press: number, widthPx: number) => DateSliderHandle | null;
|
|
14
|
+
export declare const handleOfDrag: (deltaPx: number) => DateSliderHandle;
|
|
15
|
+
/** A drag keeps the distance between a grabbed handle and the pointer: the handle does not jump. */
|
|
16
|
+
export declare const dragPositions: (start: DateSliderPositions, press: number, handle: DateSliderHandle, deltaPx: number, widthPx: number) => DateSliderPositions;
|
|
17
|
+
/** A click or tap moves the nearer handle there, or does nothing on a handle itself. */
|
|
18
|
+
export declare const tapPositions: (start: DateSliderPositions, press: number, widthPx: number) => {
|
|
19
|
+
handle: DateSliderHandle;
|
|
20
|
+
positions: DateSliderPositions | null;
|
|
21
|
+
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { Bbox } from '@osm-editor-kit/street-imagery';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* WGS84 bbox of a react-map-gl map, updated when a move of the map ends. The array stays the same
|
|
4
|
+
* object while the viewport is the same, so it works as a dependency and as a prop.
|
|
4
5
|
* @param mapId - react-map-gl `<Map id=…>`
|
|
5
|
-
* @param viewportTrigger - optional value that changes when the camera moves
|
|
6
|
-
* (e.g. URL map param) so the bbox recomputes after pan/zoom without relying
|
|
7
|
-
* on MapLibre events.
|
|
8
6
|
*/
|
|
9
|
-
export declare const useMapViewportBbox: (mapId: string
|
|
7
|
+
export declare const useMapViewportBbox: (mapId: string) => Bbox | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { VIEWPOINT_DEFAULT_COLOR, VIEWPOINT_DIRECTION_LAYER_ID, ViewpointLayer,
|
|
|
15
15
|
export { viewSuggestionLabel } from './viewpoints/viewDirectionLabels';
|
|
16
16
|
export * from './viewpoints/useViewpointSessionStore';
|
|
17
17
|
export * from './viewpoints/useViewSuggestions';
|
|
18
|
+
export * from './viewpoints/usePhotosLookingAt';
|
|
18
19
|
export type { MapillaryLookAt, MapillaryViewerOutline } from './panels/mapillaryLookAt';
|
|
19
20
|
export * from './mapillary/useMapillaryFeatures';
|
|
20
21
|
export { LocationPickOnMap, type LocationPickOnMapProps } from './openers/LocationPickOnMap';
|