| @@ -0,0 +1,409 @@ | |||
| <template> | |||
| <div class="land-map-container"> | |||
| <!-- 地图容器 --> | |||
| <div id="mapWrap" class="map-wrap"></div> | |||
| <!-- 地图操作按钮 --> | |||
| <div id="land-btn-wrap" class="map-btn-wrap"> | |||
| <el-row> | |||
| <input id="drawPolygon" class="ant-btn ant-btn-red" type="button" value="画图" click="handleDrawPolygon"/> | |||
| <input id="drawReset" type="button" class="ant-btn ant-btn-red" value="还原" @click="handleDrawReset"/> | |||
| </el-row> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import ol from 'ol' // 确保项目已引入OpenLayers | |||
| import $ from 'jquery' | |||
| export default { | |||
| name: 'LandMapComponent', | |||
| props: { | |||
| // 地图配置参数 | |||
| mapConfig: { | |||
| type: Object, | |||
| required: true, | |||
| default: () => ({ | |||
| geoServerUrl: '', // GeoServer地址 | |||
| landLayerName: '', // 地块图层名 | |||
| villageBorderLayerName: '', // 村边界图层名 | |||
| centerLng: 115.452752, // 默认中心点经度 | |||
| centerLat: 31.789033, // 默认中心点纬度 | |||
| zoom: 17.8, // 默认缩放级别 | |||
| maxZoom: 18.3, // 最大缩放级别 | |||
| minZoom: 0 // 最小缩放级别 | |||
| }) | |||
| }, | |||
| // 目标地块数据(用于定位和高亮) | |||
| targetLand: { | |||
| type: Object, | |||
| default: () => ({ | |||
| fid: '', | |||
| theGeom: '', // 地块几何信息 | |||
| importCode: '' // 用于筛选村边界的编码 | |||
| }) | |||
| }, | |||
| // 其他地块数据(用于加载已有地块图层) | |||
| otherLands: { | |||
| type: Array, | |||
| default: () => [] | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| map: null, // 地图实例 | |||
| draw: null, // 绘制实例 | |||
| vectorDrawingLayer: null, // 绘制图层 | |||
| targetLandLayer: null, // 目标地块高亮图层 | |||
| otherLandsLayer: null, // 其他地块图层 | |||
| villageBorderLayer: null, // 村边界图层 | |||
| drawResult: null // 绘制结果(几何坐标) | |||
| } | |||
| }, | |||
| watch: { | |||
| // 监听地块数据变化,重新加载图层 | |||
| targetLand: { | |||
| deep: true, | |||
| handler(newVal) { | |||
| this.initTargetLandLayer(newVal) | |||
| this.initVillageBorderLayer(newVal.importCode) | |||
| } | |||
| }, | |||
| otherLands: { | |||
| deep: true, | |||
| handler(newVal) { | |||
| this.initOtherLandsLayer(newVal) | |||
| } | |||
| }, | |||
| // 监听地图配置变化,重新初始化地图 | |||
| mapConfig: { | |||
| deep: true, | |||
| handler(newVal) { | |||
| this.destroyMap() // 销毁旧地图 | |||
| this.initMap(newVal) // 初始化新地图 | |||
| } | |||
| } | |||
| }, | |||
| mounted() { | |||
| // 组件挂载后初始化地图 | |||
| this.initMap(this.mapConfig) | |||
| }, | |||
| beforeUnmount() { | |||
| // 组件卸载前销毁地图资源 | |||
| this.destroyMap() | |||
| }, | |||
| methods: { | |||
| /** | |||
| * 初始化地图核心实例 | |||
| * @param {Object} config - 地图配置 | |||
| */ | |||
| initMap(config) { | |||
| // 1. 定义投影(EPSG:3857) | |||
| const projection = new ol.proj.Projection({ | |||
| code: 'EPSG:3857', | |||
| units: 'degrees' | |||
| }) | |||
| // 2. 加载底图(天地图卫星影像+标注) | |||
| const aerialLayer = new ol.layer.Tile({ | |||
| source: new ol.source.XYZ({ | |||
| url: `http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=cc4aba6e967096098249efa069733067` | |||
| }), | |||
| name: '卫星影像图' | |||
| }) | |||
| const labelLayer = new ol.layer.Tile({ | |||
| source: new ol.source.XYZ({ | |||
| url: `https://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=cc4aba6e967096098249efa069733067` | |||
| }), | |||
| name: '文字标注层' | |||
| }) | |||
| // 3. 创建地图实例 | |||
| this.map = new ol.Map({ | |||
| controls: ol.control.defaults({ | |||
| attribution: false, // 隐藏版权信息 | |||
| zoom: false, // 隐藏缩放按钮 | |||
| rotate: false // 隐藏旋转按钮 | |||
| }), | |||
| layers: [aerialLayer, labelLayer], | |||
| projection: projection, | |||
| target: 'mapWrap', | |||
| view: new ol.View({ | |||
| center: ol.proj.fromLonLat([config.centerLng, config.centerLat]), | |||
| zoom: config.zoom, | |||
| minZoom: config.minZoom, | |||
| maxZoom: config.maxZoom | |||
| }) | |||
| }) | |||
| // 4. 初始化附属图层 | |||
| this.initVillageBorderLayer(this.targetLand.importCode) | |||
| this.initOtherLandsLayer(this.otherLands) | |||
| this.initTargetLandLayer(this.targetLand) | |||
| }, | |||
| /** | |||
| * 初始化村边界图层 | |||
| * @param {String} importCode - 区域编码(用于筛选边界) | |||
| */ | |||
| initVillageBorderLayer(importCode) { | |||
| // 销毁旧图层 | |||
| if (this.villageBorderLayer) { | |||
| this.map.removeLayer(this.villageBorderLayer) | |||
| } | |||
| if (!importCode || !this.mapConfig.geoServerUrl) return | |||
| // 创建新的村边界图层(WMS服务) | |||
| this.villageBorderLayer = new ol.layer.Image({ | |||
| source: new ol.source.ImageWMS({ | |||
| url: `${this.mapConfig.geoServerUrl}/wms`, | |||
| params: { | |||
| LAYERS: this.mapConfig.villageBorderLayerName, | |||
| cql_filter: `import_code = '${importCode}'`, | |||
| SRID: 3857 | |||
| } | |||
| }), | |||
| name: 'villageBorderLayer' | |||
| }) | |||
| this.map.addLayer(this.villageBorderLayer) | |||
| }, | |||
| /** | |||
| * 初始化其他地块图层(青色显示) | |||
| * @param {Array} lands - 其他地块数据列表 | |||
| */ | |||
| initOtherLandsLayer(lands) { | |||
| // 销毁旧图层 | |||
| if (this.otherLandsLayer) { | |||
| this.map.removeLayer(this.otherLandsLayer) | |||
| } | |||
| if (!lands.length) return | |||
| // 创建矢量数据源 | |||
| const vectorSource = new ol.source.Vector() | |||
| // 遍历地块数据,添加到数据源 | |||
| lands.forEach(land => { | |||
| if (land.theGeom && land.fid !== this.targetLand.fid) { | |||
| const feature = new ol.Feature({ | |||
| geometry: new ol.geom.MultiPolygon(JSON.parse(land.theGeom).coordinates) | |||
| }) | |||
| vectorSource.addFeature(feature) | |||
| } | |||
| }) | |||
| // 创建其他地块图层 | |||
| this.otherLandsLayer = new ol.layer.Vector({ | |||
| source: vectorSource, | |||
| style: this.getOtherLandStyle() // 青色样式 | |||
| }) | |||
| this.map.addLayer(this.otherLandsLayer) | |||
| }, | |||
| /** | |||
| * 初始化目标地块图层(黄色高亮) | |||
| * @param {Object} land - 目标地块数据 | |||
| */ | |||
| initTargetLandLayer(land) { | |||
| // 销毁旧图层 | |||
| if (this.targetLandLayer) { | |||
| this.map.removeLayer(this.targetLandLayer) | |||
| } | |||
| if (!land.theGeom) return | |||
| // 创建目标地块数据源 | |||
| const vectorSource = new ol.source.Vector({ | |||
| features: new ol.format.GeoJSON().readFeatures({ | |||
| type: 'Feature', | |||
| geometry: JSON.parse(land.theGeom) | |||
| }) | |||
| }) | |||
| // 创建目标地块图层(黄色高亮) | |||
| this.targetLandLayer = new ol.layer.Vector({ | |||
| source: vectorSource, | |||
| style: this.getTargetLandStyle() // 黄色样式 | |||
| }) | |||
| this.map.addLayer(this.targetLandLayer) | |||
| // 定位到目标地块 | |||
| this.locateToTargetLand(vectorSource) | |||
| }, | |||
| /** | |||
| * 定位到目标地块 | |||
| * @param {ol.source.Vector} source - 目标地块数据源 | |||
| */ | |||
| locateToTargetLand(source) { | |||
| const features = source.getFeatures() | |||
| if (!features.length) return | |||
| // 获取地块边界范围 | |||
| const extent = source.getExtent() | |||
| // 地图居中到地块范围 | |||
| this.map.getView().animate({ | |||
| center: ol.extent.getCenter(extent), | |||
| zoom: this.mapConfig.zoom, | |||
| duration: 1000 | |||
| }) | |||
| }, | |||
| /** | |||
| * 处理「画图」按钮点击事件 | |||
| */ | |||
| handleDrawPolygon() { | |||
| // 移除旧的绘制图层和交互 | |||
| this.removeDrawInteraction() | |||
| if (this.vectorDrawingLayer) { | |||
| this.map.removeLayer(this.vectorDrawingLayer) | |||
| } | |||
| // 创建新的绘制数据源和图层 | |||
| const drawSource = new ol.source.Vector({ wrapX: false }) | |||
| this.vectorDrawingLayer = new ol.layer.Vector({ source: drawSource }) | |||
| this.map.addLayer(this.vectorDrawingLayer) | |||
| // 创建绘制交互(多边形) | |||
| this.draw = new ol.interaction.Draw({ | |||
| source: drawSource, | |||
| type: 'Polygon' | |||
| }) | |||
| // 绘制结束事件:保存结果并通知父组件 | |||
| this.draw.on('drawend', (evt) => { | |||
| const geometry = evt.feature.getGeometry() | |||
| this.drawResult = geometry.getCoordinates() | |||
| // 通知父组件绘制结果 | |||
| this.$emit('draw-complete', this.drawResult) | |||
| // 移除绘制交互(防止重复绘制) | |||
| this.map.removeInteraction(this.draw) | |||
| }) | |||
| this.map.addInteraction(this.draw) | |||
| }, | |||
| /** | |||
| * 处理「还原」按钮点击事件 | |||
| */ | |||
| handleDrawReset() { | |||
| // 移除绘制交互和图层 | |||
| this.removeDrawInteraction() | |||
| if (this.vectorDrawingLayer) { | |||
| this.map.removeLayer(this.vectorDrawingLayer) | |||
| } | |||
| // 清空绘制结果并通知父组件 | |||
| this.drawResult = null | |||
| this.$emit('draw-reset') | |||
| // 重新加载目标地块图层(恢复高亮) | |||
| this.initTargetLandLayer(this.targetLand) | |||
| }, | |||
| /** | |||
| * 移除绘制交互 | |||
| */ | |||
| removeDrawInteraction() { | |||
| if (this.draw && this.map) { | |||
| this.map.removeInteraction(this.draw) | |||
| this.draw = null | |||
| } | |||
| }, | |||
| /** | |||
| * 获取目标地块样式(黄色高亮) | |||
| * @returns {ol.style.Style} 样式对象 | |||
| */ | |||
| getTargetLandStyle() { | |||
| return new ol.style.Style({ | |||
| fill: new ol.style.Fill({ color: 'yellow' }), | |||
| stroke: new ol.style.Stroke({ color: 'yellow', width: 3 }) | |||
| }) | |||
| }, | |||
| /** | |||
| * 获取其他地块样式(青色半透明) | |||
| * @returns {ol.style.Style} 样式对象 | |||
| */ | |||
| getOtherLandStyle() { | |||
| return new ol.style.Style({ | |||
| fill: new ol.style.Fill({ color: 'rgba(0, 218, 255, 0.3)' }), | |||
| stroke: new ol.style.Stroke({ color: '#00DAFF', width: 3 }) | |||
| }) | |||
| }, | |||
| /** | |||
| * 销毁地图实例和资源 | |||
| */ | |||
| destroyMap() { | |||
| if (this.map) { | |||
| // 移除所有图层 | |||
| const layers = this.map.getLayers().getArray() | |||
| layers.forEach(layer => this.map.removeLayer(layer)) | |||
| // 移除所有交互 | |||
| const interactions = this.map.getInteractions().getArray() | |||
| interactions.forEach(interaction => this.map.removeInteraction(interaction)) | |||
| // 清空地图容器 | |||
| document.getElementById('mapWrap').innerHTML = '' | |||
| this.map = null | |||
| } | |||
| // 重置状态 | |||
| this.draw = null | |||
| this.vectorDrawingLayer = null | |||
| this.targetLandLayer = null | |||
| this.otherLandsLayer = null | |||
| this.villageBorderLayer = null | |||
| this.drawResult = null | |||
| }, | |||
| /** | |||
| * 对外暴露:清除所有图层(供父组件调用) | |||
| */ | |||
| clearAllLayers() { | |||
| this.removeDrawInteraction() | |||
| if (this.vectorDrawingLayer) this.map.removeLayer(this.vectorDrawingLayer) | |||
| if (this.targetLandLayer) this.map.removeLayer(this.targetLandLayer) | |||
| if (this.otherLandsLayer) this.map.removeLayer(this.otherLandsLayer) | |||
| if (this.villageBorderLayer) this.map.removeLayer(this.villageBorderLayer) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .map-wrap { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| .map-btn-wrap { | |||
| position: relative; | |||
| width: 40%; | |||
| left: 60%; | |||
| bottom: 95%; | |||
| z-index: 2000; | |||
| } | |||
| .ant-btn-red { | |||
| position: relative; | |||
| display: inline-block; | |||
| background: #D0EEFF; | |||
| border: 1px solid #99D3F5; | |||
| border-radius: 4px; | |||
| padding: 4px 12px; | |||
| overflow: hidden; | |||
| color: #1E88C7; | |||
| text-decoration: none; | |||
| text-indent: 0; | |||
| line-height: 20px; | |||
| right: -36%; | |||
| } | |||
| </style> | |||
| @@ -1,286 +0,0 @@ | |||
| <template> | |||
| <div> | |||
| <div :id="'map-element' + elementId" class="map-element" style="width: 100%; height: 100%;"></div> | |||
| <div :id="'draw-toolbar' + elementId" class='draw-toolbar' v-show="allowDraw"> | |||
| <el-row> | |||
| <input :id="'drawPolygon' + elementId" class="ant-btn ant-btn-red" type="button" value="画图"/> | |||
| <input :id="'drawRemove' + elementId" type="button" class="ant-btn ant-btn-red" value="取消画图"/> | |||
| <input :id="'drawReset' + elementId" type="button" class="ant-btn ant-btn-red" value="重置画图"/> | |||
| </el-row> | |||
| </div> | |||
| <div :id="'mark-toolbar' + elementId" class='draw-toolbar' v-show="allowMark"> | |||
| <el-row> | |||
| <input :id="'markPoint' + elementId" class="ant-btn ant-btn-red" type="button" value="标记"/> | |||
| <input :id="'markReset' + elementId" type="button" class="ant-btn ant-btn-red" value="重置标记"/> | |||
| </el-row> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import $ from "jquery"; | |||
| import {olMap} from "@/utils/ol_map"; | |||
| const TYPE_NONE = 0; // 无交互 默认 | |||
| const TYPE_DRAW = 1; // 绘制多边形 v-model为MultiPolygon的JSON | |||
| const TYPE_SELECT = 2; // 选择, 必须指定list属性 v-model为list索引, 未选中为-1 | |||
| const TYPE_MARK = 3; // 标记点 v-model为[经度, 维度]数组 | |||
| export default { | |||
| name: "MapField", | |||
| props: { | |||
| minMapZoom: { | |||
| type: Number, | |||
| default: 16, | |||
| }, | |||
| maxMapZoom: { | |||
| type: Number, | |||
| default: 18.9, | |||
| }, | |||
| allowDraw: { | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| type: { | |||
| type: [Number, String], // 0 原始 1 绘制 2 选择 | |||
| default: 0, | |||
| }, | |||
| coord: { | |||
| type: Array, | |||
| default: function() { | |||
| return [115.452752, 31.789033]; | |||
| }, | |||
| }, | |||
| value: { | |||
| type: [String, Array, Number], | |||
| }, | |||
| list: { | |||
| type: Array, | |||
| default: function() { | |||
| return []; | |||
| }, | |||
| }, | |||
| allowSelect: { | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| allowMark: { | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| }, | |||
| data() { | |||
| return { | |||
| isInited: false, | |||
| mapObject: null, | |||
| mapResult: null, | |||
| elementId: ('_' + Math.random()).replaceAll('.', ''), | |||
| internalValue: null, // string only | |||
| }; | |||
| }, | |||
| created() { | |||
| }, | |||
| mounted() { | |||
| this.Init(); | |||
| this.SetupCoord(); | |||
| if(this.list) | |||
| this.mapObject.SetLayers(this.list); | |||
| if(this.value) | |||
| this.SetValue(this.value); | |||
| }, | |||
| watch: { | |||
| value: function(newVal, oldVal) { | |||
| this.SetValue(newVal); | |||
| }, | |||
| coord: { | |||
| handler: function(newVal, oldVal) { | |||
| this.SetupCoord(); | |||
| }, | |||
| deep: true, | |||
| }, | |||
| list: { | |||
| handler: function(newVal, oldVal) { | |||
| if(this.type == TYPE_SELECT) | |||
| { | |||
| this.mapObject.ClearSelection(); | |||
| this.mapObject.SetLayers(newVal); | |||
| if(this.internalValue >= 0 && this.internalValue < this.list.length) | |||
| this.mapObject.SetSelection(this.list[this.internalValue].name); | |||
| } | |||
| }, | |||
| deep: true, | |||
| }, | |||
| }, | |||
| methods: { | |||
| SetValue(val) { | |||
| if(this.internalValue === val) | |||
| return; | |||
| this.internalValue = val; | |||
| this.UpdateValueToMap(); | |||
| }, | |||
| UpdateValueToMap() { | |||
| this.SetupCoord(); | |||
| if(this.type == TYPE_SELECT) | |||
| { | |||
| this.mapObject.ClearSelection(); | |||
| if(this.internalValue >= 0 && this.internalValue < this.list.length) | |||
| this.mapObject.SetSelection(this.list[this.internalValue].name); | |||
| } | |||
| else if(this.type == TYPE_MARK) | |||
| { | |||
| this.mapObject.RemoveDrawLayer(); | |||
| if(this.internalValue && this.internalValue.length > 0) | |||
| { | |||
| let json = olMap.gen_polygon([this.internalValue]); | |||
| this.mapObject.SetLayer(olMap.MAP_FIELD_INIT_LAYER_NAME, json, null, null, { | |||
| 'style.stroke.width': 10, | |||
| 'style.stroke.color': '#FF0000', | |||
| }); | |||
| } | |||
| else | |||
| this.mapObject.PopLayer(olMap.MAP_FIELD_INIT_LAYER_NAME); | |||
| } | |||
| else | |||
| { | |||
| this.mapObject.RemoveDrawLayer(); | |||
| this.mapObject.SetLayer(olMap.MAP_FIELD_INIT_LAYER_NAME, this.internalValue); | |||
| } | |||
| }, | |||
| Init() { | |||
| if(this.isInited) | |||
| return; | |||
| this.mapObject = new olMap('map-element' + this.elementId); | |||
| if(this.type == TYPE_DRAW) | |||
| { | |||
| this.mapObject.SetAllowDraw(this.allowDraw); | |||
| let self = this; | |||
| $("#drawPolygon" + this.elementId).click(function () { | |||
| self.mapObject.StartDraw(); | |||
| }); | |||
| //清除画图鼠标点击事件 | |||
| $("#drawRemove" + this.elementId).click(function () { | |||
| self.mapObject.ClearDraw(); | |||
| }); | |||
| //还原之前图层 | |||
| $("#drawReset" + this.elementId).click(function () { | |||
| self.mapObject.ResetDraw(); | |||
| }); | |||
| this.mapObject.SetCallback("draw::start", () => { | |||
| this.mapResult = null; | |||
| }); | |||
| this.mapObject.SetCallback("draw::remove", () => { | |||
| }); | |||
| this.mapObject.SetCallback("draw::end", (res) => { | |||
| this.mapResult = res; | |||
| this.SetInternalValue(); | |||
| }); | |||
| this.mapObject.SetCallback("draw::reset", () => { | |||
| this.mapResult = null; | |||
| }); | |||
| } | |||
| else if(this.type == TYPE_SELECT) | |||
| { | |||
| this.mapObject.SetAllowSelect(this.allowSelect); | |||
| this.mapObject.SetCallback("interactive::select", (name) => { | |||
| console.log('select -> ' + name); | |||
| this.mapResult = name; | |||
| this.SetInternalValue(); | |||
| this.$emit('select', name); | |||
| }); | |||
| } | |||
| else if(this.type == TYPE_MARK) | |||
| { | |||
| this.mapObject.SetAllowMark(this.allowMark); | |||
| let self = this; | |||
| $("#markPoint" + this.elementId).click(function () { | |||
| self.mapObject.StartMark(); | |||
| }); | |||
| //还原之前图层 | |||
| $("#markReset" + this.elementId).click(function () { | |||
| self.mapObject.ResetMark(); | |||
| }); | |||
| this.mapObject.SetCallback("mark::start", () => { | |||
| this.mapResult = null; | |||
| }); | |||
| this.mapObject.SetCallback("mark::end", (res) => { | |||
| this.mapResult = res; | |||
| this.SetInternalValue(); | |||
| }); | |||
| this.mapObject.SetCallback("mark::reset", () => { | |||
| this.mapResult = null; | |||
| }); | |||
| } | |||
| this.isInited = true; | |||
| if(this.internalValue) | |||
| this.UpdateValueToMap(); | |||
| }, | |||
| DestroyMap() { | |||
| if(!this.mapObject) | |||
| return; | |||
| //delete this.mapObject; | |||
| this.mapObject.DestroyMap(); | |||
| this.mapObject = null; | |||
| }, | |||
| SetInternalValue() { | |||
| if(this.type == TYPE_SELECT) | |||
| { | |||
| this.internalValue = this.mapResult; | |||
| if(this.mapResult) | |||
| this.internalValue = this.list.findIndex((x) => x.name == this.mapResult); | |||
| else | |||
| this.internalValue = -1; | |||
| this.$emit('input', this.internalValue); | |||
| } | |||
| else if(this.type == TYPE_MARK) | |||
| { | |||
| this.internalValue = this.mapResult ? this.mapResult : [null, null]; | |||
| this.$emit('input', this.internalValue); | |||
| } | |||
| else | |||
| { | |||
| this.internalValue = JSON.stringify(this.mapResult); | |||
| this.$emit('input', this.internalValue); | |||
| } | |||
| //console.log(this.type, this.mapResult, this.internalValue); | |||
| }, | |||
| Update() { | |||
| if(this.mapObject) | |||
| this.mapObject.Update(); | |||
| }, | |||
| SetupCoord() { | |||
| if(this.mapObject && this.coord && this.coord.length >= 2 && this.coord[0] && this.coord[1]) | |||
| this.mapObject.SetCoord(this.coord[0], this.coord[1]); | |||
| } | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .map-element { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| .draw-toolbar { | |||
| position: relative; | |||
| width: 40%; | |||
| left: 60%; | |||
| bottom: 95%; | |||
| z-index: 2000; | |||
| } | |||
| .ant-btn-red { | |||
| position: relative; | |||
| display: inline-block; | |||
| background: #D0EEFF; | |||
| border: 1px solid #99D3F5; | |||
| border-radius: 4px; | |||
| padding: 4px 12px; | |||
| overflow: hidden; | |||
| color: #1E88C7; | |||
| text-decoration: none; | |||
| text-indent: 0; | |||
| line-height: 20px; | |||
| } | |||
| </style> | |||
| @@ -332,18 +332,19 @@ | |||
| <div id="mapWrap"></div> | |||
| <div id='land-btn-wrap'> | |||
| <el-row> | |||
| <input id="drawPolygon" class="ant-btn ant-btn-red" type="button" value="画图"/> | |||
| <!-- <input id="drawRemove" type="button" class="ant-btn ant-btn-red" value="取消画图"/> --> | |||
| <input id="drawReset" type="button" class="ant-btn ant-btn-red" value="还原"/> | |||
| <input id="drawPolygon" class="ant-btn ant-btn-red" type="button" value="开启画图"/> | |||
| <!--<input id="drawRemove" type="button" class="ant-btn ant-btn-red" value="关闭画图"/> --> | |||
| <input id="drawReset" type="button" class="ant-btn ant-btn-red" value="还原图层"/> | |||
| </el-row> | |||
| </div> | |||
| </div> | |||
| <div slot="footer" class="dialog-footer"> | |||
| <el-button type="primary" v-if="diglogStatus" @click="submitFormMap">确 定</el-button> | |||
| <el-button type="primary" @click="submitFormMap">确 定</el-button> | |||
| <el-button type="danger" @click="clearMapLayer">清除图层</el-button> | |||
| <el-button @click="cancelMap">关 闭</el-button> | |||
| </div> | |||
| </el-dialog> | |||
| </div> | |||
| </template> | |||
| @@ -357,14 +358,13 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css" | |||
| import "splitpanes/dist/splitpanes.css" | |||
| import { deptTreeSelect } from "@/api/system/user" | |||
| import {getConfigKey} from "@/api/system/config"; | |||
| import {getDept,getInfoByImportCode} from "@/api/system/dept"; | |||
| import MapField from "@/components/house/MapField"; | |||
| import {getDept, getInfoByImportCode} from "@/api/system/dept"; | |||
| import $ from "jquery"; | |||
| export default { | |||
| name: "Land", | |||
| dicts: ['ownership_type', 'land_use_type', 'survey_status', 'is_common', 'land_grade_type', 'land_type', 'land_use'], | |||
| components: { Treeselect, Splitpanes, Pane,MapField }, | |||
| components: { Treeselect, Splitpanes, Pane }, | |||
| data() { | |||
| return { | |||
| // 遮罩层 | |||
| @@ -407,15 +407,13 @@ export default { | |||
| children: "children", | |||
| label: "label" | |||
| }, | |||
| // 遮罩按钮新增点击状态 | |||
| diglogStatus: true, | |||
| //地图 | |||
| //地图参数 | |||
| openMap: false, | |||
| mapTheGeomId: null, | |||
| mapTheGeom: null, | |||
| drawInsert:null, | |||
| tGeoOrganizationLng: null, | |||
| tGeoOrganizationLat: null, | |||
| jingdu: null, | |||
| weidu: null, | |||
| // 查询参数 | |||
| queryParams: { | |||
| pageNum: 1, | |||
| @@ -447,7 +445,6 @@ export default { | |||
| scmjm: [ | |||
| { required: true, message: "实测面积不能为空", trigger: "blur" } | |||
| ], | |||
| }, | |||
| // EXCEL导入 | |||
| upload: { | |||
| @@ -464,7 +461,6 @@ export default { | |||
| // 上传的地址 | |||
| url: process.env.VUE_APP_BASE_API + "/resource/land/importData" | |||
| }, | |||
| } | |||
| }, | |||
| watch: { | |||
| @@ -476,6 +472,7 @@ export default { | |||
| created() { | |||
| this.getDeptTree() | |||
| this.getList() | |||
| // 获取geoserver的地址 | |||
| this.getGeoServerUrl(); | |||
| // 获取地块图层名称 | |||
| @@ -500,7 +497,7 @@ export default { | |||
| this.open = false | |||
| this.reset() | |||
| }, | |||
| // 取消按钮 | |||
| // 取消地图按钮 | |||
| cancelMap() { | |||
| this.openMap = false; | |||
| this.reset(); | |||
| @@ -535,7 +532,6 @@ export default { | |||
| deptName: null, | |||
| sfzwd: '2' | |||
| } | |||
| this.diglogStatus = true; | |||
| this.resetForm("form") | |||
| }, | |||
| /** 搜索按钮操作 */ | |||
| @@ -772,8 +768,8 @@ export default { | |||
| getDept(deptId).then(response => { | |||
| let insertCode = response.data; | |||
| if (insertCode != null) { | |||
| this.tGeoOrganizationLat = insertCode.latitude; | |||
| this.tGeoOrganizationLng = insertCode.longitude; | |||
| this.weidu = insertCode.latitude; | |||
| this.jingdu = insertCode.longitude; | |||
| } | |||
| }); | |||
| }, | |||
| @@ -783,8 +779,8 @@ export default { | |||
| getInfoByImportCode(row.importCode).then((res) => { | |||
| let insertCode = res.data; | |||
| if (insertCode != null) { | |||
| this.tGeoOrganizationLat = insertCode.latitude; | |||
| this.tGeoOrganizationLng = insertCode.longitude; | |||
| this.weidu = insertCode.latitude; | |||
| this.jingdu = insertCode.longitude; | |||
| } | |||
| const tableRow = { importCode: row.importCode }; | |||
| listLandQuery(tableRow).then(response => { | |||
| @@ -798,43 +794,40 @@ export default { | |||
| }, | |||
| /** 地图提交按钮 */ | |||
| submitFormMap() { | |||
| this.diglogStatus = false; | |||
| if(this.drawInsert !=null && this.drawInsert !=""){ | |||
| this.mapTheGeomId.theGeom = JSON.stringify(this.drawInsert); | |||
| }else{ | |||
| this.mapTheGeomId.theGeom = this.mapTheGeomId.theGeomText | |||
| } | |||
| let sysGis = { tableName: 't_resource_land',priId: 'fid',id: this.mapTheGeomId.fid,theGeom: this.mapTheGeomId.theGeom }; | |||
| let sysGis = { tableName: 't_resource_land', priId: 'fid', id: this.mapTheGeomId.fid, theGeom: this.mapTheGeomId.theGeom }; | |||
| if (this.mapTheGeomId != null) { | |||
| areaSavePri(sysGis).then(response => { | |||
| this.$modal.msgSuccess("修改成功"); | |||
| this.openMap = false; | |||
| this.getList(); | |||
| this.diglogStatus = true; | |||
| //this.getList(); | |||
| }); | |||
| } | |||
| }, | |||
| /** 清除坐标点图层 */ | |||
| clearMapLayer() { | |||
| let sysGis = { tableName: 't_resource_land',priId: 'fid',id: this.mapTheGeomId.fid}; | |||
| let sysGis = { tableName: 't_resource_land', priId: 'fid', id: this.mapTheGeomId.fid}; | |||
| cleanSavePri(sysGis).then(response => { | |||
| this.$modal.msgSuccess("清除成功"); | |||
| this.openMap = false; | |||
| this.getList(); | |||
| //this.getList(); | |||
| }); | |||
| }, | |||
| pointDarw(resourceList) { | |||
| //加载地图编辑 | |||
| var that = this; | |||
| var map; | |||
| //var hc_land; | |||
| var draw; // global so we can remove it later | |||
| var draw; | |||
| var vector_drawing; | |||
| var startDarw =false; | |||
| var openDarw = false; | |||
| this.mapTheGeomId = resourceList.find((land) => { | |||
| //model就是上面的数据源 | |||
| return land.fid === this.mapTheGeomId.fid; //筛选出匹配数据 | |||
| return land.fid === this.mapTheGeomId.fid; | |||
| }); | |||
| if (this.mapTheGeomId.theGeom != null && this.mapTheGeomId.theGeom != "" | |||
| && this.mapTheGeomId.theGeom != undefined) { | |||
| @@ -844,9 +837,10 @@ export default { | |||
| startDarw = false; | |||
| openDarw = true; | |||
| } | |||
| if (startDarw) { | |||
| document.getElementById("mapWrap").innerHTML = ''; | |||
| var hc_land; | |||
| var thePolygon; | |||
| var draw; // global so we can remove it later | |||
| var vector_drawing; | |||
| var projection = new ol.proj.Projection({ | |||
| @@ -855,7 +849,6 @@ export default { | |||
| units: "degrees", | |||
| //extent:extent | |||
| }); | |||
| var aerial = new ol.layer.Tile({ | |||
| source: new ol.source.XYZ({ | |||
| url: "http://t0.tianditu.gov.cn/img_w/wmts?" + | |||
| @@ -865,7 +858,6 @@ export default { | |||
| isGroup: true, | |||
| name: "卫星影像图", | |||
| }); | |||
| var yingxzi = new ol.layer.Tile({ | |||
| source: new ol.source.XYZ({ | |||
| url: "https://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=cc4aba6e967096098249efa069733067", | |||
| @@ -882,8 +874,8 @@ export default { | |||
| view: new ol.View({ | |||
| //center: ol.proj.fromLonLat([115.452752, 31.789033]), | |||
| zoom: 17.8, | |||
| minZoom: 0, //地图缩小限制 | |||
| maxZoom: 18.3, //地图放大限制 | |||
| minZoom: 0, | |||
| maxZoom: 18.3, | |||
| }), | |||
| }); | |||
| // 添加村边界 | |||
| @@ -899,7 +891,6 @@ export default { | |||
| name: 'villageBorderLayer' | |||
| }); | |||
| map.addLayer(mapBorder); | |||
| // 添加已经存在的资源图层 | |||
| let vectorSource = new ol.source.Vector(); | |||
| for (let resource of resourceList) { | |||
| @@ -911,7 +902,6 @@ export default { | |||
| vectorSource.addFeature(feature); | |||
| } | |||
| } | |||
| let resourceLayer = new ol.layer.Vector({ | |||
| source: vectorSource, | |||
| style: (feature, resolution) => { | |||
| @@ -929,8 +919,8 @@ export default { | |||
| } | |||
| }); | |||
| map.addLayer(resourceLayer); | |||
| //图层查询定位开始 ---------start | |||
| hc_land = new ol.layer.Vector({ | |||
| //当前图层查询定位 | |||
| thePolygon = new ol.layer.Vector({ | |||
| title: "add Layer", | |||
| source: new ol.source.Vector({ | |||
| projection: projection, | |||
| @@ -950,24 +940,21 @@ export default { | |||
| }), | |||
| }), | |||
| }); | |||
| map.addLayer(hc_land); | |||
| var maxXMap = hc_land.values_.source.featuresRtree_.rbush_.data.maxX; | |||
| var maxYMap = hc_land.values_.source.featuresRtree_.rbush_.data.maxY; | |||
| var minXMap = hc_land.values_.source.featuresRtree_.rbush_.data.minX; | |||
| var minYMap = hc_land.values_.source.featuresRtree_.rbush_.data.minY; | |||
| //定位查询位置 | |||
| var center = ol.extent.getCenter([maxXMap, maxYMap, minXMap, minYMap]); //获取边界区域的中心位置 | |||
| map.addLayer(thePolygon); | |||
| var maxXMap = thePolygon.values_.source.featuresRtree_.rbush_.data.maxX; | |||
| var maxYMap = thePolygon.values_.source.featuresRtree_.rbush_.data.maxY; | |||
| var minXMap = thePolygon.values_.source.featuresRtree_.rbush_.data.minX; | |||
| var minYMap = thePolygon.values_.source.featuresRtree_.rbush_.data.minY; | |||
| var center = ol.extent.getCenter([maxXMap, maxYMap, minXMap, minYMap]); | |||
| map.getView().animate({ | |||
| // 只设置需要的属性即可 | |||
| center: center, // 中心点 | |||
| zoom: 17.8, // 缩放级别 | |||
| rotation: undefined, // 缩放完成view视图旋转弧度 | |||
| duration: 1000, // 缩放持续时间,默认不需要设置 | |||
| center: center, | |||
| zoom: 17.8, | |||
| rotation: undefined, | |||
| duration: 1000, | |||
| }); | |||
| //图层查询定位结束 ---------end | |||
| //开始绘制地图 | |||
| $("#drawPolygon").off("click").on("click", function () { | |||
| map.removeLayer(hc_land); | |||
| map.removeLayer(thePolygon); | |||
| map.removeLayer(vector_drawing); | |||
| that.drawInsert = null; | |||
| //var source = new ol.source.Vector({wrapX: false}); | |||
| @@ -975,7 +962,6 @@ export default { | |||
| source: new ol.source.Vector(), | |||
| }); | |||
| map.addLayer(vector_drawing); | |||
| function addInteraction() { | |||
| draw = new ol.interaction.Draw({ | |||
| source: vector_drawing.getSource(), | |||
| @@ -990,12 +976,11 @@ export default { | |||
| }); | |||
| map.addInteraction(draw); | |||
| } | |||
| addInteraction(); | |||
| }); | |||
| //清除画图鼠标点击事件 | |||
| $("#drawRemove").off("click").on("click", function () { | |||
| //map.addLayer(hc_land); | |||
| //map.addLayer(thePolygon); | |||
| map.removeInteraction(draw); | |||
| //map.removeLayer(vector_drawing); | |||
| }); | |||
| @@ -1003,10 +988,11 @@ export default { | |||
| $("#drawReset").off("click").on("click", function () { | |||
| map.removeInteraction(draw); | |||
| map.removeLayer(vector_drawing); | |||
| map.addLayer(hc_land); | |||
| map.addLayer(thePolygon); | |||
| that.drawInsert = null; | |||
| }); | |||
| } | |||
| if (openDarw) { | |||
| document.getElementById("mapWrap").innerHTML = ''; | |||
| var projection = new ol.proj.Projection({ | |||
| @@ -1015,7 +1001,6 @@ export default { | |||
| units: "degrees", | |||
| //extent:extent | |||
| }); | |||
| var aerial = new ol.layer.Tile({ | |||
| source: new ol.source.XYZ({ | |||
| url: "http://t0.tianditu.gov.cn/img_w/wmts?" + | |||
| @@ -1035,9 +1020,8 @@ export default { | |||
| }); | |||
| //获取坐标是否存在 | |||
| var Zb; | |||
| if (this.tGeoOrganizationLng != null && this.tGeoOrganizationLat != null && this.tGeoOrganizationLng !="" | |||
| && this.tGeoOrganizationLat !="" && this.tGeoOrganizationLng !=undefined && this.tGeoOrganizationLat !=undefined) { | |||
| Zb = [this.tGeoOrganizationLng, this.tGeoOrganizationLat] | |||
| if (this.jingdu != null && this.jingdu !="") { | |||
| Zb = [this.jingdu, this.weidu] | |||
| } else { | |||
| Zb = [115.452752, 31.789033]; | |||
| } | |||
| @@ -1069,7 +1053,6 @@ export default { | |||
| name: 'villageBorderLayer' | |||
| }); | |||
| map.addLayer(mapBorder); | |||
| // 添加已经存在的资源图层 | |||
| let vectorSource = new ol.source.Vector(); | |||
| for (let resource of resourceList) { | |||
| @@ -1081,7 +1064,6 @@ export default { | |||
| vectorSource.addFeature(feature); | |||
| } | |||
| } | |||
| let resourceLayer = new ol.layer.Vector({ | |||
| source: vectorSource, | |||
| style: (feature, resolution) => { | |||
| @@ -1100,10 +1082,9 @@ export default { | |||
| }); | |||
| map.addLayer(resourceLayer); | |||
| //图层查询定位结束 ---------end | |||
| //开始绘制地图 | |||
| $("#drawPolygon").off("click").on("click", function () { | |||
| //map.removeLayer(hc_land); | |||
| //map.removeLayer(thePolygon); | |||
| map.removeLayer(vector_drawing); | |||
| that.drawInsert = null; | |||
| map.removeInteraction(draw); | |||
| @@ -1130,20 +1111,21 @@ export default { | |||
| }); | |||
| map.addInteraction(draw); | |||
| } | |||
| addInteraction(); | |||
| }); | |||
| //清除画图鼠标点击事件 | |||
| $("#drawRemove").off("click").on("click", function () { | |||
| //map.addLayer(hc_land); | |||
| //map.addLayer(thePolygon); | |||
| map.removeInteraction(draw); | |||
| //map.removeLayer(vector_drawing); | |||
| }); | |||
| //还原之前图层 | |||
| $("#drawReset").off("click").on("click", function () { | |||
| map.removeInteraction(draw); | |||
| map.removeLayer(vector_drawing); | |||
| //map.addLayer(hc_land); | |||
| //map.addLayer(thePolygon); | |||
| that.drawInsert = null; | |||
| }); | |||
| } | |||
| @@ -1156,6 +1138,7 @@ export default { | |||
| height: 75vh; | |||
| overflow-y: scroll; | |||
| } | |||
| #land-btn-wrap { | |||
| position: relative; | |||
| width: 40%; | |||
| @@ -1163,7 +1146,6 @@ export default { | |||
| bottom: 95%; | |||
| z-index: 2000; | |||
| } | |||
| #mapWrap { | |||
| width: 100%; | |||
| height: 100%; | |||