From 659e5933157c15d4df0392a20993562772c44017 Mon Sep 17 00:00:00 2001 From: Swanky <413564165@qq.com> Date: Mon, 4 Mar 2024 22:58:45 +0800 Subject: [PATCH] 1 --- components/layer-checkbox.vue | 74 +++++++++ main.js | 2 + pages/index/index.vue | 280 ++++++++++++++++++++-------------- static/layer-cd.png | Bin 0 -> 2872 bytes static/layer-ffzy.png | Bin 0 -> 3849 bytes static/layer-stxfgc.png | Bin 0 -> 3082 bytes static/layer-zzy.png | Bin 0 -> 2970 bytes 7 files changed, 238 insertions(+), 118 deletions(-) create mode 100644 components/layer-checkbox.vue create mode 100644 static/layer-cd.png create mode 100644 static/layer-ffzy.png create mode 100644 static/layer-stxfgc.png create mode 100644 static/layer-zzy.png diff --git a/components/layer-checkbox.vue b/components/layer-checkbox.vue new file mode 100644 index 0000000..2d2d925 --- /dev/null +++ b/components/layer-checkbox.vue @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/main.js b/main.js index 5fc19d9..6224581 100644 --- a/main.js +++ b/main.js @@ -2,8 +2,10 @@ import Vue from 'vue' import App from './App' import imageButton from './components/image-button.vue' import customAttr from './components/custom-attr.vue' +import layerCheckbox from './components/layer-checkbox' Vue.component('image-button', imageButton) Vue.component('custom-attr', customAttr) +Vue.component('layer-checkbox', layerCheckbox) Vue.config.productionTip = false App.mpType = 'app' diff --git a/pages/index/index.vue b/pages/index/index.vue index e60a6f1..746ee77 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -32,14 +32,19 @@ 图层叠加 - - + + + + - 详情 + {{currentClickLayerItem?currentClickLayerItem.text:''}}详情 关闭 @@ -106,35 +111,54 @@ mapData: { center: [102.45438, 32.53223] }, + currentLayers: [], currentLayer: null, layerItems: [{ - text: '生态修复工程图层', - value: 'stxfgc' + text: '生态修复工程', + value: 'stxfgc', + icon: 'stxfgc', + zIndex: 99, + detailUrl: '/stxh/details' }, { - text: '征占用图层', - value: 'cdzzy_view' + text: '征占用', + value: 'cdzzy_view', + icon: 'zzy', + zIndex: 88, + detailUrl: '/cdzhy/details' }, { - text: '非法占用图层', - value: 'ffzy_layer' + text: '非法占用', + value: 'ffzy_layer', + icon: 'ffzy', + zIndex: 77, + detailUrl: '/cdzhy/ffzyDetails' }, { - text: '草地图层', - value: 't_grassland_result' + text: '草地', + value: 't_grassland_result', + icon: 'cd', + zIndex: 66, + detailUrl: '/cdzy/cdDetails' }], detailItems: [], detailGroups: [], currentGroupTab: null, token: '', - measureStatus: '' + measureStatus: '', + currentClickLayerItem: null } }, watch: { - currentLayer(newVal, oldVal) { + currentLayers(newVal, oldVal) { const map = this.$map; console.log(newVal, oldVal, map); - this.$refs.popup.close() if (newVal) { this.mapData = { - layerName: newVal + layerOpts: newVal?.map(val => { + const item = this.layerItems.find(l => l.value === val); + return { + layerName: val, + ...item + } + }) } } @@ -149,6 +173,14 @@ }) }, methods: { + checkLayer(value) { + const index = this.currentLayers.findIndex(l => l === value); + if (index > -1) { + this.currentLayers.splice(index, 1); + } else { + this.currentLayers.push(value) + } + }, closeMeasureStatus() { this.measureStatus = '' this.mapData = {} @@ -177,7 +209,9 @@ }, showFfzy(id) { console.log(id) - this.currentLayer = 'ffzy_layer' + if (!this.currentLayers.find(l => l === 'ffzy_layer')) { + this.currentLayers.push('ffzy_layer') + } uni.request({ url: `${helper.serverUrl}/ffzy/ffzy/${id}`, header: { @@ -292,72 +326,66 @@ showLayerModal() { this.$refs.popup.open('bottom') }, + _request(index, wkt, apis, callback) { + if (apis[index]) { + uni.request({ + url: `${helper.mgServerUrl}${apis[index]}?wkt=${wkt}`, + success: (resp2) => { + console.log(resp2) + if (resp2?.data?.data?.dyColumn?.length > 0) { + const layerItem = this.layerItems.find(item => item.detailUrl === apis[index]); + this.currentClickLayerItem = layerItem; + callback(resp2?.data?.data, layerItem) + } else { + this._request(++index, wkt, apis, callback) + } + } + }) + } else { + callback(); + } + }, requestDetail({ - wkt, - url + wkt }) { - uni.request({ - url, - success: (resp) => { - console.log(resp?.data?.features?.[0]) - if (resp?.data?.features?.[0]) { + // if (resp?.data?.features?.[0]) { + // this.mapData = { + // highLightData: resp?.data?.features?.[0] + // } + + // } + const apis = []; + this.layerItems.forEach(item => { + const layerStr = this.currentLayers.find(l => l === item.value); + if (layerStr) { + apis.push(item.detailUrl); + } + }); + this._request(0, wkt, apis, (resp) => { + if (resp) { + if (resp.geom) { this.mapData = { - highLightData: resp?.data?.features?.[0] - } - let apiStr = ''; - switch (this.currentLayer) { - case 'stxfgc': - apiStr = '/stxh/details'; - break; - case 't_grassland_result': - apiStr = '/cdzy/cdDetails'; - break; - case 'cdzzy_view': - apiStr = '/cdzhy/details'; - break; - case 'ffzy_layer': - apiStr = '/cdzhy/ffzyDetails'; - break; + highLightWkt: resp.geom } - if (apiStr) { - uni.request({ - url: `${helper.mgServerUrl}${apiStr}?wkt=${wkt}`, - success: (resp2) => { - console.log(resp2) - const groups = _.groupBy(resp2?.data?.data - .dyColumn, 'tab'); - this.detailGroups = _.keys(groups).map(key => { - return { - tab: key, - children: groups[key]?.map(item => { - return { - ...item, - value: item.value || '' - } - }) - } - }); - this.currentGroupTab = this.detailGroups?.[0]?.tab; - this.$refs.popupDetail.open('bottom'); + + } + const groups = _.groupBy(resp.dyColumn, 'tab'); + this.detailGroups = _.keys(groups).map(key => { + return { + tab: key, + children: groups[key]?.map(item => { + return { + ...item, + value: item.value || '' } }) } - } - // const props = resp?.data?.features?.[0]?.properties; - // if (helper.layerDetails[this.currentLayer]) { - // this.detailItems = helper.layerDetails[this.currentLayer].map(item => { - // return { - // ...item, - // value: props[item.field] - // } - // }); - // this.$refs.popupDetail.open('bottom'); - // } - }, - fail: (resp) => { - console.log(resp) + }); + this.currentGroupTab = this.detailGroups?.[0]?.tab; + this.$refs.popupDetail.open('bottom'); + } - }) + }); } } } @@ -446,30 +474,49 @@ maxZoom: 18 }); } - if (newValue.layerName) { - const layer = new Image({ - id: 'business-layer', - source: new ImageWMS({ - ratio: 1, - url: `${helper.geoserverUrl}/geoserver/yzt/wms`, - params: { - 'FORMAT': 'image/png', - 'VERSION': '1.1.1', - "STYLES": '', - "LAYERS": `yzt:${newValue.layerName}`, - "exceptions": 'application/vnd.ogc.se_inimage', - } + if (newValue.layerOpts) { + const businessLayers = map.getAllLayers().filter(l => { + return l.get('businessId') === 'business-layer'; + }) || [] + const layers = newValue.layerOpts.map(opt => { + let layer = businessLayers.find(l => { + return l.get('businessName') === opt.layerName; }) - }); + if (!layer) { + layer = new Image({ + businessId: 'business-layer', + businessName: opt.layerName, + source: new ImageWMS({ + ratio: 1, + url: `${helper.geoserverUrl}/geoserver/yzt/wms`, + params: { + 'FORMAT': 'image/png', + 'VERSION': '1.1.1', + "STYLES": '', + "LAYERS": `yzt:${opt.layerName}`, + "exceptions": 'application/vnd.ogc.se_inimage', + } + }), + zIndex: opt.zIndex + }); + businessLayers.push(layer); + map.addLayer(layer); + } else { + layer.setVisible(true) + } + return layer; + }) vectorLayer.getSource().clear(); - map.removeLayer(map.getAllLayers().find(layer => { - - return layer.get('id') === 'business-layer' - })) - map.addLayer(layer); + businessLayers.forEach(layer => { + const index = newValue.layerOpts.findIndex(opt => opt.layerName === layer.get( + 'businessName')); + if (index === -1) { + layer.setVisible(false); + } + }) } - if (newValue.highLightData) { - const feature = new GeoJSON().readFeature(newValue.highLightData) + if (newValue.highLightWkt) { + const feature = new WKT().readFeature(newValue.highLightWkt) feature.setStyle(new Style({ fill: new Fill({ color: 'rgba(0,0,0,0)', @@ -547,7 +594,7 @@ vectorLayer = new VectorLayer({ id: 'v-layer', source: new VectorSource(), - zIndex: 99 + zIndex: 999 }) map.addLayer(vectorLayer); map.on('singleclick', evt => { @@ -557,28 +604,25 @@ }) }, showByWkt(coordinate) { - const source = map.getAllLayers().find(l => l.get('id') === 'business-layer')?.getSource(); - if (source) { - const view = map.getView(); - const viewResolution = view.getResolution(); - const [x1] = map.getCoordinateFromPixel([0, 0]); - const [x2] = map.getCoordinateFromPixel([10, 0]); - const radius = x2 - x1; - const circle = new Circle(coordinate, radius); - const polygon = fromCircle(circle); - const wkt = new WKT().writeGeometry(polygon); - const url = source.getFeatureInfoUrl( - coordinate, viewResolution, view.getProjection(), { - 'INFO_FORMAT': 'application/json', - 'FEATURE_COUNT': 50 - }); - if (url) { - this.ownerInstance?.callMethod('requestDetail', { - wkt: wkt, - url - }) - } - } + // const source = map.getAllLayers().find(l => l.get('id') === 'business-layer')?.getSource(); + // if (source) { + const view = map.getView(); + const viewResolution = view.getResolution(); + const [x1] = map.getCoordinateFromPixel([0, 0]); + const [x2] = map.getCoordinateFromPixel([10, 0]); + const radius = x2 - x1; + const circle = new Circle(coordinate, radius); + const polygon = fromCircle(circle); + const wkt = new WKT().writeGeometry(polygon); + // const url = source.getFeatureInfoUrl( + // coordinate, viewResolution, view.getProjection(), { + // 'INFO_FORMAT': 'application/json', + // 'FEATURE_COUNT': 50 + // }); + this.ownerInstance?.callMethod('requestDetail', { + wkt: wkt + }) + // } } } } diff --git a/static/layer-cd.png b/static/layer-cd.png new file mode 100644 index 0000000000000000000000000000000000000000..e4acca8c1bd77d42f86b1ebe7b188b45bfe9e1dd GIT binary patch literal 2872 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 YAA9{laCb~h#{d8T07*qoM6N<$g18TUO#lD@ literal 0 HcmV?d00001 diff --git a/static/layer-zzy.png b/static/layer-zzy.png new file mode 100644 index 0000000000000000000000000000000000000000..07bd5cc4f915b5ca0ebe06a9016bb390998ef441 GIT binary patch literal 2970 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 literal 0 HcmV?d00001