UNPKG

@tmcw/togeojson

Version:
3 lines (2 loc) 13.3 kB
!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 r(t){return t?.normalize(),t?.textContent||""}function o(t,e,n){const r=t.getElementsByTagName(e),o=r.length?r[0]:null;return o&&n&&n(o),o}function i(t,e,n){const r={};if(!t)return r;const o=t.getElementsByTagName(e),i=o.length?o[0]:null;return i&&n?n(i,r):r}function s(t,e,n){const i=r(o(t,e));return i&&n&&n(i)||{}}function c(t,e,n){const i=Number.parseFloat(r(o(t,e)));if(!Number.isNaN(i))return i&&n&&n(i)||{}}function a(t,e,n){const i=Number.parseFloat(r(o(t,e)));if(!Number.isNaN(i))return n&&n(i),i}function l(t,e){const n={};for(const r of e)s(t,r,(t=>{n[r]=t}));return n}function u(t){return 1===t?.nodeType}function f(t){let e=[];if(null===t)return e;for(const n of Array.from(t.childNodes)){if(!u(n))continue;const t=p(n.nodeName);if("gpxtpx:TrackPointExtension"===t)e=e.concat(f(n));else{const o=r(n);e.push([t,g(o)])}}return e}function p(t){return["heart","gpxtpx:hr","hr"].includes(t)?"heart":t}function g(t){const e=Number.parseFloat(t);return Number.isNaN(e)?t:e}function m(t){const e=[Number.parseFloat(t.getAttribute("lon")||""),Number.parseFloat(t.getAttribute("lat")||"")];if(Number.isNaN(e[0])||Number.isNaN(e[1]))return null;a(t,"ele",(t=>{e.push(t)}));const n=o(t,"time");return{coordinates:e,time:n?r(n):null,extendedValues:f(o(t,"extensions"))}}function d(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 h(t,n){const o=l(n,["name","cmt","desc","type","time","keywords"]);for(const[e,i]of t)for(const t of Array.from(n.getElementsByTagNameNS(i,"*")))o[t.tagName.replace(":","_")]=r(t)?.trim();const i=e(n,"link");return i.length&&(o.links=i.map((t=>Object.assign({href:t.getAttribute("href")},l(t,["text","type"]))))),o}function y(t,n){const r=e(t,n),o=[],i=[],s={};for(let t=0;t<r.length;t++){const e=m(r[t]);if(e){o.push(e.coordinates),e.time&&i.push(e.time);for(const[n,o]of e.extendedValues){const e="heart"===n?n:`${n.replace("gpxtpx:","")}s`;s[e]||(s[e]=Array(r.length).fill(null)),s[e][t]=o}}}if(!(o.length<2))return{line:o,times:i,extendedValues:s}}function b(t,e){const n=y(e,"rtept");if(n)return{type:"Feature",properties:Object.assign({_gpxType:"rte"},h(t,e),d(o(e,"extensions"))),geometry:{type:"LineString",coordinates:n.line}}}function N(t,n){const r=e(n,"trkseg"),i=[],s=[],c=[];for(const t of r){const e=y(t,"trkpt");e&&(c.push(e),e.times?.length&&s.push(e.times))}if(0===c.length)return null;const a=c.length>1,l=Object.assign({_gpxType:"trk"},h(t,n),d(o(n,"extensions")),s.length?{coordinateProperties:{times:a?s:s[0]}}:{});for(const t of c){i.push(t.line),l.coordinateProperties||(l.coordinateProperties={});const e=l.coordinateProperties,n=Object.entries(t.extendedValues);for(let t=0;t<n.length;t++){const[r,o]=n[t];a?(e[r]||(e[r]=c.map((t=>new Array(t.line.length).fill(null)))),e[r][t]=o):e[r]=o}}return{type:"Feature",properties:l,geometry:a?{type:"MultiLineString",coordinates:i}:{type:"LineString",coordinates:i[0]}}}function x(t,e){const n=Object.assign(h(t,e),l(e,["sym"])),r=m(e);return r?{type:"Feature",properties:n,geometry:{type:"Point",coordinates:r.coordinates}}:null}function*k(t){const n=t,r="http://www.garmin.com/xmlschemas/GpxExtensions/v3",o=[["gpxx",r]],i=n.getElementsByTagName("gpx")[0]?.attributes;if(i)for(const t of Array.from(i))t.name?.startsWith("xmlns:")&&t.value!==r&&o.push([t.name,t.value]);for(const t of e(n,"trk")){const e=N(o,t);e&&(yield e)}for(const t of e(n,"rte")){const e=b(o,t);e&&(yield e)}for(const t of e(n,"wpt")){const e=x(o,t);e&&(yield e)}}const A=[["heartRate","heartRates"],["Cadence","cadences"],["Speed","speeds"],["Watts","watts"]],v=[["TotalTimeSeconds","totalTimeSeconds"],["DistanceMeters","distanceMeters"],["MaximumSpeed","maxSpeed"],["AverageHeartRateBpm","avgHeartRate"],["MaximumHeartRateBpm","maxHeartRate"],["AvgSpeed","avgSpeed"],["AvgWatts","avgWatts"],["MaxWatts","maxWatts"]];function S(t,e){const n=[];for(const[i,s]of e){let e=o(t,i);if(!e){const n=t.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/ActivityExtension/v2",i);n.length&&(e=n[0])}const c=Number.parseFloat(r(e));Number.isNaN(c)||n.push([s,c])}return n}function T(t){const e=[a(t,"LongitudeDegrees"),a(t,"LatitudeDegrees")];if(void 0===e[0]||Number.isNaN(e[0])||void 0===e[1]||Number.isNaN(e[1]))return null;const n=o(t,"HeartRateBpm"),i=r(o(t,"Time"));return o(t,"AltitudeMeters",(t=>{const n=Number.parseFloat(r(t));Number.isNaN(n)||e.push(n)})),{coordinates:e,time:i||null,heartRate:n?Number.parseFloat(r(n)):null,extensions:S(t,A)}}function F(t){const n=e(t,"Trackpoint"),r=[],o=[],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;r.push(e.coordinates);const{time:c,heartRate:a,extensions:l}=e;c&&o.push(c),a&&i.push(a);for(const[e,r]of l)s[e]||(s[e]=Array(n.length).fill(null)),s[e][t]=r}return r.length<2?null:Object.assign(c,{line:r,times:o,heartRates:i})}function P(t){const n=e(t,"Track"),o=[],s=[],c=[],a=[];let l;const u=Object.assign(Object.fromEntries(S(t,v)),i(t,"Name",(t=>({name:r(t)}))));for(const t of n)l=F(t),l&&(o.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 r in e)1===n.length?l&&(u[r]=l.extendedProperties[r]):(u[r]||(u[r]=o.map((t=>Array(t.length).fill(null)))),u[r][t]=e[r])}return 0===o.length?null:((s.length||c.length)&&(u.coordinateProperties=Object.assign(s.length?{times:1===o.length?s[0]:s}:{},c.length?{heart:1===o.length?c[0]:c}:{})),{type:"Feature",properties:u,geometry:1===o.length?{type:"LineString",coordinates:o[0]}:{type:"MultiLineString",coordinates:o}})}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 j(t,e){const n={},r="stroke"===e||"fill"===e?e:`${e}-color`;return"#"===t[0]&&(t=t.substring(1)),6===t.length||3===t.length?n[r]=`#${t}`:8===t.length&&(n[`${e}-opacity`]=Number.parseInt(t.substring(0,2),16)/255,n[r]=`#${t.substring(6,8)}${t.substring(4,6)}${t.substring(2,4)}`),n}function w(t,e,n){const r={};return a(t,e,(t=>{r[n]=t})),r}function L(t,e){return i(t,"color",(t=>j(r(t),e)))}function M(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=>j(r(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(L(t,"stroke"),w(t,"width","stroke-width"))))}(t),function(t){return i(t,"LabelStyle",(t=>Object.assign(L(t,"label"),w(t,"scale","label-scale"))))}(t),function(t){return i(t,"IconStyle",(t=>Object.assign(L(t,"icon"),w(t,"scale","icon-scale"),w(t,"heading","icon-heading"),i(t,"hotSpot",(t=>{const e=Number.parseFloat(t.getAttribute("x")||""),n=Number.parseFloat(t.getAttribute("y")||""),r=t.getAttribute("xunits")||"",o=t.getAttribute("yunits")||"";return Number.isNaN(e)||Number.isNaN(n)?{}:{"icon-offset":[e,n],"icon-offset-units":[r,o]}})),M(t))))}(t))}const R=/\s*/g,B=/^\s*|\s*$/g,E=/\s+/;function $(t){return t.replace(R,"").split(",").map(Number.parseFloat).filter((t=>!Number.isNaN(t))).slice(0,3)}function C(t){return t.replace(B,"").split(E).map($).filter((t=>t.length>=2))}function W(t){let n=e(t,"coord");var o,i,s;0===n.length&&(o=t,i="coord",s="*",n=Array.from(o.getElementsByTagNameNS(s,i)));const c=n.map((t=>r(t).split(" ").map(Number.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=>r(t)))}}function D(t){if(0===t.length)return t;const e=t[0],n=t[t.length-1];let r=!0;for(let t=0;t<Math.max(e.length,n.length);t++)if(e[t]!==n[t]){r=!1;break}return r?t:t.concat([t[0]])}function H(t){return r(o(t,"coordinates"))}function I(t){let n=[],r=[];for(let o=0;o<t.childNodes.length;o++){const i=t.childNodes.item(o);if(u(i))switch(i.tagName){case"MultiGeometry":case"MultiTrack":case"gx:MultiTrack":{const t=I(i);n=n.concat(t.geometries),r=r.concat(t.coordTimes);break}case"Point":{const t=$(H(i));t.length>=2&&n.push({type:"Point",coordinates:t});break}case"LinearRing":case"LineString":{const t=C(H(i));t.length>=2&&n.push({type:"LineString",coordinates:t});break}case"Polygon":{const t=[];for(const n of e(i,"LinearRing")){const e=D(C(H(n)));e.length>=4&&t.push(e)}t.length&&n.push({type:"Polygon",coordinates:t});break}case"Track":case"gx:Track":{const t=W(i);if(!t)break;const{times:e,geometry:o}=t;n.push(o),e.length&&r.push(e);break}}}return{geometries:n,coordTimes:r}}const U=t=>Number(t),V={string:t=>t,int:U,uint:U,short:U,ushort:U,float:U,double:U,bool:t=>Boolean(t)};function _(t,n){return i(t,"ExtendedData",((t,i)=>{for(const n of e(t,"Data"))i[n.getAttribute("name")||""]=r(o(n,"value"));for(const o of e(t,"SimpleData")){const t=o.getAttribute("name")||"",e=n[t]||V.string;i[t]=e(r(o))}return i}))}function q(t){const e=o(t,"description");for(const t of Array.from(e?.childNodes||[]))if(4===t.nodeType)return{description:{"@type":"html",value:r(t)}};return{}}function z(t){return i(t,"TimeSpan",(t=>({timespan:{begin:r(o(t,"begin")),end:r(o(t,"end"))}})))}function J(t){return i(t,"TimeStamp",(t=>({timestamp:r(o(t,"when"))})))}function Q(t,e){return s(t,"styleUrl",(t=>(t=n(t),e[t]?Object.assign({styleUrl:t},e[t]):{styleUrl:t})))}function K(t){if(o(t,"gx:LatLonQuad")){return{geometry:{type:"Polygon",coordinates:[D(C(H(t)))]}}}return function(t){const e=o(t,"LatLonBox");if(e){const t=a(e,"north"),n=a(e,"west"),r=a(e,"east"),o=a(e,"south"),i=a(e,"rotation");if("number"==typeof t&&"number"==typeof o&&"number"==typeof n&&"number"==typeof r){const e=[n,o,r,t];let s=[[[n,t],[r,t],[r,o],[n,o],[n,t]]];return"number"==typeof i&&(s=function(t,e,n){const r=[(t[0]+t[2])/2,(t[1]+t[3])/2];return[e[0].map((t=>{const e=t[1]-r[1],o=t[0]-r[0],i=Math.sqrt(e**2+o**2),s=Math.atan2(e,o)+n*X;return[r[0]+Math.cos(s)*i,r[1]+Math.sin(s)*i]}))]}(e,s,i)),{bbox:e,geometry:{type:"Polygon",coordinates:s}}}}return null}(t)}const X=Math.PI/180;function Y(t,e,n,r){const o=K(t),i=o?.geometry||null;if(!i&&r.skipNullGeometry)return null;const s={type:"Feature",geometry:i,properties:Object.assign({"@geometry-type":"groundoverlay"},l(t,["name","address","visibility","open","phoneNumber","description"]),q(t),Q(t,e),G(t),M(t),_(t,n),z(t),J(t))};o?.bbox&&(s.bbox=o.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 Z(t,e,n,r){const{coordTimes:o,geometries:i}=I(t),s=function(t){return 0===t.length?null:1===t.length?t[0]:{type:"GeometryCollection",geometries:t}}(i);if(!s&&r.skipNullGeometry)return null;const c={type:"Feature",geometry:s,properties:Object.assign(l(t,["name","address","visibility","open","phoneNumber","description"]),q(t),Q(t,e),G(t),_(t,n),z(t),J(t),o.length?{coordinateProperties:{times:1===o.length?o[0]:o}}:{})};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 tt(t){let e=t.getAttribute("id");const r=t.parentNode;return!e&&u(r)&&"CascadingStyle"===r.localName&&(e=r.getAttribute("kml:id")||r.getAttribute("id")),n(e||"")}function et(t){const r={};for(const n of e(t,"Style"))r[tt(n)]=G(n);for(const o of e(t,"StyleMap")){const t=n(o.getAttribute("id")||"");s(o,"styleUrl",(e=>{e=n(e),r[e]&&(r[t]=r[e])}))}return r}function nt(t){const n={};for(const r of e(t,"SimpleField"))n[r.getAttribute("name")||""]=V[r.getAttribute("type")||""]||V.string;return n}const rt=["name","visibility","open","address","description","phoneNumber","visibility"];function*ot(t,n={skipNullGeometry:!1}){const r=t,o=et(r),i=nt(r);for(const t of e(r,"Placemark")){const e=Z(t,o,i,n);e&&(yield e)}for(const t of e(r,"GroundOverlay")){const e=Y(t,o,i,n);e&&(yield e)}}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(ot(t,e))}},t.kmlGen=ot,t.kmlWithFolders=function(t,e={skipNullGeometry:!1}){const n=t,o=et(n),i=nt(n),s={type:"root",children:[]};return function t(e,n,s){if(u(e))switch(e.tagName){case"GroundOverlay":{const t=Y(e,o,i,s);t&&n.children.push(t);break}case"Placemark":{const t=Z(e,o,i,s);t&&n.children.push(t);break}case"Folder":{const t=function(t){const e={};for(const n of Array.from(t.childNodes))u(n)&&rt.includes(n.tagName)&&(e[n.tagName]=r(n));return{type:"folder",meta:e,children:[]}}(e);n.children.push(t),n=t;break}}if(e.childNodes)for(let r=0;r<e.childNodes.length;r++)t(e.childNodes[r],n,s)}(n,s,e),s},t.tcx=function(t){return{type:"FeatureCollection",features:Array.from(O(t))}},t.tcxGen=O})); //# sourceMappingURL=togeojson.umd.js.map