123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- <template>
- <div>
- <div id="toolBar" class="toolBar ol-unselectable">
- <ul class="nav nav-pills">
- <li v-if="isRes"
- @click="resShow=!resShow;coordsShow=false;measureShow=false;queryShow=false;drawShow = false;">
- <a><img
- src="@/assets/layers.png" width="24"> 图层</a></li>
- <res-catalog v-if="isRes" id="resourceCatalog" v-model="resShow"></res-catalog>
- <li v-if="isQuery" @click="queryShow=!queryShow; resShow=false;coordsShow=false;measureShow=false;drawShow = false;">
- <a><img src="@/assets/query.png" width="24"> 查询</a>
- </li>
- <query-tool v-if="isQuery" id="queryTool" ref="queryTool" v-model="queryShow"></query-tool>
- <li v-if="isCoords"
- @click="coordsShow=!coordsShow;resShow=false;measureShow=false;queryShow=false;drawShow = false;">
- <a><img
- src="@/assets/locationTool.png" width="24"> 定位</a></li>
- <coords-locate v-if="isCoords" id="coordsLocate" ref="coordsLocate"
- v-model="coordsShow"></coords-locate>
- <!-- <li v-if="isExtent" id="zoomToFullExtent" @click="zoomToFullExtent"><a><img src="@/assets/ZoomFullExtent.png" width="24">
- 全图</a></li>-->
- <li v-if="isMeasure" @click="handleMeasure"><a><img src="@/assets/measureTool.png" width="24"> 测量</a>
- </li>
- <measure-tool v-if="isMeasure" ref="measureToll" id="measureTool" v-model="measureShow"
- :output.sync="output"></measure-tool>
- <li v-if="isDraw" @click="handleDrawTool"><a><img
- src="@/assets/drawPencil.png" width="24"> 标绘</a></li>
- <draw-tool v-if="isDraw" ref="drawTool" id="drawTool" v-model="drawShow"></draw-tool>
- <li v-if="isClear" id="clearTool" @click="handleClear"><a><img src="@/assets/clear.png" width="24">
- 清除</a></li>
- </ul>
- </div>
- <!-- 点选查询弹框-->
- <div class="ant-popover ant-popover-placement-top popup" id="popup" ref="popup" v-show="tabs.length!==0">
- <div class="ant-popover-content">
- <div class="ant-popover-arrow"></div>
- <div role="tooltip" class="ant-popover-inner">
- <div>
- <div class="ant-popover-inner-content">
- <div style="width: 320px">
- <a-tabs default-active-key="1" tab-position="top" :style="{ 'min-height': '200px' }">
- <a-tab-pane v-for="(tab,i) in tabs" :key="i" :tab="tab.name">
- <a-descriptions bordered :column='1'>
- <a-descriptions-item v-for="(item,index) in tab.inner" :label="item.label">
- {{ item.content }}
- </a-descriptions-item>
- </a-descriptions>
- </a-tab-pane>
- </a-tabs>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import * as olEasing from 'ol/easing';
- import axios from "axios";
- import Overlay from "ol/Overlay";
- import {getAction} from "../../../api/manage";
- // 组件
- import CoordsLocate from '@/components/BasicMap/Tools/CoordsLocate.vue';
- import ResCatalog from "@/components/BasicMap/Tools/ResCatalog";
- import MeasureTool from '@/components/BasicMap/Tools/MeasureTool.vue'
- import QueryTool from '@/components/BasicMap/Tools/QueryTool.vue'
- import DrawTool from '@/components/BasicMap/Tools/DrawTool.vue';
- import {DragBox} from "ol/interaction";
- import {platformModifierKeyOnly} from "ol/events/condition";
- export default {
- name: 'Toolbar',
- components: {
- CoordsLocate,
- ResCatalog,
- MeasureTool,
- QueryTool,
- DrawTool
- },
- data() {
- return {
- isRes: false,
- isQuery: false,
- isCoords: false,
- isMeasure: false,
- isDraw: false,
- isClear: false,
- isExtent: false,
- coordsShow: false,
- resShow: false,
- measureShow: false,
- queryShow: false,
- drawShow: false,
- properties: {},
- labels: [],
- tabs: [],
- map: {},
- currentCoordinate: null, // 弹窗坐标数据
- overlay: null,
- mapCursorKey: '',
- output: '',
- dataport: '',
- relfield: '',
- }
- },
- props: {
- tools: {
- type: Array,
- default: function () {
- return []
- }
- },
- splitScreen: {}
- },
- mounted() {
- if (this.tools.length === 0) {
- this.isRes = true;
- this.isClear = true;
- this.isDraw = true;
- this.isCoords = true;
- this.isExtent = true;
- this.isMeasure = true;
- this.isQuery = true;
- } else {
- this.tools.forEach((item) => {
- this[item] = true;
- })
- }
- // this.initPopup();
- },
- watch: {
- measureShow: function (newValue) {
- if (newValue === false) {
- this.$refs.measureToll.closeMeasureTool(this.baseMap.map);
- this.baseMap.map.getOverlays().clear();
- if (this.drawShow === false) {
- this.initPopup();
- }
- } else {
- //移除点击事件
- this.map.un(this.mapCursorKey.type, this.mapCursorKey.listener);
- this.overlay.setPosition(undefined);
- this.currentCoordinate = null;
- }
- }
- },
- provide() {
- return {
- splitScreen: this.splitScreen,
- }
- },
- inject: ['baseMap'],
- methods: {
- handleDrawTool() {
- this.measureShow = false;
- this.coordsShow = false;
- this.resShow = false;
- this.queryShow = false;
- this.drawShow = !this.drawShow;
- if (this.drawShow) {
- this.baseMap.map.getOverlays().clear();
- this.$refs.drawTool.initDrawLayer();
- // initVectorLayer(this.baseMap.map);
- // this.output = initMeasureTool();
- }
- },
- handleMeasure() {
- this.measureShow = !this.measureShow;
- this.coordsShow = false;
- this.resShow = false;
- this.queryShow = false;
- this.drawShow = false;
- if (this.measureShow) {
- this.baseMap.map.getOverlays().clear();
- this.$refs.measureToll.onChange();
- // initVectorLayer(this.baseMap.map);
- // this.output = initMeasureTool();
- }
- },
- handleClear() {
- this.measureShow = false;
- this.coordsShow = false;
- this.resShow = false;
- this.queryShow = false;
- this.drawShow = false;
- this.$refs.measureToll.closeMeasureTool(this.baseMap.map);
- this.$refs.coordsLocate.resetForm();
- this.$refs.queryTool.clear();
- this.$refs.drawTool.clearFeature();
- },
- zoomToFullExtent() {
- let extent = [115.75550079345703, 36.407955169677734, 117.60053253173828, 38.01062774658203];
- this.baseMap.map.getView().fit(extent, {
- // size:[500,300],
- duration: 500,
- padding: [10, 10, 10, 10],
- easing: olEasing.inAndOut
- })
- },
- // 递归查找
- getTreeExpandKeys(obj, name) {
- // obj是传入的array
- if (obj && obj.length !== 0) {
- obj.forEach((item, index) => {
- if (item.alias === name) {
- this.labels = item.fields;
- this.relfield = item.relfield;
- this.dataport = item.dataport;
- return;
- }
- // 如果此列表有children, 进行递归
- if (item.layers) {
- this.getTreeExpandKeys(item.layers, name)
- }
- })
- }
- },
- initPopup() {
- // 弹窗
- this.overlay = new Overlay({
- element: this.$refs.popup, // 弹窗标签,在html里
- autoPan: true, // 如果弹窗在底图边缘时,底图会移动
- autoPanAnimation: { // 底图移动动画
- duration: 250
- },
- });
- this.map = this.baseMap.map;
- this.map.addOverlay(this.overlay);
- this.mapClick() // 初始化地图成功后,给地图添加点击事件
- const dragBox = new DragBox({
- condition: platformModifierKeyOnly,
- });
- this.map.addInteraction(dragBox);
- dragBox.on('boxend', (evt) => {
- const extent = dragBox.getGeometry().getExtent();
- let queryLayer = this.getVisibleLayers();
- if (queryLayer.length === 0) return;
- queryLayer.forEach((item) => {
- let vectorSource = item.layer.getSource();
- /*const boxFeatures = vectorSource
- .getFeaturesInExtent(extent)
- .filter((feature) => feature.getGeometry().intersectsExtent(extent));*/
- // console.log(boxFeatures);
- })
- });
- },
- mapClick() { // 地图点击事件
- // 通过 map.on() 监听,singleclick 是单击的意思。也可以用 click 代替 singleclick。
- this.mapCursorKey = this.map.on('singleclick', evt => {
- this.currentCoordinate = evt.coordinate; // 获取坐标
- this.tabs = [];
- let viewResolution = this.map.getView().getResolution();
- // 获取可查的图层
- let queryLayer = this.getVisibleLayers();
- if (queryLayer.length === 0) return;
- queryLayer.forEach((item) => {
- let url = item.layer.getSource().getFeatureInfoUrl(
- this.currentCoordinate,
- viewResolution,
- 'EPSG:4490',
- {
- 'INFO_FORMAT': 'application/json', //geoserver支持jsonp才能输出为jsonp的格式
- 'FEATURE_COUNT': 50 //点击查询能返回的数量上限
- });
- axios({url, method: 'get'})
- .then(async (res) => {
- let {status, data: {features}} = res;
- if (status === 200) {
- if (features.length === 0) return;
- this.properties = features[0].properties;
- this.getTreeExpandKeys(this.baseMap.list, item.name);
- let labels = this.labels;
- if (this.dataport) {
- let {
- message,
- success,
- result
- } = await getAction(this.dataport, {id: this.properties[this.relfield]});
- if (success) {
- this.properties = result;
- } else {
- this.$message.error(message);
- return;
- }
- this.dataport = '';
- }
- if (labels.length > 0) {
- labels.forEach((itemA) => {
- itemA.content = this.properties[itemA.name];
- });
- let tab = {name: item.name, inner: labels};
- this.tabs.push({...tab});
- setTimeout(() => {
- // 设置弹窗位置
- // 这里要设置定时器, 不然弹窗首次出现, 底图会跑偏
- this.overlay.setPosition(this.currentCoordinate);
- }, 0)
- }
- } else {
- console.log('错误');
- }
- });
- })
- });
- },
- getVisibleLayers(layerName) {
- let layer = [];
- let item = {};
- let layers = this.map.getLayers();
- let layerCount = layers.getLength();
- for (let i = 0; i < layerCount; i++) {
- let visible = layers.item(i).get('visible');
- let name = layers.item(i).get('alias');
- if (visible && name) {
- item = {name, 'layer': layers.item(i)}
- layer.push(item);
- }
- }
- return layer;
- },
- }
- }
- </script>
- <style scoped="scoped">
- .toolBar {
- position: absolute;
- top: 0.8em;
- left: 5em;
- border-radius: 4px;
- padding: 0;
- margin: 0;
- background-color: whitesmoke;
- cursor: pointer;
- z-index: 1;
- box-shadow: 0 0 5px #357ee5;
- opacity: 0.9;
- }
- .nav {
- padding-left: 0;
- margin-bottom: 0;
- list-style: none;
- display: flex;
- }
- .nav-pills > li {
- float: left;
- }
- .nav > li {
- position: relative;
- display: block;
- }
- .nav-pills > li + li {
- margin-left: 2px;
- }
- .nav-pills > li > a {
- border-radius: 4px;
- }
- .nav > li > a {
- position: relative;
- display: block;
- padding: 10px 15px;
- }
- .nav > li > a:hover,
- .nav > li > a:focus {
- text-decoration: none;
- background-color: #eeeeee;
- }
- a {
- color: #337ab7;
- text-decoration: none;
- }
- .nav > li > a > img {
- max-width: none;
- }
- img {
- vertical-align: middle;
- }
- #measureTool, #drawTool {
- position: absolute;
- top: 52px;
- left: 0px;
- }
- #coordsLocate {
- position: absolute;
- top: 52px;
- left: 0;
- }
- #resourceCatalog {
- position: absolute;
- top: 52px;
- left: 0;
- }
- #queryTool {
- position: absolute;
- top: 52px;
- left: 0;
- }
- </style>
|