基于openlayers6的基本地圖操作--4. 添加彈出框popup

實(shí)現(xiàn)map點(diǎn)擊它浅,添加彈出框popup醋寝,其實(shí)質(zhì)是Overlay

引入需要的組件

import Overlay from 'ol/Overlay';

創(chuàng)建popup

  • 創(chuàng)建div
    <div id="popup"></div>
  • 創(chuàng)建popup實(shí)例
var element = document.getElementById('popup');
var popup = new Overlay({
  element: element,
  positioning: 'bottom-center',
  stopEvent: false,
  offset: [0, -50]
});
map.addOverlay(popup);
  • map點(diǎn)擊處,添加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的實(shí)現(xiàn)過程封裝成組件谴仙,方便重復(fù)利用

  • popup.js: 實(shí)現(xiàn)添加的業(yè)務(wù)方法集合
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: 設(shè)置樣式
.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="點(diǎn)擊查看詳情" 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>

控制顯隱的實(shí)現(xiàn)方法

  • 主要實(shí)現(xiàn)方法
/**
 * 彈出框
 */
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);
  }
}
  • 組件中應(yīng)用
<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="時(shí)間:">
              <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="選擇結(jié)束日期" 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="時(shí)段降雨量" value="1"></el-option>
                <el-option label="整點(diǎn)降雨量" 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">時(shí)間段:{{form.startTime}}-{{form.endTime}} 累計(jì)雨量:{{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 標(biāo)題前icon {
  height: 30px;
  width: 32px;
  background-position: 0 0;
}
@mixin 直方圖 {
  height: 75px;
  width: 295px;
  background-position: -32px 0;
}
@mixin 雨量報(bào)表 {
  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 標(biāo)題前icon;
}
.rain-info {
  @include rain-popup;
  @include 基本信息;
}
.rain-echarts {
  @include rain-popup;
  @include 直方圖;
}
.rain-table {
  @include rain-popup;
  @include 雨量報(bào)表;
}
.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>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屋休,一起剝皮案震驚了整個(gè)濱河市雷袋,隨后出現(xiàn)的幾起案子持搜,更是在濱河造成了極大的恐慌密似,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葫盼,死亡現(xiàn)場離奇詭異残腌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贫导,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門抛猫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人孩灯,你說我怎么就攤上這事闺金。” “怎么了峰档?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵败匹,是天一觀的道長。 經(jīng)常有香客問我讥巡,道長哎壳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任尚卫,我火速辦了婚禮,結(jié)果婚禮上尸红,老公的妹妹穿的比我還像新娘吱涉。我一直安慰自己,他們只是感情好外里,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布怎爵。 她就那樣靜靜地躺著,像睡著了一般盅蝗。 火紅的嫁衣襯著肌膚如雪鳖链。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音芙委,去河邊找鬼逞敷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛灌侣,可吹牛的內(nèi)容都是我干的推捐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼侧啼,長吁一口氣:“原來是場噩夢啊……” “哼牛柒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痊乾,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤皮壁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哪审,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛾魄,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年协饲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畏腕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茉稠,死狀恐怖描馅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情而线,我是刑警寧澤铭污,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站膀篮,受9級特大地震影響嘹狞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜誓竿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一磅网、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筷屡,春花似錦涧偷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扼倘,卻和暖如春确封,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工爪喘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颜曾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓腥放,卻偏偏與公主長得像泛啸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子秃症,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,149評論 0 1
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    小姜先森o0O閱讀 9,474評論 0 72
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    35eeabfa0772閱讀 3,268評論 7 12
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    王喂馬_閱讀 6,453評論 1 77
  • 我自幼喜歡看武俠候址,喜歡抱打不平,喜歡恩怨分明种柑,多少年岗仑,我都遵循只要開心就好,隱忍是我不愿意做的事聚请,只是有了孩子后荠雕,...
    悠然_3c09閱讀 262評論 1 3