OpenLayers3 之 使用地理數據傳輸格式GeoJSON


用戶請求地理數據或者其他數據,服務器要以一定的客戶端能夠識別的數據 格式返回,數據格式是否高效,直接影響用戶的體驗!首先要求數據格式要是輕量級的,還要求客戶端處理數據方便快捷,相較於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文件內容

這就相當於我們從服務器請求了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 through opt_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格式,返回就可以。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM