@osm-editor-kit/street-imagery-react 0.1.0-alpha.8 → 1.0.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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -9
  3. package/dist/MapillaryPanel-SOHGB7JA.js +3 -0
  4. package/dist/PanoramaxPanel-5P5LWMRY.js +3 -0
  5. package/dist/StreetLevelImagerySelectionOverlay.d.ts +3 -1
  6. package/dist/StreetLevelImagerySourcesAndLayers.d.ts +10 -0
  7. package/dist/StreetLevelImageryViewCone.d.ts +3 -1
  8. package/dist/StreetLevelImageryViewer.d.ts +18 -4
  9. package/dist/{chunk-ZAIXGYAH.js → chunk-3DFVM6VK.js} +59 -15
  10. package/dist/{chunk-25UGGXIE.js → chunk-GYUS2JVV.js} +24 -4
  11. package/dist/chunk-LZR5SZDS.js +498 -0
  12. package/dist/chunk-R6BDVYWM.js +665 -0
  13. package/dist/chunk-XLBFXACK.js +56 -0
  14. package/dist/filters/PhotoDateRangeFilter.d.ts +10 -2
  15. package/dist/filters/dateSliderPointer.d.ts +21 -0
  16. package/dist/hooks/useMapViewportBbox.d.ts +3 -5
  17. package/dist/hooks/useProviderData.d.ts +14 -3
  18. package/dist/index.d.ts +12 -13
  19. package/dist/index.js +3942 -1461
  20. package/dist/mapillary/useMapillaryFeatures.d.ts +5 -5
  21. package/dist/panels/MapillaryPanel.d.ts +7 -2
  22. package/dist/panels/PanoramaxPanel.d.ts +16 -8
  23. package/dist/panels/PanoramaxWebViewerPanel.d.ts +25 -0
  24. package/dist/panels/panoramaxDataProvider.d.ts +44 -0
  25. package/dist/panels/panoramaxItem.d.ts +98 -0
  26. package/dist/panels/photoView.d.ts +19 -0
  27. package/dist/panoramax-web-viewer/index.d.ts +1 -0
  28. package/dist/{chunk-EQ2JKLGT.js → panoramax-web-viewer.js} +299 -92
  29. package/dist/photo-details.js +222 -151
  30. package/dist/streetImageryClick.d.ts +4 -0
  31. package/dist/viewer-panels/index.d.ts +5 -0
  32. package/dist/viewer-panels.js +4 -0
  33. package/dist/viewpoints/FloatingPhotoViewer.d.ts +39 -11
  34. package/dist/viewpoints/floatingViewerPosition.d.ts +18 -0
  35. package/dist/viewpoints/usePhotosLookingAt.d.ts +26 -0
  36. package/package.json +32 -6
  37. package/dist/MapillaryPanel-N45NQY4C.js +0 -2
  38. package/dist/PanoramaxPanel-MFI4L67Z.js +0 -2
  39. package/dist/chunk-53RA4OSJ.js +0 -304
@@ -1,8 +1,10 @@
1
- import { useViewerActions } from './chunk-25UGGXIE.js';
1
+ import { createPhotoViewReporter } from './chunk-XLBFXACK.js';
2
+ import { useViewerActions } from './chunk-GYUS2JVV.js';
3
+ import { c } from 'react/compiler-runtime';
2
4
  import '@panoramax/web-viewer';
3
5
  import { getStreetImageryConfig } from '@osm-editor-kit/street-imagery';
4
6
  import { useRef, useEffectEvent, useEffect } from 'react';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
8
 
7
9
  // src/panels/panoramaxLimitPanning.ts
8
10
  var toRad = (degrees) => degrees * Math.PI / 180;
@@ -19,7 +21,10 @@ var limitToImage = (psv, position) => {
19
21
  }
20
22
  const halfH = toRad(psv.state.hFov) / 2;
21
23
  const halfV = toRad(psv.state.vFov) / 2;
