map
ZZJ
2021-10-29 0bb459c121f04f573230fa98de5ffc75b53f9960
src/pages/internetEquipment/module/mapIndex.vue
@@ -1,21 +1,395 @@
<template>
  <div class="map-index">
  <div id="map-index">
    <div class="control">
      <div class="location icon iconfont" @click="location">&#xe74e;</div>
      <div class="zoom-in icon iconfont" @click="zoomIn">&#xeb89;</div>
      <div class="zoom-out icon iconfont" @click="zoomOut">&#xe758;</div>
    </div>
    <div class="range icon iconfont" @click="drawPolygon">&#xe773;</div>
    <el-input v-model="nodeId" placeholder="请输入内容"></el-input>
    <div class="save" v-if="showBtn" @click="savePoly">保存</div>
    <div class="cancel" v-if="showBtn" @click="resetMap">取消</div>
  </div>
</template>
<script>
export default {
import "ol/ol.css";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import VectorSource from "ol/source/Vector";
import { Icon, Style, Fill, Stroke } from "ol/style";
import { transform } from "ol/proj";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import { Vector as VectorLayer } from "ol/layer";
import OSM from "ol/source/OSM";
import Draw from "ol/interaction/Draw";
import { Modify, Snap } from "ol/interaction";
import Polygon from "ol/geom/Polygon";
}
let myMap = {};
let myVectorSource = {};
let baseLayer = new TileLayer({
  source: new OSM({
    // url:'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8',
    url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
    crossOrigin: "anonymous",
    // url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
  }),
});
let myDraw = {};
let myModify = {};
export default {
  data() {
    return {
      showBtn: false,
      nodeArr: [
        { data: [116.06157, 39.66157], id: 1, color: "绿" },
        { data: [116.06247, 39.66247], id: 2, color: "绿" },
        { data: [116.06337, 39.66337], id: 3, color: "绿" },
        { data: [116.06467, 39.66437], id: 4, color: "绿" },
        { data: [116.06517, 39.66517], id: 5, color: "红" },
        { data: [116.06627, 39.66627], id: 6, color: "红" },
        { data: [116.06787, 39.66787], id: 7, color: "红" },
        { data: [116.06897, 39.66897], id: 8, color: "红" },
      ],
      nodeId: "",
      iconArr: [],
      rangeArr: [],
      zoom: 15,
      center: [116.06667, 39.66667],
      polygonArr: [
        {
          data: [
            [12919660.904416857, 4817401.4907109635],
            [12921041.54824026, 4817277.28054],
            [12920195.963614853, 4816775.662541878],
            [12919493.698417485, 4816785.2171704145],
          ],
          id: "1",
        },
      ],
      polyFeature: [],
      drawStore: [],
      modifyStore: [],
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.initPolygonArr();
      const vectorSource = new VectorSource({
        features: this.polyFeature,
      });
      /* if(this.polygonArr.length>0){
      this.initPolygonArr()
      console.log(this.polyFeature);
      vectorSource.addFeature(this.polyFeature[0])
      } */
      myVectorSource = vectorSource;
      this.initAllNode();
      const vectorLayer = this.initLayer(vectorSource);
      const map = this.initBottomMap(vectorLayer);
      myMap = map;
      /* map.getView().on('change:resolution', ()=> {
      this.iconArr.forEach(item=>{
        let style = item.getStyle()
        console.log(this.zoom);
        style.getImage().setScale(this.zoom/15)
        item.setStyle(style)
        console.log(item);
      })
    }) */
    },
    initNode([x, y], color) {
      const iconFeature = new Feature({
        geometry: new Point(transform([x, y], "EPSG:4326", "EPSG:3857")),
      });
      const iconStyle = new Style({
        image: new Icon({
          size: [32, 32],
          src: `/images/map/安全帽-${color}.png`,
        }),
        zIndex: 1,
      });
      iconFeature.setStyle(iconStyle);
      this.iconArr.push(iconFeature);
      return iconFeature;
    },
    initAllNode() {
      this.nodeArr.forEach((item) => {
        const node = this.initNode(item.data, item.color);
        node.set("id", item.id);
        myVectorSource.addFeature(node);
      });
    },
    initPolygonArr() {
      this.polyFeature = [];
      this.polygonArr.forEach((item) => {
        const feature = new Feature({ geometry: new Polygon([item.data]) });
        feature.id = item.id;
        this.polyFeature.push(feature);
      });
    },
    initLayer(source) {
      return new VectorLayer({
        source: source,
        style: new Style({
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.4)",
          }),
          stroke: new Stroke({
            color: "#F54336",
            width: 2,
          }),
        }),
      });
    },
    initBottomMap(vectorLayer) {
      return new Map({
        target: "map-index",
        layers: [baseLayer, vectorLayer],
        view: new View({
          center: transform(this.center, "EPSG:4326", "EPSG:3857"),
          zoom: this.zoom,
        }),
      });
    },
    zoomIn() {
      const view = myMap.getView();
      this.zoom++;
      view.setZoom(this.zoom);
    },
    zoomOut() {
      const view = myMap.getView();
      this.zoom--;
      view.setZoom(this.zoom);
    },
    location() {
      const view = myMap.getView();
      view.setZoom(this.zoom);
      view.setCenter(
        transform([116.06667, 39.66667], "EPSG:4326", "EPSG:3857")
      );
    },
    drawPolygon() {
      this.showBtn = true;
      const draw = new Draw({
        source: myVectorSource,
        type: "Polygon",
      });
      myDraw = draw;
      draw.on("drawend", (event) => {
        let id =
          this.drawStore.length > 0
            ? +this.drawStore[this.drawStore.length - 1].id + 1
            : +this.polygonArr[this.polygonArr.length - 1].id + 1;
        event.feature.id = id;
        this.drawStore.push({
          id,
          data: event.feature.getGeometry().getCoordinates()[0],
        });
      });
      const modify = new Modify({ source: myVectorSource });
      modify.addEventListener("modifyend", (event) => {
        console.log(event.features);
        const id = event.features.array_[0].id;
        const data = event.features.array_[0].getGeometry().getCoordinates()[0];
        this.modifyStore.push({ id, data });
      });
      myModify = modify;
      myMap.addInteraction(modify);
      myMap.addInteraction(draw);
    },
    resetMap() {
      this.initPolygonArr();
      console.log(this.polyFeature);
      const vectorSource = new VectorSource({
        features: this.polyFeature,
      });
      /* if(this.polygonArr.length>0){
      this.initPolygonArr()
      console.log(this.polyFeature);
      vectorSource.addFeature(this.polyFeature[0])
      } */
      myVectorSource = vectorSource;
      this.initAllNode();
      const vectorLayer = this.initLayer(vectorSource);
      myMap.setLayers([baseLayer, vectorLayer]);
      myMap.removeInteraction(myDraw);
      myMap.removeInteraction(myModify);
      this.showBtn = false;
      this.drawStore = [];
      this.modifyStore = [];
    },
    savePoly() {
      myMap.removeInteraction(myDraw);
      myMap.removeInteraction(myModify);
      this.showBtn = false;
      if (this.drawStore.length) {
        this.polygonArr = [...this.polygonArr, ...this.drawStore];
        this.drawStore = [];
      }
      if (this.modifyStore.length) {
        this.modifyStore.forEach((item) => {
          this.polygonArr.forEach((item2) => {
            if (item.id == item2.id) {
              item2.data = item.data;
            }
          });
        });
        this.modifyStore = [];
      }
    },
  },
  watch: {
    nodeId: {
      handler(val) {
        const arr = this.nodeArr.filter((item) => item.id == val);
        if (this.rangeArr.length > 0) {
          this.rangeArr.forEach((item) => {
            myVectorSource.removeFeature(item);
          });
          this.rangeArr = [];
        }
        if (arr.length > 0) {
          arr.forEach((item) => {
            const rangeFeature = new Feature({
              geometry: new Point(
                transform(item.data, "EPSG:4326", "EPSG:3857")
              ),
              name: "Null Island",
              population: 4000,
              rainfall: 500,
            });
            const iconStyle = new Style({
              image: new Icon({
                size: [64, 64],
                src: `/images/map/范围-${item.color}.png`,
              }),
            });
            rangeFeature.setStyle(iconStyle);
            myVectorSource.addFeature(rangeFeature);
            this.rangeArr.push(rangeFeature);
          });
        }
      },
    },
  },
};
</script>
<style scoped lang="scss">
.map-index  {
    width: 1170px;
    height: 396px;
    border-radius: 15px;
    background-color: skyblue
}
#map-index {
  position: relative;
  margin: 20px 0;
  width: 1170px;
  height: 396px;
  border-radius: 15px;
  .control {
    position: absolute;
    display: flex;
    flex-direction: column;
    z-index: 1;
    left: 25px;
    bottom: 25px;
    width: 30px;
    height: 91px;
    background: #ffffff;
    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.25);
    border-radius: 8px;
    .location,
    .zoom-in,
    .zoom-out {
      line-height: 30px;
      font-size: 18px;
      flex: 1;
      cursor: pointer;
    }
    .location {
      background: #11aa66;
      border-radius: 8px 8px 0 0;
      color: #fff;
    }
  }
  .el-input {
    position: absolute;
    z-index: 1;
    top: 15px;
    left: 15px;
    width: 205px;
    height: 35px;
    ::v-deep input {
      width: 100%;
      height: 100%;
      &:focus {
        border-color: #11aa66 !important;
      }
    }
  }
  .range {
    position: absolute;
    left: 25px;
    bottom: 126px;
    width: 30px;
    height: 30px;
    background: #11aa66;
    color: #fff;
    border-radius: 8px;
    cursor: pointer;
    z-index: 1;
    line-height: 30px;
  }
  .save {
    position: absolute;
    z-index: 3;
    top: 15px;
    right: 113px;
    width: 87px;
    height: 35px;
    background: #11aa66;
    border: 1px solid #11aa66;
    border-radius: 8px;
    color: #fff;
    font-size: 12px;
    line-height: 36px;
    cursor: pointer;
  }
  .cancel {
    position: absolute;
    z-index: 3;
    top: 15px;
    right: 20px;
    width: 87px;
    height: 35px;
    background: #fff;
    border: 1px solid #11aa66;
    border-radius: 8px;
    color: #4f4f4f;
    font-size: 12px;
    line-height: 36px;
    cursor: pointer;
  }
}
</style>
<style>
.ol-zoom {
  display: none !important;
}
</style>