mapbox-gl-shadow-simulator 0.61.1 → 0.62.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 (34) hide show
  1. package/README.md +22 -3
  2. package/dist/mapbox-gl-shadow-simulator.d.ts +3 -0
  3. package/dist/mapbox-gl-shadow-simulator.esm.js +2 -2
  4. package/dist/mapbox-gl-shadow-simulator.umd.min.js +2 -2
  5. package/examples/map.html +246 -196
  6. package/examples/maplibre.html +257 -214
  7. package/examples/markers-maplibre.html +230 -0
  8. package/examples/markers.html +197 -0
  9. package/package.json +1 -1
  10. package/dist/leaflet-shademap/leaflet-shademap/dist/ShadeMap.d.ts +0 -122
  11. package/dist/leaflet-shademap/leaflet-shademap/dist/ShadeMapLeaflet.d.ts +0 -17
  12. package/dist/leaflet-shademap/leaflet-shademap/dist/ShadeMapMapbox.d.ts +0 -29
  13. package/dist/leaflet-shademap/leaflet-shademap/dist/buildings/BuildingRasterizer.d.ts +0 -42
  14. package/dist/leaflet-shademap/leaflet-shademap/dist/buildings/fetch-buildings.d.ts +0 -12
  15. package/dist/leaflet-shademap/leaflet-shademap/dist/buildings/normalize-buildings.d.ts +0 -8
  16. package/dist/leaflet-shademap/leaflet-shademap/dist/components/CanvasOverlay.d.ts +0 -11
  17. package/dist/leaflet-shademap/leaflet-shademap/dist/index.d.ts +0 -7
  18. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/EventEmitter.d.ts +0 -10
  19. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/TileMerger.d.ts +0 -49
  20. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/heightMap.d.ts +0 -33
  21. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/helpers.d.ts +0 -33
  22. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/image.d.ts +0 -13
  23. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/projection.d.ts +0 -3
  24. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/shadowMap.d.ts +0 -17
  25. package/dist/leaflet-shademap/leaflet-shademap/dist/lib/webgl.d.ts +0 -13
  26. package/dist/leaflet-shademap/leaflet-shademap/dist/map/geometryLeaflet.d.ts +0 -11
  27. package/dist/leaflet-shademap/leaflet-shademap/dist/map/umap.d.ts +0 -26
  28. package/dist/leaflet-shademap/leaflet-shademap/dist/shader/gpu.d.ts +0 -35
  29. package/dist/leaflet-shademap/leaflet-shademap/dist/shader/kernel.d.ts +0 -72
  30. package/dist/leaflet-shademap/leaflet-shademap/dist/types/color.d.ts +0 -5
  31. package/dist/leaflet-shademap/leaflet-shademap/dist/types/constants.d.ts +0 -3
  32. package/dist/leaflet-shademap/leaflet-shademap/dist/types/quality.d.ts +0 -5
  33. package/dist/leaflet-shademap/leaflet-shademap/dist/types/shadeMapOptions.d.ts +0 -46
  34. package/dist/leaflet-shademap/leaflet-shademap/dist/types/shadow3DData.d.ts +0 -21
@@ -2,231 +2,274 @@
2
2
  <html lang="en">
3
3
 
4
4
  <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <meta http-equiv="X-UA-Compatible" content="ie=edge" />
8
- <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@4.1.0/dist/maplibre-gl.css' />
9
- <script src='https://unpkg.com/maplibre-gl@4.1.0/dist/maplibre-gl.js'></script>
10
- <script src='https://www.unpkg.com/suncalc@1.9.0/suncalc.js'></script>
11
- <script src='https://unpkg.com/protomaps-themes-base@4.3.0/dist/protomaps-themes-base.js'></script>
12
- <script src="../dist/mapbox-gl-shadow-simulator.umd.min.js"></script>
13
- <style>
14
- body {
15
- padding: 0px;
16
- margin: 0px;
17
- }
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <meta http-equiv="X-UA-Compatible" content="ie=edge" />
8
+ <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.1.0/dist/maplibre-gl.css" />
9
+ <script src="https://unpkg.com/maplibre-gl@4.1.0/dist/maplibre-gl.js"></script>
10
+ <script src="https://www.unpkg.com/suncalc@1.9.0/suncalc.js"></script>
11
+ <script src="https://unpkg.com/protomaps-themes-base@4.3.0/dist/protomaps-themes-base.js"></script>
12
+ <script src="../dist/mapbox-gl-shadow-simulator.umd.min.js"></script>
13
+ <style>
14
+ body {
15
+ padding: 0px;
16
+ margin: 0px;
17
+ }
18
18
 
