浏览代码

新增位置信息组件

tags/v1.0.0^2
余菲 2 年前
父节点
当前提交
49f0b779a4
共有 11 个文件被更改,包括 397 次插入8 次删除
  1. +1
    -0
      package.json
  2. 二进制
      src/assets/point/all.png
  3. 二进制
      src/assets/point/checked.png
  4. 二进制
      src/assets/point/close.png
  5. +90
    -0
      src/components/PositionMsg/OverLay.vue
  6. +82
    -0
      src/components/PositionMsg/index.vue
  7. +215
    -0
      src/components/PositionMsg/util.js
  8. +1
    -1
      src/router/routes/modules/index.js
  9. +5
    -5
      src/store/modules/permission.js
  10. +0
    -1
      src/views/system/dept/components/DeptModal.vue
  11. +3
    -1
      src/views/task-manage/all-task/components/VerifyDrawer.vue

+ 1
- 0
package.json 查看文件

@@ -16,6 +16,7 @@
"axios": "^0.26.1",
"dayjs": "^1.11.2",
"mockjs": "^1.1.0",
"ol": "^6.15.1",
"pinia": "^2.0.13",
"pinia-plugin-persist": "^1.0.0",
"tinymce": "^5.10.2",

二进制
src/assets/point/all.png 查看文件

之前 之后
宽度: 48  |  高度: 48  |  大小: 1.2KB

二进制
src/assets/point/checked.png 查看文件

之前 之后
宽度: 48  |  高度: 48  |  大小: 1.1KB

二进制
src/assets/point/close.png 查看文件

之前 之后
宽度: 122  |  高度: 122  |  大小: 1.2KB

+ 90
- 0
src/components/PositionMsg/OverLay.vue 查看文件

@@ -0,0 +1,90 @@
<template>
<div class="overlay_container">
<div class="overlay_head">
<img class="close_img" src="@/assets/point/close.png" alt="" @click="close">
</div>
<div class="overlay_main">
<n-form
ref="formRef"
:model="form"
:label-width="80"
label-placement="left"
require-mark-placement="left"
>
<n-form-item label="问题类型:">
<n-select
v-model:value="form.name"
:options="typeList"
placeholder="请选择问题类型"
/>
</n-form-item>
<n-form-item label="问题描述:">
<span>{{ form.content }}</span>
</n-form-item>
<n-form-item label="经纬度:">
<span>{{ form.longitude }},{{ form.latitude }}</span>
</n-form-item>
<n-form-item label="问题图片:">
<img class="image_size" :src="form.fileImage" alt="" style="width: 108px; height: auto; margin: 0 5px 5px 0">
</n-form-item>
</n-form>
</div>
</div>
</template>
<script>
import { toRefs, reactive } from 'vue'
export default {
name: 'OverLay',
props: {
data: {
type: Object,
default: () => null
}
},
emits: { 'close': null },
setup(props, { emit }) {
const data = reactive({
form: Object.assign({}, props.data),
typeList: [
{ value: 0, label: '林班' }
]
})

function close() {
emit('close')
}
return {
...toRefs(data),
close
}
}

}
</script>
<style lang="scss" scoped>
.overlay_container {
width: 100%;
height: 436px;
padding: 0;
overflow-y: scroll;
background-color: #fff;
}

.overlay_head {
width: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
}
.close_img {
width: 40px;
height: 40px;
cursor: pointer;
}
.overlay_main {
width: 100%;
margin-top: 10px;
padding: 0 30px 0 40px;
}

</style>

+ 82
- 0
src/components/PositionMsg/index.vue 查看文件

@@ -0,0 +1,82 @@
<template>
<div class="main_container">
<div id="track" ref="map" />
<div id="pointOverlay" class="point_overlay">
<over-lay :data="problemData" @close="closeOverlay" />
</div>
</div>
</template>
<script>
import { reactive, toRefs, onMounted } from 'vue'
import OverLay from './OverLay.vue'
import { initMap, setOverlay } from './util.js'