22
- let { yaw, pitch } = position;
24
+ let {
25
+ yaw,
26
+ pitch
27
+ } = position;
23
28
  if (crop.croppedWidth < crop.fullWidth) {
24
29
  const left = crop.croppedX / crop.fullWidth * 2 * Math.PI - Math.PI;
25
30
  const right = (crop.croppedX + crop.croppedWidth) / crop.fullWidth * 2 * Math.PI - Math.PI;
@@ -31,7 +36,10 @@ var limitToImage = (psv, position) => {
31
36
  const bottom = Math.PI / 2 - (crop.croppedY + crop.croppedHeight) / crop.fullHeight * Math.PI;
32
37
  pitch = keepInView(pitch, bottom, top, halfV);
33
38
  }
34
- return { yaw, pitch };
39
+ return {
40
+ yaw,
41
+ pitch
42
+ };
35
43
  };
36
44
  var toDeg = (radians) => radians * 180 / Math.PI;
37
45
  var widestZoomLevel = (psv) => {
@@ -100,20 +108,48 @@ var panoramaxPhotoFromMetadata = (metadata) => {
100
108
  const exifEntries = Object.entries(properties.exif ?? {}).filter(([, value]) => typeof value === "string" || typeof value === "number").map(([key, value]) => [key, String(value)]);
101
109
  const exif = exifEntries.length > 0 ? Object.fromEntries(exifEntries) : null;
102
110
  const details = {
103
- ...creatorContact && creatorContact !== creatorName ? { creatorContact } : {},
104
- ...properties.license ? { license: properties.license } : {},
105
- ...metadata.origLinks?.find((link) => link.rel === "license")?.href ? { licenseUrl: metadata.origLinks.find((link) => link.rel === "license")?.href } : {},
106
- ...properties.datetimetz ? { capturedAtLocal: properties.datetimetz } : {},
107
- ...uploadedAt != null ? { uploadedAt } : {},
108
- ...cameraName ? { camera: cameraName } : {},
109
- ...isFlat && metadata.horizontalFov ? { fieldOfViewDeg: metadata.horizontalFov } : {},
110
- ...properties["quality:horizontal_accuracy"] != null ? { positionAccuracyMeters: properties["quality:horizontal_accuracy"] } : {},
111
- ...metadata.origInstance?.instance_name ? { instance: metadata.origInstance.instance_name } : {},
112
- ...camera?.focal_length != null ? { focalLengthMm: camera.focal_length } : {},
113
- ...properties["original_file:name"] ? { originalFileName: properties["original_file:name"] } : {},
114
- ...properties["original_file:size"] != null ? { originalFileSizeBytes: properties["original_file:size"] } : {},
115
- ...properties["geovisio:rank_in_collection"] != null ? { rankInSequence: properties["geovisio:rank_in_collection"] } : {},
116
- ...exif ? { exif } : {}
111
+ ...creatorContact && creatorContact !== creatorName ? {
112
+ creatorContact
113
+ } : {},
114
+ ...properties.license ? {
115
+ license: properties.license
116
+ } : {},
117
+ ...metadata.origLinks?.find((link) => link.rel === "license")?.href ? {
118
+ licenseUrl: metadata.origLinks.find((link) => link.rel === "license")?.href
119
+ } : {},
120
+ ...properties.datetimetz ? {
121
+ capturedAtLocal: properties.datetimetz
122
+ } : {},
123
+ ...uploadedAt != null ? {
124
+ uploadedAt
125
+ } : {},
126
+ ...cameraName ? {
127
+ camera: cameraName
128
+ } : {},
129
+ ...isFlat && metadata.horizontalFov ? {
130
+ fieldOfViewDeg: metadata.horizontalFov
131
+ } : {},
132
+ ...properties["quality:horizontal_accuracy"] != null ? {
133
+ positionAccuracyMeters: properties["quality:horizontal_accuracy"]
134
+ } : {},
135
+ ...metadata.origInstance?.instance_name ? {
136
+ instance: metadata.origInstance.instance_name
137
+ } : {},
138
+ ...camera?.focal_length != null ? {
139
+ focalLengthMm: camera.focal_length
140
+ } : {},
141
+ ...properties["original_file:name"] ? {
142
+ originalFileName: properties["original_file:name"]
143
+ } : {},
144
+ ...properties["original_file:size"] != null ? {
145
+ originalFileSizeBytes: properties["original_file:size"]
146
+ } : {},
147
+ ...properties["geovisio:rank_in_collection"] != null ? {
148
+ rankInSequence: properties["geovisio:rank_in_collection"]
149
+ } : {},
150
+ ...exif ? {
151
+ exif
152
+ } : {}
117
153
  };
118
154
  return {
119
155
  providerId: "panoramax",
@@ -123,20 +159,29 @@ var panoramaxPhotoFromMetadata = (metadata) => {
123
159
  isPano: !isFlat,
124
160
  heading: properties["view:azimuth"] ?? null,
125
161
  lngLat: metadata.gps,
126
- ...creatorName ? { creatorName } : {},
162
+ ...creatorName ? {
163
+ creatorName
164
+ } : {},
127
165
  details
128
166
  };
129
167
  };
130
168
  var panoramaxApiEndpoint = () => `${getStreetImageryConfig().panoramaxApiBase}/api`;
131
169
  var HIDE_LEGEND_CSS = "pnx-photo-viewer pnx-bottom-drawer, pnx-photo-viewer pnx-picture-legend { display: none !important; }";
132
170
  var normalizeBearing = (degrees) => (degrees % 360 + 360) % 360;
133
- var PanoramaxPanel = ({
134
- photo,
135
- onPhotoSelected,
136
- onEaseMapToPoint,
137
- onViewerPhoto,
138
- hideLegend = false
139
- }) => {
171
+ var PanoramaxWebViewerPanel = (t0) => {
172
+ const $ = c(42);
173
+ const {
174
+ photo,
175
+ onPhotoSelected,
176
+ onEaseMapToPoint,
177
+ onViewerPhoto,
178
+ onViewerView,
179
+ hideLegend: t1,
180
+ hideAttribution: t2
181
+ } = t0;
182
+ const hideLegendProp = t1 === void 0 ? false : t1;
183
+ const hideAttribution = t2 === void 0 ? false : t2;
184
+ const hideLegend = hideLegendProp || hideAttribution;
140
185
  const containerRef = useRef(null);
141
186
  const viewerRef = useRef(null);
142
187
  const lastViewerPhotoIdRef = useRef(null);
@@ -147,25 +192,55 @@ var PanoramaxPanel = ({
147
192
  const pendingBearingRef = useRef(null);
148
193
  const pendingHfovRef = useRef(null);
149
194
  const actions = useViewerActions();
150
- const emitViewerPhoto = useEffectEvent(
151
- (viewerPhoto) => onViewerPhoto?.(viewerPhoto)
152
- );
153
- useEffect(
154
- function syncPhotoRef() {
195
+ let t3;
196
+ if ($[0] !== onViewerPhoto) {
197
+ t3 = (viewerPhoto) => onViewerPhoto?.(viewerPhoto);
198
+ $[0] = onViewerPhoto;
199
+ $[1] = t3;
200
+ } else {
201
+ t3 = $[1];
202
+ }
203
+ const emitViewerPhoto = useEffectEvent(t3);
204
+ let t4;
205
+ let t5;
206
+ if ($[2] !== photo) {
207
+ t4 = function syncPhotoRef() {
155
208
  photoRef.current = photo;
156
- },
157
- [photo]
158
- );
159
- useEffect(
160
- function resetViewerStoreOnProviderChange() {
209
+ };
210
+ t5 = [photo];
211
+ $[2] = photo;
212
+ $[3] = t4;
213
+ $[4] = t5;
214
+ } else {
215
+ t4 = $[3];
216
+ t5 = $[4];
217
+ }
218
+ useEffect(t4, t5);
219
+ let t6;
220
+ if ($[5] !== actions) {
221
+ t6 = function resetViewerStoreOnProviderChange() {
161
222
  return () => {
162
223
  actions.reset();
163
224
  };
164
- },
165
- [actions, photo.providerId]
166
- );
167
- useEffect(
168
- function mountPanoramaxViewer() {
225
+ };
226
+ $[5] = actions;
227
+ $[6] = t6;
228
+ } else {
229
+ t6 = $[6];
230
+ }
231
+ let t7;
232
+ if ($[7] !== actions || $[8] !== photo.providerId) {
233
+ t7 = [actions, photo.providerId];
234
+ $[7] = actions;
235
+ $[8] = photo.providerId;
236
+ $[9] = t7;
237
+ } else {
238
+ t7 = $[9];
239
+ }
240
+ useEffect(t6, t7);
241
+ let t8;
242
+ if ($[10] !== actions || $[11] !== emitViewerPhoto || $[12] !== onEaseMapToPoint || $[13] !== onPhotoSelected) {
243
+ t8 = function mountPanoramaxViewer() {
169
244
  const viewer = viewerRef.current;
170
245
  const container = containerRef.current;
171
246
  if (!viewer || !container) {
@@ -175,16 +250,23 @@ var PanoramaxPanel = ({
175
250
  const flushBearing = () => {
176
251
  bearingRafRef.current = null;
177
252
  if (pendingBearingRef.current != null) {
178
- actions.setPov({ bearing: pendingBearingRef.current });
253
+ actions.setPov({
254
+ bearing: pendingBearingRef.current
255
+ });
179
256
  pendingBearingRef.current = null;
180
257
  }
181
258
  if (pendingHfovRef.current != null) {
182
- actions.setPov({ hfov: pendingHfovRef.current });
259
+ actions.setPov({
260
+ hfov: pendingHfovRef.current
261
+ });
183
262
  pendingHfovRef.current = null;
184
263
  }
185
264
  };
186
265
  const onSelect = (event) => {
187
- const { seqId, picId } = event.detail;
266
+ const {
267
+ seqId,
268
+ picId
269
+ } = event.detail;
188
270
  if (!picId) {
189
271
  return;
190
272
  }
@@ -197,8 +279,8 @@ var PanoramaxPanel = ({
197
279
  photoId: picId
198
280
  });
199
281
  };
200
- const onPictureLoaded = (event) => {
201
- const detail = event.detail;
282
+ const onPictureLoaded = (event_0) => {
283
+ const detail = event_0.detail;
202
284
  const metadata = viewer.psv?.getPictureMetadata();
203
285
  if (metadata) {
204
286
  emitViewerPhoto(panoramaxPhotoFromMetadata(metadata));
@@ -206,22 +288,28 @@ var PanoramaxPanel = ({
206
288
  if (detail.lon == null || detail.lat == null) {
207
289
  return;
208
290
  }
209
- actions.setPov({ lngLat: [detail.lon, detail.lat] });
291
+ actions.setPov({
292
+ lngLat: [detail.lon, detail.lat]
293
+ });
210
294
  if (detail.x != null) {
211
- actions.setPov({ bearing: normalizeBearing(detail.x) });
295
+ actions.setPov({
296
+ bearing: normalizeBearing(detail.x)
297
+ });
212
298
  }
213
299
  const psv = viewer.psv;
214
300
  if (psv && detail.z != null) {
215
- actions.setPov({ hfov: psv.dataHelper.zoomLevelToFov(detail.z) });
301
+ actions.setPov({
302
+ hfov: psv.dataHelper.zoomLevelToFov(detail.z)
303
+ });
216
304
  }
217
305
  onEaseMapToPoint(detail.lon, detail.lat);
218
306
  };
219
- const onViewRotated = (event) => {
220
- const detail = event.detail;
221
- pendingBearingRef.current = normalizeBearing(detail.x);
222
- const psv = viewer.psv;
223
- if (psv && detail.z != null) {
224
- pendingHfovRef.current = psv.dataHelper.zoomLevelToFov(detail.z);
307
+ const onViewRotated = (event_1) => {
308
+ const detail_0 = event_1.detail;
309
+ pendingBearingRef.current = normalizeBearing(detail_0.x);
310
+ const psv_0 = viewer.psv;
311
+ if (psv_0 && detail_0.z != null) {
312
+ pendingHfovRef.current = psv_0.dataHelper.zoomLevelToFov(detail_0.z);
225
313
  }
226
314
  if (bearingRafRef.current == null) {
227
315
  bearingRafRef.current = requestAnimationFrame(flushBearing);
@@ -234,7 +322,8 @@ var PanoramaxPanel = ({
234
322
  viewer.psv?.resize();
235
323
  });
236
324
  resizeObserver.observe(container);
237
- let stopLimit = null;
325
+ let stopLimit;
326
+ stopLimit = null;
238
327
  const startLimit = () => {
239
328
  if (!stopLimit && viewer.psv) {
240
329
  stopLimit = limitPanningToImage(viewer.psv);
@@ -263,49 +352,167 @@ var PanoramaxPanel = ({
263
352
  viewer.removeEventListener("psv:picture-loaded", startLimit);
264
353
  stopLimit?.();
265
354
  };
266
- },
267
- [actions, onEaseMapToPoint, onPhotoSelected]
268
- );
269
- useEffect(
270
- function syncExternalPhotoSelection() {
271
- const viewer = viewerRef.current;
272
- if (!viewer || photo.photoId === lastViewerPhotoIdRef.current) {
355
+ };
356
+ $[10] = actions;
357
+ $[11] = emitViewerPhoto;
358
+ $[12] = onEaseMapToPoint;
359
+ $[13] = onPhotoSelected;
360
+ $[14] = t8;
361
+ } else {
362
+ t8 = $[14];
363
+ }
364
+ let t9;
365
+ if ($[15] !== actions || $[16] !== onEaseMapToPoint || $[17] !== onPhotoSelected) {
366
+ t9 = [actions, onEaseMapToPoint, onPhotoSelected];
367
+ $[15] = actions;
368
+ $[16] = onEaseMapToPoint;
369
+ $[17] = onPhotoSelected;
370
+ $[18] = t9;
371
+ } else {
372
+ t9 = $[18];
373
+ }
374
+ useEffect(t8, t9);
375
+ let t10;
376
+ if ($[19] !== onViewerView) {
377
+ t10 = (view) => onViewerView?.(view);
378
+ $[19] = onViewerView;
379
+ $[20] = t10;
380
+ } else {
381
+ t10 = $[20];
382
+ }
383
+ const emitViewerView = useEffectEvent(t10);
384
+ const reportsView = onViewerView !== void 0;
385
+ let t11;
386
+ if ($[21] !== emitViewerView || $[22] !== reportsView) {
387
+ t11 = function reportViewInPhoto() {
388
+ const viewer_0 = viewerRef.current;
389
+ if (!viewer_0 || !reportsView) {
390
+ return;
391
+ }
392
+ const read = async () => {
393
+ const psv_1 = viewer_0.psv;
394
+ const photoId = psv_1?.getPictureMetadata()?.id;
395
+ if (!psv_1 || !photoId) {
396
+ return null;
397
+ }
398
+ const {
399
+ x,
400
+ y,
401
+ z
402
+ } = psv_1.getXYZ();
403
+ return {
404
+ providerId: "panoramax",
405
+ photoId,
406
+ heading: x,
407
+ pitch: y,
408
+ zoom: z
409
+ };
410
+ };
411
+ const reporter = createPhotoViewReporter(read, (view_0) => emitViewerView(view_0));
412
+ viewer_0.addEventListener("psv:picture-loaded", reporter.viewChanged);
413
+ viewer_0.addEventListener("psv:view-rotated", reporter.viewChanged);
414
+ return () => {
415
+ reporter.stop();
416
+ viewer_0.removeEventListener("psv:picture-loaded", reporter.viewChanged);
417
+ viewer_0.removeEventListener("psv:view-rotated", reporter.viewChanged);
418
+ };
419
+ };
420
+ $[21] = emitViewerView;
421
+ $[22] = reportsView;
422
+ $[23] = t11;
423
+ } else {
424
+ t11 = $[23];
425
+ }
426
+ let t12;
427
+ if ($[24] !== reportsView) {
428
+ t12 = [reportsView];
429
+ $[24] = reportsView;
430
+ $[25] = t12;
431
+ } else {
432
+ t12 = $[25];
433
+ }
434
+ useEffect(t11, t12);
435
+ let t13;
436
+ let t14;
437
+ if ($[26] !== actions || $[27] !== photo.photoId || $[28] !== photo.sequenceId) {
438
+ t13 = function syncExternalPhotoSelection() {
439
+ const viewer_1 = viewerRef.current;
440
+ if (!viewer_1 || photo.photoId === lastViewerPhotoIdRef.current) {
273
441
  return;
274
442
  }
275
443
  actions.reset();
276
444
  lastViewerPhotoIdRef.current = photo.photoId;
277
445
  if (!readyRef.current) {
278
- pendingSelectRef.current = { sequenceId: photo.sequenceId, photoId: photo.photoId };
446
+ pendingSelectRef.current = {
447
+ sequenceId: photo.sequenceId,
448
+ photoId: photo.photoId
449
+ };
279
450
  return;
280
451
  }
281
- if (typeof viewer.select === "function") {
282
- viewer.select(photo.sequenceId ?? null, photo.photoId);
452
+ if (typeof viewer_1.select === "function") {
453
+ viewer_1.select(photo.sequenceId ?? null, photo.photoId);
283
454
  }
284
- },
285
- [actions, photo.photoId, photo.sequenceId]
286
- );
287
- return /* @__PURE__ */ jsxs(
288
- "div",
289
- {
290
- ref: containerRef,
291
- className: "min-h-48 overflow-hidden rounded-lg border border-slate-200 bg-slate-900",
292
- style: { aspectRatio: "4 / 3" },
293
- children: [
294
- hideLegend ? /* @__PURE__ */ jsx("style", { children: HIDE_LEGEND_CSS }) : null,
295
- /* @__PURE__ */ jsx(
296
- "pnx-photo-viewer",
297
- {
298
- ref: viewerRef,
299
- className: "block h-full w-full",
300
- endpoint: panoramaxApiEndpoint(),
301
- "url-parameters": "false",
302
- picture: photo.photoId,
303
- sequence: photo.sequenceId ?? void 0
304
- }
305
- )
306
- ]
307
- }
308
- );
455
+ };
456
+ t14 = [actions, photo.photoId, photo.sequenceId];
457
+ $[26] = actions;
458
+ $[27] = photo.photoId;
459
+ $[28] = photo.sequenceId;
460
+ $[29] = t13;
461
+ $[30] = t14;
462
+ } else {
463
+ t13 = $[29];
464
+ t14 = $[30];
465
+ }
466
+ useEffect(t13, t14);
467
+ let t15;
468
+ if ($[31] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
469
+ t15 = {
470
+ aspectRatio: "4 / 3"
471
+ };
472
+ $[31] = t15;
473
+ } else {
474
+ t15 = $[31];
475
+ }
476
+ let t16;
477
+ if ($[32] !== hideLegend) {
478
+ t16 = hideLegend ? /* @__PURE__ */ jsx("style", { children: HIDE_LEGEND_CSS }) : null;
479
+ $[32] = hideLegend;
480
+ $[33] = t16;
481
+ } else {
482
+ t16 = $[33];
483
+ }
484
+ let t17;
485
+ if ($[34] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
486
+ t17 = panoramaxApiEndpoint();
487
+ $[34] = t17;
488
+ } else {
489
+ t17 = $[34];
490
+ }
491
+ const t18 = hideLegend ? "false" : void 0;
492
+ const t19 = photo.sequenceId ?? void 0;
493
+ let t20;
494
+ if ($[35] !== photo.photoId || $[36] !== t18 || $[37] !== t19) {
495
+ t20 = /* @__PURE__ */ jsx("pnx-photo-viewer", { ref: viewerRef, className: "block h-full w-full", endpoint: t17, "url-parameters": "false", widgets: t18, picture: photo.photoId, sequence: t19 });
496
+ $[35] = photo.photoId;
497
+ $[36] = t18;
498
+ $[37] = t19;
499
+ $[38] = t20;
500
+ } else {
501
+ t20 = $[38];
502
+ }
503
+ let t21;
504
+ if ($[39] !== t16 || $[40] !== t20) {
505
+ t21 = /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "min-h-48 overflow-hidden rounded-lg border border-slate-200 bg-slate-900", style: t15, children: [
506
+ t16,
507
+ t20
508
+ ] });
509
+ $[39] = t16;
510
+ $[40] = t20;
511
+ $[41] = t21;
512
+ } else {
513
+ t21 = $[41];
514
+ }
515
+ return t21;
309
516
  };
310
517
 
311
- export { PanoramaxPanel };
518
+ export { PanoramaxWebViewerPanel };