You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
12 lines
49 KiB
12 lines
49 KiB
{ |
|
"version": 3, |
|
"sources": [ |
|
"terraformer.js" |
|
], |
|
"names": [], |
|
"mappings": ";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", |
|
"file": "index.js", |
|
"sourcesContent": [ |
|
"(function (root, factory) {\r\n\r\n // Node.\r\n if(typeof module === 'object' && typeof module.exports === 'object') {\r\n exports = module.exports = factory();\r\n }\r\n\r\n // Browser Global.\r\n if(typeof window === \"object\") {\r\n root.Terraformer = factory();\r\n }\r\n\r\n}(this, function(){\r\n \r\n\r\n var exports = {},\r\n EarthRadius = 6378137,\r\n DegreesPerRadian = 57.295779513082320,\r\n RadiansPerDegree = 0.017453292519943,\r\n MercatorCRS = {\r\n \"type\": \"link\",\r\n \"properties\": {\r\n \"href\": \"http://spatialreference.org/ref/sr-org/6928/ogcwkt/\",\r\n \"type\": \"ogcwkt\"\r\n }\r\n },\r\n GeographicCRS = {\r\n \"type\": \"link\",\r\n \"properties\": {\r\n \"href\": \"http://spatialreference.org/ref/epsg/4326/ogcwkt/\",\r\n \"type\": \"ogcwkt\"\r\n }\r\n };\r\n\r\n /*\r\n Internal: isArray function\r\n */\r\n function isArray(obj) {\r\n return Object.prototype.toString.call(obj) === \"[object Array]\";\r\n }\r\n\r\n /*\r\n Internal: safe warning\r\n */\r\n function warn() {\r\n var args = Array.prototype.slice.apply(arguments);\r\n\r\n if (typeof console !== undefined && console.warn) {\r\n console.warn.apply(console, args);\r\n }\r\n }\r\n\r\n /*\r\n Internal: Extend one object with another.\r\n */\r\n function extend(destination, source) {\r\n for (var k in source) {\r\n if (source.hasOwnProperty(k)) {\r\n destination[k] = source[k];\r\n }\r\n }\r\n return destination;\r\n }\r\n\r\n /*\r\n Public: Calculate an bounding box for a geojson object\r\n */\r\n function calculateBounds (geojson) {\r\n if(geojson.type){\r\n switch (geojson.type) {\r\n case 'Point':\r\n return [ geojson.coordinates[0], geojson.coordinates[1], geojson.coordinates[0], geojson.coordinates[1]];\r\n\r\n case 'MultiPoint':\r\n return calculateBoundsFromArray(geojson.coordinates);\r\n\r\n case 'LineString':\r\n return calculateBoundsFromArray(geojson.coordinates);\r\n\r\n case 'MultiLineString':\r\n return calculateBoundsFromNestedArrays(geojson.coordinates);\r\n\r\n case 'Polygon':\r\n return calculateBoundsFromNestedArrays(geojson.coordinates);\r\n\r\n case 'MultiPolygon':\r\n return calculateBoundsFromNestedArrayOfArrays(geojson.coordinates);\r\n\r\n case 'Feature':\r\n return geojson.geometry? calculateBounds(geojson.geometry) : null;\r\n\r\n case 'FeatureCollection':\r\n return calculateBoundsForFeatureCollection(geojson);\r\n\r\n case 'GeometryCollection':\r\n return calculateBoundsForGeometryCollection(geojson);\r\n\r\n default:\r\n throw new Error(\"Unknown type: \" + geojson.type);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /*\r\n Internal: Calculate an bounding box from an nested array of positions\r\n [\r\n [\r\n [ [lng, lat],[lng, lat],[lng, lat] ]\r\n ]\r\n [\r\n [lng, lat],[lng, lat],[lng, lat]\r\n ]\r\n [\r\n [lng, lat],[lng, lat],[lng, lat]\r\n ]\r\n ]\r\n */\r\n function calculateBoundsFromNestedArrays (array) {\r\n var x1 = null, x2 = null, y1 = null, y2 = null;\r\n\r\n for (var i = 0; i < array.length; i++) {\r\n var inner = array[i];\r\n\r\n for (var j = 0; j < inner.length; j++) {\r\n var lonlat = inner[j];\r\n\r\n var lon = lonlat[0];\r\n var lat = lonlat[1];\r\n\r\n if (x1 === null) {\r\n x1 = lon;\r\n } else if (lon < x1) {\r\n x1 = lon;\r\n }\r\n\r\n if (x2 === null) {\r\n x2 = lon;\r\n } else if (lon > x2) {\r\n x2 = lon;\r\n }\r\n\r\n if (y1 === null) {\r\n y1 = lat;\r\n } else if (lat < y1) {\r\n y1 = lat;\r\n }\r\n\r\n if (y2 === null) {\r\n y2 = lat;\r\n } else if (lat > y2) {\r\n y2 = lat;\r\n }\r\n }\r\n }\r\n\r\n return [x1, y1, x2, y2 ];\r\n }\r\n\r\n /*\r\n Internal: Calculate a bounding box from an array of arrays of arrays\r\n [\r\n [ [lng, lat],[lng, lat],[lng, lat] ]\r\n [ [lng, lat],[lng, lat],[lng, lat] ]\r\n [ [lng, lat],[lng, lat],[lng, lat] ]\r\n ]\r\n */\r\n function calculateBoundsFromNestedArrayOfArrays (array) {\r\n var x1 = null, x2 = null, y1 = null, y2 = null;\r\n\r\n for (var i = 0; i < array.length; i++) {\r\n var inner = array[i];\r\n\r\n for (var j = 0; j < inner.length; j++) {\r\n var innerinner = inner[j];\r\n for (var k = 0; k < innerinner.length; k++) {\r\n var lonlat = innerinner[k];\r\n\r\n var lon = lonlat[0];\r\n var lat = lonlat[1];\r\n\r\n if (x1 === null) {\r\n x1 = lon;\r\n } else if (lon < x1) {\r\n x1 = lon;\r\n }\r\n\r\n if (x2 === null) {\r\n x2 = lon;\r\n } else if (lon > x2) {\r\n x2 = lon;\r\n }\r\n\r\n if (y1 === null) {\r\n y1 = lat;\r\n } else if (lat < y1) {\r\n y1 = lat;\r\n }\r\n\r\n if (y2 === null) {\r\n y2 = lat;\r\n } else if (lat > y2) {\r\n y2 = lat;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return [x1, y1, x2, y2];\r\n }\r\n\r\n /*\r\n Internal: Calculate a bounding box from an array of positions\r\n [\r\n [lng, lat],[lng, lat],[lng, lat]\r\n ]\r\n */\r\n function calculateBoundsFromArray (array) {\r\n var x1 = null, x2 = null, y1 = null, y2 = null;\r\n\r\n for (var i = 0; i < array.length; i++) {\r\n var lonlat = array[i];\r\n var lon = lonlat[0];\r\n var lat = lonlat[1];\r\n\r\n if (x1 === null) {\r\n x1 = lon;\r\n } else if (lon < x1) {\r\n x1 = lon;\r\n }\r\n\r\n if (x2 === null) {\r\n x2 = lon;\r\n } else if (lon > x2) {\r\n x2 = lon;\r\n }\r\n\r\n if (y1 === null) {\r\n y1 = lat;\r\n } else if (lat < y1) {\r\n y1 = lat;\r\n }\r\n\r\n if (y2 === null) {\r\n y2 = lat;\r\n } else if (lat > y2) {\r\n y2 = lat;\r\n }\r\n }\r\n\r\n return [x1, y1, x2, y2 ];\r\n }\r\n\r\n /*\r\n Internal: Calculate an bounding box for a feature collection\r\n */\r\n function calculateBoundsForFeatureCollection(featureCollection){\r\n var extents = [], extent;\r\n for (var i = featureCollection.features.length - 1; i >= 0; i--) {\r\n extent = calculateBounds(featureCollection.features[i].geometry);\r\n extents.push([extent[0],extent[1]]);\r\n extents.push([extent[2],extent[3]]);\r\n }\r\n\r\n return calculateBoundsFromArray(extents);\r\n }\r\n\r\n /*\r\n Internal: Calculate an bounding box for a geometry collection\r\n */\r\n function calculateBoundsForGeometryCollection(geometryCollection){\r\n var extents = [], extent;\r\n\r\n for (var i = geometryCollection.geometries.length - 1; i >= 0; i--) {\r\n extent = calculateBounds(geometryCollection.geometries[i]);\r\n extents.push([extent[0],extent[1]]);\r\n extents.push([extent[2],extent[3]]);\r\n }\r\n\r\n return calculateBoundsFromArray(extents);\r\n }\r\n\r\n function calculateEnvelope(geojson){\r\n var bounds = calculateBounds(geojson);\r\n return {\r\n x: bounds[0],\r\n y: bounds[1],\r\n w: Math.abs(bounds[0] - bounds[2]),\r\n h: Math.abs(bounds[1] - bounds[3])\r\n };\r\n }\r\n\r\n /*\r\n Internal: Convert radians to degrees. Used by spatial reference converters.\r\n */\r\n function radToDeg(rad) {\r\n return rad * DegreesPerRadian;\r\n }\r\n\r\n /*\r\n Internal: Convert degrees to radians. Used by spatial reference converters.\r\n */\r\n function degToRad(deg) {\r\n return deg * RadiansPerDegree;\r\n }\r\n\r\n /*\r\n Internal: Loop over each array in a geojson object and apply a function to it. Used by spatial reference converters.\r\n */\r\n function eachPosition(coordinates, func) {\r\n for (var i = 0; i < coordinates.length; i++) {\r\n // we found a number so lets convert this pair\r\n if(typeof coordinates[i][0] === \"number\"){\r\n coordinates[i] = func(coordinates[i]);\r\n }\r\n // we found an coordinates array it again and run THIS function against it\r\n if(typeof coordinates[i] === \"object\"){\r\n coordinates[i] = eachPosition(coordinates[i], func);\r\n }\r\n }\r\n return coordinates;\r\n }\r\n\r\n /*\r\n Public: Convert a GeoJSON Position object to Geographic (4326)\r\n */\r\n function positionToGeographic(position) {\r\n var x = position[0];\r\n var y = position[1];\r\n return [radToDeg(x / EarthRadius) - (Math.floor((radToDeg(x / EarthRadius) + 180) / 360) * 360), radToDeg((Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * y / EarthRadius))))];\r\n }\r\n\r\n /*\r\n Public: Convert a GeoJSON Position object to Web Mercator (102100)\r\n */\r\n function positionToMercator(position) {\r\n var lng = position[0];\r\n var lat = Math.max(Math.min(position[1], 89.99999), -89.99999);\r\n return [degToRad(lng) * EarthRadius, EarthRadius/2.0 * Math.log( (1.0 + Math.sin(degToRad(lat))) / (1.0 - Math.sin(degToRad(lat))) )];\r\n }\r\n\r\n /*\r\n Public: Apply a function agaist all positions in a geojson object. Used by spatial reference converters.\r\n */\r\n function applyConverter(geojson, converter, noCrs){\r\n if(geojson.type === \"Point\") {\r\n geojson.coordinates = converter(geojson.coordinates);\r\n } else if(geojson.type === \"Feature\") {\r\n geojson.geometry = applyConverter(geojson.geometry, converter, true);\r\n } else if(geojson.type === \"FeatureCollection\") {\r\n for (var f = 0; f < geojson.features.length; f++) {\r\n geojson.features[f] = applyConverter(geojson.features[f], converter, true);\r\n }\r\n } else if(geojson.type === \"GeometryCollection\") {\r\n for (var g = 0; g < geojson.geometries.length; g++) {\r\n geojson.geometries[g] = applyConverter(geojson.geometries[g], converter, true);\r\n }\r\n } else {\r\n geojson.coordinates = eachPosition(geojson.coordinates, converter);\r\n }\r\n\r\n if(!noCrs){\r\n if(converter === positionToMercator){\r\n geojson.crs = MercatorCRS;\r\n }\r\n }\r\n\r\n if(converter === positionToGeographic){\r\n delete geojson.crs;\r\n }\r\n\r\n return geojson;\r\n }\r\n\r\n /*\r\n Public: Convert a GeoJSON object to ESRI Web Mercator (102100)\r\n */\r\n function toMercator(geojson) {\r\n return applyConverter(geojson, positionToMercator);\r\n }\r\n\r\n /*\r\n Convert a GeoJSON object to Geographic coordinates (WSG84, 4326)\r\n */\r\n function toGeographic(geojson) {\r\n return applyConverter(geojson, positionToGeographic);\r\n }\r\n\r\n\r\n /*\r\n Internal: -1,0,1 comparison function\r\n */\r\n function cmp(a, b) {\r\n if(a < b) {\r\n return -1;\r\n } else if(a > b) {\r\n return 1;\r\n } else {\r\n return 0;\r\n }\r\n }\r\n\r\n /*\r\n Internal: used for sorting\r\n */\r\n function compSort(p1, p2) {\r\n if (p1[0] > p2[0]) {\r\n return -1;\r\n } else if (p1[0] < p2[0]) {\r\n return 1;\r\n } else if (p1[1] > p2[1]) {\r\n return -1;\r\n } else if (p1[1] < p2[1]) {\r\n return 1;\r\n } else {\r\n return 0;\r\n }\r\n }\r\n\r\n\r\n /*\r\n Internal: used to determine turn\r\n */\r\n function turn(p, q, r) {\r\n // Returns -1, 0, 1 if p,q,r forms a right, straight, or left turn.\r\n return cmp((q[0] - p[0]) * (r[1] - p[1]) - (r[0] - p[0]) * (q[1] - p[1]), 0);\r\n }\r\n\r\n /*\r\n Internal: used to determine euclidean distance between two points\r\n */\r\n function euclideanDistance(p, q) {\r\n // Returns the squared Euclidean distance between p and q.\r\n var dx = q[0] - p[0];\r\n var dy = q[1] - p[1];\r\n\r\n return dx * dx + dy * dy;\r\n }\r\n\r\n function nextHullPoint(points, p) {\r\n // Returns the next point on the convex hull in CCW from p.\r\n var q = p;\r\n for(var r in points) {\r\n var t = turn(p, q, points[r]);\r\n if(t === -1 || t === 0 && euclideanDistance(p, points[r]) > euclideanDistance(p, q)) {\r\n q = points[r];\r\n }\r\n }\r\n return q;\r\n }\r\n\r\n function convexHull(points) {\r\n // implementation of the Jarvis March algorithm\r\n // adapted from http://tixxit.wordpress.com/2009/12/09/jarvis-march/\r\n\r\n if(points.length === 0) {\r\n return [];\r\n } else if(points.length === 1) {\r\n return points;\r\n }\r\n\r\n // Returns the points on the convex hull of points in CCW order.\r\n var hull = [points.sort(compSort)[0]];\r\n\r\n for(var p = 0; p < hull.length; p++) {\r\n var q = nextHullPoint(points, hull[p]);\r\n\r\n if(q !== hull[0]) {\r\n hull.push(q);\r\n }\r\n }\r\n\r\n return hull;\r\n }\r\n\r\n function isConvex(points) {\r\n var ltz;\r\n\r\n for (var i = 0; i < points.length - 3; i++) {\r\n var p1 = points[i];\r\n var p2 = points[i + 1];\r\n var p3 = points[i + 2];\r\n var v = [p2[0] - p1[0], p2[1] - p1[1]];\r\n\r\n // p3.x * v.y - p3.y * v.x + v.x * p1.y - v.y * p1.x\r\n var res = p3[0] * v[1] - p3[1] * v[0] + v[0] * p1[1] - v[1] * p1[0];\r\n\r\n if (i === 0) {\r\n if (res < 0) {\r\n ltz = true;\r\n } else {\r\n ltz = false;\r\n }\r\n } else {\r\n if (ltz && (res > 0) || !ltz && (res < 0)) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function coordinatesContainPoint(coordinates, point) {\r\n var contains = false;\r\n for(var i = -1, l = coordinates.length, j = l - 1; ++i < l; j = i) {\r\n if (((coordinates[i][1] <= point[1] && point[1] < coordinates[j][1]) ||\r\n (coordinates[j][1] <= point[1] && point[1] < coordinates[i][1])) &&\r\n (point[0] < (coordinates[j][0] - coordinates[i][0]) * (point[1] - coordinates[i][1]) / (coordinates[j][1] - coordinates[i][1]) + coordinates[i][0])) {\r\n contains = !contains;\r\n }\r\n }\r\n return contains;\r\n }\r\n\r\n function polygonContainsPoint(polygon, point) {\r\n if (polygon && polygon.length) {\r\n if (polygon.length === 1) { // polygon with no holes\r\n return coordinatesContainPoint(polygon[0], point);\r\n } else { // polygon with holes\r\n if (coordinatesContainPoint(polygon[0], point)) {\r\n for (var i = 1; i < polygon.length; i++) {\r\n if (coordinatesContainPoint(polygon[i], point)) {\r\n return false; // found in hole\r\n }\r\n }\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n function edgeIntersectsEdge(a1, a2, b1, b2) {\r\n var ua_t = (b2[0] - b1[0]) * (a1[1] - b1[1]) - (b2[1] - b1[1]) * (a1[0] - b1[0]);\r\n var ub_t = (a2[0] - a1[0]) * (a1[1] - b1[1]) - (a2[1] - a1[1]) * (a1[0] - b1[0]);\r\n var u_b = (b2[1] - b1[1]) * (a2[0] - a1[0]) - (b2[0] - b1[0]) * (a2[1] - a1[1]);\r\n\r\n if ( u_b !== 0 ) {\r\n var ua = ua_t / u_b;\r\n var ub = ub_t / u_b;\r\n\r\n if ( 0 <= ua && ua <= 1 && 0 <= ub && ub <= 1 ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n function isNumber(n) {\r\n return !isNaN(parseFloat(n)) && isFinite(n);\r\n }\r\n\r\n function arraysIntersectArrays(a, b) {\r\n if (isNumber(a[0][0])) {\r\n if (isNumber(b[0][0])) {\r\n for (var i = 0; i < a.length - 1; i++) {\r\n for (var j = 0; j < b.length - 1; j++) {\r\n if (edgeIntersectsEdge(a[i], a[i + 1], b[j], b[j + 1])) {\r\n return true;\r\n }\r\n }\r\n }\r\n } else {\r\n for (var k = 0; k < b.length; k++) {\r\n if (arraysIntersectArrays(a, b[k])) {\r\n return true;\r\n }\r\n }\r\n }\r\n } else {\r\n for (var l = 0; l < a.length; l++) {\r\n if (arraysIntersectArrays(a[l], b)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /*\r\n Internal: Returns a copy of coordinates for s closed polygon\r\n */\r\n function closedPolygon(coordinates) {\r\n var outer = [ ];\r\n\r\n for (var i = 0; i < coordinates.length; i++) {\r\n var inner = coordinates[i].slice();\r\n if (pointsEqual(inner[0], inner[inner.length - 1]) === false) {\r\n inner.push(inner[0]);\r\n }\r\n\r\n outer.push(inner);\r\n }\r\n\r\n return outer;\r\n }\r\n\r\n function pointsEqual(a, b) {\r\n for (var i = 0; i < a.length; i++) {\r\n\r\n if (a[i] !== b[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n function coordinatesEqual(a, b) {\r\n if (a.length !== b.length) {\r\n return false;\r\n }\r\n\r\n var na = a.slice().sort(compSort);\r\n var nb = b.slice().sort(compSort);\r\n\r\n for (var i = 0; i < na.length; i++) {\r\n if (na[i].length !== nb[i].length) {\r\n return false;\r\n }\r\n for (var j = 0; j < na.length; j++) {\r\n if (na[i][j] !== nb[i][j]) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /*\r\n Internal: An array of variables that will be excluded form JSON objects.\r\n */\r\n var excludeFromJSON = [\"length\"];\r\n\r\n /*\r\n Internal: Base GeoJSON Primitive\r\n */\r\n function Primitive(geojson){\r\n if(geojson){\r\n switch (geojson.type) {\r\n case 'Point':\r\n return new Point(geojson);\r\n\r\n case 'MultiPoint':\r\n return new MultiPoint(geojson);\r\n\r\n case 'LineString':\r\n return new LineString(geojson);\r\n\r\n case 'MultiLineString':\r\n return new MultiLineString(geojson);\r\n\r\n case 'Polygon':\r\n return new Polygon(geojson);\r\n\r\n case 'MultiPolygon':\r\n return new MultiPolygon(geojson);\r\n\r\n case 'Feature':\r\n return new Feature(geojson);\r\n\r\n case 'FeatureCollection':\r\n return new FeatureCollection(geojson);\r\n\r\n case 'GeometryCollection':\r\n return new GeometryCollection(geojson);\r\n\r\n default:\r\n throw new Error(\"Unknown type: \" + geojson.type);\r\n }\r\n }\r\n }\r\n\r\n Primitive.prototype.toMercator = function(){\r\n return toMercator(this);\r\n };\r\n\r\n Primitive.prototype.toGeographic = function(){\r\n return toGeographic(this);\r\n };\r\n\r\n Primitive.prototype.envelope = function(){\r\n return calculateEnvelope(this);\r\n };\r\n\r\n Primitive.prototype.bbox = function(){\r\n return calculateBounds(this);\r\n };\r\n\r\n Primitive.prototype.convexHull = function(){\r\n var coordinates = [ ], i, j;\r\n if (this.type === 'Point') {\r\n return null;\r\n } else if (this.type === 'LineString' || this.type === 'MultiPoint') {\r\n if (this.coordinates && this.coordinates.length >= 3) {\r\n coordinates = this.coordinates;\r\n } else {\r\n return null;\r\n }\r\n } else if (this.type === 'Polygon' || this.type === 'MultiLineString') {\r\n if (this.coordinates && this.coordinates.length > 0) {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n coordinates = coordinates.concat(this.coordinates[i]);\r\n }\r\n if(coordinates.length < 3){\r\n return null;\r\n }\r\n } else {\r\n return null;\r\n }\r\n } else if (this.type === 'MultiPolygon') {\r\n if (this.coordinates && this.coordinates.length > 0) {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n for (j = 0; j < this.coordinates[i].length; j++) {\r\n coordinates = coordinates.concat(this.coordinates[i][j]);\r\n }\r\n }\r\n if(coordinates.length < 3){\r\n return null;\r\n }\r\n } else {\r\n return null;\r\n }\r\n } else if(this.type === \"Feature\"){\r\n var primitive = new Primitive(this.geometry);\r\n return primitive.convexHull();\r\n }\r\n\r\n return new Polygon({\r\n type: 'Polygon',\r\n coordinates: closedPolygon([convexHull(coordinates)])\r\n });\r\n };\r\n\r\n Primitive.prototype.toJSON = function(){\r\n var obj = {};\r\n for (var key in this) {\r\n if (this.hasOwnProperty(key) && excludeFromJSON.indexOf(key) === -1) {\r\n obj[key] = this[key];\r\n }\r\n }\r\n obj.bbox = calculateBounds(this);\r\n return obj;\r\n };\r\n\r\n Primitive.prototype.contains = function(primitive){\r\n return new Primitive(primitive).within(this);\r\n };\r\n\r\n Primitive.prototype.within = function(primitive) {\r\n var coordinates, i, j, contains;\r\n\r\n // if we are passed a feature, use the polygon inside instead\r\n if (primitive.type === 'Feature') {\r\n primitive = primitive.geometry;\r\n }\r\n\r\n // point.within(point) :: equality\r\n if (primitive.type === \"Point\") {\r\n if (this.type === \"Point\") {\r\n return pointsEqual(this.coordinates, primitive.coordinates);\r\n\r\n }\r\n }\r\n\r\n // point.within(multilinestring)\r\n if (primitive.type === \"MultiLineString\") {\r\n if (this.type === \"Point\") {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n var linestring = { type: \"LineString\", coordinates: primitive.coordinates[i] };\r\n\r\n if (this.within(linestring)) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // point.within(linestring), point.within(multipoint)\r\n if (primitive.type === \"LineString\" || primitive.type === \"MultiPoint\") {\r\n if (this.type === \"Point\") {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n if (this.coordinates.length !== primitive.coordinates[i].length) {\r\n return false;\r\n }\r\n\r\n if (pointsEqual(this.coordinates, primitive.coordinates[i])) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (primitive.type === \"Polygon\") {\r\n // polygon.within(polygon)\r\n if (this.type === \"Polygon\") {\r\n // check for equal polygons\r\n if (primitive.coordinates.length === this.coordinates.length) {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n if (coordinatesEqual(this.coordinates[i], primitive.coordinates[i])) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n if (this.coordinates.length && polygonContainsPoint(primitive.coordinates, this.coordinates[0][0])) {\r\n return !arraysIntersectArrays(closedPolygon(this.coordinates), closedPolygon(primitive.coordinates));\r\n } else {\r\n return false;\r\n }\r\n\r\n // point.within(polygon)\r\n } else if (this.type === \"Point\") {\r\n return polygonContainsPoint(primitive.coordinates, this.coordinates);\r\n\r\n // linestring/multipoint withing polygon\r\n } else if (this.type === \"LineString\" || this.type === \"MultiPoint\") {\r\n if (!this.coordinates || this.coordinates.length === 0) {\r\n return false;\r\n }\r\n\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n if (polygonContainsPoint(primitive.coordinates, this.coordinates[i]) === false) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n\r\n // multilinestring.within(polygon)\r\n } else if (this.type === \"MultiLineString\") {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n var ls = new LineString(this.coordinates[i]);\r\n\r\n if (ls.within(primitive) === false) {\r\n contains++;\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n\r\n // multipolygon.within(polygon)\r\n } else if (this.type === \"MultiPolygon\") {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n var p1 = new Primitive({ type: \"Polygon\", coordinates: this.coordinates[i] });\r\n\r\n if (p1.within(primitive) === false) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n }\r\n\r\n if (primitive.type === \"MultiPolygon\") {\r\n // point.within(multipolygon)\r\n if (this.type === \"Point\") {\r\n if (primitive.coordinates.length) {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n coordinates = primitive.coordinates[i];\r\n if (polygonContainsPoint(coordinates, this.coordinates) && arraysIntersectArrays([this.coordinates], primitive.coordinates) === false) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n // polygon.within(multipolygon)\r\n } else if (this.type === \"Polygon\") {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n if (primitive.coordinates[i].length === this.coordinates.length) {\r\n for (j = 0; j < this.coordinates.length; j++) {\r\n if (coordinatesEqual(this.coordinates[j], primitive.coordinates[i][j])) {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (arraysIntersectArrays(this.coordinates, primitive.coordinates) === false) {\r\n if (primitive.coordinates.length) {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n coordinates = primitive.coordinates[i];\r\n if (polygonContainsPoint(coordinates, this.coordinates[0][0]) === false) {\r\n contains = false;\r\n } else {\r\n contains = true;\r\n }\r\n }\r\n\r\n return contains;\r\n }\r\n }\r\n\r\n // linestring.within(multipolygon), multipoint.within(multipolygon)\r\n } else if (this.type === \"LineString\" || this.type === \"MultiPoint\") {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n var p = { type: \"Polygon\", coordinates: primitive.coordinates[i] };\r\n\r\n if (this.within(p)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // multilinestring.within(multipolygon)\r\n } else if (this.type === \"MultiLineString\") {\r\n for (i = 0; i < this.coordinates.length; i++) {\r\n var lines = new LineString(this.coordinates[i]);\r\n\r\n if (lines.within(primitive) === false) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n\r\n // multipolygon.within(multipolygon)\r\n } else if (this.type === \"MultiPolygon\") {\r\n for (i = 0; i < primitive.coordinates.length; i++) {\r\n var mpoly = { type: \"Polygon\", coordinates: primitive.coordinates[i] };\r\n\r\n if (this.within(mpoly) === false) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n }\r\n\r\n // default to false\r\n return false;\r\n };\r\n\r\n Primitive.prototype.intersects = function(primitive) {\r\n // if we are passed a feature, use the polygon inside instead\r\n if (primitive.type === 'Feature') {\r\n primitive = primitive.geometry;\r\n }\r\n\r\n var p = new Primitive(primitive);\r\n if (this.within(primitive) || p.within(this)) {\r\n return true;\r\n }\r\n\r\n\r\n if (this.type !== 'Point' && this.type !== 'MultiPoint' &&\r\n primitive.type !== 'Point' && primitive.type !== 'MultiPoint') {\r\n return arraysIntersectArrays(this.coordinates, primitive.coordinates);\r\n } else if (this.type === 'Feature') {\r\n // in the case of a Feature, use the internal primitive for intersection\r\n var inner = new Primitive(this.geometry);\r\n return inner.intersects(primitive);\r\n }\r\n\r\n warn(\"Type \" + this.type + \" to \" + primitive.type + \" intersection is not supported by intersects\");\r\n return false;\r\n };\r\n\r\n\r\n /*\r\n GeoJSON Point Class\r\n new Point();\r\n new Point(x,y,z,wtf);\r\n new Point([x,y,z,wtf]);\r\n new Point([x,y]);\r\n new Point({\r\n type: \"Point\",\r\n coordinates: [x,y]\r\n });\r\n */\r\n function Point(input){\r\n var args = Array.prototype.slice.call(arguments);\r\n\r\n if(input && input.type === \"Point\" && input.coordinates){\r\n extend(this, input);\r\n } else if(input && isArray(input)) {\r\n this.coordinates = input;\r\n } else if(args.length >= 2) {\r\n this.coordinates = args;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.Point\";\r\n }\r\n\r\n this.type = \"Point\";\r\n }\r\n\r\n Point.prototype = new Primitive();\r\n Point.prototype.constructor = Point;\r\n\r\n /*\r\n GeoJSON MultiPoint Class\r\n new MultiPoint();\r\n new MultiPoint([[x,y], [x1,y1]]);\r\n new MultiPoint({\r\n type: \"MultiPoint\",\r\n coordinates: [x,y]\r\n });\r\n */\r\n function MultiPoint(input){\r\n if(input && input.type === \"MultiPoint\" && input.coordinates){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.coordinates = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.MultiPoint\";\r\n }\r\n\r\n this.type = \"MultiPoint\";\r\n }\r\n\r\n MultiPoint.prototype = new Primitive();\r\n MultiPoint.prototype.constructor = MultiPoint;\r\n MultiPoint.prototype.forEach = function(func){\r\n for (var i = 0; i < this.coordinates.length; i++) {\r\n func.apply(this, [this.coordinates[i], i, this.coordinates]);\r\n }\r\n return this;\r\n };\r\n MultiPoint.prototype.addPoint = function(point){\r\n this.coordinates.push(point);\r\n return this;\r\n };\r\n MultiPoint.prototype.insertPoint = function(point, index){\r\n this.coordinates.splice(index, 0, point);\r\n return this;\r\n };\r\n MultiPoint.prototype.removePoint = function(remove){\r\n if(typeof remove === \"number\"){\r\n this.coordinates.splice(remove, 1);\r\n } else {\r\n this.coordinates.splice(this.coordinates.indexOf(remove), 1);\r\n }\r\n return this;\r\n };\r\n MultiPoint.prototype.get = function(i){\r\n return new Point(this.coordinates[i]);\r\n };\r\n\r\n /*\r\n GeoJSON LineString Class\r\n new LineString();\r\n new LineString([[x,y], [x1,y1]]);\r\n new LineString({\r\n type: \"LineString\",\r\n coordinates: [x,y]\r\n });\r\n */\r\n function LineString(input){\r\n if(input && input.type === \"LineString\" && input.coordinates){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.coordinates = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.LineString\";\r\n }\r\n\r\n this.type = \"LineString\";\r\n }\r\n\r\n LineString.prototype = new Primitive();\r\n LineString.prototype.constructor = LineString;\r\n LineString.prototype.addVertex = function(point){\r\n this.coordinates.push(point);\r\n return this;\r\n };\r\n LineString.prototype.insertVertex = function(point, index){\r\n this.coordinates.splice(index, 0, point);\r\n return this;\r\n };\r\n LineString.prototype.removeVertex = function(remove){\r\n this.coordinates.splice(remove, 1);\r\n return this;\r\n };\r\n\r\n /*\r\n GeoJSON MultiLineString Class\r\n new MultiLineString();\r\n new MultiLineString([ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ]);\r\n new MultiLineString({\r\n type: \"MultiLineString\",\r\n coordinates: [ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ]\r\n });\r\n */\r\n function MultiLineString(input){\r\n if(input && input.type === \"MultiLineString\" && input.coordinates){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.coordinates = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.MultiLineString\";\r\n }\r\n\r\n this.type = \"MultiLineString\";\r\n }\r\n\r\n MultiLineString.prototype = new Primitive();\r\n MultiLineString.prototype.constructor = MultiLineString;\r\n MultiLineString.prototype.forEach = function(func){\r\n for (var i = 0; i < this.coordinates.length; i++) {\r\n func.apply(this, [this.coordinates[i], i, this.coordinates ]);\r\n }\r\n };\r\n MultiLineString.prototype.get = function(i){\r\n return new LineString(this.coordinates[i]);\r\n };\r\n\r\n /*\r\n GeoJSON Polygon Class\r\n new Polygon();\r\n new Polygon([ [[x,y], [x1,y1], [x2,y2]] ]);\r\n new Polygon({\r\n type: \"Polygon\",\r\n coordinates: [ [[x,y], [x1,y1], [x2,y2]] ]\r\n });\r\n */\r\n function Polygon(input){\r\n if(input && input.type === \"Polygon\" && input.coordinates){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.coordinates = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.Polygon\";\r\n }\r\n\r\n this.type = \"Polygon\";\r\n }\r\n\r\n Polygon.prototype = new Primitive();\r\n Polygon.prototype.constructor = Polygon;\r\n Polygon.prototype.addVertex = function(point){\r\n this.insertVertex(point, this.coordinates[0].length - 1);\r\n return this;\r\n };\r\n Polygon.prototype.insertVertex = function(point, index){\r\n this.coordinates[0].splice(index, 0, point);\r\n return this;\r\n };\r\n Polygon.prototype.removeVertex = function(remove){\r\n this.coordinates[0].splice(remove, 1);\r\n return this;\r\n };\r\n Polygon.prototype.close = function() {\r\n this.coordinates = closedPolygon(this.coordinates);\r\n };\r\n Polygon.prototype.hasHoles = function() {\r\n return this.coordinates.length > 1;\r\n };\r\n Polygon.prototype.holes = function() {\r\n var holes = [];\r\n if (this.hasHoles()) {\r\n for (var i = 1; i < this.coordinates.length; i++) {\r\n holes.push(new Polygon([this.coordinates[i]]));\r\n }\r\n }\r\n return holes;\r\n };\r\n\r\n /*\r\n GeoJSON MultiPolygon Class\r\n new MultiPolygon();\r\n new MultiPolygon([ [ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ] ]);\r\n new MultiPolygon({\r\n type: \"MultiPolygon\",\r\n coordinates: [ [ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ] ]\r\n });\r\n */\r\n function MultiPolygon(input){\r\n if(input && input.type === \"MultiPolygon\" && input.coordinates){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.coordinates = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.MultiPolygon\";\r\n }\r\n\r\n this.type = \"MultiPolygon\";\r\n }\r\n\r\n MultiPolygon.prototype = new Primitive();\r\n MultiPolygon.prototype.constructor = MultiPolygon;\r\n MultiPolygon.prototype.forEach = function(func){\r\n for (var i = 0; i < this.coordinates.length; i++) {\r\n func.apply(this, [this.coordinates[i], i, this.coordinates ]);\r\n }\r\n };\r\n MultiPolygon.prototype.get = function(i){\r\n return new Polygon(this.coordinates[i]);\r\n };\r\n MultiPolygon.prototype.close = function(){\r\n var outer = [];\r\n this.forEach(function(polygon){\r\n outer.push(closedPolygon(polygon));\r\n });\r\n this.coordinates = outer;\r\n return this;\r\n };\r\n\r\n /*\r\n GeoJSON Feature Class\r\n new Feature();\r\n new Feature({\r\n type: \"Feature\",\r\n geometry: {\r\n type: \"Polygon\",\r\n coordinates: [ [ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ] ]\r\n }\r\n });\r\n new Feature({\r\n type: \"Polygon\",\r\n coordinates: [ [ [[x,y], [x1,y1]], [[x2,y2], [x3,y3]] ] ]\r\n });\r\n */\r\n function Feature(input){\r\n if(input && input.type === \"Feature\"){\r\n extend(this, input);\r\n } else if(input && input.type && input.coordinates) {\r\n this.geometry = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.Feature\";\r\n }\r\n\r\n this.type = \"Feature\";\r\n }\r\n\r\n Feature.prototype = new Primitive();\r\n Feature.prototype.constructor = Feature;\r\n\r\n /*\r\n GeoJSON FeatureCollection Class\r\n new FeatureCollection();\r\n new FeatureCollection([feature, feature1]);\r\n new FeatureCollection({\r\n type: \"FeatureCollection\",\r\n coordinates: [feature, feature1]\r\n });\r\n */\r\n function FeatureCollection(input){\r\n if(input && input.type === \"FeatureCollection\" && input.features){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.features = input;\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.FeatureCollection\";\r\n }\r\n\r\n this.type = \"FeatureCollection\";\r\n }\r\n\r\n FeatureCollection.prototype = new Primitive();\r\n FeatureCollection.prototype.constructor = FeatureCollection;\r\n FeatureCollection.prototype.forEach = function(func){\r\n for (var i = 0; i < this.features.length; i++) {\r\n func.apply(this, [this.features[i], i, this.features]);\r\n }\r\n };\r\n FeatureCollection.prototype.get = function(id){\r\n var found;\r\n this.forEach(function(feature){\r\n if(feature.id === id){\r\n found = feature;\r\n }\r\n });\r\n return new Feature(found);\r\n };\r\n\r\n /*\r\n GeoJSON GeometryCollection Class\r\n new GeometryCollection();\r\n new GeometryCollection([geometry, geometry1]);\r\n new GeometryCollection({\r\n type: \"GeometryCollection\",\r\n coordinates: [geometry, geometry1]\r\n });\r\n */\r\n function GeometryCollection(input){\r\n if(input && input.type === \"GeometryCollection\" && input.geometries){\r\n extend(this, input);\r\n } else if(isArray(input)) {\r\n this.geometries = input;\r\n } else if(input.coordinates && input.type){\r\n this.type = \"GeometryCollection\";\r\n this.geometries = [input];\r\n } else {\r\n throw \"Terraformer: invalid input for Terraformer.GeometryCollection\";\r\n }\r\n\r\n this.type = \"GeometryCollection\";\r\n }\r\n\r\n GeometryCollection.prototype = new Primitive();\r\n GeometryCollection.prototype.constructor = GeometryCollection;\r\n GeometryCollection.prototype.forEach = function(func){\r\n for (var i = 0; i < this.geometries.length; i++) {\r\n func.apply(this, [this.geometries[i], i, this.geometries]);\r\n }\r\n };\r\n GeometryCollection.prototype.get = function(i){\r\n return new Primitive(this.geometries[i]);\r\n };\r\n\r\n function createCircle(center, radius, interpolate){\r\n var mercatorPosition = positionToMercator(center);\r\n var steps = interpolate || 64;\r\n var polygon = {\r\n type: \"Polygon\",\r\n coordinates: [[]]\r\n };\r\n for(var i=1; i<=steps; i++) {\r\n var radians = i * (360/steps) * Math.PI / 180;\r\n polygon.coordinates[0].push([mercatorPosition[0] + radius * Math.cos(radians), mercatorPosition[1] + radius * Math.sin(radians)]);\r\n }\r\n polygon.coordinates = closedPolygon(polygon.coordinates);\r\n\r\n return toGeographic(polygon);\r\n }\r\n\r\n function Circle (center, radius, interpolate) {\r\n var steps = interpolate || 64;\r\n var rad = radius || 250;\r\n\r\n if(!center || center.length < 2 || !rad || !steps) {\r\n throw new Error(\"Terraformer: missing parameter for Terraformer.Circle\");\r\n }\r\n\r\n extend(this, new Feature({\r\n type: \"Feature\",\r\n geometry: createCircle(center, rad, steps),\r\n properties: {\r\n radius: rad,\r\n center: center,\r\n steps: steps\r\n }\r\n }));\r\n }\r\n\r\n Circle.prototype = new Primitive();\r\n Circle.prototype.constructor = Circle;\r\n Circle.prototype.recalculate = function(){\r\n this.geometry = createCircle(this.properties.center, this.properties.radius, this.properties.steps);\r\n return this;\r\n };\r\n Circle.prototype.center = function(coordinates){\r\n if(coordinates){\r\n this.properties.center = coordinates;\r\n this.recalculate();\r\n }\r\n return this.properties.center;\r\n };\r\n Circle.prototype.radius = function(radius){\r\n if(radius){\r\n this.properties.radius = radius;\r\n this.recalculate();\r\n }\r\n return this.properties.radius;\r\n };\r\n Circle.prototype.steps = function(steps){\r\n if(steps){\r\n this.properties.steps = steps;\r\n this.recalculate();\r\n }\r\n return this.properties.steps;\r\n };\r\n\r\n Circle.prototype.toJSON = function() {\r\n var output = Primitive.prototype.toJSON.call(this);\r\n return output;\r\n };\r\n\r\n exports.Primitive = Primitive;\r\n exports.Point = Point;\r\n exports.MultiPoint = MultiPoint;\r\n exports.LineString = LineString;\r\n exports.MultiLineString = MultiLineString;\r\n exports.Polygon = Polygon;\r\n exports.MultiPolygon = MultiPolygon;\r\n exports.Feature = Feature;\r\n exports.FeatureCollection = FeatureCollection;\r\n exports.GeometryCollection = GeometryCollection;\r\n exports.Circle = Circle;\r\n\r\n exports.toMercator = toMercator;\r\n exports.toGeographic = toGeographic;\r\n\r\n exports.Tools = {};\r\n exports.Tools.positionToMercator = positionToMercator;\r\n exports.Tools.positionToGeographic = positionToGeographic;\r\n exports.Tools.applyConverter = applyConverter;\r\n exports.Tools.toMercator = toMercator;\r\n exports.Tools.toGeographic = toGeographic;\r\n exports.Tools.createCircle = createCircle;\r\n\r\n exports.Tools.calculateBounds = calculateBounds;\r\n exports.Tools.calculateEnvelope = calculateEnvelope;\r\n\r\n exports.Tools.coordinatesContainPoint = coordinatesContainPoint;\r\n exports.Tools.polygonContainsPoint = polygonContainsPoint;\r\n exports.Tools.arraysIntersectArrays = arraysIntersectArrays;\r\n exports.Tools.coordinatesContainPoint = coordinatesContainPoint;\r\n exports.Tools.coordinatesEqual = coordinatesEqual;\r\n exports.Tools.convexHull = convexHull;\r\n exports.Tools.isConvex = isConvex;\r\n\r\n exports.MercatorCRS = MercatorCRS;\r\n exports.GeographicCRS = GeographicCRS;\r\n\r\n return exports;\r\n}));\r\n" |
|
] |
|
} |