source: binary-improvements/webserver/js/map.js@ 309

Last change on this file since 309 was 306, checked in by alloc, 7 years ago

Fixes update A16.2

File size: 15.9 KB
Line 
1var mapinfo = {
2 regionsize: 512,
3 chunksize: 16,
4 tilesize: 128,
5 maxzoom: 4
6}
7
8function InitMap() {
9 // ===============================================================================================
10 // 7dtd coordinate transformations
11
12 SDTD_Projection = {
13 project: function (latlng) {
14 return new L.Point(
15 (latlng.lat) / Math.pow(2, mapinfo.maxzoom),
16 (latlng.lng) / Math.pow(2, mapinfo.maxzoom) );
17 },
18
19 unproject: function (point) {
20 return new L.LatLng(
21 point.x * Math.pow(2, mapinfo.maxzoom),
22 point.y * Math.pow(2, mapinfo.maxzoom) );
23 }
24 };
25
26 SDTD_CRS = L.extend({}, L.CRS.Simple, {
27 projection: SDTD_Projection,
28 transformation: new L.Transformation(1, 0, -1, 0),
29
30 scale: function (zoom) {
31 return Math.pow(2, zoom);
32 }
33 });
34
35 // ===============================================================================================
36 // Map and basic tile layers
37
38 map = L.map('tab_map', {
39 zoomControl: false, // Added by Zoomslider
40 zoomsliderControl: true,
41 attributionControl: false,
42 crs: SDTD_CRS
43 }).setView([0, 0], Math.max(0, mapinfo.maxzoom - 5));
44
45
46 var initTime = new Date().getTime();
47 var tileLayer = GetSdtdTileLayer (mapinfo, initTime);
48 var tileLayerMiniMap = GetSdtdTileLayer (mapinfo, initTime, true);
49
50 // player icon
51 var playerIcon = L.icon({
52 iconUrl: '/static/leaflet/images/marker-survivor.png',
53 iconRetinaUrl: '/static/leaflet/images/marker-survivor-2x.png',
54 iconSize: [25, 48],
55 iconAnchor: [12, 24],
56 popupAnchor: [0, -20]
57 });
58
59 // hostile icon
60 var hostileIcon = L.icon({
61 iconUrl: '/static/leaflet/images/marker-zombie.png',
62 iconRetinaUrl: '/static/leaflet/images/marker-zombie-2x.png',
63 iconSize: [25, 33],
64 iconAnchor: [12, 16],
65 popupAnchor: [0, -10]
66 });
67
68 // animal icon
69 var animalIcon = L.icon({
70 iconUrl: '/static/leaflet/images/marker-animal.png',
71 iconRetinaUrl: '/static/leaflet/images/marker-animal-2x.png',
72 iconSize: [25, 26],
73 iconAnchor: [12, 13],
74 popupAnchor: [0, -10]
75 });
76
77
78
79 // ===============================================================================================
80 // Overlays and controls
81
82 var playersOnlineMarkerGroup = L.markerClusterGroup({
83 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
84 });
85 var playersOfflineMarkerGroup = L.markerClusterGroup({
86 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
87 });
88 var hostilesMarkerGroup = L.markerClusterGroup({
89 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
90 });
91 var animalsMarkerGroup = L.markerClusterGroup({
92 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
93 });
94
95 var densityMismatchMarkerGroupAir = L.markerClusterGroup({
96 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
97 });
98 var densityMismatchMarkerGroupTerrain = L.markerClusterGroup({
99 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
100 });
101 var densityMismatchMarkerGroupNonTerrain = L.markerClusterGroup({
102 maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
103 });
104
105
106 var layerControl = L.control.layers({
107 //"Map": tileLayer
108 }, null, {
109 collapsed: false
110 }
111 );
112
113 var layerCount = 0;
114
115
116 tileLayer.addTo(map);
117
118 new L.Control.Coordinates({}).addTo(map);
119
120 new L.Control.ReloadTiles({
121 autoreload_enable: true,
122 autoreload_minInterval: 30,
123 autoreload_interval: 120,
124 autoreload_defaultOn: false,
125 layers: [tileLayer, tileLayerMiniMap]
126 }).addTo(map);
127
128 layerControl.addOverlay (GetRegionLayer (mapinfo), "Region files");
129 layerCount++;
130
131 var miniMap = new L.Control.MiniMap(tileLayerMiniMap, {
132 zoomLevelOffset: -6,
133 toggleDisplay: true
134 }).addTo(map);
135
136 var measure = L.control.measure({
137 units: {
138 sdtdMeters: {
139 factor: 0.00001,
140 display: 'XMeters',
141 decimals: 0
142 },
143 sdtdSqMeters: {
144 factor: 0.000000001,
145 display: 'XSqMeters',
146 decimals: 0
147 }
148 },
149 primaryLengthUnit: "sdtdMeters",
150 primaryAreaUnit: "sdtdSqMeters",
151 //activeColor: "#ABE67E",
152 //completedColor: "#C8F2BE",
153 position: "bottomleft"
154 });
155 //measure.addTo(map);
156
157 //new L.Control.GameTime({}).addTo(map);
158
159 if (HasPermission ("webapi.getlandclaims")) {
160 layerControl.addOverlay (GetLandClaimsLayer (map, mapinfo), "Land claims");
161 layerCount++;
162 }
163
164 if (HasPermission ("webapi.gethostilelocation")) {
165 layerControl.addOverlay (hostilesMarkerGroup, "Hostiles (<span id='mapControlHostileCount'>0</span>)");
166 layerCount++;
167 }
168
169 if (HasPermission ("webapi.getanimalslocation")) {
170 layerControl.addOverlay (animalsMarkerGroup, "Animals (<span id='mapControlAnimalsCount'>0</span>)");
171 layerCount++;
172 }
173
174 if (HasPermission ("webapi.getplayerslocation")) {
175 layerControl.addOverlay (playersOfflineMarkerGroup, "Players (offline) (<span id='mapControlOfflineCount'>0</span>)");
176 layerControl.addOverlay (playersOnlineMarkerGroup, "Players (online) (<span id='mapControlOnlineCount'>0</span>)");
177 layerCount++;
178 }
179
180 if (layerCount > 0) {
181 layerControl.addTo(map);
182 }
183
184
185
186
187 var hostilesMappingList = {};
188 var animalsMappingList = {};
189 var playersMappingList = {};
190
191
192
193 // ===============================================================================================
194 // Player markers
195
196 $(".leaflet-popup-pane").on('click.action', '.inventoryButton', function(event) {
197 ShowInventoryDialog ($(this).data('steamid'));
198 });
199
200 var openedPopup = null;
201 var updatingMarkers = false;
202
203 map.on ("popupopen", function (event) {
204 console.log ("open");
205 console.log (event.popup._source);
206 openedPopup = event.popup._source;
207 });
208 map.on ("popupclose", function (event) {
209 if (!updatingMarkers) {
210 console.log ("close");
211 openedPopup = null;
212 }
213 });
214
215 var setPlayerMarkers = function(data) {
216 var online = 0;
217 var offline = 0;
218 updatingMarkers = true;
219 $.each( data, function( key, val ) {
220 var marker;
221 if (playersMappingList.hasOwnProperty(val.steamid)) {
222 marker = playersMappingList[val.steamid].currentPosMarker;
223 } else {
224 marker = L.marker([val.position.x, val.position.z], {icon: playerIcon}).bindPopup(
225 "Player: " + val.name +
226 (HasPermission ("webapi.getplayerinventory") ?
227 "<br/><a class='inventoryButton' data-steamid='"+val.steamid+"'>Show inventory</a>"
228 : "")
229 );
230 playersMappingList[val.steamid] = { online: !val.online };
231 }
232
233 oldpos = marker.getLatLng ();
234 if ( playersMappingList[val.steamid].online != val.online || oldpos.lat != val.position.x || oldpos.lng != val.position.z ) {
235 if (playersMappingList[val.steamid].online) {
236 playersOnlineMarkerGroup.removeLayer(marker);
237 } else {
238 playersOfflineMarkerGroup.removeLayer(marker);
239 }
240 marker.setLatLng([val.position.x, val.position.z]);
241 if (val.online) {
242 marker.setOpacity(1.0);
243 playersOnlineMarkerGroup.addLayer(marker);
244 } else {
245 marker.setOpacity(0.5);
246 playersOfflineMarkerGroup.addLayer(marker);
247 }
248 }
249
250 val.currentPosMarker = marker;
251 playersMappingList[val.steamid] = val;
252
253 if (val.online)
254 online++;
255 else
256 offline++;
257 });
258 updatingMarkers = false;
259 if (openedPopup != null) {
260 openedPopup.openPopup ();
261 }
262 $( "#mapControlOnlineCount" ).text( online );
263 $( "#mapControlOfflineCount" ).text( offline );
264 }
265
266 var updatePlayerTimeout;
267 var updatePlayerEvent = function() {
268 $.getJSON( "../api/getplayerslocation")
269 .done(setPlayerMarkers)
270 .fail(function(jqxhr, textStatus, error) {
271 console.log("Error fetching players list");
272 })
273 .always(function() {
274 updatePlayerTimeout = window.setTimeout(updatePlayerEvent, 4000);
275 });
276 }
277
278 tabs.on ("tabbedcontenttabopened", function (event, data) {
279 if (data.newTab === "#tab_map") {
280 if (HasPermission ("webapi.getplayerslocation")) {
281 updatePlayerEvent ();
282 }
283 } else {
284 window.clearTimeout (updatePlayerTimeout);
285 }
286 });
287
288 if (tabs.tabbedContent ("isTabOpen", "tab_map")) {
289 if (HasPermission ("webapi.getplayerslocation")) {
290 updatePlayerEvent ();
291 }
292 }
293
294
295
296
297 // ===============================================================================================
298 // Hostiles markers
299
300 var setHostileMarkers = function(data) {
301 updatingMarkersHostile = true;
302
303 var hostileCount = 0;
304
305 hostilesMarkerGroup.clearLayers();
306
307 $.each( data, function( key, val ) {
308 var marker;
309 if (hostilesMappingList.hasOwnProperty(val.id)) {
310 marker = hostilesMappingList[val.id].currentPosMarker;
311 } else {
312 marker = L.marker([val.position.x, val.position.z], {icon: hostileIcon}).bindPopup(
313 "Hostile: " + val.name
314 );
315 //hostilesMappingList[val.id] = { };
316 hostilesMarkerGroup.addLayer(marker);
317 }
318
319 var bAbort = false;
320
321 oldpos = marker.getLatLng ();
322
323 //if ( oldpos.lat != val.position.x || oldpos.lng != val.position.z ) {
324 // hostilesMarkerGroup.removeLayer(marker);
325 marker.setLatLng([val.position.x, val.position.z]);
326 marker.setOpacity(1.0);
327 hostilesMarkerGroup.addLayer(marker);
328 //}
329
330 val.currentPosMarker = marker;
331 hostilesMappingList[val.id] = val;
332
333 hostileCount++;
334 });
335
336 $( "#mapControlHostileCount" ).text( hostileCount );
337
338 updatingMarkersHostile = false;
339 }
340
341 var updateHostileTimeout;
342 var updateHostileEvent = function() {
343 $.getJSON( "../api/gethostilelocation")
344 .done(setHostileMarkers)
345 .fail(function(jqxhr, textStatus, error) {
346 console.log("Error fetching hostile list");
347 })
348 .always(function() {
349 updateHostileTimeout = window.setTimeout(updateHostileEvent, 4000);
350 });
351 }
352
353 tabs.on ("tabbedcontenttabopened", function (event, data) {
354 if (data.newTab === "#tab_map") {
355 if (HasPermission ("webapi.gethostilelocation")) {
356 updateHostileEvent ();
357 }
358 } else {
359 window.clearTimeout (updateHostileTimeout);
360 }
361 });
362
363 if (tabs.tabbedContent ("isTabOpen", "tab_map")) {
364 if (HasPermission ("webapi.gethostilelocation")) {
365 updateHostileEvent ();
366 }
367 }
368
369
370
371 // ===============================================================================================
372 // Animals markers
373
374 var setAnimalMarkers = function(data) {
375 updatingMarkersAnimals = true;
376
377 var animalsCount = 0;
378
379 animalsMarkerGroup.clearLayers();
380
381 $.each( data, function( key, val ) {
382 var marker;
383 if (animalsMappingList.hasOwnProperty(val.id)) {
384 marker = animalsMappingList[val.id].currentPosMarker;
385 } else {
386 marker = L.marker([val.position.x, val.position.z], {icon: animalIcon}).bindPopup(
387 "Animal: " + val.name
388 );
389 //animalsMappingList[val.id] = { };
390 animalsMarkerGroup.addLayer(marker);
391 }
392
393 var bAbort = false;
394
395 oldpos = marker.getLatLng ();
396
397 //if ( oldpos.lat != val.position.x || oldpos.lng != val.position.z ) {
398 // animalsMarkerGroup.removeLayer(marker);
399 marker.setLatLng([val.position.x, val.position.z]);
400 marker.setOpacity(1.0);
401 animalsMarkerGroup.addLayer(marker);
402 //}
403
404 val.currentPosMarker = marker;
405 animalsMappingList[val.id] = val;
406
407 animalsCount++;
408 });
409
410 $( "#mapControlAnimalsCount" ).text( animalsCount );
411
412 updatingMarkersAnimals = false;
413 }
414
415 var updateAnimalsTimeout;
416 var updateAnimalsEvent = function() {
417 $.getJSON( "../api/getanimalslocation")
418 .done(setAnimalMarkers)
419 .fail(function(jqxhr, textStatus, error) {
420 console.log("Error fetching animals list");
421 })
422 .always(function() {
423 updateAnimalsTimeout = window.setTimeout(updateAnimalsEvent, 4000);
424 });
425 }
426
427 tabs.on ("tabbedcontenttabopened", function (event, data) {
428 if (data.newTab === "#tab_map") {
429 if (HasPermission ("webapi.getanimalslocation")) {
430 updateAnimalsEvent ();
431 }
432 } else {
433 window.clearTimeout (updateAnimalsTimeout);
434 }
435 });
436
437 if (tabs.tabbedContent ("isTabOpen", "tab_map")) {
438 if (HasPermission ("webapi.getanimalslocation")) {
439 updateAnimalsEvent ();
440 }
441 }
442
443
444
445
446
447
448
449
450
451 // ===============================================================================================
452 // Density markers
453
454 var setDensityMarkers = function(data) {
455 var densityCountAir = 0;
456 var densityCountTerrain = 0;
457 var densityCountNonTerrain = 0;
458
459 densityMismatchMarkerGroupAir.clearLayers();
460 densityMismatchMarkerGroupTerrain.clearLayers();
461 densityMismatchMarkerGroupNonTerrain.clearLayers();
462
463
464 var downloadCsv = true;
465 var downloadJson = false;
466
467 if (downloadJson) {
468 var jsonAir = [];
469 var jsonTerrain = [];
470 var jsonNonTerrain = [];
471 }
472 if (downloadCsv) {
473 var csvAir = "x;y;z;Density;IsTerrain;BvType\r\n";
474 var csvTerrain = "x;y;z;Density;IsTerrain;BvType\r\n";
475 var csvNonTerrain = "x;y;z;Density;IsTerrain;BvType\r\n";
476 }
477
478 $.each( data, function( key, val ) {
479 if (val.bvtype == 0) {
480 marker = L.marker([val.x, val.z]).bindPopup(
481 "Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
482 );
483 densityMismatchMarkerGroupAir.addLayer(marker);
484 densityCountAir++;
485 if (downloadJson) {
486 jsonAir.push (val);
487 }
488 if (downloadCsv) {
489 csvAir += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
490 }
491 } else if (val.terrain) {
492 marker = L.marker([val.x, val.z]).bindPopup(
493 "Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
494 );
495 densityMismatchMarkerGroupTerrain.addLayer(marker);
496 densityCountTerrain++;
497 if (downloadJson) {
498 jsonTerrain.push (val);
499 }
500 if (downloadCsv) {
501 csvTerrain += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
502 }
503 } else {
504 marker = L.marker([val.x, val.z]).bindPopup(
505 "Density Mismatch: <br>Position: " + val.x + " " + val.y + " " + val.z + "<br>Density: " + val.density + "<br>isTerrain: " + val.terrain + "<br>bv.type: " + val.bvtype
506 );
507 densityMismatchMarkerGroupNonTerrain.addLayer(marker);
508 densityCountNonTerrain++;
509 if (downloadJson) {
510 jsonNonTerrain.push (val);
511 }
512 if (downloadCsv) {
513 csvNonTerrain += val.x + ";" + val.y + ";" + val.z + ";" + val.density + ";" + val.terrain + ";" + val.bvtype + "\r\n";
514 }
515 }
516 });
517
518 layerControl.addOverlay (densityMismatchMarkerGroupAir, "Density Mismatches Air (<span id='mapControlDensityCountAir'>0</span>)");
519 layerControl.addOverlay (densityMismatchMarkerGroupTerrain, "Density Mismatches Terrain (<span id='mapControlDensityCountTerrain'>0</span>)");
520 layerControl.addOverlay (densityMismatchMarkerGroupNonTerrain, "Density Mismatches NonTerrain (<span id='mapControlDensityCountNonTerrain'>0</span>)");
521
522 $( "#mapControlDensityCountAir" ).text( densityCountAir );
523 $( "#mapControlDensityCountTerrain" ).text( densityCountTerrain );
524 $( "#mapControlDensityCountNonTerrain" ).text( densityCountNonTerrain );
525
526 if (downloadJson) {
527 download ("air-negative-density.json", JSON.stringify(jsonAir, null, '\t'));
528 download ("terrain-positive-density.json", JSON.stringify(jsonTerrain, null, '\t'));
529 download ("nonterrain-negative-density.json", JSON.stringify(jsonNonTerrain, null, '\t'));
530 }
531 if (downloadCsv) {
532 download ("air-negative-density.csv", csvAir);
533 download ("terrain-positive-density.csv", csvTerrain);
534 download ("nonterrain-negative-density.csv", csvNonTerrain);
535 }
536
537 function download(filename, text) {
538 var element = document.createElement('a');
539 var file = new Blob([text], {type: 'text/plain'});
540 element.href = URL.createObjectURL(file);
541 element.download = filename;
542
543 element.style.display = 'none';
544 document.body.appendChild(element);
545
546 element.click();
547
548 document.body.removeChild(element);
549 }
550 }
551
552 $.getJSON("densitymismatch.json")
553 .done(setDensityMarkers)
554 .fail(function(jqxhr, textStatus, error) {
555 console.log("Error fetching density mismatch list");
556 });
557
558}
559
560
561
562
563
564function StartMapModule () {
565 $.getJSON( "../map/mapinfo.json")
566 .done(function(data) {
567 mapinfo.tilesize = data.blockSize;
568 mapinfo.maxzoom = data.maxZoom;
569 })
570 .fail(function(jqxhr, textStatus, error) {
571 console.log ("Error fetching map information");
572 })
573 .always(function() {
574 InitMap ();
575 });
576}
577
578
Note: See TracBrowser for help on using the repository browser.