itowns 2.36.2 → 2.38.1
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/CONTRIBUTING.md +30 -17
- package/README.md +12 -1
- package/changelog.md +138 -0
- package/dist/debug.js +1 -1
- package/dist/debug.js.LICENSE.txt +2 -2
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.LICENSE.txt +2 -2
- package/dist/itowns.js.map +1 -1
- package/dist/itowns_widgets.js +2 -0
- package/dist/itowns_widgets.js.map +1 -0
- package/examples/config.json +28 -6
- package/examples/css/example.css +21 -1
- package/examples/css/widgets.css +360 -0
- package/examples/geoid_geoidLayer.html +102 -0
- package/examples/images/code-logo.svg +43 -0
- package/examples/index.html +5 -5
- package/examples/itowns-potree.html +252 -0
- package/examples/js/GUI/GuiTools.js +17 -0
- package/examples/mars.html +0 -1
- package/examples/misc_orthographic_camera.html +7 -19
- package/examples/source_file_from_fetched_data.html +90 -0
- package/examples/source_file_from_format.html +85 -0
- package/examples/source_file_from_methods.html +87 -0
- package/examples/source_file_from_parsed_data.html +104 -0
- package/examples/source_file_geojson_raster.html +21 -45
- package/examples/source_file_gpx_raster.html +28 -36
- package/examples/source_file_kml_raster.html +1 -4
- package/examples/source_file_shapefile.html +39 -34
- package/examples/source_stream_wfs_25d.html +21 -13
- package/examples/source_stream_wfs_3d.html +21 -12
- package/examples/source_stream_wfs_raster.html +20 -20
- package/examples/vector_tile_3d_mesh.html +155 -0
- package/examples/vector_tile_raster_3d.html +0 -5
- package/examples/view_25d_map.html +6 -19
- package/examples/view_2d_map.html +6 -19
- package/examples/view_3d_map.html +106 -81
- package/examples/view_immersive.html +13 -14
- package/examples/widgets_minimap.html +124 -0
- package/examples/widgets_navigation.html +124 -0
- package/examples/widgets_scale.html +96 -0
- package/examples/widgets_searchbar.html +124 -0
- package/lib/Controls/GlobeControls.js +13 -0
- package/lib/Controls/PlanarControls.js +11 -43
- package/lib/Converter/Feature2Mesh.js +203 -45
- package/lib/Converter/convertToTile.js +13 -4
- package/lib/Core/3DTiles/C3DTBoundingVolume.js +4 -1
- package/lib/Core/Deprecated/Undeprecator.js +1 -1
- package/lib/Core/Feature.js +60 -34
- package/lib/Core/Geographic/Extent.js +1 -1
- package/lib/Core/Geographic/GeoidGrid.js +143 -0
- package/lib/Core/MainLoop.js +137 -63
- package/lib/Core/Math/Ellipsoid.js +1 -1
- package/lib/Core/Prefab/Globe/SkyShader.js +3 -1
- package/lib/Core/Prefab/Planar/PlanarLayer.js +3 -1
- package/lib/Core/Style.js +1 -1
- package/lib/Core/TileGeometry.js +3 -1
- package/lib/Core/TileMesh.js +32 -22
- package/lib/Core/View.js +81 -15
- package/lib/Layer/ElevationLayer.js +6 -2
- package/lib/Layer/FeatureGeometryLayer.js +36 -7
- package/lib/Layer/GeoidLayer.js +142 -0
- package/lib/Layer/GeometryLayer.js +6 -54
- package/lib/Layer/InfoLayer.js +1 -1
- package/lib/Layer/Layer.js +1 -1
- package/lib/Layer/LayerUpdateStrategy.js +1 -1
- package/lib/Layer/OrientedImageLayer.js +1 -0
- package/lib/Layer/PotreeLayer.js +3 -1
- package/lib/Layer/RasterLayer.js +3 -1
- package/lib/Layer/ReferencingLayerProperties.js +50 -0
- package/lib/Layer/TiledGeometryLayer.js +3 -1
- package/lib/Main.js +214 -174
- package/lib/MainBundle.js +1 -1
- package/lib/Parser/B3dmParser.js +5 -3
- package/lib/Parser/GDFParser.js +118 -0
- package/lib/Parser/GTXParser.js +92 -0
- package/lib/Parser/GeoJsonParser.js +29 -7
- package/lib/Parser/ISGParser.js +121 -0
- package/lib/Parser/LASParser.js +3 -1
- package/lib/Parser/VectorTileParser.js +4 -3
- package/lib/Parser/XbilParser.js +1 -1
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +1 -1
- package/lib/Process/3dTilesProcessing.js +2 -2
- package/lib/Process/FeatureProcessing.js +38 -86
- package/lib/Process/LayeredMaterialNodeProcessing.js +16 -7
- package/lib/Process/ObjectRemovalHelper.js +4 -0
- package/lib/Provider/3dTilesProvider.js +2 -7
- package/lib/Provider/Fetcher.js +4 -1
- package/lib/Provider/TileProvider.js +18 -2
- package/lib/Provider/URLBuilder.js +1 -1
- package/lib/Renderer/Camera.js +33 -12
- package/lib/Renderer/ColorLayersOrdering.js +3 -1
- package/lib/Renderer/LayeredMaterial.js +34 -9
- package/lib/Renderer/OBB.js +22 -25
- package/lib/Renderer/OrientedImageMaterial.js +8 -5
- package/lib/Renderer/PointsMaterial.js +6 -6
- package/lib/Renderer/RasterTile.js +1 -1
- package/lib/Renderer/RenderMode.js +3 -1
- package/lib/Renderer/Shader/ShaderChunk.js +5 -1
- package/lib/Renderer/Shader/ShaderUtils.js +4 -2
- package/lib/Renderer/c3DEngine.js +9 -6
- package/lib/Source/C3DTilesSource.js +3 -1
- package/lib/Source/EntwinePointTileSource.js +3 -1
- package/lib/Source/FileSource.js +8 -1
- package/lib/Source/PotreeSource.js +3 -1
- package/lib/Source/Source.js +15 -10
- package/lib/Source/VectorTilesSource.js +5 -0
- package/lib/Source/WFSSource.js +9 -3
- package/lib/Source/WMTSSource.js +3 -1
- package/lib/ThreeExtended/{WebGL.js → capabilities/WebGL.js} +8 -7
- package/lib/ThreeExtended/loaders/GLTFLoader.js +88 -39
- package/lib/Utils/CameraUtils.js +11 -1
- package/lib/Utils/DEMUtils.js +4 -2
- package/lib/Utils/FeaturesUtils.js +8 -4
- package/lib/Utils/gui/Main.js +39 -0
- package/lib/Utils/gui/Minimap.js +197 -0
- package/lib/Utils/gui/Navigation.js +322 -0
- package/lib/Utils/gui/Scale.js +154 -0
- package/lib/Utils/gui/Searchbar.js +299 -0
- package/lib/Utils/gui/Widget.js +119 -0
- package/package.json +32 -27
- package/examples/js/Scale.js +0 -40
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Itowns - Globe + vector-tiles 3d</title>
|
|
4
|
+
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="css/example.css">
|
|
9
|
+
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
|
|
10
|
+
<link rel="stylesheet" type="text/css" href="css/widgets.css">
|
|
11
|
+
|
|
12
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div id="viewerDiv"></div>
|
|
16
|
+
|
|
17
|
+
<!-- Import iTowns source code -->
|
|
18
|
+
<script src="../dist/itowns.js"></script>
|
|
19
|
+
<script src="../dist/debug.js"></script>
|
|
20
|
+
<!-- Import iTowns LoadingScreen and GuiTools plugins -->
|
|
21
|
+
<script src="js/GUI/GuiTools.js"></script>
|
|
22
|
+
<script src="js/GUI/LoadingScreen.js"></script>
|
|
23
|
+
|
|
24
|
+
<script type="text/javascript">
|
|
25
|
+
|
|
26
|
+
// ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
|
|
27
|
+
|
|
28
|
+
// Define camera initial position
|
|
29
|
+
const placement = {
|
|
30
|
+
coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
|
|
31
|
+
range: 5000,
|
|
32
|
+
tilt: 45,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// `viewerDiv` will contain iTowns' rendering area (`<canvas>`)
|
|
36
|
+
const viewerDiv = document.getElementById('viewerDiv');
|
|
37
|
+
|
|
38
|
+
// Create a GlobeView
|
|
39
|
+
const view = new itowns.GlobeView(viewerDiv, placement);
|
|
40
|
+
|
|
41
|
+
// Define poles texture
|
|
42
|
+
view.tileLayer.noTextureColor = new itowns.THREE.Color(0x95c1e1);
|
|
43
|
+
|
|
44
|
+
// Disable atmosphere lighting
|
|
45
|
+
view.getLayerById('atmosphere').visible = false;
|
|
46
|
+
view.getLayerById('atmosphere').fog.enable = false;
|
|
47
|
+
|
|
48
|
+
// Setup loading screen and debug menu
|
|
49
|
+
setupLoadingScreen(viewerDiv, view);
|
|
50
|
+
const debugMenu = new GuiTools('menuDiv', view, 300);
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// ---------- DISPLAY CONTEXTUAL DATA : ----------
|
|
55
|
+
|
|
56
|
+
// Add two elevation layers, each with a different level of detail. Each layer's properties are defined in
|
|
57
|
+
// a json file.
|
|
58
|
+
function addElevationLayerFromConfig(config) {
|
|
59
|
+
config.source = new itowns.WMTSSource(config.source);
|
|
60
|
+
view.addLayer(
|
|
61
|
+
new itowns.ElevationLayer(config.id, config),
|
|
62
|
+
).then(debugMenu.addLayerGUI.bind(debugMenu));
|
|
63
|
+
}
|
|
64
|
+
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
|
|
65
|
+
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
|
|
66
|
+
|
|
67
|
+
// ---------- DISPLAY VECTOR TILED MAP DATA AS A ColorLayer : ----------
|
|
68
|
+
|
|
69
|
+
// Define the source of the ColorLayer data : a vector tiled map from the geoportail.
|
|
70
|
+
const mapSource = new itowns.VectorTilesSource({
|
|
71
|
+
style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
|
|
72
|
+
// We don't display mountains and parcels related data to ease visualisation. Also, we don't display
|
|
73
|
+
// buildings related data as it will be displayed in another Layer.
|
|
74
|
+
filter: (layer) => {
|
|
75
|
+
return !layer['source-layer'].includes('bati_surf')
|
|
76
|
+
&& !layer['source-layer'].includes('oro_')
|
|
77
|
+
&& !layer['source-layer'].includes('routier_ponc')
|
|
78
|
+
&& !layer['source-layer'].includes('parcellaire')
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Create a ColorLayer to support map data.
|
|
83
|
+
const mapLayer = new itowns.ColorLayer('MVT', {
|
|
84
|
+
source: mapSource,
|
|
85
|
+
effect_type: itowns.colorLayerEffects.removeLightColor,
|
|
86
|
+
effect_parameter: 2.5,
|
|
87
|
+
addLabelLayer: true,
|
|
88
|
+
style: new itowns.Style({
|
|
89
|
+
text: {
|
|
90
|
+
color: '#000000',
|
|
91
|
+
haloColor: '#ffffff',
|
|
92
|
+
haloWidth: 3,
|
|
93
|
+
haloBlur: 2,
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Add the ColorLayer to the scene and to the debug menu.
|
|
99
|
+
view.addLayer(mapLayer).then(debugMenu.addLayerGUI.bind(debugMenu));
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
// ---------- DISPLAY ORTHO-IMAGES : ----------
|
|
103
|
+
|
|
104
|
+
const ortho = itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
|
|
105
|
+
config.source = new itowns.WMTSSource(config.source);
|
|
106
|
+
var layer = new itowns.ColorLayer('Ortho', config);
|
|
107
|
+
return view.addLayer(layer);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ---------- DISPLAY VECTOR TILED BUILDING DATA AS 3D MESHES : ----------
|
|
111
|
+
|
|
112
|
+
// Define the source of the building data : those are vector tiled data from the geoportail.
|
|
113
|
+
const buildingsSource = new itowns.VectorTilesSource({
|
|
114
|
+
style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
|
|
115
|
+
// We only want to display buildings related data.
|
|
116
|
+
filter: (layer) => {
|
|
117
|
+
return layer['source-layer'].includes('bati_surf')
|
|
118
|
+
&& layer.paint["fill-color"];
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Create a FeatureGeometryLayer to support building data.
|
|
123
|
+
var buildingsLayer = new itowns.FeatureGeometryLayer('VTBuilding',{
|
|
124
|
+
source: buildingsSource,
|
|
125
|
+
zoom: { min: 15 },
|
|
126
|
+
accurate: false,
|
|
127
|
+
style: new itowns.Style({
|
|
128
|
+
fill: {
|
|
129
|
+
base_altitude: (p) => p.alti_sol || 0,
|
|
130
|
+
extrusion_height: (p) => p.hauteur || 0,
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Add the FeatureGeometryLayer to the scene and to the debug menu.
|
|
136
|
+
view.addLayer(buildingsLayer).then((layer) => {
|
|
137
|
+
const gui = debug.GeometryDebug.createGeometryDebugUI(debugMenu.gui, view, layer);
|
|
138
|
+
debug.GeometryDebug.addWireFrameCheckbox(gui, view, layer);
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// ---------- DEBUG TOOLS : ----------
|
|
144
|
+
|
|
145
|
+
debug.createTileDebugUI(debugMenu.gui, view);
|
|
146
|
+
|
|
147
|
+
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, function () {
|
|
148
|
+
ortho.then(function () {
|
|
149
|
+
itowns.ColorLayersOrdering.moveLayerToIndex(view, 'Ortho', 0);
|
|
150
|
+
}).catch(console.error);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
</script>
|
|
154
|
+
</body>
|
|
155
|
+
</html>
|
|
@@ -47,11 +47,6 @@
|
|
|
47
47
|
return view.addLayer(layer);
|
|
48
48
|
}));
|
|
49
49
|
|
|
50
|
-
// Add a vector tile layer
|
|
51
|
-
function inter(z) {
|
|
52
|
-
return z - (z % 5);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
50
|
// Define a VectorTilesSource to load Vector Tiles data from the geoportail
|
|
56
51
|
var mvtSource = new itowns.VectorTilesSource({
|
|
57
52
|
style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<link rel="stylesheet" type="text/css" href="css/example.css">
|
|
7
7
|
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="css/widgets.css">
|
|
8
9
|
|
|
9
10
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10
11
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
|
|
@@ -23,13 +24,12 @@
|
|
|
23
24
|
</ul>
|
|
24
25
|
</div>
|
|
25
26
|
<div id="viewerDiv" class="viewer"></div>
|
|
26
|
-
<span id="divScaleWidget"> Scale </span>
|
|
27
27
|
|
|
28
28
|
<script src="../dist/itowns.js"></script>
|
|
29
29
|
<script src="js/GUI/LoadingScreen.js"></script>
|
|
30
30
|
<script src="../dist/debug.js"></script>
|
|
31
|
+
<script src="../dist/itowns_widgets.js"></script>
|
|
31
32
|
<script src="js/GUI/GuiTools.js"></script>
|
|
32
|
-
<script src="js/Scale.js"></script>
|
|
33
33
|
<script type="text/javascript">
|
|
34
34
|
// Define crs projection that we will use (taken from https://epsg.io/3946, Proj4js section)
|
|
35
35
|
itowns.proj4.defs('EPSG:3946', '+proj=lcc +lat_1=45.25 +lat_2=46.75 +lat_0=46 +lon_0=3 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
|
|
@@ -125,23 +125,10 @@
|
|
|
125
125
|
|
|
126
126
|
view.addLayer(wfsCartoLayer);
|
|
127
127
|
|
|
128
|
-
//
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
let computedScale = roundPixelsFromMeters(view, initialScaleSize);
|
|
133
|
-
let format = getMetersUnit(computedScale.meters);
|
|
134
|
-
divScaleWidget.innerHTML = `${format.distance} ${format.unit}`;
|
|
135
|
-
divScaleWidget.style.width = `${computedScale.pixels}`;
|
|
136
|
-
}
|
|
137
|
-
// Updates scale when needed :
|
|
138
|
-
view.addEventListener(itowns.VIEW_EVENTS.INITIALIZED, function () {
|
|
139
|
-
// eslint-disable-next-line no-console
|
|
140
|
-
console.info('view initialized');
|
|
141
|
-
updateScaleWidget();
|
|
142
|
-
});
|
|
143
|
-
view.addEventListener(itowns.PLANAR_CONTROL_EVENT.MOVED, function () {
|
|
144
|
-
updateScaleWidget();
|
|
128
|
+
// Add a scale :
|
|
129
|
+
const scale = new itowns_widgets.Scale(view, {
|
|
130
|
+
position: 'bottom-right',
|
|
131
|
+
translate: { x: -70 },
|
|
145
132
|
});
|
|
146
133
|
|
|
147
134
|
// Request redraw
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<link rel="stylesheet" type="text/css" href="css/example.css">
|
|
7
7
|
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="css/widgets.css">
|
|
8
9
|
|
|
9
10
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10
11
|
</head>
|
|
11
12
|
<body>
|
|
12
13
|
<div id="viewerDiv"></div>
|
|
13
|
-
<span id="divScaleWidget"> Scale </span>
|
|
14
14
|
|
|
15
15
|
<script src="../dist/itowns.js"></script>
|
|
16
|
+
<script src="../dist/itowns_widgets.js"></script>
|
|
16
17
|
<script src="js/GUI/LoadingScreen.js"></script>
|
|
17
|
-
<script src="js/Scale.js"></script>
|
|
18
18
|
<script type="text/javascript">
|
|
19
19
|
// # Orthographic viewer
|
|
20
20
|
|
|
@@ -67,24 +67,11 @@
|
|
|
67
67
|
|
|
68
68
|
view.addLayer(opensmLayer);
|
|
69
69
|
|
|
70
|
-
//
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
let computedScale = roundPixelsFromMeters(view, initialScaleSize);
|
|
75
|
-
let format = getMetersUnit(computedScale.meters);
|
|
76
|
-
divScaleWidget.innerHTML = `${format.distance} ${format.unit}`;
|
|
77
|
-
divScaleWidget.style.width = `${computedScale.pixels}`;
|
|
78
|
-
}
|
|
79
|
-
// Updates scale when needed :
|
|
80
|
-
view.addEventListener(itowns.VIEW_EVENTS.INITIALIZED, function () {
|
|
81
|
-
// eslint-disable-next-line no-console
|
|
82
|
-
console.info('View initialized');
|
|
83
|
-
updateScaleWidget();
|
|
70
|
+
// Add a scale :
|
|
71
|
+
const scale = new itowns_widgets.Scale(view, {
|
|
72
|
+
position: 'bottom-right',
|
|
73
|
+
translate: { x: -70 },
|
|
84
74
|
});
|
|
85
|
-
view.addEventListener(itowns.PLANAR_CONTROL_EVENT.MOVED, function () {
|
|
86
|
-
updateScaleWidget();
|
|
87
|
-
})
|
|
88
75
|
|
|
89
76
|
// Request redraw
|
|
90
77
|
view.notifyChange();
|
|
@@ -3,130 +3,155 @@
|
|
|
3
3
|
<title>Itowns - Globe</title>
|
|
4
4
|
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
|
|
6
8
|
<link rel="stylesheet" type="text/css" href="css/example.css">
|
|
7
9
|
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
|
|
10
|
+
<link rel="stylesheet" type="text/css" href="css/widgets.css">
|
|
8
11
|
|
|
9
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10
12
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
|
|
11
13
|
</head>
|
|
12
14
|
<body>
|
|
13
15
|
<div id="viewerDiv"></div>
|
|
14
|
-
<span id="divScaleWidget"> Scale </span>
|
|
15
|
-
<div id="miniDiv"></div>
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
<!-- Import iTowns source code -->
|
|
18
18
|
<script src="../dist/itowns.js"></script>
|
|
19
|
-
<script src="js/GUI/LoadingScreen.js"></script>
|
|
20
19
|
<script src="../dist/debug.js"></script>
|
|
20
|
+
<!-- Import iTowns Widgets plugin -->
|
|
21
|
+
<script src="../dist/itowns_widgets.js"></script>
|
|
22
|
+
<!-- Import iTowns LoadingScreen and GuiTools plugins -->
|
|
23
|
+
<script src="js/GUI/GuiTools.js"></script>
|
|
24
|
+
<script src="js/GUI/LoadingScreen.js"></script>
|
|
25
|
+
|
|
26
|
+
|
|
21
27
|
<script type="text/javascript">
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
|
|
32
|
+
|
|
33
|
+
// Define camera initial position
|
|
34
|
+
const placement = {
|
|
25
35
|
coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
|
|
26
36
|
range: 25000000,
|
|
27
37
|
}
|
|
28
|
-
var miniView;
|
|
29
|
-
var minDistance = 10000000;
|
|
30
|
-
var maxDistance = 30000000;
|
|
31
38
|
|
|
32
39
|
// `viewerDiv` will contain iTowns' rendering area (`<canvas>`)
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
const viewerDiv = document.getElementById('viewerDiv');
|
|
41
|
+
|
|
42
|
+
// Create a GlobeView
|
|
43
|
+
const view = new itowns.GlobeView(viewerDiv, placement);
|
|
35
44
|
|
|
36
|
-
//
|
|
37
|
-
var view = new itowns.GlobeView(viewerDiv, placement);
|
|
45
|
+
// Setup loading screen and debug menu
|
|
38
46
|
setupLoadingScreen(viewerDiv, view);
|
|
47
|
+
const debugMenu = new GuiTools('menuDiv', view);
|
|
39
48
|
|
|
40
|
-
// Dont' instance mini viewer if it's Test env
|
|
41
|
-
miniView = new itowns.GlobeView(miniDiv, placement, {
|
|
42
|
-
// `limit globe' subdivision level:
|
|
43
|
-
// we're don't need a precise globe model
|
|
44
|
-
// since the mini globe will always be seen from a far point of view (see minDistance above)
|
|
45
|
-
maxSubdivisionLevel: 2,
|
|
46
|
-
// Don't instance default controls since miniview's camera will be synced
|
|
47
|
-
// on the main view's one (see view.addFrameRequester)
|
|
48
|
-
noControls: true,
|
|
49
|
-
});
|
|
50
49
|
|
|
51
|
-
// Set a 0 alpha clear value (instead of the default '1')
|
|
52
|
-
// because we want a transparent background for the miniglobe view to be able
|
|
53
|
-
// to see the main view "behind"
|
|
54
|
-
miniView.mainLoop.gfxEngine.renderer.setClearColor(0x000000, 0);
|
|
55
|
-
|
|
56
|
-
// update miniview's camera with the view's camera position
|
|
57
|
-
view.addFrameRequester(itowns.MAIN_LOOP_EVENTS.AFTER_RENDER, function updateMiniView() {
|
|
58
|
-
// clamp distance camera from globe
|
|
59
|
-
var distanceCamera = view.camera.camera3D.position.length();
|
|
60
|
-
var distance = Math.min(Math.max(distanceCamera * 1.5, minDistance), maxDistance);
|
|
61
|
-
var camera = miniView.camera.camera3D;
|
|
62
|
-
var cameraTargetPosition = view.controls.getCameraTargetPosition();
|
|
63
|
-
// Update target miniview's camera
|
|
64
|
-
camera.position.copy(cameraTargetPosition).setLength(distance);
|
|
65
|
-
camera.lookAt(cameraTargetPosition);
|
|
66
|
-
miniView.notifyChange(camera);
|
|
67
|
-
});
|
|
68
50
|
|
|
51
|
+
// ---------- DISPLAY ORTHO-IMAGES : ----------
|
|
69
52
|
|
|
70
|
-
// Add one imagery layer to the scene
|
|
71
|
-
//
|
|
72
|
-
// object. See Layer* for more info.
|
|
53
|
+
// Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
|
|
54
|
+
// defined as a plain js object. See `Layer` documentation for more info.
|
|
73
55
|
itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
|
|
74
56
|
config.source = new itowns.WMTSSource(config.source);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
var miniLayer = new itowns.ColorLayer('OrthoMini', config);
|
|
79
|
-
miniView.addLayer(miniLayer);
|
|
57
|
+
view.addLayer(
|
|
58
|
+
new itowns.ColorLayer('Ortho', config),
|
|
59
|
+
).then(debugMenu.addLayerGUI.bind(debugMenu));
|
|
80
60
|
});
|
|
81
|
-
|
|
82
|
-
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// ---------- DISPLAY A DIGITAL ELEVATION MODEL : ----------
|
|
65
|
+
|
|
66
|
+
// Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
|
|
67
|
+
// defined in a json file.
|
|
83
68
|
function addElevationLayerFromConfig(config) {
|
|
84
69
|
config.source = new itowns.WMTSSource(config.source);
|
|
85
|
-
|
|
86
|
-
|
|
70
|
+
view.addLayer(
|
|
71
|
+
new itowns.ElevationLayer(config.id, config),
|
|
72
|
+
).then(debugMenu.addLayerGUI.bind(debugMenu));
|
|
87
73
|
}
|
|
88
74
|
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
|
|
89
75
|
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
|
|
90
76
|
|
|
91
|
-
var menuGlobe = new GuiTools('menuDiv', view);
|
|
92
|
-
var divScaleWidget = document.getElementById('divScaleWidget');
|
|
93
|
-
|
|
94
|
-
function updateScaleWidget() {
|
|
95
|
-
var value = view.getPixelsToMeters(200);
|
|
96
|
-
value = Math.floor(value);
|
|
97
|
-
var digit = Math.pow(10, value.toString().length - 1);
|
|
98
|
-
value = Math.round(value / digit) * digit;
|
|
99
|
-
var pix = view.getMetersToPixels(value);
|
|
100
|
-
var unit = 'm';
|
|
101
|
-
if (value >= 1000) {
|
|
102
|
-
value /= 1000;
|
|
103
|
-
unit = 'km';
|
|
104
|
-
}
|
|
105
|
-
divScaleWidget.innerHTML = `${value} ${unit}`;
|
|
106
|
-
divScaleWidget.style.width = `${pix}px`;
|
|
107
|
-
}
|
|
108
77
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
78
|
+
|
|
79
|
+
// ---------- ADD SOME WIDGETS : ----------
|
|
80
|
+
|
|
81
|
+
// ADD A SCALE :
|
|
82
|
+
const scale = new itowns_widgets.Scale(view, { position: 'bottom-right', translate: { x: -80 } });
|
|
83
|
+
|
|
84
|
+
// ADD A MINIMAP :
|
|
85
|
+
const minimap = new itowns_widgets.Minimap(
|
|
86
|
+
view,
|
|
87
|
+
new itowns.ColorLayer('minimap', {
|
|
88
|
+
source: new itowns.VectorTilesSource({
|
|
89
|
+
style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/gris.json',
|
|
90
|
+
// We don't display mountains and plot related data to ease visualisation
|
|
91
|
+
filter: (layer) => !layer['source-layer'].includes('oro_')
|
|
92
|
+
&& !layer['source-layer'].includes('parcellaire'),
|
|
93
|
+
}),
|
|
94
|
+
addLabelLayer: true,
|
|
95
|
+
}),
|
|
96
|
+
{ cursor: '+' },
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// ADD NAVIGATION TOOLS :
|
|
100
|
+
const navigation = new itowns_widgets.Navigation(view, {
|
|
101
|
+
position: 'bottom-right',
|
|
102
|
+
translate: { y: -40 },
|
|
114
103
|
});
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
|
|
105
|
+
// ADD A SEARCH BAR :
|
|
106
|
+
|
|
107
|
+
// You can find more precise explanation on searchbar options in the doc
|
|
108
|
+
// (http://www.itowns-project.org/itowns/docs/#api/Widgets/Searchbar) and in the searchbar example
|
|
109
|
+
// (https://www.itowns-project.org/itowns/examples/#widgets_searchbar)
|
|
110
|
+
|
|
111
|
+
// Define options for geocoding service that should be used by the searchbar.
|
|
112
|
+
const geocodingOptions = {
|
|
113
|
+
url: new URL(
|
|
114
|
+
'https://wxs.ign.fr/ayxvok72rcocdyn8xyvy32og/ols/apis/completion?text=&type=StreetAddress,' +
|
|
115
|
+
'PositionOfInterest',
|
|
116
|
+
),
|
|
117
|
+
parser: (response) => {
|
|
118
|
+
const map = new Map();
|
|
119
|
+
response.results.forEach(location => {
|
|
120
|
+
map.set(location.fulltext, new itowns.Coordinates('EPSG:4326', location.x, location.y));
|
|
121
|
+
});
|
|
122
|
+
return map;
|
|
123
|
+
},
|
|
124
|
+
onSelected: (coordinates) => {
|
|
125
|
+
view.controls.lookAtCoordinate({ coord: coordinates, range: 20000, tilt: 45, heading: 0 });
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Create the searchbar
|
|
130
|
+
const searchbar = new itowns_widgets.Searchbar(view, geocodingOptions, {
|
|
131
|
+
maxSuggestionNumber: 15,
|
|
132
|
+
placeholder: 'Search a location in France',
|
|
133
|
+
position: 'top-right',
|
|
117
134
|
});
|
|
118
135
|
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
// ---------- DISPLAY ATMOSPHERIC LIGHTING : ----------
|
|
139
|
+
|
|
119
140
|
const atmosphere = view.getLayerById('atmosphere');
|
|
120
141
|
atmosphere.setRealisticOn(!view.isDebugMode);
|
|
121
142
|
|
|
122
|
-
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
// ---------- DEBUG TOOLS : ----------
|
|
146
|
+
|
|
147
|
+
// Toggle atmospheric lighting on/off.
|
|
148
|
+
const cRL = debugMenu.addGUI('RealisticLighting', !view.isDebugMode, function (v) {
|
|
123
149
|
atmosphere.setRealisticOn(v);
|
|
124
150
|
view.notifyChange(atmosphere);
|
|
125
151
|
});
|
|
126
152
|
|
|
127
|
-
|
|
153
|
+
debug.createTileDebugUI(debugMenu.gui, view);
|
|
128
154
|
|
|
129
|
-
debug.createTileDebugUI(menuGlobe.gui, view);
|
|
130
155
|
</script>
|
|
131
156
|
</body>
|
|
132
157
|
</html>
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
|
|
81
81
|
function altitudeBuildings(properties) {
|
|
82
82
|
// I set altitude building 3 meters down, to be sure building is anchored in the ground
|
|
83
|
-
return properties.
|
|
83
|
+
return properties.altitude_minimale_sol - 3;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function extrudeBuildings(properties) {
|
|
@@ -115,22 +115,21 @@
|
|
|
115
115
|
|
|
116
116
|
// when oriented image layer is ready..
|
|
117
117
|
view.addLayer(olayer, view.tileLayer).then(function addWfsLayer(orientedImageLayer) {
|
|
118
|
-
|
|
119
118
|
// prepare WFS source for the buildings
|
|
120
119
|
var wfsBuildingSource = new itowns.WFSSource({
|
|
121
|
-
url: 'https://wxs.ign.fr/
|
|
120
|
+
url: 'https://wxs.ign.fr/topographie/geoportail/wfs?',
|
|
122
121
|
version: '2.0.0',
|
|
123
|
-
typeName: '
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
122
|
+
typeName: 'BDTOPO_V3:batiment',
|
|
123
|
+
crs: 'EPSG:4326',
|
|
124
|
+
ipr: 'IGN',
|
|
125
|
+
format: 'application/json',
|
|
126
|
+
extent: {
|
|
127
|
+
west: 2.334,
|
|
128
|
+
east: 2.335,
|
|
129
|
+
south: 48.849,
|
|
130
|
+
north: 48.851,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
134
133
|
|
|
135
134
|
// create geometry layer for the buildings
|
|
136
135
|
var wfsBuildingLayer = new itowns.FeatureGeometryLayer('Buildings', {
|