Commit 90443acc authored by JOE XMG's avatar JOE XMG
Browse files

update

parent 4c68f557
Pipeline #9120 passed with stage
in 19 seconds
{
"liveServer.settings.port": 5501
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Space-Time Cube Visualization</title>
<!-- Include necessary libraries -->
<script src="https://cdn.jsdelivr.net/npm/@arcgis/core@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/plotly.js-dist@latest"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
<style>
#plotlyContainer {
height: 100vh;
position: absolute;
bottom: 0;
left: 0;
top: 6%;
right:100;
width: 100%;
z-index: 3;
}
</style>
</head>
<body>
<!-- Add your HTML content here -->
<button id="toggleSpaceTime">Toggle Space-Time Cube</button>
<div id="spaceTimeCubeContainer" style="display: none;">
<!-- Container for the space-time cube visualization -->
<div id="spaceTimeCube"></div>
</div>
<!-- Container for Plotly visualization -->
<div id="plotlyContainer"></div>
<script>
document.getElementById("toggleSpaceTime").addEventListener("click", function () {
const spaceTimeContainer = document.getElementById("spaceTimeCubeContainer");
console.log("Toggle button clicked");
console.log("Current display style:", spaceTimeContainer.style.display);
spaceTimeContainer.style.display = spaceTimeContainer.style.display === "none" ? "block" : "none";
console.log("New display style:", spaceTimeContainer.style.display);
// If the space-time container is set to block initialize/reload the space-time visualization
if (spaceTimeContainer.style.display === "block") {
console.log("Initializing space-time visualization...");
animateSpaceTimeRoute('https://ogcapi.hft-stuttgart.de/ogc_api_moving_features/collections/bus_1/items', 'spaceTimeCube', 'black', 'Bus');
}
});
function animateSpaceTimeRoute(url, containerId, trainColor, trainName) {
fetch(url)
.then(response => response.json())
.then(data => {
if (!data || !data.features) {
console.error('Invalid data format:', data);
return;
}
const frames = data.features.map((feature, index) => {
const coordinates = feature.geometry.coordinates;
const timestamps = feature.properties.datetimes;
if (!Array.isArray(coordinates) || !Array.isArray(timestamps)) {
console.error('Invalid feature format:', feature);
return;
}
const lineColors = Array.from({ length: coordinates.length - 1 }, () => 'orange'); // Create an array of orange colors
return {
data: [
{
type: 'scattermapbox',
lat: coordinates.map(coord => coord[1]),
lon: coordinates.map(coord => coord[0]),
mode: 'lines+markers', // Display both points and lines
marker: { size: 6, color: 'black' },
line: { color: 'black' }, // This line is not used when mode is 'lines+markers'
name: 'Bus route',
},
{
type: 'scatter3d',
x: coordinates.map(coord => coord[0]),
y: coordinates.map(coord => coord[1]),
z: timestamps.map((time, i) => new Date(time).toISOString()),
mode: 'lines+markers', // Change mode to display both points and lines
marker: { color: 'black', size: 5 },
line: { color: 'red', size: 3 },
name: 'Bus trajectory line',
},
],
name: `frame${index + 1}`,
};
});
// Set the layout with mapbox style and access token
const layout = {
mapbox: {
style: 'light',
center: { lon: frames[0].data[0].lon[0], lat: frames[0].data[0].lat[0] },
zoom: 10,
accesstoken: 'pk.eyJ1IjoicmVkaWV0OTk2MyIsImEiOiJjbHJ1cmk5aGUwaDRvMmpuYWM4Z2NqcmZuIn0.c11HYT-5ucd6g6mL03bp3Q', // Mapbox access token
},
margin: { t: 0, b: 0, l: 0, r: 0 },
scene: {
xaxis: {
title: 'Long',
titlefont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
yaxis: {
title: 'Lat',
titlefont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
zaxis: {
title: 'Time',
titlefont: {
family: 'Arial, sans-serif',
size: 16,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
// Common font settings for both
font: {
family: 'Arial, sans-serif',
size: 12,
color: 'black',
bold: true
}
}
};
// Initialize Plotly container
Plotly.newPlot('plotlyContainer', frames[0].data, layout);
Plotly.addFrames('plotlyContainer', frames);
})
.catch(error => {
console.error('Error fetching data:', error);
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
......@@ -11,7 +12,7 @@
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.js"></script>
<link href="https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.common.min.js" integrity="sha512-klHlINboj5r1sfTjdyb2PJn7ixcYb5zN+WC/gbFlK3r8/nmhmwQ3yvi5q49tX39DcHX/HwPnXTIblG5/cb6IEA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.2.2/dist/echarts.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js" integrity="sha512-k37wQcV4v2h6jgYf5IUz1MoSKPpDs630XGSmCaCCOXxy2awgAWKHGZWr9nMyGgk3IOxA1NxdkN8r1JHgkUtMoQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
......@@ -54,12 +55,38 @@
margin-bottom: 5px;
}
#mainMenu label {
color: white;
}
#mainMenu button {
margin-top: 10px;
padding: 5px 10px;
cursor: pointer;
color: white; /* Set the color of the text to white */
margin-bottom: 10px;
}
#mainMenu button {
border: none; /* Remove default button border */
background: none; /* Remove default button background */
cursor: pointer;
position: relative; /* Position for the separator line */
}
#mainMenu button:after {
content: "";
position: absolute;
bottom: -5px; /* Adjust position of the separator line */
left: 0;
width: 100%;
height: 2px; /* Adjust thickness of the separator line */
background-color: red; /* Color of the separator line */
}
#main-menu {
width: 20%;
height: 100%;
......@@ -80,15 +107,22 @@
#main {
width: 36%;
height: 65%;
width: 60%;
height: 60%;
position:relative;
top:35%;
right:0;
top: 36%;
z-index: 1;
}
/* responsive */
#main canvas {
width: 100%;
height: 100%;
}
#viewDiv {
width: 100%;
......@@ -103,6 +137,8 @@
display: none;
}
.legend-building {
position: absolute;
bottom: 10px;
......@@ -116,13 +152,13 @@
}
.legend {
position: absolute;
top: 90%;
left: 36%;
position: relative;
top: 72%;
left: 51%;
padding: 5px;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 5px;
border-radius: 3px;
z-index: 1;
display: flex;
flex-direction: column;
......@@ -166,11 +202,11 @@
#usage-pie-chart {
display: none;
width: 600px;
height: 400px;
z-index: 1;
width: 400px;
height: 300px;
z-index: 0;
position: absolute;
top:65%;
top:0%;
right: 0%;
bottom:0%;
}
......@@ -187,7 +223,7 @@
<div id="timeSlider"></div>
<div id="usage-pie-chart"></div>
<div class="legend"></div>
<div class="legend-building"></div>
<div id="spaceTimeCubeContainer">
<div id="plotlyContainer"></div>
......@@ -217,10 +253,12 @@
<button id="loadDatastream">Load Datastream</button>
<button id="loadDatastream">Load Chart</button>
<button id="toggleSpaceTime">Bus Space-Time Visualization</button>
<button id="toggle3DButton">3D City Building</button>
<button id="toggle3DButton">3D CityModel</button>
</div>
......@@ -239,9 +277,39 @@
//to ensure if plotly and mapbox are loaded
if (window.Plotly && window.L) {
document.getElementById("loadDatastream").addEventListener("click", function () {
var selectedMeasurementType = document.getElementById("measurementType").value;
var selectedChartType = document.getElementById("chartType").value;
document.getElementById("loadDatastream").addEventListener("click", function() {
var chartContainer = document.getElementById("main");
if (chartContainer.style.display === "none") {
// Datastream is not loaded, load it
loadDatastream();
// Change the button text to "Close Chart"
this.innerText = "Close Chart";
} else {
// Datastream is loaded, close it
closeDatastream();
// Change the button text back to "Load Chart"
this.innerText = "Load Chart";
}
});
function loadDatastream() {
// Code to load the datastream and display the chart
var chartContainer = document.getElementById("main");
chartContainer.style.display = "block";
}
function closeDatastream() {
// Code to close the datastream and hide the chart
var chartContainer = document.getElementById("main");
chartContainer.style.display = "none";
}
// Your existing code continues here...
......@@ -310,8 +378,8 @@
myChart.setOption({
backgroundColor: 'dark-gray',
title: {
text: selectedMeasurementType.charAt(0).toUpperCase() + selectedMeasurementType.slice(1) +
' Results at Different Sensor Locations',
text: ' Data Stream Result Observing ' + selectedMeasurementType.charAt(0).toUpperCase() + selectedMeasurementType.slice(1),
left: 'center',
textStyle: {
color: 'white',
......@@ -321,7 +389,7 @@
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(0, 0, 0, 0.7)',
backgroundColor: 'rgba(230, 230, 255, 0.9)',
formatter: function (params) {
var timestamp = new Date(params[0].value[0]);
var formattedTime = timestamp.toLocaleString();
......@@ -341,12 +409,12 @@
},
xAxis: {
name: 'Phenomenon Time',
name: 'Date Time',
type: 'time',
boundaryGap: false,
axisLabel: {
color: 'green',
fontSize: 20,
fontSize: 18,
},
},
yAxis: {
......@@ -363,7 +431,7 @@
itemStyle: {
color: locationColors[locationData.location],
emphasis: {
color: 'white',
color: 'red',
fontWeight: 'bold',
},
},
......@@ -427,7 +495,6 @@
function createLegendItem(color, label, id) {
const legendItem = document.createElement("div");
legendItem.className = "legend-item";
......@@ -450,123 +517,6 @@
return legendItem;
}
// To animating space-time routes directly
animateSpaceTimeRoutes('https://ogcapi.hft-stuttgart.de/ogc_api_moving_features/collections/bus_1/items');
function animateSpaceTimeRoutes(url) {
fetch(url)
.then(response => response.json())
.then(data => {
if (!data || !data.features) {
console.error('Invalid data format:', data);
return;
}
const frames = data.features.map((feature, index) => {
const coordinates = feature.geometry.coordinates;
const timestamps = feature.properties.datetimes;
if (!Array.isArray(coordinates) || !Array.isArray(timestamps)) {
console.error('Invalid feature format:', feature);
return;
}
return {
data: [
{
type: 'scattermapbox',
lat: coordinates.map(coord => coord[1]),
lon: coordinates.map(coord => coord[0]),
mode: 'lines+markers',
marker: { size: 6, color: 'black' },
line: { color: 'black' },
name: 'Bus route',
},
{
type: 'scatter3d',
x: coordinates.map(coord => coord[0]),
y: coordinates.map(coord => coord[1]),
z: timestamps.map((time, i) => new Date(time).toISOString()),
mode: 'lines+markers',
line: { color: 'dark' },
name: 'Bus trajectory line',
},
],
name: `frame${index + 1}`,
};
});
// to set the layout with mapbox _ access token
const layout = {
mapbox: {
style: 'light',
center: { lon: frames[0].data[0].lon[0], lat: frames[0].data[0].lat[0] },
zoom: 10,
accesstoken: 'pk.eyJ1IjoicmVkaWV0OTk2MyIsImEiOiJjbHJ1cmk5aGUwaDRvMmpuYWM4Z2NqcmZuIn0.c11HYT-5ucd6g6mL03bp3Q', // Mapbox access token
},
margin: { t: 0, b: 0, l: 0, r: 0 },
scene: {
xaxis: {
title: 'X Axis',
titlefont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
yaxis: {
title: 'Y Axis',
titlefont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
zaxis: {
title: 'Time',
titlefont: {
family: 'Arial, sans-serif',
size: 16,
color: 'black'
},
tickfont: {
family: 'Arial, sans-serif',
size: 15,
color: 'black',
bold: true
}
},
// Common font settings for both
font: {
family: 'Arial, sans-serif',
size: 12,
color: 'black',
bold: true
}
}
};
// Initialize Plotly container
Plotly.newPlot('plotlyContainer', frames[0].data, layout);
Plotly.addFrames('plotlyContainer', frames);
})
.catch(error => {
console.error('Error fetching data:', error);
});
}
// Function to toggle space-time visualization
document.getElementById("toggleSpaceTime").addEventListener("click", function () {
......@@ -577,13 +527,21 @@ const layout = {
console.error("Plotly or Mapbox not loaded. Check if the libraries are loaded correctly.");
}
document.getElementById("toggleSpaceTime").addEventListener("click", function () {
// URL for the space-time visualization page
var spaceTimeURL = "/STC.html";
// Open the space-time visualization page in a new window
window.open(spaceTimeURL, "_blank");
});
function loadHistoricalRoutes() {
// to fetch historical data and update the scene layer
animateHistoricalMovingFeatures('https://ogcapi.hft-stuttgart.de/ogc_api_moving_features/collections/bus_1/items', [226, 119, 40], 'Bus', 'Bus', 'busLegend');
}
</script>
<script>
......@@ -916,22 +874,32 @@ document.getElementById("toggle3DButton").addEventListener("click", function ()
// Toggle 3D building layer visibility
hostedLayer.visible = !hostedLayer.visible;
// Update button text based on 3D building visibility
const button = document.getElementById("toggle3DButton");
if (hostedLayer.visible) {
// If 3D building is visible, change button text to "Hide 3D CityModel"
button.innerText = "Hide 3D CityModel";
} else {
// If 3D building is hidden, change button text to "Show 3D CityModel"
button.innerText = "Show 3D CityModel";
}
// Toggle pie chart visibility based on 3D building visibility
const pieChartContainer = document.getElementById("usage-pie-chart");
const echartContainer = document.getElementById("main");
const legendContainer = document.querySelector('.legend');
const currentDisplay = pieChartContainer.style.display;
const loadDatastreamButton = document.getElementById("loadDatastream");
if (hostedLayer.visible) {
// If 3D building is visible, show the pie chart
pieChartContainer.style.display = "block";
echartContainer.style.display = "none";
legendContainer.style.display = "none";
} else {
// If 3D building is hidden, hide the pie chart
pieChartContainer.style.display = "none";
echartContainer.style.display = "block";
legendContainer.style.display = "block";
}
});
......@@ -939,9 +907,6 @@ document.getElementById("toggle3DButton").addEventListener("click", function ()
const graphicsLayer = new GraphicsLayer();
map.add(graphicsLayer);
......@@ -1115,74 +1080,6 @@ animateMovingFeatures("https://ogcapi.hft-stuttgart.de/ogc_api_moving_features/c
});
function animateSpaceTimeRoute(url, containerId, trainColor, trainName) {
fetch(url)
.then(response => response.json())
.then(data => {
if (!data || !data.features) {
console.error('Invalid data format:', data);
return;
}
const features = Array.isArray(data.features) ? data.features : [data.features];
const frames = features.map((feature, index) => {
const coordinates = feature.geometry.coordinates;
const timestamps = feature.properties.datetimes;
if (!Array.isArray(coordinates) || !Array.isArray(timestamps)) {
console.error('Invalid feature format:', feature);
return;
}
return {
data: [
{
type: 'scattermapbox',
lat: coordinates.map(coord => coord[1]),
lon: coordinates.map(coord => coord[0]),
mode: 'lines+markers',
marker: { size: 20, color: trainColor },
line: { color: trainColor },
name: `Bus route`,
},
{
type: 'scatter3d',
x: coordinates.map(coord => coord[0]),
y: coordinates.map(coord => coord[1]),
z: timestamps.map((time, i) => new Date(time).toISOString()), // convert to ISO format
mode: 'lines+markers',
line: { color: trainColor },
text: timestamps.map((time) => new Date(time).toLocaleTimeString()), // labels on the points
name: `Bus Space-Time - ${index + 1}`,
},
],
name: `Frame ${index + 1}`,
};
});
// Set the layout with mapbox style and access token
const layout = {
mapbox: {
style: 'light',
center: { lon: features[0].geometry.coordinates[0][0], lat: features[0].geometry.coordinates[0][1] },
zoom: 10,
accesstoken: 'pk.eyJ1IjoicmVkaWV0OTk2MyIsImEiOiJjbHJ1cmk5aGUwaDRvMmpuYWM4Z2NqcmZuIn0.c11HYT-5ucd6g6mL03bp3Q',
},
margin: { t: 0, b: 0, l: 0, r: 0 },
};
// initialize Plotly container
Plotly.newPlot(containerId, frames[0].data, layout);
// adding frames
Plotly.addFrames(containerId, frames);
})
.catch(error => {
console.error('Error fetching data:', error);
});
}
</script>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment