diff --git a/omnivore/CHANGELOG.md b/omnivore/CHANGELOG.md new file mode 100644 index 0000000..0f01932 --- /dev/null +++ b/omnivore/CHANGELOG.md @@ -0,0 +1,37 @@ +## 0.3.4 + +* From now on, the repository doesn't contain leaflet-omnivore.js or leaflet-omnivore.min.js. Those + files will be in the npm package and you can use unpkg.com to get them. + +## 0.3.3 + +* Call either `setGeoJSON` or `addData` on GeoJSON layers, not both. + +## 0.3.2 + +* Move `brfs` and `hintify` to dependencies. + +## 0.3.1 + +* Updates [wellknown](https://github.com/mapbox/wellknown) to 0.3.0 with exponent coordinate support +* Updates [togeojson](https://github.com/mapbox/togeojson) to 0.10.1 with timestamp, ie9 feature id, gx:Track, gx:MultiTrack support + +## 0.3.0 + +* Includes [encoded polyline](https://developers.google.com/maps/documentation/utilities/polylinealgorithm) support. + +## 0.2.0 + +* Only includes the necessary parts of [TopoJSON](https://github.com/mbostock/topojson): less bytes, + and **IE9** and **IE10** are now supported. +* Tests now use Sauce Labs and run on real browsers for every commit. +* Builds now use an `npm` script rather than a Makefile. + +## 0.1.0 + +* loader functions now support a `customLayer` option for providing options to + `L.geoJson` or using a different layer type. + +## 0.0.1 + +* `gpx.parse` and `kml.parse` support parsing from either strings or DOM objects diff --git a/omnivore/LICENSE b/omnivore/LICENSE new file mode 100644 index 0000000..9df952a --- /dev/null +++ b/omnivore/LICENSE @@ -0,0 +1,58 @@ +Copyright (c) 2014, Mapbox +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------------------------------------------------------------------------- + +TopoJSON + +Copyright (c) 2012, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/omnivore/README.md b/omnivore/README.md new file mode 100644 index 0000000..d66e9df --- /dev/null +++ b/omnivore/README.md @@ -0,0 +1,184 @@ +# leaflet-omnivore + +![](https://farm8.staticflickr.com/7373/12376158164_e335b4e61d_b.jpg) + +[Leaflet](http://leafletjs.com/) supports the [GeoJSON](http://geojson.org/) format +by default. What if you have something else? That's where omnivore comes in. + +It currently supports: + +* [CSV](http://en.wikipedia.org/wiki/Comma-separated_values) (via [csv2geojson](https://github.com/mapbox/csv2geojson)) +* GPX (via [toGeoJSON](https://github.com/mapbox/togeojson)) +* [KML](http://developers.google.com/kml/documentation/) (via [toGeoJSON](https://github.com/mapbox/togeojson)) +* [WKT](http://en.wikipedia.org/wiki/Well-known_text) (via [wellknown](https://github.com/mapbox/wellknown)) +* [TopoJSON](https://github.com/mbostock/topojson) +* [Encoded Polylines](https://developers.google.com/maps/documentation/utilities/polylinealgorithm) via [polyline](https://github.com/mapbox/polyline) + +Omnivore also includes an AJAX library, [corslite](https://github.com/mapbox/corslite), +so you can specify what you want to add to the map with just a URL. + +## Installation + +use it easily with the [Mapbox Plugins CDN](http://mapbox.com/mapbox.js/plugins/#leaflet-omnivore): + +```html + +``` + + +Or download `leaflet-omnivore.min.js` from this repository. + +## example + +Live examples: + +* [WKT](https://www.mapbox.com/mapbox.js/example/v1.0.0/omnivore-wkt/) +* [TopoJSON](https://www.mapbox.com/mapbox.js/example/v1.0.0/omnivore-topojson/) +* [Tooltips](https://www.mapbox.com/mapbox.js/example/v1.0.0/omnivore-kml-tooltip/) +* [KML](https://www.mapbox.com/mapbox.js/example/v1.0.0/omnivore-kml/) +* [GPX](https://www.mapbox.com/mapbox.js/example/v1.0.0/omnivore-gpx/) +* [Icons](https://www.mapbox.com/mapbox.js/example/v1.0.0/markers-from-csv-custom-style/) +* [CSV](https://www.mapbox.com/mapbox.js/example/v1.0.0/markers-from-csv/) + +```js +var map = L.mapbox.map('map', 'mapbox.streets') + .setView([38, -102.0], 5); + +omnivore.csv('a.csv').addTo(map); +omnivore.gpx('a.gpx').addTo(map); +omnivore.kml('a.kml').addTo(map); +omnivore.wkt('a.wkt').addTo(map); +omnivore.topojson('a.topojson').addTo(map); +omnivore.geojson('a.geojson').addTo(map); +omnivore.polyline('a.txt').addTo(map); +``` + +## API + +Arguments with `?` are optional. **parser_options** consists of options +sent to the parser library, _not_ to the layer: if you want to provide options +to the layer, see the example in the Custom Layers section. + +By default, the library will construct a `L.geoJson()` layer internally and +call `.addData(geojson)` on it in order to load it full of GeoJSON. If you want +to use a different kind of layer, like a `L.mapbox.featureLayer()`, you can, +by passing it as `customLayer`, as long as it supports events and `addData()`. +You can also use this API to pass custom options to a `L.geoJson()` instance.: + + +* `.csv(url, parser_options?, customLayer?)`: Load & parse CSV, and return layer. Options are the same as [csv2geojson](https://github.com/mapbox/csv2geojson#api): `latfield, lonfield, delimiter` +* `.csv.parse(csvString, parser_options?)`: Parse CSV, and return layer. +* `.kml(url)`: Load & parse KML, and return layer. +* `.kml.parse(kmlString | gpxDom)`: Parse KML from a string of XML or XML DOM, and return layer. +* `.gpx(url, parser_options?, customLayer?)`: Load & parse GPX, and return layer. +* `.gpx.parse(gpxString | gpxDom)`: Parse GPX from a string of XML or XML DOM, and return layer. +* `.geojson(url, parser_options?, customLayer?)`: Load GeoJSON file at URL, parse GeoJSON, and return layer. +* `.wkt(url, parser_options?, customLayer?)`: Load & parse WKT, and return layer. +* `.wkt.parse(wktString)`: Parse WKT, and return layer. +* `.topojson(url, parser_options?, customLayer?)`: Load & parse TopoJSON, and return layer. +* `.topojson.parse(topojson)`: Parse TopoJSON (given as a string or object), and return layer. +* `.polyline(url, parser_options?, customLayer?)`: Load & parse polyline, and return layer. +* `.polyline.parse(txt, options, layer)`: Parse polyline (given as a string or object), and return layer. + +Valid options: + +#### polyline + +* `precision` will change how the polyline is interpreted. By default, the value + is 5. This is the [factor in the algorithm](https://developers.google.com/maps/documentation/utilities/polylinealgorithm), + by default 1e5, which is adjustable. + +### Custom Layers + +Passing custom options: + +```js +var customLayer = L.geoJson(null, { + filter: function() { + // my custom filter function + return true; + } +}); + +var myLayer = omnivore.csv('foo', null, customLayer); +``` + +Adding custom styles to a GeoJSON layer: + +```js +var customLayer = L.geoJson(null, { + // http://leafletjs.com/reference.html#geojson-style + style: function(feature) { + return { color: '#f00' }; + } +}); +// this can be any kind of omnivore layer +var runLayer = omnivore.kml('line.kml', null, customLayer) +``` + +Using a `L.mapbox.featureLayer`: + +```js +var layer = omnivore.gpx('a.gpx', null, L.mapbox.featureLayer()); +``` + +### Async & Events + +Each function returns an `L.geoJson` object. Functions that load from URLs +are **asynchronous**, so they will **not** immediately expose accurate `.setGeoJSON()` functions. + +For this reason, we fire events: + +* `ready`: fired when all data is loaded into the layer +* `error`: fired if data can't be loaded or parsed + +```js +var layer = omnivore.gpx('a.gpx') + .on('ready', function() { + // when this is fired, the layer + // is done being initialized + }) + .on('error', function() { + // fired if the layer can't be loaded over AJAX + // or can't be parsed + }) + .addTo(map); +``` + +`ready` does **not** fire if you don't use an asynchronous form of the function +like `.topojson.parse()`: because you don't need an event. Just run your code +after the call. + +## Development + +This is a [browserify](http://browserify.org/) project: + +```sh +git clone git@github.com:mapbox/leaflet-omnivore.git + +cd leaflet-omnivore + +# to run tests +npm install + +# to build leaflet-omnivore.js +npm run prepublish +``` + +`leaflet-omnivore.js` and `leaflet-omnivore.min.js` are **built files** generated +from `index.js` by `browserify`. If you find an issue, it either needs to be +fixed in `index.js`, or in one of the libraries leaflet-omnivore uses +to parse formats. + +## FAQ + +* **What if I just want one format?** Lucky for you, each format is specified + in a different module, so you can just use [TopoJSON](https://github.com/mbostock/topojson), + [csv2geojson](https://github.com/mapbox/csv2geojson), [wellknown](https://github.com/mapbox/wellknown), or + [toGeoJSON](https://github.com/mapbox/togeojson) + individually. +* **My AJAX request is failing for a cross-domain request**. Read up on the [Same Origin Restriction](http://en.wikipedia.org/wiki/Same-origin_policy). + By default, we use corslite, so cross-domain requests will try to use [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) + if your server and browser supports it, but if one of them doesn't, there's no + way on the internet to support your request. +* **Why isn't JSONP supported?** [Here's why](https://gist.github.com/tmcw/6244497). diff --git a/omnivore/component.json b/omnivore/component.json new file mode 100644 index 0000000..99feb3b --- /dev/null +++ b/omnivore/component.json @@ -0,0 +1,8 @@ +{ + "name": "leaflet-omnivore", + "version": "0.2.0", + "description": "a geospatial format parser for Leaflet", + "scripts": [ + "leaflet-omnivore.js" + ] +} diff --git a/omnivore/index.js b/omnivore/index.js new file mode 100644 index 0000000..afb7dcb --- /dev/null +++ b/omnivore/index.js @@ -0,0 +1,258 @@ +var xhr = require('corslite'), + csv2geojson = require('csv2geojson'), + wellknown = require('wellknown'), + polyline = require('polyline'), + topojson = require('topojson'), + toGeoJSON = require('togeojson'); + +module.exports.polyline = polylineLoad; +module.exports.polyline.parse = polylineParse; + +module.exports.geojson = geojsonLoad; + +module.exports.topojson = topojsonLoad; +module.exports.topojson.parse = topojsonParse; + +module.exports.csv = csvLoad; +module.exports.csv.parse = csvParse; + +module.exports.gpx = gpxLoad; +module.exports.gpx.parse = gpxParse; + +module.exports.kml = kmlLoad; +module.exports.kml.parse = kmlParse; + +module.exports.wkt = wktLoad; +module.exports.wkt.parse = wktParse; + +function addData(l, d) { + if ('setGeoJSON' in l) { + l.setGeoJSON(d); + } else if ('addData' in l) { + l.addData(d); + } +} + +/** + * Load a [GeoJSON](http://geojson.org/) document into a layer and return the layer. + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function geojsonLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, function(err, response) { + if (err) return layer.fire('error', { error: err }); + addData(layer, JSON.parse(response.responseText)); + layer.fire('ready'); + }); + return layer; +} + +/** + * Load a [TopoJSON](https://github.com/mbostock/topojson) document into a layer and return the layer. + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function topojsonLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + if (err) return layer.fire('error', { error: err }); + topojsonParse(response.responseText, options, layer); + layer.fire('ready'); + } + return layer; +} + +/** + * Load a CSV document into a layer and return the layer. + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function csvLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + var error; + if (err) return layer.fire('error', { error: err }); + function avoidReady() { + error = true; + } + layer.on('error', avoidReady); + csvParse(response.responseText, options, layer); + layer.off('error', avoidReady); + if (!error) layer.fire('ready'); + } + return layer; +} + +/** + * Load a GPX document into a layer and return the layer. + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function gpxLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + var error; + if (err) return layer.fire('error', { error: err }); + function avoidReady() { + error = true; + } + layer.on('error', avoidReady); + gpxParse(response.responseXML || response.responseText, options, layer); + layer.off('error', avoidReady); + if (!error) layer.fire('ready'); + } + return layer; +} + +/** + * Load a [KML](https://developers.google.com/kml/documentation/) document into a layer and return the layer. + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function kmlLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + var error; + if (err) return layer.fire('error', { error: err }); + function avoidReady() { + error = true; + } + layer.on('error', avoidReady); + kmlParse(response.responseXML || response.responseText, options, layer); + layer.off('error', avoidReady); + if (!error) layer.fire('ready'); + } + return layer; +} + +/** + * Load a WKT (Well Known Text) string into a layer and return the layer + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function wktLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + if (err) return layer.fire('error', { error: err }); + wktParse(response.responseText, options, layer); + layer.fire('ready'); + } + return layer; +} + +/** + * Load a polyline string into a layer and return the layer + * + * @param {string} url + * @param {object} options + * @param {object} customLayer + * @returns {object} + */ +function polylineLoad(url, options, customLayer) { + var layer = customLayer || L.geoJson(); + xhr(url, onload); + function onload(err, response) { + if (err) return layer.fire('error', { error: err }); + polylineParse(response.responseText, options, layer); + layer.fire('ready'); + } + return layer; +} + +function topojsonParse(data, options, layer) { + var o = typeof data === 'string' ? + JSON.parse(data) : data; + layer = layer || L.geoJson(); + for (var i in o.objects) { + var ft = topojson.feature(o, o.objects[i]); + if (ft.features) addData(layer, ft.features); + else addData(layer, ft); + } + return layer; +} + +function csvParse(csv, options, layer) { + layer = layer || L.geoJson(); + options = options || {}; + csv2geojson.csv2geojson(csv, options, onparse); + function onparse(err, geojson) { + if (err) return layer.fire('error', { error: err }); + addData(layer, geojson); + } + return layer; +} + +function gpxParse(gpx, options, layer) { + var xml = parseXML(gpx); + if (!xml) return layer.fire('error', { + error: 'Could not parse GPX' + }); + layer = layer || L.geoJson(); + var geojson = toGeoJSON.gpx(xml); + addData(layer, geojson); + return layer; +} + + +function kmlParse(gpx, options, layer) { + var xml = parseXML(gpx); + if (!xml) return layer.fire('error', { + error: 'Could not parse KML' + }); + layer = layer || L.geoJson(); + var geojson = toGeoJSON.kml(xml); + addData(layer, geojson); + return layer; +} + +function polylineParse(txt, options, layer) { + layer = layer || L.geoJson(); + options = options || {}; + var coords = polyline.decode(txt, options.precision); + var geojson = { type: 'LineString', coordinates: [] }; + for (var i = 0; i < coords.length; i++) { + // polyline returns coords in lat, lng order, so flip for geojson + geojson.coordinates[i] = [coords[i][1], coords[i][0]]; + } + addData(layer, geojson); + return layer; +} + +function wktParse(wkt, options, layer) { + layer = layer || L.geoJson(); + var geojson = wellknown(wkt); + addData(layer, geojson); + return layer; +} + +function parseXML(str) { + if (typeof str === 'string') { + return (new DOMParser()).parseFromString(str, 'text/xml'); + } else { + return str; + } +} diff --git a/omnivore/leaflet-omnivore.js b/omnivore/leaflet-omnivore.js new file mode 100644 index 0000000..4c37d2e --- /dev/null +++ b/omnivore/leaflet-omnivore.js @@ -0,0 +1,2 @@ + +!function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.omnivore=r()}}(function(){var r;return function r(e,t,n){function o(u,a){if(!t[u]){if(!e[u]){var s="function"==typeof require&&require;if(!a&&s)return s(u,!0);if(i)return i(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var c=t[u]={exports:{}};e[u][0].call(c.exports,function(r){var t=e[u][1][r];return o(t?t:r)},c,c.exports,r,e,t,n)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;u=200&&r<300||304===r}function o(){void 0===a.status||n(a.status)?e.call(a,null,a):e.call(a,a,null)}var i=!1;if("undefined"==typeof window.XMLHttpRequest)return e(Error("Browser not supported"));if("undefined"==typeof t){var u=r.match(/^\s*https?:\/\/[^\/]*/);t=u&&u[0]!==location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")}var a=new window.XMLHttpRequest;if(t&&!("withCredentials"in a)){a=new window.XDomainRequest;var s=e;e=function(){if(i)s.apply(this,arguments);else{var r=this,e=arguments;setTimeout(function(){s.apply(r,e)},0)}}}return"onload"in a?a.onload=o:a.onreadystatechange=function(){4===a.readyState&&o()},a.onerror=function(r){e.call(this,r||!0,null),e=function(){}},a.onprogress=function(){},a.ontimeout=function(r){e.call(this,r,null),e=function(){}},a.onabort=function(r){e.call(this,r,null),e=function(){}},a.open("GET",r,!0),a.send(null),i=!0,a}"undefined"!=typeof e&&(e.exports=n)},{}],4:[function(r,e,t){"use strict";function n(r,e){var t,n,o;for(var i in r)n=i.match(e),n&&(!t||n[0].length/i.length>o)&&(o=n[0].length/i.length,t=i);return t}function o(r){return n(r,m)}function i(r){return n(r,y)}function u(r){return!!r.match(m)}function a(r){return!!r.match(y)}function s(r){return"object"==typeof r?Object.keys(r).length:0}function f(r){var e=[",",";","\t","|"],t=[];return e.forEach(function(e){var n=d.dsvFormat(e).parse(r);if(n.length>=1){for(var o=s(n[0]),i=0;i=s)return u;if(o)return o=!1,i;var e,t=f;if(34===r.charCodeAt(t)){for(var n=t;n++=32;)t+=String.fromCharCode((32|31&r)+63),r>>=5;return t+=String.fromCharCode(r+63)}function o(r){for(var e=[],t=0;t=32);t=1&f?~(f>>1):f>>1,s=f=0;do c=r.charCodeAt(o++)-63,f|=(31&c)<=32);n=1&f?~(f>>1):f>>1,i+=t,u+=n,a.push([i/l,u/l])}return a},i.encode=function(r,e){if(!r.length)return"";for(var t=Math.pow(10,e||5),o=n(r[0][0],t)+n(r[0][1],t),i=1;i1)for(var t=1;t=0?0:1],o=Math.abs(r),i=Math.floor(o),u=o-i,a=60*u,s=Math.floor(a),f=Math.floor(60*(a-s));return{whole:i,minutes:s,seconds:f,dir:n}}function a(r,e,t){if(e||(e="NSEW"),"string"!=typeof r)return{val:null,regex:t};t=t||/[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;var n=t.exec(r);return n?n[4]&&e.indexOf(n[4])===-1?{val:null,regex:t}:{val:((n[1]?parseFloat(n[1]):0)+(n[2]?parseFloat(n[2])/60:0)+(n[3]?parseFloat(n[3])/3600:0))*(n[4]&&"S"===n[4]||"W"===n[4]?-1:1),regex:t,raw:n[0],dim:n[4]}:{val:null,regex:t}}function s(r,e){r=r.trim();var t=a(r,e);if(null===t.val)return null;var n=a(r,e,t.regex);return null===n.val?null:t.raw+n.raw!==r?null:t.dim?f(t.val,n.val,t.dim):[t.val,n.val]}function f(r,e,t){return"N"===t||"S"===t?[r,e]:"W"===t||"E"===t?[e,r]:void 0}e.exports=n,e.exports.pair=s,e.exports.format=i,e.exports.formatPair=o,e.exports.coordToDMS=u},{}],9:[function(r,e,t){(function(n){var o=function(){"use strict";function e(r){if(!r||!r.length)return 0;for(var e=0,t=0;e>>1;r[o]1){var s,c=[],l={LineString:o,MultiLineString:i,Polygon:i,MultiPolygon:function(r){r.forEach(i)}};u(e),c.forEach(arguments.length<3?function(r){a.push(r[0].i)}:function(r){t(r[0].g,r[r.length-1].g)&&a.push(r[0].i)})}else for(var p=0,h=r.arcs.length;p1)for(var u,a,s=1,c=n(i[0]);sc&&(a=i[0],i[0]=i[s],i[s]=a,c=u);return i})}}function v(r){function e(r,e){r.forEach(function(r){r<0&&(r=~r);var t=o[r];t?t.push(e):o[r]=[e]})}function t(r,t){r.forEach(function(r){e(r,t)})}function n(r,e){"GeometryCollection"===r.type?r.geometries.forEach(function(r){n(r,e)}):r.type in a&&a[r.type](r.arcs,e)}var o={},u=r.map(function(){return[]}),a={LineString:e,MultiLineString:t,Polygon:t,MultiPolygon:function(r,e){r.forEach(function(r){t(r,e)})}};r.forEach(n);for(var s in o)for(var f=o[s],c=f.length,l=0;l0;){var t=(e+1>>1)-1,o=n[t];if(m(r,o)>=0)break;n[o._=e]=o,n[r._=e=t]=r}}function e(r,e){for(;;){var t=e+1<<1,i=t-1,u=e,a=n[u];if(i0&&(r=n[o],e(n[r._=0]=r,0)),t}},t.remove=function(t){var i,u=t._;if(n[u]===t)return u!==--o&&(i=n[o],(m(i,t)<0?r:e)(n[i._=u]=i,u)),u},t}function x(r,e){function o(r){a.remove(r),r[1][2]=e(r),a.push(r)}var i=t(r.transform),u=n(r.transform),a=y();return e||(e=p),r.arcs.forEach(function(r){var t,n,s,f,c=[],l=0;for(n=0,s=r.length;n0)){var t=r.shift();t()}},!0),function(n){r.push(n),window.postMessage("process-tick","*")}}return function(n){setTimeout(n,0)}}(),t.title="browser",t.browser=!0,t.env={},t.argv=[],t.on=r,t.addListener=r,t.once=r,t.off=r,t.removeListener=r,t.removeAllListeners=r,t.emit=r,t.binding=function(){throw new Error("process.binding is not supported")},t.cwd=function(){return"/"},t.chdir=function(){throw new Error("process.chdir is not supported")}},{}],5:[function(n,e){function r(n,e,r){function t(n){return n>=200&&300>n||304===n}function o(){void 0===a.status||t(a.status)?e.call(a,null,a):e.call(a,a,null)}var i=!1;if("undefined"==typeof window.XMLHttpRequest)return e(Error("Browser not supported"));if("undefined"==typeof r){var u=n.match(/^\s*https?:\/\/[^\/]*/);r=u&&u[0]!==location.protocol+"//"+location.domain+(location.port?":"+location.port:"")}var a=new window.XMLHttpRequest;if(r&&!("withCredentials"in a)){a=new window.XDomainRequest;var s=e;e=function(){if(i)s.apply(this,arguments);else{var n=this,e=arguments;setTimeout(function(){s.apply(n,e)},0)}}}return"onload"in a?a.onload=o:a.onreadystatechange=function(){4===a.readyState&&o()},a.onerror=function(n){e.call(this,n||!0,null),e=function(){}},a.onprogress=function(){},a.ontimeout=function(n){e.call(this,n,null),e=function(){}},a.onabort=function(n){e.call(this,n,null),e=function(){}},a.open("GET",n,!0),a.send(null),i=!0,a}"undefined"!=typeof e&&(e.exports=r)},{}],6:[function(n,e){function r(n){return!!n.match(/(Lat)(itude)?/gi)}function t(n){return!!n.match(/(L)(on|ng)(gitude)?/i)}function o(n){return"object"==typeof n?Object.keys(n).length:0}function i(n){var e=[",",";"," ","|"],r=[];return e.forEach(function(e){var t=c(e).parse(n);if(t.length>=1){for(var i=o(t[0]),u=0;u= 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;\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 var 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.substring(j + 1, i).replace(/""/g, "\\"");\n }\n\n // common case: find next delimiter or newline\n while (I < N) {\n var c = text.charCodeAt(I++), k = 1;\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.substring(j, I - k);\n }\n\n // special case: last token before EOF\n return text.substring(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++))) continue;\n rows.push(a);\n }\n\n return rows;\n };\n\n dsv.format = function(rows) {\n if (Array.isArray(rows[0])) return dsv.formatRows(rows); // deprecated; use formatRows\n var fieldSet = {}, fields = [];\n\n // Compute unique fields in order of discovery.\n rows.forEach(function(row) {\n for (var field in row) {\n if (!(field in fieldSet)) {\n fields.push(fieldSet[field] = field);\n }\n }\n });\n\n return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return fields.map(function(field) {\n return formatValue(row[field]);\n }).join(delimiter);\n })).join("\\n");\n };\n\n dsv.formatRows = function(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 reFormat.test(text) ? "\\"" + text.replace(/\\"/g, "\\"\\"") + "\\"" : text;\n }\n\n return dsv;\n}\n;return dsv')()},{fs:2}],8:[function(n,e){e.exports=function(n,e){if(e||(e="NSEW"),"string"!=typeof n)return null;var r=/^([0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/,t=n.match(r);return t?t[4]&&-1===e.indexOf(t[4])?null:((t[1]?parseFloat(t[1]):0)+(t[2]?parseFloat(t[2])/60:0)+(t[3]?parseFloat(t[3])/3600:0))*(t[4]&&"S"===t[4]||"W"===t[4]?-1:1):null}},{}],9:[function(n,e,r){(function(t){toGeoJSON=function(){"use strict";function e(n){if(!n||!n.length)return 0;for(var e=0,r=0;ee?~e:e],o=t[0];return n.transform?(r=[0,0],t.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=t[t.length-1],0>e?[r,o]:[o,r]}function t(n,e){for(var r in n){var t=n[r];delete e[t.start],delete t.start,delete t.end,t.forEach(function(n){o[0>n?~n:n]=1}),a.push(t)}}var o={},i={},u={},a=[],s=-1;return e.forEach(function(r,t){var o,i=n.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=e[++s],e[s]=r,e[t]=o)}),e.forEach(function(n){var e,t,o=r(n),a=o[0],s=o[1];if(e=u[a])if(delete u[e.end],e.push(n),e.end=s,t=i[s]){delete i[t.start];var f=t===e?e:e.concat(t);i[f.start=e.start]=u[f.end=t.end]=f}else i[e.start]=u[e.end]=e;else if(e=i[s])if(delete i[e.start],e.unshift(n),e.start=a,t=u[a]){delete u[t.end];var c=t===e?e:t.concat(e);i[c.start=t.start]=u[c.end=e.end]=c}else i[e.start]=u[e.end]=e;else e=[n],i[e.start=a]=u[e.end=s]=e}),t(u,i),t(i,u),e.forEach(function(n){o[0>n?~n:n]||a.push([n])}),a}function o(n,e,t){function o(n){var e=0>n?~n:n;(c[e]||(c[e]=[])).push({i:n,g:f})}function i(n){n.forEach(o)}function u(n){n.forEach(i)}function a(n){"GeometryCollection"===n.type?n.geometries.forEach(a):n.type in l&&(f=n,l[n.type](n.arcs))}var s=[];if(arguments.length>1){var f,c=[],l={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(n){n.forEach(u)}};a(e),c.forEach(arguments.length<3?function(n){s.push(n[0].i)}:function(n){t(n[0].g,n[n.length-1].g)&&s.push(n[0].i)})}else for(var p=0,d=n.arcs.length;d>p;++p)s.push(p);return{type:"MultiLineString",arcs:r(n,s)}}function i(e,t){function o(n){n.forEach(function(e){e.forEach(function(e){(u[e=0>e?~e:e]||(u[e]=[])).push(n)})}),a.push(n)}function i(n){return d(s(e,{type:"Polygon",arcs:[n]}).coordinates[0])>0}var u={},a=[],f=[];return t.forEach(function(n){"Polygon"===n.type?o(n.arcs):"MultiPolygon"===n.type&&n.arcs.forEach(o)}),a.forEach(function(n){if(!n._){var e=[],r=[n];for(n._=1,f.push(e);n=r.pop();)e.push(n),n.forEach(function(n){n.forEach(function(n){u[0>n?~n:n].forEach(function(n){n._||(n._=1,r.push(n))})})})}}),a.forEach(function(n){delete n._}),{type:"MultiPolygon",arcs:f.map(function(t){var o=[];if(t.forEach(function(n){n.forEach(function(n){n.forEach(function(n){u[0>n?~n:n].length<2&&o.push(n)})})}),o=r(e,o),(n=o.length)>1)for(var a,s=i(t[0][0]),f=0;n>f;++f)if(s===i(o[f])){a=o[0],o[0]=o[f],o[f]=a;break}return o})}}function u(n,e){return"GeometryCollection"===e.type?{type:"FeatureCollection",features:e.geometries.map(function(e){return a(n,e)})}:a(n,e)}function a(n,e){var r={type:"Feature",id:e.id,properties:e.properties||{},geometry:s(n,e)};return null==e.id&&delete r.id,r}function s(n,e){function r(n,e){e.length&&e.pop();for(var r,t=c[0>n?~n:n],o=0,i=t.length;i>o;++o)e.push(r=t[o].slice()),s(r,o);0>n&&f(e,i)}function t(n){return n=n.slice(),s(n,0),n}function o(n){for(var e=[],t=0,o=n.length;o>t;++t)r(n[t],e);return e.length<2&&e.push(e[0].slice()),e}function i(n){for(var e=o(n);e.length<4;)e.push(e[0].slice());return e}function u(n){return n.map(i)}function a(n){var e=n.type;return"GeometryCollection"===e?{type:e,geometries:n.geometries.map(a)}:e in l?{type:e,coordinates:l[e](n)}:null}var s=m(n.transform),c=n.arcs,l={Point:function(n){return t(n.coordinates)},MultiPoint:function(n){return n.coordinates.map(t)},LineString:function(n){return o(n.arcs)},MultiLineString:function(n){return n.arcs.map(o)},Polygon:function(n){return u(n.arcs)},MultiPolygon:function(n){return n.arcs.map(u)}};return a(e)}function f(n,e){for(var r,t=n.length,o=t-e;o<--t;)r=n[o],n[o++]=n[t],n[t]=r}function c(n,e){for(var r=0,t=n.length;t>r;){var o=r+t>>>1;n[o]n&&(n=~n);var r=o[n];r?r.push(e):o[n]=[e]})}function r(n,r){n.forEach(function(n){e(n,r)})}function t(n,e){"GeometryCollection"===n.type?n.geometries.forEach(function(n){t(n,e)}):n.type in u&&u[n.type](n.arcs,e)}var o={},i=n.map(function(){return[]}),u={LineString:e,MultiLineString:r,Polygon:r,MultiPolygon:function(n,e){n.forEach(function(n){r(n,e)})}};n.forEach(t);for(var a in o)for(var s=o[a],f=s.length,l=0;f>l;++l)for(var p=l+1;f>p;++p){var d,g=s[l],v=s[p];(d=i[g])[a=c(d,v)]!==v&&d.splice(a,0,v),(d=i[v])[a=c(d,g)]!==g&&d.splice(a,0,g)}return i}function p(n,e){function r(n){u.remove(n),n[1][2]=e(n),u.push(n)}var t,o=m(n.transform),i=y(n.transform),u=h(),a=0;for(e||(e=g),n.arcs.forEach(function(n){var r=[];n.forEach(o);for(var i=1,a=n.length-1;a>i;++i)t=n.slice(i-1,i+2),t[1][2]=e(t),r.push(t),u.push(t);n[0][2]=n[a][2]=1/0;for(var i=0,a=r.length;a>i;++i)t=r[i],t.previous=r[i-1],t.next=r[i+1]});t=u.pop();){var s=t.previous,f=t.next;t[1][2]0;){var r=(e+1>>1)-1,o=t[r];if(v(n,o)>=0)break;t[o._=e]=o,t[n._=e=r]=n}}function e(n,e){for(;;){var r=e+1<<1,i=r-1,u=e,a=t[u];if(o>i&&v(t[i],a)<0&&(a=t[u=i]),o>r&&v(t[r],a)<0&&(a=t[u=r]),u===e)break;t[a._=e]=a,t[n._=e=u]=n}}var r={},t=[],o=0;return r.push=function(e){return n(t[e._=o]=e,o++),o},r.pop=function(){if(!(0>=o)){var n,r=t[0];return--o>0&&(n=t[o],e(t[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(t[u]===r)return u!==--o&&(i=t[o],(v(i,r)<0?n:e)(t[i._=u]=i,u)),u},r}function m(n){if(!n)return w;var e,r,t=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,a){a||(e=r=0),n[0]=(e+=n[0])*t+i,n[1]=(r+=n[1])*o+u}}function y(n){if(!n)return w;var e,r,t=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,a){a||(e=r=0);var s=(n[0]-i)/t|0,f=(n[1]-u)/o|0;n[0]=s-e,n[1]=f-r,e=s,r=f}}function w(){}var x={version:"1.6.8",mesh:function(n){return s(n,o.apply(this,arguments))},meshArcs:o,merge:function(n){return s(n,i.apply(this,arguments))},mergeArcs:i,feature:u,neighbors:l,presimplify:p};"function"==typeof e&&e.amd?e(x):"object"==typeof t&&t.exports?t.exports=x:this.topojson=x}()},{}],11:[function(n,e){function r(n){function e(e){var r=n.substring(h).match(e);return r?(h+=r[0].length,r[0]):null}function r(n){return n&&v.match(/\d+/)&&(n.crs={type:"name",properties:{name:"urn:ogc:def:crs:EPSG::"+v}}),n}function t(){e(/^\s*/)}function o(){t();for(var n,r=0,o=[],i=[o],u=o;n=e(/^(\()/)||e(/^(\))/)||e(/^(\,)/)||e(/^[-+]?([0-9]*\.[0-9]+|[0-9]+)/);){if("("==n)i.push(u),u=[],i[i.length-1].push(u),r++;else if(")"==n){if(u=i.pop(),!u)return;if(r--,0===r)break}else if(","===n)u=[],i[i.length-1].push(u);else{if(isNaN(parseFloat(n)))return null;u.push(parseFloat(n))}t()}return 0!==r?null:o}function i(){for(var n,r,o=[];r=e(/^[-+]?([0-9]*\.[0-9]+|[0-9]+)/)||e(/^(\,)/);)","==r?(o.push(n),n=[]):(n||(n=[]),n.push(parseFloat(r))),t();return n&&o.push(n),o.length?o:null}function u(){if(!e(/^(point)/i))return null;if(t(),!e(/^(\()/))return null;var n=i();return n?(t(),e(/^(\))/)?{type:"Point",coordinates:n[0]}:null):null}function a(){if(!e(/^(multipoint)/i))return null;t();var n=o();return n?(t(),{type:"MultiPoint",coordinates:n}):null}function s(){if(!e(/^(multilinestring)/i))return null;t();var n=o();return n?(t(),{type:"MultiLineString",coordinates:n}):null}function f(){if(!e(/^(linestring)/i))return null;if(t(),!e(/^(\()/))return null;var n=i();return n?e(/^(\))/)?{type:"LineString",coordinates:n}:null:null}function c(){return e(/^(polygon)/i)?(t(),{type:"Polygon",coordinates:o()}):null}function l(){return e(/^(multipolygon)/i)?(t(),{type:"MultiPolygon",coordinates:o()}):null}function p(){var n,r=[];if(!e(/^(geometrycollection)/i))return null;if(t(),!e(/^(\()/))return null;for(;n=d();)r.push(n),t(),e(/^(\,)/),t();return e(/^(\))/)?{type:"GeometryCollection",geometries:r}:null}function d(){return u()||f()||c()||a()||s()||l()||p()}var g=n.split(";"),n=g.pop(),v=(g.shift()||"").split("=").pop(),h=0;return r(d())}function t(n){function e(n){return 2===n.length?n[0]+" "+n[1]:3===n.length?n[0]+" "+n[1]+" "+n[2]:void 0}function r(n){return n.map(e).join(", ")}function o(n){return n.map(r).map(u).join(", ")}function i(n){return n.map(o).map(u).join(", ")}function u(n){return"("+n+")"}switch("Feature"===n.type&&(n=n.geometry),n.type){case"Point":return"POINT ("+e(n.coordinates)+")";case"LineString":return"LINESTRING ("+r(n.coordinates)+")";case"Polygon":return"POLYGON ("+o(n.coordinates)+")";case"MultiPoint":return"MULTIPOINT ("+r(n.coordinates)+")";case"MultiPolygon":return"MULTIPOLYGON ("+i(n.coordinates)+")";case"MultiLineString":return"MULTILINESTRING ("+o(n.coordinates)+")";case"GeometryCollection":return"GEOMETRYCOLLECTION ("+n.geometries.map(t).join(", ")+")";default:throw new Error("stringify requires a valid GeoJSON Feature or geometry object as input")}}e.exports=r,e.exports.parse=r,e.exports.stringify=t},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/omnivore/package.json b/omnivore/package.json new file mode 100644 index 0000000..e0a45a0 --- /dev/null +++ b/omnivore/package.json @@ -0,0 +1,70 @@ +{ + "name": "@mapbox/leaflet-omnivore", + "version": "0.3.4", + "description": "a geospatial format parser for Leaflet", + "main": "index.js", + "scripts": { + "test": "zuul --local -- test/test.js", + "test-remote": "zuul -- test/test.js", + "test-headless": "zuul --phantom -- test/test.js", + "prepublish": "browserify -s omnivore index.js > leaflet-omnivore.js && uglifyjs leaflet-omnivore.js -c -m > leaflet-omnivore.min.js" + }, + "repository": { + "type": "git", + "url": "git@github.com:mapbox/leaflet-omnivore.git" + }, + "files": [ + "index.js", + "leaflet-omnivore.js", + "leaflet-omnivore.min.js" + ], + "browserify": { + "transform": [ + "brfs" + ] + }, + "keywords": [ + "leaflet", + "formats", + "kml", + "csv", + "gpx", + "geojson", + "kml", + "leaflet", + "maps", + "gpx", + "wkt", + "osm", + "polyline", + "topojson", + "format", + "converter" + ], + "author": "Tom MacWright", + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/mapbox/leaflet-omnivore/issues" + }, + "homepage": "https://github.com/mapbox/leaflet-omnivore", + "dependencies": { + "csv2geojson": "~5.0.0", + "togeojson": "0.13.0", + "corslite": "0.0.7", + "wellknown": "0.4.2", + "brfs": "1.4.3", + "topojson": "1.6.26", + "polyline": "0.2.0" + }, + "devDependencies": { + "browserify": "13.0.1", + "tape": "4.5.1", + "uglify-js": "^2.6.2", + "jshint": "2.9.2", + "mocha": "~2.5.3", + "zuul": "~3.10.1", + "st": "1.1.0", + "mapbox.js": "2.4.0", + "phantomjs-prebuilt": "2.1.7" + } +} \ No newline at end of file