/* * L.GeoJSON turns any GeoJSON data into a Leaflet layer. */ L.GeoJSON = L.FeatureGroup.extend({ initialize: function (geojson, options) { L.setOptions(this, options); this._layers = {}; if (geojson) { this.addData(geojson); } }, addData: function (geojson) { var features = L.Util.isArray(geojson) ? geojson : geojson.features, i, len, feature; if (features) { for (i = 0, len = features.length; i < len; i++) { // Only add this if geometry or geometries are set and not null feature = features[i]; if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { this.addData(feature); } } return this; } var options = this.options; if (options.filter && !options.filter(geojson)) { return; } var layer = L.GeoJSON.geometryToLayer(geojson, options); layer.feature = L.GeoJSON.asFeature(geojson); layer.defaultOptions = layer.options; this.resetStyle(layer); if (options.onEachFeature) { options.onEachFeature(geojson, layer); } return this.addLayer(layer); }, resetStyle: function (layer) { // reset any custom styles layer.options = layer.defaultOptions; this._setLayerStyle(layer, this.options.style); }, setStyle: function (style) { this.eachLayer(function (layer) { this._setLayerStyle(layer, style); }, this); }, _setLayerStyle: function (layer, style) { if (typeof style === 'function') { style = style(layer.feature); } if (layer.setStyle) { layer.setStyle(style); } } }); L.extend(L.GeoJSON, { geometryToLayer: function (geojson, options) { var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson, coords = geometry.coordinates, layers = [], coordsToLatLng = options.coordsToLatLng || this.coordsToLatLng, latlng, latlngs, i, len; switch (geometry.type) { case 'Point': latlng = coordsToLatLng(coords); return options.pointToLayer ? options.pointToLayer(geojson, latlng) : new L.Marker(latlng); case 'MultiPoint': for (i = 0, len = coords.length; i < len; i++) { latlng = coordsToLatLng(coords[i]); layers.push(options.pointToLayer ? options.pointToLayer(geojson, latlng) : new L.Marker(latlng)); } return new L.FeatureGroup(layers); case 'LineString': case 'MultiLineString': latlngs = this.coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, coordsToLatLng); return new L.Polyline(latlngs, options); case 'Polygon': case 'MultiPolygon': latlngs = this.coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, coordsToLatLng); return new L.Polygon(latlngs, options); case 'GeometryCollection': for (i = 0, len = geometry.geometries.length; i < len; i++) { layers.push(this.geometryToLayer({ geometry: geometry.geometries[i], type: 'Feature', properties: geojson.properties }, options)); } return new L.FeatureGroup(layers); default: throw new Error('Invalid GeoJSON object.'); } }, coordsToLatLng: function (coords) { return new L.LatLng(coords[1], coords[0], coords[2]); }, coordsToLatLngs: function (coords, levelsDeep, coordsToLatLng) { var latlngs = []; for (var i = 0, len = coords.length, latlng; i < len; i++) { latlng = levelsDeep ? this.coordsToLatLngs(coords[i], levelsDeep - 1, coordsToLatLng) : (coordsToLatLng || this.coordsToLatLng)(coords[i]); latlngs.push(latlng); } return latlngs; }, latLngToCoords: function (latlng) { return latlng.alt !== undefined ? [latlng.lng, latlng.lat, latlng.alt] : [latlng.lng, latlng.lat]; }, latLngsToCoords: function (latlngs, levelsDeep, closed) { var coords = []; for (var i = 0, len = latlngs.length; i < len; 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; }, getFeature: function (layer, 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 }; } }); var PointToGeoJSON = { toGeoJSON: function () { return L.GeoJSON.getFeature(this, { type: 'Point', coordinates: L.GeoJSON.latLngToCoords(this.getLatLng()) }); } }; L.Marker.include(PointToGeoJSON); L.Circle.include(PointToGeoJSON); L.CircleMarker.include(PointToGeoJSON); L.Polyline.prototype.toGeoJSON = function () { var multi = !this._flat(this._latlngs); var coords = L.GeoJSON.latLngsToCoords(this._latlngs, multi ? 1 : 0); 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]; } return L.GeoJSON.getFeature(this, { type: (multi ? 'Multi' : '') + 'Polygon', coordinates: coords }); }; L.LayerGroup.include({ toMultiPoint: function () { var coords = []; this.eachLayer(function (layer) { coords.push(layer.toGeoJSON().geometry.coordinates); }); return L.GeoJSON.getFeature(this, { type: 'MultiPoint', coordinates: coords }); }, toGeoJSON: function () { var type = this.feature && this.feature.geometry && this.feature.geometry.type; 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, { geometries: jsons, type: 'GeometryCollection' }); } return { type: 'FeatureCollection', features: jsons }; } }); L.geoJson = function (geojson, options) { return new L.GeoJSON(geojson, options); };