export default {
name: 'PositionMsg',
components: { OverLay },
props: {},
emits: {},
setup(props, { emit }) {
const data = reactive({
mapdata: null, // 地图
view: null, // 视图
source: null,
layer: null, // 底图
problemLayer: null, // 问题矢量图
select: null,
TDimageMap: null, // 影像底图
problemList: [
{ content: '河道内存在水生植被',
fileImage: 'https://image.t-aaron.com/XJRW20220725103839/2022-07-25-10-41-46_frame-1500-1680_type-水生植被_VMgRwh05s4clHXCu_s-live-XJRW20220725103839-b73c470768f74422b287981fc75c31c3_AI.jpg',
handlerImage: 'https://image.t-aaron.com/imagedir/kw6vv4m1yw_1658717157035.png',
handlerResult: '',
handlerTime: '2022-07-25 10:45:56',
latitude: '31.829037194418085',
location: '江苏省南京市江宁区秣陵街道东吉大道',
longitude: '118.770222690945',
name: 1,
status: 1,
type: 1,
userName: '运管单位' }
], // 问题矢量点列表
overlay: null, // overlay弹出框
problemData: {} // 问题点数据
})
onMounted(() => {
initMap('track', data.problemList, 'pointOverlay').then(({ mapdata, select, view, overlay, dataObj, problemLayer }) => {
data.mapdata = mapdata
data.select = select
data.view = view
data.overlay = overlay
data.problemData = dataObj
data.problemLayer = problemLayer
})
})

const closeOverlay = () => {
data.select.getFeatures().clear()
data.mapdata.removeOverlay(data.overlay)
}

return {
...toRefs(data),
closeOverlay
}
}
}
</script>
<style scoped>
.main_container {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
#track {
width: 100%;
height: 100%;
}
.point_overlay {
width: 400px;
}
</style>

+ 215
- 0
src/components/PositionMsg/util.js 查看文件

