Skip to content

Commit

Permalink
feat(web): add time series czml example (#1417)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShogoHirasawa authored Feb 13, 2025
1 parent 6b3a042 commit 1ad2fc9
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 4 deletions.
11 changes: 7 additions & 4 deletions web/src/beta/features/PluginPlayground/Plugins/presets/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { PluginType } from "../constants";

import { cameraPosition } from "./camera/cameraPosition";
import { cameraRotation } from "./camera/cameraRotation";
import { zoomInOut } from "./camera/zoomInOut";
import { extensionExtensionMessenger } from "./communication/extensionExtensionMessenger";
import { uiExtensionMessenger } from "./communication/uiExtensionMessenger";
import { myPlugin } from "./custom/myPlugin";
Expand All @@ -24,6 +21,12 @@ import { filterFeatureWithStyle } from "./manageLayerStyle/filterFeaturebyStyle"
import { layerStylingExamples } from "./layerStyles/layerStylingExamples";
import { overrideStyle } from "./manageLayerStyle/overrideStyle";
import { styleWithCondition } from "./manageLayerStyle/styleWithCondition";
import { zoomInOut } from "./camera/zoomInOut";
import { cameraRotation } from "./camera/cameraRotation";
import { cameraPosition } from "./camera/cameraPosition";
import { playbackControl } from "./timeline/playbackControl";
import { timeDrivenFeatures } from "./timeline/timeDrivenFeatures";
import { timeDrivenPath } from "./timeline/timeDrivenPath";
import { header } from "./ui/header";
import { responsivePanel } from "./ui/responsivePanel";
import { sidebar } from "./ui/sidebar";
Expand Down Expand Up @@ -94,7 +97,7 @@ export const presetPlugins: PresetPlugins = [
{
id: "timeline",
title: "Timeline",
plugins: []
plugins: [playbackControl,timeDrivenFeatures,timeDrivenPath]
},
{
id: "dataStorage",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { FileType, PluginType } from "../../constants";

const yamlFile: FileType = {
id: "playback-control-reearth-yml",
title: "reearth.yml",
sourceCode: `id: playback-control-plugin
name: Playback Control
version: 1.0.0
extensions:
- id: playback-control
type: widget
name: Playback Control
description: Playback Control
`,
disableEdit: true,
disableDelete: true
};

const widgetFile: FileType = {
id: "playback-control",
title: "playback-control.js",
sourceCode: `TBD
`
};

export const playbackControl: PluginType = {
id: "playback-control",
title: "Playback Control",
files: [widgetFile, yamlFile]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { FileType, PluginType } from "../../constants";

const yamlFile: FileType = {
id: "time-driven-features-reearth-yml",
title: "reearth.yml",
sourceCode: `id: timeDrivenFeatures-plugin
name: Time Driven Features
version: 1.0.0
extensions:
- id: timeDrivenFeatures
type: widget
name: Time Driven Features
description: Time Driven Features
`,
disableEdit: true,
disableDelete: true
};

const widgetFile: FileType = {
id: "timeDrivenFeatures",
title: "timeDrivenFeatures.js",
sourceCode: `// This example shows how to make a feature change with time //
// Define CZML that has time series data
// Polygon height changes every 5 seconds
const czmlData = [
{
id: "document",
name: "3D Polygon Example",
version: "1.0",
clock: {
interval: "2024-12-24T01:00:00Z/2024-12-24T01:00:20Z", // Define time range
currentTime: "2024-12-24T01:00:00Z", // Define current (start) time
multiplier: 5, // Playback speed (5 means 20 seconds of real time = 4 seconds in the animation)
},
},
{
id: "samplePolygon001",
name: "samplePolygon001",
availability: "2024-12-24T01:00:00Z/2024-12-24T01:00:05Z", // Define the time the feature is displayed
polygon: {
positions: {
cartographicDegrees: [
// Define lon,lat,height of the bottom of the feature
-95.19644404998762, 39.121855688403606, 0, -95.86066795468007,
30.135315689161864, 0, -84.60676001423798, 29.013591974308632, 0,
-82.7088322952643, 37.87660535441917, 0, -95.19644404998762,
39.121855688403606, 0,
],
},
extrudedHeight: 100000, // Defines the height at which the polygon is extruded
},
},
{
id: "samplePolygon002",
name: "samplePolygon002",
availability: "2024-12-24T01:00:05Z/2024-12-24T01:00:10Z",
polygon: {
positions: {
cartographicDegrees: [
-95.19644404998762, 39.121855688403606, 0, -95.86066795468007,
30.135315689161864, 0, -84.60676001423798, 29.013591974308632, 0,
-82.7088322952643, 37.87660535441917, 0, -95.19644404998762,
39.121855688403606, 0,
],
},
extrudedHeight: 200000,
},
},
{
id: "samplePolygon003",
name: "samplePolygon003",
availability: "2024-12-24T01:00:10Z/2024-12-24T01:00:15Z",
polygon: {
positions: {
cartographicDegrees: [
-95.19644404998762, 39.121855688403606, 0, -95.86066795468007,
30.135315689161864, 0, -84.60676001423798, 29.013591974308632, 0,
-82.7088322952643, 37.87660535441917, 0, -95.19644404998762,
39.121855688403606, 0,
],
},
extrudedHeight: 300000,
},
},
{
id: "samplePolygon004",
name: "samplePolygon004",
availability: "2024-12-24T01:00:15Z/2024-12-24T01:00:20Z",
polygon: {
positions: {
cartographicDegrees: [
-95.19644404998762, 39.121855688403606, 0, -95.86066795468007,
30.135315689161864, 0, -84.60676001423798, 29.013591974308632, 0,
-82.7088322952643, 37.87660535441917, 0, -95.19644404998762,
39.121855688403606, 0,
],
},
extrudedHeight: 400000,
},
},
];
// Convert the CZML array to a JSON string, then encode it, and make a data URI
const czmlString = JSON.stringify(czmlData);
const encodedCzml =
"data:text/plain;charset=UTF-8," + encodeURIComponent(czmlString);
// Define a layer using the encoded CZML
const layerCzmlEncoded = {
type: "simple", // Required
data: {
type: "czml", // Data format
url: encodedCzml, // Use the encoded CZML string as a data URI
},
// Write the features style
polygon: {
fillColor: "#7fffd480",
},
};
// Add the encoded CZML layer to Re:Earth
reearth.layers.add(layerCzmlEncoded);
// Play timeline
reearth.timeline.play();
// Move the camera to the position where the CZML data is displayed
reearth.camera.flyTo(
{
heading: 5.672603993826703,
height: 975442.3456206004,
lat: 23.205784181888504,
lng: -78.89068372906681,
pitch: -0.63747059888472,
roll: 0.0003915776610474708,
},
// Define camera movement time
{
duration: 2.0,
}
);`
};

export const timeDrivenFeatures: PluginType = {
id: "timeDrivenFeatures",
title: "Time Driven Features",
files: [widgetFile, yamlFile]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { FileType, PluginType } from "../../constants";

const yamlFile: FileType = {
id: "timeDrivenPath-reearth-yml",
title: "reearth.yml",
sourceCode: `id: timeDrivenPath-plugin
name: Time Driven Path
version: 1.0.0
extensions:
- id: timeDrivenPath
type: widget
name: Time Driven Path
description: Time Driven Path
`,
disableEdit: true,
disableDelete: true
};

const widgetFile: FileType = {
id: "timeDrivenPath",
title: "timeDrivenPath.js",
sourceCode: ` // This example shows how to move a 3D model linearly along time
// Define the CZML data that includes time series information
const czmlData = [
{
id: "document",
name: "Tokaido Shinkansen Animation",
version: "1.0",
clock: {
interval: "2024-02-12T06:00:00Z/2024-02-12T08:22:00Z", // Define time range(start and end time)
currentTime: "2024-02-12T06:00:00Z", // The initial time
multiplier: 600, // Playback speed (600 means 10 minutes of real time = 1 minute in the animation)
range: "LOOP_STOP", // This will loop the animation until it stops
},
},
{
id: "toukaido",
name: "toukaido-shinkansen-root",
availability: "2024-02-12T06:00:00Z/2024-02-12T08:22:00Z", // Availability time range for the train
position: {
epoch: "2024-02-12T06:00:00Z", // Starting point for the position (time)
cartographicDegrees: [
// Define the time, longitude, latitude, and height (altitude) for each time point
// Time, lon, lat, height (in the order: time, lon, lat, height)
0, 139.766084, 35.681382, 0, 532.5, 139.73868, 35.62847, 0, 1065,
139.617572, 35.465031, 0, 1597.5, 139.159921, 35.254122, 0, 2130,
139.071773, 35.115197, 0, 2662.5, 138.965717, 35.126885, 0, 3195,
138.622902, 35.144373, 0, 3727.5, 138.383054, 34.975357, 0, 4260,
137.997, 34.770556, 0, 4792.5, 137.734958, 34.702523, 0, 5325,
137.391372, 34.769233, 0, 5857.5, 137.061397, 34.963855, 0, 6390,
136.884094, 35.170417, 0, 6922.5, 136.756847, 35.302581, 0, 7455,
136.292578, 35.315653, 0, 7987.5, 135.757784, 35.013298, 0, 8520,
135.49056, 34.730327, 0,
],
},
// Define how the path will be displayed (the line showing the train's movement)
path: {
material: {
solidColor: {
color: {
rgba: [255, 255, 255, 255],
},
},
},
width: 5,
leadTime: 0,
},
// Define the 3D model
model: {
gltf: "https://reearth.github.io/visualizer-plugin-sample-data/public/gltf/train.gltf", // URL of 3D model(gltf)
scale: 1.0, // Scale of the 3D model
minimumPixelSize: 70, // Minimum pixel size of the model for visibility
},
orientation: {
"velocityReference": "toukaido#position" // Set the 3D model to face the direction of travel based on the position
}
},
];
// Convert the CZML array to a JSON string, then encode it, and make a data URI
const czmlString = JSON.stringify(czmlData);
const encodedCzml =
"data:text/plain;charset=UTF-8," + encodeURIComponent(czmlString);
// Define a layer using the encoded CZML
const layerCzmlEncoded = {
type: "simple",
data: {
type: "czml",
url: encodedCzml,
},
polygon: {
fillColor: "#7fffd480",
},
};
// Add the encoded CZML layer to Re:Earth
reearth.layers.add(layerCzmlEncoded);
// Play timeline
reearth.timeline.play();
// Move the camera to the position where the CZML data is displayed
reearth.camera.flyTo(
{
heading: 6.246954319760702,
height: 591887.4618586897,
lat: 29.62255491782384,
lng: 137.32567845678386,
pitch: -0.8072976015234672,
roll: 0.0006403173192017775,
},
// Define camera movement time
{
duration: 2.0,
}
);
// * Data License * //
// Line data: uedayou(https://uedayou.net/jrslod/)
`
};

export const timeDrivenPath: PluginType = {
id: "timeDrivenPath",
title: "Time Driven Path",
files: [widgetFile, yamlFile]
};

0 comments on commit 1ad2fc9

Please sign in to comment.