开源的前端GIS空间分析库介绍 (三)turf与ol结合

前言

turf是mapbox出品的前端空间分析库,官网:http://turfjs.org/
turf库中包含的空间分析计算功能比较多,也非常简单易用。相比于jsts,turf的官方文档维护的非常好,非常利用学习。
在这里插入图片描述
openlayers(简称ol)是一个非常优秀的webgis库,非常适合去开发地图相关的应用。但是openlayers的短板就是空间分析计算功能很少,因为它与turf的结合,可以很好的解决这一问题。

接下来看下ol与turf结合使用的方法。

1. 安装和引用

1.1 turf

turf的安装引用可以参考《开源的前端GIS空间分析库介绍 (一)jsts与turf
如果时cdn引入,可以使用以下地址:

<script src="https://cdn.bootcdn.net/ajax/libs/Turf.js/6.5.0/turf.min.js"></script>

1.2 openlayers

html中引入

<!-- 引入ol-->
<link href="https://cdn.bootcdn.net/ajax/libs/ol3/4.6.5/ol.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/ol3/4.6.5/ol.js"></script>

NPM方式安装

npm i ol 

需要注意的是,ol不支持Node环境中运行,只能在浏览器端运行。

2. ol与turf结合使用

看个示例:
在地图上绘制一个湖泊周边50米范围内的生态红线,湖泊范围已知。
熟悉gis的同学都知道,这时候用用到gis种的缓冲操作了。openlayers中没有缓存相关的方法,因此这里采用turf。
来看看代码:

// 视图
var view = new ol.View({
    
    
  projection: 'EPSG:4326',
  zoom: 14,
  center:  [0, 0]
})

// 底图
var baseLayer = new ol.layer.Tile({
    
    
  source: new ol.source.XYZ({
    
    
    url:'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}'
  })
})

// 矢量图层
var vectorLayer = new ol.layer.Vector({
    
    
  source: new ol.source.Vector(),
  style: function (ft) {
    
    
    var name = ft.get('name')
    var color = name === 'buffer' ? '#F44336' : '#3F51B5'
    return new ol.style.Style({
    
    
      fill: new ol.style.Fill({
    
    
        color
      })
    })
  },
  // 定义渲染顺序,谁大谁在上
  renderOrder: function (ft1, ft2) {
    
    
    return ft1.get('order') - ft2.get('order')
  }
})

// 地图对象
var map = new ol.Map({
    
    
  target: 'map',
  view: view,
  layers: [baseLayer,vectorLayer],
})

