如何给一条路线等间距插入样式,以openlayers为例

已被阅读 2895 次 | 文章分类:OpenLayers | 2021-06-20 18:59

如果想突出显示一条路径的特征,想等间距插入几个点的样式,比如点,或者箭头,该怎么实现呢,这里以openlayers为例,在nodejs环境实现,其他相关地图api都是同理实现,比如 arcgis api for js、leaflet、ceaium、百度地图等等

1 实现思路

实现思路:绘制一条线,将线段等间距分割,拿到分割后所有位置的坐标,然后绘制点即可.openlayers中直接可以定义几何样式,所以就更方便了,不用自己绘制点。

2 绘制一条线段

首先绘制一条默认样式的路径,代码如下

                                        
/**
 * 完整可用
 */
 import { Map, View, Feature} from 'ol';
 import * as Style from 'ol/style';
 import { OSM as OsmSource } from 'ol/source';
 import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
 import { Vector as VectorSource } from 'ol/source';
 import {
     Point,
     LineString
   } from 'ol/geom';
 import 'ol/ol.css';
 let map = new Map({
   target: 'map',
   layers: [
     new TileLayer({
       source: new OsmSource()
     })
   ],
   view: new View({
     center: [99.64149080182347, 39.57246995882144],
     zoom: 18,
     projection: 'EPSG:4326'
   })
 });
 createLine();
 /**
  * 创建线 linestiring
  */
function createLine() {
     var layer = new VectorLayer({})
     var source = new VectorSource();
     map.addLayer(layer);
     layer.setSource(source);
     let arr=[
      [99.64064006712545, 39.57211613643938],
      [99.64149080182347, 39.57246995882144], 
      [99.64311537333242, 39.573145621589674], 
      [99.64381486128156, 39.572191381856385],
      [99.64442816904665, 39.571354708917454]
    ];
     var feature = new Feature({
       geometry: new LineString(arr)
     });
     source.addFeature(feature);
}
                                        
                                    

小白GIS

3 定义一条绿色线

openlayers中设置样式,参数可以是style对象,或者style数组;添加如下代码

                                        
let style= new Style.Style({
      stroke: new Style.Stroke({
        color: 'green',
        width: 10
      })
    })
     feature.setStyle(style);
                                        
                                    

小白GIS

4 等间距定义点样式

实现这一步基本思路基本思路如下

1 定义一个间距,用像素表示,比如40个像素

2 获取每段间距的距离;获取地图分辨率(一个像素表示的实际距离),然后用分辨率乘以40,即可得到每段的距离

3 总共分割多少段;获取线段长度,除每段间距距离即可获得

4 获取每段末端的坐标,用来定义该点出的样式

这里需要借助openlayers中几何对象的方法,getCoordinateAt(),该方法是将整个线段规定为0-1的区间,然后可以获取中间任意比例出的坐标,比如1/10,1/20等等,所以这里需要获取1/40,2/40.....39/40出的坐标;全部代码如下:

                                        
/**
 * 完整可用
 */
 import { Map, View, Feature} from 'ol';

 import * as Style from 'ol/style';
 import { OSM as OsmSource } from 'ol/source';
 import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
 import { XYZ as XYZSource, Vector as VectorSource } from 'ol/source';
 import GeoJSON from 'ol/format/GeoJSON'
 import {
     Point,
     MultiPoint,
     LineString,
     MultiLineString,
     Circle,
     Polygon
   } from 'ol/geom';
 import 'ol/ol.css';
 let map = new Map({
   target: 'map',
   layers: [
     new TileLayer({
       source: new OsmSource()
     })
   ],
   view: new View({
     center: [99.64149080182347, 39.57246995882144],
     zoom: 18,
     projection: 'EPSG:4326'
   })
 });
 
 /**
  * 创建线 linestiring
  */
  let arr=[
    [99.64064006712545, 39.57211613643938],
    [99.64149080182347, 39.57246995882144], 
    [99.64311537333242, 39.573145621589674], 
    [99.64381486128156, 39.572191381856385],
    [99.64442816904665, 39.571354708917454]
  ];
     var layer = new VectorLayer({})
     var source = new VectorSource();
     var feature = new Feature({
      geometry: new LineString(arr)
    });
    map.addLayer(layer);
    layer.setSource(source);
    source.addFeature(feature);
    

 let res=map.getView().getResolution();
 var styleFunction = function(){
   //轨迹线图形
  var line= feature.getGeometry();
  var styles = [
     new Style.Style({
       stroke: new Style.Stroke({
         color: 'red',
         width: 10
       })
     })
   ];
   //轨迹地理长度
   let length=line.getLength();
   //像素间隔步长
   let stpes=40;//像素步长间隔
   //将像素步长转实际地理距离步长
   let geo_steps=stpes*res;
   //箭头总数
   let num=parseInt(length/geo_steps);
   for(let i=1;i<num+1;i++){
       let arraw_coor=line.getCoordinateAt(i*1.0/num);
       styles.push(new Style.Style({
           geometry: new Point(arraw_coor),
           image: new Style.Circle({
               radius: 7,
               fill: new Style.Fill({
                   color: '#ffcc33'
               })
           })
       }));
   }
   return styles;
 }
 feature.setStyle(styleFunction);

                                        
                                    

小白GIS

5 图标样式

可以将上面的circle样式用图片样式替换

                                        
       styles.push(new Style.Style({
           geometry: new Point(coor),   // 这里是关键,定义几何对象样式
           image: new Style.Icon({ 
            src: '../static/imgs/forbid.png', 
            scale:0.5,
            rotation: 0 
          }) 
       }));
                                        
                                    

小白GIS

6 根据分辨率改变数量

将获取分辨率代码,放入stylefunction函数中即可

小白GIS

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号