@osm-editor-kit/street-imagery-react 0.1.0-alpha.5 → 0.1.0-alpha.6
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 +45 -0
- package/dist/MapillaryPanel-N45NQY4C.js +2 -0
- package/dist/PanoramaxPanel-MFI4L67Z.js +2 -0
- package/dist/StreetLevelImagerySelectionOverlay.d.ts +20 -3
- package/dist/StreetLevelImagerySourcesAndLayers.d.ts +9 -1
- package/dist/StreetLevelImageryViewCone.d.ts +11 -1
- package/dist/StreetLevelImageryViewer.d.ts +7 -2
- package/dist/{chunk-72HJV6II.js → chunk-53RA4OSJ.js} +6 -2
- package/dist/chunk-EQ2JKLGT.js +311 -0
- package/dist/chunk-HA4GJWHI.js +120 -0
- package/dist/hooks/useAllProviderMapFeatures.d.ts +0 -4
- package/dist/i18n/PhotoDate.d.ts +16 -0
- package/dist/i18n/StreetImageryLocaleProvider.d.ts +21 -0
- package/dist/i18n/messages.d.ts +35 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +470 -167
- package/dist/mapillary/MapillaryFeatureBar.d.ts +13 -0
- package/dist/openers/LocationPickOnMap.d.ts +10 -0
- package/dist/openers/useLocationPickStore.d.ts +9 -0
- package/dist/panels/MapillaryPanel.d.ts +7 -1
- package/dist/panels/PanoramaxPanel.d.ts +8 -1
- package/dist/panels/panoramaxLimitPanning.d.ts +54 -0
- package/dist/panels/panoramaxPhotoFromMetadata.d.ts +8 -0
- package/dist/photo-details/PhotoDetailsDialog.d.ts +21 -0
- package/dist/photo-details/index.d.ts +6 -0
- package/dist/photo-details/labels.d.ts +33 -0
- package/dist/photo-details.js +235 -0
- package/dist/viewpoints/FloatingPhotoViewer.d.ts +25 -2
- package/dist/viewpoints/useViewpointSessionStore.d.ts +2 -9
- package/dist/viewpoints/viewDirectionLabels.d.ts +4 -4
- package/package.json +10 -2
- package/dist/MapillaryPanel-I5GKT6YT.js +0 -2
- package/dist/PanoramaxPanel-J6ANR6LB.js +0 -2
- package/dist/chunk-ZH3TPW4D.js +0 -165
package/dist/index.js
CHANGED
|
@@ -1,67 +1,127 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import { useStreetImageryI18n } from './chunk-HA4GJWHI.js';
|
|
2
|
+
export { STREET_IMAGERY_MESSAGES, StreetImageryLocaleProvider, useStreetImageryI18n } from './chunk-HA4GJWHI.js';
|
|
3
|
+
export { MapillaryPanel, mapillaryViewFor, setMapillaryViewerOutlines, turnMapillaryViewerTo } from './chunk-53RA4OSJ.js';
|
|
4
|
+
export { PanoramaxPanel } from './chunk-EQ2JKLGT.js';
|
|
3
5
|
export { useViewerActions, useViewerBearing, useViewerHfov, useViewerLngLat } from './chunk-25UGGXIE.js';
|
|
4
|
-
import {
|
|
6
|
+
import { distanceMeters, sequencesToFeatureCollection, emptyLineCollection, adapterById, viewConeGeoJson, viewShapeRadiusMeters, setStreetImageryConfig, viewfieldLayerId, photoLayerId, featureLayerId, PROVIDER_IDS, mapFeatureMatchesDateRange, isBrowserAvailableProvider, photoMatchesFilters, resolvePhotoPanoramaUrl, photoFullUrlQueryKey, resolvePhotoThumbnailUrl, photoThumbnailQueryKey, formatLocalDateTime, formatMonth, formatRelativeDate, formatDateTooltip, mapillaryPhotoSource, buildViewSuggestions, yearsToMs, SIGN_TARGET, fetchMapFeatureImages, fetchMapillaryMapFeaturesInBbox, bboxAround, fetchImageDetections, findLocationOpener, mapillaryIconUrl, openLocationInNewTab, alignLineToPoints, coneRadiusMeters, mapFeaturesToFeatureCollection, emptyPointCollection, buildMapFeatureLayerFilter, featureSourceId, photosToFeatureCollection, photosToViewfieldsFeatureCollection, emptyPolygonCollection, buildPhotoLayerFilter, photoSourceId, viewfieldSourceId, sequenceSourceId, sequenceLayerId, viewfieldLineLayerId, VIEWFIELD_MIN_ZOOM } from '@osm-editor-kit/street-imagery';
|
|
5
7
|
import { Source, Layer, useMap } from 'react-map-gl/maplibre';
|
|
6
8
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
7
9
|
import { lazy, useEffect, Fragment as Fragment$1, Suspense, useState, useRef, useEffectEvent } from 'react';
|
|
8
10
|
import { useQuery, useQueries } from '@tanstack/react-query';
|
|
9
11
|
import { create } from 'zustand';
|
|
10
12
|
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
+
var POINTS_SOURCE_ID = "selection-highlight";
|
|
14
|
+
var CONNECTOR_SOURCE_ID = "selection-connector";
|
|
13
15
|
var SEQUENCE_HIGHLIGHT_SOURCE_ID = "sequence-highlight";
|
|
14
|
-
var
|
|
16
|
+
var BASE_COLOR = "#171717";
|
|
17
|
+
var SELECTION_COLOR = "#f97316";
|
|
18
|
+
var SAME_POSITION_METERS = 0.75;
|
|
19
|
+
var ACTIVE_LINE_WIDTH = 2.5;
|
|
15
20
|
var StreetLevelImagerySelectionOverlay = ({
|
|
16
21
|
selectedPhoto,
|
|
17
|
-
selectedSequence
|
|
22
|
+
selectedSequence,
|
|
23
|
+
cameraLngLat,
|
|
24
|
+
sequenceBeforeId
|
|
18
25
|
}) => {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
26
|
+
const photoLngLat = selectedPhoto?.lngLat;
|
|
27
|
+
const cameraDiffers = photoLngLat != null && cameraLngLat != null && distanceMeters(photoLngLat, cameraLngLat) > SAME_POSITION_METERS;
|
|
28
|
+
const camera = cameraDiffers ? cameraLngLat : null;
|
|
29
|
+
const dot = photoLngLat && cameraLngLat && !cameraDiffers ? cameraLngLat : photoLngLat;
|
|
30
|
+
const sequenceLines = selectedSequence ? sequencesToFeatureCollection([selectedSequence]) : emptyLineCollection();
|
|
31
|
+
const throughDot = (line) => dot ? alignLineToPoints(line, [dot]) : line;
|
|
32
|
+
const sequenceCollection = {
|
|
33
|
+
...sequenceLines,
|
|
34
|
+
features: sequenceLines.features.map((feature) => ({
|
|
35
|
+
...feature,
|
|
36
|
+
geometry: feature.geometry.type === "LineString" ? { ...feature.geometry, coordinates: throughDot(feature.geometry.coordinates) } : { ...feature.geometry, coordinates: feature.geometry.coordinates.map(throughDot) }
|
|
37
|
+
}))
|
|
38
|
+
};
|
|
39
|
+
if (!selectedPhoto && sequenceCollection.features.length === 0) {
|
|
22
40
|
return null;
|
|
23
41
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Layer,
|
|
42
|
+
const points = {
|
|
43
|
+
type: "FeatureCollection",
|
|
44
|
+
features: [
|
|
45
|
+
...dot ? [
|
|
29
46
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
paint: {
|
|
34
|
-
"circle-radius": 10,
|
|
35
|
-
"circle-color": "#ffffff",
|
|
36
|
-
"circle-stroke-width": 3,
|
|
37
|
-
"circle-stroke-color": "#0f172a"
|
|
38
|
-
}
|
|
47
|
+
type: "Feature",
|
|
48
|
+
properties: { kind: "dot" },
|
|
49
|
+
geometry: { type: "Point", coordinates: dot }
|
|
39
50
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
sequenceHighlightCollection.features.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
43
|
-
/* @__PURE__ */ jsx(
|
|
44
|
-
Source,
|
|
51
|
+
] : [],
|
|
52
|
+
...camera ? [
|
|
45
53
|
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
type: "Feature",
|
|
55
|
+
properties: { kind: "camera" },
|
|
56
|
+
geometry: { type: "Point", coordinates: camera }
|
|
49
57
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
] : []
|
|
59
|
+
]
|
|
60
|
+
};
|
|
61
|
+
const connector = {
|
|
62
|
+
type: "FeatureCollection",
|
|
63
|
+
features: dot && camera ? [
|
|
64
|
+
{
|
|
65
|
+
type: "Feature",
|
|
66
|
+
properties: {},
|
|
67
|
+
geometry: { type: "LineString", coordinates: [dot, camera] }
|
|
68
|
+
}
|
|
69
|
+
] : []
|
|
70
|
+
};
|
|
71
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
72
|
+
/* @__PURE__ */ jsx(Source, { id: SEQUENCE_HIGHLIGHT_SOURCE_ID, type: "geojson", data: sequenceCollection }),
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
Layer,
|
|
75
|
+
{
|
|
76
|
+
beforeId: sequenceBeforeId,
|
|
77
|
+
id: "sequence-highlight-layer",
|
|
78
|
+
type: "line",
|
|
79
|
+
source: SEQUENCE_HIGHLIGHT_SOURCE_ID,
|
|
80
|
+
layout: { "line-cap": "round", "line-join": "round" },
|
|
81
|
+
paint: { "line-color": BASE_COLOR, "line-width": ACTIVE_LINE_WIDTH }
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsx(Source, { id: CONNECTOR_SOURCE_ID, type: "geojson", data: connector }),
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
Layer,
|
|
87
|
+
{
|
|
88
|
+
id: "selection-connector-layer",
|
|
89
|
+
type: "line",
|
|
90
|
+
source: CONNECTOR_SOURCE_ID,
|
|
91
|
+
paint: { "line-color": SELECTION_COLOR, "line-width": 1.5, "line-dasharray": [2, 1.5] }
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx(Source, { id: POINTS_SOURCE_ID, type: "geojson", data: points }),
|
|
95
|
+
/* @__PURE__ */ jsx(
|
|
96
|
+
Layer,
|
|
97
|
+
{
|
|
98
|
+
id: "selection-highlight-layer",
|
|
99
|
+
type: "circle",
|
|
100
|
+
source: POINTS_SOURCE_ID,
|
|
101
|
+
filter: ["==", ["get", "kind"], "dot"],
|
|
102
|
+
paint: {
|
|
103
|
+
"circle-radius": 6,
|
|
104
|
+
"circle-color": SELECTION_COLOR,
|
|
105
|
+
"circle-stroke-width": 2,
|
|
106
|
+
"circle-stroke-color": BASE_COLOR
|
|
62
107
|
}
|
|
63
|
-
|
|
64
|
-
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsx(
|
|
111
|
+
Layer,
|
|
112
|
+
{
|
|
113
|
+
id: "selection-camera-layer",
|
|
114
|
+
type: "circle",
|
|
115
|
+
source: POINTS_SOURCE_ID,
|
|
116
|
+
filter: ["==", ["get", "kind"], "camera"],
|
|
117
|
+
paint: {
|
|
118
|
+
"circle-radius": 3.5,
|
|
119
|
+
"circle-color": SELECTION_COLOR,
|
|
120
|
+
"circle-stroke-width": 1.5,
|
|
121
|
+
"circle-stroke-color": BASE_COLOR
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
)
|
|
65
125
|
] });
|
|
66
126
|
};
|
|
67
127
|
var resolveSelectedSequence = (selectedPhoto, sequences, sequenceId) => {
|
|
@@ -116,7 +176,8 @@ var useProviderMapFeatures = (providerId, bbox, zoom) => {
|
|
|
116
176
|
};
|
|
117
177
|
var CONE_SOURCE_ID = "view-direction-cone";
|
|
118
178
|
var CONE_FILL_LAYER_ID = "view-direction-cone-fill";
|
|
119
|
-
var
|
|
179
|
+
var MIN_CONE_FOV_DEG = 45;
|
|
180
|
+
var VIEW_SHAPE_FILL_OPACITY = 0.25;
|
|
120
181
|
var INTERACTIVE_PANO_PROVIDERS = /* @__PURE__ */ new Set([
|
|
121
182
|
"mapillary",
|
|
122
183
|
"panoramax",
|
|
@@ -128,7 +189,9 @@ var INTERACTIVE_PANO_PROVIDERS = /* @__PURE__ */ new Set([
|
|
|
128
189
|
var StreetLevelImageryViewCone = ({
|
|
129
190
|
selectedPhoto,
|
|
130
191
|
zoom,
|
|
131
|
-
viewerPov
|
|
192
|
+
viewerPov,
|
|
193
|
+
color = SELECTION_COLOR,
|
|
194
|
+
scale = 2.5
|
|
132
195
|
}) => {
|
|
133
196
|
const apex = viewerPov?.lngLat ?? selectedPhoto.lngLat;
|
|
134
197
|
const isPano = selectedPhoto.isPano === true;
|
|
@@ -148,7 +211,11 @@ var StreetLevelImageryViewCone = ({
|
|
|
148
211
|
if (bearing == null) {
|
|
149
212
|
return null;
|
|
150
213
|
}
|
|
151
|
-
|
|
214
|
+
fov = Math.max(fov, MIN_CONE_FOV_DEG);
|
|
215
|
+
const coneFeature = {
|
|
216
|
+
...viewConeGeoJson(apex, bearing, fov, viewShapeRadiusMeters(zoom) * scale),
|
|
217
|
+
properties: { isPano: selectedPhoto.isPano, capturedAt: selectedPhoto.capturedAt }
|
|
218
|
+
};
|
|
152
219
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
153
220
|
/* @__PURE__ */ jsx(Source, { id: CONE_SOURCE_ID, type: "geojson", data: coneFeature }),
|
|
154
221
|
/* @__PURE__ */ jsx(
|
|
@@ -158,37 +225,14 @@ var StreetLevelImageryViewCone = ({
|
|
|
158
225
|
type: "fill",
|
|
159
226
|
source: CONE_SOURCE_ID,
|
|
160
227
|
paint: {
|
|
161
|
-
"fill-color":
|
|
162
|
-
"fill-opacity":
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
),
|
|
166
|
-
/* @__PURE__ */ jsx(
|
|
167
|
-
Layer,
|
|
168
|
-
{
|
|
169
|
-
id: CONE_LINE_LAYER_ID,
|
|
170
|
-
type: "line",
|
|
171
|
-
source: CONE_SOURCE_ID,
|
|
172
|
-
paint: {
|
|
173
|
-
"line-color": "#0f172a",
|
|
174
|
-
"line-width": 1.5,
|
|
175
|
-
"line-opacity": 0.5
|
|
228
|
+
"fill-color": color,
|
|
229
|
+
"fill-opacity": VIEW_SHAPE_FILL_OPACITY,
|
|
230
|
+
"fill-outline-color": "rgba(0, 0, 0, 0)"
|
|
176
231
|
}
|
|
177
232
|
}
|
|
178
233
|
)
|
|
179
234
|
] });
|
|
180
235
|
};
|
|
181
|
-
var CIRCLE_RADIUS = [
|
|
182
|
-
"interpolate",
|
|
183
|
-
["linear"],
|
|
184
|
-
["zoom"],
|
|
185
|
-
10,
|
|
186
|
-
2,
|
|
187
|
-
14,
|
|
188
|
-
4,
|
|
189
|
-
18,
|
|
190
|
-
6
|
|
191
|
-
];
|
|
192
236
|
var FEATURE_CIRCLE_RADIUS = [
|
|
193
237
|
"interpolate",
|
|
194
238
|
["linear"],
|
|
@@ -206,6 +250,24 @@ var padBbox = ([west, south, east, north], factor) => {
|
|
|
206
250
|
return [west - dx, south - dy, east + dx, north + dy];
|
|
207
251
|
};
|
|
208
252
|
var lngLatInBbox = ([lng, lat], [west, south, east, north]) => lng >= west && lng <= east && lat >= south && lat <= north;
|
|
253
|
+
var YEAR_MS = 365.25 * 24 * 60 * 60 * 1e3;
|
|
254
|
+
var LOADED_AT = Date.now();
|
|
255
|
+
var AGE_SHADE = [
|
|
256
|
+
"case",
|
|
257
|
+
["==", ["get", "capturedAt"], null],
|
|
258
|
+
BASE_COLOR,
|
|
259
|
+
[
|
|
260
|
+
"step",
|
|
261
|
+
["get", "capturedAt"],
|
|
262
|
+
"#909090",
|
|
263
|
+
LOADED_AT - 3 * YEAR_MS,
|
|
264
|
+
"#686868",
|
|
265
|
+
LOADED_AT - 2 * YEAR_MS,
|
|
266
|
+
"#404040",
|
|
267
|
+
LOADED_AT - YEAR_MS,
|
|
268
|
+
BASE_COLOR
|
|
269
|
+
]
|
|
270
|
+
];
|
|
209
271
|
var PHOTO_SORT_KEY = ["coalesce", ["get", "capturedAt"], 0];
|
|
210
272
|
var FEATURE_SORT_KEY = ["coalesce", ["get", "lastSeenAt"], 0];
|
|
211
273
|
var PhotoProviderLayer = ({
|
|
@@ -215,7 +277,10 @@ var PhotoProviderLayer = ({
|
|
|
215
277
|
filter,
|
|
216
278
|
showSequences,
|
|
217
279
|
showViewfields,
|
|
218
|
-
photoCircleColor
|
|
280
|
+
photoCircleColor,
|
|
281
|
+
activeSequenceId,
|
|
282
|
+
hasActiveSequence,
|
|
283
|
+
shownPhotoId
|
|
219
284
|
}) => {
|
|
220
285
|
const adapter = adapterById[providerId];
|
|
221
286
|
const { data: photos = [] } = useProviderPhotos(providerId, bbox, zoom);
|
|
@@ -227,6 +292,41 @@ var PhotoProviderLayer = ({
|
|
|
227
292
|
) : emptyPointCollection();
|
|
228
293
|
const viewfieldsActive = showViewfields && zoom >= VIEWFIELD_MIN_ZOOM;
|
|
229
294
|
const viewfieldCollection = viewfieldsActive ? photosToViewfieldsFeatureCollection(visiblePhotos, zoom, { bbox }) : emptyPolygonCollection();
|
|
295
|
+
const inActiveSequence = [
|
|
296
|
+
"==",
|
|
297
|
+
["get", "sequenceId"],
|
|
298
|
+
activeSequenceId ?? ""
|
|
299
|
+
];
|
|
300
|
+
const lineOpacity = [
|
|
301
|
+
"case",
|
|
302
|
+
inActiveSequence,
|
|
303
|
+
1,
|
|
304
|
+
hasActiveSequence ? 0.45 : 1
|
|
305
|
+
];
|
|
306
|
+
const dotRadius = [
|
|
307
|
+
"interpolate",
|
|
308
|
+
["linear"],
|
|
309
|
+
["zoom"],
|
|
310
|
+
10,
|
|
311
|
+
["case", inActiveSequence, 2, 1.2],
|
|
312
|
+
14,
|
|
313
|
+
["case", inActiveSequence, 4, 2],
|
|
314
|
+
// Up to here there are no view shapes and the dots are 20 % smaller.
|
|
315
|
+
VIEWFIELD_MIN_ZOOM - 0.01,
|
|
316
|
+
["case", inActiveSequence, 5.5, 2.9],
|
|
317
|
+
VIEWFIELD_MIN_ZOOM,
|
|
318
|
+
["case", inActiveSequence, 5.5, 3.6],
|
|
319
|
+
18,
|
|
320
|
+
["case", inActiveSequence, 6, 4]
|
|
321
|
+
];
|
|
322
|
+
const lineAndDotColor = viewfieldsActive ? ["case", inActiveSequence, BASE_COLOR, AGE_SHADE] : photoCircleColor;
|
|
323
|
+
const viewShapeOpacity = (full) => [
|
|
324
|
+
"case",
|
|
325
|
+
inActiveSequence,
|
|
326
|
+
full,
|
|
327
|
+
hasActiveSequence ? full * 0.4 : full
|
|
328
|
+
];
|
|
329
|
+
const notShownPhoto = ["!=", ["get", "photoId"], shownPhotoId ?? ""];
|
|
230
330
|
const photoFilter = buildPhotoLayerFilter(filter?.photoTypes, filter?.date);
|
|
231
331
|
const photoSrcId = photoSourceId(providerId);
|
|
232
332
|
const viewfieldSrcId = viewfieldSourceId(providerId);
|
|
@@ -254,7 +354,34 @@ var PhotoProviderLayer = ({
|
|
|
254
354
|
};
|
|
255
355
|
return photoMatchesFilters(asPhoto, filter?.photoTypes, filter?.date);
|
|
256
356
|
}) : [];
|
|
257
|
-
const
|
|
357
|
+
const photoLngLatsBySequence = /* @__PURE__ */ new Map();
|
|
358
|
+
for (const photo of photos) {
|
|
359
|
+
if (photo.sequenceId == null) continue;
|
|
360
|
+
const list = photoLngLatsBySequence.get(photo.sequenceId);
|
|
361
|
+
if (list) {
|
|
362
|
+
list.push(photo.lngLat);
|
|
363
|
+
} else {
|
|
364
|
+
photoLngLatsBySequence.set(photo.sequenceId, [photo.lngLat]);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const alignedSequences = filteredSequences.map((sequence) => {
|
|
368
|
+
const points = photoLngLatsBySequence.get(sequence.sequenceId);
|
|
369
|
+
if (!points) return sequence;
|
|
370
|
+
const { geometry } = sequence;
|
|
371
|
+
return {
|
|
372
|
+
...sequence,
|
|
373
|
+
geometry: geometry.type === "LineString" ? {
|
|
374
|
+
...geometry,
|
|
375
|
+
coordinates: alignLineToPoints(geometry.coordinates, points)
|
|
376
|
+
} : {
|
|
377
|
+
...geometry,
|
|
378
|
+
coordinates: geometry.coordinates.map(
|
|
379
|
+
(line) => alignLineToPoints(line, points)
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
const sequenceCollection = alignedSequences.length > 0 ? sequencesToFeatureCollection(alignedSequences) : emptyLineCollection();
|
|
258
385
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
259
386
|
adapter.fetchSequences && showSequences ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
260
387
|
/* @__PURE__ */ jsx(
|
|
@@ -272,10 +399,15 @@ var PhotoProviderLayer = ({
|
|
|
272
399
|
id: sequenceLayerId(providerId),
|
|
273
400
|
type: "line",
|
|
274
401
|
source: sequenceSourceId(providerId),
|
|
402
|
+
layout: {
|
|
403
|
+
"line-cap": "round",
|
|
404
|
+
"line-join": "round",
|
|
405
|
+
"line-sort-key": ["case", inActiveSequence, 1, 0]
|
|
406
|
+
},
|
|
275
407
|
paint: {
|
|
276
|
-
"line-color":
|
|
277
|
-
"line-width":
|
|
278
|
-
"line-opacity":
|
|
408
|
+
"line-color": lineAndDotColor,
|
|
409
|
+
"line-width": ["case", inActiveSequence, ACTIVE_LINE_WIDTH, 1.25],
|
|
410
|
+
"line-opacity": lineOpacity
|
|
279
411
|
}
|
|
280
412
|
}
|
|
281
413
|
)
|
|
@@ -296,9 +428,11 @@ var PhotoProviderLayer = ({
|
|
|
296
428
|
id: viewfieldLayerId(providerId),
|
|
297
429
|
type: "fill",
|
|
298
430
|
source: viewfieldSrcId,
|
|
431
|
+
filter: notShownPhoto,
|
|
299
432
|
paint: {
|
|
300
433
|
"fill-color": photoCircleColor,
|
|
301
|
-
"fill-opacity":
|
|
434
|
+
"fill-opacity": viewShapeOpacity(VIEW_SHAPE_FILL_OPACITY),
|
|
435
|
+
"fill-outline-color": "rgba(0, 0, 0, 0)"
|
|
302
436
|
}
|
|
303
437
|
}
|
|
304
438
|
),
|
|
@@ -308,10 +442,11 @@ var PhotoProviderLayer = ({
|
|
|
308
442
|
id: viewfieldLineLayerId(providerId),
|
|
309
443
|
type: "line",
|
|
310
444
|
source: viewfieldSrcId,
|
|
445
|
+
filter: notShownPhoto,
|
|
311
446
|
paint: {
|
|
312
447
|
"line-color": photoCircleColor,
|
|
313
|
-
"line-width":
|
|
314
|
-
"line-opacity": 0.
|
|
448
|
+
"line-width": 0.5,
|
|
449
|
+
"line-opacity": viewShapeOpacity(0.3)
|
|
315
450
|
}
|
|
316
451
|
}
|
|
317
452
|
)
|
|
@@ -335,10 +470,8 @@ var PhotoProviderLayer = ({
|
|
|
335
470
|
filter: photoFilter,
|
|
336
471
|
layout: { "circle-sort-key": PHOTO_SORT_KEY },
|
|
337
472
|
paint: {
|
|
338
|
-
"circle-radius":
|
|
339
|
-
"circle-color":
|
|
340
|
-
"circle-stroke-width": 1,
|
|
341
|
-
"circle-stroke-color": "#ffffff"
|
|
473
|
+
"circle-radius": dotRadius,
|
|
474
|
+
"circle-color": lineAndDotColor
|
|
342
475
|
}
|
|
343
476
|
}
|
|
344
477
|
)
|
|
@@ -380,9 +513,7 @@ var MapFeatureProviderLayer = ({
|
|
|
380
513
|
layout: { "circle-sort-key": FEATURE_SORT_KEY },
|
|
381
514
|
paint: {
|
|
382
515
|
"circle-radius": FEATURE_CIRCLE_RADIUS,
|
|
383
|
-
"circle-color": mapFeatureCircleColor
|
|
384
|
-
"circle-stroke-width": 1,
|
|
385
|
-
"circle-stroke-color": "#ffffff"
|
|
516
|
+
"circle-color": mapFeatureCircleColor
|
|
386
517
|
}
|
|
387
518
|
}
|
|
388
519
|
)
|
|
@@ -408,6 +539,8 @@ var StreetLevelImagerySourcesAndLayers = ({
|
|
|
408
539
|
selectedPhoto,
|
|
409
540
|
selectedSequenceId,
|
|
410
541
|
viewerPov,
|
|
542
|
+
viewConeColor,
|
|
543
|
+
viewConeScale,
|
|
411
544
|
photoCircleColor,
|
|
412
545
|
mapFeatureCircleColor
|
|
413
546
|
} = options;
|
|
@@ -425,11 +558,13 @@ var StreetLevelImagerySourcesAndLayers = ({
|
|
|
425
558
|
showSelectionHighlight && selectedProviderId ? bbox : null,
|
|
426
559
|
zoom
|
|
427
560
|
);
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
561
|
+
const activeSequenceId = selectedSequenceId ?? selectedPhoto?.sequenceId;
|
|
562
|
+
const selectedSequence = resolveSelectedSequence(selectedPhoto, sequences, activeSequenceId);
|
|
563
|
+
const providerDrawsSequences = selectedProviderId != null && showSequences && providers.includes(selectedProviderId);
|
|
564
|
+
const firstPhotoProvider = providers.find(
|
|
565
|
+
(id) => adapterById[id].kind === "photo" && adapterById[id].fetchPhotos
|
|
432
566
|
);
|
|
567
|
+
const sequenceBeforeId = firstPhotoProvider ? showViewfields ? viewfieldLayerId(firstPhotoProvider) : photoLayerId(firstPhotoProvider) : void 0;
|
|
433
568
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
434
569
|
providers.map((providerId) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
|
|
435
570
|
ProviderLayer,
|
|
@@ -437,6 +572,9 @@ var StreetLevelImagerySourcesAndLayers = ({
|
|
|
437
572
|
bbox,
|
|
438
573
|
filter,
|
|
439
574
|
mapFeatureCircleColor,
|
|
575
|
+
activeSequenceId: providerId === selectedProviderId ? activeSequenceId : null,
|
|
576
|
+
hasActiveSequence: activeSequenceId != null,
|
|
577
|
+
shownPhotoId: showViewCone && providerId === selectedProviderId ? selectedPhoto?.photoId : null,
|
|
440
578
|
photoCircleColor,
|
|
441
579
|
providerId,
|
|
442
580
|
showSequences,
|
|
@@ -447,6 +585,8 @@ var StreetLevelImagerySourcesAndLayers = ({
|
|
|
447
585
|
showViewCone && selectedPhoto ? /* @__PURE__ */ jsx(
|
|
448
586
|
StreetLevelImageryViewCone,
|
|
449
587
|
{
|
|
588
|
+
color: viewConeColor ?? SELECTION_COLOR,
|
|
589
|
+
scale: viewConeScale,
|
|
450
590
|
selectedPhoto,
|
|
451
591
|
viewerPov,
|
|
452
592
|
zoom
|
|
@@ -455,23 +595,28 @@ var StreetLevelImagerySourcesAndLayers = ({
|
|
|
455
595
|
showSelectionHighlight ? /* @__PURE__ */ jsx(
|
|
456
596
|
StreetLevelImagerySelectionOverlay,
|
|
457
597
|
{
|
|
598
|
+
cameraLngLat: viewerPov?.lngLat,
|
|
458
599
|
selectedPhoto,
|
|
459
|
-
selectedSequence
|
|
600
|
+
selectedSequence: providerDrawsSequences ? null : selectedSequence,
|
|
601
|
+
sequenceBeforeId
|
|
460
602
|
}
|
|
461
603
|
) : null
|
|
462
604
|
] });
|
|
463
605
|
};
|
|
464
606
|
var MapillaryPanel2 = lazy(
|
|
465
|
-
() => import('./MapillaryPanel-
|
|
607
|
+
() => import('./MapillaryPanel-N45NQY4C.js').then((module) => ({
|
|
466
608
|
default: module.MapillaryPanel
|
|
467
609
|
}))
|
|
468
610
|
);
|
|
469
611
|
var PanoramaxPanel2 = lazy(
|
|
470
|
-
() => import('./PanoramaxPanel-
|
|
612
|
+
() => import('./PanoramaxPanel-MFI4L67Z.js').then((module) => ({
|
|
471
613
|
default: module.PanoramaxPanel
|
|
472
614
|
}))
|
|
473
615
|
);
|
|
474
|
-
var ViewerPanelPlaceholder = () =>
|
|
616
|
+
var ViewerPanelPlaceholder = () => {
|
|
617
|
+
const { messages } = useStreetImageryI18n();
|
|
618
|
+
return /* @__PURE__ */ jsx("div", { className: "flex min-h-48 animate-pulse items-center justify-center rounded-lg border border-slate-200 bg-slate-100", children: /* @__PURE__ */ jsx("span", { className: "text-sm text-slate-500", children: messages.viewer.loading }) });
|
|
619
|
+
};
|
|
475
620
|
var StreetLevelImageryViewer = ({
|
|
476
621
|
photo,
|
|
477
622
|
groupPhotos,
|
|
@@ -480,13 +625,15 @@ var StreetLevelImageryViewer = ({
|
|
|
480
625
|
onViewerPhoto,
|
|
481
626
|
lookAtBearing,
|
|
482
627
|
lookAt,
|
|
483
|
-
outlines
|
|
628
|
+
outlines,
|
|
629
|
+
hideAttribution
|
|
484
630
|
}) => {
|
|
485
631
|
if (photo.providerId === "mapillary") {
|
|
486
632
|
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ViewerPanelPlaceholder, {}), children: /* @__PURE__ */ jsx(
|
|
487
633
|
MapillaryPanel2,
|
|
488
634
|
{
|
|
489
635
|
groupPhotos,
|
|
636
|
+
hideAttribution,
|
|
490
637
|
onEaseMapToPoint,
|
|
491
638
|
onPhotoSelected,
|
|
492
639
|
lookAt,
|
|
@@ -502,6 +649,8 @@ var StreetLevelImageryViewer = ({
|
|
|
502
649
|
PanoramaxPanel2,
|
|
503
650
|
{
|
|
504
651
|
groupPhotos,
|
|
652
|
+
hideLegend: hideAttribution,
|
|
653
|
+
onViewerPhoto,
|
|
505
654
|
onEaseMapToPoint,
|
|
506
655
|
onPhotoSelected,
|
|
507
656
|
photo
|
|
@@ -589,18 +738,6 @@ var useAllProviderMapFeatures = (providerIds, bbox, zoom, date) => {
|
|
|
589
738
|
return data.filter((feature) => mapFeatureMatchesDateRange(feature, date));
|
|
590
739
|
});
|
|
591
740
|
};
|
|
592
|
-
var useAllProviderMapFeaturesLoading = (providerIds, bbox, zoom) => {
|
|
593
|
-
const enabled = new Set(providerIds);
|
|
594
|
-
const queries = PROVIDER_IDS.map((providerId) => ({
|
|
595
|
-
providerId,
|
|
596
|
-
query: useProviderMapFeaturesMaybe(providerId, enabled.has(providerId), bbox, zoom)
|
|
597
|
-
}));
|
|
598
|
-
const activeQueries = queries.filter(({ providerId }) => enabled.has(providerId));
|
|
599
|
-
return {
|
|
600
|
-
isLoading: activeQueries.some(({ query }) => query.isLoading),
|
|
601
|
-
isFetching: activeQueries.some(({ query }) => query.isFetching)
|
|
602
|
-
};
|
|
603
|
-
};
|
|
604
741
|
var useProviderPhotosMaybe = (providerId, enabled, bbox, zoom) => useProviderPhotos(providerId, enabled ? bbox : null, zoom);
|
|
605
742
|
var useAllProviderPhotos = (providerIds, bbox, zoom, photoTypes, date) => {
|
|
606
743
|
const enabled = new Set(providerIds);
|
|
@@ -677,32 +814,26 @@ var usePhotoThumbnail = (photo) => useQuery({
|
|
|
677
814
|
enabled: photo != null,
|
|
678
815
|
staleTime: 24 * 60 * 60 * 1e3
|
|
679
816
|
});
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
"line-start": "Start",
|
|
685
|
-
"line-end": "End",
|
|
686
|
-
"into-node": "Junction",
|
|
687
|
-
custom: "View"
|
|
688
|
-
};
|
|
689
|
-
var viewpointRoleLabel = (role) => ROLE_LABELS[role];
|
|
690
|
-
var viewSuggestionLabel = ({ viewpoint, direction }) => {
|
|
691
|
-
const role = viewpoint.label ?? viewpointRoleLabel(viewpoint.role);
|
|
692
|
-
switch (direction.kind) {
|
|
693
|
-
case "forward":
|
|
694
|
-
return `${role}, looking along the street`;
|
|
695
|
-
case "back":
|
|
696
|
-
return `${role}, looking back along the street`;
|
|
697
|
-
case "into":
|
|
698
|
-
return `${role}, looking into the junction`;
|
|
699
|
-
case "N":
|
|
700
|
-
case "E":
|
|
701
|
-
case "S":
|
|
702
|
-
case "W":
|
|
703
|
-
return `${role}, looking ${direction.kind}`;
|
|
817
|
+
var PhotoDate = ({ timestamp, className, localDateTime }) => {
|
|
818
|
+
const { locale, messages } = useStreetImageryI18n();
|
|
819
|
+
if (timestamp == null) {
|
|
820
|
+
return /* @__PURE__ */ jsx("span", { className, children: messages.unknownDate });
|
|
704
821
|
}
|
|
822
|
+
const precise = localDateTime ? formatLocalDateTime(localDateTime, locale) : null;
|
|
823
|
+
return /* @__PURE__ */ jsx(
|
|
824
|
+
"time",
|
|
825
|
+
{
|
|
826
|
+
className,
|
|
827
|
+
dateTime: new Date(timestamp).toISOString(),
|
|
828
|
+
title: precise ? `${precise}
|
|
829
|
+
${formatRelativeDate(timestamp, locale)}` : formatDateTooltip(timestamp, locale),
|
|
830
|
+
children: formatMonth(timestamp, locale)
|
|
831
|
+
}
|
|
832
|
+
);
|
|
705
833
|
};
|
|
834
|
+
|
|
835
|
+
// src/viewpoints/viewDirectionLabels.ts
|
|
836
|
+
var viewSuggestionLabel = ({ viewpoint, direction }, messages) => messages.viewDirection(viewpoint.label ?? messages.viewpointRole[viewpoint.role], direction.kind);
|
|
706
837
|
var DEFAULT_LAYOUT = { right: 16, bottom: 32, width: 420, minimized: false };
|
|
707
838
|
var MIN_WIDTH = 280;
|
|
708
839
|
var EDGE = 8;
|
|
@@ -736,11 +867,14 @@ var Icon = ({ path, className = "size-4" }) => /* @__PURE__ */ jsx(
|
|
|
736
867
|
);
|
|
737
868
|
var ICONS = {
|
|
738
869
|
back: "M15 18l-6-6 6-6",
|
|
870
|
+
undo: "M9 14 4 9l5-5M4 9h10.5a5.5 5.5 0 0 1 0 11H11",
|
|
871
|
+
redo: "m15 14 5-5-5-5M20 9H9.5a5.5 5.5 0 0 0 0 11H13",
|
|
739
872
|
forward: "M9 18l6-6-6-6",
|
|
740
873
|
close: "M18 6 6 18M6 6l12 12",
|
|
741
874
|
minimize: "M5 12h14",
|
|
742
875
|
expand: "M4 14v6h6M20 10V4h-6M14 10l6-6M10 14l-6 6",
|
|
743
|
-
arrow: "M12 20V5M6 11l6-6 6 6"
|
|
876
|
+
arrow: "M12 20V5M6 11l6-6 6 6",
|
|
877
|
+
info: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM12 11v5M12 8h.01"
|
|
744
878
|
};
|
|
745
879
|
var ToolbarButton = ({
|
|
746
880
|
label,
|
|
@@ -759,18 +893,18 @@ var ToolbarButton = ({
|
|
|
759
893
|
children
|
|
760
894
|
}
|
|
761
895
|
);
|
|
762
|
-
var formatShortDate = (capturedAt) => capturedAt == null ? "\u2014" : new Intl.DateTimeFormat("en", { year: "2-digit", month: "short" }).format(capturedAt);
|
|
763
896
|
var SuggestionChip = ({
|
|
764
897
|
suggestion,
|
|
765
898
|
active,
|
|
766
899
|
onSelect
|
|
767
900
|
}) => {
|
|
901
|
+
const { messages } = useStreetImageryI18n();
|
|
768
902
|
const best = suggestion.candidates[0];
|
|
769
|
-
const label = viewSuggestionLabel(suggestion);
|
|
903
|
+
const label = viewSuggestionLabel(suggestion, messages);
|
|
770
904
|
return /* @__PURE__ */ jsxs(
|
|
771
905
|
"button",
|
|
772
906
|
{
|
|
773
|
-
"aria-label": best ? label :
|
|
907
|
+
"aria-label": best ? label : messages.viewer.noPhoto(label),
|
|
774
908
|
"aria-pressed": active,
|
|
775
909
|
className: [
|
|
776
910
|
"inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-0.5 text-xs whitespace-nowrap",
|
|
@@ -778,10 +912,10 @@ var SuggestionChip = ({
|
|
|
778
912
|
].join(" "),
|
|
779
913
|
disabled: !best,
|
|
780
914
|
onClick: onSelect,
|
|
781
|
-
title: best ? label :
|
|
915
|
+
title: best ? label : messages.viewer.noMatchingPhoto(label),
|
|
782
916
|
type: "button",
|
|
783
917
|
children: [
|
|
784
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children:
|
|
918
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: suggestion.viewpoint.label ?? messages.viewpointRole[suggestion.viewpoint.role] }),
|
|
785
919
|
/* @__PURE__ */ jsx(
|
|
786
920
|
"span",
|
|
787
921
|
{
|
|
@@ -791,13 +925,24 @@ var SuggestionChip = ({
|
|
|
791
925
|
children: /* @__PURE__ */ jsx(Icon, { className: "size-3", path: ICONS.arrow })
|
|
792
926
|
}
|
|
793
927
|
),
|
|
794
|
-
/* @__PURE__ */ jsx(
|
|
928
|
+
best ? /* @__PURE__ */ jsx(
|
|
929
|
+
PhotoDate,
|
|
930
|
+
{
|
|
931
|
+
className: active ? "text-fuchsia-100" : "text-slate-400",
|
|
932
|
+
timestamp: best.photo.capturedAt
|
|
933
|
+
}
|
|
934
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-slate-400", children: "\u2014" })
|
|
795
935
|
]
|
|
796
936
|
}
|
|
797
937
|
);
|
|
798
938
|
};
|
|
939
|
+
var FloatingViewerInfoButton = ({
|
|
940
|
+
label,
|
|
941
|
+
onClick
|
|
942
|
+
}) => /* @__PURE__ */ jsx(ToolbarButton, { label, onClick, children: /* @__PURE__ */ jsx(Icon, { path: ICONS.info }) });
|
|
799
943
|
var FloatingPhotoViewer = ({
|
|
800
944
|
title,
|
|
945
|
+
titleActions,
|
|
801
946
|
suggestions,
|
|
802
947
|
activeDirectionKey,
|
|
803
948
|
onSelectSuggestion,
|
|
@@ -806,17 +951,18 @@ var FloatingPhotoViewer = ({
|
|
|
806
951
|
onBack,
|
|
807
952
|
onForward,
|
|
808
953
|
onClose,
|
|
954
|
+
step,
|
|
955
|
+
toolbar,
|
|
809
956
|
status,
|
|
810
957
|
children,
|
|
811
958
|
footer,
|
|
812
959
|
drawer,
|
|
813
960
|
storageKey = "street-imagery:floating-viewer"
|
|
814
961
|
}) => {
|
|
962
|
+
const { messages } = useStreetImageryI18n();
|
|
815
963
|
const [layout, setLayout] = useState(() => readLayout(storageKey));
|
|
816
964
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
817
|
-
const dragRef = useRef(
|
|
818
|
-
null
|
|
819
|
-
);
|
|
965
|
+
const dragRef = useRef(null);
|
|
820
966
|
const updateLayout = (next) => {
|
|
821
967
|
setLayout(next);
|
|
822
968
|
writeLayout(storageKey, next);
|
|
@@ -832,6 +978,10 @@ var FloatingPhotoViewer = ({
|
|
|
832
978
|
onBack();
|
|
833
979
|
} else if (event.key === "]" && canGoForward) {
|
|
834
980
|
onForward();
|
|
981
|
+
} else if (event.key === "ArrowLeft" && event.altKey) {
|
|
982
|
+
step?.onPrevious?.();
|
|
983
|
+
} else if (event.key === "ArrowRight" && event.altKey) {
|
|
984
|
+
step?.onNext?.();
|
|
835
985
|
}
|
|
836
986
|
});
|
|
837
987
|
useEffect(function subscribeKeyboardShortcuts() {
|
|
@@ -885,7 +1035,7 @@ var FloatingPhotoViewer = ({
|
|
|
885
1035
|
return /* @__PURE__ */ jsxs(
|
|
886
1036
|
"section",
|
|
887
1037
|
{
|
|
888
|
-
"aria-label":
|
|
1038
|
+
"aria-label": messages.viewer.regionLabel,
|
|
889
1039
|
className: "absolute z-10 flex max-h-[calc(100%-1rem)] flex-col overflow-hidden rounded-xl bg-white shadow-xl ring-1 ring-slate-200",
|
|
890
1040
|
style: {
|
|
891
1041
|
right: layout.right,
|
|
@@ -909,43 +1059,70 @@ var FloatingPhotoViewer = ({
|
|
|
909
1059
|
onPointerDown: (event) => startDrag(event, "move"),
|
|
910
1060
|
...dragHandlers,
|
|
911
1061
|
children: [
|
|
912
|
-
|
|
1062
|
+
step ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1063
|
+
/* @__PURE__ */ jsx(
|
|
1064
|
+
ToolbarButton,
|
|
1065
|
+
{
|
|
1066
|
+
disabled: !step.onPrevious,
|
|
1067
|
+
label: step.previousLabel,
|
|
1068
|
+
onClick: () => step.onPrevious?.(),
|
|
1069
|
+
children: /* @__PURE__ */ jsx(Icon, { path: ICONS.back })
|
|
1070
|
+
}
|
|
1071
|
+
),
|
|
1072
|
+
/* @__PURE__ */ jsx(
|
|
1073
|
+
ToolbarButton,
|
|
1074
|
+
{
|
|
1075
|
+
disabled: !step.onNext,
|
|
1076
|
+
label: step.nextLabel,
|
|
1077
|
+
onClick: () => step.onNext?.(),
|
|
1078
|
+
children: /* @__PURE__ */ jsx(Icon, { path: ICONS.forward })
|
|
1079
|
+
}
|
|
1080
|
+
)
|
|
1081
|
+
] }) : null,
|
|
1082
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-0.5", children: [
|
|
1083
|
+
/* @__PURE__ */ jsx("h2", { className: "min-w-0 truncate px-1 text-sm font-semibold text-slate-800", children: title }),
|
|
1084
|
+
titleActions
|
|
1085
|
+
] }),
|
|
1086
|
+
/* @__PURE__ */ jsx(ToolbarButton, { disabled: !canGoBack, label: messages.viewer.backInHistory, onClick: onBack, children: /* @__PURE__ */ jsx(Icon, { path: ICONS.undo }) }),
|
|
913
1087
|
/* @__PURE__ */ jsx(
|
|
914
1088
|
ToolbarButton,
|
|
915
1089
|
{
|
|
916
1090
|
disabled: !canGoForward,
|
|
917
|
-
label:
|
|
1091
|
+
label: messages.viewer.forwardInHistory,
|
|
918
1092
|
onClick: onForward,
|
|
919
|
-
children: /* @__PURE__ */ jsx(Icon, { path: ICONS.
|
|
1093
|
+
children: /* @__PURE__ */ jsx(Icon, { path: ICONS.redo })
|
|
920
1094
|
}
|
|
921
1095
|
),
|
|
922
|
-
/* @__PURE__ */ jsx("h2", { className: "min-w-0 flex-1 truncate px-1 text-sm font-semibold text-slate-800", children: title }),
|
|
923
1096
|
/* @__PURE__ */ jsx(
|
|
924
1097
|
ToolbarButton,
|
|
925
1098
|
{
|
|
926
|
-
label:
|
|
1099
|
+
label: messages.viewer.minimize,
|
|
927
1100
|
onClick: () => updateLayout({ ...layout, minimized: true }),
|
|
928
1101
|
children: /* @__PURE__ */ jsx(Icon, { path: ICONS.minimize })
|
|
929
1102
|
}
|
|
930
1103
|
),
|
|
931
|
-
/* @__PURE__ */ jsx(ToolbarButton, { label:
|
|
1104
|
+
/* @__PURE__ */ jsx(ToolbarButton, { label: messages.viewer.close, onClick: onClose, children: /* @__PURE__ */ jsx(Icon, { path: ICONS.close }) })
|
|
932
1105
|
]
|
|
933
1106
|
}
|
|
934
1107
|
),
|
|
935
|
-
suggestions.length > 0 ? /* @__PURE__ */
|
|
1108
|
+
toolbar ? /* @__PURE__ */ jsx("div", { className: "border-b border-slate-100 px-2 py-1.5", children: toolbar }) : suggestions.length > 0 ? /* @__PURE__ */ jsxs(
|
|
936
1109
|
"nav",
|
|
937
1110
|
{
|
|
938
|
-
"aria-label":
|
|
1111
|
+
"aria-label": messages.viewer.suggestedViews,
|
|
939
1112
|
className: "flex gap-1 overflow-x-auto border-b border-slate-100 px-2 py-1.5",
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
{
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1113
|
+
title: messages.viewer.suggestedViewsHint,
|
|
1114
|
+
children: [
|
|
1115
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 self-center pr-0.5 text-xs text-slate-500", children: messages.viewer.views }),
|
|
1116
|
+
suggestions.map((suggestion) => /* @__PURE__ */ jsx(
|
|
1117
|
+
SuggestionChip,
|
|
1118
|
+
{
|
|
1119
|
+
active: suggestion.direction.key === activeDirectionKey,
|
|
1120
|
+
onSelect: () => onSelectSuggestion(suggestion),
|
|
1121
|
+
suggestion
|
|
1122
|
+
},
|
|
1123
|
+
suggestion.direction.key
|
|
1124
|
+
))
|
|
1125
|
+
]
|
|
949
1126
|
}
|
|
950
1127
|
) : null,
|
|
951
1128
|
/* @__PURE__ */ jsxs("div", { className: "min-h-0 overflow-y-auto", children: [
|
|
@@ -1121,17 +1298,22 @@ var useViewpointSessionStore = create()((set, get) => ({
|
|
|
1121
1298
|
set({ historyIndex: historyIndex + 1, activeDirectionKey: entry.directionKey });
|
|
1122
1299
|
return entry;
|
|
1123
1300
|
},
|
|
1124
|
-
close: () => set({ viewpoints: [], line: null, activeDirectionKey: null })
|
|
1301
|
+
close: () => set({ viewpoints: [], line: null, activeDirectionKey: null }),
|
|
1302
|
+
reset: () => set({
|
|
1303
|
+
viewpoints: [],
|
|
1304
|
+
line: null,
|
|
1305
|
+
activeDirectionKey: null,
|
|
1306
|
+
history: [],
|
|
1307
|
+
historyIndex: -1
|
|
1308
|
+
})
|
|
1125
1309
|
}
|
|
1126
1310
|
}));
|
|
1127
|
-
var useViewpointSessionId = () => useViewpointSessionStore((state) => state.sessionId);
|
|
1128
1311
|
var useViewpoints = () => useViewpointSessionStore((state) => state.viewpoints);
|
|
1129
1312
|
var useViewpointLine = () => useViewpointSessionStore((state) => state.line);
|
|
1130
1313
|
var useActiveDirectionKey = () => useViewpointSessionStore((state) => state.activeDirectionKey);
|
|
1131
1314
|
var useCurrentHistoryEntry = () => useViewpointSessionStore((state) => state.history[state.historyIndex] ?? null);
|
|
1132
1315
|
var useCanGoBack = () => useViewpointSessionStore((state) => state.historyIndex > 0);
|
|
1133
1316
|
var useCanGoForward = () => useViewpointSessionStore((state) => state.historyIndex < state.history.length - 1);
|
|
1134
|
-
var useViewpointSessionActions = () => useViewpointSessionStore((state) => state.actions);
|
|
1135
1317
|
var getViewpointSession = () => {
|
|
1136
1318
|
const { actions, history, historyIndex } = useViewpointSessionStore.getState();
|
|
1137
1319
|
return { actions, current: history[historyIndex] ?? null };
|
|
@@ -1219,5 +1401,126 @@ var useMapillaryImageDetections = (imageId, { filter, filterKey } = {}) => useQu
|
|
|
1219
1401
|
enabled: !!imageId,
|
|
1220
1402
|
staleTime: STALE_TIME
|
|
1221
1403
|
});
|
|
1404
|
+
var useLocationPickStore = create()((set) => ({
|
|
1405
|
+
armedOpenerId: null,
|
|
1406
|
+
actions: {
|
|
1407
|
+
arm: (openerId) => set({ armedOpenerId: openerId }),
|
|
1408
|
+
disarm: () => set((state) => state.armedOpenerId == null ? state : { armedOpenerId: null }),
|
|
1409
|
+
toggle: (openerId) => set((state) => ({ armedOpenerId: state.armedOpenerId === openerId ? null : openerId }))
|
|
1410
|
+
}
|
|
1411
|
+
}));
|
|
1412
|
+
var useArmedLocationOpenerId = () => useLocationPickStore((state) => state.armedOpenerId);
|
|
1413
|
+
var useLocationPickActions = () => useLocationPickStore((state) => state.actions);
|
|
1414
|
+
|
|
1415
|
+
// src/openers/LocationPickOnMap.tsx
|
|
1416
|
+
var roundCoordinate = (value) => Number(value.toFixed(7));
|
|
1417
|
+
var LocationPickOnMap = ({ onPick }) => {
|
|
1418
|
+
const { current: map } = useMap();
|
|
1419
|
+
const armedOpenerId = useArmedLocationOpenerId();
|
|
1420
|
+
const { disarm } = useLocationPickActions();
|
|
1421
|
+
useEffect(
|
|
1422
|
+
function openArmedOpenerOnNextMapClick() {
|
|
1423
|
+
if (!map || !armedOpenerId) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1426
|
+
const opener = findLocationOpener(armedOpenerId);
|
|
1427
|
+
if (!opener) {
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1430
|
+
const onClick = (event) => {
|
|
1431
|
+
const target = {
|
|
1432
|
+
lngLat: [roundCoordinate(event.lngLat.lng), roundCoordinate(event.lngLat.lat)],
|
|
1433
|
+
zoom: map.getZoom()
|
|
1434
|
+
};
|
|
1435
|
+
openLocationInNewTab(opener, target);
|
|
1436
|
+
disarm();
|
|
1437
|
+
onPick?.(target, opener);
|
|
1438
|
+
};
|
|
1439
|
+
const onKeyDown = (event) => {
|
|
1440
|
+
if (event.key === "Escape") {
|
|
1441
|
+
disarm();
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1444
|
+
map.on("click", onClick);
|
|
1445
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1446
|
+
return function stopListeningForPick() {
|
|
1447
|
+
map.off("click", onClick);
|
|
1448
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
1449
|
+
};
|
|
1450
|
+
},
|
|
1451
|
+
[armedOpenerId, disarm, map, onPick]
|
|
1452
|
+
);
|
|
1453
|
+
return null;
|
|
1454
|
+
};
|
|
1455
|
+
var MapillaryFeatureBar = ({ data, shownImage, onShow }) => {
|
|
1456
|
+
const { locale, messages } = useStreetImageryI18n();
|
|
1457
|
+
const labels = messages.feature;
|
|
1458
|
+
const { feature, days, images } = data;
|
|
1459
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
1460
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", title: feature.value, children: [
|
|
1461
|
+
/* @__PURE__ */ jsx(
|
|
1462
|
+
"img",
|
|
1463
|
+
{
|
|
1464
|
+
alt: "",
|
|
1465
|
+
className: "size-7 shrink-0",
|
|
1466
|
+
onError: (event) => {
|
|
1467
|
+
event.currentTarget.style.display = "none";
|
|
1468
|
+
},
|
|
1469
|
+
src: mapillaryIconUrl(feature.value)
|
|
1470
|
+
},
|
|
1471
|
+
feature.value
|
|
1472
|
+
),
|
|
1473
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1474
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-sm leading-tight font-medium text-slate-900", children: labels.name(feature.value) }),
|
|
1475
|
+
/* @__PURE__ */ jsxs("p", { className: "truncate text-xs leading-tight text-slate-500", children: [
|
|
1476
|
+
labels.seen,
|
|
1477
|
+
" ",
|
|
1478
|
+
/* @__PURE__ */ jsx(PhotoDate, { timestamp: feature.firstSeenAt }),
|
|
1479
|
+
" \u2013",
|
|
1480
|
+
" ",
|
|
1481
|
+
/* @__PURE__ */ jsx(PhotoDate, { timestamp: feature.lastSeenAt })
|
|
1482
|
+
] })
|
|
1483
|
+
] })
|
|
1484
|
+
] }),
|
|
1485
|
+
days.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-500", children: labels.noPhotos }) : /* @__PURE__ */ jsx(
|
|
1486
|
+
"div",
|
|
1487
|
+
{
|
|
1488
|
+
"aria-label": labels.daysSummary(images.length, days.length),
|
|
1489
|
+
className: "flex gap-1 overflow-x-auto",
|
|
1490
|
+
role: "group",
|
|
1491
|
+
children: days.map((day) => {
|
|
1492
|
+
const noon = /* @__PURE__ */ new Date(`${day.day}T12:00:00Z`);
|
|
1493
|
+
const shownIndex = shownImage ? day.images.findIndex((image) => image.id === shownImage.id) : -1;
|
|
1494
|
+
const active = shownIndex >= 0;
|
|
1495
|
+
return /* @__PURE__ */ jsxs(
|
|
1496
|
+
"button",
|
|
1497
|
+
{
|
|
1498
|
+
"aria-pressed": active,
|
|
1499
|
+
className: `shrink-0 rounded-md border px-2 py-1 text-xs whitespace-nowrap ${active ? "border-amber-500 bg-amber-100 text-amber-950" : "border-slate-300 bg-white text-slate-700 hover:border-slate-400"}`,
|
|
1500
|
+
onClick: () => {
|
|
1501
|
+
const next = active ? day.images[(shownIndex + 1) % day.images.length] : day.best;
|
|
1502
|
+
if (next) {
|
|
1503
|
+
onShow(next);
|
|
1504
|
+
}
|
|
1505
|
+
},
|
|
1506
|
+
title: `${formatDateTooltip(noon, locale)}
|
|
1507
|
+
${labels.dayPhotos(day.images.length, active && day.images.length > 1)}`,
|
|
1508
|
+
type: "button",
|
|
1509
|
+
children: [
|
|
1510
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatMonth(noon, locale) }),
|
|
1511
|
+
" ",
|
|
1512
|
+
/* @__PURE__ */ jsxs("span", { className: active ? "text-amber-800" : "text-slate-500", children: [
|
|
1513
|
+
active ? `${shownIndex + 1}/` : "",
|
|
1514
|
+
day.images.length
|
|
1515
|
+
] })
|
|
1516
|
+
]
|
|
1517
|
+
},
|
|
1518
|
+
day.day
|
|
1519
|
+
);
|
|
1520
|
+
})
|
|
1521
|
+
}
|
|
1522
|
+
)
|
|
1523
|
+
] });
|
|
1524
|
+
};
|
|
1222
1525
|
|
|
1223
|
-
export { FloatingPhotoViewer, StreetLevelImagerySelectionOverlay, StreetLevelImagerySourcesAndLayers, StreetLevelImageryViewCone, StreetLevelImageryViewer, VIEWPOINT_DEFAULT_COLOR, VIEWPOINT_DIRECTION_LAYER_ID, ViewpointLayer, getViewpointSession, queryStreetImageryFeatures, resolveSelectedSequence, streetImageryInteractiveLayerIds, useActiveDirectionKey, useAllProviderMapFeatures,
|
|
1526
|
+
export { BASE_COLOR, FloatingPhotoViewer, FloatingViewerInfoButton, LocationPickOnMap, MapillaryFeatureBar, PhotoDate, SELECTION_COLOR, StreetLevelImagerySelectionOverlay, StreetLevelImagerySourcesAndLayers, StreetLevelImageryViewCone, StreetLevelImageryViewer, VIEWPOINT_DEFAULT_COLOR, VIEWPOINT_DIRECTION_LAYER_ID, VIEW_SHAPE_FILL_OPACITY, ViewpointLayer, getViewpointSession, queryStreetImageryFeatures, resolveSelectedSequence, streetImageryInteractiveLayerIds, useActiveDirectionKey, useAllProviderMapFeatures, useAllProviderPhotos, useArmedLocationOpenerId, useCanGoBack, useCanGoForward, useCurrentHistoryEntry, useLocationPickActions, useMapViewportBbox, useMapillaryImageDetections, useMapillaryMapFeatureImages, useMapillaryMapFeaturesNear, usePhotoFullUrl, usePhotoThumbnail, useProviderMapFeatures, useProviderPhotos, useProviderSequences, useViewSuggestions, useViewpointLine, useViewpoints, viewDirectionKeyFromFeatures, viewSuggestionLabel };
|