├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── dist
├── maplibre-gl-vector-text-protocol.esm.js
├── maplibre-gl-vector-text-protocol.js
├── maplibre-gl-vector-text-protocol.min.js
├── maplibre-gl-vector-text-protocol.min.js.map
└── src
│ ├── converter.d.ts
│ ├── converter.d.ts.map
│ ├── index.d.ts
│ ├── index.d.ts.map
│ └── worker
│ ├── actor.d.ts
│ ├── actor.d.ts.map
│ ├── worker.d.ts
│ └── worker.d.ts.map
├── examples
├── data
│ ├── beach_ave.gpx
│ ├── cape_may_incorporated_places.geojson
│ ├── cape_may_incorporated_places.kml
│ └── cape_may_restaurants.csv
├── index.css
├── index.html
├── index.js
├── indexv3.html
├── layerSelector.js
└── umd.html
├── package.json
├── rollup.config.mjs
├── src
├── converter.ts
├── custom.d.ts
├── index.ts
└── worker
│ ├── actor.ts
│ └── worker.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .npmrc
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Blacklist everything first
2 | *
3 |
4 | # Whitelist specific files or folders
5 | !dist/
6 | !README.md
7 | !LICENSE
8 | !package.json
9 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGE LOG
2 |
3 | ## April 28, 2024 - v0.0.5
4 | * Bump to 5 to keep NPM / Github synchronized
5 |
6 | ## April 28, 2024 - v0.0.4
7 | * Export processData so it can use used without adding data to the map directly
8 | * Update libraries
9 | * maplibre-gl ^4.1.2 → ^4.1.3
10 | * rollup ^4.14.1 → ^4.17.0
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Jim McAndrew
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # maplibre-gl-vector-text-protocol
2 | Supports geospatial text based vector data using [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) in v1.15.0 or later.
3 |
4 | It makes use of the [addProtocol](https://github.com/maplibre/maplibre-gl-js/pull/30) functionality that was added in version [1.15.0](https://github.com/maplibre/maplibre-gl-js/releases/tag/v1.15.0).
5 |
6 | It can be used with Mapbox GL JS 1.x.x using the [mapbox-gl-custom-protocol](https://www.github.com/jimmyrocks/mapbox-gl-custom-protocol) library. I haven't tested it with Mapbox GL JS 2+.
7 |
8 | Web workers are used to convert `CSV`, `TSV`, `Topojson`, and `OSM` formats. `KML`, `GPX`, and `TCX` formats are based on XML and use the [DOMParser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser), which isn't available to web workers, so they are converted to GeoJSON in the main thread.
9 |
10 | ## Supported Formats 🗎
11 | * [`Topojson`](https://en.wikipedia.org/wiki/GeoJSON#TopoJSON) - A more compact JSON based format than [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) that takes advantage of shared **topo**logies.
12 | * [`OSM`](https://wiki.openstreetmap.org/wiki/OSM_JSON) - Open Street Map json/xml.
13 | * [`KML`](https://en.wikipedia.org/wiki/Keyhole_Markup_Language) - **K**eyhole **M**arkup **L**anguage, popularized by [Google Earth](https://en.wikipedia.org/wiki/Google_Earth).
14 | * [`GPX`](https://en.wikipedia.org/wiki/GPS_Exchange_Format) - **GP**S E**x**change Format - A common XML-based format used by may GPS devices.
15 | * [`TCX`](https://en.wikipedia.org/wiki/Training_Center_XML) - **T**raining **C**enter **X**ML - An XML-based format used by various Garmin devices and applications (e.g. [Garmin Connect](https://connect.garmin.com)).
16 | * [`CSV`](https://en.wikipedia.org/wiki/Comma-separated_values) - **C**omma-**S**eparated **V**alues, the old reliable of data formats. No options are exposed, Latitude fields must start with "lat" and Longitude fields must start with "lon" or "lng". Will also work with bar (|) and tab (\t) separated values.
17 | * [`TSV`](https://en.wikipedia.org/wiki/Tab-separated_values) - **T**ab-**S**eparated **V**alue - Same as CSV, but it forces the delimiter to be a tab character (\t).
18 |
19 | ## Objective ✨
20 | The [`addProtocol`](https://github.com/maplibre/maplibre-gl-js/blob/492bec58c5684609af8fba81ef01e5f5a3ef0711/src/index.js#L177) feature makes it extremely easy to extend the existing functionality of MapLibre sources without creating a new source type using the [addSourceType](https://github.com/maplibre/maplibre-gl-js/blob/d375def728d23b9d443a4dcaab0fd06df912223e/src/ui/map.ts#L1583) feature. This makes it very easy to support all kinds of new things in MapLibre.
21 |
22 | ## Inspiration 💡
23 | I have worked on many projects where users want to add their own data to a map, but their data is rarely in the right format. This library makes it as easy as adding a `csv://` before the file path to bring a csv file in.
24 |
25 | There are a lot of [Geospatial File Formats](https://en.wikipedia.org/wiki/GIS_file_formats#Vector) out there, this library is intended to serve the most common formats (CSV, KML, GPX, Topojson, OSM) without creating a huge library. There are other formats I would like to support, but they will be available in different libraries.
26 |
27 | ## External Libraries 📚
28 | This project would not be possible if it weren't for the core libraries that drive it:
29 | * `@tmcw/togeojson` - Supported by [placemark.io](https://placemark.io) - `KML`, `GPX`, `TCX` support
30 | * `csv2geojson` - Supported by [Mapbox](https://mapbox.com) - `CSV`, `TSV` support
31 | * `topojson-client` - From [Mike Bostock](https://github.com/mbostock) - `Topojson` support
32 | * `osm2geojson-lite` - From [tibetty](https://github.com/tibetty/osm2geojson-lite) - `osm2geojson-lite` support
33 |
34 | I'd also like to thank the Mapbox🚀 and MapLibre teams for creating such a great project that is easily extendable.
35 |
36 | ## Usage 🛠️
37 |
38 | ```javascript
39 |
40 |
41 | // Add all types
42 | VectorTextProtocol.addProtocols(maplibregl);
43 |
44 | // Individual protocols can be added as well
45 | maplibregl.addProtocol('csv', VectorTextProtocol.VectorTextProtocol);
46 | maplibregl.addProtocol('kml', VectorTextProtocol.VectorTextProtocol);
47 | ```
48 |
49 | ## Examples ⚙️
50 | * [KML, CSV, TOPOJSON, GPX (using Modules)](https://loc8.us/maplibre-gl-vector-text-protocol/examples/index.html)
51 | * [TOPOJSON (using UMD)](https://loc8.us/maplibre-gl-vector-text-protocol/examples/umd.html)
52 | ### Codepen
53 | * [TOPOJSON](https://codepen.io/jimmyrocks/pen/ExbPXZP)
54 |
--------------------------------------------------------------------------------
/dist/maplibre-gl-vector-text-protocol.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"maplibre-gl-vector-text-protocol.min.js","sources":["../node_modules/d3-dsv/src/dsv.js","../node_modules/d3-dsv/src/csv.js","../node_modules/d3-dsv/src/tsv.js","../node_modules/@mapbox/sexagesimal/index.js","../node_modules/csv2geojson/index.js","../node_modules/topojson-client/src/identity.js","../node_modules/topojson-client/src/feature.js","../node_modules/topojson-client/src/transform.js","../node_modules/topojson-client/src/reverse.js","../node_modules/@tmcw/togeojson/dist/togeojson.es.mjs","../node_modules/@mapbox/polyline/src/polyline.js","../node_modules/osm2geojson-lite/lib/utils.js","../node_modules/osm2geojson-lite/lib/osmobjs.js","../node_modules/osm2geojson-lite/lib/xmlparser.js","../node_modules/osm2geojson-lite/lib/index.js"],"sourcesContent":["function objectConverter(columns) {\n return new Function(\"d\", \"return {\" + columns.map(function(name, i) {\n return JSON.stringify(name) + \": d[\" + i + \"]\";\n }).join(\",\") + \"}\");\n}\n\nfunction customConverter(columns, f) {\n var object = objectConverter(columns);\n return function(row, i) {\n return f(object(row), i, columns);\n };\n}\n\n// Compute unique columns in order of discovery.\nfunction inferColumns(rows) {\n var columnSet = Object.create(null),\n columns = [];\n\n rows.forEach(function(row) {\n for (var column in row) {\n if (!(column in columnSet)) {\n columns.push(columnSet[column] = column);\n }\n }\n });\n\n return columns;\n}\n\nexport default function(delimiter) {\n var reFormat = new RegExp(\"[\\\"\" + delimiter + \"\\n]\"),\n delimiterCode = delimiter.charCodeAt(0);\n\n function parse(text, f) {\n var convert, columns, rows = parseRows(text, function(row, i) {\n if (convert) return convert(row, i - 1);\n columns = row, convert = f ? customConverter(row, f) : objectConverter(row);\n });\n rows.columns = columns;\n return rows;\n }\n\n function parseRows(text, f) {\n var EOL = {}, // sentinel value for end-of-line\n EOF = {}, // sentinel value for end-of-file\n rows = [], // output rows\n N = text.length,\n I = 0, // current character index\n n = 0, // the current line number\n t, // the current token\n eol; // is the current token followed by EOL?\n\n function token() {\n if (I >= N) return EOF; // special case: end of file\n if (eol) return eol = false, EOL; // special case: end of line\n\n // special case: quotes\n var j = I, c;\n if (text.charCodeAt(j) === 34) {\n var i = j;\n while (i++ < N) {\n if (text.charCodeAt(i) === 34) {\n if (text.charCodeAt(i + 1) !== 34) break;\n ++i;\n }\n }\n I = i + 2;\n c = text.charCodeAt(i + 1);\n if (c === 13) {\n eol = true;\n if (text.charCodeAt(i + 2) === 10) ++I;\n } else if (c === 10) {\n eol = true;\n }\n return text.slice(j + 1, i).replace(/\"\"/g, \"\\\"\");\n }\n\n // common case: find next delimiter or newline\n while (I < N) {\n var k = 1;\n c = text.charCodeAt(I++);\n if (c === 10) eol = true; // \\n\n else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \\r|\\r\\n\n else if (c !== delimiterCode) continue;\n return text.slice(j, I - k);\n }\n\n // special case: last token before EOF\n return text.slice(j);\n }\n\n while ((t = token()) !== EOF) {\n var a = [];\n while (t !== EOL && t !== EOF) {\n a.push(t);\n t = token();\n }\n if (f && (a = f(a, n++)) == null) continue;\n rows.push(a);\n }\n\n return rows;\n }\n\n function format(rows, columns) {\n if (columns == null) columns = inferColumns(rows);\n return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return columns.map(function(column) {\n return formatValue(row[column]);\n }).join(delimiter);\n })).join(\"\\n\");\n }\n\n function formatRows(rows) {\n return rows.map(formatRow).join(\"\\n\");\n }\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return text == null ? \"\"\n : reFormat.test(text += \"\") ? \"\\\"\" + text.replace(/\\\"/g, \"\\\"\\\"\") + \"\\\"\"\n : text;\n }\n\n return {\n parse: parse,\n parseRows: parseRows,\n format: format,\n formatRows: formatRows\n };\n}\n","import dsv from \"./dsv\";\n\nvar csv = dsv(\",\");\n\nexport var csvParse = csv.parse;\nexport var csvParseRows = csv.parseRows;\nexport var csvFormat = csv.format;\nexport var csvFormatRows = csv.formatRows;\n","import dsv from \"./dsv\";\n\nvar tsv = dsv(\"\\t\");\n\nexport var tsvParse = tsv.parse;\nexport var tsvParseRows = tsv.parseRows;\nexport var tsvFormat = tsv.format;\nexport var tsvFormatRows = tsv.formatRows;\n","module.exports = element;\nmodule.exports.pair = pair;\nmodule.exports.format = format;\nmodule.exports.formatPair = formatPair;\nmodule.exports.coordToDMS = coordToDMS;\n\n\nfunction element(input, dims) {\n var result = search(input, dims);\n return (result === null) ? null : result.val;\n}\n\n\nfunction formatPair(input) {\n return format(input.lat, 'lat') + ' ' + format(input.lon, 'lon');\n}\n\n\n// Is 0 North or South?\nfunction format(input, dim) {\n var dms = coordToDMS(input, dim);\n return dms.whole + '° ' +\n (dms.minutes ? dms.minutes + '\\' ' : '') +\n (dms.seconds ? dms.seconds + '\" ' : '') + dms.dir;\n}\n\n\nfunction coordToDMS(input, dim) {\n var dirs = { lat: ['N', 'S'], lon: ['E', 'W'] }[dim] || '';\n var dir = dirs[input >= 0 ? 0 : 1];\n var abs = Math.abs(input);\n var whole = Math.floor(abs);\n var fraction = abs - whole;\n var fractionMinutes = fraction * 60;\n var minutes = Math.floor(fractionMinutes);\n var seconds = Math.floor((fractionMinutes - minutes) * 60);\n\n return {\n whole: whole,\n minutes: minutes,\n seconds: seconds,\n dir: dir\n };\n}\n\n\nfunction search(input, dims) {\n if (!dims) dims = 'NSEW';\n if (typeof input !== 'string') return null;\n\n input = input.toUpperCase();\n var regex = /^[\\s\\,]*([NSEW])?\\s*([\\-|\\—|\\―]?[0-9.]+)[°º˚]?\\s*(?:([0-9.]+)['’′‘]\\s*)?(?:([0-9.]+)(?:''|\"|”|″)\\s*)?([NSEW])?/;\n\n var m = input.match(regex);\n if (!m) return null; // no match\n\n var matched = m[0];\n\n // extract dimension.. m[1] = leading, m[5] = trailing\n var dim;\n if (m[1] && m[5]) { // if matched both..\n dim = m[1]; // keep leading\n matched = matched.slice(0, -1); // remove trailing dimension from match\n } else {\n dim = m[1] || m[5];\n }\n\n // if unrecognized dimension\n if (dim && dims.indexOf(dim) === -1) return null;\n\n // extract DMS\n var deg = m[2] ? parseFloat(m[2]) : 0;\n var min = m[3] ? parseFloat(m[3]) / 60 : 0;\n var sec = m[4] ? parseFloat(m[4]) / 3600 : 0;\n var sign = (deg < 0) ? -1 : 1;\n if (dim === 'S' || dim === 'W') sign *= -1;\n\n return {\n val: (Math.abs(deg) + min + sec) * sign,\n dim: dim,\n matched: matched,\n remain: input.slice(matched.length)\n };\n}\n\n\nfunction pair(input, dims) {\n input = input.trim();\n var one = search(input, dims);\n if (!one) return null;\n\n input = one.remain.trim();\n var two = search(input, dims);\n if (!two || two.remain) return null;\n\n if (one.dim) {\n return swapdim(one.val, two.val, one.dim);\n } else {\n return [one.val, two.val];\n }\n}\n\n\nfunction swapdim(a, b, dim) {\n if (dim === 'N' || dim === 'S') return [a, b];\n if (dim === 'W' || dim === 'E') return [b, a];\n}\n","'use strict';\n\nvar dsv = require('d3-dsv'),\n sexagesimal = require('@mapbox/sexagesimal');\n\nvar latRegex = /(Lat)(itude)?/gi,\n lonRegex = /(L)(on|ng)(gitude)?/i;\n\nfunction guessHeader(row, regexp) {\n var name, match, score;\n for (var f in row) {\n match = f.match(regexp);\n if (match && (!name || match[0].length / f.length > score)) {\n score = match[0].length / f.length;\n name = f;\n }\n }\n return name;\n}\n\nfunction guessLatHeader(row) { return guessHeader(row, latRegex); }\nfunction guessLonHeader(row) { return guessHeader(row, lonRegex); }\n\nfunction isLat(f) { return !!f.match(latRegex); }\nfunction isLon(f) { return !!f.match(lonRegex); }\n\nfunction keyCount(o) {\n return (typeof o == 'object') ? Object.keys(o).length : 0;\n}\n\nfunction autoDelimiter(x) {\n var delimiters = [',', ';', '\\t', '|'];\n var results = [];\n\n delimiters.forEach(function (delimiter) {\n var res = dsv.dsvFormat(delimiter).parse(x);\n if (res.length >= 1) {\n var count = keyCount(res[0]);\n for (var i = 0; i < res.length; i++) {\n if (keyCount(res[i]) !== count) return;\n }\n results.push({\n delimiter: delimiter,\n arity: Object.keys(res[0]).length,\n });\n }\n });\n\n if (results.length) {\n return results.sort(function (a, b) {\n return b.arity - a.arity;\n })[0].delimiter;\n } else {\n return null;\n }\n}\n\n/**\n * Silly stopgap for dsv to d3-dsv upgrade\n *\n * @param {Array} x dsv output\n * @returns {Array} array without columns member\n */\nfunction deleteColumns(x) {\n delete x.columns;\n return x;\n}\n\nfunction auto(x) {\n var delimiter = autoDelimiter(x);\n if (!delimiter) return null;\n return deleteColumns(dsv.dsvFormat(delimiter).parse(x));\n}\n\nfunction csv2geojson(x, options, callback) {\n\n if (!callback) {\n callback = options;\n options = {};\n }\n\n options.delimiter = options.delimiter || ',';\n\n var latfield = options.latfield || '',\n lonfield = options.lonfield || '',\n crs = options.crs || '';\n\n var features = [],\n featurecollection = {type: 'FeatureCollection', features: features};\n\n if (crs !== '') {\n featurecollection.crs = {type: 'name', properties: {name: crs}};\n }\n\n if (options.delimiter === 'auto' && typeof x == 'string') {\n options.delimiter = autoDelimiter(x);\n if (!options.delimiter) {\n callback({\n type: 'Error',\n message: 'Could not autodetect delimiter'\n });\n return;\n }\n }\n\n var numericFields = options.numericFields ? options.numericFields.split(',') : null;\n\n var parsed = (typeof x == 'string') ?\n dsv.dsvFormat(options.delimiter).parse(x, function (d) {\n if (numericFields) {\n for (var key in d) {\n if (numericFields.includes(key)) {\n d[key] = +d[key];\n }\n }\n }\n return d;\n }) : x;\n\n if (!parsed.length) {\n callback(null, featurecollection);\n return;\n }\n\n var errors = [];\n var i;\n\n\n if (!latfield) latfield = guessLatHeader(parsed[0]);\n if (!lonfield) lonfield = guessLonHeader(parsed[0]);\n var noGeometry = (!latfield || !lonfield);\n\n if (noGeometry) {\n for (i = 0; i < parsed.length; i++) {\n features.push({\n type: 'Feature',\n properties: parsed[i],\n geometry: null\n });\n }\n callback(errors.length ? errors : null, featurecollection);\n return;\n }\n\n for (i = 0; i < parsed.length; i++) {\n if (parsed[i][lonfield] !== undefined &&\n parsed[i][latfield] !== undefined) {\n\n var lonk = parsed[i][lonfield],\n latk = parsed[i][latfield],\n lonf, latf,\n a;\n\n a = sexagesimal(lonk, 'EW');\n if (a) lonk = a;\n a = sexagesimal(latk, 'NS');\n if (a) latk = a;\n\n lonf = parseFloat(lonk);\n latf = parseFloat(latk);\n\n if (isNaN(lonf) ||\n isNaN(latf)) {\n errors.push({\n message: 'A row contained an invalid value for latitude or longitude',\n row: parsed[i],\n index: i\n });\n } else {\n if (!options.includeLatLon) {\n delete parsed[i][lonfield];\n delete parsed[i][latfield];\n }\n\n features.push({\n type: 'Feature',\n properties: parsed[i],\n geometry: {\n type: 'Point',\n coordinates: [\n parseFloat(lonf),\n parseFloat(latf)\n ]\n }\n });\n }\n }\n }\n\n callback(errors.length ? errors : null, featurecollection);\n}\n\nfunction toLine(gj) {\n var features = gj.features;\n var line = {\n type: 'Feature',\n geometry: {\n type: 'LineString',\n coordinates: []\n }\n };\n for (var i = 0; i < features.length; i++) {\n line.geometry.coordinates.push(features[i].geometry.coordinates);\n }\n line.properties = features.reduce(function (aggregatedProperties, newFeature) {\n for (var key in newFeature.properties) {\n if (!aggregatedProperties[key]) {\n aggregatedProperties[key] = [];\n }\n aggregatedProperties[key].push(newFeature.properties[key]);\n }\n return aggregatedProperties;\n }, {});\n return {\n type: 'FeatureCollection',\n features: [line]\n };\n}\n\nfunction toPolygon(gj) {\n var features = gj.features;\n var poly = {\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [[]]\n }\n };\n for (var i = 0; i < features.length; i++) {\n poly.geometry.coordinates[0].push(features[i].geometry.coordinates);\n }\n poly.properties = features.reduce(function (aggregatedProperties, newFeature) {\n for (var key in newFeature.properties) {\n if (!aggregatedProperties[key]) {\n aggregatedProperties[key] = [];\n }\n aggregatedProperties[key].push(newFeature.properties[key]);\n }\n return aggregatedProperties;\n }, {});\n return {\n type: 'FeatureCollection',\n features: [poly]\n };\n}\n\nmodule.exports = {\n isLon: isLon,\n isLat: isLat,\n guessLatHeader: guessLatHeader,\n guessLonHeader: guessLonHeader,\n csv: dsv.csvParse,\n tsv: dsv.tsvParse,\n dsv: dsv,\n auto: auto,\n csv2geojson: csv2geojson,\n toLine: toLine,\n toPolygon: toPolygon\n};\n","export default function(x) {\n return x;\n}\n","import reverse from \"./reverse.js\";\nimport transform from \"./transform.js\";\n\nexport default function(topology, o) {\n if (typeof o === \"string\") o = topology.objects[o];\n return o.type === \"GeometryCollection\"\n ? {type: \"FeatureCollection\", features: o.geometries.map(function(o) { return feature(topology, o); })}\n : feature(topology, o);\n}\n\nfunction feature(topology, o) {\n var id = o.id,\n bbox = o.bbox,\n properties = o.properties == null ? {} : o.properties,\n geometry = object(topology, o);\n return id == null && bbox == null ? {type: \"Feature\", properties: properties, geometry: geometry}\n : bbox == null ? {type: \"Feature\", id: id, properties: properties, geometry: geometry}\n : {type: \"Feature\", id: id, bbox: bbox, properties: properties, geometry: geometry};\n}\n\nexport function object(topology, o) {\n var transformPoint = transform(topology.transform),\n arcs = topology.arcs;\n\n function arc(i, points) {\n if (points.length) points.pop();\n for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) {\n points.push(transformPoint(a[k], k));\n }\n if (i < 0) reverse(points, n);\n }\n\n function point(p) {\n return transformPoint(p);\n }\n\n function line(arcs) {\n var points = [];\n for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n if (points.length < 2) points.push(points[0]); // This should never happen per the specification.\n return points;\n }\n\n function ring(arcs) {\n var points = line(arcs);\n while (points.length < 4) points.push(points[0]); // This may happen if an arc has only two points.\n return points;\n }\n\n function polygon(arcs) {\n return arcs.map(ring);\n }\n\n function geometry(o) {\n var type = o.type, coordinates;\n switch (type) {\n case \"GeometryCollection\": return {type: type, geometries: o.geometries.map(geometry)};\n case \"Point\": coordinates = point(o.coordinates); break;\n case \"MultiPoint\": coordinates = o.coordinates.map(point); break;\n case \"LineString\": coordinates = line(o.arcs); break;\n case \"MultiLineString\": coordinates = o.arcs.map(line); break;\n case \"Polygon\": coordinates = polygon(o.arcs); break;\n case \"MultiPolygon\": coordinates = o.arcs.map(polygon); break;\n default: return null;\n }\n return {type: type, coordinates: coordinates};\n }\n\n return geometry(o);\n}\n","import identity from \"./identity.js\";\n\nexport default function(transform) {\n if (transform == null) return identity;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(input, i) {\n if (!i) x0 = y0 = 0;\n var j = 2, n = input.length, output = new Array(n);\n output[0] = (x0 += input[0]) * kx + dx;\n output[1] = (y0 += input[1]) * ky + dy;\n while (j < n) output[j] = input[j], ++j;\n return output;\n };\n}\n","export default function(array, n) {\n var t, j = array.length, i = j - n;\n while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n}\n","function $(element, tagName) {\n return Array.from(element.getElementsByTagName(tagName));\n}\nfunction normalizeId(id) {\n return id[0] === \"#\" ? id : `#${id}`;\n}\nfunction $ns(element, tagName, ns) {\n return Array.from(element.getElementsByTagNameNS(ns, tagName));\n}\n/**\n * get the content of a text node, if any\n */\nfunction nodeVal(node) {\n node?.normalize();\n return (node && node.textContent) || \"\";\n}\n/**\n * Get one Y child of X, if any, otherwise null\n */\nfunction get1(node, tagName, callback) {\n const n = node.getElementsByTagName(tagName);\n const result = n.length ? n[0] : null;\n if (result && callback)\n callback(result);\n return result;\n}\nfunction get(node, tagName, callback) {\n const properties = {};\n if (!node)\n return properties;\n const n = node.getElementsByTagName(tagName);\n const result = n.length ? n[0] : null;\n if (result && callback) {\n return callback(result, properties);\n }\n return properties;\n}\nfunction val1(node, tagName, callback) {\n const val = nodeVal(get1(node, tagName));\n if (val && callback)\n return callback(val) || {};\n return {};\n}\nfunction $num(node, tagName, callback) {\n const val = parseFloat(nodeVal(get1(node, tagName)));\n if (isNaN(val))\n return undefined;\n if (val && callback)\n return callback(val) || {};\n return {};\n}\nfunction num1(node, tagName, callback) {\n const val = parseFloat(nodeVal(get1(node, tagName)));\n if (isNaN(val))\n return undefined;\n if (callback)\n callback(val);\n return val;\n}\nfunction getMulti(node, propertyNames) {\n const properties = {};\n for (const property of propertyNames) {\n val1(node, property, (val) => {\n properties[property] = val;\n });\n }\n return properties;\n}\nfunction isElement(node) {\n return node?.nodeType === 1;\n}\n\nfunction getLineStyle(node) {\n return get(node, \"line\", (lineStyle) => {\n const val = Object.assign({}, val1(lineStyle, \"color\", (color) => {\n return { stroke: `#${color}` };\n }), $num(lineStyle, \"opacity\", (opacity) => {\n return { \"stroke-opacity\": opacity };\n }), $num(lineStyle, \"width\", (width) => {\n // GPX width is in mm, convert to px with 96 px per inch\n return { \"stroke-width\": (width * 96) / 25.4 };\n }));\n return val;\n });\n}\n\nfunction getExtensions(node) {\n let values = [];\n if (node === null)\n return values;\n for (const child of Array.from(node.childNodes)) {\n if (!isElement(child))\n continue;\n const name = abbreviateName(child.nodeName);\n if (name === \"gpxtpx:TrackPointExtension\") {\n // loop again for nested garmin extensions (eg. \"gpxtpx:hr\")\n values = values.concat(getExtensions(child));\n }\n else {\n // push custom extension (eg. \"power\")\n const val = nodeVal(child);\n values.push([name, parseNumeric(val)]);\n }\n }\n return values;\n}\nfunction abbreviateName(name) {\n return [\"heart\", \"gpxtpx:hr\", \"hr\"].includes(name) ? \"heart\" : name;\n}\nfunction parseNumeric(val) {\n const num = parseFloat(val);\n return isNaN(num) ? val : num;\n}\n\nfunction coordPair$1(node) {\n const ll = [\n parseFloat(node.getAttribute(\"lon\") || \"\"),\n parseFloat(node.getAttribute(\"lat\") || \"\"),\n ];\n if (isNaN(ll[0]) || isNaN(ll[1])) {\n return null;\n }\n num1(node, \"ele\", (val) => {\n ll.push(val);\n });\n const time = get1(node, \"time\");\n return {\n coordinates: ll,\n time: time ? nodeVal(time) : null,\n extendedValues: getExtensions(get1(node, \"extensions\")),\n };\n}\n\nfunction extractProperties(node) {\n const properties = getMulti(node, [\n \"name\",\n \"cmt\",\n \"desc\",\n \"type\",\n \"time\",\n \"keywords\",\n ]);\n const extensions = Array.from(node.getElementsByTagNameNS(\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\", \"*\"));\n for (const child of extensions) {\n if (child.parentNode?.parentNode === node) {\n properties[child.tagName.replace(\":\", \"_\")] = nodeVal(child);\n }\n }\n const links = $(node, \"link\");\n if (links.length) {\n properties.links = links.map((link) => Object.assign({ href: link.getAttribute(\"href\") }, getMulti(link, [\"text\", \"type\"])));\n }\n return properties;\n}\n\n/**\n * Extract points from a trkseg or rte element.\n */\nfunction getPoints$1(node, pointname) {\n const pts = $(node, pointname);\n const line = [];\n const times = [];\n const extendedValues = {};\n for (let i = 0; i < pts.length; i++) {\n const c = coordPair$1(pts[i]);\n if (!c) {\n continue;\n }\n line.push(c.coordinates);\n if (c.time)\n times.push(c.time);\n for (const [name, val] of c.extendedValues) {\n const plural = name === \"heart\" ? name : name.replace(\"gpxtpx:\", \"\") + \"s\";\n if (!extendedValues[plural]) {\n extendedValues[plural] = Array(pts.length).fill(null);\n }\n extendedValues[plural][i] = val;\n }\n }\n if (line.length < 2)\n return; // Invalid line in GeoJSON\n return {\n line: line,\n times: times,\n extendedValues: extendedValues,\n };\n}\n/**\n * Extract a LineString geometry from a rte\n * element.\n */\nfunction getRoute(node) {\n const line = getPoints$1(node, \"rtept\");\n if (!line)\n return;\n return {\n type: \"Feature\",\n properties: Object.assign({ _gpxType: \"rte\" }, extractProperties(node), getLineStyle(get1(node, \"extensions\"))),\n geometry: {\n type: \"LineString\",\n coordinates: line.line,\n },\n };\n}\nfunction getTrack(node) {\n const segments = $(node, \"trkseg\");\n const track = [];\n const times = [];\n const extractedLines = [];\n for (const segment of segments) {\n const line = getPoints$1(segment, \"trkpt\");\n if (line) {\n extractedLines.push(line);\n if (line.times && line.times.length)\n times.push(line.times);\n }\n }\n if (extractedLines.length === 0)\n return null;\n const multi = extractedLines.length > 1;\n const properties = Object.assign({ _gpxType: \"trk\" }, extractProperties(node), getLineStyle(get1(node, \"extensions\")), times.length\n ? {\n coordinateProperties: {\n times: multi ? times : times[0],\n },\n }\n : {});\n for (const line of extractedLines) {\n track.push(line.line);\n if (!properties.coordinateProperties) {\n properties.coordinateProperties = {};\n }\n const props = properties.coordinateProperties;\n const entries = Object.entries(line.extendedValues);\n for (let i = 0; i < entries.length; i++) {\n const [name, val] = entries[i];\n if (multi) {\n if (!props[name]) {\n props[name] = extractedLines.map((line) => new Array(line.line.length).fill(null));\n }\n props[name][i] = val;\n }\n else {\n props[name] = val;\n }\n }\n }\n return {\n type: \"Feature\",\n properties: properties,\n geometry: multi\n ? {\n type: \"MultiLineString\",\n coordinates: track,\n }\n : {\n type: \"LineString\",\n coordinates: track[0],\n },\n };\n}\n/**\n * Extract a point, if possible, from a given node,\n * which is usually a wpt or trkpt\n */\nfunction getPoint(node) {\n const properties = Object.assign(extractProperties(node), getMulti(node, [\"sym\"]));\n const pair = coordPair$1(node);\n if (!pair)\n return null;\n return {\n type: \"Feature\",\n properties,\n geometry: {\n type: \"Point\",\n coordinates: pair.coordinates,\n },\n };\n}\n/**\n * Convert GPX to GeoJSON incrementally, returning\n * a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)\n * that yields output feature by feature.\n */\nfunction* gpxGen(node) {\n for (const track of $(node, \"trk\")) {\n const feature = getTrack(track);\n if (feature)\n yield feature;\n }\n for (const route of $(node, \"rte\")) {\n const feature = getRoute(route);\n if (feature)\n yield feature;\n }\n for (const waypoint of $(node, \"wpt\")) {\n const point = getPoint(waypoint);\n if (point)\n yield point;\n }\n}\n/**\n *\n * Convert a GPX document to GeoJSON. The first argument, `doc`, must be a GPX\n * document as an XML DOM - not as a string. You can get this using jQuery's default\n * `.ajax` function or using a bare XMLHttpRequest with the `.response` property\n * holding an XML DOM.\n *\n * The output is a JavaScript object of GeoJSON data, same as `.kml` outputs, with the\n * addition of a `_gpxType` property on each `LineString` feature that indicates whether\n * the feature was encoded as a route (`rte`) or track (`trk`) in the GPX document.\n */\nfunction gpx(node) {\n return {\n type: \"FeatureCollection\",\n features: Array.from(gpxGen(node)),\n };\n}\n\nconst EXTENSIONS_NS = \"http://www.garmin.com/xmlschemas/ActivityExtension/v2\";\nconst TRACKPOINT_ATTRIBUTES = [\n [\"heartRate\", \"heartRates\"],\n [\"Cadence\", \"cadences\"],\n // Extended Trackpoint attributes\n [\"Speed\", \"speeds\"],\n [\"Watts\", \"watts\"],\n];\nconst LAP_ATTRIBUTES = [\n [\"TotalTimeSeconds\", \"totalTimeSeconds\"],\n [\"DistanceMeters\", \"distanceMeters\"],\n [\"MaximumSpeed\", \"maxSpeed\"],\n [\"AverageHeartRateBpm\", \"avgHeartRate\"],\n [\"MaximumHeartRateBpm\", \"maxHeartRate\"],\n // Extended Lap attributes\n [\"AvgSpeed\", \"avgSpeed\"],\n [\"AvgWatts\", \"avgWatts\"],\n [\"MaxWatts\", \"maxWatts\"],\n];\nfunction getProperties(node, attributeNames) {\n const properties = [];\n for (const [tag, alias] of attributeNames) {\n let elem = get1(node, tag);\n if (!elem) {\n const elements = node.getElementsByTagNameNS(EXTENSIONS_NS, tag);\n if (elements.length) {\n elem = elements[0];\n }\n }\n const val = parseFloat(nodeVal(elem));\n if (!isNaN(val)) {\n properties.push([alias, val]);\n }\n }\n return properties;\n}\nfunction coordPair(node) {\n const ll = [num1(node, \"LongitudeDegrees\"), num1(node, \"LatitudeDegrees\")];\n if (ll[0] === undefined ||\n isNaN(ll[0]) ||\n ll[1] === undefined ||\n isNaN(ll[1])) {\n return null;\n }\n const heartRate = get1(node, \"HeartRateBpm\");\n const time = nodeVal(get1(node, \"Time\"));\n get1(node, \"AltitudeMeters\", (alt) => {\n const a = parseFloat(nodeVal(alt));\n if (!isNaN(a)) {\n ll.push(a);\n }\n });\n return {\n coordinates: ll,\n time: time || null,\n heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null,\n extensions: getProperties(node, TRACKPOINT_ATTRIBUTES),\n };\n}\nfunction getPoints(node) {\n const pts = $(node, \"Trackpoint\");\n const line = [];\n const times = [];\n const heartRates = [];\n if (pts.length < 2)\n return null; // Invalid line in GeoJSON\n const extendedProperties = {};\n const result = { extendedProperties };\n for (let i = 0; i < pts.length; i++) {\n const c = coordPair(pts[i]);\n if (c === null)\n continue;\n line.push(c.coordinates);\n const { time, heartRate, extensions } = c;\n if (time)\n times.push(time);\n if (heartRate)\n heartRates.push(heartRate);\n for (const [alias, value] of extensions) {\n if (!extendedProperties[alias]) {\n extendedProperties[alias] = Array(pts.length).fill(null);\n }\n extendedProperties[alias][i] = value;\n }\n }\n if (line.length < 2)\n return null;\n return Object.assign(result, {\n line: line,\n times: times,\n heartRates: heartRates,\n });\n}\nfunction getLap(node) {\n const segments = $(node, \"Track\");\n const track = [];\n const times = [];\n const heartRates = [];\n const allExtendedProperties = [];\n let line;\n const properties = Object.assign(Object.fromEntries(getProperties(node, LAP_ATTRIBUTES)), get(node, \"Name\", (nameElement) => {\n return { name: nodeVal(nameElement) };\n }));\n for (const segment of segments) {\n line = getPoints(segment);\n if (line) {\n track.push(line.line);\n if (line.times.length)\n times.push(line.times);\n if (line.heartRates.length)\n heartRates.push(line.heartRates);\n allExtendedProperties.push(line.extendedProperties);\n }\n }\n for (let i = 0; i < allExtendedProperties.length; i++) {\n const extendedProperties = allExtendedProperties[i];\n for (const property in extendedProperties) {\n if (segments.length === 1) {\n if (line) {\n properties[property] = line.extendedProperties[property];\n }\n }\n else {\n if (!properties[property]) {\n properties[property] = track.map((track) => Array(track.length).fill(null));\n }\n properties[property][i] = extendedProperties[property];\n }\n }\n }\n if (track.length === 0)\n return null;\n if (times.length || heartRates.length) {\n properties.coordinateProperties = Object.assign(times.length\n ? {\n times: track.length === 1 ? times[0] : times,\n }\n : {}, heartRates.length\n ? {\n heart: track.length === 1 ? heartRates[0] : heartRates,\n }\n : {});\n }\n return {\n type: \"Feature\",\n properties: properties,\n geometry: track.length === 1\n ? {\n type: \"LineString\",\n coordinates: track[0],\n }\n : {\n type: \"MultiLineString\",\n coordinates: track,\n },\n };\n}\n/**\n * Incrementally convert a TCX document to GeoJSON. The\n * first argument, `doc`, must be a TCX\n * document as an XML DOM - not as a string.\n */\nfunction* tcxGen(node) {\n for (const lap of $(node, \"Lap\")) {\n const feature = getLap(lap);\n if (feature)\n yield feature;\n }\n for (const course of $(node, \"Courses\")) {\n const feature = getLap(course);\n if (feature)\n yield feature;\n }\n}\n/**\n * Convert a TCX document to GeoJSON. The first argument, `doc`, must be a TCX\n * document as an XML DOM - not as a string.\n */\nfunction tcx(node) {\n return {\n type: \"FeatureCollection\",\n features: Array.from(tcxGen(node)),\n };\n}\n\nfunction fixColor(v, prefix) {\n const properties = {};\n const colorProp = prefix == \"stroke\" || prefix === \"fill\" ? prefix : prefix + \"-color\";\n if (v[0] === \"#\") {\n v = v.substring(1);\n }\n if (v.length === 6 || v.length === 3) {\n properties[colorProp] = \"#\" + v;\n }\n else if (v.length === 8) {\n properties[prefix + \"-opacity\"] = parseInt(v.substring(0, 2), 16) / 255;\n properties[colorProp] =\n \"#\" + v.substring(6, 8) + v.substring(4, 6) + v.substring(2, 4);\n }\n return properties;\n}\n\nfunction numericProperty(node, source, target) {\n const properties = {};\n num1(node, source, (val) => {\n properties[target] = val;\n });\n return properties;\n}\nfunction getColor(node, output) {\n return get(node, \"color\", (elem) => fixColor(nodeVal(elem), output));\n}\nfunction extractIconHref(node) {\n return get(node, \"Icon\", (icon, properties) => {\n val1(icon, \"href\", (href) => {\n properties.icon = href;\n });\n return properties;\n });\n}\nfunction extractIcon(node) {\n return get(node, \"IconStyle\", (iconStyle) => {\n return Object.assign(getColor(iconStyle, \"icon\"), numericProperty(iconStyle, \"scale\", \"icon-scale\"), numericProperty(iconStyle, \"heading\", \"icon-heading\"), get(iconStyle, \"hotSpot\", (hotspot) => {\n const left = parseFloat(hotspot.getAttribute(\"x\") || \"\");\n const top = parseFloat(hotspot.getAttribute(\"y\") || \"\");\n const xunits = hotspot.getAttribute(\"xunits\") || \"\";\n const yunits = hotspot.getAttribute(\"yunits\") || \"\";\n if (!isNaN(left) && !isNaN(top))\n return {\n \"icon-offset\": [left, top],\n \"icon-offset-units\": [xunits, yunits],\n };\n return {};\n }), extractIconHref(iconStyle));\n });\n}\nfunction extractLabel(node) {\n return get(node, \"LabelStyle\", (labelStyle) => {\n return Object.assign(getColor(labelStyle, \"label\"), numericProperty(labelStyle, \"scale\", \"label-scale\"));\n });\n}\nfunction extractLine(node) {\n return get(node, \"LineStyle\", (lineStyle) => {\n return Object.assign(getColor(lineStyle, \"stroke\"), numericProperty(lineStyle, \"width\", \"stroke-width\"));\n });\n}\nfunction extractPoly(node) {\n return get(node, \"PolyStyle\", (polyStyle, properties) => {\n return Object.assign(properties, get(polyStyle, \"color\", (elem) => fixColor(nodeVal(elem), \"fill\")), val1(polyStyle, \"fill\", (fill) => {\n if (fill === \"0\")\n return { \"fill-opacity\": 0 };\n }), val1(polyStyle, \"outline\", (outline) => {\n if (outline === \"0\")\n return { \"stroke-opacity\": 0 };\n }));\n });\n}\nfunction extractStyle(node) {\n return Object.assign({}, extractPoly(node), extractLine(node), extractLabel(node), extractIcon(node));\n}\n\nconst toNumber = (x) => Number(x);\nconst typeConverters = {\n string: (x) => x,\n int: toNumber,\n uint: toNumber,\n short: toNumber,\n ushort: toNumber,\n float: toNumber,\n double: toNumber,\n bool: (x) => Boolean(x),\n};\nfunction extractExtendedData(node, schema) {\n return get(node, \"ExtendedData\", (extendedData, properties) => {\n for (const data of $(extendedData, \"Data\")) {\n properties[data.getAttribute(\"name\") || \"\"] = nodeVal(get1(data, \"value\"));\n }\n for (const simpleData of $(extendedData, \"SimpleData\")) {\n const name = simpleData.getAttribute(\"name\") || \"\";\n const typeConverter = schema[name] || typeConverters.string;\n properties[name] = typeConverter(nodeVal(simpleData));\n }\n return properties;\n });\n}\nfunction getMaybeHTMLDescription(node) {\n const descriptionNode = get1(node, \"description\");\n for (const c of Array.from(descriptionNode?.childNodes || [])) {\n if (c.nodeType === 4) {\n return {\n description: {\n \"@type\": \"html\",\n value: nodeVal(c),\n },\n };\n }\n }\n return {};\n}\nfunction extractTimeSpan(node) {\n return get(node, \"TimeSpan\", (timeSpan) => {\n return {\n timespan: {\n begin: nodeVal(get1(timeSpan, \"begin\")),\n end: nodeVal(get1(timeSpan, \"end\")),\n },\n };\n });\n}\nfunction extractTimeStamp(node) {\n return get(node, \"TimeStamp\", (timeStamp) => {\n return { timestamp: nodeVal(get1(timeStamp, \"when\")) };\n });\n}\nfunction extractCascadedStyle(node, styleMap) {\n return val1(node, \"styleUrl\", (styleUrl) => {\n styleUrl = normalizeId(styleUrl);\n if (styleMap[styleUrl]) {\n return Object.assign({ styleUrl }, styleMap[styleUrl]);\n }\n // For backward-compatibility. Should we still include\n // styleUrl even if it's not resolved?\n return { styleUrl };\n });\n}\n\nconst removeSpace = /\\s*/g;\nconst trimSpace = /^\\s*|\\s*$/g;\nconst splitSpace = /\\s+/;\n/**\n * Get one coordinate from a coordinate array, if any\n */\nfunction coord1(value) {\n return value\n .replace(removeSpace, \"\")\n .split(\",\")\n .map(parseFloat)\n .filter((num) => !isNaN(num))\n .slice(0, 3);\n}\n/**\n * Get all coordinates from a coordinate array as [[],[]]\n */\nfunction coord(value) {\n return value\n .replace(trimSpace, \"\")\n .split(splitSpace)\n .map(coord1)\n .filter((coord) => {\n return coord.length >= 2;\n });\n}\nfunction gxCoords(node) {\n let elems = $(node, \"coord\");\n if (elems.length === 0) {\n elems = $ns(node, \"coord\", \"*\");\n }\n const coordinates = elems.map((elem) => {\n return nodeVal(elem).split(\" \").map(parseFloat);\n });\n if (coordinates.length === 0) {\n return null;\n }\n return {\n geometry: coordinates.length > 2\n ? {\n type: \"LineString\",\n coordinates,\n }\n : {\n type: \"Point\",\n coordinates: coordinates[0],\n },\n times: $(node, \"when\").map((elem) => nodeVal(elem)),\n };\n}\nfunction fixRing(ring) {\n if (ring.length === 0)\n return ring;\n const first = ring[0];\n const last = ring[ring.length - 1];\n let equal = true;\n for (let i = 0; i < Math.max(first.length, last.length); i++) {\n if (first[i] !== last[i]) {\n equal = false;\n break;\n }\n }\n if (!equal) {\n return ring.concat([ring[0]]);\n }\n return ring;\n}\nfunction getCoordinates(node) {\n return nodeVal(get1(node, \"coordinates\"));\n}\nfunction getGeometry(node) {\n let geometries = [];\n let coordTimes = [];\n for (let i = 0; i < node.childNodes.length; i++) {\n const child = node.childNodes.item(i);\n if (isElement(child)) {\n switch (child.tagName) {\n case \"MultiGeometry\":\n case \"MultiTrack\":\n case \"gx:MultiTrack\": {\n const childGeometries = getGeometry(child);\n geometries = geometries.concat(childGeometries.geometries);\n coordTimes = coordTimes.concat(childGeometries.coordTimes);\n break;\n }\n case \"Point\": {\n const coordinates = coord1(getCoordinates(child));\n if (coordinates.length >= 2) {\n geometries.push({\n type: \"Point\",\n coordinates,\n });\n }\n break;\n }\n case \"LinearRing\":\n case \"LineString\": {\n const coordinates = coord(getCoordinates(child));\n if (coordinates.length >= 2) {\n geometries.push({\n type: \"LineString\",\n coordinates,\n });\n }\n break;\n }\n case \"Polygon\": {\n const coords = [];\n for (const linearRing of $(child, \"LinearRing\")) {\n const ring = fixRing(coord(getCoordinates(linearRing)));\n if (ring.length >= 4) {\n coords.push(ring);\n }\n }\n if (coords.length) {\n geometries.push({\n type: \"Polygon\",\n coordinates: coords,\n });\n }\n break;\n }\n case \"Track\":\n case \"gx:Track\": {\n const gx = gxCoords(child);\n if (!gx)\n break;\n const { times, geometry } = gx;\n geometries.push(geometry);\n if (times.length)\n coordTimes.push(times);\n break;\n }\n }\n }\n }\n return {\n geometries,\n coordTimes,\n };\n}\n\nfunction geometryListToGeometry(geometries) {\n return geometries.length === 0\n ? null\n : geometries.length === 1\n ? geometries[0]\n : {\n type: \"GeometryCollection\",\n geometries,\n };\n}\nfunction getPlacemark(node, styleMap, schema, options) {\n const { coordTimes, geometries } = getGeometry(node);\n const geometry = geometryListToGeometry(geometries);\n if (!geometry && options.skipNullGeometry) {\n return null;\n }\n const feature = {\n type: \"Feature\",\n geometry,\n properties: Object.assign(getMulti(node, [\n \"name\",\n \"address\",\n \"visibility\",\n \"open\",\n \"phoneNumber\",\n \"description\",\n ]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractExtendedData(node, schema), extractTimeSpan(node), extractTimeStamp(node), coordTimes.length\n ? {\n coordinateProperties: {\n times: coordTimes.length === 1 ? coordTimes[0] : coordTimes,\n },\n }\n : {}),\n };\n if (feature.properties?.visibility !== undefined) {\n feature.properties.visibility = feature.properties.visibility !== \"0\";\n }\n const id = node.getAttribute(\"id\");\n if (id !== null && id !== \"\")\n feature.id = id;\n return feature;\n}\n\nfunction getGroundOverlayBox(node) {\n const latLonQuad = get1(node, \"gx:LatLonQuad\");\n if (latLonQuad) {\n const ring = fixRing(coord(getCoordinates(node)));\n return {\n geometry: {\n type: \"Polygon\",\n coordinates: [ring],\n },\n };\n }\n return getLatLonBox(node);\n}\nconst DEGREES_TO_RADIANS = Math.PI / 180;\nfunction rotateBox(bbox, coordinates, rotation) {\n const center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];\n return [\n coordinates[0].map((coordinate) => {\n const dy = coordinate[1] - center[1];\n const dx = coordinate[0] - center[0];\n const distance = Math.sqrt(Math.pow(dy, 2) + Math.pow(dx, 2));\n const angle = Math.atan2(dy, dx) + rotation * DEGREES_TO_RADIANS;\n return [\n center[0] + Math.cos(angle) * distance,\n center[1] + Math.sin(angle) * distance,\n ];\n }),\n ];\n}\nfunction getLatLonBox(node) {\n const latLonBox = get1(node, \"LatLonBox\");\n if (latLonBox) {\n const north = num1(latLonBox, \"north\");\n const west = num1(latLonBox, \"west\");\n const east = num1(latLonBox, \"east\");\n const south = num1(latLonBox, \"south\");\n const rotation = num1(latLonBox, \"rotation\");\n if (typeof north === \"number\" &&\n typeof south === \"number\" &&\n typeof west === \"number\" &&\n typeof east === \"number\") {\n const bbox = [west, south, east, north];\n let coordinates = [\n [\n [west, north],\n [east, north],\n [east, south],\n [west, south],\n [west, north], // top left (again)\n ],\n ];\n if (typeof rotation === \"number\") {\n coordinates = rotateBox(bbox, coordinates, rotation);\n }\n return {\n bbox,\n geometry: {\n type: \"Polygon\",\n coordinates,\n },\n };\n }\n }\n return null;\n}\nfunction getGroundOverlay(node, styleMap, schema, options) {\n const box = getGroundOverlayBox(node);\n const geometry = box?.geometry || null;\n if (!geometry && options.skipNullGeometry) {\n return null;\n }\n const feature = {\n type: \"Feature\",\n geometry,\n properties: Object.assign(\n /**\n * Related to\n * https://gist.github.com/tmcw/037a1cb6660d74a392e9da7446540f46\n */\n { \"@geometry-type\": \"groundoverlay\" }, getMulti(node, [\n \"name\",\n \"address\",\n \"visibility\",\n \"open\",\n \"phoneNumber\",\n \"description\",\n ]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractIconHref(node), extractExtendedData(node, schema), extractTimeSpan(node), extractTimeStamp(node)),\n };\n if (box?.bbox) {\n feature.bbox = box.bbox;\n }\n if (feature.properties?.visibility !== undefined) {\n feature.properties.visibility = feature.properties.visibility !== \"0\";\n }\n const id = node.getAttribute(\"id\");\n if (id !== null && id !== \"\")\n feature.id = id;\n return feature;\n}\n\nfunction getStyleId(style) {\n let id = style.getAttribute(\"id\");\n const parentNode = style.parentNode;\n if (!id &&\n isElement(parentNode) &&\n parentNode.localName === \"CascadingStyle\") {\n id = parentNode.getAttribute(\"kml:id\") || parentNode.getAttribute(\"id\");\n }\n return normalizeId(id || \"\");\n}\nfunction buildStyleMap(node) {\n const styleMap = {};\n for (const style of $(node, \"Style\")) {\n styleMap[getStyleId(style)] = extractStyle(style);\n }\n for (const map of $(node, \"StyleMap\")) {\n const id = normalizeId(map.getAttribute(\"id\") || \"\");\n val1(map, \"styleUrl\", (styleUrl) => {\n styleUrl = normalizeId(styleUrl);\n if (styleMap[styleUrl]) {\n styleMap[id] = styleMap[styleUrl];\n }\n });\n }\n return styleMap;\n}\nfunction buildSchema(node) {\n const schema = {};\n for (const field of $(node, \"SimpleField\")) {\n schema[field.getAttribute(\"name\") || \"\"] =\n typeConverters[field.getAttribute(\"type\") || \"\"] ||\n typeConverters[\"string\"];\n }\n return schema;\n}\nconst FOLDER_PROPS = [\n \"name\",\n \"visibility\",\n \"open\",\n \"address\",\n \"description\",\n \"phoneNumber\",\n \"visibility\",\n];\nfunction getFolder(node) {\n const meta = {};\n for (const child of Array.from(node.childNodes)) {\n if (isElement(child) && FOLDER_PROPS.includes(child.tagName)) {\n meta[child.tagName] = nodeVal(child);\n }\n }\n return {\n type: \"folder\",\n meta,\n children: [],\n };\n}\n/**\n * Yield a nested tree with KML folder structure\n *\n * This generates a tree with the given structure:\n *\n * ```js\n * {\n * \"type\": \"root\",\n * \"children\": [\n * {\n * \"type\": \"folder\",\n * \"meta\": {\n * \"name\": \"Test\"\n * },\n * \"children\": [\n * // ...features and folders\n * ]\n * }\n * // ...features\n * ]\n * }\n * ```\n *\n * ### GroundOverlay\n *\n * GroundOverlay elements are converted into\n * `Feature` objects with `Polygon` geometries,\n * a property like:\n *\n * ```json\n * {\n * \"@geometry-type\": \"groundoverlay\"\n * }\n * ```\n *\n * And the ground overlay's image URL in the `href`\n * property. Ground overlays will need to be displayed\n * with a separate method to other features, depending\n * on which map framework you're using.\n */\nfunction kmlWithFolders(node, options = {\n skipNullGeometry: false,\n}) {\n const styleMap = buildStyleMap(node);\n const schema = buildSchema(node);\n const tree = { type: \"root\", children: [] };\n function traverse(node, pointer, options) {\n if (isElement(node)) {\n switch (node.tagName) {\n case \"GroundOverlay\": {\n const placemark = getGroundOverlay(node, styleMap, schema, options);\n if (placemark) {\n pointer.children.push(placemark);\n }\n break;\n }\n case \"Placemark\": {\n const placemark = getPlacemark(node, styleMap, schema, options);\n if (placemark) {\n pointer.children.push(placemark);\n }\n break;\n }\n case \"Folder\": {\n const folder = getFolder(node);\n pointer.children.push(folder);\n pointer = folder;\n break;\n }\n }\n }\n if (node.childNodes) {\n for (let i = 0; i < node.childNodes.length; i++) {\n traverse(node.childNodes[i], pointer, options);\n }\n }\n }\n traverse(node, tree, options);\n return tree;\n}\n/**\n * Convert KML to GeoJSON incrementally, returning\n * a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)\n * that yields output feature by feature.\n */\nfunction* kmlGen(node, options = {\n skipNullGeometry: false,\n}) {\n const styleMap = buildStyleMap(node);\n const schema = buildSchema(node);\n for (const placemark of $(node, \"Placemark\")) {\n const feature = getPlacemark(placemark, styleMap, schema, options);\n if (feature)\n yield feature;\n }\n for (const groundOverlay of $(node, \"GroundOverlay\")) {\n const feature = getGroundOverlay(groundOverlay, styleMap, schema, options);\n if (feature)\n yield feature;\n }\n}\n/**\n * Convert a KML document to GeoJSON. The first argument, `doc`, must be a KML\n * document as an XML DOM - not as a string. You can get this using jQuery's default\n * `.ajax` function or using a bare XMLHttpRequest with the `.response` property\n * holding an XML DOM.\n *\n * The output is a JavaScript object of GeoJSON data. You can convert it to a string\n * with [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)\n * or use it directly in libraries.\n */\nfunction kml(node, options = {\n skipNullGeometry: false,\n}) {\n return {\n type: \"FeatureCollection\",\n features: Array.from(kmlGen(node, options)),\n };\n}\n\nexport { gpx, gpxGen, kml, kmlGen, kmlWithFolders, tcx, tcxGen };\n//# sourceMappingURL=togeojson.es.mjs.map\n","'use strict';\n\n/**\n * Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)\n *\n * Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js)\n * by [Mark McClure](http://facstaff.unca.edu/mcmcclur/)\n *\n * @module polyline\n */\n\nvar polyline = {};\n\nfunction py2_round(value) {\n // Google's polyline algorithm uses the same rounding strategy as Python 2, which is different from JS for negative values\n return Math.floor(Math.abs(value) + 0.5) * (value >= 0 ? 1 : -1);\n}\n\nfunction encode(current, previous, factor) {\n current = py2_round(current * factor);\n previous = py2_round(previous * factor);\n var coordinate = (current - previous) * 2;\n if (coordinate < 0) {\n coordinate = -coordinate - 1\n }\n var output = '';\n while (coordinate >= 0x20) {\n output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63);\n coordinate /= 32;\n }\n output += String.fromCharCode((coordinate | 0) + 63);\n return output;\n}\n\n/**\n * Decodes to a [latitude, longitude] coordinates array.\n *\n * This is adapted from the implementation in Project-OSRM.\n *\n * @param {String} str\n * @param {Number} precision\n * @returns {Array}\n *\n * @see https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js\n */\npolyline.decode = function(str, precision) {\n var index = 0,\n lat = 0,\n lng = 0,\n coordinates = [],\n shift = 0,\n result = 0,\n byte = null,\n latitude_change,\n longitude_change,\n factor = Math.pow(10, Number.isInteger(precision) ? precision : 5);\n\n // Coordinates have variable length when encoded, so just keep\n // track of whether we've hit the end of the string. In each\n // loop iteration, a single coordinate is decoded.\n while (index < str.length) {\n\n // Reset shift, result, and byte\n byte = null;\n shift = 1;\n result = 0;\n\n do {\n byte = str.charCodeAt(index++) - 63;\n result += (byte & 0x1f) * shift;\n shift *= 32;\n } while (byte >= 0x20);\n\n latitude_change = (result & 1) ? ((-result - 1) / 2) : (result / 2);\n\n shift = 1;\n result = 0;\n\n do {\n byte = str.charCodeAt(index++) - 63;\n result += (byte & 0x1f) * shift;\n shift *= 32;\n } while (byte >= 0x20);\n\n longitude_change = (result & 1) ? ((-result - 1) / 2) : (result / 2);\n\n lat += latitude_change;\n lng += longitude_change;\n\n coordinates.push([lat / factor, lng / factor]);\n }\n\n return coordinates;\n};\n\n/**\n * Encodes the given [latitude, longitude] coordinates array.\n *\n * @param {Array.>} coordinates\n * @param {Number} precision\n * @returns {String}\n */\npolyline.encode = function(coordinates, precision) {\n if (!coordinates.length) { return ''; }\n\n var factor = Math.pow(10, Number.isInteger(precision) ? precision : 5),\n output = encode(coordinates[0][0], 0, factor) + encode(coordinates[0][1], 0, factor);\n\n for (var i = 1; i < coordinates.length; i++) {\n var a = coordinates[i], b = coordinates[i - 1];\n output += encode(a[0], b[0], factor);\n output += encode(a[1], b[1], factor);\n }\n\n return output;\n};\n\nfunction flipped(coords) {\n var flipped = [];\n for (var i = 0; i < coords.length; i++) {\n var coord = coords[i].slice();\n flipped.push([coord[1], coord[0]]);\n }\n return flipped;\n}\n\n/**\n * Encodes a GeoJSON LineString feature/geometry.\n *\n * @param {Object} geojson\n * @param {Number} precision\n * @returns {String}\n */\npolyline.fromGeoJSON = function(geojson, precision) {\n if (geojson && geojson.type === 'Feature') {\n geojson = geojson.geometry;\n }\n if (!geojson || geojson.type !== 'LineString') {\n throw new Error('Input must be a GeoJSON LineString');\n }\n return polyline.encode(flipped(geojson.coordinates), precision);\n};\n\n/**\n * Decodes to a GeoJSON LineString geometry.\n *\n * @param {String} str\n * @param {Number} precision\n * @returns {Object}\n */\npolyline.toGeoJSON = function(str, precision) {\n var coords = polyline.decode(str, precision);\n return {\n type: 'LineString',\n coordinates: flipped(coords)\n };\n};\n\nif (typeof module === 'object' && module.exports) {\n module.exports = polyline;\n}\n","module.exports = (() => {\n 'use strict';\n\n const purgeProps = (obj, blacklist) => {\n if (obj) {\n let rs = Object.assign({}, obj);\n if (blacklist) {\n for (let prop of blacklist) {\n delete rs[prop];\n }\n }\n return rs;\n }\n return {};\n }\n\n const mergeProps = (obj1, obj2) => {\n obj1 = obj1 ? obj1 : {};\n obj2 = obj2 ? obj2 : {};\n return Object.assign(obj1, obj2);\n }\n\n const addPropToFeature = (f, k, v) => {\n if (f.properties && k && v) {\n f.properties[k] = v;\n }\n }\n\n const addPropToFeatures = (fs, k, v) => {\n for (let f of fs) {\n addPropToFeature(f, k, v);\n }\n }\n\n const first = a => a[0];\n const last = a => a[a.length - 1];\n const coordsToKey = a => a.join(',');\n\n const addToMap = (m, k, v) => {\n let a = m[k];\n if (a) {\n a.push(v);\n } else {\n m[k] = [v];\n }\n }\n\n const removeFromMap = (m, k, v) => {\n let a = m[k];\n let idx = null;\n if (a && (idx = a.indexOf(v)) >= 0) {\n a.splice(idx, 1);\n }\n }\n\n const getFirstFromMap = (m, k) => {\n let a = m[k];\n if (a && a.length > 0) {\n return a[0];\n }\n return null;\n }\n\n // need 3+ different points to form a ring, here using > 3 is 'coz a the first and the last points are actually the same\n const isRing = a => a.length > 3 && coordsToKey(first(a)) === coordsToKey(last(a));\n\n const ringDirection = (a, xIdx, yIdx) => {\n xIdx = xIdx || 0, yIdx = yIdx || 1;\n // get the index of the point which has the maximum x value\n let m = a.reduce((maxxIdx, v, idx) => a[maxxIdx][xIdx] > v[xIdx] ? maxxIdx : idx, 0);\n // 'coz the first point is virtually the same one as the last point, \n // we need to skip a.length - 1 for left when m = 0,\n // and skip 0 for right when m = a.length - 1;\n let l = m <= 0 ? a.length - 2 : m - 1, r = m >= a.length - 1 ? 1 : m + 1;\n let xa = a[l][xIdx], xb = a[m][xIdx], xc = a[r][xIdx];\n let ya = a[l][yIdx], yb = a[m][yIdx], yc = a[r][yIdx];\n let det = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);\n return det < 0 ? 'clockwise' : 'counterclockwise';\n }\n\n const ptInsidePolygon = (pt, polygon, xIdx, yIdx) => {\n xIdx = xIdx || 0, yIdx = yIdx || 1;\n let result = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n if ((polygon[i][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[j][xIdx] ||\n polygon[j][xIdx] <= pt[xIdx] && pt[xIdx] < polygon[i][xIdx]) &&\n pt[yIdx] < (polygon[j][yIdx] - polygon[i][yIdx]) * (pt[xIdx] - polygon[i][xIdx]) / (polygon[j][xIdx] - polygon[i][xIdx]) + polygon[i][yIdx]) {\n result = !result;\n }\n\n }\n return result;\n }\n\n const strToFloat = el => el instanceof Array ? el.map(strToFloat) : parseFloat(el);\n\n class RefElements extends Map {\n constructor() {\n super();\n this.binders = [];\n }\n\n add(k, v) {\n if (!this.has(k)) {\n this.set(k, v);\n }\n // suppress duplcated key error\n // else\n // throw `Error: adding duplicated key '${k}' to RefElements`;\n }\n\n addBinder(binder) {\n this.binders.push(binder);\n }\n\n bindAll() {\n this.binders.forEach(binder => binder.bind());\n }\n }\n\n class LateBinder {\n constructor(container, valueFunc, ctx, args) {\n this.container = container;\n this.valueFunc = valueFunc;\n this.ctx = ctx;\n this.args = args;\n }\n\n bind() {\n let v = this.valueFunc.apply(this.ctx, this.args);\n if (this.container instanceof Array) {\n let idx = this.container.indexOf(this);\n if (idx >= 0) {\n let args = [idx, 1];\n if (v) {\n args.push(v);\n }\n [].splice.apply(this.container, args);\n }\n } else if (typeof this.container === 'object') {\n let k = Object.keys(this.container).find(v => this.container[v] === this);\n if (k) {\n if (v) {\n this.container[k] = v;\n } else {\n delete this.container[k];\n }\n }\n }\n }\n }\n\n class WayCollection extends Array {\n constructor() {\n super();\n this.firstMap = {};\n this.lastMap = {};\n }\n\n addWay(way) {\n way = way.toCoordsArray();\n if (way.length > 0) {\n this.push(way);\n addToMap(this.firstMap, coordsToKey(first(way)), way);\n addToMap(this.lastMap, coordsToKey(last(way)), way);\n }\n }\n\n toStrings() {\n let strings = [], way = null;\n while (way = this.shift()) {\n removeFromMap(this.firstMap, coordsToKey(first(way)), way);\n removeFromMap(this.lastMap, coordsToKey(last(way)), way);\n let current = way, next = null;\n do {\n let key = coordsToKey(last(current)), shouldReverse = false;\n\n next = getFirstFromMap(this.firstMap, key);\n if (!next) {\n next = getFirstFromMap(this.lastMap, key);\n shouldReverse = true;\n }\n\n if (next) {\n this.splice(this.indexOf(next), 1);\n removeFromMap(this.firstMap, coordsToKey(first(next)), next);\n removeFromMap(this.lastMap, coordsToKey(last(next)), next);\n if (shouldReverse) {\n // always reverse shorter one to save time\n if (next.length > current.length) {\n [current, next] = [next, current];\n }\n next.reverse();\n }\n\n current = current.concat(next.slice(1));\n }\n } while (next);\n strings.push(strToFloat(current));\n }\n\n return strings;\n }\n\n toRings(direction) {\n let strings = this.toStrings();\n let rings = [], string = null;\n while (string = strings.shift()) {\n if (isRing(string)) {\n if (ringDirection(string) !== direction) {\n string.reverse();\n }\n rings.push(string);\n }\n }\n return rings;\n }\n }\n\n return {\n purgeProps, mergeProps,\n first, last, coordsToKey,\n addToMap, removeFromMap, getFirstFromMap,\n isRing, ringDirection, ptInsidePolygon, strToFloat,\n RefElements, LateBinder, WayCollection\n };\n})();\n","module.exports = (() => {\n 'use strict';\n\n const { first, last, coordsToKey,\n addToMap, removeFromMap, getFirstFromMap,\n isRing, ringDirection, ptInsidePolygon, strToFloat,\n LateBinder, WayCollection } = require('./utils.js'),\n polygonTags = require('./polytags.json');\n\n class OsmObject {\n constructor(type, id, refElems) {\n this.type = type;\n this.id = id;\n this.refElems = refElems;\n this.tags = {};\n this.props = { id: this.getCompositeId() };\n this.refCount = 0;\n this.hasTag = false;\n if (refElems) {\n refElems.add(this.getCompositeId(), this);\n }\n }\n\n addTags(tags) {\n this.tags = Object.assign(this.tags, tags);\n this.hasTag = tags ? true : false;\n }\n\n addTag(k, v) {\n this.tags[k] = v;\n this.hasTag = k ? true : false;\n }\n\n addProp(k, v) {\n this.props[k] = v;\n }\n\n addProps(props) {\n this.props = Object.assign(this.props, props);\n }\n\n getCompositeId() {\n return `${this.type}/${this.id}`;\n }\n\n getProps() {\n return Object.assign(this.props, this.tags);\n }\n\n toFeatureArray() {\n return [];\n }\n }\n\n class Node extends OsmObject {\n constructor(id, refElems) {\n super('node', id, refElems);\n this.latLng = null;\n }\n\n setLatLng(latLng) {\n this.latLng = latLng;\n }\n\n toFeatureArray() {\n if (this.latLng) {\n return [{\n type: 'Feature',\n id: this.getCompositeId(),\n properties: this.getProps(),\n geometry: {\n type: 'Point',\n coordinates: strToFloat([this.latLng.lon, this.latLng.lat])\n }\n }];\n }\n\n return [];\n }\n\n getLatLng() {\n return this.latLng;\n }\n }\n\n class Way extends OsmObject {\n constructor(id, refElems) {\n super('way', id, refElems);\n this.latLngArray = [];\n this.isPolygon = false;\n }\n\n addLatLng(latLng) {\n this.latLngArray.push(latLng);\n }\n\n setLatLngArray(latLngArray) {\n this.latLngArray = latLngArray;\n }\n\n addNodeRef(ref) {\n let binder = new LateBinder(this.latLngArray, function (id) {\n let node = this.refElems.get(`node/${id}`);\n if (node) {\n node.refCount++;\n return node.getLatLng();\n }\n }, this, [ref]);\n\n this.latLngArray.push(binder);\n this.refElems.addBinder(binder);\n }\n\n analyzeGeometryType(k, v) {\n let o = polygonTags[k];\n if (o) {\n this.isPolygon = true;\n if (o.whitelist) {\n this.isPolygon = o.whitelist.indexOf(v) >= 0 ? true : false;\n } else if (o.blacklist) {\n this.isPolygon = o.blacklist.indexOf(v) >= 0 ? false : true;\n }\n }\n }\n\n addTags(tags) {\n super.addTags(tags);\n for (let [k, v] of Object.entries(tags)) {\n this.analyzeGeometryType(k, v);\n }\n }\n\n addTag(k, v) {\n super.addTag(k, v);\n this.analyzeGeometryType(k, v);\n }\n\n toCoordsArray() {\n return this.latLngArray.map(latLng => [latLng.lon, latLng.lat]);\n }\n\n toFeatureArray() {\n let coordsArray = this.toCoordsArray();\n if (coordsArray.length > 1) {\n coordsArray = strToFloat(coordsArray);\n let feature = {\n type: 'Feature',\n id: this.getCompositeId(),\n properties: this.getProps(),\n geometry: {\n type: 'LineString',\n coordinates: coordsArray\n }\n };\n\n if (this.isPolygon && isRing(coordsArray)) {\n if (ringDirection(coordsArray) !== 'counterclockwise') {\n coordsArray.reverse();\n }\n\n feature.geometry = {\n type: 'Polygon',\n coordinates: [coordsArray]\n };\n\n return [feature];\n }\n\n return [feature];\n }\n\n return [];\n }\n }\n\n class Relation extends OsmObject {\n constructor(id, refElems) {\n super('relation', id, refElems);\n this.relations = [];\n this.nodes = [];\n this.bounds = null;\n }\n\n setBounds(bounds) {\n this.bounds = bounds;\n }\n\n addMember(member) {\n switch (member.type) {\n // super relation, need to do combination\n case 'relation':\n let binder = new LateBinder(this.relations, function (id) {\n let relation = this.refElems.get(`relation/${id}`);\n if (relation) {\n relation.refCount++;\n return relation;\n }\n }, this, [member.ref]);\n this.relations.push(binder);\n this.refElems.addBinder(binder);\n break;\n\n case 'way':\n if (!member.role) {\n member.role = '';\n }\n let ways = this[member.role];\n if (!ways) {\n ways = this[member.role] = [];\n }\n if (member.geometry) {\n let way = new Way(member.ref, this.refElems);\n way.setLatLngArray(member.geometry);\n way.refCount++;\n ways.push(way);\n } else if (member.nodes) {\n let way = new Way(member.ref, this.refElems);\n for (let nid of member.nodes) {\n way.addNodeRef(nid);\n }\n way.refCount++;\n ways.push(way);\n } else {\n let binder = new LateBinder(ways, function (id) {\n let way = this.refElems.get(`way/${id}`);\n if (way) {\n way.refCount++;\n return way;\n }\n }, this, [member.ref]);\n ways.push(binder);\n this.refElems.addBinder(binder);\n }\n break;\n\n case 'node':\n let node = null;\n if (member.lat && member.lon) {\n node = new Node(member.ref, this.refElems);\n node.setLatLng({ lon: member.lon, lat: member.lat });\n if (member.tags) {\n node.addTags(member.tags);\n }\n for (let [k, v] of Object.entries(member)) {\n if (['id', 'type', 'lat', 'lon'].indexOf(k) < 0) {\n node.addProp(k, v);\n }\n }\n\n node.refCount++;\n this.nodes.push(node);\n } else {\n let binder = new LateBinder(this.nodes, function (id) {\n let node = this.refElems.get(`node/${id}`);\n if (node) {\n node.refCount++;\n return node;\n }\n }, this, [member.ref]);\n this.nodes.push(binder);\n this.refElems.addBinder(binder);\n }\n break;\n\n default:\n break;\n }\n }\n\n toFeatureArray() {\n const constructStringGeometry = (ws) => {\n let strings = ws ? ws.toStrings() : [];\n if (strings.length > 0) {\n if (strings.length === 1) return {\n type: 'LineString',\n coordinates: strings[0]\n }\n\n return {\n type: 'MultiLineString',\n coordinates: strings\n }\n }\n return null;\n }\n\n const constructPolygonGeometry = (ows, iws) => {\n let outerRings = ows ? ows.toRings('counterclockwise') : [],\n innerRings = iws ? iws.toRings('clockwise') : [];\n\n if (outerRings.length > 0) {\n let compositPolyons = [];\n\n let ring = null;\n for (ring of outerRings)\n compositPolyons.push([ring]);\n\n // link inner polygons to outer containers\n while (ring = innerRings.shift()) {\n for (let idx in outerRings) {\n if (ptInsidePolygon(first(ring), outerRings[idx])) {\n compositPolyons[idx].push(ring);\n break;\n }\n }\n }\n\n // construct the Polygon/MultiPolygon geometry\n if (compositPolyons.length === 1) {\n return {\n type: 'Polygon',\n coordinates: compositPolyons[0]\n };\n }\n\n return {\n type: 'MultiPolygon',\n coordinates: compositPolyons\n }\n }\n\n return null;\n }\n\n let polygonFeatures = [], stringFeatures = [], pointFeatures = [];\n const waysFieldNames = ['outer', 'inner', ''];\n // need to do combination when there're nested relations\n for (let relation of this.relations) {\n if (relation) {\n for (let fieldName of waysFieldNames) {\n let ways = relation[fieldName];\n if (ways) {\n let thisWays = this[fieldName];\n if (thisWays) {\n [].splice.apply(thisWays, [thisWays.length, 0].concat(ways));\n } else {\n this[fieldName] = ways;\n }\n }\n }\n }\n }\n\n for (let fieldName of waysFieldNames) {\n let ways = this[fieldName];\n if (ways) {\n this[fieldName] = new WayCollection();\n for (let way of ways) {\n this[fieldName].addWay(way);\n }\n }\n }\n\n let geometry = null;\n\n let feature = {\n type: 'Feature',\n id: this.getCompositeId(),\n bbox: this.bounds,\n properties: this.getProps()\n };\n\n if (!this.bounds) {\n delete feature.bbox;\n }\n\n if (this.outer) {\n geometry = constructPolygonGeometry(this.outer, this.inner);\n if (geometry) {\n feature.geometry = geometry;\n polygonFeatures.push(feature);\n }\n }\n else if (this['']) {\n geometry = constructStringGeometry(this['']);\n if (geometry) {\n feature.geometry = geometry;\n stringFeatures.push(feature);\n }\n }\n\n for (let node of this.nodes) {\n pointFeatures = pointFeatures.concat(node.toFeatureArray());\n }\n\n return polygonFeatures.concat(stringFeatures).concat(pointFeatures);\n }\n }\n\n return { Node, Way, Relation };\n})();","module.exports = (() => {\n 'use strict';\n\n function conditioned(evt) {\n return evt.match(/^(.+?)\\[(.+?)\\]>$/g) != null;\n }\n\n function parseEvent(evt) {\n let match = /^(.+?)\\[(.+?)\\]>$/g.exec(evt);\n if (match) {\n return { evt: match[1] + '>', exp: match[2] };\n }\n return { evt: evt };\n }\n\n function genConditionFunc(cond) {\n let body = 'return ' + cond.replace(/(\\$.+?)(?=[=!.])/g, 'node.$&') + ';';\n return new Function('node', body);\n }\n\n return class {\n constructor(opts) {\n if (opts) {\n this.queryParent = opts.queryParent ? true : false;\n this.progressive = opts.progressive;\n if (this.queryParent) {\n this.parentMap = new WeakMap();\n }\n }\n this.evtListeners = {};\n }\n\n parse(xml, parent, dir) {\n dir = dir ? dir + '.' : '';\n let nodeRegEx = /<([^ >\\/]+)(.*?)>/mg, nodeMatch = null, nodes = [];\n while (nodeMatch = nodeRegEx.exec(xml)) {\n let tag = nodeMatch[1], node = { $tag: tag }, fullTag = dir + tag;\n\n let attrText = nodeMatch[2].trim(), closed = false;\n if (attrText.endsWith('/') || tag.startsWith('?') || tag.startsWith('!')) {\n closed = true;\n }\n\n let attRegEx1 = /([^ ]+?)=\"(.+?)\"/g, attRegEx2 = /([^ ]+?)='(.+?)'/g;\n let attMatch = null, hasAttrs = false;\n while (attMatch = attRegEx1.exec(attrText)) {\n hasAttrs = true;\n node[attMatch[1]] = attMatch[2];\n }\n if (!hasAttrs)\n while (attMatch = attRegEx2.exec(attrText)) {\n hasAttrs = true;\n node[attMatch[1]] = attMatch[2];\n }\n\n if (!hasAttrs && attrText !== '') {\n node.text = attrText;\n }\n if (this.progressive) {\n this.emit(`<${fullTag}>`, node, parent);\n }\n\n if (!closed) {\n let innerRegEx = new RegExp(`([^]+?)<\\/${tag}>`, 'g');\n innerRegEx.lastIndex = nodeRegEx.lastIndex;\n let innerMatch = innerRegEx.exec(xml);\n if (innerMatch && innerMatch[1]) {\n nodeRegEx.lastIndex = innerRegEx.lastIndex;\n let innerNodes = this.parse(innerMatch[1], node, fullTag);\n if (innerNodes.length > 0) {\n node.$innerNodes = innerNodes;\n } else {\n node.$innerText = innerMatch[1];\n }\n }\n }\n if (this.queryParent && parent) {\n this.parentMap.set(node, parent);\n }\n\n if (this.progressive) {\n this.emit(`${fullTag}>`, node, parent);\n }\n\n nodes.push(node);\n }\n\n return nodes;\n }\n\n getParent(node) {\n if (this.queryParent) {\n return this.parentMap.get(node);\n }\n return null;\n }\n\n #addListener(evt, func) {\n let funcs = this.evtListeners[evt];\n if (funcs) {\n funcs.push(func);\n } else {\n this.evtListeners[evt] = [func];\n }\n }\n\n // support javascript condition for the last tag\n addListener(evt, func) {\n if (conditioned(evt)) {\n // func.prototype = evt;\n evt = parseEvent(evt);\n func.condition = genConditionFunc(evt.exp);\n evt = evt.evt;\n }\n this.#addListener(evt, func);\n }\n\n #removeListener(evt, func) {\n let funcs = this.evtListeners[evt];\n let idx = null;\n if (funcs && (idx = funcs.indexOf(func)) >= 0) {\n funcs.splice(idx, 1);\n }\n }\n\n removeListener(evt, func) {\n if (conditioned(evt)) {\n evt = parseEvent(evt);\n evt = evt.evt;\n }\n this.#removeListener(evt, func);\n }\n\n emit(evt, ...args) {\n let funcs = this.evtListeners[evt];\n if (funcs) {\n for (let func of funcs) {\n if (func.condition) {\n if (func.condition.apply(null, args) === true) {\n func.apply(null, args);\n }\n } else {\n func.apply(null, args);\n }\n }\n }\n }\n\n on(evt, func) {\n this.addListener(evt, func);\n }\n\n off(evt, func) {\n this.removeListener(evt, func);\n }\n };\n})();","const { Node, Way, Relation } = require('./osmobjs.js'),\n { purgeProps, RefElements } = require('./utils.js'),\n XmlParser = require('./xmlparser.js');\n\nmodule.exports = (osm, opts) => {\n let completeFeature = false, renderTagged = false, excludeWay = true;\n\n const parseOpts = opts => {\n if (opts) {\n completeFeature = opts.completeFeature || opts.allFeatures ? true : false;\n renderTagged = opts.renderTagged ? true : false;\n let wayOpt = opts.suppressWay || opts.excludeWay;\n if (wayOpt !== undefined && !wayOpt) {\n excludeWay = false;\n }\n }\n }\n\n parseOpts(opts);\n\n const detectFormat = osm => {\n if (osm.elements) {\n return 'json';\n }\n if (osm.indexOf('= 0) {\n return 'xml';\n }\n if (osm.trim().startsWith('{')) {\n return 'json-raw';\n }\n return 'invalid';\n }\n\n let format = detectFormat(osm);\n\n let refElements = new RefElements(), featureArray = [];\n\n const analyzeFeaturesFromJson = osm => {\n for (let elem of osm.elements) {\n switch (elem.type) {\n case 'node':\n let node = new Node(elem.id, refElements);\n if (elem.tags) {\n node.addTags(elem.tags);\n }\n node.addProps(purgeProps(elem, ['id', 'type', 'tags', 'lat', 'lon']));\n node.setLatLng(elem);\n break;\n\n case 'way':\n let way = new Way(elem.id, refElements);\n if (elem.tags) {\n way.addTags(elem.tags);\n }\n way.addProps(purgeProps(elem, ['id', 'type', 'tags', 'nodes', 'geometry']));\n if (elem.nodes) {\n for (let n of elem.nodes) {\n way.addNodeRef(n);\n }\n } else if (elem.geometry) {\n way.setLatLngArray(elem.geometry);\n }\n break;\n\n case 'relation':\n let relation = new Relation(elem.id, refElements);\n if (elem.bounds) {\n relation.setBounds([parseFloat(elem.bounds.minlon), parseFloat(elem.bounds.minlat), parseFloat(elem.bounds.maxlon), parseFloat(elem.bounds.maxlat)]);\n }\n if (elem.tags) {\n relation.addTags(elem.tags);\n }\n relation.addProps(purgeProps(elem, ['id', 'type', 'tags', 'bounds', 'members']));\n if (elem.members) {\n for (let member of elem.members) {\n relation.addMember(member);\n }\n }\n break;\n\n default:\n break;\n }\n }\n }\n\n const analyzeFeaturesFromXml = osm => {\n const xmlParser = new XmlParser({ progressive: true });\n\n xmlParser.on('', node => {\n let nd = new Node(node.id, refElements);\n for (let [k, v] of Object.entries(node))\n if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0) {\n nd.addProp(k, v);\n }\n nd.setLatLng(node);\n if (node.$innerNodes) {\n for (let ind of node.$innerNodes) {\n if (ind.$tag === 'tag') {\n nd.addTag(ind.k, ind.v);\n }\n }\n }\n });\n\n xmlParser.on('', node => {\n let way = new Way(node.id, refElements);\n for (let [k, v] of Object.entries(node)) {\n if (!k.startsWith('$') && ['id'].indexOf(k) < 0) {\n way.addProp(k, v);\n }\n }\n if (node.$innerNodes) {\n for (let ind of node.$innerNodes) {\n if (ind.$tag === 'nd') {\n if (ind.lon && ind.lat) {\n way.addLatLng(ind);\n } else if (ind.ref) {\n way.addNodeRef(ind.ref);\n }\n } else if (ind.$tag === 'tag')\n way.addTag(ind.k, ind.v);\n }\n }\n });\n\n xmlParser.on('', node => {\n new Relation(node.id, refElements);\n });\n\n xmlParser.on('', (node, parent) => {\n let relation = refElements.get(`relation/${parent.id}`);\n let member = {\n type: node.type,\n role: node.role ? node.role : '',\n ref: node.ref\n };\n if (node.lat && node.lon) {\n member.lat = node.lat, member.lon = node.lon, member.tags = {};\n for (let [k, v] of Object.entries(node)) {\n if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0) {\n member[k] = v;\n }\n }\n }\n if (node.$innerNodes) {\n let geometry = [];\n let nodes = [];\n for (let ind of node.$innerNodes) {\n if (ind.lat && ind.lon) {\n geometry.push(ind);\n } else {\n nodes.push(ind.ref);\n }\n }\n if (geometry.length > 0) {\n member.geometry = geometry;\n } else if (nodes.length > 0) {\n member.nodes = nodes;\n }\n }\n relation.addMember(member);\n });\n\n xmlParser.on('', (node, parent) => {\n refElements.get(`relation/${parent.id}`).setBounds([parseFloat(node.minlon), parseFloat(node.minlat), parseFloat(node.maxlon), parseFloat(node.maxlat)]);\n });\n\n xmlParser.on('', (node, parent) => {\n refElements.get(`relation/${parent.id}`).addTag(node.k, node.v);\n });\n\n xmlParser.parse(osm);\n }\n\n if (format === 'json-raw') {\n osm = JSON.parse(osm);\n if (osm.elements) {\n format = 'json';\n } else {\n format = 'invalid';\n }\n }\n\n if (format === 'json') {\n analyzeFeaturesFromJson(osm);\n } else if (format === 'xml') {\n analyzeFeaturesFromXml(osm);\n }\n\n refElements.bindAll();\n\n for (let v of refElements.values()) {\n if (v.refCount <= 0 || (v.hasTag && renderTagged && !(v instanceof Way && excludeWay))) {\n let features = v.toFeatureArray();\n // return the first geometry of the first relation element\n if (v instanceof Relation && !completeFeature && features.length > 0) {\n return features[0].geometry;\n }\n featureArray = featureArray.concat(features);\n }\n }\n\n return { type: 'FeatureCollection', features: featureArray };\n}\n"],"names":["objectConverter","columns","Function","map","name","i","JSON","stringify","join","dsv$1","delimiter","reFormat","RegExp","delimiterCode","charCodeAt","parseRows","text","f","t","eol","EOL","EOF","rows","N","length","I","n","token","c","j","slice","replace","k","a","push","formatRow","row","formatValue","test","parse","convert","object","customConverter","format","columnSet","Object","create","forEach","column","inferColumns","concat","formatRows","csv","dsv","csvParse","csvParseRows","csvFormat","csvFormatRows","tsv","tsvParse","tsvParseRows","tsvFormat","tsvFormatRows","input","dim","dms","coordToDMS","whole","minutes","seconds","dir","lat","lon","abs","Math","floor","fractionMinutes","search","dims","m","toUpperCase","match","matched","indexOf","deg","parseFloat","min","sec","sign","val","remain","sexagesimalModule","exports","result","pair","one","trim","two","b","swapdim","formatPair","require$$0","sexagesimal","require$$1","latRegex","lonRegex","guessHeader","regexp","score","guessLatHeader","guessLonHeader","keyCount","o","keys","autoDelimiter","x","results","res","dsvFormat","count","arity","sort","csv2geojson_1","isLon","isLat","auto","deleteColumns","csv2geojson","options","callback","latfield","lonfield","crs","features","featurecollection","type","properties","numericFields","split","parsed","d","key","includes","errors","geometry","undefined","lonf","latf","lonk","latk","isNaN","message","index","includeLatLon","coordinates","toLine","gj","line","reduce","aggregatedProperties","newFeature","toPolygon","poly","identity","feature","topology","id","bbox","transformPoint","transform","x0","y0","kx","scale","ky","dx","translate","dy","output","Array","arcs","arc","points","pop","array","reverse","point","p","ring","polygon","geometries","$","element","tagName","from","getElementsByTagName","normalizeId","nodeVal","node","normalize","textContent","get1","get","val1","$num","num1","getMulti","propertyNames","property","isElement","nodeType","getLineStyle","lineStyle","assign","color","stroke","opacity","width","getExtensions","values","child","childNodes","abbreviateName","nodeName","parseNumeric","num","coordPair$1","ll","getAttribute","time","extendedValues","extractProperties","extensions","getElementsByTagNameNS","parentNode","links","link","href","getPoints$1","pointname","pts","times","plural","fill","getRoute","_gpxType","getTrack","segments","track","extractedLines","segment","multi","coordinateProperties","props","entries","getPoint","gpxGen","route","waypoint","EXTENSIONS_NS","TRACKPOINT_ATTRIBUTES","LAP_ATTRIBUTES","getProperties","attributeNames","tag","alias","elem","elements","coordPair","heartRate","alt","getPoints","heartRates","extendedProperties","value","getLap","allExtendedProperties","fromEntries","nameElement","heart","tcxGen","lap","course","fixColor","v","prefix","colorProp","substring","parseInt","numericProperty","source","target","getColor","extractIconHref","icon","extractStyle","polyStyle","outline","extractPoly","extractLine","labelStyle","extractLabel","iconStyle","hotspot","left","top","xunits","yunits","extractIcon","toNumber","Number","typeConverters","string","int","uint","short","ushort","float","double","bool","Boolean","extractExtendedData","schema","extendedData","data","simpleData","typeConverter","getMaybeHTMLDescription","descriptionNode","description","extractTimeSpan","timeSpan","timespan","begin","end","extractTimeStamp","timeStamp","timestamp","extractCascadedStyle","styleMap","styleUrl","removeSpace","trimSpace","splitSpace","coord1","filter","coord","gxCoords","elems","ns","$ns","fixRing","first","last","equal","max","getCoordinates","getGeometry","coordTimes","item","childGeometries","coords","linearRing","gx","getPlacemark","geometryListToGeometry","skipNullGeometry","visibility","getGroundOverlayBox","latLonBox","north","west","east","south","rotation","center","coordinate","distance","sqrt","pow","angle","atan2","DEGREES_TO_RADIANS","cos","sin","rotateBox","getLatLonBox","PI","getGroundOverlay","box","getStyleId","style","localName","buildStyleMap","buildSchema","field","FOLDER_PROPS","kmlGen","placemark","groundOverlay","tree","children","traverse","pointer","folder","meta","getFolder","polyline","py2_round","encode","current","previous","factor","String","fromCharCode","flipped","decode","str","precision","latitude_change","lng","shift","byte","isInteger","fromGeoJSON","geojson","Error","toGeoJSON","module","utils","coordsToKey","addToMap","removeFromMap","idx","splice","getFirstFromMap","isRing","ringDirection","xIdx","yIdx","maxxIdx","l","r","xa","xb","xc","ya","yb","strToFloat","el","RefElements","Map","constructor","super","this","binders","add","has","set","addBinder","binder","bindAll","bind","purgeProps","obj","blacklist","rs","prop","mergeProps","obj1","obj2","ptInsidePolygon","pt","LateBinder","container","valueFunc","ctx","args","apply","find","WayCollection","firstMap","lastMap","addWay","way","toCoordsArray","toStrings","strings","next","shouldReverse","toRings","direction","rings","osmobjs","polygonTags","OsmObject","refElems","tags","getCompositeId","refCount","hasTag","addTags","addTag","addProp","addProps","getProps","toFeatureArray","Node","latLng","setLatLng","getLatLng","Way","latLngArray","isPolygon","addLatLng","setLatLngArray","addNodeRef","ref","analyzeGeometryType","whitelist","coordsArray","Relation","relations","nodes","bounds","setBounds","addMember","member","relation","role","ways","nid","polygonFeatures","stringFeatures","pointFeatures","waysFieldNames","fieldName","thisWays","outer","ows","iws","outerRings","innerRings","compositPolyons","constructPolygonGeometry","inner","ws","constructStringGeometry","xmlparser","conditioned","evt","parseEvent","exec","exp","opts","queryParent","progressive","parentMap","WeakMap","evtListeners","xml","parent","nodeRegEx","nodeMatch","$tag","fullTag","attrText","closed","endsWith","startsWith","attRegEx1","attRegEx2","attMatch","hasAttrs","emit","innerRegEx","lastIndex","innerMatch","innerNodes","$innerNodes","$innerText","getParent","addListener","func","funcs","condition","cond","body","genConditionFunc","removeListener","on","off","XmlParser","require$$2","lib","osm","completeFeature","renderTagged","excludeWay","allFeatures","wayOpt","suppressWay","parseOpts","detectFormat","refElements","featureArray","minlon","minlat","maxlon","maxlat","members","analyzeFeaturesFromJson","xmlParser","nd","ind","analyzeFeaturesFromXml","objects"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]}
--------------------------------------------------------------------------------
/dist/src/converter.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { FeatureCollection, GeoJsonProperties } from 'geojson';
3 | import * as csv2geojson from 'csv2geojson';
4 | export declare const supportedFormats: readonly ["topojson", "osm", "kml", "gpx", "tcx", "csv", "tsv", "polyline"];
5 | export type supportedFormatsType = typeof supportedFormats[number];
6 | export type supportedOptions = {
7 | csvOptions?: csv2geojson.csvOptions;
8 | polylineOptions?: {
9 | precision?: number;
10 | properties?: GeoJsonProperties;
11 | type?: 'point' | 'line' | 'polygon';
12 | };
13 | };
14 | export declare class Converter {
15 | _conversionFn: () => Promise;
16 | _rawData: string;
17 | _format: supportedFormatsType;
18 | _options: supportedOptions;
19 | constructor(format: supportedFormatsType, data: string, options?: supportedOptions);
20 | /**
21 | * Creates a blank GeoJSON feature collection.
22 | * @returns A new GeoJSON feature collection with no features.
23 | */
24 | blankGeoJSON: () => FeatureCollection;
25 | convert(): Promise;
26 | /**
27 | * Load the XML data as GeoJSON
28 | * @returns A promise resolving to a GeoJSON FeatureCollection
29 | */
30 | loadXml(): Promise;
31 | /**
32 | * Loads and parses CSV data into a GeoJSON FeatureCollection.
33 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
34 | */
35 | loadCsv(): Promise;
36 | /**
37 | * Loads TopoJSON data and converts it into a GeoJSON FeatureCollection
38 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
39 | */
40 | loadTopoJson(): Promise;
41 | /**
42 | * Loads OSM data and converts it into a GeoJSON FeatureCollection
43 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
44 | */
45 | loadOsm(): Promise;
46 | /**
47 | * Loads and parses Polyline data into a GeoJSON FeatureCollection.
48 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
49 | */
50 | loadPolyline(): Promise;
51 | }
52 | //# sourceMappingURL=converter.d.ts.map
--------------------------------------------------------------------------------
/dist/src/converter.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/converter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAwB,MAAM,SAAS,CAAC;AAErF,OAAO,KAAK,WAAW,MAAM,aAAa,CAAC;AAM3C,eAAO,MAAM,gBAAgB,6EAA8E,CAAC;AAC5G,MAAM,MAAM,oBAAoB,GAAG,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GAAG;IAC3B,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC;IACpC,eAAe,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,iBAAiB,CAAC;QAC/B,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KACtC,CAAA;CACJ,CAAC;AAEF,qBAAa,SAAS;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE,gBAAgB,CAAC;gBAEf,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAmBtF;;;OAGG;IACH,YAAY,EAAE,MAAM,iBAAiB,CAGlC;IAEG,OAAO;IAQb;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAS3C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA0B3C;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA4BhD;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI3C;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,iBAAiB,CAAC;CA+CnD"}
--------------------------------------------------------------------------------
/dist/src/index.d.ts:
--------------------------------------------------------------------------------
1 | import { RequestParameters, default as MapLibrary, GetResourceResponse } from 'maplibre-gl';
2 | import { FeatureCollection } from 'geojson';
3 | import { supportedFormatsType, supportedOptions } from './converter';
4 | /**
5 | * The processData function accepts a URL, prefix, and an optional controller
6 | * and tries to read and convert the data
7 | * @param url - The URL of the resource.
8 | * @param prefix - The prefix used to process the data
9 | * @param controller - optional controller that can be used to cancel a request
10 | * @returns A geojson FeatureCollection (or undefined)
11 | */
12 | export declare function processData(url: string, prefix: supportedFormatsType, controller?: AbortController): Promise;
13 | /**
14 | * Selects the appropriate Vector Text Protocol version based on the type of controller provided.
15 | *
16 | * @param requestParameters - The parameters for the request including the URL.
17 | * @param controller - Either an AbortController or a callback function.
18 | * @returns Either a Promise for V4 or an object with a cancel method for V3.
19 | */
20 | export declare const VectorTextProtocol: (requestParameters: RequestParameters, controller: AbortController | ((e: string | null, d?: FeatureCollection) => void)) => Promise> | {
21 | cancel: () => void;
22 | };
23 | /**
24 | * Add options to a URL for the Vector Text Protocol.
25 | *
26 | * @param url - The URL to add options to.
27 | * @param options - The options to add to the URL.
28 | * @returns A string with the updated URL.
29 | */
30 | export declare const addOptions: (url: string | URL, options: supportedOptions) => string | URL;
31 | /**
32 | * Add the vector text protocol to a map library for each supported format.
33 | * @param mapLibrary - The MapLibrary object to add the protocols to.
34 | */
35 | export declare const addProtocols: (mapLibrary: typeof MapLibrary) => void;
36 | export declare const vectorFormats: readonly ["topojson", "osm", "kml", "gpx", "tcx", "csv", "tsv", "polyline"];
37 | export { supportedFormatsType } from './converter';
38 | //# sourceMappingURL=index.d.ts.map
--------------------------------------------------------------------------------
/dist/src/index.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iBAAiB,EACjB,OAAO,IAAI,UAAU,EACrB,mBAAmB,EACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAa,oBAAoB,EAAoB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAuBlG;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAuCjJ;AAsED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,sBACR,iBAAiB,cACxB,eAAe,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAC,KAClF,QAAQ,oBAAoB,iBAAiB,GAAG,SAAS,CAAC,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,IAAI,CAAA;CAMpF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAS,MAAM,GAAG,GAAG,WAAW,gBAAgB,iBActE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,eAAgB,iBAAiB,SAIzD,CAAC;AAEF,eAAO,MAAM,aAAa,6EAAmB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
--------------------------------------------------------------------------------
/dist/src/worker/actor.d.ts:
--------------------------------------------------------------------------------
1 | import type { SubClasses } from './worker';
2 | export declare class Actor {
3 | subClass: any;
4 | worker: Worker;
5 | handlers: Map void;
7 | 'reject': (value: Error) => void;
8 | }>;
9 | initId: string;
10 | _: Record | undefined;
11 | /**
12 | * Creates a new instance of the `Actor` class.
13 | * @param subClass - The name of the subclass.
14 | * @param args - The arguments to pass to the subclass constructor.
15 | */
16 | constructor(subClass: SubClasses, args: Array);
17 | /**
18 | * Waits for the initialization of the object to complete and returns the resulting object.
19 | * @returns A promise that resolves with the initialized object.
20 | */
21 | onLoad(): Promise;
22 | /**
23 | * returns a Promise for a given command that will be executed in a worker.
24 | * @param command - The command to execute.
25 | * @returns A Promise that resolves with the result of the command execution or rejects with an error.
26 | */
27 | exec(command: string): (...args: any[]) => Promise;
28 | /**
29 | * Returns a Promise that resolves with the result of a command sent to a Web Worker.
30 | * @param command - The command to send to the Web Worker.
31 | * @returns A Promise that resolves with the result of the command.
32 | */
33 | get(command: string): Promise;
34 | }
35 | //# sourceMappingURL=actor.d.ts.map
--------------------------------------------------------------------------------
/dist/src/worker/actor.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../../src/worker/actor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,UAAU,CAAC;AAExD,qBAAa,KAAK;IACd,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAClB,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;QAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KACnC,CAAC,CAAC;IACH,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;IAExC;;;;OAIG;gBACS,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;IAiDlD;;;OAGG;IACH,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;IAatB;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAuBvD;;;;OAIG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAiBrC"}
--------------------------------------------------------------------------------
/dist/src/worker/worker.d.ts:
--------------------------------------------------------------------------------
1 | export interface MessageData {
2 | 'type': 'response' | 'error' | 'init' | 'exec' | 'get' | 'init_response';
3 | 'id': string;
4 | 'message': Array;
5 | 'error'?: Error;
6 | 'command': string;
7 | }
8 | declare const subClasses: readonly ["Converter"];
9 | export type SubClasses = typeof subClasses[number];
10 | export {};
11 | //# sourceMappingURL=worker.d.ts.map
--------------------------------------------------------------------------------
/dist/src/worker/worker.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/worker/worker.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,eAAe,CAAC;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,QAAA,MAAM,UAAU,wBAAyB,CAAC;AAC1C,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC"}
--------------------------------------------------------------------------------
/examples/data/beach_ave.gpx:
--------------------------------------------------------------------------------
1 |
2 | Filtered OSM data converted to GPX by overpass turboBeach Avenuealt_name=County Highway 604
3 | highway=tertiary
4 | lanes=2
5 | lit=yes
6 | name=Beach Avenue
7 | oneway=no
8 | ref=CR 604
9 | source:name=survey
10 | surface=asphalt
11 | tiger:cfcc=A41
12 | tiger:county=Cape May, NJ
13 | tiger:name_base=Beach
14 | tiger:name_base_1=County Highway 604
15 | tiger:name_type=Dr
16 | tiger:zip_left=08204
17 | tiger:zip_right=08204Beach Avenuealt_name=County Highway 604
18 | highway=tertiary
19 | lanes=2
20 | maxspeed=25 mph
21 | name=Beach Avenue
22 | ref=CR 604
23 | surface=asphalt
24 | survey:date=2015-10-17
25 | tiger:cfcc=A41
26 | tiger:county=Cape May, NJ
27 | tiger:name_base=Beach
28 | tiger:name_base_1=County Highway 604
29 | tiger:name_type=Dr
30 | tiger:zip_left=08204
31 | tiger:zip_right=08204Beach Avenuealt_name=County Highway 604
32 | highway=tertiary
33 | lanes=2
34 | maxspeed=25 mph
35 | name=Beach Avenue
36 | ref=CR 604
37 | surface=asphalt
38 | tiger:cfcc=A41
39 | tiger:county=Cape May, NJ
40 | tiger:name_base=Beach
41 | tiger:name_base_1=County Highway 604
42 | tiger:name_type=Dr
43 | tiger:reviewed=no
44 | tiger:zip_left=08204
45 | tiger:zip_right=08204Beach Avenuealt_name=County Highway 604
46 | highway=tertiary
47 | lanes=3
48 | lanes:backward=2
49 | lanes:forward=1
50 | lit=yes
51 | name=Beach Avenue
52 | oneway=no
53 | ref=CR 604
54 | source:name=survey
55 | surface=asphalt
56 | tiger:cfcc=A41
57 | tiger:county=Cape May, NJ
58 | tiger:name_base=Beach
59 | tiger:name_base_1=County Highway 604
60 | tiger:name_type=Dr
61 | tiger:zip_left=08204
62 | tiger:zip_right=08204
63 | turn:lanes:backward=|rightBeach Avenuealt_name=County Highway 604
64 | highway=tertiary
65 | lanes=3
66 | lanes:backward=1
67 | lanes:forward=2
68 | lit=yes
69 | name=Beach Avenue
70 | oneway=no
71 | ref=CR 604
72 | source:name=survey
73 | surface=asphalt
74 | tiger:cfcc=A41
75 | tiger:county=Cape May, NJ
76 | tiger:name_base=Beach
77 | tiger:name_base_1=County Highway 604
78 | tiger:name_type=Dr
79 | tiger:zip_left=08204
80 | tiger:zip_right=08204
81 | turn:lanes:forward=left|Beach Avenuealt_name=County Highway 604
82 | highway=tertiary
83 | lanes=3
84 | lanes:backward=1
85 | lanes:forward=2
86 | name=Beach Avenue
87 | oneway=no
88 | ref=CR 604
89 | surface=asphalt
90 | survey:date=2015-10-17
91 | tiger:cfcc=A41
92 | tiger:county=Cape May, NJ
93 | tiger:name_base=Beach
94 | tiger:name_base_1=County Highway 604
95 | tiger:name_type=Dr
96 | tiger:zip_left=08204
97 | tiger:zip_right=08204
98 | turn:lanes:forward=left|Beach Avenuealt_name=County Highway 604
99 | highway=tertiary
100 | lanes=2
101 | lit=yes
102 | name=Beach Avenue
103 | oneway=no
104 | ref=CR 604
105 | source:name=survey
106 | surface=asphalt
107 | tiger:cfcc=A41
108 | tiger:county=Cape May, NJ
109 | tiger:name_base=Beach
110 | tiger:name_base_1=County Highway 604
111 | tiger:name_type=Dr
112 | tiger:zip_left=08204
113 | tiger:zip_right=08204Beach Avenuealt_name=County Highway 604
114 | highway=tertiary
115 | lanes=2
116 | lit=yes
117 | name=Beach Avenue
118 | oneway=no
119 | ref=CR 604
120 | source:name=survey
121 | surface=asphalt
122 | tiger:cfcc=A41
123 | tiger:county=Cape May, NJ
124 | tiger:name_base=Beach
125 | tiger:name_base_1=County Highway 604
126 | tiger:name_type=Dr
127 | tiger:zip_left=08204
128 | tiger:zip_right=08204Beach Avenuealt_name=County Highway 604
129 | highway=tertiary
130 | lanes=2
131 | name=Beach Avenue
132 | oneway=no
133 | ref=CR 604
134 | source:name=survey
135 | surface=asphalt
136 | tiger:cfcc=A41
137 | tiger:county=Cape May, NJ
138 | tiger:name_base=Beach
139 | tiger:name_base_1=County Highway 604
140 | tiger:name_type=Dr
141 | tiger:zip_left=08204
142 | tiger:zip_right=08204
--------------------------------------------------------------------------------
/examples/data/cape_may_restaurants.csv:
--------------------------------------------------------------------------------
1 | Lon,Lat,node_id,amenity,name,cuisine
2 | -74.9240905,38.9314775,node/2668042329,restaurant,The Blue Pig Tavern,
3 | -74.9235904,38.9321656,node/4269020158,restaurant,Tisha's Fine Dining,
4 | -74.9229949,38.9304472,node/4269020175,restaurant,George's Place,
5 | -74.9222267,38.9304928,node/4269020176,restaurant,Y B,
6 | -74.921045,38.9305072,node/4269020185,restaurant,Cabanas Beach Bar & Grill,
7 | -74.9212548,38.9305288,node/4269020210,restaurant,Blue Moon Pizza,
8 | -74.9286053,38.9303859,node/4269040153,restaurant,Rusty Nail,
9 | -74.9242976,38.9321708,node/4269043553,restaurant,That's Amore,
10 | -74.9235954,38.9325113,node/4269043554,restaurant,Louisa's Cafe,
11 | -74.9241207,38.9319708,node/4269043556,restaurant,Cape May Pizza,
12 | -74.9224554,38.9333619,node/4269043577,restaurant,Jojo Pizza,
13 | -74.9194566,38.9308589,node/4269119887,restaurant,Aleathea's,
14 | -74.9212412,38.9341178,node/4269120225,restaurant,Asian Legends,
15 | -74.9211607,38.9340302,node/4269120226,restaurant,Mario's Pizza & Italian,
16 | -74.9168336,38.9309033,node/4269120596,restaurant,Union Park Dining Room,
17 | -74.9102599,38.9320212,node/4269169574,restaurant,Sea Salt,
18 | -74.908346,38.9328039,node/4269169583,restaurant,Hemingway's,
19 | -74.9098421,38.9466451,node/4269173977,restaurant,Big Wave Burritos,
20 | -74.9087764,38.9466129,node/4269173982,restaurant,Cappy's Seaside Pizza & Steaks,
21 | -74.9112036,38.9316934,node/4269812060,restaurant,Harry's Ocean Bar & Grille,
22 | -74.9168154,38.930357,node/4269812061,restaurant,Manga Beachfront Pizza,pizza
23 | -74.9165975,38.9304109,node/4269812062,restaurant,Surfside Delites,
24 | -74.9170268,38.9301732,node/4987008532,restaurant,McGlades On The Pier,
25 | -74.9182861,38.9310235,node/4987008533,restaurant,Louie's Pizza,pizza
26 | -74.9180225,38.9302381,node/5598722999,restaurant,Mermaids restaurant,
--------------------------------------------------------------------------------
/examples/index.css:
--------------------------------------------------------------------------------
1 | /* From here https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/ */
2 |
3 | body { margin: 0; padding: 0; }
4 |
5 | #map { position: absolute; top: 0; bottom: 0; width: 100%; }
6 |
7 | #menu {
8 | background: #fff;
9 | position: absolute;
10 | z-index: 1;
11 | top: 10px;
12 | right: 10px;
13 | border-radius: 3px;
14 | width: 180px;
15 | border: 1px solid rgba(0, 0, 0, 0.4);
16 | font-family: 'Open Sans', sans-serif;
17 | }
18 |
19 | #menu a {
20 | font-size: 13px;
21 | color: #404040;
22 | display: block;
23 | margin: 0;
24 | padding: 0;
25 | padding: 10px;
26 | text-decoration: none;
27 | border-bottom: 1px solid rgba(0, 0, 0, 0.25);
28 | text-align: center;
29 | }
30 |
31 | #menu a:last-child {
32 | border: none;
33 | }
34 |
35 | #menu a:hover {
36 | background-color: #f8f8f8;
37 | color: #404040;
38 | }
39 |
40 | #menu a.active {
41 | background-color: #3887be;
42 | color: #ffffff;
43 | }
44 |
45 | #menu a.active:hover {
46 | background: #3074a4;
47 | }
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Display a map with an XML, CSV, or TopoJSON Overlay
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/index.js:
--------------------------------------------------------------------------------
1 | import { addProtocols } from "../dist/maplibre-gl-vector-text-protocol.esm.js";
2 | import { default as layerSelector } from "./layerSelector.js";
3 |
4 | const map = new maplibregl.Map({
5 | container: 'map', // container id
6 | style: 'https://demotiles.maplibre.org/style.json', // style URL
7 | center: [-74.8306, 39.06], // starting position [lng, lat]
8 | zoom: 9 // starting zoom
9 | });
10 |
11 | // Add the sources for all the types
12 | addProtocols(maplibregl);
13 |
14 | // Use a prefix so the layer selector can find our layers
15 | const layerIdPrefix = 'example-';
16 |
17 | map.on('load', () => {
18 |
19 | // Add few sources and layers to show how each converter works
20 |
21 | // KML
22 | const kmlSourceName = 'cape-may-incorporated-place (kml)';
23 | const kmlLink = 'kml://./data/cape_may_incorporated_places.kml';
24 | map.addSource(kmlSourceName, {
25 | 'type': 'geojson',
26 | 'data': kmlLink,
27 | });
28 | map.addLayer({
29 | 'id': layerIdPrefix + kmlSourceName,
30 | 'type': 'fill',
31 | 'source': kmlSourceName,
32 | 'minzoom': 0,
33 | 'maxzoom': 20,
34 | 'paint': {
35 | 'fill-opacity': 0.5,
36 | 'fill-color': 'green',
37 | 'fill-outline-color': 'gray'
38 | }
39 | });
40 |
41 | // TOPOJSON
42 | const topojsonSourceName = 'us-congress-113 (topojson)';
43 | const topojsonLink = 'topojson://https://gist.githubusercontent.com/mbostock/4090846/raw/07e73f3c2d21558489604a0bc434b3a5cf41a867/us-congress-113.json'
44 | map.addSource(topojsonSourceName, {
45 | 'type': 'geojson',
46 | 'data': topojsonLink,
47 | });
48 | map.addLayer({
49 | 'id': layerIdPrefix + topojsonSourceName,
50 | 'type': 'fill',
51 | 'source': topojsonSourceName,
52 | 'minzoom': 0,
53 | 'maxzoom': 20,
54 | 'paint': {
55 | 'fill-opacity': 0.25,
56 | 'fill-color': 'yellow',
57 | 'fill-outline-color': 'gray'
58 | }
59 | });
60 |
61 | // OSM polygon (json)
62 | const osmSourceName = 'marsh (osm polygon json)';
63 | const osmLink = 'osm://https://www.openstreetmap.org/api/0.6/relation/5544086/full.json'
64 | map.addSource(osmSourceName, {
65 | 'type': 'geojson',
66 | 'data': osmLink,
67 | });
68 | map.addLayer({
69 | 'id': layerIdPrefix + osmSourceName,
70 | 'type': 'fill',
71 | 'source': osmSourceName,
72 | 'minzoom': 0,
73 | 'maxzoom': 20,
74 | 'paint': {
75 | 'fill-opacity': 0.25,
76 | 'fill-color': 'blue',
77 | 'fill-outline-color': 'gray'
78 | }
79 | });
80 |
81 | // OSM line (xml)
82 | const osmLineSourceName = 'madison ave (osm line xml)';
83 | const osmLineLink = 'osm://https://www.openstreetmap.org/api/0.6/relation/968291/full'
84 | map.addSource(osmLineSourceName, {
85 | 'type': 'geojson',
86 | 'data': osmLineLink,
87 | });
88 | map.addLayer({
89 | 'id': layerIdPrefix + osmLineSourceName,
90 | 'type': 'line',
91 | 'source': osmLineSourceName,
92 | 'minzoom': 0,
93 | 'maxzoom': 20,
94 | 'paint': {
95 | 'line-opacity': 0.4,
96 | 'line-color': 'blue',
97 | }
98 | });
99 |
100 | // CSV
101 | const csvSourceName = 'restaurants (csv)';
102 | const csvLink = 'csv://./data/cape_may_restaurants.csv';
103 | map.addSource(csvSourceName, {
104 | 'type': 'geojson',
105 | 'data': csvLink,
106 | });
107 | map.addLayer({
108 | 'id': layerIdPrefix + csvSourceName,
109 | 'type': 'circle',
110 | 'source': csvSourceName,
111 | 'minzoom': 0,
112 | 'maxzoom': 20,
113 | 'paint': {
114 | 'circle-color': 'orange',
115 | 'circle-radius': 5,
116 | 'circle-stroke-color': 'black'
117 | }
118 | });
119 |
120 | // GPX
121 | const gpxSourceName = 'beach ave (gpx)';
122 | const gpxLink = 'gpx://./data/beach_ave.gpx';
123 | map.addSource(gpxSourceName, {
124 | 'type': 'geojson',
125 | 'data': gpxLink,
126 | });
127 | map.addLayer({
128 | 'id': layerIdPrefix + gpxSourceName,
129 | 'type': 'line',
130 | 'source': gpxSourceName,
131 | 'minzoom': 0,
132 | 'maxzoom': 20,
133 | 'paint': {
134 | 'line-color': 'red',
135 | 'line-width': 5
136 | }
137 | });
138 |
139 |
140 | // Polyline
141 | const polylineSourceName = 'pittsburg ave (polyline)';
142 | const polylineProperties = {
143 | "@id": "way/11605426",
144 | "alt_name": "County Highway 622",
145 | "cycleway": "lane",
146 | "highway": "tertiary",
147 | "name": "Pittsburg Avenue",
148 | };
149 | const polylinePath = 'ymslF`cdhMSJcBv@}@`@QHcDzA{CpA}CvA{CtAcAd@KDo@ZyAp@GByCtAOFgCjAGBaBt@u@ZOHyCrAKFqCnAGB{CvAOFkClAgAd@OHKJKPIN';
150 | // Convert the string into a Blob
151 | const polylineBlob = new Blob([polylinePath], { type: 'text/plain' });
152 |
153 | // Create a data URL from the Blob
154 | const polylineURL = 'polyline://' + URL.createObjectURL(polylineBlob);
155 | console.log('s1', polylineBlob, polylineURL);
156 | /*addOptions(polylineURL, {
157 | polylineOptions: {
158 | properties: polylineProperties
159 | }
160 | });*/
161 |
162 | map.addSource(polylineSourceName, {
163 | 'type': 'geojson',
164 | 'data': polylineURL,
165 | });
166 | map.addLayer({
167 | 'id': layerIdPrefix + polylineSourceName,
168 | 'type': 'line',
169 | 'source': polylineSourceName,
170 | 'minzoom': 0,
171 | 'maxzoom': 20,
172 | 'paint': {
173 | 'line-color': 'purple',
174 | 'line-width': 5
175 | }
176 | });
177 | });
178 |
179 | // After the last frame rendered before the map enters an "idle" state,
180 | // add the toggle fields / layer selector
181 | map.on('idle', () => {
182 | // Add the layer selector
183 | layerSelector(map, layerIdPrefix);
184 | });
185 |
--------------------------------------------------------------------------------
/examples/indexv3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Display a map with an XML, CSV, or TopoJSON Overlay
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/layerSelector.js:
--------------------------------------------------------------------------------
1 | // Adapted from: https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/
2 |
3 | export default function layerSelector (map, prefix) {
4 | // Enumerate ids of the layers
5 | const prefixRegexp = new RegExp(`^${prefix}`);
6 | const toggleableLayerIds = Object.keys(map.style._layers)
7 | .filter(name => name.match(prefixRegexp));
8 |
9 | toggleableLayerIds.forEach(layerId => {
10 | // Make the name nicer
11 | const layerName = layerId.replace(prefixRegexp, '');
12 |
13 | if (!document.getElementById(layerId)) {
14 |
15 | // Create a link.
16 | const link = document.createElement('a');
17 | link.id = layerId;
18 | link.href = '#';
19 | link.textContent = layerName,
20 | link.className = 'active';
21 |
22 | // Show or hide layer when the toggle is clicked.
23 | link.onclick = function (e) {
24 | const clickedLayer = this.id;
25 | e.preventDefault();
26 | e.stopPropagation();
27 |
28 | const visibility = map.getLayoutProperty(
29 | clickedLayer,
30 | 'visibility'
31 | );
32 |
33 | // Toggle layer visibility by changing the layout object's visibility property.
34 | if (visibility !== 'none') {
35 | map.setLayoutProperty(clickedLayer, 'visibility', 'none');
36 | this.className = '';
37 | } else {
38 | this.className = 'active';
39 | map.setLayoutProperty(
40 | clickedLayer,
41 | 'visibility',
42 | 'visible'
43 | );
44 | }
45 | };
46 |
47 | const layers = document.getElementById('menu');
48 | layers.appendChild(link);
49 | }
50 | });
51 | };
--------------------------------------------------------------------------------
/examples/umd.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Display a map with an XML, CSV, or TopoJSON Overlay
7 |
8 |
9 |
10 |
11 |
12 | ß
13 |
14 |
15 |
16 |
48 |
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "maplibre-gl-vector-text-protocol",
3 | "version": "0.0.5",
4 | "description": "Allows various text based vector formats to be used with maplibre gl js",
5 | "keywords": [
6 | "maplibre",
7 | "topojson",
8 | "osm",
9 | "kml",
10 | "gpx",
11 | "tcx",
12 | "csv",
13 | "tsv",
14 | "convert"
15 | ],
16 | "author": "James McAndrew ",
17 | "license": "MIT",
18 | "main": "dist/maplibre-gl-vector-text-protocol.js",
19 | "module": "dist/maplibre-gl-vector-text-protocol.esm.js",
20 | "browser": "dist/maplibre-gl-vector-text-protocol.min.js",
21 | "types": "dist/src/index.d.ts",
22 | "files": [
23 | "dist"
24 | ],
25 | "scripts": {
26 | "clean": "rm -rf ./dist",
27 | "build-dev": "NODE_ENV=development npm run build",
28 | "watch-dev": "NODE_ENV=development npm run watch",
29 | "build-prod": "NODE_ENV=production npm run build",
30 | "build": "npm run clean && rollup -c rollup.config.mjs",
31 | "watch": "npm run clean && rollup -c rollup.config.mjs --watch",
32 | "test": "echo 'no tests available'"
33 | },
34 | "devDependencies": {
35 | "@rollup/plugin-commonjs": "^25.0.7",
36 | "@rollup/plugin-json": "^6.1.0",
37 | "@rollup/plugin-node-resolve": "^15.2.3",
38 | "@rollup/plugin-terser": "^0.4.4",
39 | "@types/geojson": "^7946.0.14",
40 | "@types/mapbox__polyline": "^1.0.5",
41 | "@types/topojson": "^3.2.6",
42 | "maplibre-gl": "^4.1.3",
43 | "rollup": "^4.17.0",
44 | "rollup-plugin-sourcemaps": "^0.6.3",
45 | "rollup-plugin-typescript2": "^0.36.0",
46 | "rollup-plugin-web-worker-loader": "^1.6.1",
47 | "typescript": "^5.4.5"
48 | },
49 | "overrides": {
50 | "rollup-plugin-web-worker-loader": {
51 | "rollup": "^4.0.2"
52 | }
53 | },
54 | "dependencies": {
55 | "@mapbox/polyline": "^1.2.1",
56 | "@tmcw/togeojson": "5.8.1",
57 | "csv2geojson": "^5.1.2",
58 | "osm2geojson-lite": "^0.9.4",
59 | "topojson-client": "^3.1.0"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | // rollup.config.js
2 |
3 | import merge from 'deepmerge';
4 | import terser from "@rollup/plugin-terser";
5 | import typescript from 'rollup-plugin-typescript2';
6 | import { nodeResolve } from '@rollup/plugin-node-resolve';
7 | import commonjs from '@rollup/plugin-commonjs';
8 | import json from '@rollup/plugin-json';
9 | import webWorkerLoader from 'rollup-plugin-web-worker-loader';
10 |
11 | import { readFileSync, readdirSync, writeFileSync } from 'fs';
12 |
13 | const { main, module, browser, devDependencies } = JSON.parse(readFileSync('package.json'));
14 | const env = process.env.NODE_ENV || 'development';
15 |
16 | const updateMaplibreVersion = () => {
17 | const updateVersion = (fileContent) => {
18 | const maplibreVersion = devDependencies['maplibre-gl'].replace(/[\^~]/g, '');
19 | const regex = /https:\/\/unpkg\.com\/maplibre-gl@[^]?\d+\.\d+\.\d+\/dist\/maplibre-gl/g;
20 | const newVersionString = `https://unpkg.com/maplibre-gl@${maplibreVersion}/dist/maplibre-gl`;
21 | return fileContent.replace(regex, newVersionString);
22 | };
23 | readdirSync('./examples').map(item => {
24 | if (item.match(/.+?\.html/) && item !== 'indexv3.html') {
25 | const fileContent = readFileSync('./examples/' + item, { encoding: 'utf8', flag: 'r' });
26 | const newFileContent = updateVersion(fileContent);
27 | writeFileSync('./examples/' + item, newFileContent);
28 | }
29 | });
30 | };
31 | updateMaplibreVersion();
32 |
33 | const baseConfig = {
34 | input: './src/index.ts',
35 | output: {
36 | name: 'VectorTextProtocol'
37 | },
38 | treeshake: env === 'production',
39 | plugins: [webWorkerLoader({
40 | 'extensions': ['.ts']
41 | }), typescript(), nodeResolve(), commonjs(), json()]
42 | };
43 |
44 | const configs = [{
45 | environments: ['development', 'production'],
46 | output: {
47 | format: 'umd',
48 | file: main
49 | }
50 | }, {
51 | environments: ['production'],
52 | output: {
53 | format: 'umd',
54 | file: browser,
55 | sourcemap: true
56 | },
57 | plugins: [terser()]
58 | }, {
59 | environments: ['production'],
60 | output: {
61 | format: 'esm',
62 | file: module
63 | }
64 | }]
65 | .filter(config => config.environments === undefined || config.environments.indexOf(env) > -1)
66 | .map(config => { delete config.environments; return config; })
67 | .map(config => merge(baseConfig, config));
68 |
69 | console.log(configs);
70 |
71 | export default configs;
72 |
--------------------------------------------------------------------------------
/src/converter.ts:
--------------------------------------------------------------------------------
1 | import { FeatureCollection, GeoJsonProperties, Geometry, LineString } from 'geojson';
2 | import { Topology } from 'topojson-specification'
3 | import * as csv2geojson from 'csv2geojson';
4 | import { feature as topojsonFeature } from 'topojson-client';
5 | import * as toGeoJson from '@tmcw/togeojson';
6 | import { toGeoJSON as polylineToGeoJSON } from '@mapbox/polyline';
7 | import osm2geojson from 'osm2geojson-lite';
8 |
9 | export const supportedFormats = ['topojson', 'osm', 'kml', 'gpx', 'tcx', 'csv', 'tsv', 'polyline'] as const;
10 | export type supportedFormatsType = typeof supportedFormats[number];
11 |
12 | export type supportedOptions = {
13 | csvOptions?: csv2geojson.csvOptions,
14 | polylineOptions?: {
15 | precision?: number,
16 | properties?: GeoJsonProperties,
17 | type?: 'point' | 'line' | 'polygon'
18 | }
19 | };
20 |
21 | export class Converter {
22 | _conversionFn: () => Promise;
23 | _rawData: string;
24 | _format: supportedFormatsType;
25 | _options: supportedOptions;
26 |
27 | constructor(format: supportedFormatsType, data: string, options: supportedOptions = {}) {
28 | this._rawData = data;
29 | this._format = format;
30 | this._options = options;
31 |
32 | const converters: { [key: string]: () => Promise } = {
33 | 'topojson': this.loadTopoJson,
34 | 'osm': this.loadOsm,
35 | 'kml': this.loadXml,
36 | 'gpx': this.loadXml,
37 | 'tcx': this.loadXml,
38 | 'csv': this.loadCsv,
39 | 'tsv': this.loadCsv,
40 | 'polyline': this.loadPolyline
41 | };
42 | this._conversionFn = converters[format];
43 |
44 | }
45 |
46 | /**
47 | * Creates a blank GeoJSON feature collection.
48 | * @returns A new GeoJSON feature collection with no features.
49 | */
50 | blankGeoJSON: () => FeatureCollection = () => ({
51 | type: 'FeatureCollection',
52 | features: [],
53 | });
54 |
55 | async convert() {
56 | if (!this._conversionFn) {
57 | return new Promise((_, rej) => rej(`No converter exists for ${this._format}`));
58 | } else {
59 | return this._conversionFn();
60 | }
61 | }
62 |
63 | /**
64 | * Load the XML data as GeoJSON
65 | * @returns A promise resolving to a GeoJSON FeatureCollection
66 | */
67 | async loadXml(): Promise {
68 | // Use the appropriate parser based on the format
69 | const geojson = (toGeoJson as any)[this._format](
70 | new DOMParser().parseFromString(this._rawData, "text/xml")
71 | );
72 |
73 | return geojson;
74 | }
75 |
76 | /**
77 | * Loads and parses CSV data into a GeoJSON FeatureCollection.
78 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
79 | */
80 | async loadCsv(): Promise {
81 | // Define options for the csv2geojson library
82 | let options: csv2geojson.csvOptions = this._options.csvOptions || {}; // TODO allow CSV options
83 |
84 | if (this._format === 'tsv') {
85 | options.delimiter = '\t';
86 | }
87 |
88 | // Use the csv2geojson library to convert the CSV to GeoJSON
89 | const geojson = await new Promise((resolve, reject) => {
90 | csv2geojson.csv2geojson(
91 | this._rawData,
92 | options,
93 | (err: string, data: FeatureCollection) => {
94 | if (err) {
95 | reject(err);
96 | } else {
97 | resolve(data);
98 | }
99 | }
100 | );
101 | });
102 |
103 | return geojson;
104 | }
105 |
106 | /**
107 | * Loads TopoJSON data and converts it into a GeoJSON FeatureCollection
108 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
109 | */
110 | async loadTopoJson(): Promise {
111 |
112 | type TopoJson = {
113 | type?: 'Topology';
114 | objects?: { [key: string]: Topology };
115 | arcs?: any;
116 | };
117 | let topoJsonData: TopoJson = {};
118 |
119 | try {
120 | topoJsonData = JSON.parse(this._rawData);
121 | } catch (e) {
122 | throw "Invalid TopoJson";
123 | }
124 |
125 | // Convert the data
126 | let result: FeatureCollection = this.blankGeoJSON();
127 | if (topoJsonData.type === "Topology" && topoJsonData.objects !== undefined) {
128 | result = {
129 | type: "FeatureCollection",
130 | features: result.features = Object.keys(topoJsonData.objects).map(key =>
131 | topojsonFeature(topoJsonData as any, key)
132 | ).reduce((a: any[], v) => [...a, ...(v as any).features], [])
133 | };
134 | }
135 | return result;
136 | };
137 |
138 | /**
139 | * Loads OSM data and converts it into a GeoJSON FeatureCollection
140 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
141 | */
142 | async loadOsm(): Promise {
143 | return osm2geojson(this._rawData) as FeatureCollection;
144 | }
145 |
146 | /**
147 | * Loads and parses Polyline data into a GeoJSON FeatureCollection.
148 | * @returns A Promise that resolves with the GeoJSON FeatureCollection.
149 | */
150 | async loadPolyline(): Promise {
151 | let options = this._options.polylineOptions || {};
152 |
153 | // Use the @mapbox/polyline library to convert the polyline to GeoJSON
154 | const geojson = await new Promise((resolve, reject) => {
155 | try {
156 | const lineString = polylineToGeoJSON(this._rawData, options.precision);
157 | let geometry: Geometry = lineString;
158 |
159 | if (options.type === 'point') {
160 | if (lineString.coordinates.length === 1) {
161 | // Make it a point
162 | geometry = {
163 | 'type': 'Point',
164 | 'coordinates': lineString.coordinates[0]
165 | }
166 | } else {
167 | console.warn('Cannot convert polyline to ' + options.type)
168 | }
169 | } else if (options.type === 'polygon') {
170 | if (
171 | lineString.coordinates[0][0] === lineString.coordinates[lineString.coordinates.length - 1][0] &&
172 | lineString.coordinates[0][1] === lineString.coordinates[lineString.coordinates.length - 1][1]) {
173 | // Make it a polygon
174 | geometry = {
175 | 'type': 'Polygon',
176 | 'coordinates': [lineString.coordinates]
177 | }
178 | } else {
179 | console.warn('Cannot convert polyline to ' + options.type)
180 | }
181 | }
182 | resolve({
183 | type: "FeatureCollection",
184 | features: [{
185 | "type": "Feature",
186 | "geometry": geometry,
187 | "properties": options.properties || {}
188 | }]
189 | });
190 | } catch (err) {
191 | reject(err)
192 | }
193 | });
194 |
195 | return geojson;
196 | }
197 | }
--------------------------------------------------------------------------------
/src/custom.d.ts:
--------------------------------------------------------------------------------
1 | declare module '@tmcw/togeojson' {
2 | export function kml(doc: Document): FeatureCollection;
3 | export function gpx(doc: Document): FeatureCollection;
4 | export function tcx(doc: Document): FeatureCollection;
5 | }
6 |
7 | declare module 'csv2geojson' {
8 | export interface csvOptions {
9 | 'latfield'?: string,
10 | 'lonfield'?: string,
11 | 'delimiter'?: string
12 | }
13 |
14 | export function csv2geojson(
15 | csvString: string,
16 | options: csvOptions,
17 | callback: (err: string, data: FeatureCollection) => void
18 | ): void
19 | }
20 |
21 | declare module 'web-worker:*' {
22 | const WorkerFactory: new () => Worker;
23 | export default WorkerFactory;
24 | }
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | RequestParameters,
3 | default as MapLibrary,
4 | GetResourceResponse
5 | } from 'maplibre-gl';
6 |
7 | import { FeatureCollection } from 'geojson';
8 | import { Converter, supportedFormatsType, supportedFormats, supportedOptions } from './converter';
9 | import { Actor } from './worker/actor';
10 |
11 | // Make sure we can support workers in the current browser / runtime
12 | const supportsWorkers = () => {
13 | let supported = false;
14 | try {
15 | supported = typeof (window.Worker) === 'function';
16 | } catch (e) {
17 | supported = false;
18 | }
19 | return supported;
20 | };
21 |
22 | // Safari changes https:// to http// for some reason, so this is broken in Safari and iPhone
23 | // So to fix this we add it back
24 | const needsUrlCheck = (new URL('test://http://example.com')).href !== 'test://http://example.com';
25 | const checkUrl = (url: string): string | undefined => {
26 | const safariFixRegex = new RegExp('^(https?)(\/\/)')
27 | const cleanUrl = url.replace(safariFixRegex, '$1:$2');
28 | return cleanUrl;
29 | }
30 |
31 | /**
32 | * The processData function accepts a URL, prefix, and an optional controller
33 | * and tries to read and convert the data
34 | * @param url - The URL of the resource.
35 | * @param prefix - The prefix used to process the data
36 | * @param controller - optional controller that can be used to cancel a request
37 | * @returns A geojson FeatureCollection (or undefined)
38 | */
39 | export async function processData(url: string, prefix: supportedFormatsType, controller?: AbortController): Promise {
40 | const response = await fetch(url, controller ? { signal: controller.signal } : undefined);
41 |
42 | let options = {};
43 |
44 | // Parse the URL
45 | const urlObject = new URL(url, window.location.href);
46 |
47 | if (urlObject.hash.length) {
48 | // Extract the hash (including the "#" symbol)
49 | const hash = urlObject.hash;
50 |
51 | // Remove the "#" symbol from the hash and decode it
52 | const decodedHash = decodeURIComponent(hash.slice(1)); // Remove the "#" symbol
53 |
54 | try {
55 | options = JSON.parse(decodedHash);
56 | } catch (e) {
57 | console.warn('Error parsing or reading URL:', e);
58 | }
59 | }
60 |
61 | if (response.status == 200) {
62 | const rawData = await response.text();
63 | let convertPromise;
64 | const usesDOM = (['kml', 'tcx', 'gpx'].includes(prefix));
65 | if (usesDOM || !supportsWorkers()) {
66 | // XML uses the DOM, which isn't available to web workers
67 | // It is possible to use xmldom to do this, but that increases the bundle size by 3x
68 | const converter = new Converter(prefix, rawData, options);
69 | convertPromise = converter.convert();
70 | } else {
71 | const converter = new Actor('Converter', [prefix, rawData, options]);
72 | convertPromise = converter.exec('convert')();
73 | }
74 | return await convertPromise;
75 | } else {
76 | throw (new Error(`Data fetch error: ${response.statusText}`));
77 | }
78 | };
79 |
80 | /**
81 | * Processes the URL and returns the prefix and cleaned URL.
82 | *
83 | * @param url - The URL to process.
84 | * @returns An object with the prefix and cleaned URL.
85 | */
86 | const processUrl = (url: string) => {
87 | const prefix = url.split('://')[0] as supportedFormatsType;
88 | const replacedUrl = url.replace(new RegExp(`^${prefix}://`), '');
89 |
90 | // Apply the Safari fix (if needed) to the URL
91 | const cleanUrl = needsUrlCheck ? checkUrl(replacedUrl) : replacedUrl;
92 | return { prefix, url: cleanUrl };
93 | }
94 | /**
95 | * Handles the Vector Text Protocol for version 4.
96 | *
97 | * @param requestParameters - The parameters for the request including the URL.
98 | * @param controller - An AbortController instance to manage the request lifecycle.
99 | * @returns A promise resolving to a GetResourceResponse containing a FeatureCollection or undefined.
100 | * @throws Will throw an error if the URL is invalid or if any other error occurs during data processing.
101 | */
102 | const VectorTextProtocolV4 = async (
103 | requestParameters: RequestParameters,
104 | controller: AbortController
105 | ): Promise> => {
106 | const { prefix, url } = processUrl(requestParameters.url);
107 |
108 | if (url) {
109 | try {
110 | // Process the data and return the response
111 | const data = await processData(url, prefix, controller);
112 | return { data };
113 | } catch (e) {
114 | // Catch and rethrow errors with additional context
115 | throw new Error((e as any) || 'Unknown Error');
116 | }
117 | } else {
118 | // Handle invalid URL case
119 | throw new Error('Invalid URL: ' + requestParameters.url);
120 | }
121 | };
122 |
123 | /**
124 | * Handles the Vector Text Protocol for version 3.
125 | *
126 | * @param requestParameters - The parameters for the request including the URL.
127 | * @param callback - A callback function to handle the response or error.
128 | * @returns An object with a cancel function to abort the request.
129 | */
130 | const VectorTextProtocolV3 = (
131 | requestParameters: RequestParameters,
132 | callback: (e: string | null, d?: FeatureCollection) => void
133 | ) => {
134 | const controller = new AbortController();
135 | const { prefix, url } = processUrl(requestParameters.url);
136 |
137 |
138 | if (url) {
139 | processData(url, prefix, controller)
140 | .then(data => callback(null, data))
141 | .catch(e => callback(e))
142 | }
143 |
144 | // Return an object with a cancel method to abort the request
145 | return { cancel: () => { controller.abort() } };
146 | };
147 |
148 | /**
149 | * Selects the appropriate Vector Text Protocol version based on the type of controller provided.
150 | *
151 | * @param requestParameters - The parameters for the request including the URL.
152 | * @param controller - Either an AbortController or a callback function.
153 | * @returns Either a Promise for V4 or an object with a cancel method for V3.
154 | */
155 | export const VectorTextProtocol = (
156 | requestParameters: RequestParameters,
157 | controller: AbortController | ((e: string | null, d?: FeatureCollection) => void)
158 | ): Promise> | { cancel: () => void } => {
159 | if (controller instanceof AbortController) {
160 | return VectorTextProtocolV4(requestParameters, controller);
161 | } else {
162 | return VectorTextProtocolV3(requestParameters, controller)
163 | }
164 | }
165 |
166 | /**
167 | * Add options to a URL for the Vector Text Protocol.
168 | *
169 | * @param url - The URL to add options to.
170 | * @param options - The options to add to the URL.
171 | * @returns A string with the updated URL.
172 | */
173 | export const addOptions = (url: string | URL, options: supportedOptions) => {
174 | try {
175 | // Parse the original URL
176 | const urlObject = new URL(url);
177 |
178 | // Set the hash property with the GeoJSON data
179 | urlObject.hash = `#${encodeURIComponent(JSON.stringify(options))}`;
180 |
181 | // Convert the updated URL object back to a string
182 | return urlObject.toString();
183 | } catch (error) {
184 | console.error('Error parsing or updating URL:', error);
185 | return url; // Return the original URL if there's an error
186 | }
187 | }
188 |
189 | /**
190 | * Add the vector text protocol to a map library for each supported format.
191 | * @param mapLibrary - The MapLibrary object to add the protocols to.
192 | */
193 | export const addProtocols = (mapLibrary: typeof MapLibrary) => {
194 | supportedFormats.forEach(type => {
195 | mapLibrary.addProtocol(type, VectorTextProtocol as (requestParameters: RequestParameters, controller: AbortController) => Promise>);
196 | })
197 | };
198 |
199 | export const vectorFormats = supportedFormats;
200 | export { supportedFormatsType } from './converter';
--------------------------------------------------------------------------------
/src/worker/actor.ts:
--------------------------------------------------------------------------------
1 | import WebWorker from 'web-worker:./worker';
2 |
3 | const randomString = () => Math.random().toString(36).substring(2);
4 |
5 | import type { MessageData, SubClasses } from './worker';
6 |
7 | export class Actor {
8 | subClass: any;
9 | worker: Worker;
10 | handlers: Map void,
12 | 'reject': (value: Error) => void
13 | }>;
14 | initId: string;
15 | _: Record | undefined;
16 |
17 | /**
18 | * Creates a new instance of the `Actor` class.
19 | * @param subClass - The name of the subclass.
20 | * @param args - The arguments to pass to the subclass constructor.
21 | */
22 | constructor(subClass: SubClasses, args: Array) {
23 | // Generate a random initialization ID
24 | this.initId = randomString() + '-' + subClass;
25 |
26 | // Create a new Web Worker and a new Map for handlers
27 | this.worker = new WebWorker();
28 | this.handlers = new Map();
29 |
30 | // Listen for messages from the worker
31 | this.worker.onmessage = (event: any) => {
32 | const data = event.data as MessageData;
33 | const handler = this.handlers.get(data.id);
34 | const that = this;
35 |
36 | if (handler) {
37 | // Handle responses from the worker
38 | if (data.type === 'response') {
39 | handler.resolve(data.message);
40 | }
41 | // Handle errors from the worker
42 | if (data.type === 'error') {
43 | const error = data.error || new Error(`Unknown error with ${subClass}`);
44 | handler.reject(error);
45 | }
46 | // Handle initialization responses from the worker
47 | if (data.type === 'init_response') {
48 | this._ = Object.keys(data.message)
49 | .map(key => {
50 | const isFn = typeof data.message[key as any] === 'function';
51 | const subFunction = function () {
52 | return isFn ? (that.exec(key))(...arguments) : that.get(key);
53 | };
54 | return [key, subFunction];
55 | })
56 | .reduce((a, c) => ({ ...a, ...{ [c[0] as string]: c[1] } }), {});
57 | handler.resolve(this._);
58 | }
59 | }
60 | };
61 |
62 | // Tell the worker to initialize the subclass
63 | this.worker.postMessage({
64 | type: 'init',
65 | id: this.initId,
66 | command: subClass,
67 | message: args
68 | } as MessageData);
69 | }
70 |
71 | /**
72 | * Waits for the initialization of the object to complete and returns the resulting object.
73 | * @returns A promise that resolves with the initialized object.
74 | */
75 | onLoad(): Promise {
76 | return new Promise((resolve) => {
77 | // If initialization is still in progress, add a new handler for the initialization result
78 | if (this._ === undefined) {
79 | this.handlers.set(this.initId, { resolve, 'reject': resolve });
80 | } else {
81 | // Otherwise, immediately resolve the promise with the initialized object
82 | resolve(this._);
83 | }
84 | });
85 | }
86 |
87 |
88 | /**
89 | * returns a Promise for a given command that will be executed in a worker.
90 | * @param command - The command to execute.
91 | * @returns A Promise that resolves with the result of the command execution or rejects with an error.
92 | */
93 | exec(command: string): (...args: any[]) => Promise {
94 | // Keep track of this class
95 | const that = this;
96 |
97 | // Return a function that returns a Promise
98 | return function (...args: any[]): Promise {
99 | return new Promise((resolve, reject) => {
100 | const id = randomString() + '-' + command;
101 |
102 | // Set up the resolve and reject handlers for the Promise
103 | that.handlers.set(id, { resolve, reject });
104 |
105 | // Tell the worker to run the command with the provided arguments
106 | that.worker.postMessage({
107 | type: 'exec',
108 | id: id,
109 | command: command,
110 | message: [...args]
111 | } as MessageData);
112 | });
113 | };
114 | }
115 |
116 | /**
117 | * Returns a Promise that resolves with the result of a command sent to a Web Worker.
118 | * @param command - The command to send to the Web Worker.
119 | * @returns A Promise that resolves with the result of the command.
120 | */
121 | get(command: string): Promise {
122 | return new Promise((resolve, reject) => {
123 | // Generate a unique ID for this request
124 | const id = randomString() + '-' + command;
125 |
126 | // Store the resolve and reject functions for later use
127 | this.handlers.set(id, { resolve, reject });
128 |
129 | // Send the command to the worker
130 | this.worker.postMessage({
131 | type: 'get',
132 | id,
133 | command,
134 | message: [],
135 | } as MessageData);
136 | });
137 | }
138 | };
--------------------------------------------------------------------------------
/src/worker/worker.ts:
--------------------------------------------------------------------------------
1 | import { Converter } from '../converter';
2 |
3 | export interface MessageData {
4 | 'type': 'response' | 'error' | 'init' | 'exec' | 'get' | 'init_response',
5 | 'id': string,
6 | 'message': Array,
7 | 'error'?: Error,
8 | 'command': string
9 | }
10 |
11 | const subClasses = ['Converter'] as const;
12 | export type SubClasses = typeof subClasses[number];
13 | const libraries: { [_: string]: any } = {
14 | 'Converter': Converter
15 | };
16 |
17 | let subClass: any;
18 |
19 | self.addEventListener('message', e => {
20 | const data = (e.data || e) as MessageData;
21 |
22 | const post = (id: string, err: Error | undefined, res?: any, type?: string) => {
23 | postMessage({
24 | type: type ? type : (err ? 'error' : 'response'),
25 | id: id,
26 | message: res,
27 | error: err
28 | } as MessageData)
29 | }
30 |
31 | const commands = {
32 | 'init': (msg: MessageData) => {
33 | const { id, command, message } = msg;
34 | subClass = new libraries[command](message[0], message[1]);
35 |
36 | // return the class' methods
37 | const fns = [
38 | ...Object.getOwnPropertyNames(libraries[command].prototype),
39 | ...Object.keys(subClass)
40 | ].map(key => [key, typeof libraries[command].prototype[key]])
41 | .reduce((a, c) => ({ ...a, ...{ [c[0]]: c[1] } }), {});
42 | post(id, undefined, fns, 'init_response')
43 | },
44 | 'get': function (msg: MessageData) {
45 | const { id, command } = msg;
46 | if (subClass && subClass[command]) {
47 | post(id, undefined, subClass[command]);
48 | } else {
49 | post(id, undefined, undefined);
50 | }
51 | },
52 | 'exec': function (msg: MessageData) {
53 | const { id, command, message } = msg;
54 |
55 | if (subClass && subClass[command] && typeof subClass[command] === 'function') {
56 | const cmd = (subClass[command] as () => Promise)
57 | .apply(subClass, message as []);
58 |
59 | if (!!cmd && typeof cmd.then === 'function') {
60 | // It's a promise, so wait for it
61 | cmd
62 | .then(res => post(id, undefined, res))
63 | .catch(e => post(id, e));
64 | } else {
65 | // Not a promise, just return it
66 | post(id, undefined, cmd);
67 | }
68 | } else {
69 | // Error
70 | post(id, new Error(`command "${command}" not found`));
71 | }
72 | }
73 | };
74 |
75 | if (commands[data.type as 'init' | 'exec' | 'get']) {
76 | commands[data.type as 'init' | 'exec' | 'get'](data)
77 | }
78 | });
79 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Enable incremental compilation */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "ES2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 |
26 | /* Modules */
27 | "module": "esnext", /* Specify what module code is generated. */
28 | // "rootDir": "./", /* Specify the root folder within your source files. */
29 | "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
36 | // "resolveJsonModule": true, /* Enable importing .json files */
37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
38 |
39 | /* JavaScript Support */
40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
43 |
44 | /* Emit */
45 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
46 | "declarationMap": true, /* Create sourcemaps for d.ts files. */
47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
50 | // "outDir": "./", /* Specify an output folder for all emitted files. */
51 | // "removeComments": true, /* Disable emitting comments. */
52 | // "noEmit": true, /* Disable emitting files from a compilation. */
53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
61 | // "newLine": "crlf", /* Set the newline character for emitting files. */
62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
66 | "declarationDir": "./dist", /* Specify the output directory for generated declaration files. */
67 |
68 | /* Interop Constraints */
69 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
70 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
71 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
72 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
73 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
74 |
75 | /* Type Checking */
76 | "strict": true, /* Enable all strict type-checking options. */
77 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
78 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
79 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
80 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
81 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
82 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
83 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
84 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
85 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
86 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
87 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
88 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
89 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
90 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
91 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
92 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
93 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
94 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
95 |
96 | /* Completeness */
97 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
98 | "skipLibCheck": true, /* Skip type checking all .d.ts files. */
99 | "outDir": "./out-tsc",
100 | "rootDir": "./"
101 | },
102 | "include": ["./src/**/*.ts"]
103 | }
104 |
--------------------------------------------------------------------------------