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.
Files changed (122) hide show
  1. package/CONTRIBUTING.md +30 -17
  2. package/README.md +12 -1
  3. package/changelog.md +138 -0
  4. package/dist/debug.js +1 -1
  5. package/dist/debug.js.LICENSE.txt +2 -2
  6. package/dist/debug.js.map +1 -1
  7. package/dist/itowns.js +1 -1
  8. package/dist/itowns.js.LICENSE.txt +2 -2
  9. package/dist/itowns.js.map +1 -1
  10. package/dist/itowns_widgets.js +2 -0
  11. package/dist/itowns_widgets.js.map +1 -0
  12. package/examples/config.json +28 -6
  13. package/examples/css/example.css +21 -1
  14. package/examples/css/widgets.css +360 -0
  15. package/examples/geoid_geoidLayer.html +102 -0
  16. package/examples/images/code-logo.svg +43 -0
  17. package/examples/index.html +5 -5
  18. package/examples/itowns-potree.html +252 -0
  19. package/examples/js/GUI/GuiTools.js +17 -0
  20. package/examples/mars.html +0 -1
  21. package/examples/misc_orthographic_camera.html +7 -19
  22. package/examples/source_file_from_fetched_data.html +90 -0
  23. package/examples/source_file_from_format.html +85 -0
  24. package/examples/source_file_from_methods.html +87 -0
  25. package/examples/source_file_from_parsed_data.html +104 -0
  26. package/examples/source_file_geojson_raster.html +21 -45
  27. package/examples/source_file_gpx_raster.html +28 -36
  28. package/examples/source_file_kml_raster.html +1 -4
  29. package/examples/source_file_shapefile.html +39 -34
  30. package/examples/source_stream_wfs_25d.html +21 -13
  31. package/examples/source_stream_wfs_3d.html +21 -12
  32. package/examples/source_stream_wfs_raster.html +20 -20
  33. package/examples/vector_tile_3d_mesh.html +155 -0
  34. package/examples/vector_tile_raster_3d.html +0 -5
  35. package/examples/view_25d_map.html +6 -19
  36. package/examples/view_2d_map.html +6 -19
  37. package/examples/view_3d_map.html +106 -81
  38. package/examples/view_immersive.html +13 -14
  39. package/examples/widgets_minimap.html +124 -0
  40. package/examples/widgets_navigation.html +124 -0
  41. package/examples/widgets_scale.html +96 -0
  42. package/examples/widgets_searchbar.html +124 -0
  43. package/lib/Controls/GlobeControls.js +13 -0
  44. package/lib/Controls/PlanarControls.js +11 -43
  45. package/lib/Converter/Feature2Mesh.js +203 -45
  46. package/lib/Converter/convertToTile.js +13 -4
  47. package/lib/Core/3DTiles/C3DTBoundingVolume.js +4 -1
  48. package/lib/Core/Deprecated/Undeprecator.js +1 -1
  49. package/lib/Core/Feature.js +60 -34
  50. package/lib/Core/Geographic/Extent.js +1 -1
  51. package/lib/Core/Geographic/GeoidGrid.js +143 -0
  52. package/lib/Core/MainLoop.js +137 -63
  53. package/lib/Core/Math/Ellipsoid.js +1 -1
  54. package/lib/Core/Prefab/Globe/SkyShader.js +3 -1
  55. package/lib/Core/Prefab/Planar/PlanarLayer.js +3 -1
  56. package/lib/Core/Style.js +1 -1
  57. package/lib/Core/TileGeometry.js +3 -1
  58. package/lib/Core/TileMesh.js +32 -22
  59. package/lib/Core/View.js +81 -15
  60. package/lib/Layer/ElevationLayer.js +6 -2
  61. package/lib/Layer/FeatureGeometryLayer.js +36 -7
  62. package/lib/Layer/GeoidLayer.js +142 -0
  63. package/lib/Layer/GeometryLayer.js +6 -54
  64. package/lib/Layer/InfoLayer.js +1 -1
  65. package/lib/Layer/Layer.js +1 -1
  66. package/lib/Layer/LayerUpdateStrategy.js +1 -1
  67. package/lib/Layer/OrientedImageLayer.js +1 -0
  68. package/lib/Layer/PotreeLayer.js +3 -1
  69. package/lib/Layer/RasterLayer.js +3 -1
  70. package/lib/Layer/ReferencingLayerProperties.js +50 -0
  71. package/lib/Layer/TiledGeometryLayer.js +3 -1
  72. package/lib/Main.js +214 -174
  73. package/lib/MainBundle.js +1 -1
  74. package/lib/Parser/B3dmParser.js +5 -3
  75. package/lib/Parser/GDFParser.js +118 -0
  76. package/lib/Parser/GTXParser.js +92 -0
  77. package/lib/Parser/GeoJsonParser.js +29 -7
  78. package/lib/Parser/ISGParser.js +121 -0
  79. package/lib/Parser/LASParser.js +3 -1
  80. package/lib/Parser/VectorTileParser.js +4 -3
  81. package/lib/Parser/XbilParser.js +1 -1
  82. package/lib/Parser/deprecated/LegacyGLTFLoader.js +1 -1
  83. package/lib/Process/3dTilesProcessing.js +2 -2
  84. package/lib/Process/FeatureProcessing.js +38 -86
  85. package/lib/Process/LayeredMaterialNodeProcessing.js +16 -7
  86. package/lib/Process/ObjectRemovalHelper.js +4 -0
  87. package/lib/Provider/3dTilesProvider.js +2 -7
  88. package/lib/Provider/Fetcher.js +4 -1
  89. package/lib/Provider/TileProvider.js +18 -2
  90. package/lib/Provider/URLBuilder.js +1 -1
  91. package/lib/Renderer/Camera.js +33 -12
  92. package/lib/Renderer/ColorLayersOrdering.js +3 -1
  93. package/lib/Renderer/LayeredMaterial.js +34 -9
  94. package/lib/Renderer/OBB.js +22 -25
  95. package/lib/Renderer/OrientedImageMaterial.js +8 -5
  96. package/lib/Renderer/PointsMaterial.js +6 -6
  97. package/lib/Renderer/RasterTile.js +1 -1
  98. package/lib/Renderer/RenderMode.js +3 -1
  99. package/lib/Renderer/Shader/ShaderChunk.js +5 -1
  100. package/lib/Renderer/Shader/ShaderUtils.js +4 -2
  101. package/lib/Renderer/c3DEngine.js +9 -6
  102. package/lib/Source/C3DTilesSource.js +3 -1
  103. package/lib/Source/EntwinePointTileSource.js +3 -1
  104. package/lib/Source/FileSource.js +8 -1
  105. package/lib/Source/PotreeSource.js +3 -1
  106. package/lib/Source/Source.js +15 -10
  107. package/lib/Source/VectorTilesSource.js +5 -0
  108. package/lib/Source/WFSSource.js +9 -3
  109. package/lib/Source/WMTSSource.js +3 -1
  110. package/lib/ThreeExtended/{WebGL.js → capabilities/WebGL.js} +8 -7
  111. package/lib/ThreeExtended/loaders/GLTFLoader.js +88 -39
  112. package/lib/Utils/CameraUtils.js +11 -1
  113. package/lib/Utils/DEMUtils.js +4 -2
  114. package/lib/Utils/FeaturesUtils.js +8 -4
  115. package/lib/Utils/gui/Main.js +39 -0
  116. package/lib/Utils/gui/Minimap.js +197 -0
  117. package/lib/Utils/gui/Navigation.js +322 -0
  118. package/lib/Utils/gui/Scale.js +154 -0
  119. package/lib/Utils/gui/Searchbar.js +299 -0
  120. package/lib/Utils/gui/Widget.js +119 -0
  121. package/package.json +32 -27
  122. package/examples/js/Scale.js +0 -40
