|
@@ -1,390 +1,268 @@ |
|
|
<template> |
|
|
<template> |
|
|
<div class="land-map-container"> |
|
|
|
|
|
<!-- 地图容器 --> |
|
|
|
|
|
<div id="mapWrap" class="map-wrap"></div> |
|
|
|
|
|
<!-- 地图操作按钮 --> |
|
|
|
|
|
<div id="land-btn-wrap" class="map-btn-wrap"> |
|
|
|
|
|
|
|
|
<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> |
|
|
<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"/> |
|
|
|
|
|
|
|
|
<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> |
|
|
</el-row> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script> |
|
|
<script> |
|
|
import ol from 'ol' // 确保项目已引入OpenLayers |
|
|
|
|
|
import $ from 'jquery' |
|
|
|
|
|
|
|
|
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 { |
|
|
export default { |
|
|
name: 'LandMapComponent', |
|
|
|
|
|
|
|
|
name: "MapField", |
|
|
props: { |
|
|
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 // 最小缩放级别 |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
minMapZoom: { |
|
|
|
|
|
type: Number, |
|
|
|
|
|
default: 16, |
|
|
|
|
|
}, |
|
|
|
|
|
maxMapZoom: { |
|
|
|
|
|
type: Number, |
|
|
|
|
|
default: 18.9, |
|
|
}, |
|
|
}, |
|
|
// 目标地块数据(用于定位和高亮) |
|
|
|
|
|
targetLand: { |
|
|
|
|
|
type: Object, |
|
|
|
|
|
default: () => ({ |
|
|
|
|
|
fid: '', |
|
|
|
|
|
theGeom: '', // 地块几何信息 |
|
|
|
|
|
importCode: '' // 用于筛选村边界的编码 |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
allowDraw: { |
|
|
|
|
|
type: Boolean, |
|
|
|
|
|
default: false, |
|
|
}, |
|
|
}, |
|
|
// 其他地块数据(用于加载已有地块图层) |
|
|
|
|
|
otherLands: { |
|
|
|
|
|
|
|
|
type: { |
|
|
|
|
|
type: [Number, String], // 0 原始 1 绘制 2 选择 |
|
|
|
|
|
default: 0, |
|
|
|
|
|
}, |
|
|
|
|
|
coord: { |
|
|
type: Array, |
|
|
type: Array, |
|
|
default: () => [] |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
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() { |
|
|
data() { |
|
|
return { |
|
|
return { |
|
|
map: null, // 地图实例 |
|
|
|
|
|
draw: null, // 绘制实例 |
|
|
|
|
|
vectorDrawingLayer: null, // 绘制图层 |
|
|
|
|
|
targetLandLayer: null, // 目标地块高亮图层 |
|
|
|
|
|
otherLandsLayer: null, // 其他地块图层 |
|
|
|
|
|
villageBorderLayer: null, // 村边界图层 |
|
|
|
|
|
drawResult: null // 绘制结果(几何坐标) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
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: { |
|
|
watch: { |
|
|
// 监听地块数据变化,重新加载图层 |
|
|
|
|
|
targetLand: { |
|
|
|
|
|
deep: true, |
|
|
|
|
|
handler(newVal) { |
|
|
|
|
|
this.initTargetLandLayer(newVal) |
|
|
|
|
|
this.initVillageBorderLayer(newVal.importCode) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
value: function(newVal, oldVal) { |
|
|
|
|
|
this.SetValue(newVal); |
|
|
}, |
|
|
}, |
|
|
otherLands: { |
|
|
|
|
|
|
|
|
coord: { |
|
|
|
|
|
handler: function(newVal, oldVal) { |
|
|
|
|
|
this.SetupCoord(); |
|
|
|
|
|
}, |
|
|
deep: true, |
|
|
deep: true, |
|
|
handler(newVal) { |
|
|
|
|
|
this.initOtherLandsLayer(newVal) |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
}, |
|
|
// 监听地图配置变化,重新初始化地图 |
|
|
|
|
|
mapConfig: { |
|
|
|
|
|
|
|
|
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, |
|
|
deep: true, |
|
|
handler(newVal) { |
|
|
|
|
|
this.destroyMap() // 销毁旧地图 |
|
|
|
|
|
this.initMap(newVal) // 初始化新地图 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
mounted() { |
|
|
|
|
|
// 组件挂载后初始化地图 |
|
|
|
|
|
this.initMap(this.mapConfig) |
|
|
|
|
|
}, |
|
|
|
|
|
beforeUnmount() { |
|
|
|
|
|
// 组件卸载前销毁地图资源 |
|
|
|
|
|
this.destroyMap() |
|
|
|
|
|
|
|
|
}, |
|
|
}, |
|
|
}, |
|
|
methods: { |
|
|
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) |
|
|
|
|
|
|
|
|
SetValue(val) { |
|
|
|
|
|
if(this.internalValue === val) |
|
|
|
|
|
return; |
|
|
|
|
|
this.internalValue = val; |
|
|
|
|
|
this.UpdateValueToMap(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 初始化村边界图层 |
|
|
|
|
|
* @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) |
|
|
|
|
|
|
|
|
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); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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', |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 创建其他地块图层 |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
this.mapObject.PopLayer(olMap.MAP_FIELD_INIT_LAYER_NAME); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
this.mapObject.RemoveDrawLayer(); |
|
|
|
|
|
this.mapObject.SetLayer(olMap.MAP_FIELD_INIT_LAYER_NAME, this.internalValue); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 创建新的绘制数据源和图层 |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 清空绘制结果并通知父组件 |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取目标地块样式(黄色高亮) |
|
|
|
|
|
* @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 }) |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
DestroyMap() { |
|
|
|
|
|
if(!this.mapObject) |
|
|
|
|
|
return; |
|
|
|
|
|
//delete this.mapObject; |
|
|
|
|
|
this.mapObject.DestroyMap(); |
|
|
|
|
|
this.mapObject = null; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取其他地块样式(青色半透明) |
|
|
|
|
|
* @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 |
|
|
|
|
|
|
|
|
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); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 重置状态 |
|
|
|
|
|
this.draw = null |
|
|
|
|
|
this.vectorDrawingLayer = null |
|
|
|
|
|
this.targetLandLayer = null |
|
|
|
|
|
this.otherLandsLayer = null |
|
|
|
|
|
this.villageBorderLayer = null |
|
|
|
|
|
this.drawResult = null |
|
|
|
|
|
|
|
|
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); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 对外暴露:清除所有图层(供父组件调用) |
|
|
|
|
|
*/ |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped> |
|
|
<style scoped> |
|
|
.map-wrap { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.map-element { |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.map-btn-wrap { |
|
|
|
|
|
|
|
|
.draw-toolbar { |
|
|
position: relative; |
|
|
position: relative; |
|
|
width: 40%; |
|
|
width: 40%; |
|
|
left: 60%; |
|
|
left: 60%; |
|
@@ -404,6 +282,5 @@ |
|
|
text-decoration: none; |
|
|
text-decoration: none; |
|
|
text-indent: 0; |
|
|
text-indent: 0; |
|
|
line-height: 20px; |
|
|
line-height: 20px; |
|
|
right: -36%; |
|
|
|
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |