用户请求地理数据或者其他数据,服务器要以一定的客户端能够识别的数据 格式返回,数据格式是否高效,直接影响用户的体验!首先要求数据格式要是轻量级的,还要求客户端处理数据方便快捷,相较于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格式,返回就可以。