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格式,返回就可以。

posted @ 2016-07-14 11:33  韩慧兵  阅读(9078)  评论(0编辑  收藏  举报