19
- #mapid {
20
- height: 100vh;
21
- }
19
+ #mapid {
20
+ height: 100vh;
21
+ }
22
22
 
23
- .maplibregl-control-time {
24
- padding: 20px;
25
- background-color: white;
26
- }
23
+ .maplibregl-control-time {
24
+ padding: 20px;
25
+ background-color: white;
26
+ }
27
27
 
28
- #exposure-gradient-container {
29
- display: none;
30
- background-color: white;
31
- padding: 0 10px 5px;
32
- }
28
+ #exposure-gradient-container {
29
+ display: none;
30
+ background-color: white;
31
+ padding: 0 10px 5px;
32
+ }
33
33
 
34
- #exposure-gradient {
35
- height: 20px;
36
- background-image: linear-gradient(to right, rgb(0 0 255/ 0.5), rgb(0 255 0 / 0.5), rgb(255 0 0 / 0.5));
37
- display: flex;
38
- }
34
+ #exposure-gradient {
35
+ height: 20px;
36
+ background-image: linear-gradient(to right,
37
+ rgb(0 0 255/ 0.5),
38
+ rgb(0 255 0 / 0.5),
39
+ rgb(255 0 0 / 0.5));
40
+ display: flex;
41
+ }
39
42
 
40
- #exposure-gradient>div {
41
- flex: 1;
42
- border: 1px solid white;
43
- text-align: center;
44
- font-weight: bold;
45
- }
46
- </style>
47
- <title>Shade Map Maplibre example</title>
43
+ #exposure-gradient>div {
44
+ flex: 1;
45
+ border: 1px solid white;
46
+ text-align: center;
47
+ font-weight: bold;
48
+ }
49
+ </style>
50
+ <title>mapbox-gl-shadow-simulator Maplibre Example</title>
48
51
  </head>
49
52
 
50
53
  <body>
51
- <div id="mapid">
52
- <div class="maplibregl-control-container" style="z-index: 2000; pointer-events: auto;">
53
- <div class="maplibregl-ctrl-top-left">
54
- <div class="maplibregl-control-time" style="pointer-events: auto;">
55
- <button id="decrement">-1 hour</button>
56
- <button id="increment">+1 hour</button>
57
- <button id="play">Play</button>
58
- <button id="stop">Stop</button>
59
- <label><input id="exposure" type="checkbox" autocomplete="off" />Full-day sun exposure</label>
60
- <button>
61
- <a href="https://shademap.app/about" target="_blank">Get API key</a>
62
- </button>
63
- <span id="loader" style="padding: 3px;"></span>
64
- </div>
65
- <div id="exposure-gradient-container">
66
- <div>Hours of sunlight</div>
67
- <div id="exposure-gradient"></div>
68
- </div>
69
- </div>
54
+ <div id="mapid">
55
+ <div class="maplibregl-control-container" style="z-index: 2000; pointer-events: auto">
56
+ <div class="maplibregl-ctrl-top-left">
57
+ <div class="maplibregl-control-time" style="pointer-events: auto">
58
+ <button id="decrement">-1 hour</button>
59
+ <button id="increment">+1 hour</button>
60
+ <button id="play">Play</button>
61
+ <button id="stop">Stop</button>
62
+ <label><input id="exposure" type="checkbox" autocomplete="off" />Full-day sun exposure</label>
63
+ <button>
64
+ <a href="https://shademap.app/about" target="_blank">Get API key</a>
65
+ </button>
66
+ <span id="loader" style="padding: 3px"></span>
70
67
  </div>
68
+ <div id="exposure-gradient-container">
69
+ <div>Hours of sunlight</div>
70
+ <div id="exposure-gradient"></div>
71
+ </div>
72
+ </div>
71
73
  </div>
