1. 程式人生 > 程式設計 >vue整合openlayers載入geojson並實現點選彈窗教程

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,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:4326')).getCoordinates();
    var b2 = new Point(transform(that.allFeatures[j+1].getGeometry().getClosestPoint(p),'EPSG:4326')).getCoordinates();
    var x1 = that.getDistance(p1[0],p1[1],b1[0],b1[1]);
    var x2 = that.getDistance(p1[0],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.2));
 filter: drop-shadow(0 1px 4px rgba(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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。