vue集成openlayers加载geojson并实现点击弹窗教程

本文实例为大家分享了vue+openlayers加载geojson并实现点击弹窗教程,供大家参考,具体内容如下

第一步:安装vue-cli

cnpm install -g @vue/cli

第二步:新建一个项目

1.新建项目 (vue-openlayers为项目名),并选择default模版

vue create vue-openlayers

2.安装openlayers

cnpm i -S ol

第三步:写业务代码

1.删除掉HelloWorld.vue 新建 olmap.vue组件

components/olmap.vue代码:

<template>
 <div id="map" ref="rootmap">
  <div class="vm">
  <!-- <h2 class="h-title">弹窗 popup</h2> -->

  <!-- 弹窗元素 -->
  <div id="popup" class="ol-popup" ref="popup">
   <a href="#" id="popup-close" class="ol-popup-closer" @click="closePopup"></a>
   <div class="popup-content">
   <table id="routeBox">
    <tbody>
     <tr>
     </tr>
     <tr>
      <td>所在图层:</td>
      <td>{{layerName}}</td>
     </tr>
     <tr>
      <td>handle:</td>
      <td>{{handle}}</td>
     </tr>
     <tr>
      <td>块名称:</td>
      <td>{{blockName}}</td>
     </tr>
    </tbody>
   </table>
   </div>
  </div>
  </div>
 </div>
</template>

<script>
import "ol/ol.css";
import { Map, View } from "ol";
// import TileLayer from "ol/layer/Tile";

import VectorLayer from "ol/layer/Vector";

// import OSM from "ol/source/OSM";
import VectorSource from "ol/source/Vector";
// import Feature from "ol/Feature";
import GeoJSON from "ol/format/GeoJSON";
import Style from "ol/style/Style";
import Stroke from "ol/style/Stroke";
import Fill from "ol/style/Fill";
// import Select from "ol/interaction/Select"
// import {bbox} from 'ol/loadingstrategy';
import Point from "ol/geom/Point";
import { transform } from "ol/proj";
import Text from "ol/style/Text";
import Overlay from "ol/Overlay";
export default {
 data() {
 return {
  map: null,
  allFeatures: null,
  layerName: null,
  blockName: null,
  handle: null,
  overlayer: null,
 };
 },
 mounted() {
 this.initMap()
 },
 methods: {
 initMap(){
  var extent = [11285.07103919199,20056.574012374178,61290.31172946711,33996.47243386325];
  var wfsVectorSource = new VectorSource({
  url: 'http://localhost:8082/geoserver/workhome/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=workhome%3A28f&outputFormat=application%2Fjson',
  format: new GeoJSON(),
  // features: Feature,
  // strategy: bbox
  })

  var wfsVectorLayer = new VectorLayer({
  style: new Style({
   stroke: new Stroke({
    // color: 'blue',
    color: 'rgba(30,144,255)',
    width: 3
   }),
   fill: new Fill({
    color: 'rgba(0, 0, 255, 0.1)'
   })
  }),
  source: wfsVectorSource,
  visible:true,
  })

  this.map = new Map({
  target: "map",
  layers: [
   wfsVectorLayer
  ],
  view: new View({
   center: [31955.4551374715, 28165.253430237015],
   projection: 'EPSG:3857',
   zoom: 14
  }),
  });
  // this.map.addLayer()
  this.map.getView().fit(extent, this.map.getSize());
  // this.map.getView().setZoom(14);
  var that = this

  // 2. 创建Overlay图层
  that.overlayer = new Overlay({
   element: this.$refs.popup, // 弹窗标签,在html里
   autoPan: true, // 如果弹窗在底图边缘时,底图会移动
   autoPanAnimation: { // 底图移动动画
   duration: 250
   }
  })

  if(timer){
   clearInterval(timer)
  }

  var timer = setTimeout(() =>{
   var fs = wfsVectorSource.getFeatures()

   that.allFeatures = fs

   console.log('allFeatures',that.allFeatures)
  },3000);

  //Vector第一种单击事件
  // var selectSingleClick = new Select();
  // this.map.addInteraction(selectSingleClick);

  // selectSingleClick.on('select', function(e) {
  //  // var p = e.mapBrowserEvent.coordinate
  //  // console.log('p',p)
  //  console.log(e)
  //  var features=e.target.getFeatures().getArray();
  //  if (features.length>0)
  //  {
  //   console.log('length',features.length)
  //   var feature=features[0];
  //   console.log('feature',feature)
  //  }
  // })

  //Vector第二种单击事件
  this.map.on('singleclick',mapClick);

  function mapClick(e){
   var p = e.coordinate
   var p1 = new Point(transform(p, 'EPSG:3857', 'EPSG:4326')).getCoordinates();
   console.log(p)
   console.log('this.allFeatures.length',that.allFeatures)
   for(let j=0;j<that.allFeatures.length-1;j++){
    var b1 = new Point(transform(that.allFeatures[j].getGeometry().getClosestPoint(p), 'EPSG:3857', 'EPSG:4326')).getCoordinates();
    var b2 = new Point(transform(that.allFeatures[j+1].getGeometry().getClosestPoint(p), 'EPSG:3857', 'EPSG:4326')).getCoordinates();
    var x1 = that.getDistance(p1[0],p1[1],b1[0],b1[1]);
    var x2 = that.getDistance(p1[0],p1[1],b2[0],b2[1]);
    let fea = that.allFeatures[j+1]
    if(x1<x2){
     that.allFeatures[j+1] = that.allFeatures[j]
     that.allFeatures[j] = fea
    }
   }

   let a = that.allFeatures[that.allFeatures.length-1]
   that.overlayer.setPosition(p)
   that.map.addOverlay(that.overlayer)
   a.setStyle(that.polygonStyle())
   that.map.getView().setCenter(p)
   console.log(a)
  }

 },
 // 关闭弹窗
 closePopup: function(){
  console.log(this)
  // 把弹窗位置设置为undefined,并清空坐标数据
  this.overlayer.setPosition(undefined)
  this.currentCoordinate = null
 },
 //计算两点之间距离
 getDistance: (lat1, lng1, lat2, lng2)=>{

  lat1 = lat1 || 0;

  lng1 = lng1 || 0;

  lat2 = lat2 || 0;

  lng2 = lng2 || 0;

  var rad1 = lat1 * Math.PI / 180.0;

  var rad2 = lat2 * Math.PI / 180.0;

  var a = rad1 - rad2;

  var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;

  var r = 6378137;

  return r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)))

 },
 //设置高亮样式
 polygonStyle: ()=>{
  var style = new Style({
   fill: new Fill({ //矢量图层填充颜色,以及透明度
    color: 'rgba(220, 20, 60, 1)'
   }),
   stroke: new Stroke({ //边界样式
    lineDash:[6],//注意:该属性为虚线效果,在IE10以上版本才有效果
    color: '#FF0000',
    width: 2
   }),
   text: new Text({ //文本样式
    font: '20px Verdana,sans-serif',
    // text:feature.attr.dmaName,
    fill: new Fill({
     color: '#FF0000'
    })
   })
  });
  return style;
 }
 }
};
</script>

