用戶請求地理數據或者其他數據,服務器要以一定的客戶端能夠識別的數據 格式返回,數據格式是否高效,直接影響用戶的體驗!首先要求數據格式要是輕量級的,還要求客戶端處理數據方便快捷,相較於XML,JSON滿足這兩個要 求,且目前應用廣泛,非常流行。而在傳輸地理信息方面,相應有GeoJSON。下面咱就來了解一下GeoJSON,並看看它怎么應用到應用里!
1. GeoJSON
可以說GeoJSON就是JSON格式,只不過是針對Geometry的JSON,遵循JSON的語法和格式,其解析方式和JSON完全相同。
GeoJSON是一種針對地理數據編碼的數據傳輸格式,支持Point、LineString、Polygon、MultiPoint和 MultiPolygon。多個地理要素用GeometryCollection表示,有多余的屬性,使用Feature對象表示,一組Feature用 FeatureCollection表示。以下代碼就是一個Point類型的地理要素,包含name屬性。
在這里你可以看到它的詳細規范。
{
"type": "Feature", "geometry": { "type": "Point", "coordinates": [125.6, 10.1] }, "properties": { "name": "Dinagat Islands" } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2. 如何利用它構建應用
-
2.1. 載入數據
上一篇我們初始化Vector圖層時候,用到了GeoJSON文件:
vectorLayer = new ol.layer.Vector({ //初始化矢量圖層 source: new ol.source.GeoJSON({ projection: 'EPSG:3857', url: 'data/geojson/countries.geojson' //從文件加載邊界等地理信息 }), style: function(feature, resolution) { style.getText().setText(resolution < 5000 ? feature.get('name') : ''); //當放大到1:5000分辨率時,顯示國家名字 return [style]; } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
其中的url:’data/geojson/countries.geojson’屬性,便是一個GeoJSON文件,里邊的內容是國家的邊界信息:
這就相當於我們從服務器請求了GeoJSON數據,只不過不是通過查詢數據庫,而是請求文件。
我們抽取一部分分解一下,因為其它都是重復的:
{"type":"FeatureCollection","features":[ {"type":"Feature","id":"CHN","properties":{"name":"China"},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.339188,18.67 ...
- 1
- 2
- 1
- 2
第一個type屬性,指定要素種類是要素集合;接下來的features屬性是一個feature數組,每一個數組有type、id、 properties、和geometry屬性,其中properties是一個屬性集合,這里只包含一個name屬性,指國家的名字,可以包含多個屬 性,以都好分開即可;geometry也包含type和coordinates屬性,type指定地理要素的種類,之前我們提到GeoJSON支持的種 類,coordinates便是該要素的坐標。
- 2.2. 調取數據
當我們初始化vector圖層,並將其加入map中,這些GeoJSON數據已經載入到Vector圖層(當然,Vector支持GeoJSON格式)。我們可以添加處理事件,直接調取GeoJSON里包含的數據,咱們再回憶一下上一篇定義的鼠標點擊事件:
/** * 鼠標點擊的事件 */ map.on('click', function(evt) { var pixel = map.getEventPixel(evt.originalEvent); var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) { return feature; }); var coordinate = evt.coordinate; var hdms = ol.coordinate.toStringHDMS(ol.proj.transform( coordinate, 'EPSG:3857', 'EPSG:4326')); if(feature!==undefined){ content.innerHTML = '<p>你點擊的坐標是:</p><code>' + hdms + '</code><p>這里屬於:'+ feature.get('name') + '</p>'; } else{ content.innerHTML = '<p>你點擊的坐標是:</p><code>' + hdms + '</code><p>這里是大海!</p>'; } overlay.setPosition(coordinate); map.addOverlay(overlay); });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
feature的定義中用到了forEachFeatureAtPixel這個函數,這個函數的GitHub上的解釋如下:
/**
* Detect features that intersect a pixel on the viewport, and execute a callback with each intersecting feature. Layers included in the detection can be configured throughopt_layerFilter
. Feature overlays will always be included in the detection.
函數原型如下:
ol.Map.prototype.forEachFeatureAtPixel =
function(pixel, callback, opt_this, opt_layerFilter, opt_this2){}
- 1
- 2
- 1
- 2
也就是說,這個函數會檢測與pixel像素相交的要素feature,並對該feature調用callback函數。其它參數都是可選的,其中opt_layerFilter 可以配置檢測的圖層,可以保證的是,矢量要素一定在被檢查之列。
這個函數執行之后,返回與像素相交的feature,然后我們可以調用相關的feature的屬性等:
if(feature!==undefined){
content.innerHTML = '<p>你點擊的坐標是:</p><code>' + hdms + '</code><p>這里屬於:'+ feature.get('name') + '</p>'; } else{ content.innerHTML = '<p>你點擊的坐標是:</p><code>' + hdms + '</code><p>這里是大海!</p>'; }
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
其中feature.get(‘name’)就是取用feature的name屬性,這里是國家名‘China’!之所以添加feature是否為null,是因為大海處沒有feature。
這樣會有如下的效果:
OK,這樣就將GeoJSON的要素定義、格式以及取用方法都講清楚了,親,你看明白了么,沒有的話請留言告知哦!
3. PS
其實從服務器請求一個GeoJSON文件(本文例子),和從服務器端查詢數據庫是一樣一樣的啊,就是利用AJAX或者其他通信技術,來發送請求,而 服務器有相應的處理程序,直接將結果通過GeoJSON格式,返回就可以。