From 55edd44678509e85fa266d515fc8d80756541f7b Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 26 Feb 2013 14:54:58 -0800 Subject: [PATCH] Add #toGeoJSON to various layer types (#712) --- spec/index.html | 1 + spec/suites/layer/GeoJSONSpec.js | 86 ++++++++++++++++++++++++++++ src/layer/GeoJSON.js | 96 ++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 spec/suites/layer/GeoJSONSpec.js diff --git a/spec/index.html b/spec/index.html index ff017363..966147ba 100644 --- a/spec/index.html +++ b/spec/index.html @@ -56,6 +56,7 @@ + diff --git a/spec/suites/layer/GeoJSONSpec.js b/spec/suites/layer/GeoJSONSpec.js new file mode 100644 index 00000000..e2030da0 --- /dev/null +++ b/spec/suites/layer/GeoJSONSpec.js @@ -0,0 +1,86 @@ +describe("L.Marker#toGeoJSON", function () { + it("returns a Point object", function () { + var marker = new L.Marker([10, 20]); + expect(marker.toGeoJSON()).toEqual({ + type: 'Point', + coordinates: [20, 10] + }); + }); +}); + +describe("L.Polyline#toGeoJSON", function () { + it("returns a LineString object", function () { + var polyline = new L.Polyline([[10, 20], [2, 5]]); + expect(polyline.toGeoJSON()).toEqual({ + type: 'LineString', + coordinates: [[20, 10], [5, 2]] + }); + }); +}); + +describe("L.MultiPolyline#toGeoJSON", function () { + it("returns a MultiLineString object", function () { + var multiPolyline = new L.MultiPolyline([[[10, 20], [2, 5]], [[1, 2], [3, 4]]]); + expect(multiPolyline.toGeoJSON()).toEqual({ + type: 'MultiLineString', + coordinates: [ + [[20, 10], [5, 2]], + [[2, 1], [4, 3]] + ] + }); + }); +}); + +describe("L.Polygon#toGeoJSON", function () { + it("returns a Polygon object (no holes)", function () { + var polygon = new L.Polygon([[1, 2], [3, 4], [5, 6]]); + expect(polygon.toGeoJSON()).toEqual({ + type: 'Polygon', + coordinates: [[[2, 1], [4, 3], [6, 5], [2, 1]]] + }); + }); + + it("returns a Polygon object (with holes)", function () { + var polygon = new L.Polygon([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]); + expect(polygon.toGeoJSON()).toEqual({ + type: 'Polygon', + coordinates: [ + [[2, 1], [4, 3], [6, 5], [2, 1]], + [[8, 7], [10, 9], [12, 11], [8, 7]] + ] + }); + }); +}); + +describe("L.MultiPolygon#toGeoJSON", function () { + it("returns a MultiPolygon object", function () { + var multiPolygon = new L.MultiPolygon([[[1, 2], [3, 4], [5, 6]]]); + expect(multiPolygon.toGeoJSON()).toEqual({ + type: 'MultiPolygon', + coordinates: [ + [[[2, 1], [4, 3], [6, 5], [2, 1]]] + ] + }); + }); +}); + +describe("L.LayerGroup#toGeoJSON", function () { + it("returns a GeometryCollection object", function () { + var marker = new L.Marker([10, 20]), + polyline = new L.Polyline([[10, 20], [2, 5]]), + layerGroup = new L.LayerGroup([marker, polyline]); + expect(layerGroup.toGeoJSON()).toEqual({ + type: 'GeometryCollection', + geometries: [marker.toGeoJSON(), polyline.toGeoJSON()] + }); + }); + + it("omits layers which do not implement toGeoJSON", function () { + var tileLayer = new L.TileLayer(), + layerGroup = new L.LayerGroup([tileLayer]); + expect(layerGroup.toGeoJSON()).toEqual({ + type: 'GeometryCollection', + geometries: [] + }); + }); +}); diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index 0a154a7e..5bed24f4 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -147,6 +147,102 @@ L.extend(L.GeoJSON, { } }); +L.extend(L.GeoJSON, { + latLngToCoords: function (latLng) { + return [latLng.lng, latLng.lat]; + }, + + latLngsToCoords: function (latLngs) { + var coords = [], + i, len; + + for (i = 0, len = latLngs.length; i < len; i++) { + coords.push(L.GeoJSON.latLngToCoords(latLngs[i])); + } + + return coords; + } +}); + +L.Marker.include({ + toGeoJSON: function () { + return { + type: 'Point', + coordinates: L.GeoJSON.latLngToCoords(this.getLatLng()) + }; + } +}); + +L.Polyline.include({ + toGeoJSON: function () { + return { + type: 'LineString', + coordinates: L.GeoJSON.latLngsToCoords(this.getLatLngs()) + }; + } +}); + +L.Polygon.include({ + toGeoJSON: function () { + var coords = [L.GeoJSON.latLngsToCoords(this.getLatLngs())], + i, len, hole; + + coords[0].push(coords[0][0]); + + if (this._holes) { + for (i = 0, len = this._holes.length; i < len; i++) { + hole = L.GeoJSON.latLngsToCoords(this._holes[i]); + hole.push(hole[0]); + coords.push(hole); + } + } + + return { + type: 'Polygon', + coordinates: coords + }; + } +}); + +(function () { + function includeMulti(Klass, type) { + Klass.include({ + toGeoJSON: function () { + var coords = []; + + this.eachLayer(function (layer) { + coords.push(layer.toGeoJSON().coordinates); + }); + + return { + type: type, + coordinates: coords + }; + } + }); + } + + includeMulti(L.MultiPolyline, 'MultiLineString'); + includeMulti(L.MultiPolygon, 'MultiPolygon'); +}()); + +L.LayerGroup.include({ + toGeoJSON: function () { + var geoms = []; + + this.eachLayer(function (layer) { + if (layer.toGeoJSON) { + geoms.push(layer.toGeoJSON()); + } + }); + + return { + type: 'GeometryCollection', + geometries: geoms + }; + } +}); + L.geoJson = function (geojson, options) { return new L.GeoJSON(geojson, options); };