<style>
#map{height:100%;}
/*隐藏ol的一些自带元素*/
.ol-attribution,.ol-zoom { display: none;}

.ol-popup {
 position: absolute;
 background-color: #fff;
 -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
 filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
 padding: 15px;
 border-radius: 10px;
 border: 1px solid #cccccc;
 bottom: 12px;
 left: -50px;
 min-width: 280px;
}
.ol-popup:after,
.ol-popup:before {
 top: 100%;
 border: solid transparent;
 content: " ";
 height: 0;
 width: 0;
 position: absolute;
 pointer-events: none;
}
.ol-popup:after {
 border-top-color: #fff;
 border-width: 10px;
 left: 48px;
 margin-left: -10px;
}
.ol-popup:before {
 border-top-color: #cccccc;
 border-width: 11px;
 left: 48px;
 margin-left: -11px;
}
.ol-popup-closer {
 text-decoration: none;
 position: absolute;
 top: 2px;
 right: 8px;
}
.ol-popup-closer:after {
 content: "✖";
}
</style>

App.vue代码:

<template>
 <div id="app">
 <olmap />
 </div>
</template>

<script>
import olmap from './components/olmap.vue'

export default {
 name: 'app',
 components: {
 olmap
 }
}
</script>

<style>
*{padding:0; margin:0;}
html,body{
 height: 100%;
}
#app {
 height: 100%;
}
</style>

2.运行

