Closed kimmy-stack closed 3 years ago
<template>
<div class="hello">
<mapgis-web-map
id="map"
:access-token="accessToken"
:map-style="mapStyle"
:zoom="mapZoom"
:center="outerCenter"
:crs="mapCrs"
v-on:load="handleMapLoad"
>
<mapgis-igs-tdt-layer
:layer="layer"
:layer-id="layerId"
:source-id="sourceId"
:baseURL="baseURL"
:token="token"
:crs="mapCrs"
>
</mapgis-igs-tdt-layer>
<mapgis-measure
class="custom-measure-wrapper"
:measure-mode="measureMode"
v-on:added="handleAdded"
v-on:measurecreate="handleCreate"
v-on:measureresult="handleMeasure"
ref="measureref"
>
<div id="toolbar-wrapper">
<div class="toolbar-item" v-on:click="toggleQueryLength">长度</div>
<div class="toolbar-item" v-on:click="toggleQueryArea">面积</div>
</div>
<mapgis-marker color="#ff0000" :coordinates="coordinates" v-if="coordinates.length > 0">
<div slot="marker" class="label">
<div>面积:{{ area }}</div>
<div>周长:{{ perimeter }}</div>
</div>
</mapgis-marker>
</mapgis-measure>
<mapgis-draw
class="custom-draw-wrapper"
position="top-left"
v-bind:controls="controls"
v-on:added="handleAdded1"
v-on:drawcreate="handleCreate1"
ref="drawref1"
>
<div id="toolbar-wrapper1">
<div class="toolbar-item" v-on:click="togglePoint1">画点</div>
<div class="toolbar-item" v-on:click="togglePolyline1">画线</div>
<div class="toolbar-item" v-on:click="togglePolygon1">画区</div>
<div class="toolbar-item" v-on:click="toggleDelete1">删除</div>
</div>
</mapgis-draw>
<mapgis-draw
class="custom-draw-wrapper"
position="top-left"
v-bind:controls="controls"
v-on:added="handleAdded2"
v-on:drawcreate="handleCreate2"
ref="drawref2"
>
<div id="toolbar-wrapper2">
<div class="toolbar-item" v-on:click="toggleQueryPoint2">点查询</div>
<div class="toolbar-item" v-on:click="toggleQueryPolygon2">区查询</div>
</div>
</mapgis-draw>
</mapgis-web-map>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
accessToken:
'pk.eyJ1IjoicGFybmRlZWRsaXQiLCJhIjoiY2o1MjBtYTRuMDhpaTMzbXhpdjd3YzhjdCJ9.sCoubaHF9-nhGTA-sgz0sA', // 使用mapbox样式需要的秘钥
mapStyle: {
//设置版本号,一定要设置
version: 8,
//添加来源
sources: {},
//设置加载并显示来源的图层信息
layers: []
}, // 地图样式
mapZoom: 3, // 地图初始化级数
outerCenter: [130, 30], // 地图显示中心
mapCrs: 'EPSG:4326',
layerId: 'igsLayer_layerId',
sourceId: 'igsLayer_sourceId',
layer: {}, // 图层配置信息
baseURL: 'http://t2.tianditu.gov.cn/vec_c/wmts', // 请求基地址
token: '2ddaabf906d4b5418aed0078e1657029', // 请求天地图的key值
controls: {
point: false,
line_string: false,
polygon: false,
trash: false,
combine_features: false,
uncombine_features: false
},
measureMode: undefined,
coordinates: [],
area: 0,
perimeter: 0,
mode: undefined
}
},
methods: {
enableMeasure() {
const component = this.$refs.measureref
if (component) {
component.enableMeasure()
}
},
handleMapLoad(payload) {
this.map = payload.map
},
handleAdded(e, data) {
const vm = this
let { measure, map } = e
this.measure = measure
vm.map.on('draw.selectionchange', e => {
const { features, points } = e
const hasLine = features && features.length > 0
const hasPoints = points && points.length > 0
if (hasLine && !hasPoints) {
// line clicked
if (vm.measure.getMode() !== 'direct_select') {
vm.measure.changeMode('direct_select', { featureId: features[0].id })
}
} else if (hasLine && hasPoints) {
// line vertex clicked
} else if (!hasLine && !hasPoints) {
// deselected
}
})
},
handleCreate(e) {
// this.measure && this.measure.deleteAll();
console.log('绘制结果', e)
this.disableDrag()
},
handleMeasure(e) {
console.log('测量结果', e)
this.disableDrag()
const { center, perimeter, area } = e
const coords = center.geometry.coordinates
this.coordinates = coords
this.area = area || '无'
this.perimeter = perimeter
},
toggleQueryLength(e) {
this.enableMeasure()
this.coordinates = []
this.measureMode = 'measure-length'
this.measure && this.measure.changeMode('draw_line_string')
},
toggleQueryArea(e) {
this.enableMeasure()
this.coordinates = []
this.measureMode = 'measure-area'
this.measure && this.measure.changeMode('draw_polygon')
},
disableDrag() {
const vm = this
vm.map.on('draw.selectionchange', e => {
const { features, points } = e
const hasLine = features && features.length > 0
const hasPoints = points && points.length > 0
if (hasLine && !hasPoints) {
// line clicked
if (vm.measure.getMode() !== 'simple_select') {
vm.measure.changeMode('simple_select', { featureIds: [] })
// vm.measure.changeMode('direct_select', { featureId: features[0].id });
}
} else if (hasLine && hasPoints) {
// line vertex clicked
} else if (!hasLine && !hasPoints) {
// deselected
}
})
},
enableDrawer1() {
const component = this.$refs.drawref1
if (component) {
component.enableDrawer()
}
},
enableDrawer2() {
const component = this.$refs.drawref2
if (component) {
component.enableDrawer()
}
},
handleAdded1(e, data) {
let { drawer, map } = e
this.drawer1 = drawer
},
handleAdded2(e, data) {
let { drawer, map } = e
this.drawer2 = drawer
},
handleCreate1(e) {
console.log('create', e)
// this.drawer1 && this.drawer1.deleteAll();
},
handleCreate2(e) {
console.log('create', e)
this.drawer2 && this.drawer2.deleteAll()
},
togglePoint1(e) {
this.enableDrawer1()
this.drawer1 && this.drawer1.changeMode('draw_point')
},
togglePolyline1() {
this.enableDrawer1()
this.drawer1 && this.drawer1.changeMode('draw_line_string')
},
togglePolygon1() {
this.enableDrawer1()
this.mode = 'QueryByPolygon'
this.drawer1 && this.drawer1.changeMode('draw_polygon')
},
toggleDelete1() {
this.drawer1 && this.drawer1.deleteAll()
},
toggleQueryPoint2() {
this.enableDrawer2()
this.drawer2 && this.drawer2.changeMode('draw_point')
},
toggleQueryPolygon2() {
this.enableDrawer2()
this.drawer2 && this.drawer2.changeMode('draw_polygon')
},
toggleDelete2() {
this.drawer2 && this.drawer2.deleteAll()
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
#toolbar-wrapper {
position: absolute;
z-index: 9999;
display: inline-flex;
overflow-x: hidden;
overflow-y: visible;
top: 20px;
left: 20px;
}
#toolbar-wrapper1 {
position: absolute;
z-index: 9999;
display: inline-flex;
overflow-x: hidden;
overflow-y: visible;
top: 80px;
left: 20px;
}
#toolbar-wrapper2 {
position: absolute;
z-index: 9999;
display: inline-flex;
overflow-x: hidden;
overflow-y: visible;
top: 140px;
left: 20px;
}
.toolbar-item {
background: #ffffff;
border: 1px dashed #666666;
text-align: center;
font-size: 20px;
line-height: 20px;
height: fit-content;
padding: 6px 16px;
cursor: pointer;
}
#map {
height: 100vh;
width: 100%;
}
.label {
color: #3bb2d0;
font-size: 16px;
font-weight: bold;
}
</style>
Due to draw & measure all both packaging
mapboxgl-draw , when both use draw & measure, draw.create event will repeat bind
in same map.
绘制和测量组件都是同时针对 mapbox-draw的包装
,因此同时使用的时候,会导致draw的事件 和 measure的事件重复绑定
在同一个地图对象上。
when use draw Component unbind measure event, when use measure component unbind draw event 当使用绘制组件的时候取消测量组件的绑定,当使用测量组件的时候取消绘制组件的绑定
enableMeasure () {
this.$_unbindDrawEvents();
// ........
},
enableDrawer () {
this.$_unbindMeasureEvents();
// ........
},
<template>
<div>
<mapgis-web-map @load="handleMapLoad">
<mapgis-rastertile-layer :layerId="layerId" :url="url" />
<mapgis-mvt-style-layer :mvtStyle="mvtStyle" v-if="show" />
<mapgis-draw
position="top-left"
v-bind:controls="controls"
v-on:added="handleDrawAdded"
v-on:drawcreate="handleDrawCreate"
ref="draw"
>
<div id="mapgis-2d-draw-wrapper">
<a-button-group>
<a-button v-on:click="togglePoint">画点</a-button>
<a-button v-on:click="togglePolyline">画线</a-button>
<a-button v-on:click="togglePolygon">画区</a-button>
<a-button type="primary" v-on:click="toggleDelete">删除</a-button>
</a-button-group>
</div>
</mapgis-draw>
<mapgis-measure
position="top-left"
:measureMode="measureMode"
v-on:added="handleMeasureAdded"
ref="measure"
>
<div id="mapgis-2d-measure-wrapper">
<a-button-group>
<a-button v-on:click="toggleLength">长度</a-button>
<a-button v-on:click="toggleArea">面积</a-button>
</a-button-group>
</div>
</mapgis-measure>
</mapgis-web-map>
</div>
</template>
<script>
export default {
name: 'mapgis-2d-map-wrapper',
data () {
return {
show: true,
layerId: 'igsLayer_layerId',
url: 'http://t0.tianditu.com/DataServer?T=vec_w&L={z}&Y={y}&X={x}&tk=9c157e9585486c02edf817d2ecbc7752',
mvtStyle: 'http://develop.smaryun.com:6163/igs/rest/mrms/vtiles/styles/街道-墨卡托.json',
drawer: undefined,
measure: undefined,
measureMode: undefined,
controls: {
point: false,
line_string: false,
polygon: false,
trash: false,
combine_features: false,
uncombine_features: false
}
}
},
methods: {
handleMapLoad () {
/* const vm = this
window.setTimeout(() => {
vm.mvtStyle = 'http://develop.smaryun.com:6163/igs/rest/mrms/vtiles/styles/深色-墨卡托.json'
}, 5000)
window.setTimeout(() => {
vm.show = false
}, 15000) */
},
enableDrawer () {
const component = this.$refs.draw
if (component) {
component.enableDrawer()
}
},
handleDrawAdded (e) {
const { drawer } = e
this.drawer = drawer
},
togglePoint (e) {
this.type = 'point'
this.enableDrawer()
this.drawer && this.drawer.changeMode('draw_point')
},
togglePolyline () {
this.type = 'polyline'
this.enableDrawer()
this.drawer && this.drawer.changeMode('draw_line_string')
},
togglePolygon () {
this.type = 'polygon'
this.enableDrawer()
this.drawer && this.drawer.changeMode('draw_polygon')
},
toggleDelete () {
this.featureArr = ''
this.queryParameters = ''
this.drawer && this.drawer.deleteAll()
},
handleDrawCreate () {
},
handleMeasureAdded (e) {
const { measure } = e
this.measure = measure
},
enableMeasure () {
const component = this.$refs.measure
if (component) {
component.enableMeasure()
}
},
toggleLength () {
this.enableMeasure()
// this.coordinates = []
this.measureMode = 'measure-length'
this.measure && this.measure.changeMode('draw_line_string')
},
toggleArea () {
this.enableMeasure()
// this.coordinates = [];
this.measureMode = 'measure-area'
this.measure && this.measure.changeMode('draw_polygon')
}
}
}
</script>
<style>
#mapgis-2d-draw-wrapper {
position: absolute;
z-index: 9999;
top: 10px;
left: 10px;
}
#mapgis-2d-measure-wrapper {
position: absolute;
z-index: 9999;
top: 50px;
left: 10px;
}
</style>
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'off' of null at MapboxDraw.onRemove (setup.js?2140:15) at o.removeControl (mapbox-gl.js?12f2:33) at VueComponent.$_removeDrawControl (withControlEvents.js?20da:58) at VueComponent.$_addDrawControl (withControlEvents.js?20da:42) at VueComponent.enableDrawer (BaseDraw.vue?9d04:157) at VueComponent.enableDrawer1 (HelloWorld.vue?140d:195) at VueComponent.togglePolygon1 (HelloWorld.vue?140d:228) at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854) at HTMLDivElement.invoker (vue.runtime.esm.js?2b0e:2179) at HTMLDivElement.original._wrapper (vue.runtime.esm.js?2b0e:6917)
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'off' of null at MapboxDraw.onRemove (setup.js?5a7e:15) at o.removeControl (mapbox-gl.js?10e2:33) at VueComponent.$_removeMeasureControl (withControlEvents.js?e394:100) at VueComponent.$_addMeasureControl (withControlEvents.js?e394:84) at VueComponent.enableMeasure (Measure.vue?b5f7:120) at VueComponent.enableMeasure (HelloWorld.vue?140d:121) at VueComponent.toggleQueryArea (HelloWorld.vue?140d:169) at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854) at HTMLDivElement.invoker (vue.runtime.esm.js?2b0e:2179) at HTMLDivElement.original._wrapper (vue.runtime.esm.js?2b0e:6917)