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

发布时间:2023-07-03 08:30

第一步:安装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

如果该文章对您有所帮助,留下您的关注和点赞,谢谢

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号