npm run serve

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue-openlayers实现地图坐标弹框效果

    本文实例为大家分享了vue-openlayers实现地图坐标弹框的具体代码,供大家参考,具体内容如下 openlayers 这个效果是点击地图,弹出坐标信息. 点击地图边缘时,底图会跟着移动,使弹窗能完整显示出来. <template> <div class="vm"> <h2 class="h-title">弹窗 popup</h2> <div id="map" class="ma

  • vue集成openlayers加载geojson并实现点击弹窗教程

    本文实例为大家分享了vue+openlayers加载geojson并实现点击弹窗教程,供大家参考,具体内容如下 第一步:安装vue-cli cnpm install -g @vue/cli 第二步:新建一个项目 1.新建项目 (vue-openlayers为项目名),并选择default模版 vue create vue-openlayers 2.安装openlayers cnpm i -S ol 第三步:写业务代码 1.删除掉HelloWorld.vue 新建 olmap.vue组件 comp

  • vue利用openlayers加载天地图和高德地图

    目录 一.天地图部分 1.在vue中安装openlayers 二.高德地图部分 一.天地图部分 1.在vue中安装openlayers npm i --save ol 这里说的vue是基于脚手架构建的. 新建个页面,也就是vue文件,配置好路由.接着就是可以直接放入我的代码运行显示了. <template> <div class="wrapper"> <div>天地图</div> <div class="map"

  • 基于Vue+Openlayer实现动态加载geojson的方法

    加载1个或多个要素 <template> <div id="map" style="width: 100vw; height: 100vh"></div> </template> <script> import "ol/ol.css"; import TileLayer from "ol/layer/Tile"; import VectorLayer from &qu

  • vue集成openlayers问题

    目录 vue集成openlayers 下载依赖 创建地图文件 其他API vue openlayers绘制数据时鼠标位置偏移问题 解决方案 总结 vue集成openlayers 下载依赖 cnpm i -S ol 创建地图文件  <div class="map"></div> 按需引入相应的API,具体查看官方文档 <script> import Map from "ol/Map"; import View from "

  • Vue通过懒加载提升页面响应速度

    概述 项目的目的是要通过数据透视表和Excel公式来分析公司的各项运营数据.不过在集成后,在开发环境页面运行流畅,大量数据加载处理也很快.但是发布生产后,在用户每次打开页面时,加载时间上相较开发阶段均有所降低,经过排查速度变慢是由于发布包的vendor.js变大所导致的,这个文件加载每次都需300毫秒左右,由于小的Vue项目并没有做模块划分,所以所有的代码都直接打包到了vendor中,在集成了新功能后,发布包也随之变大了. 既然找到了原因,就开始着手优化,在前端对于需加载较大资源时,一般都采用懒

  • vue 项目常用加载器及配置详解

    本文介绍了vue 项目常用加载器及配置详解,分享给大家,具体如下: 1.安装sass: 1.1 由于sass-loader依赖于node-sass,所以在安装sass-loader的同时还需安装node-sass npm install --save-dev node-sass npm install --save-dev sass-loader 1.2 安装完成后修改 <style>标签: <style lang="scss"></style> 2

  • vue中v-for加载本地静态图片方法

    vue-cli 项目中本地图片放在assets目录下(原因vue-cli最开始的vue图片就在里面,就把所有图片放在里面了): 之后v-for 动态加载图片路径就遇到了问题 源码: <ul> <li v-for="(item,index) in teamInfo" @click="trastFun(item)"> <div><img v-bind:src="item.imageurl"/></

  • Vue SSR 组件加载问题

    Node 端渲染提示 window/document 没有定义 业务场景 首先来看一个简单的 Vue 组件 test.vue <template> <div> <h2>clientHeight: {{ clientHeight }} px </h2> </div> </template> <script type="text/babel"> export default { data(){ return

  • Vue 无限滚动加载指令实现方法

    也不存在什么加载咯, 就是一个判断滚动条是否到达浏览器底部了. 如果到了就触发事件,米到就不处理. 计算公式提简单的   底部等于(0) =  滚动条高度 - 滚动条顶部距离 - 可视高度.  反正结果就是0. 一.获取滚动条位置 class Scroll { static get top() { return Math.max(document.documentElement.scrollTop || document.body.scrollTop); } static get clientH

  • 通过原生vue添加滚动加载更多功能

    这篇文章主要介绍了通过原生vue添加滚动加载更多功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 vue中添加滚动加载更多,因为是单页面所以需要在跳出页面时候销毁滚动,要不会出现错乱.我们在mounted建立滚动,destroyed销毁滚动. mounted () { window.addEventListener('scroll', this.handleScroll) }, destroyed () { window.removeEven

随机推荐