From 5841fd87a40bc543cc8d2845c48270083814eec2 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Fri, 19 Apr 2013 20:16:43 +0300 Subject: [PATCH 1/3] convert geojson-converted layers back to features --- src/layer/GeoJSON.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index 0fc1e1a8..1f90628e 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -158,24 +158,28 @@ L.extend(L.GeoJSON, { } return coords; + }, + + getFeature: function (layer, newGeometry) { + return layer.feature ? L.extend(layer.feature, {geometry: newGeometry}) : newGeometry; } }); L.Marker.include({ toGeoJSON: function () { - return { + return L.GeoJSON.getFeature(this, { type: 'Point', coordinates: L.GeoJSON.latLngToCoords(this.getLatLng()) - }; + }); } }); L.Polyline.include({ toGeoJSON: function () { - return { + return L.GeoJSON.getFeature(this, { type: 'LineString', coordinates: L.GeoJSON.latLngsToCoords(this.getLatLngs()) - }; + }); } }); @@ -194,10 +198,10 @@ L.Polygon.include({ } } - return { + return L.GeoJSON.getFeature(this, { type: 'Polygon', coordinates: coords - }; + }); } }); @@ -211,10 +215,10 @@ L.Polygon.include({ coords.push(layer.toGeoJSON().coordinates); }); - return { + return L.GeoJSON.getFeature(this, { type: type, coordinates: coords - }; + }); } }); } @@ -233,10 +237,10 @@ L.LayerGroup.include({ } }); - return { + return L.GeoJSON.getFeature(this, { type: 'GeometryCollection', geometries: geoms - }; + }); } }); From d57525ec5298c00a788eaad346903079c771ef6d Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 24 Jun 2013 14:14:12 -0400 Subject: [PATCH 2/3] Don't overwrite layer.feature.geometry --- src/layer/GeoJSON.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index 1f90628e..ba61fef2 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -161,7 +161,7 @@ L.extend(L.GeoJSON, { }, getFeature: function (layer, newGeometry) { - return layer.feature ? L.extend(layer.feature, {geometry: newGeometry}) : newGeometry; + return layer.feature ? L.extend({}, layer.feature, {geometry: newGeometry}) : newGeometry; } }); From e7d0fb1b377cee309adfbfcfc5008a1ab716645e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 24 Jun 2013 13:52:05 -0400 Subject: [PATCH 3/3] Normalize all toGeoJSON output to Features --- spec/suites/layer/GeoJSONSpec.js | 70 +++++++++++++++++++++++++++----- src/layer/GeoJSON.js | 30 ++++++++++---- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/spec/suites/layer/GeoJSONSpec.js b/spec/suites/layer/GeoJSONSpec.js index 36428200..84c9cf6a 100644 --- a/spec/suites/layer/GeoJSONSpec.js +++ b/spec/suites/layer/GeoJSONSpec.js @@ -1,7 +1,31 @@ +describe("L.GeoJSON", function () { + describe("addData", function () { + var geoJSON = { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [20, 10] + } + }; + + it("sets feature property on member layers", function () { + var layer = new L.GeoJSON(); + layer.addData(geoJSON); + expect(layer.getLayers()[0].feature).to.eql(geoJSON); + }); + + it("normalizes a geometry to a Feature", function () { + var layer = new L.GeoJSON(); + layer.addData(geoJSON.geometry); + expect(layer.getLayers()[0].feature).to.eql(geoJSON); + }); + }); +}); + describe("L.Marker#toGeoJSON", function () { it("returns a Point object", function () { var marker = new L.Marker([10, 20]); - expect(marker.toGeoJSON()).to.eql({ + expect(marker.toGeoJSON().geometry).to.eql({ type: 'Point', coordinates: [20, 10] }); @@ -11,7 +35,7 @@ describe("L.Marker#toGeoJSON", function () { describe("L.Polyline#toGeoJSON", function () { it("returns a LineString object", function () { var polyline = new L.Polyline([[10, 20], [2, 5]]); - expect(polyline.toGeoJSON()).to.eql({ + expect(polyline.toGeoJSON().geometry).to.eql({ type: 'LineString', coordinates: [[20, 10], [5, 2]] }); @@ -21,7 +45,7 @@ describe("L.Polyline#toGeoJSON", function () { 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()).to.eql({ + expect(multiPolyline.toGeoJSON().geometry).to.eql({ type: 'MultiLineString', coordinates: [ [[20, 10], [5, 2]], @@ -34,7 +58,7 @@ describe("L.MultiPolyline#toGeoJSON", function () { 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()).to.eql({ + expect(polygon.toGeoJSON().geometry).to.eql({ type: 'Polygon', coordinates: [[[2, 1], [4, 3], [6, 5], [2, 1]]] }); @@ -42,7 +66,7 @@ describe("L.Polygon#toGeoJSON", function () { 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()).to.eql({ + expect(polygon.toGeoJSON().geometry).to.eql({ type: 'Polygon', coordinates: [ [[2, 1], [4, 3], [6, 5], [2, 1]], @@ -55,7 +79,7 @@ describe("L.Polygon#toGeoJSON", function () { 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()).to.eql({ + expect(multiPolygon.toGeoJSON().geometry).to.eql({ type: 'MultiPolygon', coordinates: [ [[[2, 1], [4, 3], [6, 5], [2, 1]]] @@ -65,13 +89,37 @@ describe("L.MultiPolygon#toGeoJSON", function () { }); describe("L.LayerGroup#toGeoJSON", function () { - it("returns a GeometryCollection object", function () { + it("returns a FeatureCollection 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()).to.eql({ - type: 'GeometryCollection', - geometries: [marker.toGeoJSON(), polyline.toGeoJSON()] + type: 'FeatureCollection', + features: [marker.toGeoJSON(), polyline.toGeoJSON()] + }); + }); + + it("ensures that every member is a Feature", function () { + var tileLayer = new L.TileLayer(), + layerGroup = new L.LayerGroup([tileLayer]); + + tileLayer.toGeoJSON = function () { + return { + type: 'Point', + coordinates: [20, 10] + } + }; + + expect(layerGroup.toGeoJSON()).to.eql({ + type: 'FeatureCollection', + features: [{ + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: [20, 10] + } + }] }); }); @@ -79,8 +127,8 @@ describe("L.LayerGroup#toGeoJSON", function () { var tileLayer = new L.TileLayer(), layerGroup = new L.LayerGroup([tileLayer]); expect(layerGroup.toGeoJSON()).to.eql({ - type: 'GeometryCollection', - geometries: [] + type: 'FeatureCollection', + features: [] }); }); }); diff --git a/src/layer/GeoJSON.js b/src/layer/GeoJSON.js index ba61fef2..3bba3e4e 100644 --- a/src/layer/GeoJSON.js +++ b/src/layer/GeoJSON.js @@ -33,7 +33,7 @@ L.GeoJSON = L.FeatureGroup.extend({ if (options.filter && !options.filter(geojson)) { return; } var layer = L.GeoJSON.geometryToLayer(geojson, options.pointToLayer, options.coordsToLatLng); - layer.feature = geojson; + layer.feature = L.GeoJSON.asFeature(geojson); layer.defaultOptions = layer.options; this.resetStyle(layer); @@ -161,7 +161,19 @@ L.extend(L.GeoJSON, { }, getFeature: function (layer, newGeometry) { - return layer.feature ? L.extend({}, layer.feature, {geometry: newGeometry}) : newGeometry; + return layer.feature ? L.extend({}, layer.feature, {geometry: newGeometry}) : L.GeoJSON.asFeature(newGeometry); + }, + + asFeature: function (geoJSON) { + if (geoJSON.type === 'Feature') { + return geoJSON; + } + + return { + type: 'Feature', + properties: {}, + geometry: geoJSON + }; } }); @@ -212,7 +224,7 @@ L.Polygon.include({ var coords = []; this.eachLayer(function (layer) { - coords.push(layer.toGeoJSON().coordinates); + coords.push(layer.toGeoJSON().geometry.coordinates); }); return L.GeoJSON.getFeature(this, { @@ -229,18 +241,18 @@ L.Polygon.include({ L.LayerGroup.include({ toGeoJSON: function () { - var geoms = []; + var features = []; this.eachLayer(function (layer) { if (layer.toGeoJSON) { - geoms.push(layer.toGeoJSON()); + features.push(L.GeoJSON.asFeature(layer.toGeoJSON())); } }); - return L.GeoJSON.getFeature(this, { - type: 'GeometryCollection', - geometries: geoms - }); + return { + type: 'FeatureCollection', + features: features + }; } });