72
- <script>
73
- const mapLoaded = (map) => {
74
- return new Promise((res, rej) => {
75
- function cb() {
76
- if (!map.loaded()) {
77
- return;
78
- }
79
- map.off("render", cb);
80
- res();
81
- }
82
- map.on("render", cb);
83
- cb();
74
+ </div>
75
+ <script>
76
+ const mapLoaded = (map) => {
77
+ return new Promise((res, rej) => {
78
+ function cb() {
79
+ if (!map.loaded()) {
80
+ return;
81
+ }
82
+ map.off("render", cb);
83
+ res();
84
+ }
85
+ map.on("render", cb);
86
+ cb();
87
+ });
88
+ };
89
+ /* Maplibregl setup */
90
+ maplibregl.setRTLTextPlugin(
91
+ "https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js",
92
+ true // Lazy load the plugin
93
+ );
94
+
95
+ const map = new maplibregl.Map({
96
+ container: "mapid",
97
+ style: {
98
+ version: 8,
99
+ glyphs:
100
+ "https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf",
101
+ sources: {
102
+ protomaps: {
103
+ type: "vector",
104
+ tiles: ["https://cfw.shademap.app/planet/{z}/{x}/{y}.pbf"],
105
+ attribution:
106
+ '<a href="https://protomaps.com">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>',
107
+ maxzoom: 15,
108
+ },
109
+ buildings: {
110
+ type: "vector",
111
+ tiles: [
112
+ `https://cfw.shademap.app/buildings/{z}/{x}/{y}.mvt`,
113
+ ],
114
+ minzoom: 14,
115
+ maxzoom: 14,
116
+ },
117
+ },
118
+ layers: [
119
+ ...protomaps_themes_base.default("protomaps", "light", "en"),
120
+ {
121
+ id: "building",
122
+ source: "buildings",
123
+ "source-layer": "building",
124
+ type: "line",
125
+ },
126
+ ],
127
+ },
128
+ maplibreLogo: true,
129
+ center: { lng: -122.18578164139899, lat: 47.694878957368815 },
130
+ zoom: 8, // starting zoom
131
+ hash: true,
132
+ });
133
+ /* End Maplibregl setup */
134
+
135
+ /* ShadeMap setup */
136
+ const loaderEl = document.getElementById("loader");
137
+ let now = new Date(
138
+ SunCalc.getTimes(
139
+ new Date(),
140
+ 47.694878957368815,
141
+ -122.18578164139899
142
+ ).sunrise.getTime() +
143
+ 60 * 60 * 1000
144
+ );
145
+ let shadeMap;
146
+ map.on("load", () => {
147
+ shadeMap = new ShadeMap({
148
+ apiKey:
149
+ "eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InRwcGlvdHJvd3NraUBzaGFkZW1hcC5hcHAiLCJjcmVhdGVkIjoxNjYyNDkzMDY2Nzk0LCJpYXQiOjE2NjI0OTMwNjZ9.ovCrLTYsdKFTF6TW3DuODxCaAtGQ3qhcmqj3DWcol5g",
150
+ date: now,
151
+ color: "#01112f",
152
+ opacity: 0.7,
153
+ terrainSource: {
154
+ maxZoom: 15,
155
+ tileSize: 256,
156
+ getSourceUrl: ({ x, y, z }) =>
157
+ `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/${z}/${x}/${y}.png`,
158
+ getElevation: ({ r, g, b, a }) => r * 256 + g + b / 256 - 32768,
159
+ _overzoom: 18,
160
+ },
161
+ getFeatures: async () => {
162
+ if (map.getZoom() >= 12) {
163
+ await mapLoaded(map);
164
+ const buildingData = map.querySourceFeatures("buildings", {
165
+ sourceLayer: "building",
84
166
  });
85
- };
86
- /* Maplibregl setup */
87
- maplibregl.setRTLTextPlugin(
88
- 'https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js',
89
- true // Lazy load the plugin
90
- );
91
-
92
- const map = new maplibregl.Map({
93
- container: 'mapid',
94
- style: {
95
- version: 8,
96
- glyphs: 'https://protomaps.github.io/basemaps-assets/fonts/{fontstack}/{range}.pbf',
97
- sources: {
98
- "protomaps": {
99
- type: "vector",
100
- tiles: [
101
- "https://cfw.shademap.app/planet/{z}/{x}/{y}.pbf"
102
- ],
103
- // url: "pmtiles://https://example.com/example.pmtiles",
104
- // // ^-- Remember to prefix the URL with pmtiles://
105
- attribution: '<a href="https://protomaps.com">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>',
106
- maxzoom: 15,
107
- }
108
- },
109
- layers: protomaps_themes_base.default("protomaps", "light", "en")
110
- },
111
- maplibreLogo: true,
112
- center: { lng: -122.18578164139899, lat: 47.694878957368815 },
113
- zoom: 8, // starting zoom
114
- hash: true,
115
- });
116
- /* End Maplibregl setup */
117
-
118
-
119
- /* ShadeMap setup */
120
- const loaderEl = document.getElementById('loader');
121
- let now = new Date((SunCalc.getTimes(new Date(), 47.694878957368815, -122.18578164139899).sunrise).getTime() + 60 * 60 * 1000);
122
- let shadeMap;
123
- map.on('load', () => {
124
- shadeMap = new ShadeMap({
125
- apiKey: "eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InRwcGlvdHJvd3NraUBzaGFkZW1hcC5hcHAiLCJjcmVhdGVkIjoxNjYyNDkzMDY2Nzk0LCJpYXQiOjE2NjI0OTMwNjZ9.ovCrLTYsdKFTF6TW3DuODxCaAtGQ3qhcmqj3DWcol5g",
126
- date: now,
127
- color: '#01112f',
128
- opacity: 0.7,
129
- terrainSource: {
130
- maxZoom: 15,
131
- tileSize: 256,
132
- getSourceUrl: ({ x, y, z }) => `https://s3.amazonaws.com/elevation-tiles-prod/terrarium/${z}/${x}/${y}.png`,
133
- getElevation: ({ r, g, b, a }) => (r * 256 + g + b / 256) - 32768,
134
- _overzoom: 18,
135
- },
136
- getFeatures: async () => {
137
- if (map.getZoom() >= 12) {
138
- await mapLoaded(map);
139
- const buildingData = map
140
- .querySourceFeatures("protomaps", { sourceLayer: "buildings" })
141
-
142
- buildingData.forEach(feature => { feature.properties.height = feature.properties.height || 3.1 })
143
-
144
- // Buildings segments must be rasterized from bottom to top. If not, the base of a building
145
- // could rasterize over the top tower of the building
146
- buildingData.sort((a, b) => {
147
- return a.properties.height - b.properties.height;
148
- });
149
- return buildingData;
150
-
151
- }
152
- return [];
153
- },
154
- debug: (msg) => { console.log(new Date().toISOString(), msg) }
155
- }).addTo(map);
156
-
157
- shadeMap.on('tileloaded', (loadedTiles, totalTiles) => {
158
- loaderEl.innerText = `Loading: ${(loadedTiles / totalTiles * 100).toFixed(0)}%`;
167
+
168
+ buildingData.forEach((feature) => {
169
+ feature.properties.height = feature.properties.height || 3.1;
159
170
  });
160
- });
161
- /* End ShadeMap setup */
162
-
163
- /* Controls setup */
164
- let intervalTimer;
165
-
166
- const increment = document.getElementById('increment');
167
- const decrement = document.getElementById('decrement');
168
- const play = document.getElementById('play');
169
- const stop = document.getElementById('stop');
170
- const exposure = document.getElementById('exposure');
171
- const exposureGradientContainer = document.getElementById('exposure-gradient-container');
172
- const exposureGradient = document.getElementById('exposure-gradient');
173
-
174
- increment.addEventListener('click', () => {
175
- now = new Date(now.getTime() + 3600000);
176
- shadeMap && shadeMap.setDate(now);
177
- }, false);
178
-
179
- decrement.addEventListener('click', () => {
180
- now = new Date(now.getTime() - 3600000);
181
- shadeMap && shadeMap.setDate(now);
182
- }, false);
183
-
184
- play.addEventListener('click', () => {
185
- intervalTimer = setInterval(() => {
186
- now = new Date(now.getTime() + 60000);
187
- shadeMap && shadeMap.setDate(now);
188
- }, 100);
189
- });
190
-
191
- stop.addEventListener('click', () => {
192
- clearInterval(intervalTimer);
193
- })
194
-
195
- exposure.addEventListener('click', (e) => {
196
- clearInterval(intervalTimer);
197
- const target = e.target;
198
- if (!target.checked) {
199
- shadeMap && shadeMap.setSunExposure(false);
200
- increment.disabled = false;
201
- decrement.disabled = false;
202
- play.disabled = false;
203
- stop.disabled = false;
204
- exposureGradientContainer.style.display = 'none';
205
- } else {
206
- const { lat, lng } = map.getCenter();
207
- const { sunrise, sunset } = SunCalc.getTimes(now, lat, lng);
208
- shadeMap && shadeMap.setSunExposure(true, {
209
- startDate: sunrise,
210
- endDate: sunset
211
- });
212
- increment.disabled = true
213
- decrement.disabled = true;
214
- play.disabled = true;
215
- stop.disabled = true;
216
-
217
- const hours = (sunset - sunrise) / 1000 / 3600;
218
- const partial = hours - Math.floor(hours);
219
- const html = [];
220
- for (let i = 0; i < hours; i++) {
221
- html.push(`<div>${i + 1}</div>`)
222
- }
223
- html.push(`<div style="flex: ${partial}"></div>`);
224
- exposureGradientContainer.style.display = 'block';
225
- exposureGradient.innerHTML = html.join('');
226
- }
227
- })
228
- /* End controls setup */
229
- </script>
171
+
172
+ // Buildings segments must be rasterized from bottom to top. If not, the base of a building
173
+ // could rasterize over the top tower of the building
174
+ buildingData.sort((a, b) => {
175
+ return a.properties.height - b.properties.height;
176
+ });
177
+ return buildingData;
178
+ }
179
+ return [];
180
+ },
181
+ debug: (msg) => {
182
+ console.log(new Date().toISOString(), msg);
183
+ },
184
+ }).addTo(map);
185
+
186
+ shadeMap.on("tileloaded", (loadedTiles, totalTiles) => {
187
+ loaderEl.innerText = `Loading: ${(
188
+ (loadedTiles / totalTiles) *
189
+ 100
190
+ ).toFixed(0)}%`;
191
+ });
192
+ });
193
+ /* End ShadeMap setup */
194
+
195
+ /* Controls setup */
196
+ let intervalTimer;
197
+
198
+ const increment = document.getElementById("increment");
199
+ const decrement = document.getElementById("decrement");
200
+ const play = document.getElementById("play");
201
+ const stop = document.getElementById("stop");
202
+ const exposure = document.getElementById("exposure");
203
+ const exposureGradientContainer = document.getElementById(
204
+ "exposure-gradient-container"
205
+ );
206
+ const exposureGradient = document.getElementById("exposure-gradient");
207
+
208
+ increment.addEventListener(
209
+ "click",
210
+ () => {
211
+ now = new Date(now.getTime() + 3600000);
212
+ shadeMap && shadeMap.setDate(now);
213
+ },
214
+ false
215
+ );
216
+
217
+ decrement.addEventListener(
218
+ "click",
219
+ () => {
220
+ now = new Date(now.getTime() - 3600000);
221
+ shadeMap && shadeMap.setDate(now);
222
+ },
223
+ false
224
+ );
225
+
226
+ play.addEventListener("click", () => {
227
+ intervalTimer = setInterval(() => {
228
+ now = new Date(now.getTime() + 60000);
229
+ shadeMap && shadeMap.setDate(now);
230
+ }, 100);
231
+ });
232
+
233
+ stop.addEventListener("click", () => {
234
+ clearInterval(intervalTimer);
235
+ });
236
+
237
+ exposure.addEventListener("click", (e) => {
238
+ clearInterval(intervalTimer);
239
+ const target = e.target;
240
+ if (!target.checked) {
241
+ shadeMap && shadeMap.setSunExposure(false);
242
+ increment.disabled = false;
243
+ decrement.disabled = false;
244
+ play.disabled = false;
245
+ stop.disabled = false;
246
+ exposureGradientContainer.style.display = "none";
247
+ } else {
248
+ const { lat, lng } = map.getCenter();
249
+ const { sunrise, sunset } = SunCalc.getTimes(now, lat, lng);
250
+ shadeMap &&
251
+ shadeMap.setSunExposure(true, {
252
+ startDate: sunrise,
253
+ endDate: sunset,
254
+ });
255
+ increment.disabled = true;
256
+ decrement.disabled = true;
257
+ play.disabled = true;
258
+ stop.disabled = true;
259
+
260
+ const hours = (sunset - sunrise) / 1000 / 3600;
261
+ const partial = hours - Math.floor(hours);
262
+ const html = [];
263
+ for (let i = 0; i < hours; i++) {
264
+ html.push(`<div>${i + 1}</div>`);
265
+ }
266
+ html.push(`<div style="flex: ${partial}"></div>`);
267
+ exposureGradientContainer.style.display = "block";
268
+ exposureGradient.innerHTML = html.join("");
269
+ }
270
+ });
271
+ /* End controls setup */
272
+ </script>
230
273
  </body>
231
274
 
232
- </html>
275
+ </html>