@@ -0,0 +1,124 @@
1
+ <html>
2
+ <head>
3
+ <title>Itowns - Minimap widget</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
+
11
+ <!-- Import stylesheet for itowns Widgets plugin. This stylesheet is included in the bundles if you downloaded
12
+ them, or it can be found in `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it
13
+ can be found here : https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css -->
14
+ <link rel="stylesheet" type="text/css" href="css/widgets.css">
15
+
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <!-- Add a description -->
20
+ <div id="description">
21
+ Double click on the minimap to travel to the cursor location.
22
+ </div>
23
+
24
+ <!-- Create a container for itowns viewer -->
25
+ <div id="viewerDiv"></div>
26
+
27
+ <!-- Import iTowns source code -->
28
+ <script src="../dist/itowns.js"></script>
29
+ <script src="../dist/debug.js"></script>
30
+ <!-- Import iTowns Widgets plugin -->
31
+ <script src="../dist/itowns_widgets.js"></script>
32
+ <!-- Import iTowns LoadingScreen and GuiTools plugins -->
33
+ <script src="js/GUI/LoadingScreen.js"></script>
34
+ <script src="js/GUI/GuiTools.js"></script>
35
+
36
+
37
+ <script type="text/javascript">
38
+
39
+
40
+
41
+ // ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
42
+
43
+ // Define camera initial position
44
+ const placement = {
45
+ coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
46
+ range: 6000,
47
+ tilt: 50,
48
+ }
49
+
50
+ // `viewerDiv` contains iTowns' rendering area (`<canvas>`)
51
+ const viewerDiv = document.getElementById('viewerDiv');
52
+
53
+ // Create a GlobeView
54
+ const view = new itowns.GlobeView(viewerDiv, placement);
55
+
56
+ // Setup loading screen and debug menu
57
+ setupLoadingScreen(viewerDiv, view);
58
+ const debugMenu = new GuiTools('menuDiv', view);
59
+
60
+
61
+
62
+ // ---------- DISPLAY CONTEXTUAL DATA : ----------
63
+
64
+ // Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
65
+ // defined as a plain js object. See `Layer` documentation for more info.
66
+ itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
67
+ config.source = new itowns.WMTSSource(config.source);
68
+ view.addLayer(
69
+ new itowns.ColorLayer(config.id, config),
70
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
71
+ });
72
+
73
+ // Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
74
+ // defined in a json file.
75
+ function addElevationLayerFromConfig(config) {
76
+ config.source = new itowns.WMTSSource(config.source);
77
+ view.addLayer(
78
+ new itowns.ElevationLayer(config.id, config),
79
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
80
+ }
81
+ itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
82
+ itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
83
+
84
+
85
+
86
+ // ---------- ADD MINIMAP WIDGET : ----------
87
+
88
+ // Create a ColorLayer that shall be displayed on the minimap.
89
+ const minimapColorLayer = new itowns.ColorLayer('minimap', {
90
+ source: new itowns.VectorTilesSource({
91
+ style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
92
+ // We don't display mountains and plot related data to ease visualisation
93
+ filter: (layer) => !layer['source-layer'].includes('oro_')
94
+ && !layer['source-layer'].includes('parcellaire'),
95
+ }),
96
+ addLabelLayer: true,
97
+ });
98
+
99
+ // Create a minimap.
100
+ const minimap = new itowns_widgets.Minimap(view, minimapColorLayer, {
101
+ cursor: '+',
102
+ size: 200,
103
+ });
104
+
105
+
106
+
107
+ // ---------- ADD INTERACTION WITH MINIMAP : ----------
108
+
109
+ // When double-clicking the minimap, travel to the cursor location.
110
+ const cursorCoordinates = new itowns.Coordinates(minimap.view.referenceCrs);
111
+ minimap.domElement.addEventListener('dblclick', (event) => {
112
+ minimap.view.pickCoordinates(event, cursorCoordinates);
113
+ view.controls.lookAtCoordinate({ coord: cursorCoordinates });
114
+ });
115
+
116
+
117
+
118
+ // ---------- DEBUG TOOLS : ----------
119
+
120
+ debug.createTileDebugUI(debugMenu.gui, view);
121
+
122
+ </script>
123
+ </body>
124
+ </html>
@@ -0,0 +1,124 @@
1
+ <html>
2
+ <head>
3
+ <title>Itowns - Navigation widget</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
+
11
+ <!-- Import stylesheet for itowns Widgets plugin. This stylesheet is included in the bundles if you downloaded
12
+ them, or it can be found in `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it
13
+ can be found here : https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css -->
14
+ <link rel="stylesheet" type="text/css" href="css/widgets.css">
15
+
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <div id="viewerDiv"></div>
20
+
21
+ <!-- Import iTowns source code -->
22
+ <script src="../dist/itowns.js"></script>
23
+ <script src="../dist/debug.js"></script>
24
+ <!-- Import iTowns Widgets plugin -->
25
+ <script src="../dist/itowns_widgets.js"></script>
26
+ <!-- Import iTowns LoadingScreen and GuiTools plugins -->
27
+ <script src="js/GUI/LoadingScreen.js"></script>
28
+ <script src="js/GUI/GuiTools.js"></script>
29
+
30
+
31
+ <script type="text/javascript">
32
+
33
+
34
+
35
+ // ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
36
+
37
+ // Define camera initial position
38
+ const placement = {
39
+ coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
40
+ range: 6000,
41
+ tilt: 50,
42
+ }
43
+
44
+ // `viewerDiv` contains iTowns' rendering area (`<canvas>`)
45
+ const viewerDiv = document.getElementById('viewerDiv');
46
+
47
+ // Create a GlobeView
48
+ const view = new itowns.GlobeView(viewerDiv, placement);
49
+
50
+ // Setup loading screen and debug menu
51
+ setupLoadingScreen(viewerDiv, view);
52
+ const debugMenu = new GuiTools('menuDiv', view);
53
+
54
+
55
+
56
+ // ---------- DISPLAY CONTEXTUAL DATA : ----------
57
+
58
+ // Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
59
+ // defined as a plain js object. See `Layer` documentation for more info.
60
+ itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
61
+ config.source = new itowns.WMTSSource(config.source);
62
+ view.addLayer(
63
+ new itowns.ColorLayer(config.id, config),
64
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
65
+ });
66
+
67
+ // Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
68
+ // defined in a json file.
69
+ function addElevationLayerFromConfig(config) {
70
+ config.source = new itowns.WMTSSource(config.source);
71
+ view.addLayer(
72
+ new itowns.ElevationLayer(config.id, config),
73
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
74
+ }
75
+ itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
76
+ itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
77
+
78
+
79
+
80
+ // ---------- ADD NAVIGATION WIDGET : ----------
81
+
82
+ const widgets = new itowns_widgets.Navigation(view);
83
+
84
+ // Example on how to add a new button to the widgets menu
85
+ widgets.addButton(
86
+ 'rotate-up',
87
+ '<p style="font-size: 20px">&#8595</p>',
88
+ 'rotate camera up',
89
+ () => {
90
+ view.controls.lookAtCoordinate({
91
+ tilt: view.controls.getTilt() - 10,
92
+ time: 500,
93
+ });
94
+ },
95
+ 'button-bar-rotation',
96
+ );
97
+ widgets.addButton(
98
+ 'rotate-down',
99
+ '<p style="font-size: 20px">&#8593</p>',
100
+ 'rotate camera down',
101
+ () => {
102
+ view.controls.lookAtCoordinate({
103
+ tilt: view.controls.getTilt() + 10,
104
+ time: 500,
105
+ });
106
+ },
107
+ 'button-bar-rotation',
108
+ );
109
+ widgets.addButton(
110
+ 'reset-position',
111
+ '&#8634',
112
+ 'reset position',
113
+ () => { view.controls.lookAtCoordinate(placement) },
114
+ );
115
+
116
+
117
+
118
+ // ---------- DEBUG TOOLS : ----------
119
+
120
+ debug.createTileDebugUI(debugMenu.gui, view);
121
+
122
+ </script>
123
+ </body>
124
+ </html>
@@ -0,0 +1,96 @@
1
+ <html>
2
+ <head>
3
+ <title>Itowns - Scale widget</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
+
11
+ <!-- Import stylesheet for itowns Widgets plugin. This stylesheet is included in the bundles if you downloaded
12
+ them, or it can be found in `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it
13
+ can be found here : https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css -->
14
+ <link rel="stylesheet" type="text/css" href="css/widgets.css">
15
+
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <!-- Create a container for itowns viewer -->
20
+ <div id="viewerDiv"></div>
21
+
22
+ <!-- Import iTowns source code -->
23
+ <script src="../dist/itowns.js"></script>
24
+ <script src="../dist/debug.js"></script>
25
+ <!-- Import iTowns Widgets plugin -->
26
+ <script src="../dist/itowns_widgets.js"></script>
27
+ <!-- Import iTowns LoadingScreen and GuiTools plugins -->
28
+ <script src="js/GUI/LoadingScreen.js"></script>
29
+ <script src="js/GUI/GuiTools.js"></script>
30
+
31
+
32
+ <script type="text/javascript">
33
+
34
+
35
+
36
+ // ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
37
+
38
+ // Define camera initial position
39
+ const placement = {
40
+ coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
41
+ range: 6000,
42
+ tilt: 50,
43
+ }
44
+
45
+ // `viewerDiv` contains iTowns' rendering area (`<canvas>`)
46
+ const viewerDiv = document.getElementById('viewerDiv');
47
+
48
+ // Create a GlobeView
49
+ const view = new itowns.GlobeView(viewerDiv, placement);
50
+
51
+ // Setup loading screen and debug menu
52
+ setupLoadingScreen(viewerDiv, view);
53
+ const debugMenu = new GuiTools('menuDiv', view);
54
+
55
+
56
+
57
+ // ---------- DISPLAY CONTEXTUAL DATA : ----------
58
+
59
+ // Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
60
+ // defined as a plain js object. See `Layer` documentation for more info.
61
+ itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
62
+ config.source = new itowns.WMTSSource(config.source);
63
+ view.addLayer(
64
+ new itowns.ColorLayer(config.id, config),
65
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
66
+ });
67
+
68
+ // Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
69
+ // defined in a json file.
70
+ function addElevationLayerFromConfig(config) {
71
+ config.source = new itowns.WMTSSource(config.source);
72
+ view.addLayer(
73
+ new itowns.ElevationLayer(config.id, config),
74
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
75
+ }
76
+ itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
77
+ itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
78
+
79
+
80
+
81
+ // ---------- ADD SCALE WIDGET : ----------
82
+
83
+ const scale = new itowns_widgets.Scale(view, {
84
+ position: 'bottom-right',
85
+ translate: { x: -70 },
86
+ });
87
+
88
+
89
+
90
+ // ---------- DEBUG TOOLS : ----------
91
+
92
+ debug.createTileDebugUI(debugMenu.gui, view);
93
+
94
+ </script>
95
+ </body>
96
+ </html>
@@ -0,0 +1,124 @@
1
+ <html>
2
+ <head>
3
+ <title>Itowns - Searchbar widget</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
+
11
+ <!-- Import stylesheet for itowns Widgets plugin. This stylesheet is included in the bundles if you downloaded
12
+ them, or it can be found in `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it
13
+ can be found here : https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css -->
14
+ <link rel="stylesheet" type="text/css" href="css/widgets.css">
15
+
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <!-- Create a container for itowns viewer -->
20
+ <div id="viewerDiv"></div>
21
+
22
+ <!-- Import iTowns source code -->
23
+ <script src="../dist/itowns.js"></script>
24
+ <script src="../dist/debug.js"></script>
25
+ <!-- Import iTowns Widgets plugin -->
26
+ <script src="../dist/itowns_widgets.js"></script>
27
+ <!-- Import iTowns LoadingScreen and GuiTools plugins -->
28
+ <script src="js/GUI/LoadingScreen.js"></script>
29
+ <script src="js/GUI/GuiTools.js"></script>
30
+
31
+
32
+ <script type="text/javascript">
33
+
34
+
35
+
36
+ // ---------- CREATE A GlobeView FOR SUPPORTING DATA VISUALIZATION : ----------
37
+
38
+ // Define camera initial position
39
+ const placement = {
40
+ coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
41
+ range: 6000,
42
+ tilt: 50,
43
+ }
44
+
45
+ // `viewerDiv` contains iTowns' rendering area (`<canvas>`)
46
+ const viewerDiv = document.getElementById('viewerDiv');
47
+
48
+ // Create a GlobeView
49
+ const view = new itowns.GlobeView(viewerDiv, placement);
50
+
51
+ // Setup loading screen and debug menu
52
+ setupLoadingScreen(viewerDiv, view);
53
+ const debugMenu = new GuiTools('menuDiv', view);
54
+
55
+
56
+
57
+ // ---------- DISPLAY CONTEXTUAL DATA : ----------
58
+
59
+ // Add one imagery layer to the scene. This layer's properties are defined in a json file, but it could be
60
+ // defined as a plain js object. See `Layer` documentation for more info.
61
+ itowns.Fetcher.json('layers/JSONLayers/Ortho.json').then((config) => {
62
+ config.source = new itowns.WMTSSource(config.source);
63
+ view.addLayer(
64
+ new itowns.ColorLayer(config.id, config),
65
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
66
+ });
67
+
68
+ // Add two elevation layers, each with a different level of detail. Here again, each layer's properties are
69
+ // defined in a json file.
70
+ function addElevationLayerFromConfig(config) {
71
+ config.source = new itowns.WMTSSource(config.source);
72
+ view.addLayer(
73
+ new itowns.ElevationLayer(config.id, config),
74
+ ).then(debugMenu.addLayerGUI.bind(debugMenu));
75
+ }
76
+ itowns.Fetcher.json('layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
77
+ itowns.Fetcher.json('layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
78
+
79
+
80
+
81
+ // ---------- ADD SEARCH BAR WIDGET : ----------
82
+
83
+ // Function that should be called when clicking a location suggestion.
84
+ function lookAtCoordinate(coordinates) {
85
+ view.controls.lookAtCoordinate({ coord: coordinates, range: 20000, tilt: 45, heading: 0 });
86
+ }
87
+
88
+ // Define options for geocoding service that should be used by the searchbar.
89
+ const geocodingOptions = {
90
+ url: new URL(
91
+ 'https://wxs.ign.fr/ayxvok72rcocdyn8xyvy32og/ols/apis/completion?text=&type=StreetAddress,' +
92
+ 'PositionOfInterest',
93
+ ),
94
+ // As precised in the doc (http://www.itowns-project.org/itowns/docs/#api/Widgets/Searchbar), the parser
95
+ // method must parse the geocoding service response into a Map object. For each item of this Map, the
96
+ // key is a string that is displayed in the suggestions bellow the searchbar, and the value is whatever
97
+ // the user wants. The value is the parameter that is passed to the `onSelected` method when a
98
+ // suggestion is clicked. Here, we se the value as the `Coordinates` associated to the location.
99
+ parser: (response) => {
100
+ const map = new Map();
101
+ response.results.forEach(location => {
102
+ map.set(location.fulltext, new itowns.Coordinates('EPSG:4326', location.x, location.y));
103
+ });
104
+ return map;
105
+ },
106
+ onSelected: lookAtCoordinate,
107
+ }
108
+
109
+ // Create the searchbar
110
+ const searchbar = new itowns_widgets.Searchbar(view, geocodingOptions, {
111
+ // We want to display at maximum 15 location suggestions when typing the searchbar.
112
+ maxSuggestionNumber: 15,
113
+ placeholder: 'Search a location in France',
114
+ });
115
+
116
+
117
+
118
+ // ---------- DEBUG TOOLS : ----------
119
+
120
+ debug.createTileDebugUI(debugMenu.gui, view);
121
+
122
+ </script>
123
+ </body>
124
+ </html>
@@ -33,6 +33,8 @@ var _CameraUtils = _interopRequireDefault(require("../Utils/CameraUtils"));
33
33
 
34
34
  var _StateControl = _interopRequireDefault(require("./StateControl"));
35
35
 
36
+ var _View = require("../Core/View");
37
+
36
38
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
37
39
 
38
40
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -75,6 +77,7 @@ var dollyScale; // Globe move
75
77
 
76
78
  var moveAroundGlobe = new THREE.Quaternion();
77
79
  var cameraTarget = new THREE.Object3D();
80
+ var coordCameraTarget = new _Coordinates["default"]('EPSG:4978');
78
81
  cameraTarget.matrixWorldInverse = new THREE.Matrix4();
79
82
  var xyz = new _Coordinates["default"]('EPSG:4978', 0, 0, 0);
80
83
  var c = new _Coordinates["default"]('EPSG:4326', 0, 0, 0); // Position object on globe
@@ -342,6 +345,7 @@ var GlobeControls = /*#__PURE__*/function (_THREE$EventDispatche) {
342
345
 
343
346
  _this.lookAtCoordinate(placement, false);
344
347
 
348
+ coordCameraTarget.crs = _this.view.referenceCrs;
345
349
  return _this;
346
350
  }
347
351
 
@@ -610,6 +614,14 @@ var GlobeControls = /*#__PURE__*/function (_THREE$EventDispatche) {
610
614
  });
611
615
  this.player.playLater(durationDampingOrbital, 2);
612
616
  }
617
+
618
+ this.view.dispatchEvent({
619
+ type: _View.VIEW_EVENTS.CAMERA_MOVED,
620
+ coord: coordCameraTarget.setFromVector3(cameraTarget.position),
621
+ range: spherical.radius,
622
+ heading: -THREE.MathUtils.radToDeg(spherical.theta),
623
+ tilt: 90 - THREE.MathUtils.radToDeg(spherical.phi)
624
+ });
613
625
  }
614
626
  }, {
615
627
  key: "onStateChange",
@@ -1300,6 +1312,7 @@ var GlobeControls = /*#__PURE__*/function (_THREE$EventDispatche) {
1300
1312
 
1301
1313
  var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1302
1314
  var isAnimated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.isAnimationEnabled();
1315
+ this.player.stop();
1303
1316
 
1304
1317
  if (!params.isExtent) {
1305
1318
  if (params.zoom) {
@@ -7,7 +7,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports["default"] = exports.PLANAR_CONTROL_EVENT = exports.STATE = exports.keys = void 0;
10
+ exports.keys = exports["default"] = exports.STATE = exports.PLANAR_CONTROL_EVENT = void 0;
11
11
 
12
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
13
 
@@ -126,8 +126,6 @@ var defaultOptions = {
126
126
  instantTravel: false,
127
127
  minZenithAngle: 0,
128
128
  maxZenithAngle: 82.5,
129
- focusOnMouseOver: true,
130
- focusOnMouseClick: true,
131
129
  handleCollision: true,
132
130
  minDistanceCollision: 30,
133
131
  enableSmartTravel: true,
@@ -183,8 +181,6 @@ var PLANAR_CONTROL_EVENT = {
183
181
  * rotation, in degrees.
184
182
  * @param {number} [options.maxZenithAngle=82.5] The maximum reachable zenith angle for a camera
185
183
  * rotation, in degrees.
186
- * @param {boolean} [options.focusOnMouseOver=true] Set the focus on the canvas if hovered.
187
- * @param {boolean} [options.focusOnMouseClick=true] Set the focus on the canvas if clicked.
188
184
  * @param {boolean} [options.handleCollision=true]
189
185
  */
190
186
 
@@ -280,8 +276,14 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
280
276
 
281
277
  _this.maxZenithAngle = (options.maxZenithAngle || defaultOptions.maxZenithAngle) * Math.PI / 180; // focus policy options
282
278
 
283
- _this.focusOnMouseOver = options.focusOnMouseOver || defaultOptions.focusOnMouseOver;
284
- _this.focusOnMouseClick = options.focusOnMouseClick || defaultOptions.focusOnMouseClick; // set collision options
279
+ if (options.focusOnMouseOver) {
280
+ console.warn('Planar controls \'focusOnMouseOver\' optional parameter has been removed.');
281
+ }
282
+
283
+ if (options.focusOnMouseClick) {
284
+ console.warn('Planar controls \'focusOnMouseClick\' optional parameter has been removed.');
285
+ } // set collision options
286
+
285
287
 
286
288
  _this.handleCollision = options.handleCollision === undefined ? defaultOptions.handleCollision : options.handleCollision;
287
289
  _this.minDistanceCollision = defaultOptions.minDistanceCollision; // enable smart travel
@@ -307,8 +309,6 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
307
309
  _this._handlerOnMouseUp = _this.onMouseUp.bind((0, _assertThisInitialized2["default"])(_this));
308
310
  _this._handlerOnMouseMove = _this.onMouseMove.bind((0, _assertThisInitialized2["default"])(_this));
309
311
  _this._handlerOnMouseWheel = _this.onMouseWheel.bind((0, _assertThisInitialized2["default"])(_this));
310
- _this._handlerFocusOnMouseClick = _this.onMouseClick.bind((0, _assertThisInitialized2["default"])(_this));
311
- _this._handlerFocusOnMouseOver = _this.onMouseOver.bind((0, _assertThisInitialized2["default"])(_this));
312
312
  _this._handlerContextMenu = _this.onContextMenu.bind((0, _assertThisInitialized2["default"])(_this));
313
313
  _this._handlerUpdate = _this.update.bind((0, _assertThisInitialized2["default"])(_this)); // add this PlanarControl instance to the view's frameRequesters
314
314
  // with this, PlanarControl.update() will be called each frame
@@ -856,18 +856,9 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
856
856
  this.view.domElement.addEventListener('mouseup', this._handlerOnMouseUp, false);
857
857
  this.view.domElement.addEventListener('mouseleave', this._handlerOnMouseUp, false);
858
858
  this.view.domElement.addEventListener('mousemove', this._handlerOnMouseMove, false);
859
- this.view.domElement.addEventListener('wheel', this._handlerOnMouseWheel, false); // focus policy
860
-
861
- if (this.focusOnMouseOver) {
862
- this.view.domElement.addEventListener('mouseover', this._handlerFocusOnMouseOver, false);
863
- }
864
-
865
- if (this.focusOnMouseClick) {
866
- this.view.domElement.addEventListener('click', this._handlerFocusOnMouseClick, false);
867
- } // prevent the default context menu from appearing when right-clicking
859
+ this.view.domElement.addEventListener('wheel', this._handlerOnMouseWheel, false); // prevent the default context menu from appearing when right-clicking
868
860
  // this allows to use right-click for input without the menu appearing
869
861
 
870
-
871
862
  this.view.domElement.addEventListener('contextmenu', this._handlerContextMenu, false);
872
863
  }
873
864
  /**
@@ -885,8 +876,6 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
885
876
  this.view.domElement.removeEventListener('mouseleave', this._handlerOnMouseUp, false);
886
877
  this.view.domElement.removeEventListener('mousemove', this._handlerOnMouseMove, false);
887
878
  this.view.domElement.removeEventListener('wheel', this._handlerOnMouseWheel, false);
888
- this.view.domElement.removeEventListener('mouseover', this._handlerFocusOnMouseOver, false);
889
- this.view.domElement.removeEventListener('click', this._handlerFocusOnMouseClick, false);
890
879
  this.view.domElement.removeEventListener('contextmenu', this._handlerContextMenu, false);
891
880
  }
892
881
  /**
@@ -959,6 +948,7 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
959
948
  key: "onMouseDown",
960
949
  value: function onMouseDown(event) {
961
950
  event.preventDefault();
951
+ this.view.domElement.focus();
962
952
 
963
953
  if (STATE.NONE !== this.state) {
964
954
  return;
@@ -1086,28 +1076,6 @@ var PlanarControls = /*#__PURE__*/function (_THREE$EventDispatche) {
1086
1076
  this.initiateZoom(event);
1087
1077
  }
1088
1078
  }
1089
- /**
1090
- * Set the focus on view's domElement according to focus policy regarding MouseOver
1091
- *
1092
- * @ignore
1093
- */
1094
-
1095
- }, {
1096
- key: "onMouseOver",
1097
- value: function onMouseOver() {
1098
- this.view.domElement.focus();
1099
- }
1100
- /**
1101
- * Set the focus on view's domElement according to focus policy regarding MouseClick
1102
- *
1103
- * @ignore
1104
- */
1105
-
1106
- }, {
1107
- key: "onMouseClick",
1108
- value: function onMouseClick() {
1109
- this.view.domElement.focus();
1110
- }
1111
1079
  /**
1112
1080
  * Catch and manage the event when the context menu is called (by a right-click on the window). We use this
1113
1081
  * to prevent the context menu from appearing so we can use right click for other inputs.