可視化你的足跡 - Web端
可視化你的足跡
上一篇文章講述了如何在服務器端通過MapServer來生成地圖。雖然MapServer發布出來的地圖是標準的WMS服務,但是我們還需要一個客戶端程序來展現。我們在上一篇中,通過一些小腳本將照片中的地理信息抽取到了一個GeoJSON
文件中。GeoJSON
是一種向量圖層格式,向量數據可以在服務器端繪制成柵格圖,也可以直接在客戶端canvas上直接繪制出來。當數據量比較大的時候,我們更傾向于在服務器端繪制,這樣只需要在網絡上傳輸一張圖片(而且可以做緩存)。大數據量的客戶端繪制在性能上會比較差(當然現在已經有了一些新的解決方案,我們后續再細談),特別是有用戶交互時,會出現明顯的卡頓。
在本文中,我將分別使用客戶端和服務端繪制的兩種方式來展現兩種不同的地圖:使用OpenLayers直接在客戶端繪制矢量圖,以及使用Leaflet來展示在服務器端繪制好的柵格圖層。
使用OpenLayers3展示GeoJSON
展示GeoJSON非常容易,也是一種比較直接的方式,只需要將GeoJSON文件發送到前端,然后直接通過客戶端渲染即可。使用OpenLayers3
的API,代碼會是這樣:
$.getJSON('data/places-ive-been-3857.json').done(function(geojson) {
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojson)
});
});
客戶端發送一個ajax
請求,得到GeoJSON
數據之后,將其轉換成一個向量
類型。OpenLayers
定義了很多中格式讀取器,比如KML的,GML的,GeoJSON的等等。然后我們可以定義一個樣式函數:
var image = new ol.style.Circle({
radius: 5,
fill: null,
stroke: new ol.style.Stroke({color: '#f04e98', width: 1})
});
var styles = {
'Point': [new ol.style.Style({
image: image
})]
};
var styleFunction = function(feature, resolution) {
return styles[feature.getGeometry().getType()];
};
這個函數會應用到向量集的Point
類型,將其繪制為一個紅色,半徑為5像素的圓圈。有了數據和樣式,我們再來創建一個新的向量,然后生成一個新的圖層:
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: styleFunction
});
創建地圖,為了方便對照,我們加入了另外一個ol.source.Stamen
圖層作為參照。這樣當縮放到較小的區域時,我們可以清楚的知道當前的點和地物的對照,比如道路名稱,建筑名稱等,從而確定目前的位置。這是一種非常常見的GIS應用的場景,但是需要注意的是,不同的圖層需要有相同的空間映射方式,OpenLayers默認才用EPSG:3857,所以需要兩者都采用該投影:
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.Stamen({
layer: 'toner'
})
}),
vectorLayer
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: ol.proj.transform([108.87316667, 34.19216667], 'EPSG:4326', 'EPSG:3857'),
zoom: 2
})
});
創建地圖時,我們可以通過layers
來指定多個圖層。在OpenLayers中,有很多類型的Tile
,Stamen
是一個專注于做非常漂亮的地圖的組織。
在view中,我們需要將經緯度(EPSG:4326)轉換為墨卡托投影(EPSG:3857)。這樣我們就可以得到一個很漂亮的地圖了:
使用Leaflet展示柵格數據
我們在上一篇中已經生成了MapServer的WMS地圖,這里可以用Leaflet來消費該地圖(使用OpenLayers也可以消費,不過V3似乎在和WMS集成時有些問題,我此處使用了Leaflet)。
首先創建一個地圖:
var map = L.map('map').setView([34, 108], 10);
然后就可以直接接入我們在上一篇中生成的地圖:
L.tileLayer.wms("http://localhost:9999/cgi-bin/mapserv?map=/data/xian.map", {
layers: 'places',
format: 'image/png',
transparent: true,
maxZoom: 16,
minZoom: 2,
}).addTo(map);
便于對照,我們先添加一個底圖:
L.tileLayer( 'http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: '© <a title="OpenStreetMap" target="_blank">OpenStreetMap</a> contributors | Tiles Courtesy of <a title="MapQuest" target="_blank">MapQuest</a> <img src="https://simg.open-open.com/show/4524cfe6bd8603f9de822827effab038.png" width="16" height="16">',
subdomains: ['otile1','otile2','otile3','otile4'],
detectRetina: true
}).addTo( map );
這樣就可以看到最終的地圖:
使用Web界面,我們可以自由的拖拽,移動,并且方便的放大縮小。如果觀察瀏覽器的網絡標簽,在放大地圖時,可以看到很多的WMS請求:
其他
如果你對代碼感興趣,可以參看這個repo。
Posted by Qiu Juntao Sep 20th, 2015 Data, GIS, Visualization
來源:原始鏈接