node-red-contrib-web-worldmap 2.42.1 → 2.42.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,6 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
+ - v2.42.3 - More KML and GEOJson drag drop fixes
3
4
  - v2.42.1 - Remove extraneous debug logging, fix KMZ icons
4
5
  - v2.42.0 - Add handling for TAK type spots, waypoints, alerts, sensors. Better KML/KMZ handling.
5
6
  - v2.41.0 - Bump leaflet libs to latest stable (1.9.4)
package/README.md CHANGED
@@ -13,6 +13,7 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%
13
13
 
14
14
  ### Updates
15
15
 
16
+ - v2.42.3 - More KML and GEOJson drag drop fixes
16
17
  - v2.42.1 - Remove extraneous debug logging, fix KMZ icons
17
18
  - v2.42.0 - Add handling for TAK type spots, waypoints, alerts, sensors. Better KML/KMZ handling.
18
19
  - v2.41.0 - Bump leaflet libs to latest stable (1.9.4)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-web-worldmap",
3
- "version": "2.42.1",
3
+ "version": "2.42.3",
4
4
  "description": "A Node-RED node to provide a web page of a world map for plotting things on.",
5
5
  "dependencies": {
6
6
  "@turf/bezier-spline": "~6.5.0",
@@ -68,8 +68,8 @@
68
68
  <script src="leaflet/leaflet-side-by-side.js"></script>
69
69
  <script src="leaflet/OSMBuildings-Leaflet.js"></script>
70
70
  <script src="leaflet/leaflet-omnivore.min.js"></script>
71
+ <script src="leaflet/togeojson.umd.js"></script>
71
72
  <script src="leaflet/leaflet-kmz.js"></script>
72
- <!-- <script src="leaflet/L.KML.js"></script> -->
73
73
  <script src="leaflet/leaflet.mousecoordinate.js"></script>
74
74
  <script src="leaflet/leaflet.latlng-graticule.js"></script>
75
75
  <script src="leaflet/VectorTileLayer.umd.min.js"></script>
@@ -140,6 +140,9 @@
140
140
  text = new TextDecoder(encoding[1]).decode(data);
141
141
  }
142
142
  }
143
+ else {
144
+ text = text.substr(text.indexOf('<'));
145
+ }
143
146
  return text ? (new DOMParser()).parseFromString(text, 'text/xml') : document.implementation.createDocument(null, "kml");}
144
147
 
