Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Alfakhori
Gengenbach
Commits
d69bf271
Commit
d69bf271
authored
Oct 05, 2026
by
Alfakhori
Browse files
v0.2.0
parent
9ecd2076
Pipeline
#12490
passed with stage
in 26 seconds
Changes
5
Pipelines
1
Show whitespace changes
Inline
Side-by-side
public/ar_download.js
View file @
d69bf271
import
{
showInfoDialog
}
from
'
./ar_main.js
'
;
function
downloadScene
()
{
function
downloadScene
()
{
const
placedModels
=
window
.
getAllPlacedModels
().
map
(
model
=>
{
const
placedModels
=
getAllPlacedModels
().
map
(
model
=>
{
const
{
lat
,
lng
}
=
window
.
threeToLeaflet
(
model
.
position
.
x
,
model
.
position
.
z
);
const
{
lat
,
lng
}
=
threeToLeaflet
(
model
.
position
.
x
,
model
.
position
.
z
);
return
{
return
{
name
:
model
.
modelConfig
.
name
,
name
:
model
.
modelConfig
.
name
,
position
:
model
.
position
,
position
:
model
.
position
,
...
@@ -18,7 +17,6 @@ function downloadScene() {
...
@@ -18,7 +17,6 @@ function downloadScene() {
return
;
return
;
}
}
const
geoLocation
=
window
.
getGeoLocation
();
if
(
!
geoLocation
)
{
if
(
!
geoLocation
)
{
console
.
log
(
"
Standort nicht geladen
"
);
console
.
log
(
"
Standort nicht geladen
"
);
showInfoDialog
(
"
Ihr Standort wurde noch nicht geladen
"
);
showInfoDialog
(
"
Ihr Standort wurde noch nicht geladen
"
);
...
@@ -73,7 +71,3 @@ function loadSceneFromFile(loadedData) {
...
@@ -73,7 +71,3 @@ function loadSceneFromFile(loadedData) {
});
});
fileInput
.
click
();
fileInput
.
click
();
}
}
\ No newline at end of file
/* Expose functions used by the existing HTML and ar_start.js. */
window
.
downloadScene
=
downloadScene
;
window
.
loadSceneFromFile
=
loadSceneFromFile
;
public/ar_main.js
View file @
d69bf271
import
*
as
THREE
from
"
three
"
;
import
{
GLTFLoader
}
from
"
three/addons/loaders/GLTFLoader.js
"
;
/* ========================= */
/* ========================= */
/* GLOBALE VARIABLEN */
/* GLOBALE VARIABLEN */
/* ========================= */
/* ========================= */
...
@@ -9,14 +6,13 @@ let selectedPlacedModel = null;
...
@@ -9,14 +6,13 @@ let selectedPlacedModel = null;
let
currentSession
=
null
;
let
currentSession
=
null
;
let
reticle
=
null
;
let
reticle
=
null
;
let
scene
,
camera
;
let
scene
,
camera
;
let
xrRenderer
=
null
;
let
geoLocation
;
let
geoLocation
;
const
modelCache
=
new
Map
();
const
modelCache
=
new
Map
();
// PERFORMANCE: Reuse one GLTFLoader instead of creating
// PERFORMANCE: Reuse one GLTFLoader instead of creating
// a new loader every time a model is placed.
// a new loader every time a model is placed.
const
gltfLoader
=
new
GLTFLoader
();
const
gltfLoader
=
new
THREE
.
GLTFLoader
();
const
menus
=
[
const
menus
=
[
'
menu-bar
'
,
'
menu-bar
'
,
...
@@ -294,7 +290,7 @@ function closeDynamicMenu() {
...
@@ -294,7 +290,7 @@ function closeDynamicMenu() {
}
}
export
function
showInfoDialog
(
message
)
{
function
showInfoDialog
(
message
)
{
const
infoDialog
=
const
infoDialog
=
document
.
getElementById
(
document
.
getElementById
(
...
@@ -518,14 +514,9 @@ function selectModelFromScene(event) {
...
@@ -518,14 +514,9 @@ function selectModelFromScene(event) {
new
THREE
.
Raycaster
();
new
THREE
.
Raycaster
();
const
rayCamera
=
xrRenderer
&&
xrRenderer
.
xr
.
isPresenting
?
xrRenderer
.
xr
.
getCamera
(
camera
)
:
camera
;
raycaster
.
setFromCamera
(
raycaster
.
setFromCamera
(
mouse
,
mouse
,
rayC
amera
c
amera
);
);
...
@@ -1123,64 +1114,78 @@ function closeMapDialog() {
...
@@ -1123,64 +1114,78 @@ function closeMapDialog() {
async
function
activateXR
(
sceneData
=
null
)
{
async
function
activateXR
(
sceneData
=
null
)
{
const
canvas
=
document
.
createElement
(
"
canvas
"
);
const
canvas
=
document
.
createElement
(
"
canvas
"
);
document
.
body
.
appendChild
(
canvas
);
document
.
body
.
appendChild
(
canvas
);
// Keep the original WebXR rendering architecture.
// Three.js r186 is used only as the renderer/scene library;
// WebXR session, hit-test source, framebuffer and camera pose
// are still controlled explicitly as in the working r126 version.
const
gl
=
canvas
.
getContext
(
"
webgl
"
,
{
const
gl
=
canvas
.
getContext
(
"
webgl
"
,
{
xrCompatible
:
true
,
xrCompatible
:
true
,
alpha
:
true
,
antialias
:
true
,
});
});
if
(
!
gl
)
{
throw
new
Error
(
"
WebGL konnte nicht initialisiert werden.
"
);
}
const
renderer
=
new
THREE
.
WebGLRenderer
({
const
renderer
=
new
THREE
.
WebGLRenderer
({
alpha
:
true
,
alpha
:
true
,
canvas
,
canvas
,
context
:
gl
,
context
:
gl
,
antialias
:
true
,
});
});
renderer
.
autoClear
=
false
;
renderer
.
autoClear
=
false
;
xrRenderer
=
renderer
;
scene
=
new
THREE
.
Scene
();
scene
=
new
THREE
.
Scene
();
camera
=
new
THREE
.
PerspectiveCamera
();
camera
=
new
THREE
.
PerspectiveCamera
();
camera
.
matrixAutoUpdate
=
false
;
camera
.
matrixAutoUpdate
=
false
;
// ========================================================
// AR lighting
// ========================================================
// Soft overall illumination
const
ambientLight
=
new
THREE
.
AmbientLight
(
0xffffff
,
2.5
);
const
ambientLight
=
new
THREE
.
AmbientLight
(
0xffffff
,
2.5
);
scene
.
add
(
ambientLight
);
scene
.
add
(
ambientLight
);
// Sky/ground illumination
const
hemisphereLight
=
new
THREE
.
HemisphereLight
(
0xffffff
,
0x888888
,
1.5
);
const
hemisphereLight
=
new
THREE
.
HemisphereLight
(
0xffffff
,
0x888888
,
1.5
);
scene
.
add
(
hemisphereLight
);
scene
.
add
(
hemisphereLight
);
// Directional light for shadows and form
const
directionalLight
=
new
THREE
.
DirectionalLight
(
0xffffff
,
1.5
);
const
directionalLight
=
new
THREE
.
DirectionalLight
(
0xffffff
,
1.5
);
directionalLight
.
position
.
set
(
10
,
20
,
10
);
directionalLight
.
position
.
set
(
10
,
20
,
10
);
scene
.
add
(
directionalLight
);
scene
.
add
(
directionalLight
);
// ========================================================
// Reticle
// Reticle
const
loader
=
new
GLTFLoader
();
// ========================================================
const
loader
=
new
THREE
.
GLTFLoader
();
loader
.
load
(
loader
.
load
(
"
https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf
"
,
"
https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf
"
,
(
gltf
)
=>
{
(
gltf
)
=>
{
reticle
=
gltf
.
scene
;
reticle
=
gltf
.
scene
;
reticle
.
visible
=
false
;
reticle
.
visible
=
false
;
scene
.
add
(
reticle
);
scene
.
add
(
reticle
);
},
},
undefined
,
(
error
)
=>
console
.
error
(
"
Fehler beim Laden des Reticles:
"
,
error
)
);
);
// WebXR session
// ========================================================
// Start WebXR AR session
// ========================================================
currentSession
=
await
navigator
.
xr
.
requestSession
(
"
immersive-ar
"
,
{
currentSession
=
await
navigator
.
xr
.
requestSession
(
"
immersive-ar
"
,
{
requiredFeatures
:
[
"
hit-test
"
],
optionalFeatures
:
[
"
dom-overlay
"
],
optionalFeatures
:
[
"
dom-overlay
"
],
domOverlay
:
{
root
:
document
.
body
},
domOverlay
:
{
root
:
document
.
body
,
},
requiredFeatures
:
[
"
hit-test
"
],
});
});
currentSession
.
updateRenderState
({
currentSession
.
updateRenderState
({
...
@@ -1188,131 +1193,168 @@ async function activateXR(sceneData = null) {
...
@@ -1188,131 +1193,168 @@ async function activateXR(sceneData = null) {
});
});
const
referenceSpace
=
await
currentSession
.
requestReferenceSpace
(
"
local
"
);
const
referenceSpace
=
await
currentSession
.
requestReferenceSpace
(
"
local
"
);
const
viewerSpace
=
await
currentSession
.
requestReferenceSpace
(
"
viewer
"
);
const
viewerSpace
=
await
currentSession
.
requestReferenceSpace
(
"
viewer
"
);
const
hitTestSource
=
await
currentSession
.
requestHitTestSource
({
const
hitTestSource
=
await
currentSession
.
requestHitTestSource
({
space
:
viewerSpace
,
space
:
viewerSpace
,
});
});
// ========================================================
// Show main menu
// ========================================================
document
.
getElementById
(
"
menu-bar
"
).
style
.
display
=
"
flex
"
;
document
.
getElementById
(
"
menu-bar
"
).
style
.
display
=
"
flex
"
;
// ========================================================
// AR session ended
// Reload the complete website
// ========================================================
currentSession
.
addEventListener
(
"
end
"
,
()
=>
{
currentSession
.
addEventListener
(
"
end
"
,
()
=>
{
console
.
log
(
"
AR session ended
"
);
console
.
log
(
"
AR session ended
"
);
// Completely reload the website.
// This resets the AR canvas, menus, scene, map,
// variables, and all other application state.
window
.
location
.
reload
();
window
.
location
.
reload
();
});
});
// ========================================================
// Select objects in AR
// ========================================================
canvas
.
addEventListener
(
"
pointerdown
"
,
selectModelFromScene
);
canvas
.
addEventListener
(
"
pointerdown
"
,
selectModelFromScene
);
// ========================================================
// Geolocation
// Geolocation
// ========================================================
if
(
navigator
.
geolocation
)
{
if
(
navigator
.
geolocation
)
{
navigator
.
geolocation
.
getCurrentPosition
(
navigator
.
geolocation
.
getCurrentPosition
(
(
position
)
=>
{
(
position
)
=>
{
geoLocation
=
{
geoLocation
=
{
latitude
:
window
.
roundTo
(
position
.
coords
.
latitude
,
5
),
latitude
:
roundTo
(
position
.
coords
.
latitude
,
5
),
longitude
:
window
.
roundTo
(
position
.
coords
.
longitude
,
5
),
longitude
:
roundTo
(
position
.
coords
.
longitude
,
5
),
};
};
console
.
log
(
"
GeoLocation:
"
+
JSON
.
stringify
(
geoLocation
));
console
.
log
(
"
GeoLocation:
"
+
JSON
.
stringify
(
geoLocation
));
if
(
sceneData
&&
Array
.
isArray
(
sceneData
.
models
))
{
// =================================================
scene
Data
.
models
.
forEach
((
model
)
=>
{
// Load saved
scene
models
if
(
!
model
.
name
)
return
;
// =================================================
if
(
sceneData
)
{
sceneData
.
models
.
forEach
((
model
)
=>
{
if
(
model
.
name
)
{
const
modelDefinition
=
Object
.
values
(
models
).
find
(
const
modelDefinition
=
Object
.
values
(
models
).
find
(
(
m
)
=>
model
.
name
===
m
.
name
(
m
)
=>
model
.
name
===
m
.
name
,
);
);
if
(
!
modelDefinition
)
{
if
(
!
modelDefinition
)
{
console
.
error
(
"
Modell nicht gefunden:
"
,
model
.
name
);
console
.
error
(
"
Modell nicht gefunden:
"
,
model
.
name
);
return
;
return
;
}
}
const
{
x
,
z
}
=
window
.
leafletToThree
(
model
.
lat
,
model
.
lng
);
const
filePath
=
modelDefinition
.
file
;
const
positionVector
=
new
THREE
.
Vector3
(
x
,
const
{
x
,
z
}
=
leafletToThree
(
model
.
lat
,
model
.
lng
);
model
.
position
?.
y
??
0
,
z
const
positionVector
=
new
THREE
.
Vector3
(
x
,
model
.
position
.
y
,
z
);
);
placeModel
(
modelDefinition
.
file
,
positionVector
,
(
placed
)
=>
{
placeModel
(
file
Path
,
positionVector
,
(
placed
)
=>
{
if
(
model
.
rotation
)
{
if
(
model
.
rotation
)
{
placed
.
rotation
.
set
(
placed
.
rotation
.
_x
=
model
.
rotation
.
_x
;
model
.
rotation
.
_x
??
model
.
rotation
.
x
??
0
,
model
.
rotation
.
_y
??
model
.
rotation
.
y
??
0
,
placed
.
rotation
.
_y
=
model
.
rotation
.
_y
;
model
.
rotation
.
_z
??
model
.
rotation
.
z
??
0
)
;
placed
.
rotation
.
_z
=
model
.
rotation
.
_z
;
}
}
if
(
model
.
scale
)
{
if
(
model
.
scale
)
{
placed
.
scale
.
set
(
placed
.
scale
.
x
=
model
.
scale
.
x
;
model
.
scale
.
x
,
model
.
scale
.
y
,
placed
.
scale
.
y
=
model
.
scale
.
y
;
model
.
scale
.
z
)
;
placed
.
scale
.
z
=
model
.
scale
.
z
;
}
}
});
});
}
});
});
}
}
},
},
(
error
)
=>
{
(
error
)
=>
{
console
.
error
(
"
Fehler bei der Geolokalisierung:
"
,
error
);
console
.
error
(
"
Fehler bei der Geolokalisierung:
"
,
JSON
.
stringify
(
error
),
);
},
},
{
{
enableHighAccuracy
:
true
,
enableHighAccuracy
:
true
,
maximumAge
:
2000
,
maximumAge
:
2000
,
timeout
:
5000
,
timeout
:
5000
,
}
}
,
);
);
}
}
// ========================================================
// XR render loop
// ========================================================
// Keep the original explicit XR frame loop.
currentSession
.
requestAnimationFrame
(
function
onXRFrame
(
time
,
frame
)
{
currentSession
.
requestAnimationFrame
(
function
onXRFrame
(
time
,
frame
)
{
currentSession
.
requestAnimationFrame
(
onXRFrame
);
currentSession
.
requestAnimationFrame
(
onXRFrame
);
const
session
=
frame
.
session
;
gl
.
bindFramebuffer
(
const
baseLayer
=
session
.
renderState
.
baseLayer
;
gl
.
FRAMEBUFFER
,
currentSession
.
renderState
.
baseLayer
.
framebuffer
,
if
(
!
baseLayer
)
return
;
);
gl
.
bindFramebuffer
(
gl
.
FRAMEBUFFER
,
baseLayer
.
framebuffer
);
const
pose
=
frame
.
getViewerPose
(
referenceSpace
);
const
pose
=
frame
.
getViewerPose
(
referenceSpace
);
if
(
!
pose
)
return
;
// This application uses one camera/view, as in the original version.
if
(
pose
)
{
const
view
=
pose
.
views
[
0
];
const
view
=
pose
.
views
[
0
];
const
viewport
=
baseLayer
.
getViewport
(
view
);
if
(
!
viewport
)
return
;
const
viewport
=
currentSession
.
renderState
.
baseLayer
.
getViewport
(
view
);
renderer
.
setViewport
(
renderer
.
setSize
(
viewport
.
width
,
viewport
.
height
);
viewport
.
x
,
viewport
.
y
,
viewport
.
width
,
viewport
.
height
);
camera
.
matrix
.
fromArray
(
view
.
transform
.
matrix
);
camera
.
matrix
.
fromArray
(
view
.
transform
.
matrix
);
camera
.
projectionMatrix
.
fromArray
(
view
.
projectionMatrix
);
camera
.
projectionMatrix
.
fromArray
(
view
.
projectionMatrix
);
camera
.
updateMatrixWorld
(
true
);
camera
.
updateMatrixWorld
(
true
);
// =================================================
// Hit testing
// =================================================
const
hitTestResults
=
frame
.
getHitTestResults
(
hitTestSource
);
const
hitTestResults
=
frame
.
getHitTestResults
(
hitTestSource
);
if
(
hitTestResults
.
length
>
0
)
{
if
(
hitTestResults
.
length
>
0
)
{
const
hitPose
=
hitTestResults
[
0
].
getPose
(
referenceSpace
);
const
hitPose
=
hitTestResults
[
0
].
getPose
(
referenceSpace
);
if
(
hitPose
&&
reticle
)
{
reticle
.
visible
=
true
;
reticle
.
visible
=
true
;
reticle
.
position
.
set
(
reticle
.
position
.
set
(
hitPose
.
transform
.
position
.
x
,
hitPose
.
transform
.
position
.
x
,
hitPose
.
transform
.
position
.
y
,
hitPose
.
transform
.
position
.
y
,
hitPose
.
transform
.
position
.
z
hitPose
.
transform
.
position
.
z
,
);
);
reticle
.
updateMatrixWorld
(
true
);
reticle
.
updateMatrixWorld
(
true
);
}
}
}
else
if
(
reticle
)
{
reticle
.
visible
=
false
;
// =================================================
}
// Render AR scene
// =================================================
renderer
.
render
(
scene
,
camera
);
renderer
.
render
(
scene
,
camera
);
}
});
});
}
}
...
@@ -1353,34 +1395,3 @@ function playButtonSound() {
...
@@ -1353,34 +1395,3 @@ function playButtonSound() {
},
200
);
},
200
);
}
}
}
}
\ No newline at end of file
window
.
selectModel
=
selectModel
;
window
.
updateRotation
=
updateRotation
;
window
.
updateScale
=
updateScale
;
window
.
updateMoveDelta
=
updateMoveDelta
;
window
.
moveModelDynamic
=
moveModelDynamic
;
window
.
closeDynamicMenu
=
closeDynamicMenu
;
/* ============================================================
GLOBAL API BRIDGE
------------------------------------------------------------
ES modules have their own scope. The existing HTML UI uses
inline onclick handlers, so expose the existing application
functions explicitly on window.
============================================================ */
window
.
showMenu
=
showMenu
;
window
.
openRotationMenu
=
openRotationMenu
;
window
.
openScaleMenu
=
openScaleMenu
;
window
.
openMoveMenu
=
openMoveMenu
;
window
.
deleteModel
=
deleteModel
;
window
.
completeEditing
=
completeEditing
;
window
.
confirmDelete
=
confirmDelete
;
window
.
exitAR
=
exitAR
;
window
.
confirmExit
=
confirmExit
;
window
.
closeInfoDialog
=
closeInfoDialog
;
window
.
getAllPlacedModels
=
getAllPlacedModels
;
window
.
activateXR
=
activateXR
;
window
.
getXRRenderCamera
=
()
=>
camera
;
window
.
getGeoLocation
=
()
=>
geoLocation
;
public/ar_overviewmap.js
View file @
d69bf271
import
*
as
THREE
from
"
three
"
;
let
init
=
false
;
let
init
=
false
;
let
mymap
;
let
mymap
;
let
userIcon
;
let
userIcon
;
...
@@ -100,7 +98,7 @@ function init_map() {
...
@@ -100,7 +98,7 @@ function init_map() {
// Add currently placed models to map
// Add currently placed models to map
// ========================================================
// ========================================================
const
models
=
window
.
getAllPlacedModels
();
const
models
=
getAllPlacedModels
();
models
.
forEach
((
model
)
=>
{
models
.
forEach
((
model
)
=>
{
const
{
lat
,
lng
}
=
threeToLeaflet
(
model
.
position
.
x
,
model
.
position
.
z
);
const
{
lat
,
lng
}
=
threeToLeaflet
(
model
.
position
.
x
,
model
.
position
.
z
);
...
@@ -212,12 +210,7 @@ function updateMap() {
...
@@ -212,12 +210,7 @@ function updateMap() {
}
}
// PERFORMANCE: Reuse the same Vector3 object.
// PERFORMANCE: Reuse the same Vector3 object.
const
activeCamera
=
camera
.
getWorldPosition
(
cameraPosition
);
typeof
window
.
getXRRenderCamera
===
"
function
"
?
window
.
getXRRenderCamera
()
:
camera
;
activeCamera
.
getWorldPosition
(
cameraPosition
);
// PERFORMANCE: Do not update Leaflet if the user
// PERFORMANCE: Do not update Leaflet if the user
// has not moved.
// has not moved.
...
@@ -330,11 +323,3 @@ function roundTo(n, digits) {
...
@@ -330,11 +323,3 @@ function roundTo(n, digits) {
return
parseFloat
(
n
);
return
parseFloat
(
n
);
}
}
/* Expose map functions needed by the other application modules. */
window
.
init_map
=
init_map
;
window
.
centerOnPlan
=
centerOnPlan
;
window
.
threeToLeaflet
=
threeToLeaflet
;
window
.
leafletToThree
=
leafletToThree
;
window
.
roundTo
=
roundTo
;
public/ar_start.js
View file @
d69bf271
import
{
activateXR
}
from
'
./ar_main.js
'
;
import
{
loadSceneFromFile
}
from
'
./ar_download.js
'
;
/* ========================= */
/* ========================= */
/* DEBUGGING UND START */
/* DEBUGGING UND START */
/* ========================= */
/* ========================= */
...
@@ -192,7 +190,7 @@ function showStartScreen() {
...
@@ -192,7 +190,7 @@ function showStartScreen() {
predefinedButton2
=
null
;
predefinedButton2
=
null
;
// Start AR
// Start AR
window
.
window
.
activateXR
(
sceneData
);
activateXR
(
sceneData
);
};
};
/* ==========================================================
/* ==========================================================
...
@@ -200,7 +198,7 @@ function showStartScreen() {
...
@@ -200,7 +198,7 @@ function showStartScreen() {
========================================================== */
========================================================== */
loadButton
.
onclick
=
()
=>
{
loadButton
.
onclick
=
()
=>
{
window
.
window
.
loadSceneFromFile
((
data
,
fileName
)
=>
{
loadSceneFromFile
((
data
,
fileName
)
=>
{
if
(
data
&&
fileName
)
{
if
(
data
&&
fileName
)
{
sceneData
=
data
;
sceneData
=
data
;
sceneFileName
=
fileName
;
sceneFileName
=
fileName
;
...
...
public/index.html
View file @
d69bf271
...
@@ -9,15 +9,8 @@
...
@@ -9,15 +9,8 @@
<link
rel=
"stylesheet"
href=
"style.css"
>
<link
rel=
"stylesheet"
href=
"style.css"
>
<!-- Three.js (modern ES module setup) -->
<script
src=
"https://unpkg.com/three@0.126.0/build/three.js"
></script>
<script
type=
"importmap"
>
<script
src=
"https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"
></script>
{
"
imports
"
:
{
"
three
"
:
"
https://unpkg.com/three@0.186.0/build/three.module.js
"
,
"
three/addons/
"
:
"
https://unpkg.com/three@0.186.0/examples/jsm/
"
}
}
</script>
</head>
</head>
<body>
<body>
...
@@ -306,7 +299,7 @@
...
@@ -306,7 +299,7 @@
============================================================ -->
============================================================ -->
<div
id=
"app-version"
>
<div
id=
"app-version"
>
v
186.
0.2
v0.2
.0
</div>
</div>
...
@@ -314,7 +307,10 @@
...
@@ -314,7 +307,10 @@
JAVASCRIPT
JAVASCRIPT
============================================================ -->
============================================================ -->
<!-- Debug console loads first so it can capture module errors/logs -->
<script
src=
"ar_start.js"
></script>
<script
src=
"ar_main.js"
></script>
<script
src=
"ar_debug_console.js"
></script>
<script
src=
"ar_debug_console.js"
></script>
<link
<link
...
@@ -323,13 +319,9 @@
...
@@ -323,13 +319,9 @@
<script
src=
"https://unpkg.com/leaflet/dist/leaflet.js"
></script>
<script
src=
"https://unpkg.com/leaflet/dist/leaflet.js"
></script>
<!-- Application modules -->
<script
src=
"ar_overviewmap.js"
></script>
<script
type=
"module"
src=
"ar_main.js"
></script>
<script
type=
"module"
src=
"ar_overviewmap.js"
></script>
<script
type=
"module"
src=
"ar_download.js"
></script>
<script
type=
"module"
src=
"ar_start.js"
></script>
<script
src=
"ar_download.js"
></script>
<!-- ============================================================
<!-- ============================================================
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment