Leaflet

一個開源 JavaScript 函式庫
用於行動裝置友善的互動式地圖

← 教學

在 Leaflet 中使用 GeoJSON

GeoJSON 在許多 GIS 技術和服務中是非常流行的資料格式 — 它簡單、輕巧、直接,而且 Leaflet 非常擅長處理它。在這個範例中,您將學習如何從 GeoJSON 物件建立及互動地圖向量。

查看這個獨立範例。

關於 GeoJSON

根據 GeoJSON 規範 (RFC 7946)

GeoJSON 是一種用於編碼各種地理數據結構的格式 […]。一個 GeoJSON 物件可以代表一個空間區域(一個幾何形狀)、一個空間界定的實體(一個特徵),或是一個特徵列表(一個特徵集合)。GeoJSON 支援以下幾何類型:點、線串、多邊形、多點、多線串、多邊形和幾何集合。GeoJSON 中的特徵包含一個幾何物件和額外的屬性,而一個特徵集合包含一個特徵列表。

Leaflet 支援以上所有的 GeoJSON 類型,但是 特徵特徵集合 效果最好,因為它們允許您使用一組屬性來描述特徵。我們甚至可以使用這些屬性來設定 Leaflet 向量的樣式。這是一個簡單的 GeoJSON 特徵範例

var geojsonFeature = {
	"type": "Feature",
	"properties": {
		"name": "Coors Field",
		"amenity": "Baseball Stadium",
		"popupContent": "This is where the Rockies play!"
	},
	"geometry": {
		"type": "Point",
		"coordinates": [-104.99404, 39.75621]
	}
};

GeoJSON 圖層

GeoJSON 物件透過 GeoJSON 圖層新增到地圖上。為了建立它並將其新增到地圖上,我們可以使用以下程式碼

L.geoJSON(geojsonFeature).addTo(map);

GeoJSON 物件也可以以有效 GeoJSON 物件陣列的形式傳遞。

var myLines = [{
	"type": "LineString",
	"coordinates": [[-100, 40], [-105, 45], [-110, 55]]
}, {
	"type": "LineString",
	"coordinates": [[-105, 40], [-110, 45], [-115, 55]]
}];

或者,我們可以建立一個空的 GeoJSON 圖層並將其指定給一個變數,以便稍後可以向其中新增更多特徵。

var myLayer = L.geoJSON().addTo(map);
myLayer.addData(geojsonFeature);

選項

style

style 選項可以用兩種不同的方式設定特徵樣式。首先,我們可以傳遞一個簡單的物件,以相同的方式設定所有路徑(折線和多邊形)的樣式

var myLines = [{
	"type": "LineString",
	"coordinates": [[-100, 40], [-105, 45], [-110, 55]]
}, {
	"type": "LineString",
	"coordinates": [[-105, 40], [-110, 45], [-115, 55]]
}];

var myStyle = {
	"color": "#ff7800",
	"weight": 5,
	"opacity": 0.65
};

L.geoJSON(myLines, {
	style: myStyle
}).addTo(map);

或者,我們可以傳遞一個函數,根據它們的屬性設定個別特徵的樣式。在下面的範例中,我們檢查「party」屬性並相應地設定多邊形的樣式

var states = [{
	"type": "Feature",
	"properties": {"party": "Republican"},
	"geometry": {
		"type": "Polygon",
		"coordinates": [[
			[-104.05, 48.99],
			[-97.22,  48.98],
			[-96.58,  45.94],
			[-104.03, 45.94],
			[-104.05, 48.99]
		]]
	}
}, {
	"type": "Feature",
	"properties": {"party": "Democrat"},
	"geometry": {
		"type": "Polygon",
		"coordinates": [[
			[-109.05, 41.00],
			[-102.06, 40.99],
			[-102.03, 36.99],
			[-109.04, 36.99],
			[-109.05, 41.00]
		]]
	}
}];

L.geoJSON(states, {
	style: function(feature) {
		switch (feature.properties.party) {
			case 'Republican': return {color: "#ff0000"};
			case 'Democrat':   return {color: "#0000ff"};
		}
	}
}).addTo(map);

pointToLayer

點的處理方式與折線和多邊形不同。預設情況下,會為 GeoJSON 點繪製簡單的標記。我們可以透過在建立 GeoJSON 圖層時,於 GeoJSON 選項物件中傳遞 pointToLayer 函數來改變這一點。這個函數會傳遞一個 LatLng,並且應該傳回一個 ILayer 的實例,在此案例中很可能是一個 MarkerCircleMarker

在這裡,我們使用 pointToLayer 選項來建立一個 CircleMarker

var geojsonMarkerOptions = {
	radius: 8,
	fillColor: "#ff7800",
	color: "#000",
	weight: 1,
	opacity: 1,
	fillOpacity: 0.8
};

L.geoJSON(someGeojsonFeature, {
	pointToLayer: function (feature, latlng) {
		return L.circleMarker(latlng, geojsonMarkerOptions);
	}
}).addTo(map);

我們也可以在這個範例中設定 style 屬性 — 如果您在 pointToLayer 函數內建立像圓形這樣的向量圖層,Leaflet 會聰明地將樣式套用到 GeoJSON 點。

onEachFeature

onEachFeature 選項是一個函數,在將每個特徵新增到 GeoJSON 圖層之前會針對每個特徵調用。使用此選項的一個常見原因是當特徵被點擊時,將彈出視窗附加到特徵上。

function onEachFeature(feature, layer) {
	// does this feature have a property named popupContent?
	if (feature.properties && feature.properties.popupContent) {
		layer.bindPopup(feature.properties.popupContent);
	}
}

var geojsonFeature = {
	"type": "Feature",
	"properties": {
		"name": "Coors Field",
		"amenity": "Baseball Stadium",
		"popupContent": "This is where the Rockies play!"
	},
	"geometry": {
		"type": "Point",
		"coordinates": [-104.99404, 39.75621]
	}
};

L.geoJSON(geojsonFeature, {
	onEachFeature: onEachFeature
}).addTo(map);

filter

filter 選項可以用來控制 GeoJSON 特徵的能見度。為了實現這一點,我們將一個函數作為 filter 選項傳遞。此函數會針對 GeoJSON 圖層中的每個特徵調用,並傳遞 featurelayer。然後,您可以使用特徵屬性中的值,透過傳回 truefalse 來控制能見度。

在下面的範例中,「Busch Field」將不會在地圖上顯示。

var someFeatures = [{
	"type": "Feature",
	"properties": {
		"name": "Coors Field",
		"show_on_map": true
	},
	"geometry": {
		"type": "Point",
		"coordinates": [-104.99404, 39.75621]
	}
}, {
	"type": "Feature",
	"properties": {
		"name": "Busch Field",
		"show_on_map": false
	},
	"geometry": {
		"type": "Point",
		"coordinates": [-104.98404, 39.74621]
	}
}];

L.geoJSON(someFeatures, {
	filter: function(feature, layer) {
		return feature.properties.show_on_map;
	}
}).addTo(map);

檢視 範例頁面,以詳細了解 GeoJSON 圖層的可能性。