Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
UGL
website
Commits
90443acc
Commit
90443acc
authored
Feb 20, 2024
by
JOE XMG
Browse files
update
parent
4c68f557
Pipeline
#9120
passed with stage
in 19 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
public/udigit4icity/.vscode/settings.json
0 → 100644
View file @
90443acc
{
"liveServer.settings.port"
:
5501
}
\ No newline at end of file
public/udigit4icity/STC.html
0 → 100644
View file @
90443acc
<!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>
public/udigit4icity/index.html
View file @
90443acc
<!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
.
js
delivr.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
:
3
6%
;
height
:
6
5
%
;
width
:
6
0
%
;
height
:
6
0
%
;
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
:
absolut
e
;
top
:
90
%
;
left
:
36
%
;
position
:
relativ
e
;
top
:
72
%
;
left
:
51
%
;
padding
:
5px
;
background-color
:
rgba
(
255
,
255
,
255
,
0.8
);
border-radius
:
5
px
;
border-radius
:
3
px
;
z-index
:
1
;
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -166,11 +202,11 @@
#usage-pie-chart
{
display
:
none
;
width
:
6
00px
;
height
:
4
00px
;
z-index
:
1
;
width
:
4
00px
;
height
:
3
00px
;
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 City
Model
</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(
23
0,
23
0,
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
=>
{