fix GeoJSON roundtripping
This commit is contained in:
parent
87bf1ff144
commit
dc5151b81a
@ -147,7 +147,7 @@ var deps = {
|
|||||||
|
|
||||||
GeoJSON: {
|
GeoJSON: {
|
||||||
src: ['layer/GeoJSON.js'],
|
src: ['layer/GeoJSON.js'],
|
||||||
deps: ['Polygon', 'Circle', 'Marker', 'FeatureGroup'],
|
deps: ['Polygon', 'Circle', 'CircleMarker', 'Marker', 'FeatureGroup'],
|
||||||
desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
var circle = L.circle([35, 0], 700000, {color: 'green', renderer: canvas}).addTo(map).bindPopup('Hello Circle');
|
var circle = L.circle([35, 0], 700000, {color: 'green', renderer: canvas}).addTo(map).bindPopup('Hello Circle');
|
||||||
|
|
||||||
map.fitBounds(path);
|
map.setView([36, 52], 3);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -95,9 +95,9 @@ describe("L.Polyline#toGeoJSON", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("L.MultiPolyline#toGeoJSON", function () {
|
describe("L.Polyline (multi) #toGeoJSON", function () {
|
||||||
it("returns a 2D MultiLineString object", function () {
|
it("returns a 2D MultiLineString object", function () {
|
||||||
var multiPolyline = new L.MultiPolyline([[[10, 20], [2, 5]], [[1, 2], [3, 4]]]);
|
var multiPolyline = new L.Polyline([[[10, 20], [2, 5]], [[1, 2], [3, 4]]]);
|
||||||
expect(multiPolyline.toGeoJSON().geometry).to.eql({
|
expect(multiPolyline.toGeoJSON().geometry).to.eql({
|
||||||
type: 'MultiLineString',
|
type: 'MultiLineString',
|
||||||
coordinates: [
|
coordinates: [
|
||||||
@ -108,7 +108,7 @@ describe("L.MultiPolyline#toGeoJSON", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns a 3D MultiLineString object", function () {
|
it("returns a 3D MultiLineString object", function () {
|
||||||
var multiPolyline = new L.MultiPolyline([[[10, 20, 30], [2, 5, 10]], [[1, 2, 3], [4, 5, 6]]]);
|
var multiPolyline = new L.Polyline([[[10, 20, 30], [2, 5, 10]], [[1, 2, 3], [4, 5, 6]]]);
|
||||||
expect(multiPolyline.toGeoJSON().geometry).to.eql({
|
expect(multiPolyline.toGeoJSON().geometry).to.eql({
|
||||||
type: 'MultiLineString',
|
type: 'MultiLineString',
|
||||||
coordinates: [
|
coordinates: [
|
||||||
@ -159,9 +159,9 @@ describe("L.Polygon#toGeoJSON", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("L.MultiPolygon#toGeoJSON", function () {
|
describe("L.Polygon (multi) #toGeoJSON", function () {
|
||||||
it("returns a 2D MultiPolygon object", function () {
|
it("returns a 2D MultiPolygon object", function () {
|
||||||
var multiPolygon = new L.MultiPolygon([[[1, 2], [3, 4], [5, 6]]]);
|
var multiPolygon = new L.Polygon([[[1, 2], [3, 4], [5, 6]]]);
|
||||||
expect(multiPolygon.toGeoJSON().geometry).to.eql({
|
expect(multiPolygon.toGeoJSON().geometry).to.eql({
|
||||||
type: 'MultiPolygon',
|
type: 'MultiPolygon',
|
||||||
coordinates: [
|
coordinates: [
|
||||||
@ -171,7 +171,7 @@ describe("L.MultiPolygon#toGeoJSON", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns a 3D MultiPolygon object", function () {
|
it("returns a 3D MultiPolygon object", function () {
|
||||||
var multiPolygon = new L.MultiPolygon([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]);
|
var multiPolygon = new L.Polygon([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]);
|
||||||
expect(multiPolygon.toGeoJSON().geometry).to.eql({
|
expect(multiPolygon.toGeoJSON().geometry).to.eql({
|
||||||
type: 'MultiPolygon',
|
type: 'MultiPolygon',
|
||||||
coordinates: [
|
coordinates: [
|
||||||
|
@ -99,23 +99,14 @@ L.extend(L.GeoJSON, {
|
|||||||
return new L.FeatureGroup(layers);
|
return new L.FeatureGroup(layers);
|
||||||
|
|
||||||
case 'LineString':
|
case 'LineString':
|
||||||
latlngs = this.coordsToLatLngs(coords, 0, coordsToLatLng);
|
case 'MultiLineString':
|
||||||
|
latlngs = this.coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, coordsToLatLng);
|
||||||
return new L.Polyline(latlngs, options);
|
return new L.Polyline(latlngs, options);
|
||||||
|
|
||||||
case 'Polygon':
|
case 'Polygon':
|
||||||
if (coords.length === 2 && !coords[1].length) {
|
|
||||||
throw new Error('Invalid GeoJSON object.');
|
|
||||||
}
|
|
||||||
latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng);
|
|
||||||
return new L.Polygon(latlngs, options);
|
|
||||||
|
|
||||||
case 'MultiLineString':
|
|
||||||
latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng);
|
|
||||||
return new L.MultiPolyline(latlngs, options);
|
|
||||||
|
|
||||||
case 'MultiPolygon':
|
case 'MultiPolygon':
|
||||||
latlngs = this.coordsToLatLngs(coords, 2, coordsToLatLng);
|
latlngs = this.coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, coordsToLatLng);
|
||||||
return new L.MultiPolygon(latlngs, options);
|
return new L.Polygon(latlngs, options);
|
||||||
|
|
||||||
case 'GeometryCollection':
|
case 'GeometryCollection':
|
||||||
for (i = 0, len = geometry.geometries.length; i < len; i++) {
|
for (i = 0, len = geometry.geometries.length; i < len; i++) {
|
||||||
@ -157,11 +148,17 @@ L.extend(L.GeoJSON, {
|
|||||||
[latlng.lng, latlng.lat];
|
[latlng.lng, latlng.lat];
|
||||||
},
|
},
|
||||||
|
|
||||||
latLngsToCoords: function (latLngs) {
|
latLngsToCoords: function (latlngs, levelsDeep, closed) {
|
||||||
var coords = [];
|
var coords = [];
|
||||||
|
|
||||||
for (var i = 0, len = latLngs.length; i < len; i++) {
|
for (var i = 0, len = latlngs.length; i < len; i++) {
|
||||||
coords.push(L.GeoJSON.latLngToCoords(latLngs[i]));
|
coords.push(levelsDeep ?
|
||||||
|
L.GeoJSON.latLngsToCoords(latlngs[i], levelsDeep - 1, closed):
|
||||||
|
L.GeoJSON.latLngToCoords(latlngs[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!levelsDeep && closed) {
|
||||||
|
coords.push(coords[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return coords;
|
return coords;
|
||||||
@ -199,90 +196,83 @@ L.Marker.include(PointToGeoJSON);
|
|||||||
L.Circle.include(PointToGeoJSON);
|
L.Circle.include(PointToGeoJSON);
|
||||||
L.CircleMarker.include(PointToGeoJSON);
|
L.CircleMarker.include(PointToGeoJSON);
|
||||||
|
|
||||||
L.Polyline.include({
|
L.Polyline.prototype.toGeoJSON = function () {
|
||||||
toGeoJSON: function () {
|
var multi = !this._flat(this._latlngs);
|
||||||
return L.GeoJSON.getFeature(this, {
|
|
||||||
type: 'LineString',
|
var coords = L.GeoJSON.latLngsToCoords(this._latlngs, multi ? 1 : 0);
|
||||||
coordinates: L.GeoJSON.latLngsToCoords(this.getLatLngs())
|
|
||||||
});
|
return L.GeoJSON.getFeature(this, {
|
||||||
|
type: (multi ? 'Multi' : '') + 'LineString',
|
||||||
|
coordinates: coords
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
L.Polygon.prototype.toGeoJSON = function () {
|
||||||
|
var holes = !this._flat(this._latlngs),
|
||||||
|
multi = holes && !this._flat(this._latlngs[0]);
|
||||||
|
|
||||||
|
var coords = L.GeoJSON.latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true);
|
||||||
|
|
||||||
|
if (holes && this._latlngs.length === 1) {
|
||||||
|
multi = true;
|
||||||
|
coords = [coords];
|
||||||
|
}
|
||||||
|
if (!holes) {
|
||||||
|
coords = [coords];
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
L.Polygon.include({
|
return L.GeoJSON.getFeature(this, {
|
||||||
toGeoJSON: function () {
|
type: (multi ? 'Multi' : '') + 'Polygon',
|
||||||
var coords = [L.GeoJSON.latLngsToCoords(this.getLatLngs())],
|
coordinates: coords
|
||||||
i, len, hole;
|
});
|
||||||
|
};
|
||||||
|
|
||||||
coords[0].push(coords[0][0]);
|
|
||||||
|
|
||||||
if (this._holes) {
|
L.LayerGroup.include({
|
||||||
for (i = 0, len = this._holes.length; i < len; i++) {
|
toMultiPoint: function () {
|
||||||
hole = L.GeoJSON.latLngsToCoords(this._holes[i]);
|
var coords = [];
|
||||||
hole.push(hole[0]);
|
|
||||||
coords.push(hole);
|
this.eachLayer(function (layer) {
|
||||||
}
|
coords.push(layer.toGeoJSON().geometry.coordinates);
|
||||||
}
|
});
|
||||||
|
|
||||||
return L.GeoJSON.getFeature(this, {
|
return L.GeoJSON.getFeature(this, {
|
||||||
type: 'Polygon',
|
type: 'MultiPoint',
|
||||||
coordinates: coords
|
coordinates: coords
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
|
||||||
|
|
||||||
(function () {
|
toGeoJSON: function () {
|
||||||
function multiToGeoJSON(type) {
|
|
||||||
return function () {
|
|
||||||
var coords = [];
|
|
||||||
|
|
||||||
this.eachLayer(function (layer) {
|
var type = this.feature && this.feature.geometry && this.feature.geometry.type;
|
||||||
coords.push(layer.toGeoJSON().geometry.coordinates);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
if (type === 'MultiPoint') {
|
||||||
|
return this.toMultiPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
var isGeometryCollection = type === 'GeometryCollection',
|
||||||
|
jsons = [];
|
||||||
|
|
||||||
|
this.eachLayer(function (layer) {
|
||||||
|
if (layer.toGeoJSON) {
|
||||||
|
var json = layer.toGeoJSON();
|
||||||
|
jsons.push(isGeometryCollection ? json.geometry : L.GeoJSON.asFeature(json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isGeometryCollection) {
|
||||||
return L.GeoJSON.getFeature(this, {
|
return L.GeoJSON.getFeature(this, {
|
||||||
type: type,
|
geometries: jsons,
|
||||||
coordinates: coords
|
type: 'GeometryCollection'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: jsons
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
});
|
||||||
L.MultiPolyline.include({toGeoJSON: multiToGeoJSON('MultiLineString')});
|
|
||||||
L.MultiPolygon.include({toGeoJSON: multiToGeoJSON('MultiPolygon')});
|
|
||||||
|
|
||||||
L.LayerGroup.include({
|
|
||||||
toGeoJSON: function () {
|
|
||||||
|
|
||||||
var geometry = this.feature && this.feature.geometry,
|
|
||||||
jsons = [],
|
|
||||||
json;
|
|
||||||
|
|
||||||
if (geometry && geometry.type === 'MultiPoint') {
|
|
||||||
return multiToGeoJSON('MultiPoint').call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
var isGeometryCollection = geometry && geometry.type === 'GeometryCollection';
|
|
||||||
|
|
||||||
this.eachLayer(function (layer) {
|
|
||||||
if (layer.toGeoJSON) {
|
|
||||||
json = layer.toGeoJSON();
|
|
||||||
jsons.push(isGeometryCollection ? json.geometry : L.GeoJSON.asFeature(json));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isGeometryCollection) {
|
|
||||||
return L.GeoJSON.getFeature(this, {
|
|
||||||
geometries: jsons,
|
|
||||||
type: 'GeometryCollection'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'FeatureCollection',
|
|
||||||
features: jsons
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
|
|
||||||
L.geoJson = function (geojson, options) {
|
L.geoJson = function (geojson, options) {
|
||||||
return new L.GeoJSON(geojson, options);
|
return new L.GeoJSON(geojson, options);
|
||||||
|
@ -72,7 +72,7 @@ L.Polyline = L.Path.extend({
|
|||||||
|
|
||||||
_convertLatLngs: function (latlngs) {
|
_convertLatLngs: function (latlngs) {
|
||||||
var result = [],
|
var result = [],
|
||||||
flat = !L.Util.isArray(latlngs[0]) || typeof latlngs[0][0] === 'number';
|
flat = this._flat(latlngs);
|
||||||
|
|
||||||
for (var i = 0, len = latlngs.length; i < len; i++) {
|
for (var i = 0, len = latlngs.length; i < len; i++) {
|
||||||
result[i] = flat ? L.latLng(latlngs[i]) : this._convertLatLngs(latlngs[i]);
|
result[i] = flat ? L.latLng(latlngs[i]) : this._convertLatLngs(latlngs[i]);
|
||||||
@ -81,6 +81,10 @@ L.Polyline = L.Path.extend({
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_flat: function (latlngs) {
|
||||||
|
return !L.Util.isArray(latlngs[0]) || typeof latlngs[0][0] === 'number';
|
||||||
|
},
|
||||||
|
|
||||||
_project: function () {
|
_project: function () {
|
||||||
this._rings = [];
|
this._rings = [];
|
||||||
this._projectLatlngs(this._latlngs, this._rings);
|
this._projectLatlngs(this._latlngs, this._rings);
|
||||||
|
Loading…
Reference in New Issue
Block a user