@@ -0,0 +1,215 @@
import { Map, View, Feature, Overlay } from 'ol'
import 'ol/ol.css'
import Projection from 'ol/proj/Projection'
import { Tile, Vector as VectorLayer } from 'ol/layer'
import LineString from 'ol/geom/LineString'
import { ImageStatic, TileWMS, XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import * as control from 'ol/control'
import { Select } from 'ol/interaction'
import { Stroke, Style, Icon } from 'ol/style'
import Point from 'ol/geom/Point'
import imgAll from '../../assets/point/all.png'
import imgChecked from '../../assets/point/checked.png'

/**
* 初始化地图
* @param {*} ids dom的id
* @param {*} mapdata 地图对象
* @param {*} blanklayerList 显示图层列表
* @param {*} datalayerList 待添加图层列表
* @param {*} zoom 层级
* @param {*} interactions 控制
*/
export function initMap(ids, data, overlayId) {
const layers = [
new Tile({
visible: true,
source: new XYZ({
url: 'https://tianditu.t-aaron.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f82bb2fd8115c7fb576a8b2fcf738523'
})
})
]

const view = new View({
maxZoom: 18,
zoom: 4,
center: transform([108.94043, 31.008173], 'EPSG:4326', 'EPSG:3857')
})
const mapdata = new Map({
layers: layers,
target: ids,
view: view,
controls: control.defaults({
attribution: false,
rotate: false,
zoom: false
})
})
mapdata.render()
const problemLayer = null
getLayers(data, problemLayer, view, mapdata)

const select = new Select({
style: (feature) => {
const properties = feature.getProperties()
if (feature.getGeometry() instanceof Point) {
return styleList[properties.item.status]
}
}
})
mapdata.addInteraction(select)
// 新建overlay弹出框
const overlay = new Overlay({
element: document.getElementById(overlayId),
autoPan: true
})
let dataObj
select.on('select', (e) => {
if (e.selected.length > 0) {
const properties = e.selected[0].getProperties()
const geom = properties.geometry
if (geom instanceof Point) {
dataObj = properties.item
const coordinate = e.mapBrowserEvent.coordinate
overlay.setPosition(coordinate)
overlay.setOffset([30, -400])
mapdata.addOverlay(overlay)
} else {
mapdata.removeOverlay(overlay)
}
} else {
mapdata.removeOverlay(overlay)
}
})

return Promise.resolve({
mapdata,
view,
select,
overlay,
dataObj
})
}

/**
* 选择矢量图层并添加overlay
* @param {*} overlay
* @param {*} select 选择
* @param {*} mapdata 地图
* @param {*} problemData 问题数据
*/
export function setOverlay(overlay, select, mapdata, problemData) {
console.log(select)
select.on('select', (e) => {
if (e.selected.length > 0) {
const properties = e.selected[0].getProperties()
const geom = properties.geometry
if (geom instanceof Point) {
problemData = properties.item
const coordinate = e.mapBrowserEvent.coordinate
overlay.setPosition(coordinate)
overlay.setOffset([30, -400])
mapdata.addOverlay(overlay)
} else {
mapdata.removeOverlay(overlay)
}
} else {
mapdata.removeOverlay(overlay)
}
})
return Promise.resolve({
overlay,
select,
mapdata,
problemData
})
}

// 矢量图标样式
const styleList = [
new Style({
image: new Icon({
anchor: [0.5, 0.5],
src: imgAll,
crossOrigin: '',
scale: [1, 1],
rotateWithView: true
})
}),
new Style({
image: new Icon({
anchor: [0.5, 0.5],
src: imgChecked,
crossOrigin: '',
scale: [1, 1],
rotateWithView: true
})
})
]

/**
* 生成矢量图层
* @param {*} datalayerList 图层数据列表
* [{paramlayer: '图层名',type: 'wms' 类型}]
* @returns
*/
function getLayers(data, layer, view, map) {
const pointFeatures = []
const points = []
if (data.length) {
data.forEach((item) => {
const pointItem = []
pointItem.push(parseFloat(item.longitude))
pointItem.push(parseFloat(item.latitude))
const featureItem = new Feature(new Point(fromLonLat(pointItem)))
points.push(fromLonLat(pointItem))
featureItem.setProperties({ item: item, type: 'problem' }, false)
featureItem.setStyle(styleList[item.status])
pointFeatures.push(featureItem)
})
const pointSource = new VectorSource({
wrapX: false,
features: pointFeatures
})
layer = new VectorLayer({
source: pointSource,
zIndex: 12
})
let geom
if (points.length > 1) {
geom = new LineString(points)
} else if (points.length > 0) {
geom = new Point(points[0])
}
if (geom) {
view.fit(geom, { padding: [100, 100, 100, 100] })
}
map.addLayer(layer)
}
}

/**
* 引入静态图标创建图标对象
**/
const imgstyle = new Style({
image: new Icon({
anchor: [0.5, 1],
src: import.meta.env.BASE_URL + `img/icon-biaozhu.png`,
scale: 0.5
})
})

/**
* 使用feature
* coordinate 坐标
**/
export function setTrmFeature(coordinate) {
const feature = new Feature({
type: 'icon',
geometry: new Point(coordinate)
})
feature.setStyle(imgstyle)
return feature
}


+ 1
- 1
src/router/routes/modules/index.js 查看文件

@@ -11,7 +11,7 @@ export default [
},
children: [
{
path: 'allTask',
path: 'all',
component: () => import('@/views/task-manage/all-task/index.vue'),
name: 'TaskAll',
title: '所有任务',

+ 5
- 5
src/store/modules/permission.js 查看文件

@@ -114,11 +114,11 @@ export const usePermissionStore = defineStore('permission', {
try {
const res = await getMenu()
if (res.code === 0) {
// const result = dataArrayToRoutes(res.data)
// this.accessRoutes = result
// return Promise.resolve(result)
this.accessRoutes = router
return Promise.resolve(router)
const result = dataArrayToRoutes(res.data)
this.accessRoutes = result
return Promise.resolve(result)
// this.accessRoutes = router
// return Promise.resolve(router)
} else {
return Promise.reject(res.message)
}

+ 0
- 1
src/views/system/dept/components/DeptModal.vue 查看文件

@@ -126,7 +126,6 @@ export default defineComponent({
if (props.row.pid === 0) {
row.pid = null
}
console.log('====部门计算属性触发了====', row)
return {
title: props.row.name ? '修改部门' : '添加部门',
show: props.visible,

+ 3
- 1
src/views/task-manage/all-task/components/VerifyDrawer.vue 查看文件

@@ -1,16 +1,18 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="问题核实">
问题核实
<position-msg />
</n-drawer-content>
</n-drawer>
</template>

<script>
import { h, defineComponent, computed, reactive, toRefs } from 'vue'
import PositionMsg from '@/components/PositionMsg/index.vue'

export default defineComponent({
name: 'LiveDrawer',
components: { PositionMsg },
props: {
/* 可见 */
visible: {

正在加载...
取消
保存