145
148
  function unzip(folder) {
@@ -229,9 +232,10 @@
229
232
  var preferCanvas = this._map ? this._map.options.preferCanvas : this.options.preferCanvas;
230
233
  // var emptyIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E";
231
234
  // parse GeoJSON
235
+ //console.log("DATA",data)
232
236
  var layer = L.geoJson(data, {
233
237
  pointToLayer: (feature, latlng) => {
234
- // console.log("FEAT",feature)
238
+ //console.log("FEAT",feature)
235
239
  if (preferCanvas) {
236
240
  return L.kmzMarker(latlng, {
237
241
  iconUrl: data.properties.icons[feature.properties.icon] || feature.properties.icon,
@@ -246,12 +250,25 @@
246
250
  iconAnchor: [14, 14],
247
251
  })
248
252
  if (feature.properties && feature.properties.SymbolSpecification) {
249
- var mysymbol = new ms.Symbol(feature.properties.SymbolSpecification.split(':')[1]);
253
+ var mysymbol;
254
+ if (feature.properties.MilitaryEchelon && feature.properties.SymbolSpecification.split(':')[0] === "APP-6D") {
255
+ var a = feature.properties.SymbolSpecification.split(':')[1].substr(0,8);
256
+ var c = feature.properties.SymbolSpecification.split(':')[1].substr(10);
257
+ var b = parseInt(feature.properties.MilitaryEchelon) + 10;
258
+ mysymbol = new ms.Symbol("" + a + b + c);
259
+ }
260
+ else {
261
+ mysymbol = new ms.Symbol(feature.properties.SymbolSpecification.split(':')[1]);
262
+ }
263
+
250
264
  mysymbol = mysymbol.setOptions({ size:20 });
265
+ if (feature.properties.name) { mysymbol = mysymbol.setOptions({ uniqueDesignation:feature.properties.name }); }
266
+ if (feature.properties.MilitaryParentId) { mysymbol = mysymbol.setOptions({ higherFormation:feature.properties.MilitaryParentId }); }
251
267
  kicon = L.icon({
252
268
  iconUrl: mysymbol.toDataURL(),
253
269
  iconAnchor: [mysymbol.getAnchor().x, mysymbol.getAnchor().y],
254
270
  });
271
+ //console.log("META",mysymbol.getMetadata())
255
272
  }
256
273
  if (kicon.options.iconUrl === undefined) { // No icon found so just use default marker.
257
274
  return L.marker(latlng);
@@ -265,6 +282,7 @@
265
282
  // TODO: handle L.svg renderer within the L.KMZMarker class?
266
283
  },
267
284
  style: (feature) => {
285
+ //console.log("FEATSTYLE",feature)
268
286
  var styles = {};
269
287
  var prop = feature.properties;
270
288
 
@@ -289,16 +307,18 @@
289
307
  return styles;
290
308
  },
291
309
  onEachFeature: (feature, layer) => {
292
- if (!this.options.ballon) return;
293
-
310
+ //console.log("POP",feature.properties)
311
+ //if (!this.options.ballon) return;
294
312
  var prop = feature.properties;
295
- var name = prop.name || "";
296
- var desc = prop.description || "";
313
+ var name = (prop.name || "").trim();
314
+ // var desc = (prop.description || "").trim();
315
+ var desc = prop.description || "";
297
316
 
317
+ var p = '<div>';
298
318
  if (name || desc) {
299
- if (this.options.bindPopup) {
300
- layer.bindPopup('<div>' + '<b>' + name + '</b>' + '<br>' + desc + '</div>');
301
- }
319
+ // if (this.options.bindPopup) {
320
+ p += '<b>' + name + '</b>' + '<br>' + desc + '</div>';
321
+ // }
302
322
  if (this.options.bindTooltip) {
303
323
  layer.bindTooltip('<b>' + name + '</b>', {
304
324
  direction: 'auto',
@@ -306,6 +326,24 @@
306
326
  });
307
327
  }
308
328
  }
329
+
330
+ var u = {};
331
+ if (prop.MilitaryParentId) { u.group = prop.MilitaryParentId; }
332
+ if (prop.FeaturePlatformId) { u["platform id"] = prop.FeaturePlatformId; }
333
+ if (prop.FeatureAddress) { u.address = prop.FeatureAddress; }
334
+ if (prop.SymbolSpecification) { u[prop.SymbolSpecification.split(':')[0]] = prop.SymbolSpecification.split(':')[1]; }
335
+ if (prop.Speed && prop.Speed !== "0") { u.speed = prop.Speed; }
336
+ if (prop.FeatureLastModified) { u["last update"] = prop.FeatureLastModified; }
337
+ if (u["last update"]) { u["last update"] = (new Date(u["last update"]*1000)).toISOString(); }
338
+
339
+ p += '<table border="0">';
340
+ Object.entries(u).forEach(([key, value]) => {
341
+ p += '<tr><td>'+key+'</td><td>'+value+'</td></tr>';
342
+ });
343
+ p += '</table></div>';
344
+ if (p !== '<div><table border="0"></table></div>') {
345
+ layer.bindPopup(p);
346
+ }
309
347
  },
310
348
  interactive: this.options.interactive,
311
349
  });
@@ -426,5 +464,4 @@
426
464
 
427
465
  Object.defineProperty(exports, '__esModule', { value: true });
428
466
 
429
- })));
430
- //# sourceMappingURL=leaflet-kmz-src.js.map
467
+ })));
@@ -0,0 +1,2 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).toGeoJSON={})}(this,(function(t){"use strict";function e(t,e){return Array.from(t.getElementsByTagName(e))}function n(t){return"#"===t[0]?t:`#${t}`}function o(t){return t?.normalize(),t&&t.textContent||""}function r(t,e,n){const o=t.getElementsByTagName(e),r=o.length?o[0]:null;return r&&n&&n(r),r}function i(t,e,n){const o={};if(!t)return o;const r=t.getElementsByTagName(e),i=r.length?r[0]:null;return i&&n?n(i,o):o}function s(t,e,n){const i=o(r(t,e));return i&&n&&n(i)||{}}function c(t,e,n){const i=parseFloat(o(r(t,e)));if(!isNaN(i))return i&&n&&n(i)||{}}function a(t,e,n){const i=parseFloat(o(r(t,e)));if(!isNaN(i))return n&&n(i),i}function l(t,e){const n={};for(const o of e)s(t,o,(t=>{n[o]=t}));return n}function u(t){return 1===t?.nodeType}function f(t){return i(t,"line",(t=>Object.assign({},s(t,"color",(t=>({stroke:`#${t}`}))),c(t,"opacity",(t=>({"stroke-opacity":t}))),c(t,"width",(t=>({"stroke-width":96*t/25.4}))))))}function p(t){let e=[];if(null===t)return e;for(const n of Array.from(t.childNodes)){if(!u(n))continue;const t=g(n.nodeName);if("gpxtpx:TrackPointExtension"===t)e=e.concat(p(n));else{const r=o(n);e.push([t,d(r)])}}return e}function g(t){return["heart","gpxtpx:hr","hr"].includes(t)?"heart":t}function d(t){const e=parseFloat(t);return isNaN(e)?t:e}function m(t){const e=[parseFloat(t.getAttribute("lon")||""),parseFloat(t.getAttribute("lat")||"")];if(isNaN(e[0])||isNaN(e[1]))return null;a(t,"ele",(t=>{e.push(t)}));const n=r(t,"time");return{coordinates:e,time:n?o(n):null,extendedValues:p(r(t,"extensions"))}}function h(t){const n=l(t,["name","cmt","desc","type","time","keywords"]),r=Array.from(t.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/GpxExtensions/v3","*"));for(const e of r)e.parentNode?.parentNode===t&&(n[e.tagName.replace(":","_")]=o(e));const i=e(t,"link");return i.length&&(n.links=i.map((t=>Object.assign({href:t.getAttribute("href")},l(t,["text","type"]))))),n}function y(t,n){const o=e(t,n),r=[],i=[],s={};for(let t=0;t<o.length;t++){const e=m(o[t]);if(e){r.push(e.coordinates),e.time&&i.push(e.time);for(const[n,r]of e.extendedValues){const e="heart"===n?n:n.replace("gpxtpx:","")+"s";s[e]||(s[e]=Array(o.length).fill(null)),s[e][t]=r}}}if(!(r.length<2))return{line:r,times:i,extendedValues:s}}function b(t){const e=y(t,"rtept");if(e)return{type:"Feature",properties:Object.assign({_gpxType:"rte"},h(t),f(r(t,"extensions"))),geometry:{type:"LineString",coordinates:e.line}}}function N(t){const n=e(t,"trkseg"),o=[],i=[],s=[];for(const t of n){const e=y(t,"trkpt");e&&(s.push(e),e.times&&e.times.length&&i.push(e.times))}if(0===s.length)return null;const c=s.length>1,a=Object.assign({_gpxType:"trk"},h(t),f(r(t,"extensions")),i.length?{coordinateProperties:{times:c?i:i[0]}}:{});for(const t of s){o.push(t.line),a.coordinateProperties||(a.coordinateProperties={});const e=a.coordinateProperties,n=Object.entries(t.extendedValues);for(let t=0;t<n.length;t++){const[o,r]=n[t];c?(e[o]||(e[o]=s.map((t=>new Array(t.line.length).fill(null)))),e[o][t]=r):e[o]=r}}return{type:"Feature",properties:a,geometry:c?{type:"MultiLineString",coordinates:o}:{type:"LineString",coordinates:o[0]}}}function x(t){const e=Object.assign(h(t),l(t,["sym"])),n=m(t);return n?{type:"Feature",properties:e,geometry:{type:"Point",coordinates:n.coordinates}}:null}function*k(t){for(const n of e(t,"trk")){const t=N(n);t&&(yield t)}for(const n of e(t,"rte")){const t=b(n);t&&(yield t)}for(const n of e(t,"wpt")){const t=x(n);t&&(yield t)}}const A=[["heartRate","heartRates"],["Cadence","cadences"],["Speed","speeds"],["Watts","watts"]],S=[["TotalTimeSeconds","totalTimeSeconds"],["DistanceMeters","distanceMeters"],["MaximumSpeed","maxSpeed"],["AverageHeartRateBpm","avgHeartRate"],["MaximumHeartRateBpm","maxHeartRate"],["AvgSpeed","avgSpeed"],["AvgWatts","avgWatts"],["MaxWatts","maxWatts"]];function v(t,e){const n=[];for(const[i,s]of e){let e=r(t,i);if(!e){const n=t.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/ActivityExtension/v2",i);n.length&&(e=n[0])}const c=parseFloat(o(e));isNaN(c)||n.push([s,c])}return n}function T(t){const e=[a(t,"LongitudeDegrees"),a(t,"LatitudeDegrees")];if(void 0===e[0]||isNaN(e[0])||void 0===e[1]||isNaN(e[1]))return null;const n=r(t,"HeartRateBpm"),i=o(r(t,"Time"));return r(t,"AltitudeMeters",(t=>{const n=parseFloat(o(t));isNaN(n)||e.push(n)})),{coordinates:e,time:i||null,heartRate:n?parseFloat(o(n)):null,extensions:v(t,A)}}function F(t){const n=e(t,"Trackpoint"),o=[],r=[],i=[];if(n.length<2)return null;const s={},c={extendedProperties:s};for(let t=0;t<n.length;t++){const e=T(n[t]);if(null===e)continue;o.push(e.coordinates);const{time:c,heartRate:a,extensions:l}=e;c&&r.push(c),a&&i.push(a);for(const[e,o]of l)s[e]||(s[e]=Array(n.length).fill(null)),s[e][t]=o}return o.length<2?null:Object.assign(c,{line:o,times:r,heartRates:i})}function P(t){const n=e(t,"Track"),r=[],s=[],c=[],a=[];let l;const u=Object.assign(Object.fromEntries(v(t,S)),i(t,"Name",(t=>({name:o(t)}))));for(const t of n)l=F(t),l&&(r.push(l.line),l.times.length&&s.push(l.times),l.heartRates.length&&c.push(l.heartRates),a.push(l.extendedProperties));for(let t=0;t<a.length;t++){const e=a[t];for(const o in e)1===n.length?l&&(u[o]=l.extendedProperties[o]):(u[o]||(u[o]=r.map((t=>Array(t.length).fill(null)))),u[o][t]=e[o])}return 0===r.length?null:((s.length||c.length)&&(u.coordinateProperties=Object.assign(s.length?{times:1===r.length?s[0]:s}:{},c.length?{heart:1===r.length?c[0]:c}:{})),{type:"Feature",properties:u,geometry:1===r.length?{type:"LineString",coordinates:r[0]}:{type:"MultiLineString",coordinates:r}})}function*O(t){for(const n of e(t,"Lap")){const t=P(n);t&&(yield t)}for(const n of e(t,"Courses")){const t=P(n);t&&(yield t)}}function w(t,e){const n={},o="stroke"==e||"fill"===e?e:e+"-color";return"#"===t[0]&&(t=t.substring(1)),6===t.length||3===t.length?n[o]="#"+t:8===t.length&&(n[e+"-opacity"]=parseInt(t.substring(0,2),16)/255,n[o]="#"+t.substring(6,8)+t.substring(4,6)+t.substring(2,4)),n}function M(t,e,n){const o={};return a(t,e,(t=>{o[n]=t})),o}function j(t,e){return i(t,"color",(t=>w(o(t),e)))}function L(t){return i(t,"Icon",((t,e)=>(s(t,"href",(t=>{e.icon=t})),e)))}function G(t){return Object.assign({},function(t){return i(t,"PolyStyle",((t,e)=>Object.assign(e,i(t,"color",(t=>w(o(t),"fill"))),s(t,"fill",(t=>{if("0"===t)return{"fill-opacity":0}})),s(t,"outline",(t=>{if("0"===t)return{"stroke-opacity":0}})))))}(t),function(t){return i(t,"LineStyle",(t=>Object.assign(j(t,"stroke"),M(t,"width","stroke-width"))))}(t),function(t){return i(t,"LabelStyle",(t=>Object.assign(j(t,"label"),M(t,"scale","label-scale"))))}(t),function(t){return i(t,"IconStyle",(t=>Object.assign(j(t,"icon"),M(t,"scale","icon-scale"),M(t,"heading","icon-heading"),i(t,"hotSpot",(t=>{const e=parseFloat(t.getAttribute("x")||""),n=parseFloat(t.getAttribute("y")||""),o=t.getAttribute("xunits")||"",r=t.getAttribute("yunits")||"";return isNaN(e)||isNaN(n)?{}:{"icon-offset":[e,n],"icon-offset-units":[o,r]}})),L(t))))}(t))}const R=t=>Number(t),B={string:t=>t,int:R,uint:R,short:R,ushort:R,float:R,double:R,bool:t=>Boolean(t)};function E(t,n){return i(t,"ExtendedData",((t,i)=>{for(const n of e(t,"Data"))i[n.getAttribute("name")||""]=o(r(n,"value"));for(const r of e(t,"SimpleData")){const t=r.getAttribute("name")||"",e=n[t]||B.string;i[t]=e(o(r))}return i}))}function C(t){const e=r(t,"description");for(const t of Array.from(e?.childNodes||[]))if(4===t.nodeType)return{description:{"@type":"html",value:o(t)}};return{}}function D(t){return i(t,"TimeSpan",(t=>({timespan:{begin:o(r(t,"begin")),end:o(r(t,"end"))}})))}function W(t){return i(t,"TimeStamp",(t=>({timestamp:o(r(t,"when"))})))}function H(t,e){return s(t,"styleUrl",(t=>(t=n(t),e[t]?Object.assign({styleUrl:t},e[t]):{styleUrl:t})))}const _=/\s*/g,I=/^\s*|\s*$/g,U=/\s+/;function V(t){return t.replace(_,"").split(",").map(parseFloat).filter((t=>!isNaN(t))).slice(0,3)}function $(t){return t.replace(I,"").split(U).map(V).filter((t=>t.length>=2))}function q(t){let n=e(t,"coord");var r,i,s;0===n.length&&(r=t,i="coord",s="*",n=Array.from(r.getElementsByTagNameNS(s,i)));const c=n.map((t=>o(t).split(" ").map(parseFloat)));return 0===c.length?null:{geometry:c.length>2?{type:"LineString",coordinates:c}:{type:"Point",coordinates:c[0]},times:e(t,"when").map((t=>o(t)))}}function z(t){if(0===t.length)return t;const e=t[0],n=t[t.length-1];let o=!0;for(let t=0;t<Math.max(e.length,n.length);t++)if(e[t]!==n[t]){o=!1;break}return o?t:t.concat([t[0]])}function J(t){return o(r(t,"coordinates"))}function Q(t){let n=[],o=[];for(let r=0;r<t.childNodes.length;r++){const i=t.childNodes.item(r);if(u(i))switch(i.tagName){case"MultiGeometry":case"MultiTrack":case"gx:MultiTrack":{const t=Q(i);n=n.concat(t.geometries),o=o.concat(t.coordTimes);break}case"Point":{const t=V(J(i));t.length>=2&&n.push({type:"Point",coordinates:t});break}case"LinearRing":case"LineString":{const t=$(J(i));t.length>=2&&n.push({type:"LineString",coordinates:t});break}case"Polygon":{const t=[];for(const n of e(i,"LinearRing")){const e=z($(J(n)));e.length>=4&&t.push(e)}t.length&&n.push({type:"Polygon",coordinates:t});break}case"Track":case"gx:Track":{const t=q(i);if(!t)break;const{times:e,geometry:r}=t;n.push(r),e.length&&o.push(e);break}}}return{geometries:n,coordTimes:o}}function K(t,e,n,o){const{coordTimes:r,geometries:i}=Q(t),s=function(t){return 0===t.length?null:1===t.length?t[0]:{type:"GeometryCollection",geometries:t}}(i);if(!s&&o.skipNullGeometry)return null;const c={type:"Feature",geometry:s,properties:Object.assign(l(t,["name","address","visibility","open","phoneNumber","description"]),C(t),H(t,e),G(t),E(t,n),D(t),W(t),r.length?{coordinateProperties:{times:1===r.length?r[0]:r}}:{})};void 0!==c.properties?.visibility&&(c.properties.visibility="0"!==c.properties.visibility);const a=t.getAttribute("id");return null!==a&&""!==a&&(c.id=a),c}function X(t){if(r(t,"gx:LatLonQuad")){return{geometry:{type:"Polygon",coordinates:[z($(J(t)))]}}}return function(t){const e=r(t,"LatLonBox");if(e){const t=a(e,"north"),n=a(e,"west"),o=a(e,"east"),r=a(e,"south"),i=a(e,"rotation");if("number"==typeof t&&"number"==typeof r&&"number"==typeof n&&"number"==typeof o){const e=[n,r,o,t];let s=[[[n,t],[o,t],[o,r],[n,r],[n,t]]];return"number"==typeof i&&(s=function(t,e,n){const o=[(t[0]+t[2])/2,(t[1]+t[3])/2];return[e[0].map((t=>{const e=t[1]-o[1],r=t[0]-o[0],i=Math.sqrt(Math.pow(e,2)+Math.pow(r,2)),s=Math.atan2(e,r)+n*Y;return[o[0]+Math.cos(s)*i,o[1]+Math.sin(s)*i]}))]}(e,s,i)),{bbox:e,geometry:{type:"Polygon",coordinates:s}}}}return null}(t)}const Y=Math.PI/180;function Z(t,e,n,o){const r=X(t),i=r?.geometry||null;if(!i&&o.skipNullGeometry)return null;const s={type:"Feature",geometry:i,properties:Object.assign({"@geometry-type":"groundoverlay"},l(t,["name","address","visibility","open","phoneNumber","description"]),C(t),H(t,e),G(t),L(t),E(t,n),D(t),W(t))};r?.bbox&&(s.bbox=r.bbox),void 0!==s.properties?.visibility&&(s.properties.visibility="0"!==s.properties.visibility);const c=t.getAttribute("id");return null!==c&&""!==c&&(s.id=c),s}function tt(t){let e=t.getAttribute("id");const o=t.parentNode;return!e&&u(o)&&"CascadingStyle"===o.localName&&(e=o.getAttribute("kml:id")||o.getAttribute("id")),n(e||"")}function et(t){const o={};for(const n of e(t,"Style"))o[tt(n)]=G(n);for(const r of e(t,"StyleMap")){const t=n(r.getAttribute("id")||"");s(r,"styleUrl",(e=>{e=n(e),o[e]&&(o[t]=o[e])}))}return o}function nt(t){const n={};for(const o of e(t,"SimpleField"))n[o.getAttribute("name")||""]=B[o.getAttribute("type")||""]||B.string;return n}const ot=["name","visibility","open","address","description","phoneNumber","visibility"];function*rt(t,n={skipNullGeometry:!1}){const o=et(t),r=nt(t);for(const i of e(t,"Placemark")){const t=K(i,o,r,n);t&&(yield t)}for(const i of e(t,"GroundOverlay")){const t=Z(i,o,r,n);t&&(yield t)}}t.gpx=function(t){return{type:"FeatureCollection",features:Array.from(k(t))}},t.gpxGen=k,t.kml=function(t,e={skipNullGeometry:!1}){return{type:"FeatureCollection",features:Array.from(rt(t,e))}},t.kmlGen=rt,t.kmlWithFolders=function(t,e={skipNullGeometry:!1}){const n=et(t),r=nt(t),i={type:"root",children:[]};return function t(e,i,s){if(u(e))switch(e.tagName){case"GroundOverlay":{const t=Z(e,n,r,s);t&&i.children.push(t);break}case"Placemark":{const t=K(e,n,r,s);t&&i.children.push(t);break}case"Folder":{const t=function(t){const e={};for(const n of Array.from(t.childNodes))u(n)&&ot.includes(n.tagName)&&(e[n.tagName]=o(n));return{type:"folder",meta:e,children:[]}}(e);i.children.push(t),i=t;break}}if(e.childNodes)for(let n=0;n<e.childNodes.length;n++)t(e.childNodes[n],i,s)}(t,i,e),i},t.tcx=function(t){return{type:"FeatureCollection",features:Array.from(O(t))}},t.tcxGen=O,Object.defineProperty(t,"__esModule",{value:!0})}));
2
+ //# sourceMappingURL=togeojson.umd.js.map
@@ -0,0 +1,2 @@
1
+ // https://github.com/topojson/topojson-client Version 1.8.0. Copyright 2016 Mike Bostock.
2
+ !function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.topojson=n.topojson||{})}(this,function(n){"use strict";function t(n){if(!n)return h;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0),n[0]=(t+=n[0])*e+i,n[1]=(r+=n[1])*o+u}}function r(n){if(!n)return h;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0);var c=Math.round((n[0]-i)/e),a=Math.round((n[1]-u)/o);n[0]=c-t,n[1]=a-r,t=c,r=a}}function e(n,t){for(var r,e=n.length,o=e-t;o<--e;)r=n[o],n[o++]=n[e],n[e]=r}function o(n,t){for(var r=0,e=n.length;r<e;){var o=r+e>>>1;n[o]<t?r=o+1:e=o}return r}function i(n,t){var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:u(n,t)};return null==t.id&&delete r.id,r}function u(n,r){function o(n,t){t.length&&t.pop();for(var r,o=l[n<0?~n:n],i=0,u=o.length;i<u;++i)t.push(r=o[i].slice()),s(r,i);n<0&&e(t,u)}function i(n){return n=n.slice(),s(n,0),n}function u(n){for(var t=[],r=0,e=n.length;r<e;++r)o(n[r],t);return t.length<2&&t.push(t[0].slice()),t}function f(n){for(var t=u(n);t.length<4;)t.push(t[0].slice());return t}function c(n){return n.map(f)}function a(n){var t=n.type;return"GeometryCollection"===t?{type:t,geometries:n.geometries.map(a)}:t in h?{type:t,coordinates:h[t](n)}:null}var s=t(n.transform),l=n.arcs,h={Point:function(n){return i(n.coordinates)},MultiPoint:function(n){return n.coordinates.map(i)},LineString:function(n){return u(n.arcs)},MultiLineString:function(n){return n.arcs.map(u)},Polygon:function(n){return c(n.arcs)},MultiPolygon:function(n){return n.arcs.map(c)}};return a(r)}function f(n,t,r){function e(n){var t=n<0?~n:n;(a[t]||(a[t]=[])).push({i:n,g:c})}function o(n){n.forEach(e)}function i(n){n.forEach(o)}function u(n){"GeometryCollection"===n.type?n.geometries.forEach(u):n.type in s&&(c=n,s[n.type](n.arcs))}var f=[];if(arguments.length>1){var c,a=[],s={LineString:o,MultiLineString:i,Polygon:i,MultiPolygon:function(n){n.forEach(i)}};u(t),a.forEach(arguments.length<3?function(n){f.push(n[0].i)}:function(n){r(n[0].g,n[n.length-1].g)&&f.push(n[0].i)})}else for(var l=0,h=n.arcs.length;l<h;++l)f.push(l);return{type:"MultiLineString",arcs:v(n,f)}}function c(n){var t=n[0],r=n[1],e=n[2];return Math.abs((t[0]-e[0])*(r[1]-t[1])-(t[0]-r[0])*(e[1]-t[1]))}function a(n){for(var t,r=-1,e=n.length,o=n[e-1],i=0;++r<e;)t=o,o=n[r],i+=t[0]*o[1]-t[1]*o[0];return i/2}function s(n,t){function r(n){n.forEach(function(t){t.forEach(function(t){(o[t=t<0?~t:t]||(o[t]=[])).push(n)})}),i.push(n)}function e(t){return Math.abs(a(u(n,{type:"Polygon",arcs:[t]}).coordinates[0]))}var o={},i=[],f=[];return t.forEach(function(n){"Polygon"===n.type?r(n.arcs):"MultiPolygon"===n.type&&n.arcs.forEach(r)}),i.forEach(function(n){if(!n._){var t=[],r=[n];for(n._=1,f.push(t);n=r.pop();)t.push(n),n.forEach(function(n){n.forEach(function(n){o[n<0?~n:n].forEach(function(n){n._||(n._=1,r.push(n))})})})}}),i.forEach(function(n){delete n._}),{type:"MultiPolygon",arcs:f.map(function(t){var r,i=[];if(t.forEach(function(n){n.forEach(function(n){n.forEach(function(n){o[n<0?~n:n].length<2&&i.push(n)})})}),i=v(n,i),(r=i.length)>1)for(var u,f,c=1,a=e(i[0]);c<r;++c)(u=e(i[c]))>a&&(f=i[0],i[0]=i[c],i[c]=f,a=u);return i})}}function l(n,t){return n[1][2]-t[1][2]}var h=function(){},p=function(n,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return i(n,t)})}:i(n,t)},v=function(n,t){function r(t){var r,e=n.arcs[t<0?~t:t],o=e[0];return n.transform?(r=[0,0],e.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=e[e.length-1],t<0?[r,o]:[o,r]}function e(n,t){for(var r in n){var e=n[r];delete t[e.start],delete e.start,delete e.end,e.forEach(function(n){o[n<0?~n:n]=1}),f.push(e)}}var o={},i={},u={},f=[],c=-1;return t.forEach(function(r,e){var o,i=n.arcs[r<0?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++c],t[c]=r,t[e]=o)}),t.forEach(function(n){var t,e,o=r(n),f=o[0],c=o[1];if(t=u[f])if(delete u[t.end],t.push(n),t.end=c,e=i[c]){delete i[e.start];var a=e===t?t:t.concat(e);i[a.start=t.start]=u[a.end=e.end]=a}else i[t.start]=u[t.end]=t;else if(t=i[c])if(delete i[t.start],t.unshift(n),t.start=f,e=u[f]){delete u[e.end];var s=e===t?t:e.concat(t);i[s.start=e.start]=u[s.end=t.end]=s}else i[t.start]=u[t.end]=t;else t=[n],i[t.start=f]=u[t.end=c]=t}),e(u,i),e(i,u),t.forEach(function(n){o[n<0?~n:n]||f.push([n])}),f},g=function(n){return u(n,f.apply(this,arguments))},d=function(n){return u(n,s.apply(this,arguments))},y=function(n){function t(n,t){n.forEach(function(n){n<0&&(n=~n);var r=i[n];r?r.push(t):i[n]=[t]})}function r(n,r){n.forEach(function(n){t(n,r)})}function e(n,t){"GeometryCollection"===n.type?n.geometries.forEach(function(n){e(n,t)}):n.type in f&&f[n.type](n.arcs,t)}var i={},u=n.map(function(){return[]}),f={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(n,t){n.forEach(function(n){r(n,t)})}};n.forEach(e);for(var c in i)for(var a=i[c],s=a.length,l=0;l<s;++l)for(var h=l+1;h<s;++h){var p,v=a[l],g=a[h];(p=u[v])[c=o(p,g)]!==g&&p.splice(c,0,g),(p=u[g])[c=o(p,v)]!==v&&p.splice(c,0,v)}return u},m=function(){function n(n,t){for(;t>0;){var r=(t+1>>1)-1,o=e[r];if(l(n,o)>=0)break;e[o._=t]=o,e[n._=t=r]=n}}function t(n,t){for(;;){var r=t+1<<1,i=r-1,u=t,f=e[u];if(i<o&&l(e[i],f)<0&&(f=e[u=i]),r<o&&l(e[r],f)<0&&(f=e[u=r]),u===t)break;e[f._=t]=f,e[n._=t=u]=n}}var r={},e=[],o=0;return r.push=function(t){return n(e[t._=o]=t,o++),o},r.pop=function(){if(!(o<=0)){var n,r=e[0];return--o>0&&(n=e[o],t(e[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(e[u]===r)return u!==--o&&(i=e[o],(l(i,r)<0?n:t)(e[i._=u]=i,u)),u},r},E=function(n,e){function o(n){f.remove(n),n[1][2]=e(n),f.push(n)}var i=t(n.transform),u=r(n.transform),f=m();return null==e&&(e=c),n.arcs.forEach(function(n){var t,r,c,a,s=[],l=0;for(r=0,c=n.length;r<c;++r)a=n[r],i(n[r]=[a[0],a[1],1/0],r);for(r=1,c=n.length-1;r<c;++r)t=n.slice(r-1,r+2),t[1][2]=e(t),s.push(t),f.push(t);for(r=0,c=s.length;r<c;++r)t=s[r],t.previous=s[r-1],t.next=s[r+1];for(;t=f.pop();){var h=t.previous,p=t.next;t[1][2]<l?t[1][2]=l:l=t[1][2],h&&(h.next=p,h[2]=t[2],o(h)),p&&(p.previous=h,p[0]=t[0],o(p))}n.forEach(u)}),n};n.mesh=g,n.meshArcs=f,n.merge=d,n.mergeArcs=s,n.feature=p,n.neighbors=y,n.presimplify=E,Object.defineProperty(n,"__esModule",{value:!0})});
@@ -257,6 +257,10 @@ var readFile = function(file) {
257
257
  console.log("ZIP FILE",file);
258
258
  }
259
259
  }
260
+ else if (file.type.indexOf('geo+json') !== -1 ) {
261
+ data = JSON.parse(data);
262
+ doGeojson(file.name,data,"geojson");
263
+ }
260
264
  else {
261
265
  try {
262
266
  data = JSON.parse(data);
@@ -2140,17 +2144,23 @@ function setMarker(data) {
2140
2144
  if (data.hasOwnProperty("fillColor")) { delete data.fillColor; }
2141
2145
  if (data.hasOwnProperty("radius")) { delete data.radius; }
2142
2146
  if (data.hasOwnProperty("greatcircle")) { delete data.greatcircle; }
2143
- for (var i in data) {
2144
- if ((i != "name") && (i != "length") && (i != "clickable")) {
2145
- if (typeof data[i] === "object") {
2146
- words += i +" : "+JSON.stringify(data[i])+"<br/>";
2147
- } else {
2148
- words += i +" : "+data[i]+"<br/>";
2147
+ if (data.popup) { words = data.popup; }
2148
+ else {
2149
+ words += '<table>';
2150
+ for (var i in data) {
2151
+ if ((i != "name") && (i != "length") && (i != "clickable")) {
2152
+ if (typeof data[i] === "object") {
2153
+ //
2154
+ words += '<tr><td>'+ i +'</td><td>' + JSON.stringify(data[i]) + '</td></tr>';
2155
+ } else {
2156
+ // words += i +" : "+data[i]+"<br/>";
2157
+ words += '<tr><td>'+ i +'</td><td>' + data[i] + '</td></tr>';
2158
+ }
2149
2159
  }
2150
2160
  }
2161
+ words += '<tr><td>lat, lon</td><td>'+ marker.getLatLng().toString().replace('LatLng(','').replace(')','') + '</td></tr>';
2162
+ words += '</table>';
2151
2163
  }
2152
- if (data.popup) { words = data.popup; }
2153
- else { words = words + marker.getLatLng().toString().replace('LatLng(','lat, lon : ').replace(')',''); }
2154
2164
  words = "<b>"+data.name+"</b><br/>" + words; //"<button style=\"border-radius:4px; float:right; background-color:lightgrey;\" onclick='popped=false;popmark.closePopup();'>X</button><br/>" + words;
2155
2165
  var wopt = {autoClose:false, closeButton:true, closeOnClick:false, minWidth:200};
2156
2166
  if (words.indexOf('<video ') >=0 || words.indexOf('<img ') >=0 ) { wopt.maxWidth="640"; }
@@ -2612,28 +2622,6 @@ function doCommand(cmd) {
2612
2622
  return customLayer;
2613
2623
  }
2614
2624
 
2615
- // Add a new KML overlay layer
2616
- // if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kml") ) {
2617
- // if (overlays.hasOwnProperty(cmd.map.overlay)) {
2618
- // overlays[cmd.map.overlay].removeFrom(map);
2619
- // existsalready = true;
2620
- // }
2621
- // try {
2622
- // const parser = new DOMParser();
2623
- // if (typeof cmd.map.kml === "object") { cmd.map.kml = new TextDecoder().decode(new Uint8Array(cmd.map.kml.data).buffer); }
2624
- // const kml = parser.parseFromString(cmd.map.kml, 'text/xml');
2625
- // const track = new L.KML(kml);
2626
- // overlays[cmd.map.overlay] = track;
2627
- // } catch(e) { console.log("Failed to parse KML",e) }
2628
- // if (!existsalready) {
2629
- // layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
2630
- // }
2631
- // if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2632
- // overlays[cmd.map.overlay].addTo(map);
2633
- // }
2634
- // if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2635
- // else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2636
- // }
2637
2625
  // Add a new KMZ overlay layer (or KML)
2638
2626
  //if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kmz")) {
2639
2627
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && ( cmd.map.hasOwnProperty("kmz") || cmd.map.hasOwnProperty("kml")) ) {
@@ -2695,6 +2683,10 @@ function doCommand(cmd) {
2695
2683
  overlays[cmd.map.overlay].removeFrom(map);
2696
2684
  existsalready = true;
2697
2685
  }
2686
+ // var gp = new DOMParser().parseFromString(cmd.map.gpx, "text/xml");
2687
+ // var json = window.toGeoJSON.gpx(gp);
2688
+ // console.log("j",json)
2689
+ // doGeojson(json.features[0].properties.name,json,json.features[0].properties.type) // DCJ name,geojson,layer,options
2698
2690
  overlays[cmd.map.overlay] = omnivore.gpx.parse(cmd.map.gpx, null, custIco());
2699
2691
  if (!existsalready) {
2700
2692
  layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
@@ -2874,7 +2866,7 @@ function doCommand(cmd) {
2874
2866
 
2875
2867
  // handle any incoming GEOJSON directly - may style badly
2876
2868
  function doGeojson(n,g,l,o) {
2877
- // console.log("GEOJSON",n,g,l,o)
2869
+ // console.log("GEOJSON",n,g,l,o) // name,geojson,layer,options
2878
2870
  var lay = l ?? g.name ?? "unknown";
2879
2871
  // if (!basemaps[lay]) {
2880
2872
  var opt = { style: function(feature) {
@@ -2968,6 +2960,8 @@ function doGeojson(n,g,l,o) {
2968
2960
  delete tx["marker-symbol"];
2969
2961
  delete tx["marker-color"];
2970
2962
  delete tx["marker-size"];
2963
+ delete tx["coordinateProperties"];
2964
+ delete tx["_gpxType"]
2971
2965
  tx = JSON.stringify(tx,null,' ');
2972
2966
  if ( tx !== "{}") {
2973
2967
  l.bindPopup('<pre style="overflow-x: scroll">'+tx.replace(/[\{\}"]/g,'')+'</pre>');
@@ -3021,7 +3015,9 @@ function doTAKjson(p) {
3021
3015
  }
3022
3016
  catch(e) { console.log(e); }
3023
3017
  d.alt = Number(p.point.hae) || 9999999;
3024
- if (d.alt === 9999999) { delete d.alt; }
3018
+ if (d.alt && d.alt == 9999999) { delete d.alt; }
3019
+ if (d.speed && d.speed == 9999999) { delete d.speed; }
3020
+ if (d.hdg && d.hdg == 9999999) { delete d.hdg; }
3025
3021
  handleCoTtypes(d,p);
3026
3022
  setMarker(d);
3027
3023
  }
@@ -3052,7 +3048,9 @@ function doTAKMCjson(p) {
3052
3048
  d.ttl = parseInt((+p.staleTime / 1000) - (+p.sendTime / 1000));
3053
3049
  } catch(e) { console.log(e); }
3054
3050
  d.alt = p.hae || 9999999;
3055
- if (d.alt === 9999999) { delete d.alt; }
3051
+ if (d.alt && d.alt == 9999999) { delete d.alt; }
3052
+ if (d.speed && d.speed == 9999999) { delete d.speed; }
3053
+ if (d.hdg && d.hdg == 9999999) { delete d.hdg; }
3056
3054
  handleCoTtypes(d,p);
3057
3055
  setMarker(d);
3058
3056
  }
@@ -1,470 +0,0 @@
1
- /*!
2
- Copyright (c) 2011-2015, Pavel Shramov, Bruno Bergot - MIT licence
3
- */
4
-
5
- L.KML = L.FeatureGroup.extend({
6
-
7
- initialize: function (kml) {
8
- this._kml = kml;
9
- this._layers = {};
10
-
11
- if (kml) {
12
- this.addKML(kml);
13
- }
14
- },
15
-
16
- addKML: function (xml) {
17
- var layers = L.KML.parseKML(xml);
18
- if (!layers || !layers.length) return;
19
- for (var i = 0; i < layers.length; i++) {
20
- this.fire('addlayer', {
21
- layer: layers[i]
22
- });
23
- this.addLayer(layers[i]);
24
- }
25
- this.latLngs = L.KML.getLatLngs(xml);
26
- this.fire('loaded');
27
- },
28
-
29
- latLngs: []
30
- });
31
-
32
- L.Util.extend(L.KML, {
33
-
34
- parseKML: function (xml) {
35
- var style = this.parseStyles(xml);
36
- this.parseStyleMap(xml, style);
37
- var el = xml.getElementsByTagName('Folder');
38
- var layers = [], l;
39
- for (var i = 0; i < el.length; i++) {
40
- if (!this._check_folder(el[i])) { continue; }
41
- l = this.parseFolder(el[i], style);
42
- if (l) { layers.push(l); }
43
- }
44
- el = xml.getElementsByTagName('Placemark');
45
- for (var j = 0; j < el.length; j++) {
46
- if (!this._check_folder(el[j])) { continue; }
47
- l = this.parsePlacemark(el[j], xml, style);
48
- if (l) { layers.push(l); }
49
- }
50
- el = xml.getElementsByTagName('GroundOverlay');
51
- for (var k = 0; k < el.length; k++) {
52
- l = this.parseGroundOverlay(el[k]);
53
- if (l) { layers.push(l); }
54
- }
55
- return layers;
56
- },
57
-
58
- // Return false if e's first parent Folder is not [folder]
59
- // - returns true if no parent Folders
60
- _check_folder: function (e, folder) {
61
- e = e.parentNode;
62
- while (e && e.tagName !== 'Folder')
63
- {
64
- e = e.parentNode;
65
- }
66
- return !e || e === folder;
67
- },
68
-
69
- parseStyles: function (xml) {
70
- var styles = {};
71
- var sl = xml.getElementsByTagName('Style');
72
- for (var i=0, len=sl.length; i<len; i++) {
73
- var style = this.parseStyle(sl[i]);
74
- if (style) {
75
- var styleName = '#' + style.id;
76
- styles[styleName] = style;
77
- }
78
- }
79
- return styles;
80
- },
81
-
82
- parseStyle: function (xml) {
83
- var style = {}, poptions = {}, ioptions = {}, el, id;
84
-
85
- var attributes = {color: true, width: true, Icon: true, href: true, hotSpot: true};
86
-
87
- function _parse (xml) {
88
- var options = {};
89
- for (var i = 0; i < xml.childNodes.length; i++) {
90
- var e = xml.childNodes[i];
91
- var key = e.tagName;
92
- if (!attributes[key]) { continue; }
93
- if (key === 'hotSpot')
94
- {
95
- for (var j = 0; j < e.attributes.length; j++) {
96
- options[e.attributes[j].name] = e.attributes[j].nodeValue;
97
- }
98
- } else {
99
- var value = e.childNodes[0].nodeValue;
100
- if (key === 'color') {
101
- options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
102
- options.color = '#' + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
103
- } else if (key === 'width') {
104
- options.weight = value;
105
- } else if (key === 'Icon') {
106
- ioptions = _parse(e);
107
- if (ioptions.href) { options.href = ioptions.href; }
108
- } else if (key === 'href') {
109
- options.href = value;
110
- }
111
- }
112
- }
113
- return options;
114
- }
115
-
116
- el = xml.getElementsByTagName('LineStyle');
117
- if (el && el[0]) { style = _parse(el[0]); }
118
- el = xml.getElementsByTagName('PolyStyle');
119
- if (el && el[0]) { poptions = _parse(el[0]); }
120
- if (poptions.color) { style.fillColor = poptions.color; }
121
- if (poptions.opacity) { style.fillOpacity = poptions.opacity; }
122
- el = xml.getElementsByTagName('IconStyle');
123
- if (el && el[0]) { ioptions = _parse(el[0]); }
124
- if (ioptions.href) {
125
- style.icon = new L.KMLIcon({
126
- iconUrl: ioptions.href,
127
- shadowUrl: null,
128
- anchorRef: {x: ioptions.x, y: ioptions.y},
129
- anchorType: {x: ioptions.xunits, y: ioptions.yunits}
130
- });
131
- }
132
- el = xml.getElementsByTagName('Data');
133
- if (el && el[0]) {
134
- var appicon = el[0].getElementsByTagName('value')[0].innerHTML;
135
- var sidc;
136
- if (appicon.indexOf("APP-6D") === 0) {
137
- sidc = appicon.split(':')[1];
138
- var mysymbol = new ms.Symbol(sidc);
139
- mysymbol = mysymbol.setOptions({ size:20 });
140
- style.icon = L.icon({
141
- iconUrl: mysymbol.toDataURL(),
142
- iconAnchor: [mysymbol.getAnchor().x, mysymbol.getAnchor().y],
143
- });
144
- }
145
- }
146
-
147
- id = xml.getAttribute('id');
148
- if (id && style) {
149
- style.id = id;
150
- }
151
-
152
- return style;
153
- },
154
-
155
- parseStyleMap: function (xml, existingStyles) {
156
- var sl = xml.getElementsByTagName('StyleMap');
157
-
158
- for (var i = 0; i < sl.length; i++) {
159
- var e = sl[i], el;
160
- var smKey, smStyleUrl;
161
-
162
- el = e.getElementsByTagName('key');
163
- if (el && el[0]) { smKey = el[0].textContent; }
164
- el = e.getElementsByTagName('styleUrl');
165
- if (el && el[0]) { smStyleUrl = el[0].textContent; }
166
-
167
- if (smKey === 'normal')
168
- {
169
- existingStyles['#' + e.getAttribute('id')] = existingStyles[smStyleUrl];
170
- }
171
- }
172
-
173
- return;
174
- },
175
-
176
- parseFolder: function (xml, style) {
177
- var el, layers = [], l;
178
- el = xml.getElementsByTagName('Folder');
179
- for (var i = 0; i < el.length; i++) {
180
- if (!this._check_folder(el[i], xml)) { continue; }
181
- l = this.parseFolder(el[i], style);
182
- if (l) { layers.push(l); }
183
- }
184
- el = xml.getElementsByTagName('Placemark');
185
- for (var j = 0; j < el.length; j++) {
186
- if (!this._check_folder(el[j], xml)) { continue; }
187
- l = this.parsePlacemark(el[j], xml, style);
188
- if (l) { layers.push(l); }
189
- }
190
- el = xml.getElementsByTagName('GroundOverlay');
191
- for (var k = 0; k < el.length; k++) {
192
- if (!this._check_folder(el[k], xml)) { continue; }
193
- l = this.parseGroundOverlay(el[k]);
194
- if (l) { layers.push(l); }
195
- }
196
- if (!layers.length) { return; }
197
- if (layers.length === 1) { return layers[0]; }
198
- return new L.FeatureGroup(layers);
199
- },
200
-
201
- parsePlacemark: function (place, xml, style, options) {
202
- var h, i, j, k, el, il, opts = options || {};
203
-
204
- el = place.getElementsByTagName('styleUrl');
205
- for (i = 0; i < el.length; i++) {
206
- var url = el[i].childNodes[0].nodeValue;
207
- for (var a in style[url]) {
208
- opts[a] = style[url][a];
209
- }
210
- }
211
-
212
- il = place.getElementsByTagName('Style')[0];
213
- if (il) {
214
- var inlineStyle = this.parseStyle(place);
215
- if (inlineStyle) {
216
- for (k in inlineStyle) {
217
- opts[k] = inlineStyle[k];
218
- }
219
- }
220
- }
221
-
222
- var multi = ['MultiGeometry', 'MultiTrack', 'gx:MultiTrack'];
223
- for (h in multi) {
224
- el = place.getElementsByTagName(multi[h]);
225
- for (i = 0; i < el.length; i++) {
226
- return this.parsePlacemark(el[i], xml, style, opts);
227
- }
228
- }
229
-
230
- var layers = [];
231
-
232
- var parse = ['LineString', 'Polygon', 'Point', 'Track', 'gx:Track'];
233
- for (j in parse) {
234
- var tag = parse[j];
235
- el = place.getElementsByTagName(tag);
236
- for (i = 0; i < el.length; i++) {
237
- var l = this['parse' + tag.replace(/gx:/, '')](el[i], xml, opts);
238
- if (l) { layers.push(l); }
239
- }
240
- }
241
-
242
- if (!layers.length) {
243
- return;
244
- }
245
- var layer = layers[0];
246
- if (layers.length > 1) {
247
- layer = new L.FeatureGroup(layers);
248
- }
249
-
250
- var name, descr = '';
251
- el = place.getElementsByTagName('name');
252
- if (el.length && el[0].childNodes.length) {
253
- name = el[0].childNodes[0].nodeValue;
254
- }
255
- el = place.getElementsByTagName('description');
256
- for (i = 0; i < el.length; i++) {
257
- for (j = 0; j < el[i].childNodes.length; j++) {
258
- descr = descr + el[i].childNodes[j].nodeValue;
259
- }
260
- }
261
-
262
- if (name) {
263
- layer.on('add', function () {
264
- layer.bindPopup('<h2>' + name + '</h2>' + descr, { className: 'kml-popup'});
265
- });
266
- }
267
-
268
- return layer;
269
- },
270
-
271
- parseCoords: function (xml) {
272
- var el = xml.getElementsByTagName('coordinates');
273
- return this._read_coords(el[0]);
274
- },
275
-
276
- parseLineString: function (line, xml, options) {
277
- var coords = this.parseCoords(line);
278
- if (!coords.length) { return; }
279
- return new L.Polyline(coords, options);
280
- },
281
-
282
- parseTrack: function (line, xml, options) {
283
- var el = xml.getElementsByTagName('gx:coord');
284
- if (el.length === 0) { el = xml.getElementsByTagName('coord'); }
285
- var coords = [];
286
- for (var j = 0; j < el.length; j++) {
287
- coords = coords.concat(this._read_gxcoords(el[j]));
288
- }
289
- if (!coords.length) { return; }
290
- return new L.Polyline(coords, options);
291
- },
292
-
293
- parsePoint: function (line, xml, options) {
294
- var el = line.getElementsByTagName('coordinates');
295
- if (!el.length) {
296
- return;
297
- }
298
- var ll = el[0].childNodes[0].nodeValue.split(',');
299
- return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
300
- },
301
-
302
- parsePolygon: function (line, xml, options) {
303
- var el, polys = [], inner = [], i, coords;
304
- el = line.getElementsByTagName('outerBoundaryIs');
305
- for (i = 0; i < el.length; i++) {
306
- coords = this.parseCoords(el[i]);
307
- if (coords) {
308
- polys.push(coords);
309
- }
310
- }
311
- el = line.getElementsByTagName('innerBoundaryIs');
312
- for (i = 0; i < el.length; i++) {
313
- coords = this.parseCoords(el[i]);
314
- if (coords) {
315
- inner.push(coords);
316
- }
317
- }
318
- if (!polys.length) {
319
- return;
320
- }
321
- if (options.fillColor) {
322
- options.fill = true;
323
- }
324
- if (polys.length === 1) {
325
- return new L.Polygon(polys.concat(inner), options);
326
- }
327
- return new L.MultiPolygon(polys, options);
328
- },
329
-
330
- getLatLngs: function (xml) {
331
- var el = xml.getElementsByTagName('coordinates');
332
- var coords = [];
333
- for (var j = 0; j < el.length; j++) {
334
- // text might span many childNodes
335
- coords = coords.concat(this._read_coords(el[j]));
336
- }
337
- return coords;
338
- },
339
-
340
- _read_coords: function (el) {
341
- var text = '', coords = [], i;
342
- for (i = 0; i < el.childNodes.length; i++) {
343
- text = text + el.childNodes[i].nodeValue;
344
- }
345
- text = text.split(/[\s\n]+/);
346
- for (i = 0; i < text.length; i++) {
347
- var ll = text[i].split(',');
348
- if (ll.length < 2) {
349
- continue;
350
- }
351
- coords.push(new L.LatLng(ll[1], ll[0]));
352
- }
353
- return coords;
354
- },
355
-
356
- _read_gxcoords: function (el) {
357
- var text = '', coords = [];
358
- text = el.firstChild.nodeValue.split(' ');
359
- coords.push(new L.LatLng(text[1], text[0]));
360
- return coords;
361
- },
362
-
363
- parseGroundOverlay: function (xml) {
364
- var latlonbox = xml.getElementsByTagName('LatLonBox')[0];
365
- var bounds = new L.LatLngBounds(
366
- [
367
- latlonbox.getElementsByTagName('south')[0].childNodes[0].nodeValue,
368
- latlonbox.getElementsByTagName('west')[0].childNodes[0].nodeValue
369
- ],
370
- [
371
- latlonbox.getElementsByTagName('north')[0].childNodes[0].nodeValue,
372
- latlonbox.getElementsByTagName('east')[0].childNodes[0].nodeValue
373
- ]
374
- );
375
- var attributes = {Icon: true, href: true, color: true};
376
- function _parse (xml) {
377
- var options = {}, ioptions = {};
378
- for (var i = 0; i < xml.childNodes.length; i++) {
379
- var e = xml.childNodes[i];
380
- var key = e.tagName;
381
- if (!attributes[key]) { continue; }
382
- var value = e.childNodes[0].nodeValue;
383
- if (key === 'Icon') {
384
- ioptions = _parse(e);
385
- if (ioptions.href) { options.href = ioptions.href; }
386
- } else if (key === 'href') {
387
- options.href = value;
388
- } else if (key === 'color') {
389
- options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
390
- options.color = '#' + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
391
- }
392
- }
393
- return options;
394
- }
395
- var options = {};
396
- options = _parse(xml);
397
- if (latlonbox.getElementsByTagName('rotation')[0] !== undefined) {
398
- var rotation = latlonbox.getElementsByTagName('rotation')[0].childNodes[0].nodeValue;
399
- options.rotation = parseFloat(rotation);
400
- }
401
- return new L.RotatedImageOverlay(options.href, bounds, {opacity: options.opacity, angle: options.rotation});
402
- }
403
-
404
- });
405
-
406
- L.KMLIcon = L.Icon.extend({
407
- options: {
408
- iconSize: [32, 32],
409
- iconAnchor: [16, 16],
410
- },
411
- _setIconStyles: function (img, name) {
412
- L.Icon.prototype._setIconStyles.apply(this, [img, name]);
413
- if( img.complete ) {
414
- this.applyCustomStyles( img )
415
- } else {
416
- img.onload = this.applyCustomStyles.bind(this,img)
417
- }
418
-
419
- },
420
- applyCustomStyles: function(img) {
421
- var options = this.options;
422
- this.options.popupAnchor = [0,(-0.83*img.height)];
423
- if (options.anchorType.x === 'fraction')
424
- img.style.marginLeft = (-options.anchorRef.x * img.width) + 'px';
425
- if (options.anchorType.y === 'fraction')
426
- img.style.marginTop = ((-(1 - options.anchorRef.y) * img.height) + 1) + 'px';
427
- if (options.anchorType.x === 'pixels')
428
- img.style.marginLeft = (-options.anchorRef.x) + 'px';
429
- if (options.anchorType.y === 'pixels')
430
- img.style.marginTop = (options.anchorRef.y - img.height + 1) + 'px';
431
- }
432
- });
433
-
434
-
435
- L.KMLMarker = L.Marker.extend({
436
- options: {
437
- icon: new L.KMLIcon.Default()
438
- }
439
- });
440
-
441
- // Inspired by https://github.com/bbecquet/Leaflet.PolylineDecorator/tree/master/src
442
- L.RotatedImageOverlay = L.ImageOverlay.extend({
443
- options: {
444
- angle: 0
445
- },
446
- _reset: function () {
447
- L.ImageOverlay.prototype._reset.call(this);
448
- this._rotate();
449
- },
450
- _animateZoom: function (e) {
451
- L.ImageOverlay.prototype._animateZoom.call(this, e);
452
- this._rotate();
453
- },
454
- _rotate: function () {
455
- if (L.DomUtil.TRANSFORM) {
456
- // use the CSS transform rule if available
457
- this._image.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
458
- } else if (L.Browser.ie) {
459
- // fallback for IE6, IE7, IE8
460
- var rad = this.options.angle * (Math.PI / 180),
461
- costheta = Math.cos(rad),
462
- sintheta = Math.sin(rad);
463
- this._image.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
464
- costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
465
- }
466
- },
467
- getBounds: function () {
468
- return this._bounds;
469
- }
470
- });