@reearth/core 0.0.7-alpha.15 → 0.0.7-alpha.17

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/dist/index.d.ts CHANGED
@@ -169,7 +169,6 @@ export declare type Cesium3DTilesAppearance = {
169
169
  selectedFeatureColor?: string;
170
170
  disableIndexingFeature?: boolean;
171
171
  tileset?: string;
172
- apiKey?: string;
173
172
  experimental_clipping?: EXPERIMENTAL_clipping;
174
173
  pointSize?: number;
175
174
  meta?: unknown;
@@ -356,6 +355,7 @@ export declare type CoreVisualizerProps = {
356
355
  ready?: boolean;
357
356
  hiddenLayers?: string[];
358
357
  zoomedLayerId?: string;
358
+ displayCredits?: boolean;
359
359
  onCameraChange?: (camera: Camera) => void;
360
360
  onLayerDrop?: (layerId: string, propertyKey: string, position: LatLng | undefined) => void;
361
361
  onLayerSelect?: (layerId: string | undefined, layer: (() => Promise<ComputedLayer | undefined>) | undefined, feature: ComputedFeature | undefined, reason: LayerSelectionReason | undefined) => void;
@@ -367,6 +367,11 @@ export declare type CoreVisualizerProps = {
367
367
  onSketchFeatureDelete?: (layerId: string, featureId: string) => void;
368
368
  onInteractionModeChange?: (mode: InteractionModeType) => void;
369
369
  onAPIReady?: () => void;
370
+ onCreditsUpdate?: (credits: Credit[]) => void;
371
+ };
372
+
373
+ export declare type Credit = {
374
+ html?: string;
370
375
  };
371
376
 
372
377
  export declare type CursorType = "auto" | "grab" | "crosshair";
@@ -383,6 +388,9 @@ export declare type Data = {
383
388
  updateInterval?: number;
384
389
  parameters?: Record<string, any>;
385
390
  idProperty?: string;
391
+ serviceTokens?: {
392
+ googleMapApiKey?: string;
393
+ };
386
394
  time?: {
387
395
  property?: string;
388
396
  interval?: number;
@@ -496,6 +504,7 @@ export declare type EngineProps = {
496
504
  isLayerDragging?: boolean;
497
505
  shouldRender?: boolean;
498
506
  meta?: Record<string, unknown>;
507
+ displayCredits?: boolean;
499
508
  layersRef?: RefObject<LayersRef>;
500
509
  requestingRenderMode?: MutableRefObject<RequestingRenderMode>;
501
510
  timelineManagerRef?: TimelineManagerRef;
@@ -510,6 +519,7 @@ export declare type EngineProps = {
510
519
  onLayerSelectWithRectStart?: (e: LayerSelectWithRectStart) => void;
511
520
  onLayerSelectWithRectMove?: (e: LayerSelectWithRectMove) => void;
512
521
  onLayerSelectWithRectEnd?: (e: LayerSelectWithRectEnd) => void;
522
+ onCreditsUpdate?: (credits: Credit[]) => void;
513
523
  };
514
524
 
515
525
  export declare type EngineRef = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reearth/core",
3
- "version": "0.0.7-alpha.15",
3
+ "version": "0.0.7-alpha.17",
4
4
  "author": "Re:Earth contributors <community@reearth.io>",
5
5
  "license": "Apache-2.0",
6
6
  "description": "A library that abstracts a map engine as one common API.",
@@ -235,6 +235,7 @@ export type EngineProps = {
235
235
  isLayerDragging?: boolean;
236
236
  shouldRender?: boolean;
237
237
  meta?: Record<string, unknown>;
238
+ displayCredits?: boolean;
238
239
  layersRef?: RefObject<LayersRef>;
239
240
  requestingRenderMode?: MutableRefObject<RequestingRenderMode>;
240
241
  timelineManagerRef?: TimelineManagerRef;
@@ -258,6 +259,7 @@ export type EngineProps = {
258
259
  onLayerSelectWithRectStart?: (e: LayerSelectWithRectStart) => void;
259
260
  onLayerSelectWithRectMove?: (e: LayerSelectWithRectMove) => void;
260
261
  onLayerSelectWithRectEnd?: (e: LayerSelectWithRectEnd) => void;
262
+ onCreditsUpdate?: (credits: Credit[]) => void;
261
263
  };
262
264
 
263
265
  export type LayerEditEvent = {
@@ -381,3 +383,7 @@ export type SketchRef = {
381
383
  deleteFeature: (layerId: string, featureId: string) => void;
382
384
  onEditFeatureChange: (cb: SketchEditFeatureChangeCb) => void;
383
385
  };
386
+
387
+ export type Credit = {
388
+ html?: string;
389
+ };
@@ -12,6 +12,7 @@ import {
12
12
  type LatLng,
13
13
  type Cluster,
14
14
  type ComputedLayer,
15
+ type Credit,
15
16
  } from "../Map";
16
17
  import { SketchFeature, SketchType } from "../Map/Sketch/types";
17
18
 
@@ -46,6 +47,7 @@ export type CoreVisualizerProps = {
46
47
  ready?: boolean;
47
48
  hiddenLayers?: string[];
48
49
  zoomedLayerId?: string;
50
+ displayCredits?: boolean;
49
51
  onCameraChange?: (camera: Camera) => void;
50
52
  onLayerDrop?: (layerId: string, propertyKey: string, position: LatLng | undefined) => void;
51
53
  onLayerSelect?: (
@@ -62,6 +64,7 @@ export type CoreVisualizerProps = {
62
64
  onSketchFeatureDelete?: (layerId: string, featureId: string) => void;
63
65
  onInteractionModeChange?: (mode: InteractionModeType) => void;
64
66
  onAPIReady?: () => void;
67
+ onCreditsUpdate?: (credits: Credit[]) => void;
65
68
  };
66
69
 
67
70
  export const CoreVisualizer = memo(
@@ -82,6 +85,7 @@ export const CoreVisualizer = memo(
82
85
  interactionMode,
83
86
  shouldRender,
84
87
  meta,
88
+ displayCredits = true,
85
89
  style,
86
90
  zoomedLayerId,
87
91
  children,
@@ -96,6 +100,7 @@ export const CoreVisualizer = memo(
96
100
  onSketchFeatureUpdate,
97
101
  onSketchFeatureDelete,
98
102
  onAPIReady,
103
+ onCreditsUpdate,
99
104
  },
100
105
  ref: Ref<MapRef | null>,
101
106
  ) => {
@@ -160,6 +165,7 @@ export const CoreVisualizer = memo(
160
165
  isLayerDragging={isLayerDragging}
161
166
  isLayerDraggable={isEditable}
162
167
  meta={meta}
168
+ displayCredits={displayCredits}
163
169
  style={style}
164
170
  featureFlags={featureFlags}
165
171
  shouldRender={shouldRender}
@@ -191,6 +197,7 @@ export const CoreVisualizer = memo(
191
197
  onLayerSelectWithRectMove={handleLayerSelectWithRectMove}
192
198
  onLayerSelectWithRectEnd={handleLayerSelectWithRectEnd}
193
199
  onAPIReady={onAPIReady}
200
+ onCreditsUpdate={onCreditsUpdate}
194
201
  />
195
202
  <coreContext.Provider value={coreContextValue}>{children}</coreContext.Provider>
196
203
  </div>
@@ -15,13 +15,11 @@ import {
15
15
  Cesium3DTileFeature,
16
16
  Model,
17
17
  Cesium3DTilePointFeature,
18
- GoogleMaps as CesiumGoogleMaps,
19
- Resource,
20
- defaultValue,
21
18
  ImageBasedLighting,
22
19
  Cesium3DTileContent,
23
20
  Color,
24
21
  Viewer,
22
+ createGooglePhotorealistic3DTileset,
25
23
  } from "cesium";
26
24
  import { pick } from "lodash-es";
27
25
  import { MutableRefObject, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -57,7 +55,6 @@ import {
57
55
  } from "../utils";
58
56
 
59
57
  import { TilesetFeatureIndex } from "./TilesetFeatureIndex";
60
- import { GoogleMaps } from "./types";
61
58
  import { useClippingBox } from "./useClippingBox";
62
59
  import { useDrawClipping } from "./useDrawClipping";
63
60
 
@@ -77,6 +74,7 @@ const useData = (layer: ComputedLayer | undefined) => {
77
74
  ? data.layers.join(",")
78
75
  : data?.layers
79
76
  : undefined,
77
+ googleMapApiKey: data?.serviceTokens?.googleMapApiKey,
80
78
  };
81
79
  }, [layer]);
82
80
  };
@@ -460,7 +458,6 @@ export const useHooks = ({
460
458
  edgeColor,
461
459
  edgeWidth,
462
460
  experimental_clipping,
463
- apiKey,
464
461
  selectedFeatureColor,
465
462
  disableIndexingFeature,
466
463
  } = property ?? {};
@@ -481,7 +478,7 @@ export const useHooks = ({
481
478
  } = useClippingBox({ clipping: experimental_clipping, boxId });
482
479
 
483
480
  const [style, setStyle] = useState<Cesium3DTileStyle>();
484
- const { url, type, idProperty } = useData(layer);
481
+ const { url, type, idProperty, googleMapApiKey } = useData(layer);
485
482
  const shouldUseFeatureIndex = !disableIndexingFeature && !!idProperty;
486
483
 
487
484
  const [isTilesetReady, setIsTilesetReady] = useState(false);
@@ -708,31 +705,33 @@ export const useHooks = ({
708
705
  })();
709
706
  }, [styleUrl]);
710
707
 
711
- const googleMapResource = useMemo(() => {
712
- if (type !== "google-photorealistic" || !isVisible) return;
713
- // Ref: https://github.com/CesiumGS/cesium/blob/b208135a095073386e5f04a59956ee11a03aa847/packages/engine/Source/Scene/createGooglePhotorealistic3DTileset.js#L30
714
- const googleMaps = CesiumGoogleMaps as GoogleMaps;
715
- // Default key: https://github.com/CesiumGS/cesium/blob/b208135a095073386e5f04a59956ee11a03aa847/packages/engine/Source/Core/GoogleMaps.js#L6C36-L6C36
716
- const key = defaultValue(apiKey, googleMaps.defaultApiKey);
717
- const credit = googleMaps.getDefaultApiKeyCredit(key);
718
- return new Resource({
719
- url: `${googleMaps.mapTilesApiEndpoint}3dtiles/root.json`,
720
- queryParameters: { key },
721
- credits: credit ? [credit] : undefined,
722
- } as Resource.ConstructorOptions);
723
- }, [apiKey, type, isVisible]);
708
+ const googleMapPhotorealisticResource = useMemo(() => {
709
+ if (type !== "google-photorealistic" || !isVisible) return null;
710
+
711
+ const loadTileset = async () => {
712
+ try {
713
+ const tileset = await createGooglePhotorealistic3DTileset(googleMapApiKey);
714
+ return tileset.resource;
715
+ } catch (error) {
716
+ console.error(`Error loading Photorealistic 3D Tiles tileset: ${error}`);
717
+ throw error;
718
+ }
719
+ };
720
+
721
+ return loadTileset();
722
+ }, [type, isVisible, googleMapApiKey]);
724
723
 
725
724
  const tilesetUrl = useMemo(() => {
726
725
  return type === "osm-buildings" && isVisible
727
726
  ? IonResource.fromAssetId(96188, {
728
727
  accessToken: meta?.cesiumIonAccessToken as string | undefined,
729
728
  }) // https://github.com/CesiumGS/cesium/blob/main/packages/engine/Source/Scene/createOsmBuildings.js#L53
730
- : googleMapResource
731
- ? googleMapResource
729
+ : googleMapPhotorealisticResource && isVisible
730
+ ? googleMapPhotorealisticResource
732
731
  : type === "3dtiles" && isVisible
733
732
  ? url ?? tileset
734
733
  : null;
735
- }, [isVisible, tileset, url, type, meta, googleMapResource]);
734
+ }, [type, isVisible, meta?.cesiumIonAccessToken, googleMapPhotorealisticResource, url, tileset]);
736
735
 
737
736
  const imageBasedLighting = useMemo(() => {
738
737
  if (
@@ -5,7 +5,7 @@ import {
5
5
  IonResource,
6
6
  TerrainProvider,
7
7
  } from "cesium";
8
- import { useMemo } from "react";
8
+ import { useEffect, useMemo } from "react";
9
9
  import { Globe as CesiumGlobe } from "resium";
10
10
 
11
11
  import type { ViewerProperty, TerrainProperty } from "../..";
@@ -15,9 +15,14 @@ import { toColor } from "../common";
15
15
  export type Props = {
16
16
  property?: ViewerProperty;
17
17
  cesiumIonAccessToken?: string;
18
+ onTerrainProviderChange?: () => void;
18
19
  };
19
20
 
20
- export default function Globe({ property, cesiumIonAccessToken }: Props): JSX.Element | null {
21
+ export default function Globe({
22
+ property,
23
+ cesiumIonAccessToken,
24
+ onTerrainProviderChange,
25
+ }: Props): JSX.Element | null {
21
26
  const terrainProperty = useMemo(
22
27
  (): TerrainProperty => ({
23
28
  ...property?.terrain,
@@ -51,6 +56,10 @@ export default function Globe({ property, cesiumIonAccessToken }: Props): JSX.El
51
56
  [property?.globe?.baseColor],
52
57
  );
53
58
 
59
+ useEffect(() => {
60
+ onTerrainProviderChange?.();
61
+ }, [terrainProvider, onTerrainProviderChange]);
62
+
54
63
  return (
55
64
  <CesiumGlobe
56
65
  baseColor={baseColor}
@@ -5,7 +5,7 @@ import {
5
5
  TextureMinificationFilter,
6
6
  } from "cesium";
7
7
  import { isEqual } from "lodash-es";
8
- import { useCallback, useMemo, useRef, useLayoutEffect, useState } from "react";
8
+ import { useCallback, useMemo, useRef, useLayoutEffect, useState, useEffect } from "react";
9
9
  import { ImageryLayer } from "resium";
10
10
 
11
11
  import { tiles as tilePresets } from "./presets";
@@ -31,9 +31,10 @@ export type Tile = {
31
31
  export type Props = {
32
32
  tiles?: Tile[];
33
33
  cesiumIonAccessToken?: string;
34
+ onTilesChange?: () => void;
34
35
  };
35
36
 
36
- export default function ImageryLayers({ tiles, cesiumIonAccessToken }: Props) {
37
+ export default function ImageryLayers({ tiles, cesiumIonAccessToken, onTilesChange }: Props) {
37
38
  const { providers, updated } = useImageryProviders({
38
39
  tiles,
39
40
  cesiumIonAccessToken,
@@ -47,6 +48,10 @@ export default function ImageryLayers({ tiles, cesiumIonAccessToken }: Props) {
47
48
  if (updated) setCounter(c => c + 1);
48
49
  }, [providers, updated]);
49
50
 
51
+ useEffect(() => {
52
+ onTilesChange?.();
53
+ }, [tiles, counter, onTilesChange]);
54
+
50
55
  return (
51
56
  <>
52
57
  {tiles
@@ -24,17 +24,6 @@ export const tiles = {
24
24
  IonImageryProvider.fromAssetId(IonWorldImageryStyle.ROAD, {
25
25
  accessToken: cesiumIonAccessToken,
26
26
  }).catch(console.error),
27
- stamen_watercolor: () =>
28
- new OpenStreetMapImageryProvider({
29
- url: "https://stamen-tiles.a.ssl.fastly.net/watercolor/",
30
- credit: "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.",
31
- fileExtension: "jpg",
32
- }),
33
- stamen_toner: () =>
34
- new OpenStreetMapImageryProvider({
35
- url: "https://stamen-tiles.a.ssl.fastly.net/toner/",
36
- credit: "Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.",
37
- }),
38
27
  open_street_map: () =>
39
28
  new OpenStreetMapImageryProvider({
40
29
  url: "https://a.tile.openstreetmap.org/",
@@ -12,6 +12,8 @@ import {
12
12
  GroundPrimitive,
13
13
  ShadowMap,
14
14
  ImageryLayer,
15
+ CreditDisplay,
16
+ Credit as CesiumCredit,
15
17
  } from "cesium";
16
18
  import { MutableRefObject, RefObject, useCallback, useEffect, useMemo, useRef } from "react";
17
19
  import type { CesiumComponentRef, CesiumMovementEvent, RootEventTarget } from "resium";
@@ -27,6 +29,7 @@ import type {
27
29
  import { e2eAccessToken, setE2ECesiumViewer } from "../../e2eConfig";
28
30
  import { ComputedFeature, DataType, SelectedFeatureInfo, LatLng, Camera } from "../../mantle";
29
31
  import {
32
+ Credit,
30
33
  LayerLoadEvent,
31
34
  LayerSelectWithRectEnd,
32
35
  LayerSelectWithRectMove,
@@ -89,6 +92,7 @@ export default ({
89
92
  onLayerLoad,
90
93
  onCameraChange,
91
94
  onMount,
95
+ onCreditsUpdate,
92
96
  }: {
93
97
  ref: React.ForwardedRef<EngineRef>;
94
98
  property?: ViewerProperty;
@@ -128,6 +132,7 @@ export default ({
128
132
  onLayerLoad?: (e: LayerLoadEvent) => void;
129
133
  onCameraChange?: (camera: Camera) => void;
130
134
  onMount?: () => void;
135
+ onCreditsUpdate?: (credits: Credit[]) => void;
131
136
  }) => {
132
137
  const cesium = useRef<CesiumComponentRef<CesiumViewer>>(null);
133
138
 
@@ -728,6 +733,49 @@ export default ({
728
733
  unmountCamera?.();
729
734
  }, [unmountCamera]);
730
735
 
736
+ const updateCredits = useCallback(() => {
737
+ if (!onCreditsUpdate) return;
738
+ // currently we don't have a proper way to get the credits update event
739
+ // wait for 3 seconds to get latest credits
740
+ // some internal property is been used here.
741
+ setTimeout(() => {
742
+ const creditDisplay = cesium.current?.cesiumElement?.creditDisplay as
743
+ | (CreditDisplay & {
744
+ _currentFrameCredits: {
745
+ lightboxCredits: { _array: { credit?: CesiumCredit }[] };
746
+ screenCredits: { _array: { credit?: CesiumCredit }[] };
747
+ };
748
+ _currentCesiumCredit: CesiumCredit;
749
+ })
750
+ | undefined;
751
+
752
+ if (!creditDisplay) return;
753
+
754
+ const { lightboxCredits, screenCredits } = creditDisplay?._currentFrameCredits || {};
755
+ const cesiumCredits = creditDisplay._currentCesiumCredit;
756
+
757
+ const credits: Credit[] = [
758
+ ...(cesiumCredits?.html ? [{ html: cesiumCredits.html }] : []),
759
+ ...Array.from(lightboxCredits?._array ?? []).map(c => ({
760
+ html: c?.credit?.html,
761
+ })),
762
+ ...Array.from(screenCredits?._array ?? []).map(c => ({
763
+ html: c?.credit?.html,
764
+ })),
765
+ ];
766
+
767
+ onCreditsUpdate(credits);
768
+ }, 3000);
769
+ }, [onCreditsUpdate]);
770
+
771
+ const handleTilesChange = useCallback(() => {
772
+ updateCredits();
773
+ }, [updateCredits]);
774
+
775
+ const handleTerrainProviderChange = useCallback(() => {
776
+ updateCredits();
777
+ }, [updateCredits]);
778
+
731
779
  return {
732
780
  cesium,
733
781
  cesiumIonAccessToken,
@@ -747,6 +795,8 @@ export default ({
747
795
  handleClick,
748
796
  handleMount,
749
797
  handleUnmount,
798
+ handleTilesChange,
799
+ handleTerrainProviderChange,
750
800
  };
751
801
  };
752
802
 
@@ -47,6 +47,7 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
47
47
  shouldRender,
48
48
  layerSelectionReason,
49
49
  meta,
50
+ displayCredits,
50
51
  layersRef,
51
52
  featureFlags,
52
53
  requestingRenderMode,
@@ -63,6 +64,7 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
63
64
  onMount,
64
65
  onLayerVisibility,
65
66
  onLayerLoad,
67
+ onCreditsUpdate,
66
68
  },
67
69
  ref,
68
70
  ) => {
@@ -85,6 +87,8 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
85
87
  handleClick,
86
88
  handleMount,
87
89
  handleUnmount,
90
+ handleTilesChange,
91
+ handleTerrainProviderChange,
88
92
  } = useHooks({
89
93
  ref,
90
94
  property,
@@ -112,6 +116,7 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
112
116
  onLayerLoad,
113
117
  onCameraChange,
114
118
  onMount,
119
+ onCreditsUpdate,
115
120
  });
116
121
 
117
122
  return (
@@ -133,7 +138,7 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
133
138
  navigationHelpButton={false}
134
139
  projectionPicker={false}
135
140
  sceneModePicker={false}
136
- creditContainer={creditContainer}
141
+ creditContainer={displayCredits ? undefined : creditContainer}
137
142
  style={{
138
143
  width: small ? "300px" : "auto",
139
144
  height: small ? "300px" : "100%",
@@ -158,7 +163,11 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
158
163
  onWheel={mouseEventHandles.wheel}>
159
164
  <Event onMount={handleMount} onUnmount={handleUnmount} />
160
165
  <Clock timelineManagerRef={timelineManagerRef} />
161
- <ImageryLayers tiles={property?.tiles} cesiumIonAccessToken={cesiumIonAccessToken} />
166
+ <ImageryLayers
167
+ tiles={property?.tiles}
168
+ cesiumIonAccessToken={cesiumIonAccessToken}
169
+ onTilesChange={handleTilesChange}
170
+ />
162
171
  <LabelImageryLayers tileLabels={property?.tileLabels} />
163
172
  <Indicator property={property} timelineManagerRef={timelineManagerRef} />
164
173
  <ScreenSpaceEventHandler useDefault>
@@ -252,7 +261,11 @@ const Cesium: React.ForwardRefRenderFunction<EngineRef, EngineProps> = (
252
261
  saturationShift={property?.sky?.skyAtmosphere?.saturationShift}
253
262
  brightnessShift={property?.sky?.skyAtmosphere?.brightnessShift}
254
263
  />
255
- <Globe property={property} cesiumIonAccessToken={cesiumIonAccessToken} />
264
+ <Globe
265
+ property={property}
266
+ cesiumIonAccessToken={cesiumIonAccessToken}
267
+ onTerrainProviderChange={handleTerrainProviderChange}
268
+ />
256
269
  <featureContext.Provider value={context}>{ready ? children : null}</featureContext.Provider>
257
270
  <AmbientOcclusion
258
271
  {...AMBIENT_OCCLUSION_QUALITY[property?.render?.ambientOcclusion?.quality || "low"]}
@@ -200,7 +200,6 @@ export type Cesium3DTilesAppearance = {
200
200
  selectedFeatureColor?: string; // This doesn't support expression
201
201
  disableIndexingFeature?: boolean;
202
202
  tileset?: string;
203
- apiKey?: string;
204
203
  experimental_clipping?: EXPERIMENTAL_clipping;
205
204
  pointSize?: number;
206
205
  meta?: unknown;
@@ -76,6 +76,9 @@ export type Data = {
76
76
  updateInterval?: number; // milliseconds
77
77
  parameters?: Record<string, any>;
78
78
  idProperty?: string;
79
+ serviceTokens?: {
80
+ googleMapApiKey?: string;
81
+ };
79
82
  time?: {
80
83
  property?: string;
81
84
  interval?: number; // milliseconds