【类 型】:feat
【原 因】:飞行区域安全控制需求,需要前端支持禁飞区与限飞区的可视化设置与展示。 【过 程】:- 新增 RestrictflyControl 控件,支持限飞区绘制并弹窗设置高度; - 支持将限飞区多边形及高度通过 setRestrictflyData 接口保存; - 在飞行地图中新增 PolygonToggleControl 控件,可开关显示禁飞区/限飞区图层; - 限飞区标签支持显示限高信息,如“限飞高度120米”。 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
This commit is contained in:
parent
d731a42bfa
commit
555d480efd
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/node_modules
|
/node_modules
|
||||||
/dist
|
/dist
|
||||||
|
/package-lock.json
|
||||||
|
31270
package-lock.json
generated
31270
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,16 +9,17 @@
|
|||||||
"lint": "eslint --ext .js,.vue src"
|
"lint": "eslint --ext .js,.vue src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@turf/turf": "^7.2.0",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"echarts": "^5.6.0",
|
"echarts": "^5.6.0",
|
||||||
"element-ui": "^2.15.14",
|
"element-ui": "^2.15.14",
|
||||||
|
"geodist": "^0.2.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mapbox-gl": "^2.15.0",
|
"mapbox-gl": "^2.15.0",
|
||||||
"mqtt": "^2.18.9",
|
"mqtt": "^2.18.9",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"geodist": "^0.2.1",
|
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-router": "^3.6.5",
|
"vue-router": "^3.6.5",
|
||||||
"vue-template-compiler": "^2.7.16",
|
"vue-template-compiler": "^2.7.16",
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import mapboxgl from 'mapbox-gl'
|
import mapboxgl from 'mapbox-gl'
|
||||||
import { MapboxStyleSwitcherControl, FollowControl, CustomFullscreenControl, NoFlyControl, SaveToFileControl, PolygonToggleControl } from '@/utils/mapboxgl_plugs'
|
import { MapboxStyleSwitcherControl, FollowControl, CustomFullscreenControl, NoFlyControl, RestrictflyControl, SaveToFileControl, PolygonToggleControl } from '@/utils/mapboxgl_plugs'
|
||||||
import planeIcon from '@/assets/svg/plane.svg'
|
import planeIcon from '@/assets/svg/plane.svg'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -172,6 +172,10 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
enableRestrictfly: { // 限飞区 设置 组件
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
enableShowNofly: { // 显示 禁飞区 限飞区 组件
|
enableShowNofly: { // 显示 禁飞区 限飞区 组件
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -345,22 +349,23 @@ export default {
|
|||||||
|
|
||||||
// 禁飞区 限飞区 设置组件
|
// 禁飞区 限飞区 设置组件
|
||||||
if (this.enableNofly) {
|
if (this.enableNofly) {
|
||||||
const noflyPolygons = this.$store.state.noflyData[0]
|
|
||||||
const restrictflyPolygons = this.$store.state.noflyData[1]
|
|
||||||
const shopId = this.$store.state.user.shop_id
|
|
||||||
|
|
||||||
this.map.addControl(new NoFlyControl({
|
this.map.addControl(new NoFlyControl({
|
||||||
noflyPolygons,
|
defaultPolygons: this.$store.state.noflyData[0], // 禁飞
|
||||||
restrictflyPolygons,
|
shopId: this.$store.state.user.shop_id,
|
||||||
shopId,
|
onSave: (data) => {
|
||||||
onSave: (nofly, limit) => {
|
console.log('保存成功:', data)
|
||||||
console.log('保存成功:', nofly, limit)
|
}
|
||||||
},
|
}), 'top-left')
|
||||||
onDrawFinish: (nofly) => {
|
}
|
||||||
console.log('禁飞区绘制完成:', nofly)
|
|
||||||
},
|
// 禁飞区 限飞区 设置组件
|
||||||
onLimitFinish: (limit) => {
|
if (this.enableRestrictfly) {
|
||||||
console.log('限飞区绘制完成:', limit)
|
this.map.addControl(new RestrictflyControl({
|
||||||
|
defaultPolygons: this.$store.state.noflyData[1], // 限飞区
|
||||||
|
defaultHeights: this.$store.state.noflyData[2], // 限飞区对应高度
|
||||||
|
shopId: this.$store.state.user.shop_id,
|
||||||
|
onSave: (data) => {
|
||||||
|
console.log('保存成功:', data)
|
||||||
}
|
}
|
||||||
}), 'top-left')
|
}), 'top-left')
|
||||||
}
|
}
|
||||||
@ -369,6 +374,7 @@ export default {
|
|||||||
if (this.enableShowNofly) {
|
if (this.enableShowNofly) {
|
||||||
const noflyPolygons = this.$store.state.noflyData[0] || []
|
const noflyPolygons = this.$store.state.noflyData[0] || []
|
||||||
const restrictflyPolygons = this.$store.state.noflyData[1] || []
|
const restrictflyPolygons = this.$store.state.noflyData[1] || []
|
||||||
|
const restrictflyHeights = this.$store.state.noflyData[2] || []
|
||||||
|
|
||||||
this.map.addControl(new PolygonToggleControl({
|
this.map.addControl(new PolygonToggleControl({
|
||||||
defaultIconClass: 'iconfont icon-jinfeiqu_weidianji f-s-20 seatFontColor',
|
defaultIconClass: 'iconfont icon-jinfeiqu_weidianji f-s-20 seatFontColor',
|
||||||
@ -376,16 +382,18 @@ export default {
|
|||||||
|
|
||||||
onToggle: (isActive) => {
|
onToggle: (isActive) => {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
// 激活时绘制禁飞区
|
// 绘制禁飞区
|
||||||
noflyPolygons.forEach((coords, i) => {
|
noflyPolygons.forEach((coords, i) => {
|
||||||
this.drawPolygonWithLabel(coords, `nofly-polygon-${i}`, '#F33', '禁飞区')
|
this.drawPolygonWithLabel(coords, `nofly-polygon-${i}`, '#F33', '禁飞区')
|
||||||
})
|
})
|
||||||
// 绘制限飞区
|
// 绘制限飞区,添加高度标签
|
||||||
restrictflyPolygons.forEach((coords, i) => {
|
restrictflyPolygons.forEach((coords, i) => {
|
||||||
this.drawPolygonWithLabel(coords, `restrict-polygon-${i}`, '#F83', '限飞区')
|
const height = restrictflyHeights[i] || 0
|
||||||
|
const label = `限飞高度${height}米`
|
||||||
|
this.drawPolygonWithLabel(coords, `restrict-polygon-${i}`, '#F83', label)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 关闭时清除禁飞区和限飞区相关图层和数据源
|
// 清除图层
|
||||||
const layerIds = []
|
const layerIds = []
|
||||||
const sourceIds = []
|
const sourceIds = []
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/register/index',
|
redirect: '/register/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '飞机管理',
|
title: '管理飞机',
|
||||||
icon: 'el-icon-edit-outline',
|
icon: 'el-icon-edit-outline',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'plane'
|
tapName: 'plane'
|
||||||
@ -116,23 +116,33 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/nofly',
|
path: '/nofly',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/nofly/set',
|
redirect: '/nofly/setNofly',
|
||||||
meta: {
|
meta: {
|
||||||
title: '设置禁飞区',
|
title: '限制飞行',
|
||||||
icon: 'iconfont icon-feihangluxian',
|
icon: 'iconfont icon-jinfeiqu',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'plane'
|
tapName: 'plane'
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/nofly/set',
|
path: '/nofly/setNofly',
|
||||||
component: () => import('@/views/layout/components/main/nofly/set'),
|
component: () => import('@/views/layout/components/main/nofly/setNofly'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '设置禁飞区',
|
title: '设置禁飞区',
|
||||||
icon: 'iconfont icon-huizhi',
|
icon: 'iconfont icon-huizhi',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'plane'
|
tapName: 'plane'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/nofly/setRestrictfly',
|
||||||
|
component: () => import('@/views/layout/components/main/nofly/setRestrictfly'),
|
||||||
|
meta: {
|
||||||
|
title: '设置限飞区',
|
||||||
|
icon: 'iconfont icon-huizhi',
|
||||||
|
roles: ['admin', 'editor'],
|
||||||
|
tapName: 'plane'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -141,7 +151,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/route/index',
|
redirect: '/route/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '航线管理',
|
title: '管理航线',
|
||||||
icon: 'iconfont icon-feihangluxian',
|
icon: 'iconfont icon-feihangluxian',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'plane'
|
tapName: 'plane'
|
||||||
@ -185,7 +195,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/site/index',
|
redirect: '/site/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '站点管理',
|
title: '管理站点',
|
||||||
icon: 'iconfont icon-zhandianguanli',
|
icon: 'iconfont icon-zhandianguanli',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'plane'
|
tapName: 'plane'
|
||||||
@ -252,7 +262,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/shop/edit',
|
redirect: '/shop/edit',
|
||||||
meta: {
|
meta: {
|
||||||
title: '商铺管理',
|
title: '管理商铺',
|
||||||
icon: 'iconfont icon-a-shanghu_choose2x1',
|
icon: 'iconfont icon-a-shanghu_choose2x1',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -262,7 +272,7 @@ const routes = [
|
|||||||
path: '/shop/edit',
|
path: '/shop/edit',
|
||||||
component: () => import('@/views/layout/components/main/shop/add'),
|
component: () => import('@/views/layout/components/main/shop/add'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '商铺设置',
|
title: '设置商铺',
|
||||||
icon: 'iconfont icon-dianpuguanli',
|
icon: 'iconfont icon-dianpuguanli',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -340,7 +350,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/category/index',
|
redirect: '/category/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '分类管理',
|
title: '管理分类',
|
||||||
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
|
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -350,7 +360,7 @@ const routes = [
|
|||||||
path: '/category/index',
|
path: '/category/index',
|
||||||
component: () => import('@/views/layout/components/main/category/index'),
|
component: () => import('@/views/layout/components/main/category/index'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '分类管理',
|
title: '管理分类',
|
||||||
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
|
icon: 'iconfont icon-a-ziliaocaozuoxianshifenleishu',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -363,7 +373,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/spu/index',
|
redirect: '/spu/index',
|
||||||
meta: {
|
meta: {
|
||||||
title: '商品管理',
|
title: '管理商品',
|
||||||
icon: 'iconfont icon-chanpin',
|
icon: 'iconfont icon-chanpin',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -438,7 +448,7 @@ const routes = [
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/broadcast/banner',
|
redirect: '/broadcast/banner',
|
||||||
meta: {
|
meta: {
|
||||||
title: '广告管理',
|
title: '管理广告',
|
||||||
icon: 'iconfont icon-guanggao',
|
icon: 'iconfont icon-guanggao',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -448,7 +458,7 @@ const routes = [
|
|||||||
path: '/broadcast/banner',
|
path: '/broadcast/banner',
|
||||||
component: () => import('@/views/layout/components/main/broadcast/banner'),
|
component: () => import('@/views/layout/components/main/broadcast/banner'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'banner设置',
|
title: '设置banner',
|
||||||
icon: 'iconfont icon-banner',
|
icon: 'iconfont icon-banner',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -458,7 +468,7 @@ const routes = [
|
|||||||
path: '/broadcast/notice',
|
path: '/broadcast/notice',
|
||||||
component: () => import('@/views/layout/components/main/broadcast/notice'),
|
component: () => import('@/views/layout/components/main/broadcast/notice'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '滚动通知设置',
|
title: '设置滚动通知',
|
||||||
icon: 'iconfont icon-m-gundongwenzi',
|
icon: 'iconfont icon-m-gundongwenzi',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
@ -481,7 +491,7 @@ const routes = [
|
|||||||
path: '/order/index',
|
path: '/order/index',
|
||||||
component: () => import('@/views/layout/components/main/order/index'),
|
component: () => import('@/views/layout/components/main/order/index'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '订单管理',
|
title: '管理订单',
|
||||||
icon: 'iconfont icon-a-SalesOrderManagement',
|
icon: 'iconfont icon-a-SalesOrderManagement',
|
||||||
roles: ['admin', 'editor'],
|
roles: ['admin', 'editor'],
|
||||||
tapName: 'admin'
|
tapName: 'admin'
|
||||||
|
@ -17,7 +17,7 @@ const store = new Vuex.Store({
|
|||||||
airList: [], // 所有飞机列表
|
airList: [], // 所有飞机列表
|
||||||
siteList: [], // 站点列表
|
siteList: [], // 站点列表
|
||||||
routeList: [], // 航线列表
|
routeList: [], // 航线列表
|
||||||
noflyData: [[], []], // [0]禁飞区数据 [1]限制飞区
|
noflyData: [[], [], []], // [0]禁飞区数据 [1]限制飞区 [2]限飞区高度
|
||||||
categoryList: [], // 分类列表(小程序)
|
categoryList: [], // 分类列表(小程序)
|
||||||
spuList: [], // 商品spu列表
|
spuList: [], // 商品spu列表
|
||||||
skuList: [], // 商品sku列表
|
skuList: [], // 商品sku列表
|
||||||
@ -70,13 +70,14 @@ const store = new Vuex.Store({
|
|||||||
* @description: 设置禁飞区列表
|
* @description: 设置禁飞区列表
|
||||||
*/
|
*/
|
||||||
setNoflyData (state, payload) {
|
setNoflyData (state, payload) {
|
||||||
if (payload && payload.nofly_data && payload.restrictfly_data) {
|
if (payload && payload.nofly_data && payload.restrictfly_data && payload.restrictfly_height) {
|
||||||
state.noflyData = [
|
state.noflyData = [
|
||||||
JSON.parse(payload.nofly_data || '[]'),
|
JSON.parse(payload.nofly_data || '[]'),
|
||||||
JSON.parse(payload.restrictfly_data || '[]')
|
JSON.parse(payload.restrictfly_data || '[]'),
|
||||||
|
JSON.parse(payload.restrictfly_height || '[]')
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
state.noflyData = [[], []]
|
state.noflyData = [[], [], []]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -625,7 +626,7 @@ const store = new Vuex.Store({
|
|||||||
if (res.data.status === 1) {
|
if (res.data.status === 1) {
|
||||||
commit('setNoflyData', res.data.noflyData)
|
commit('setNoflyData', res.data.noflyData)
|
||||||
} else {
|
} else {
|
||||||
commit('setNoflyData', [[], []])
|
commit('setNoflyData', [[], [], []])
|
||||||
Message.warning(res.data.msg || '暂无禁飞区数据')
|
Message.warning(res.data.msg || '暂无禁飞区数据')
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
@ -198,16 +198,15 @@ export async function saveFlyData (data) {
|
|||||||
* @param {Array} restrictfly_data 限制飞区数据数组
|
* @param {Array} restrictfly_data 限制飞区数据数组
|
||||||
* @returns {Object|null} 返回接口响应数据 或 null 表示失败
|
* @returns {Object|null} 返回接口响应数据 或 null 表示失败
|
||||||
*/
|
*/
|
||||||
export async function setNoflyData (shopId, noflyData, restrictflyData) {
|
export async function setNoflyData (shopId, noflyData) {
|
||||||
try {
|
try {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
params.append('shop_id', shopId || '')
|
params.append('shop_id', shopId || '')
|
||||||
params.append('nofly_data', JSON.stringify(noflyData || []))
|
params.append('nofly_data', JSON.stringify(noflyData || []))
|
||||||
params.append('restrictfly_data', JSON.stringify(restrictflyData || []))
|
|
||||||
|
|
||||||
const res = await api.post('setNoflyData', params)
|
const res = await api.post('setNoflyData', params)
|
||||||
if (res.data.status === 1) {
|
if (res.data.status === 1) {
|
||||||
store.dispatch('fetchNoflyData', shopId)// 更新禁飞区数据
|
store.dispatch('fetchNoflyData', shopId)// 更新禁限飞区数据
|
||||||
Message.success(res.data.msg)
|
Message.success(res.data.msg)
|
||||||
} else {
|
} else {
|
||||||
Message.warning(res.data.msg)
|
Message.warning(res.data.msg)
|
||||||
@ -218,3 +217,31 @@ export async function setNoflyData (shopId, noflyData, restrictflyData) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 保存限飞区数据
|
||||||
|
* @param {string|number} shop_id 商铺ID
|
||||||
|
* @param {Array} restrictfly_data 限制飞区数据数组
|
||||||
|
* @param {Array} restrictfly_height 限制飞区数据高度组
|
||||||
|
* @returns {Object|null} 返回接口响应数据 或 null 表示失败
|
||||||
|
*/
|
||||||
|
export async function setRestrictflyData (shopId, restrictflyData, restrictflyHeight) {
|
||||||
|
try {
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
params.append('shop_id', shopId || '')
|
||||||
|
params.append('restrictfly_data', JSON.stringify(restrictflyData || []))
|
||||||
|
params.append('restrictfly_height', JSON.stringify(restrictflyHeight || []))
|
||||||
|
|
||||||
|
const res = await api.post('setNoflyData', params)
|
||||||
|
if (res.data.status === 1) {
|
||||||
|
store.dispatch('fetchNoflyData', shopId)// 更新禁限飞区数据
|
||||||
|
Message.success(res.data.msg)
|
||||||
|
} else {
|
||||||
|
Message.warning(res.data.msg)
|
||||||
|
}
|
||||||
|
return res.data
|
||||||
|
} catch (error) {
|
||||||
|
Message.error('保存限飞区数据失败')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import mapboxgl from 'mapbox-gl'
|
import mapboxgl from 'mapbox-gl'
|
||||||
import MapboxDraw from '@mapbox/mapbox-gl-draw'
|
import MapboxDraw from '@mapbox/mapbox-gl-draw'
|
||||||
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
|
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
|
||||||
import { setNoflyData } from '@/utils/api/table'
|
import { setNoflyData, setRestrictflyData } from '@/utils/api/table'
|
||||||
import { Message } from 'element-ui'
|
import { Message, MessageBox } from 'element-ui'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义地图样式切换控件
|
* 自定义地图样式切换控件
|
||||||
@ -218,65 +218,45 @@ export class CustomFullscreenControl extends mapboxgl.FullscreenControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置禁飞区 限飞区 保存 删除控件
|
// 禁飞区控件类
|
||||||
|
|
||||||
export class NoFlyControl {
|
export class NoFlyControl {
|
||||||
constructor (options = {}) {
|
constructor (options = {}) {
|
||||||
this._map = null
|
this._map = null // 地图实例
|
||||||
this._container = null
|
this._container = null // 控件容器(用于放按钮)
|
||||||
|
this._draw = null // MapboxDraw 实例
|
||||||
this._draw = null
|
this._onDrawFinish = options.onDrawFinish || function () {} // 绘制完成时的回调
|
||||||
this._onDrawFinish = options.onDrawFinish || function () {}
|
this._defaultPolygons = options.defaultPolygons || [] // 初始加载的禁飞区多边形坐标
|
||||||
this._noflyPolygons = options.noflyPolygons || []
|
this._onSave = options.onSave || function () {} // 保存时的回调
|
||||||
|
this._shopId = options.shopId // 商户ID,用于提交接口
|
||||||
this._onLimitFinish = options.onLimitFinish || function () {}
|
|
||||||
this._restrictflyPolygons = options.restrictflyPolygons || []
|
|
||||||
|
|
||||||
this._onSave = options.onSave || function () {}
|
|
||||||
this._shopId = options.shopId
|
|
||||||
|
|
||||||
this._activeMode = 'nofly' // 当前绘制类型
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当控件添加到地图上时调用
|
||||||
onAdd (map) {
|
onAdd (map) {
|
||||||
this._map = map
|
this._map = map
|
||||||
|
|
||||||
|
// 创建控件按钮容器
|
||||||
this._container = document.createElement('div')
|
this._container = document.createElement('div')
|
||||||
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group'
|
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group'
|
||||||
|
|
||||||
// --- 绘制禁飞区按钮 ---
|
// --- 绘制按钮 ---
|
||||||
const drawButton = document.createElement('button')
|
const drawButton = document.createElement('button')
|
||||||
drawButton.className = 'mapboxgl-ctrl-icon'
|
drawButton.className = 'mapboxgl-ctrl-icon'
|
||||||
drawButton.type = 'button'
|
drawButton.type = 'button'
|
||||||
drawButton.innerHTML = '✏️'
|
drawButton.innerHTML = '✏️' // 图标:铅笔
|
||||||
drawButton.title = '绘制禁飞区'
|
drawButton.title = '绘制禁飞区' // 鼠标提示
|
||||||
drawButton.onclick = () => {
|
drawButton.onclick = () => this._enableDraw() // 点击启用绘制模式
|
||||||
this._activeMode = 'nofly'
|
|
||||||
this._enableDraw()
|
|
||||||
}
|
|
||||||
this._container.appendChild(drawButton)
|
this._container.appendChild(drawButton)
|
||||||
|
|
||||||
// --- 绘制限飞区按钮 ---
|
|
||||||
const limitButton = document.createElement('button')
|
|
||||||
limitButton.className = 'mapboxgl-ctrl-icon'
|
|
||||||
limitButton.type = 'button'
|
|
||||||
limitButton.innerHTML = '✒️'
|
|
||||||
limitButton.title = '绘制限飞区'
|
|
||||||
limitButton.onclick = () => {
|
|
||||||
this._activeMode = 'limit'
|
|
||||||
this._enableDraw()
|
|
||||||
}
|
|
||||||
this._container.appendChild(limitButton)
|
|
||||||
|
|
||||||
// --- 保存按钮 ---
|
// --- 保存按钮 ---
|
||||||
const saveButton = document.createElement('button')
|
const saveButton = document.createElement('button')
|
||||||
saveButton.className = 'mapboxgl-ctrl-icon'
|
saveButton.className = 'mapboxgl-ctrl-icon'
|
||||||
saveButton.type = 'button'
|
saveButton.type = 'button'
|
||||||
saveButton.innerHTML = '💾'
|
saveButton.innerHTML = '💾' // 图标:磁盘
|
||||||
saveButton.title = '保存禁飞区及限飞区'
|
saveButton.title = '保存禁飞区'
|
||||||
saveButton.onclick = () => this._savePolygons()
|
saveButton.onclick = () => this._savePolygons()
|
||||||
this._container.appendChild(saveButton)
|
this._container.appendChild(saveButton)
|
||||||
|
|
||||||
// --- 删除按钮 ---
|
// --- 删除按钮(删除选中图形) ---
|
||||||
const deleteButton = document.createElement('button')
|
const deleteButton = document.createElement('button')
|
||||||
deleteButton.className = 'mapboxgl-ctrl-icon'
|
deleteButton.className = 'mapboxgl-ctrl-icon'
|
||||||
deleteButton.type = 'button'
|
deleteButton.type = 'button'
|
||||||
@ -285,43 +265,248 @@ export class NoFlyControl {
|
|||||||
deleteButton.onclick = () => this._deleteSelected()
|
deleteButton.onclick = () => this._deleteSelected()
|
||||||
this._container.appendChild(deleteButton)
|
this._container.appendChild(deleteButton)
|
||||||
|
|
||||||
// 初始化 Draw 控件
|
// --- 初始化 MapboxDraw 控件 ---
|
||||||
this._draw = new MapboxDraw({
|
this._draw = new MapboxDraw({
|
||||||
displayControlsDefault: false,
|
displayControlsDefault: false, // 不显示默认工具条
|
||||||
styles: this._getDrawStyles()
|
styles: [ // 自定义绘制样式(橙色)
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-fill',
|
||||||
|
type: 'fill',
|
||||||
|
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
|
||||||
|
paint: {
|
||||||
|
'fill-color': '#f33', // 填充颜色
|
||||||
|
'fill-opacity': 0.3 // 透明度
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-stroke-active',
|
||||||
|
type: 'line',
|
||||||
|
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
|
||||||
|
paint: {
|
||||||
|
'line-color': '#f33', // 边框颜色
|
||||||
|
'line-width': 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 控制点外圈(白色光晕)
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-and-line-vertex-halo-active',
|
||||||
|
type: 'circle',
|
||||||
|
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': 7,
|
||||||
|
'circle-color': '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 控制点内圈
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-and-line-vertex-active',
|
||||||
|
type: 'circle',
|
||||||
|
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': 5,
|
||||||
|
'circle-color': '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 将 Draw 控件添加到地图上
|
||||||
map.addControl(this._draw)
|
map.addControl(this._draw)
|
||||||
|
|
||||||
// 加载已有禁飞区
|
// --- 加载已有禁飞区(回显数据) ---
|
||||||
if (this._noflyPolygons.length > 0) {
|
if (this._defaultPolygons.length > 0) {
|
||||||
const features = this._noflyPolygons.map(coords => ({
|
const features = this._defaultPolygons.map(coords => ({
|
||||||
|
type: 'Feature',
|
||||||
|
geometry: {
|
||||||
|
type: 'Polygon',
|
||||||
|
coordinates: [coords] // 注意:GeoJSON Polygon 外层需要再包一层
|
||||||
|
},
|
||||||
|
properties: {}
|
||||||
|
}))
|
||||||
|
this._draw.set({
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听绘制完成事件
|
||||||
|
map.on('draw.create', this._handleDraw.bind(this))
|
||||||
|
|
||||||
|
return this._container
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当控件被移除时执行
|
||||||
|
onRemove () {
|
||||||
|
if (this._map && this._draw) {
|
||||||
|
this._map.removeControl(this._draw)
|
||||||
|
}
|
||||||
|
if (this._container?.parentNode) {
|
||||||
|
this._container.parentNode.removeChild(this._container)
|
||||||
|
}
|
||||||
|
this._map = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启用多边形绘制模式
|
||||||
|
_enableDraw () {
|
||||||
|
if (this._draw && this._map) {
|
||||||
|
this._draw.changeMode('draw_polygon')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制完成的处理函数
|
||||||
|
_handleDraw (e) {
|
||||||
|
const features = this._draw.getAll()
|
||||||
|
if (features.features.length > 0) {
|
||||||
|
const coordinates = features.features.map(f => f.geometry.coordinates)
|
||||||
|
this._onDrawFinish(coordinates) // 通知外部最新绘制结果
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除当前选中的图形
|
||||||
|
_deleteSelected () {
|
||||||
|
if (this._draw) {
|
||||||
|
const selected = this._draw.getSelectedIds()
|
||||||
|
if (selected.length > 0) {
|
||||||
|
this._draw.delete(selected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交所有禁飞区数据到服务器
|
||||||
|
async _savePolygons () {
|
||||||
|
if (!this._draw) return
|
||||||
|
|
||||||
|
const allFeatures = this._draw.getAll()
|
||||||
|
|
||||||
|
// 提取所有 Polygon 类型图形的坐标(只取外环)
|
||||||
|
const polygons = allFeatures.features
|
||||||
|
.filter(f => f.geometry.type === 'Polygon')
|
||||||
|
.map(f => f.geometry.coordinates[0])
|
||||||
|
|
||||||
|
try {
|
||||||
|
const shopId = this._shopId
|
||||||
|
await setNoflyData(shopId, polygons)
|
||||||
|
} catch (error) {
|
||||||
|
Message.error('上传禁飞区数据时发生错误')
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用保存成功回调
|
||||||
|
this._onSave(polygons)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限飞区控件类
|
||||||
|
export class RestrictflyControl {
|
||||||
|
constructor (options = {}) {
|
||||||
|
this._map = null
|
||||||
|
this._container = null
|
||||||
|
this._draw = null
|
||||||
|
this._shopId = options.shopId
|
||||||
|
this._defaultPolygons = options.defaultPolygons || []
|
||||||
|
this._defaultHeights = options.defaultHeights || []
|
||||||
|
this._restrictflyHeights = [] // 保存限高值
|
||||||
|
this._onSave = options.onSave || function () {}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd (map) {
|
||||||
|
this._map = map
|
||||||
|
|
||||||
|
this._container = document.createElement('div')
|
||||||
|
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group'
|
||||||
|
|
||||||
|
// 绘制按钮
|
||||||
|
const drawButton = document.createElement('button')
|
||||||
|
drawButton.className = 'mapboxgl-ctrl-icon'
|
||||||
|
drawButton.type = 'button'
|
||||||
|
drawButton.innerHTML = '✏️'
|
||||||
|
drawButton.title = '绘制限飞区'
|
||||||
|
drawButton.onclick = () => this._enableDraw()
|
||||||
|
this._container.appendChild(drawButton)
|
||||||
|
|
||||||
|
// 保存按钮
|
||||||
|
const saveButton = document.createElement('button')
|
||||||
|
saveButton.className = 'mapboxgl-ctrl-icon'
|
||||||
|
saveButton.type = 'button'
|
||||||
|
saveButton.innerHTML = '💾'
|
||||||
|
saveButton.title = '保存限飞区'
|
||||||
|
saveButton.onclick = () => this._savePolygons()
|
||||||
|
this._container.appendChild(saveButton)
|
||||||
|
|
||||||
|
// 删除按钮
|
||||||
|
const deleteButton = document.createElement('button')
|
||||||
|
deleteButton.className = 'mapboxgl-ctrl-icon'
|
||||||
|
deleteButton.type = 'button'
|
||||||
|
deleteButton.innerHTML = '🗑️'
|
||||||
|
deleteButton.title = '删除选中图形'
|
||||||
|
deleteButton.onclick = () => this._deleteSelected()
|
||||||
|
this._container.appendChild(deleteButton)
|
||||||
|
|
||||||
|
// 初始化 MapboxDraw 控件(橙色样式)
|
||||||
|
this._draw = new MapboxDraw({
|
||||||
|
displayControlsDefault: false,
|
||||||
|
styles: [
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-fill',
|
||||||
|
type: 'fill',
|
||||||
|
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
|
||||||
|
paint: {
|
||||||
|
'fill-color': '#f83',
|
||||||
|
'fill-opacity': 0.3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-stroke-active',
|
||||||
|
type: 'line',
|
||||||
|
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
|
||||||
|
paint: {
|
||||||
|
'line-color': '#f83',
|
||||||
|
'line-width': 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-and-line-vertex-halo-active',
|
||||||
|
type: 'circle',
|
||||||
|
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': 7,
|
||||||
|
'circle-color': '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gl-draw-polygon-and-line-vertex-active',
|
||||||
|
type: 'circle',
|
||||||
|
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
||||||
|
paint: {
|
||||||
|
'circle-radius': 5,
|
||||||
|
'circle-color': '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
map.addControl(this._draw)
|
||||||
|
|
||||||
|
// 回显已有限飞区
|
||||||
|
if (this._defaultPolygons.length > 0) {
|
||||||
|
const features = this._defaultPolygons.map((coords, index) => ({
|
||||||
type: 'Feature',
|
type: 'Feature',
|
||||||
geometry: {
|
geometry: {
|
||||||
type: 'Polygon',
|
type: 'Polygon',
|
||||||
coordinates: [coords]
|
coordinates: [coords]
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
type: 'nofly'
|
height: this._defaultHeights[index] || 0
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
this._draw.add({ type: 'FeatureCollection', features })
|
this._draw.set({
|
||||||
}
|
type: 'FeatureCollection',
|
||||||
|
features
|
||||||
// 加载已有限飞区
|
})
|
||||||
if (this._restrictflyPolygons.length > 0) {
|
this._restrictflyHeights = [...this._defaultHeights]
|
||||||
const features = this._restrictflyPolygons.map(coords => ({
|
|
||||||
type: 'Feature',
|
|
||||||
geometry: {
|
|
||||||
type: 'Polygon',
|
|
||||||
coordinates: [coords]
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
type: 'limit'
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
this._draw.add({ type: 'FeatureCollection', features })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听绘制完成
|
||||||
map.on('draw.create', this._handleDraw.bind(this))
|
map.on('draw.create', this._handleDraw.bind(this))
|
||||||
|
|
||||||
return this._container
|
return this._container
|
||||||
@ -343,31 +528,21 @@ export class NoFlyControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleDraw (e) {
|
async _handleDraw (e) {
|
||||||
const features = e.features
|
const features = this._draw.getAll()
|
||||||
if (features.length === 0) return
|
if (features.features.length > 0) {
|
||||||
|
const newFeature = features.features[features.features.length - 1]
|
||||||
|
|
||||||
const type = this._activeMode === 'limit' ? 'limit' : 'nofly'
|
try {
|
||||||
|
const height = await this._promptHeightInput()
|
||||||
features.forEach(f => {
|
this._restrictflyHeights.push(parseFloat(height))
|
||||||
f.properties.type = type
|
// 可选:在 feature 上记录高度
|
||||||
})
|
newFeature.properties.height = height
|
||||||
|
} catch (error) {
|
||||||
// 重新添加以确保类型被写入并触发样式
|
// 用户取消输入,移除刚才的图形
|
||||||
this._draw.delete(features.map(f => f.id))
|
this._draw.delete(newFeature.id)
|
||||||
this._draw.add({
|
Message.info('已取消限飞区域绘制')
|
||||||
type: 'FeatureCollection',
|
}
|
||||||
features
|
|
||||||
})
|
|
||||||
|
|
||||||
const allCoords = this._draw.getAll().features
|
|
||||||
.filter(f => f.properties.type === type)
|
|
||||||
.map(f => f.geometry.coordinates)
|
|
||||||
|
|
||||||
if (type === 'nofly') {
|
|
||||||
this._onDrawFinish(allCoords)
|
|
||||||
} else {
|
|
||||||
this._onLimitFinish(allCoords)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,94 +550,39 @@ export class NoFlyControl {
|
|||||||
if (this._draw) {
|
if (this._draw) {
|
||||||
const selected = this._draw.getSelectedIds()
|
const selected = this._draw.getSelectedIds()
|
||||||
if (selected.length > 0) {
|
if (selected.length > 0) {
|
||||||
|
// 同时删除对应的限高值(只支持最后一个被删)
|
||||||
|
this._restrictflyHeights.pop()
|
||||||
this._draw.delete(selected)
|
this._draw.delete(selected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _savePolygons () {
|
async _savePolygons () {
|
||||||
|
if (!this._draw) return
|
||||||
|
|
||||||
const allFeatures = this._draw.getAll()
|
const allFeatures = this._draw.getAll()
|
||||||
|
|
||||||
const nofly = allFeatures.features
|
const polygons = allFeatures.features
|
||||||
.filter(f => f.properties.type === 'nofly')
|
.filter(f => f.geometry.type === 'Polygon')
|
||||||
.map(f => f.geometry.coordinates[0])
|
|
||||||
|
|
||||||
const limit = allFeatures.features
|
|
||||||
.filter(f => f.properties.type === 'limit')
|
|
||||||
.map(f => f.geometry.coordinates[0])
|
.map(f => f.geometry.coordinates[0])
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const shopId = this._shopId
|
await setRestrictflyData(this._shopId, polygons, this._restrictflyHeights)
|
||||||
await setNoflyData(shopId, nofly, limit)
|
this._onSave({ polygons, heights: this._restrictflyHeights })
|
||||||
this._onSave(nofly, limit)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Message.error('上传数据失败')
|
Message.error('保存限飞区失败')
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDrawStyles () {
|
// Element UI 弹窗输入限高
|
||||||
const noflyColor = '#ff3333'
|
_promptHeightInput () {
|
||||||
const limitColor = '#ff8833'
|
return MessageBox.prompt('请输入该区域的限飞高度(单位:米)', '限高设置', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
return [
|
cancelButtonText: '取消',
|
||||||
// 区域填充样式
|
inputPattern: /^\d+(\.\d+)?$/,
|
||||||
{
|
inputErrorMessage: '请输入有效的数字'
|
||||||
id: 'custom-polygon-fill',
|
}).then(({ value }) => value)
|
||||||
type: 'fill',
|
|
||||||
filter: ['all', ['==', '$type', 'Polygon']],
|
|
||||||
paint: {
|
|
||||||
'fill-color': [
|
|
||||||
'case',
|
|
||||||
['==', ['get', 'type'], 'nofly'], noflyColor,
|
|
||||||
['==', ['get', 'type'], 'limit'], limitColor,
|
|
||||||
limitColor // 默认颜色
|
|
||||||
],
|
|
||||||
'fill-opacity': 0.3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 区域边框线(不区分 static / active)
|
|
||||||
{
|
|
||||||
id: 'custom-polygon-stroke',
|
|
||||||
type: 'line',
|
|
||||||
filter: ['all', ['==', '$type', 'Polygon']],
|
|
||||||
paint: {
|
|
||||||
'line-color': [
|
|
||||||
'case',
|
|
||||||
['==', ['get', 'type'], 'nofly'], noflyColor,
|
|
||||||
['==', ['get', 'type'], 'limit'], limitColor,
|
|
||||||
limitColor
|
|
||||||
],
|
|
||||||
'line-width': 2,
|
|
||||||
'line-dasharray': [2, 2]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 顶点圆点
|
|
||||||
{
|
|
||||||
id: 'custom-vertex-point',
|
|
||||||
type: 'circle',
|
|
||||||
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
|
||||||
paint: {
|
|
||||||
'circle-radius': 5,
|
|
||||||
'circle-color': [
|
|
||||||
'case',
|
|
||||||
['==', ['get', 'type'], 'nofly'], noflyColor,
|
|
||||||
['==', ['get', 'type'], 'limit'], limitColor,
|
|
||||||
limitColor
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 顶点外光环
|
|
||||||
{
|
|
||||||
id: 'custom-vertex-halo',
|
|
||||||
type: 'circle',
|
|
||||||
filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point']],
|
|
||||||
paint: {
|
|
||||||
'circle-radius': 7,
|
|
||||||
'circle-color': '#FFFFFF'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-100">
|
<div class="h-100">
|
||||||
<map-box v-if="showMapbox" :key="mapboxKey" ref="mapbox" :enableNofly="true" />
|
<map-box v-if="showMapbox" :key="mapboxKey" ref="mapbox" :enableRestrictfly="true" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -8,7 +8,7 @@
|
|||||||
import MapBox from '@/components/MapBox'
|
import MapBox from '@/components/MapBox'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Nofly',
|
name: 'Restrictfly',
|
||||||
components: {
|
components: {
|
||||||
MapBox
|
MapBox
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user