node-red-contrib-web-worldmap 2.42.2 → 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,6 +1,6 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
- - v2.42.2 - More KML and GEOJson drag drop fixes
3
+ - v2.42.3 - More KML and GEOJson drag drop fixes
4
4
  - v2.42.1 - Remove extraneous debug logging, fix KMZ icons
5
5
  - v2.42.0 - Add handling for TAK type spots, waypoints, alerts, sensors. Better KML/KMZ handling.
6
6
  - v2.41.0 - Bump leaflet libs to latest stable (1.9.4)
package/README.md CHANGED
@@ -13,7 +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.2 - More KML and GEOJson drag drop fixes
16
+ - v2.42.3 - More KML and GEOJson drag drop fixes
17
17
  - v2.42.1 - Remove extraneous debug logging, fix KMZ icons
18
18
  - v2.42.0 - Add handling for TAK type spots, waypoints, alerts, sensors. Better KML/KMZ handling.
19
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.2",
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>
@@ -232,9 +232,10 @@
232
232
  var preferCanvas = this._map ? this._map.options.preferCanvas : this.options.preferCanvas;
233
233
  // var emptyIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E";
234
234
  // parse GeoJSON
235
+ //console.log("DATA",data)
235
236
  var layer = L.geoJson(data, {
236
237
  pointToLayer: (feature, latlng) => {
237
- // console.log("FEAT",feature)
238
+ //console.log("FEAT",feature)
238
239
  if (preferCanvas) {
239
240
  return L.kmzMarker(latlng, {
240
241
  iconUrl: data.properties.icons[feature.properties.icon] || feature.properties.icon,
@@ -249,12 +250,25 @@
249
250
  iconAnchor: [14, 14],
250
251
  })
251
252
  if (feature.properties && feature.properties.SymbolSpecification) {
252
- 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
+
253
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 }); }
254
267
  kicon = L.icon({
255
268
  iconUrl: mysymbol.toDataURL(),
256
269
  iconAnchor: [mysymbol.getAnchor().x, mysymbol.getAnchor().y],
257
270
  });
271
+ //console.log("META",mysymbol.getMetadata())
258
272
  }
259
273
  if (kicon.options.iconUrl === undefined) { // No icon found so just use default marker.
260
274
  return L.marker(latlng);
@@ -268,7 +282,7 @@
268
282
  // TODO: handle L.svg renderer within the L.KMZMarker class?
269
283
  },
270
284
  style: (feature) => {
271
- // console.log("FEATSTYLE",feature)
285
+ //console.log("FEATSTYLE",feature)
272
286
  var styles = {};
273
287
  var prop = feature.properties;
274
288
 
@@ -293,17 +307,17 @@
293
307
  return styles;
294
308
  },
295
309
  onEachFeature: (feature, layer) => {
296
- // console.log("POP",feature.properties)
310
+ //console.log("POP",feature.properties)
297
311
  //if (!this.options.ballon) return;
298
-
299
312
  var prop = feature.properties;
300
313
  var name = (prop.name || "").trim();
301
- var desc = (prop.description || "").trim();
314
+ // var desc = (prop.description || "").trim();
315
+ var desc = prop.description || "";
302
316
 
303
317
  var p = '<div>';
304
318
  if (name || desc) {
305
319
  // if (this.options.bindPopup) {
306
- // p += '<b>' + name + '</b>' + '<br>' + desc + '</div>';
320
+ p += '<b>' + name + '</b>' + '<br>' + desc + '</div>';
307
321
  // }
308
322
  if (this.options.bindTooltip) {
309
323
  layer.bindTooltip('<b>' + name + '</b>', {
@@ -314,18 +328,20 @@
314
328
  }
315
329
 
316
330
  var u = {};
317
- if (prop.FeaturePlatformId) { u.FeaturePlatformId = prop.FeaturePlatformId; }
318
- if (prop.FeatureAddress) { u.FeatureAddress = prop.FeatureAddress; }
319
- if (prop.SymbolSpecification) { u.Symbol = prop.SymbolSpecification; }
320
- if (prop.Speed) { u.Speed = prop.Speed; }
321
- if (prop.FeatureLastModified) { u.LastUpdate = prop.FeatureLastModified; }
322
- if (u.LastUpdate) { u.LastUpdate = (new Date(u.LastUpdate*1000)).toISOString(); }
323
-
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">';
324
340
  Object.entries(u).forEach(([key, value]) => {
325
- p += '<b>'+key+'</b> : '+value+'<br/>';
341
+ p += '<tr><td>'+key+'</td><td>'+value+'</td></tr>';
326
342
  });
327
- p += '</div>';
328
- if (p !== '<div></div>') {
343
+ p += '</table></div>';
344
+ if (p !== '<div><table border="0"></table></div>') {
329
345
  layer.bindPopup(p);
330
346
  }
331
347
  },
@@ -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})});
@@ -2144,17 +2144,23 @@ function setMarker(data) {
2144
2144
  if (data.hasOwnProperty("fillColor")) { delete data.fillColor; }
2145
2145
  if (data.hasOwnProperty("radius")) { delete data.radius; }
2146
2146
  if (data.hasOwnProperty("greatcircle")) { delete data.greatcircle; }
2147
- for (var i in data) {
2148
- if ((i != "name") && (i != "length") && (i != "clickable")) {
2149
- if (typeof data[i] === "object") {
2150
- words += i +" : "+JSON.stringify(data[i])+"<br/>";
2151
- } else {
2152
- 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
+ }
2153
2159
  }
2154
2160
  }
2161
+ words += '<tr><td>lat, lon</td><td>'+ marker.getLatLng().toString().replace('LatLng(','').replace(')','') + '</td></tr>';
2162
+ words += '</table>';
2155
2163
  }
2156
- if (data.popup) { words = data.popup; }
2157
- else { words = words + marker.getLatLng().toString().replace('LatLng(','lat, lon : ').replace(')',''); }
2158
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;
2159
2165
  var wopt = {autoClose:false, closeButton:true, closeOnClick:false, minWidth:200};
2160
2166
  if (words.indexOf('<video ') >=0 || words.indexOf('<img ') >=0 ) { wopt.maxWidth="640"; }
@@ -2616,28 +2622,6 @@ function doCommand(cmd) {
2616
2622
  return customLayer;
2617
2623
  }
2618
2624
 
2619
- // Add a new KML overlay layer
2620
- // if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kml") ) {
2621
- // if (overlays.hasOwnProperty(cmd.map.overlay)) {
2622
- // overlays[cmd.map.overlay].removeFrom(map);
2623
- // existsalready = true;
2624
- // }
2625
- // try {
2626
- // const parser = new DOMParser();
2627
- // if (typeof cmd.map.kml === "object") { cmd.map.kml = new TextDecoder().decode(new Uint8Array(cmd.map.kml.data).buffer); }
2628
- // const kml = parser.parseFromString(cmd.map.kml, 'text/xml');
2629
- // const track = new L.KML(kml);
2630
- // overlays[cmd.map.overlay] = track;
2631
- // } catch(e) { console.log("Failed to parse KML",e) }
2632
- // if (!existsalready) {
2633
- // layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
2634
- // }
2635
- // if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
2636
- // overlays[cmd.map.overlay].addTo(map);
2637
- // }
2638
- // if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
2639
- // else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
2640
- // }
2641
2625
  // Add a new KMZ overlay layer (or KML)
2642
2626
  //if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kmz")) {
2643
2627
  if (cmd.map && cmd.map.hasOwnProperty("overlay") && ( cmd.map.hasOwnProperty("kmz") || cmd.map.hasOwnProperty("kml")) ) {
@@ -2699,6 +2683,10 @@ function doCommand(cmd) {
2699
2683
  overlays[cmd.map.overlay].removeFrom(map);
2700
2684
  existsalready = true;
2701
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
2702
2690
  overlays[cmd.map.overlay] = omnivore.gpx.parse(cmd.map.gpx, null, custIco());
2703
2691
  if (!existsalready) {
2704
2692
  layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
@@ -2972,6 +2960,8 @@ function doGeojson(n,g,l,o) {
2972
2960
  delete tx["marker-symbol"];
2973
2961
  delete tx["marker-color"];
2974
2962
  delete tx["marker-size"];
2963
+ delete tx["coordinateProperties"];
2964
+ delete tx["_gpxType"]
2975
2965
  tx = JSON.stringify(tx,null,' ');
2976
2966
  if ( tx !== "{}") {
2977
2967
  l.bindPopup('<pre style="overflow-x: scroll">'+tx.replace(/[\{\}"]/g,'')+'</pre>');
@@ -3025,7 +3015,9 @@ function doTAKjson(p) {
3025
3015
  }
3026
3016
  catch(e) { console.log(e); }
3027
3017
  d.alt = Number(p.point.hae) || 9999999;
3028
- 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; }
3029
3021
  handleCoTtypes(d,p);
3030
3022
  setMarker(d);
3031
3023
  }
@@ -3056,7 +3048,9 @@ function doTAKMCjson(p) {
3056
3048
  d.ttl = parseInt((+p.staleTime / 1000) - (+p.sendTime / 1000));
3057
3049
  } catch(e) { console.log(e); }
3058
3050
  d.alt = p.hae || 9999999;
3059
- 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; }
3060
3054
  handleCoTtypes(d,p);
3061
3055
  setMarker(d);
3062
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
- });