实现
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>
网友评论