美文网首页
基于openlayers6的基本地图操作--4. 添加弹出框po

基于openlayers6的基本地图操作--4. 添加弹出框po

作者: 初见_JS | 来源:发表于2020-02-14 21:04 被阅读0次

    实现map点击,添加弹出框popup,其实质是Overlay

    引入需要的组件

    import Overlay from 'ol/Overlay';

    创建popup

    • 创建div
      <div id="popup"></div>
    • 创建popup实例
    var element = document.getElementById('popup');
    var popup = new Overlay({
      element: element,
      positioning: 'bottom-center',
      stopEvent: false,
      offset: [0, -50]
    });
    map.addOverlay(popup);
    
    • map点击处,添加popup
    // display popup on click
    map.on('click', function(evt) {
      var feature = map.forEachFeatureAtPixel(evt.pixel,
        function(feature) {
          return feature;
        });
      if (feature) {
        var coordinates = feature.getGeometry().getCoordinates();
        popup.setPosition(coordinates);
        $(element).popover({
          placement: 'top',
          html: true,
          content: feature.get('name')
        });
        $(element).popover('show');
      } else {
        $(element).popover('destroy');
      }
    });
    

    封装成vue组件

    popup的实现过程封装成组件,方便重复利用

    • popup.js: 实现添加的业务方法集合
    import Overlay from 'ol/Overlay.js';
    import './popup.css'
    export class Popup {
      constructor(map, props) {
        this.map = map;
        this.container = props.container || null;
        this.content = props.content || '';
        this.addLayer()
      }
    
      addLayer() {
        if (this.container !== null) {
          this.popupLayer = new Overlay({
            element: this.container,
            autoPan: true,
            positioning: 'bottom-center',
            stopEvent: false,
            offset: [0, -20],
            autoPanAnimation: {
              duration: 250
            }
          });
          //this.map.addOverlay(this.popupLayer);
        }
      }
    
      addPopup(coordinate) {
        this.popupLayer.setPosition(coordinate);
        this.map.addOverlay(this.popupLayer);
      }
    
      removePopup() {
        this.popupLayer.setPosition(undefined);
        this.map.removeOverlay(this.popupLayer);
        return false;
      }
    
      setContent(content) {
        this.content.innerHTML = content;
      }
    
      clear() {
        if (this.popupLayer) {
          this.map.removeOverlay(this.popupLayer);
        }
      }
    }
    
    • popup.css: 设置样式
    .ol-popup {
      background-color: rgba(0, 23, 55, 0.6);
      border-radius: 5px;
      color: white;
      box-shadow: 0 4px 14px rgba(7, 154, 238, 0.35);
      border-radius: 4px;
      width: 310px;
    }
    
    .popup-title {
      border-bottom: 1px solid #eee;
      padding: 10px;
    }
    
    .ol-popup-content{
      padding: 10px;
      font-size: 0.8em;
      line-height: 25px;
    }
    
    .ol-popup-closer {
      position: absolute;
      top: 12px;
      right: 6px;
    }
    
    
    • popupView.vue: 封装的vue组件
    <template>
        <div id="popup" class="ol-popup">
          <div class="popup-title">{{title}}</div>
          <div class="ol-popup-closer" @click="handleClose"><i class="el-icon-close"></i></div>
          <!-- <a href="#" id="popup-closer" class="ol-popup-closer" @click="handleClose"></a> -->
          <div id="popup-content" class="ol-popup-content">
            <a :href="pointImageURL" title="点击查看详情" target='_blank' v-show="type==='野外核查'">
              <img class="hecha-img" :src="pointImageURL" alt="" @error="handleImgError">
            </a>
            <div v-for="(val, key) in popupContent" :key="key">
              <el-row>
                <el-col :span="8" style="text-align: right;">{{key}}:</el-col>
                <el-col :span="16">{{val}}</el-col>
              </el-row>
            </div>
          </div>
        </div>
    </template>
    <script>
    import { PopupTool } from "./popup";
    
    export default {
      name: "OlPopup",
      data() {
        return {
          popup: null,
          defaultImg: "img/lake/no_photo.png"
        };
      },
      props: ["map", "title", "popupContent", "type", "pointURL"],
      components: {},
      computed: {
        pointImageURL() {
          return this.pointURL;
        }
      },
      watch: {
        map(val) {
          if (val) {
            this.init();
          }
        }
      },
      methods: {
        init() {
          let container = document.getElementById("popup");
          let content = document.getElementById("popup-content");
          // let closer = document.getElementById('popup-closer')
          this.popup = new PopupTool(this.map, {
            container: container,
            content: content
          });
        },
        handleClose() {
          if (this.popup) {
            this.popup.removePopup();
          }
        },
        addPopup(point) {
          this.popup.addPopup(point);
        },
        setPopupContent() {
          this.popup.setContent(this.popupContent);
        },
        handleImgError() {
          this.$emit("update:pointURL", "img/lake/no_photo.png");
          //this.$emit("update:type", "");
        }
      }
    };
    </script>
    <style scoped>
    .hecha-img {
        width: 291px;
        height: 150px;
    }
    </style>
    

    控制显隐的实现方法

    • 主要实现方法
    /**
     * 弹出框
     */
    import Overlay from 'ol/Overlay';
    export default {
      overlay: null,
      map: null,
      popupId: "",
      init(map, popupId) {
        /* if (this.popupId !== popupId) {
          
        } */
        this.add(map, popupId);
      },
      add(map, popupId) {
        this.container = document.getElementById(popupId);
        this.popupId = popupId;
        this.overlay = new Overlay({
          element: this.container,
          positioning: 'bottom-left',
          stopEvent: false,
          offset: [-50, -10],
          autoPan: true,
          autoPanAnimation: {
            duration: 250
          }
        });
        map.addOverlay(this.overlay);
      },
      open(coordinate) {
        this.overlay.setPosition(coordinate);
      },
      close() {
        this.overlay.setPosition(undefined);
      }
    }
    
    • 组件中应用
    <template>
      <div class="containerRainPopup" style="display: none;">
        <div id="popupRain" class="ol-popup" v-show="activePanelName === 'rain'">
          <div class="ol-popup-closer" @click="handleClose"></div>
          <div id="rain-popup-content">
            <el-row>
              <el-col :span="1">
                <div class="rain-title"></div>
              </el-col>
              <el-col :span="10" style="line-height: 28px;">{{queryInfo['测站名称']}}</el-col>
            </el-row>
            <el-row>
              <el-form ref="form" :model="form" label-width="60px" :inline="true">
                <el-form-item label="时间:">
                  <el-col :span="12">
                    <el-date-picker type="datetime" placeholder="选择开始日期" v-model="form.startTime"></el-date-picker>
                  </el-col>
                  <el-col :span="2" style="color: white;">至</el-col>
                  <el-col :span="10">
                    <el-date-picker type="datetime" placeholder="选择结束日期" v-model="form.endTime"></el-date-picker>
                  </el-col>
                </el-form-item>
                <el-form-item label="类型:">
                  <el-select
                    v-model="form.type"
                    placeholder="类型"
                    style="width: 120px;"
                    @change="handleSearch"
                  >
                    <el-option label="时段降雨量" value="1"></el-option>
                    <el-option label="整点降雨量" value="2"></el-option>
                    <el-option label="日降雨量" value="3"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item style="margin: 0;">
                  <el-button
                    type="primary"
                    class="search"
                    size="small"
                    style="margin: 0;"
                    @click="handleSearch"
                  >查询</el-button>
                </el-form-item>
              </el-form>
            </el-row>
            <el-row>
              <div class="basic-info" @click="handleBasicClick"></div>
              <div class="process-line" @click="handleProcessClick"></div>
              <div class="info-table" @click="handleTableClick"></div>
              <div class="line"></div>
              <div :class="currentClass"></div>
              <BasicInfoPanel :queryInfo="queryInfo" v-show="currentClass === 'rain-info'"></BasicInfoPanel>
              <HistoGram :rainData="rainData" v-show="currentClass === 'rain-echarts'"></HistoGram>
              <RainTablePanel :rainData="rainData" v-show="currentClass === 'rain-table'"></RainTablePanel>
              <div class="rain-time">时间段:{{form.startTime}}-{{form.endTime}} 累计雨量:{{totalRain}}mm</div>
            </el-row>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import PopupTool from "../Popup";
    import { mapGetters } from "vuex";
    import BasicInfoPanel from "./BasicInfoPanel";
    import HistoGram from "./HistoGram";
    import RainTablePanel from "./RainTablePanel";
    import { queryByPeriodAndTypeStcd } from "@/api/queryInfo";
    
    export default {
      name: "RainPopup",
      data() {
        return {
          popup: null,
          queryInfo: {},
          form: {
            startTime: "2020-04-07 08:00:00",
            endTime: "2020-04-07 12:00:00",
            type: "2"
          },
          stcd: "80813", // 测站编码
          currentClass: "rain-info",
          rainData: [],
          totalRain: 0
        };
      },
      props: ["map", "rainQueryInfo"],
      computed: {
        ...mapGetters(["activePanelName"])
      },
      components: {
        BasicInfoPanel,
        HistoGram,
        RainTablePanel
      },
      watch: {
        rainQueryInfo(newData) {
          if (newData) {
            if (this.activePanelName === "rain") {
              this.queryInfo = newData.info;
              this.stcd = this.queryInfo["测站编码"];
              this.addPopup(newData.point);
            }
          }
        },
        activePanelName(val) {
          if (val === "rain") {
            this.$nextTick(() => {
              this.init();
            });
          }
        },
        rainData(val) {
          let pArray = [];
          val.forEach(item => {
            pArray.push(item.drpData);
          });
          this.totalRain = eval(pArray.join("+"));
        }
      },
      methods: {
        init() {
          PopupTool.init(this.map, "popupRain");
        },
        handleClose() {
          PopupTool.close();
          this.currentClass = "rain-info";
        },
        addPopup(point) {
          PopupTool.open(point);
        },
        handleBasicClick() {
          this.currentClass = "rain-info";
        },
        handleProcessClick() {
          this.currentClass = "rain-echarts";
          this.handleSearch();
        },
        handleTableClick() {
          this.currentClass = "rain-table";
        },
        handleSearch() {
          queryByPeriodAndTypeStcd(
            this.form.endTime,
            this.form.startTime,
            this.stcd,
            this.form.type
          ).then(res => {
            this.rainData = res.data.data;
          });
        }
      }
    };
    </script>
    
    <style scoped lang="scss">
    #popupRain {
      width: 730px;
    }
    /* #popupRain:after {
      border-top-color: rgba(2, 30, 80, 0.8);
      border-width: 10px;
      left: 380px;
      margin-left: -10px;
    } */
    @mixin rain-popup {
      background: url(~img/queryInfo/rain-popup.png) no-repeat;
    }
    @mixin 标题前icon {
      height: 30px;
      width: 32px;
      background-position: 0 0;
    }
    @mixin 直方图 {
      height: 75px;
      width: 295px;
      background-position: -32px 0;
    }
    @mixin 雨量报表 {
      height: 75px;
      width: 295px;
      background-position: -327px 0;
    }
    @mixin 基本信息 {
      height: 75px;
      width: 295px;
      background-position: -622px 0;
    }
    @mixin info() {
      height: 45px;
      position: absolute;
      width: 76px;
      margin-left: 20px;
      cursor: pointer;
    }
    
    .rain-title {
      @include rain-popup;
      @include 标题前icon;
    }
    .rain-info {
      @include rain-popup;
      @include 基本信息;
    }
    .rain-echarts {
      @include rain-popup;
      @include 直方图;
    }
    .rain-table {
      @include rain-popup;
      @include 雨量报表;
    }
    .basic-info {
      @include info;
    }
    .process-line {
      @include info;
      margin-left: 116px;
    }
    .info-table {
      @include info;
      margin-left: 207px;
    }
    .line {
      height: 40px;
      position: absolute;
      width: 427px;
      margin-left: 295px;
      border-bottom: 1px solid #047edb;
    }
    .rain-time {
      color: #fbc515;
      margin: 20px 0px 0 20px;
    }
    </style>
    

    相关文章

      网友评论

          本文标题:基于openlayers6的基本地图操作--4. 添加弹出框po

          本文链接:https://www.haomeiwen.com/subject/akgdfhtx.html