实现一个什么效果呢,就是在openlayers上面,绘制三个圆形,绘制完成之后,三个圆心连接起来,然后标记出每两个圆心之间的距离。

期望效果

写在前面

其实这个效果很好实现的,之前有几篇博文呢,关于 openlayers 根据半径绘制圆形,根据经纬度坐标绘制连线啥的都有涉及过,所以说如果要想实现今天想做的功能拼接一下就可以了,做一个快乐的代码裁缝。

绘制圆形

简单的什么安装 openlayers,导入,使用这里就不说了,如果不清楚直接看之前的博客,今天不多废话直接进入正题。

首先第一步,我们先绘制着三个蓝色的圆形。

关键代码如下,特别说一下哈,这是关键代码,之前有人问说你代码跑不起来,我特别无语,这是关键代码,那些基本的创建变量啥的,一看报错就知道没有创建,自己创建就行啦!没有那么难啊!适当的改一下就好了嘛。

	  // 绘制圆
      addPoint() {
      	// 下面这个经纬度都是写死的哈,一会连线和标签都是一样的数据
        let sites = [{  
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        let features = []
        sites.forEach((item, index) => {
          let feature = new Feature({
            title: item.name,
            geometry: new Circle(fromLonLat(item.site), this.getRadius(2000)),
          })
          feature.setStyle(
            new Style({
              fill: new Fill({
                color: 'rgba(32, 157, 230, 1)'
              }),
            })
          )
          features.push(feature)
        })
        let source = new VectorSource()
        source.addFeatures(features)
        let layer = new VectorLayer({
          opacity: 0.2
        })
        layer.setSource(source)
        map.addLayer(layer)
      },

好的,上面这一步完成之后呢,刷新页面看到的效果应该是下面的样子。

添加圆形标识

好了哈,我们给每个圆形添加一个文字标识,就是 覆盖物1,、覆盖物2、覆盖物3这种。

关键代码:

	  // 添加标识
      addLabel() {
        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        let features = []
        sites.forEach((item, index) => {
          let feature = new Feature({
            title: item.name,
            geometry: new Point(fromLonLat(item.site)),
          })
          feature.setStyle(
            new Style({
              text: new Text({
                textAlign: 'center',         
                textBaseline: 'middle',      
                font: 'normal 17px 微软雅黑',  
                text: item.name,     
                fill: new Fill({  
                  color: 'red'
                }),
              })
            })
          )
          features.push(feature)
        })

        let sourceLabel = new VectorSource()
        sourceLabel.addFeatures(features)
        let layerLabel = new VectorLayer({
          opacity: 1
        })
        layerLabel.setSource(sourceLabel)
        map.addLayer(layerLabel)
      },

上面的代码执行完成之后,就得到了下面的效果了。

绘制连线

接下来就是吧圆两两相连,用虚线也好,用实线也好,连接起来,这个也很简单,直接上代码。

	  // 添加连线
      addLink() {
        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        sites.push(sites[0])
        let linkData = []
        sites.forEach(item => {
          linkData.push(fromLonLat(item.site))
        })
        let features = []

        let featureLine = new Feature({
          geometry: new LineString(linkData),
        });
        let lineStyle = new Style({
          stroke: new Stroke({
            color: '#000',
            lineDash: [10, 10, 10, 10], // 重点在这
            width: 2,
          }),
        });
        // 添加线的样式
        featureLine.setStyle(lineStyle);
        features.push(featureLine)
        let sourceLink = new VectorSource()
        sourceLink.addFeatures(features)
        let layerLink = new VectorLayer()
        layerLink.setSource(sourceLink)
        map.addLayer(layerLink)
      },

上面的代码执行完成之后呢,圆就两两相连了。

标注距离

这个有两个步骤,第一个步骤,计算距离,第二个步骤,标注距离。

这个直接使用连线的图层操作就可以了,所以说修改连线代码,继续来计算距离,获取距离后进行标注。

	  // 添加连线
      addLink() {

        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        sites.push(sites[0])
        let linkData = []
        sites.forEach(item => {
          linkData.push(fromLonLat(item.site))
        })
        let features = []

        let featureLine = new Feature({
          geometry: new LineString(linkData),
        });
        let lineStyle = new Style({
          stroke: new Stroke({
            color: '#000',
            lineDash: [10, 10, 10, 10], // 重点在这
            width: 2,
          }),
        });
        // 添加线的样式
        featureLine.setStyle(lineStyle);
        features.push(featureLine)

        let distanceList = []
        for (let index = 0; index < sites.length - 1; index  ) {
          let site = fromLonLat([(sites[index].site[0]   sites[index   1].site[0]) / 2, (sites[index].site[1]   sites[index   1].site[1]) / 2])
          let length = getDistance(sites[index].site, sites[index   1].site);
          distanceList.push({
            site,
            length,
          })
        }

        distanceList.forEach((item) => {
          let feature = new Feature({
            title: '这是测试用的',
            geometry: new Point(item.site),
          })
          feature.setStyle(
            new Style({
              text: new Text({
                textAlign: 'center',            //位置
                textBaseline: 'middle',         //基准线
                font: 'normal 12px 微软雅黑',    //文字样式
                text: item.length.toFixed(0)   'm',      //文本内容
                padding: [1, 1, 1, 1],
                backgroundFill: new Fill({       //文本填充样式(即文字颜色)
                  color: '#d5e2f9'
                }),
                fill: new Fill({       //文本填充样式(即文字颜色)
                  color: 'red'
                }),
              })
            })
          )
          features.push(feature)
        })

        let sourceLink = new VectorSource()
        sourceLink.addFeatures(features)
        let layerLink = new VectorLayer()
        layerLink.setSource(sourceLink)
        map.addLayer(layerLink)
      },

好了,到此为止,最开始想要实现的效果就都出来了。

好了,下面放一下全部代码吧。

<template>
  <div style="width:100%;height: 100%;position: relative;">
    <div id="map"></div>
  </div>
</template>

<script>
  import 'ol/ol.css';
  import Map from 'ol/Map';
  import View from 'ol/View';
  import XYZ from 'ol/source/XYZ';
  import * as olProj from 'ol/proj';
  import Draw from 'ol/interaction/Draw';
  import Overlay from 'ol/Overlay';
  import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
  import { OSM, Vector as VectorSource } from 'ol/source';
  import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
  import Feature from 'ol/Feature';
  import { Point, MultiLineString, LineString, Polygon } from "ol/geom";
  import { fromLonLat } from 'ol/proj';
  import Circle from 'ol/geom/Circle';
  import { ScaleLine, defaults as defaultControls } from 'ol/control';
  import { circular } from 'ol/geom/Polygon';
  import * as olSphere from 'ol/sphere';
  import LinearRing from 'ol/geom/LinearRing';
  import { getTransform } from 'ol/proj';
  import { getArea, getLength, getDistance } from 'ol/sphere';
  import { unByKey } from 'ol/Observable';
  import WMTS from 'ol/source/WMTS';
  import ImageLayer from 'ol/layer/Image';
  import ImageWMS from 'ol/source/ImageWMS';
  import TileWMS from 'ol/source/TileWMS';
  import WMTSTileGrid from 'ol/tilegrid/WMTS';
  import * as olExtent from 'ol/extent';
  import GeoJSON from 'ol/format/GeoJSON';
  import Text from 'ol/style/Text';

  var map = null;  // /地图实例
  var view = null;  // 视图实例

  export default {
    name: "Home",
    components: {
    },
    data() {
      return { }
    },

    mounted() {
      this.initMap()
    },

    methods: {

      // 初始化地图
      initMap() {
        // 实例化Map
        map = new Map({  // 创建一个地图
          layers: [new TileLayer({
            source: new OSM(),
          }),],
          target: 'map',
          view: new View({
            center: fromLonLat([116.403218, 39.92372]),
            zoom: 15,
            constrainResolution: true,  // 设置缩放级别为整数 
            smoothResolutionConstraint: false,  // 关闭无级缩放地图
          }),
        });

        view = map.getView()
        // 加载圆形
        this.addPoint()
      },

      // 绘制圆
      addPoint() {
        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        let features = []
        sites.forEach((item, index) => {
          let feature = new Feature({
            title: item.name,
            geometry: new Circle(fromLonLat(item.site), this.getRadius(2000)),
          })
          feature.setStyle(
            new Style({
              fill: new Fill({
                color: 'rgba(32, 157, 230, 1)'
              }),
            })
          )
          features.push(feature)
        })
        let source = new VectorSource()
        source.addFeatures(features)
        let layer = new VectorLayer({
          opacity: 0.2
        })
        layer.setSource(source)
        map.addLayer(layer)
        this.addLabel()
        this.addLink()
      },

      // 添加标识
      addLabel() {
        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        let features = []
        sites.forEach((item, index) => {
          let feature = new Feature({
            title: item.name,
            geometry: new Point(fromLonLat(item.site)),
          })
          feature.setStyle(
            new Style({
              text: new Text({
                textAlign: 'center',            //位置
                textBaseline: 'middle',         //基准线
                font: 'normal 17px 微软雅黑',    //文字样式
                text: item.name,      //文本内容
                fill: new Fill({       //文本填充样式(即文字颜色)
                  color: 'red'
                }),
              })
            })
          )
          features.push(feature)
        })

        let sourceLabel = new VectorSource()
        sourceLabel.addFeatures(features)
        let layerLabel = new VectorLayer({
          opacity: 1
        })
        layerLabel.setSource(sourceLabel)
        map.addLayer(layerLabel)
      },

      // 添加连线
      addLink() {

        let sites = [{
          site: [116.400819, 39.916263],
          name: '覆盖物1'
        }, {
          site: [116.450819, 39.917263],
          name: '覆盖物2'
        }, {
          site: [116.350819, 39.857263],
          name: '覆盖物3'
        }]
        sites.push(sites[0])
        let linkData = []
        sites.forEach(item => {
          linkData.push(fromLonLat(item.site))
        })
        let features = []

        let featureLine = new Feature({
          geometry: new LineString(linkData),
        });
        let lineStyle = new Style({
          stroke: new Stroke({
            color: '#000',
            lineDash: [10, 10, 10, 10], // 重点在这
            width: 2,
          }),
        });
        // 添加线的样式
        featureLine.setStyle(lineStyle);
        features.push(featureLine)

        let distanceList = []
        for (let index = 0; index < sites.length - 1; index  ) {
          let site = fromLonLat([(sites[index].site[0]   sites[index   1].site[0]) / 2, (sites[index].site[1]   sites[index   1].site[1]) / 2])
          let length = getDistance(sites[index].site, sites[index   1].site);
          distanceList.push({
            site,
            length,
          })
        }

        distanceList.forEach((item) => {
          let feature = new Feature({
            title: '这是测试用的',
            geometry: new Point(item.site),
          })
          feature.setStyle(
            new Style({
              text: new Text({
                textAlign: 'center',            //位置
                textBaseline: 'middle',         //基准线
                font: 'normal 12px 微软雅黑',    //文字样式
                text: item.length.toFixed(0)   'm',      //文本内容
                padding: [1, 1, 1, 1],
                backgroundFill: new Fill({       //文本填充样式(即文字颜色)
                  color: '#d5e2f9'
                }),
                fill: new Fill({       //文本填充样式(即文字颜色)
                  color: 'red'
                }),
              })
            })
          )
          features.push(feature)
        })

        let sourceLink = new VectorSource()
        sourceLink.addFeatures(features)
        let layerLink = new VectorLayer()
        layerLink.setSource(sourceLink)
        map.addLayer(layerLink)
      },
      
	  // 半径计算
      getRadius(radius) {
        let metersPerUnit = map.getView().getProjection().getMetersPerUnit();
        let circleRadius = radius / metersPerUnit;
        return circleRadius;
      },

    },
  };
</script>
<style scoped>
  #map {
    width: 100%;
    height: 100%;
    background-color: azure;
  }
</style>

<style scoped>
  /deep/.ol-tooltip {
    position: relative;
    background: rgba(0, 0, 0, 0.7);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
    cursor: default;
    user-select: none;
  }

  /deep/.ol-tooltip-measure {
    opacity: 1;
    font-weight: bold;
  }

  /deep/.ol-tooltip-static {
    background-color: #ffcc33;
    color: black;
    border: 1px solid white;
  }

  /deep/.ol-tooltip-measure:before,
  /deep/.ol-tooltip-static:before {
    border-top: 6px solid rgba(0, 0, 0, 0.5);
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    content: "";
    position: absolute;
    bottom: -6px;
    margin-left: -7px;
    left: 50%;
  }

  /deep/.ol-tooltip-static:before {
    border-top-color: #ffcc33;
  }
</style>

到此这篇关于Openlayers实现根据半径绘制圆形的文章就介绍到这了,更多相关Openlayers绘制圆形内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Openlayers实现根据半径绘制圆形的更多相关文章

  1. iOS实现带文字的圆形头像效果

    随着腾讯QQ的普及,现在越来越多的社交类APP在显示头像的时候,都选择了圆形头像,本文将更进一步的介绍如何实现带文字的圆形头像效果,效果非常不错,感兴趣的朋友们可以参考借鉴,下面来一起看看吧。

  2. Openlayers实现根据半径绘制圆形

    这篇文章主要介绍了利用Openlayers实现绘制三个圆形,绘制完成之后,三个圆心连接起来,然后标记出每两个圆心之间的距离,感兴趣的可以了解一下

  3. js canvas实现圆形流水动画

    这篇文章主要为大家详细介绍了js canvas实现圆形流水动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. Android多种方式实现相机圆形预览的示例代码

    这篇文章主要介绍了Android多种方式实现相机圆形预览的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. OpenLayers实现点要素图层的聚合显示的方法

    在很多情况下,点要素图层中的要素数量可能会成百上千,如果一个点要素图层中的点数量很多,我们就会采取图层聚合的方式对其进行处理,本文就来介绍一下,感兴趣的可以了解一下

  6. vue使用openlayers创建地图

    这篇文章主要为大家详细介绍了vue项目中使用openlayers创建地图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. Android基于Fresco实现圆角和圆形图片

    这篇文章主要为大家详细介绍了Android基于Fresco实现圆角和圆形图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  8. Vue结合Openlayers使用Overlay添加Popup弹窗实现

    本文主要介绍了Vue结合Openlayers使用Overlay添加Popup弹窗实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  9. IOS实现圆形图片效果的两种方法

    这篇文章介绍在IOS中如何实现圆形图片,实现后的效果很赞,有需要的可以参考借鉴。

  10. 详解Android如何自定义view实现圆形进度条

    Android中实现进度条有很多种方式,自定义进度条一般是继承progressBar或继承view来实现。本文将介绍通过自定义View实现的圆形进度条,感兴趣的可以动手试一试

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部