// 湖泊测试数据
var data ={
    
    
  "type": "FeatureCollection",
  "name": "12",
  "crs": {
    
     "type": "name", "properties": {
    
     "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
  "features": [
    {
    
     "type": "Feature", "properties": {
    
     "name": 'water'}, "geometry": {
    
     "type": "Polygon", "coordinates": [ [ [ 106.4212556, 27.9028272 ], [ 106.4215743, 27.902787 ], [ 106.4218625, 27.9028406 ], [ 106.4221053, 27.9029747 ], [ 106.4224088, 27.9029613 ], [ 106.4226515, 27.9028406 ], [ 106.4224543, 27.9023445 ], [ 106.4225908, 27.9021031 ], [ 106.4228639, 27.9019959 ], [ 106.4231674, 27.9015131 ], [ 106.4234405, 27.9014059 ], [ 106.423744, 27.9014327 ], [ 106.4240474, 27.9018618 ], [ 106.4243054, 27.9019556 ], [ 106.4245937, 27.901969 ], [ 106.4253978, 27.9023579 ], [ 106.4258985, 27.9030015 ], [ 106.4260047, 27.9032429 ], [ 106.4260502, 27.9037926 ], [ 106.4262778, 27.904262 ], [ 106.426991, 27.9047983 ], [ 106.4270668, 27.9050531 ], [ 106.4270972, 27.9058174 ], [ 106.4274613, 27.9070375 ], [ 106.4274006, 27.9072789 ], [ 106.4271275, 27.9077214 ], [ 106.4272641, 27.9079493 ], [ 106.4276131, 27.9079627 ], [ 106.4278103, 27.908137 ], [ 106.4283262, 27.908794 ], [ 106.4284172, 27.9090354 ], [ 106.4283262, 27.9093303 ], [ 106.4281744, 27.9095315 ], [ 106.4282048, 27.9097862 ], [ 106.4284779, 27.9098935 ], [ 106.4292517, 27.9093974 ], [ 106.429191, 27.9091426 ], [ 106.429009, 27.9089281 ], [ 106.4289331, 27.9086465 ], [ 106.4289027, 27.9076007 ], [ 106.4288117, 27.9073593 ], [ 106.4283565, 27.9067023 ], [ 106.4283565, 27.9064207 ], [ 106.4286145, 27.9058978 ], [ 106.4287965, 27.9056967 ], [ 106.4293428, 27.9055224 ], [ 106.4296159, 27.9056296 ], [ 106.4299497, 27.9056565 ], [ 106.4300407, 27.9054017 ], [ 106.4299497, 27.9051603 ], [ 106.4296917, 27.9050397 ], [ 106.429449, 27.9049458 ], [ 106.4286145, 27.9048251 ], [ 106.428402, 27.9046776 ], [ 106.4277344, 27.9035245 ], [ 106.4276282, 27.9032563 ], [ 106.4276131, 27.9029747 ], [ 106.4278558, 27.9019422 ], [ 106.4277344, 27.9017143 ], [ 106.42866, 27.9012718 ], [ 106.4288269, 27.9010706 ], [ 106.4282503, 27.9011243 ], [ 106.4278255, 27.9014059 ], [ 106.4275524, 27.9014863 ], [ 106.4272792, 27.901379 ], [ 106.4271123, 27.9009097 ], [ 106.4267785, 27.900494 ], [ 106.4264447, 27.8997565 ], [ 106.4264447, 27.8995018 ], [ 106.4266723, 27.8987374 ], [ 106.4270668, 27.8983083 ], [ 106.4275068, 27.8976244 ], [ 106.4277648, 27.8968467 ], [ 106.42778, 27.8965919 ], [ 106.4276434, 27.8963639 ], [ 106.4267027, 27.8972758 ], [ 106.4263992, 27.8977049 ], [ 106.4261261, 27.8976244 ], [ 106.4258075, 27.8976244 ], [ 106.4255951, 27.8980804 ], [ 106.4253371, 27.8982279 ], [ 106.4247757, 27.8982279 ], [ 106.424715, 27.898496 ], [ 106.4244571, 27.8985631 ], [ 106.4241536, 27.8985631 ], [ 106.4238502, 27.8985363 ], [ 106.4232433, 27.8983754 ], [ 106.4215894, 27.8989251 ], [ 106.4214984, 27.8991665 ], [ 106.4214529, 27.9005477 ], [ 106.4213618, 27.900789 ], [ 106.4209218, 27.9014193 ], [ 106.4212556, 27.9028272 ] ] ] } }
  ]
}
  
// 呈现测试数据
var format = new ol.format.GeoJSON()
var fts = format.readFeatures(data)
var ft = fts[0]
ft.setProperties({
    
    
  order: 3
})
vectorLayer.getSource().addFeature(ft)
view.fit(ft.getGeometry())

// 使用turf来创建缓冲区
var turfRegion = turf.polygon(data.features[0].geometry.coordinates)
console.log(turfRegion)
var buffer = turf.buffer(turfRegion, 0.05, {
    
    units: 'miles'})

// turf缓存结果转换为ol.Feature对象
var olBuffer = format.readFeature(buffer)
olBuffer.setProperties({
    
    
  name: 'buffer',
  order: 2
})
vectorLayer.getSource().addFeature(olBuffer)

结果:
在这里插入图片描述
其中蓝色覆盖区域为湖泊范围,红色为题目所要的红线范围。
示例中的openlayers和turf都是通过cdn引入进来的。
在示例中,主要进行了以下操作过程。

  1. 给出的湖泊数据为geojson格式;
  2. 通过openlayers对数据进行读取并展示;
  3. 通过turf读取数据中的polygon,进而创建缓冲区。
  4. 将turf格式的缓冲区数据转换为ol.Feature对象,进行地图展示。

注意
在写示例的时候,遇到了一些小小的问题。
使用turf.buffer创建缓冲区时,函数第三个参数中的units属性定义了长度单位。

var data1 = {
    
    
  "type": "FeatureCollection",
  "name": "14",
  "crs": {
    
     "type": "name", "properties": {
    
     "name": "urn:ogc:def:crs:EPSG::3857" } },
  "features": [
    {
    
     "type": "Feature", "properties": {
    
     "OSM_ID": null, "OSM_WAY_ID": "355971874", "NAME": null, "TYPE": null, "CRAFT": null, "NATURAL": "water" }, "geometry": {
    
     "type": "Polygon", "coordinates": [ [ [ 11846759.98297281190753, 3236728.037491085939109 ], [ 11846795.4604945294559, 3236722.973750801291317 ], [ 11846827.542771777138114, 3236729.725404934026301 ], [ 11846854.571144139394164, 3236746.617151281796396 ], [ 11846888.356609594076872, 3236744.92923534149304 ], [ 11846915.373850012198091, 3236729.725404934026301 ], [ 11846893.421646423637867, 3236667.234942891635001 ], [ 11846908.616756919771433, 3236636.827472372446209 ], [ 11846939.018109858036041, 3236623.324259491171688 ], [ 11846972.803575312718749, 3236562.509582209866494 ], [ 11847003.204928247258067, 3236549.006442959420383 ], [ 11847036.990393701940775, 3236552.382226516958326 ], [ 11847070.764727214351296, 3236606.432665946427733 ], [ 11847099.485155833885074, 3236618.247961841057986 ], [ 11847131.578565029427409, 3236619.93586208904162 ], [ 11847221.090567579492927, 3236668.922849210910499 ], [ 11847276.828236617147923, 3236749.992983783595264 ], [ 11847288.65036654099822, 3236780.400706783868372 ], [ 11847293.715403370559216, 3236849.643401233013719 ], [ 11847319.051719473674893, 3236908.77142351353541 ], [ 11847398.444780306890607, 3236976.326825576368719 ], [ 11847406.88279770873487, 3237008.423001928254962 ], [ 11847410.26691023632884, 3237104.699387811124325 ], [ 11847450.798336829990149, 3237258.392827218864113 ], [ 11847444.041243735700846, 3237288.80168459797278 ], [ 11847413.639890801161528, 3237344.543034738395363 ], [ 11847428.84613324701786, 3237373.251493629999459 ], [ 11847467.696635531261563, 3237374.939487393014133 ], [ 11847489.648839114233851, 3237396.896022306289524 ], [ 11847547.07856441475451, 3237479.658494292292744 ], [ 11847557.208638079464436, 3237510.067845435813069 ], [ 11847547.07856441475451, 3237547.216726473998278 ], [ 11847530.180265713483095, 3237572.56217240029946 ], [ 11847533.564378233626485, 3237604.647155913058668 ], [ 11847563.965731168165803, 3237618.163938366807997 ], [ 11847650.104753144085407, 3237555.669402255676687 ], [ 11847643.347660057246685, 3237523.571936964523047 ], [ 11847623.087512725964189, 3237496.551170205697417 ], [ 11847614.638363376259804, 3237461.077834676485509 ], [ 11847611.254250859841704, 3237329.33853537356481 ], [ 11847601.124177195131779, 3237298.929587538354099 ], [ 11847550.451544987037778, 3237216.168213179334998 ], [ 11847550.451544987037778, 3237180.695607519708574 ], [ 11847579.171973612159491, 3237114.8271539285779 ], [ 11847599.432120937854052, 3237089.495156041812152 ], [ 11847660.2459587585181, 3237067.539116402622312 ], [ 11847690.647311693057418, 3237081.042769411578774 ], [ 11847727.805757720023394, 3237084.431281455326825 ], [ 11847737.935831379145384, 3237052.334926092065871 ], [ 11847727.805757720023394, 3237021.926596360746771 ], [ 11847699.085329094901681, 3237006.735053564887494 ], [ 11847672.068088676780462, 3236994.906824260484427 ], [ 11847579.171973612159491, 3236979.702714981045574 ], [ 11847555.516581816598773, 3236961.122737025842071 ], [ 11847481.199689762666821, 3236815.872270544525236 ], [ 11847469.377559846267104, 3236782.088627113960683 ], [ 11847467.696635531261563, 3236746.617151281796396 ], [ 11847494.713875949382782, 3236616.560061801224947 ], [ 11847481.199689762666821, 3236587.853196847718209 ], [ 11847584.237010441720486, 3236532.114941515494138 ], [ 11847602.816233457997441, 3236506.771430517546833 ], [ 11847538.62941506318748, 3236513.53557372558862 ], [ 11847491.340895377099514, 3236549.006442959420383 ], [ 11847460.939542442560196, 3236559.133796146139503 ], [ 11847430.527057554572821, 3236545.618064034730196 ], [ 11847411.947834543883801, 3236486.504213336855173 ], [ 11847374.789388516917825, 3236434.14212672971189 ], [ 11847337.630942489951849, 3236341.246208750642836 ], [ 11847337.630942489951849, 3236309.164199478924274 ], [ 11847362.967258594930172, 3236212.880837032105774 ], [ 11847406.88279770873487, 3236158.831958169583231 ], [ 11847455.863373659551144, 3236072.68924510711804 ], [ 11847484.583802284672856, 3235974.732328060548753 ], [ 11847486.275858547538519, 3235942.638585737440735 ], [ 11847471.069616103544831, 3235913.920544414781034 ], [ 11847366.351371115073562, 3236028.780476970598102 ], [ 11847332.565905654802918, 3236082.828840179368854 ], [ 11847302.1645527202636, 3236072.68924510711804 ], [ 11847266.698162958025932, 3236072.68924510711804 ], [ 11847243.053903110325336, 3236130.126057209447026 ], [ 11847214.333474487066269, 3236148.704902401193976 ], [ 11847151.83871235512197, 3236148.704902401193976 ], [ 11847145.081619268283248, 3236182.474380094092339 ], [ 11847116.372322585433722, 3236190.926209496334195 ], [ 11847082.586857130751014, 3236190.926209496334195 ], [ 11847048.812523625791073, 3236187.550515454728156 ], [ 11846981.252724664285779, 3236167.283772912807763 ], [ 11846797.141418838873506, 3236236.523352698422968 ], [ 11846787.01134517788887, 3236266.929930203594267 ], [ 11846781.946308348327875, 3236440.906233894173056 ], [ 11846771.805102733895183, 3236471.300671197939664 ], [ 11846722.82452679052949, 3236550.694334634579718 ], [ 11846759.98297281190753, 3236728.037491085939109 ] ] ] } }
  ]
}

var turfRegion = turf.polygon(data1.features[0].geometry.coordinates)
var buffer = turf.buffer(turfRegion, 50, {
    
    units: 'miles'})
console.log('EPSG:3857', buffer)

在这里插入图片描述
问题出在哪里?后续还需要调试下源码看看

3. geojson数据格式

turf读写数据就是本身用的geojson数据格式,ol中的ol.format.GeoJSON有支持读写geojson数据的方法。因此以geojson数据为桥梁,可以很好的在ol与turf之间进行数据交互。上面的示例也正是利用了这一点。

3.1 利用ol读取geojson

不管是利用ol读取还是写geojson,都可以先实例化一个ol.format.GeoJSON对象。

var format = new ol.format.GeoJSON()

当我们从turf对象转到ol对象时,数据对象转换过程为:
turf -> geojson -> ol.Feature、ol.geom.Geometry
需要用到读取操作,可以参考以下方法。

  • readFeature
    从geojson中读取要素,返回值是一个ol.Feature对象。
  • readFeatures
    从geojson中读取要素集,返回值是一个包含ol.Feature对象的数组。
  • readGeometry
    从geojson中读取几何对象,返回值是一个ol.geom.Geometry对象。

3.2 利用ol写geojson

当需要将ol的Feature或者Geometry对象,转为geojson,进而让turf进行操作时,数据转换过程如下:
ol.Feature、ol.geom.Geometry > geojson - >turf
这个过程可以采用以下的写操作。

  • writeFeature
    将一个ol.Feature对象转换为geojson字符串。
  • writeFeatures
    将一个由ol.Feature对象组成的数组,转换为geojson格式的字符串。
  • writeGeometry
    将一个ol.geom.Geometry对象转换为geojson字符串。

以上方法名,后面加上Object,又是一个新的方法。转换结果给对应的geojson对象。

笔者根据上面的方法写了一个js包:ol-turf-parse,预览地址:https://www.npmjs.com/package/ol-turf-parse。
如果觉得上面的方法使用麻烦,可以试试这个包。
如果是前端工程化项目中,可以采用以下命令进行安装。

npm i ol-turf-parse

在这个包中,提供了两个方法ol2turf、turf2ol方法,分别用于ol转turf和turf转ol。
示例:

let point = [0, 0]
let ft = new Feature({
    
    
  geometry: new Point(point)
})
ft.setProperties({
    
    
  name: 'ol-turf'
})
let r = ol2turf(ft)
console.log(r)

输出

{
    
    
  type: 'Feature',
  geometry: {
    
     type: 'Point', coordinates: [ 0, 0 ] },
  properties: {
    
     name: 'ol-turf' }
}

猜你喜欢

转载自blog.csdn.net/u012413551/article/details/119654608