支持仅显示 高精度数据
当两点间隔大于5分钟时 视为两条不同的路径 以不同样式显示
This commit is contained in:
parent
afca0a9e00
commit
aff0b6ca98
@ -8,6 +8,14 @@
|
|||||||
<q-btn @click="search">查询</q-btn>
|
<q-btn @click="search">查询</q-btn>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end flex-wrap items-center p-1">
|
<div class="flex justify-end flex-wrap items-center p-1">
|
||||||
|
<q-toggle
|
||||||
|
label="仅使用高精度定位"
|
||||||
|
v-model="options.useHighAccuracyLocation"
|
||||||
|
color="primary"
|
||||||
|
@update:model-value="toggleUseHighAccuracyLocation"
|
||||||
|
keep-color
|
||||||
|
/>
|
||||||
|
|
||||||
<q-toggle
|
<q-toggle
|
||||||
label="卫星地图"
|
label="卫星地图"
|
||||||
v-model="layers.satellite.show"
|
v-model="layers.satellite.show"
|
||||||
@ -50,25 +58,14 @@ import {useQuasar} from "quasar";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {auth} from "matrix-middle-service-web/src/api/auth/index";
|
import {auth} from "matrix-middle-service-web/src/api/auth/index";
|
||||||
import {locationRecord} from "matrix-middle-service-web/src/api/location/record/index";
|
import {locationRecord} from "matrix-middle-service-web/src/api/location/record/index";
|
||||||
|
import {createCanvasDir} from "matrix-middle-service-web/src/views/record/logic/icon";
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
const COLOR = [
|
const COLOR = [
|
||||||
'#6090e0', '#30c030', '#d070d0', '#80c0f0', '#f07050', '#ffb900',
|
'#6090e0', '#30c030', '#d070d0', '#80c0f0', '#f07050', '#ffb900',
|
||||||
'#37a2da', '#ffdb5c', '#8378ea', '#e7bcf3', '#32c5e9', '#67e0e3',
|
'#37a2da', '#ffdb5c', '#8378ea', '#e7bcf3', '#32c5e9', '#67e0e3',
|
||||||
'#dd6b66', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53', '#eedd78',
|
'#dd6b66', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53', '#eedd78',
|
||||||
]
|
]
|
||||||
let canvasDir = document.createElement('canvas')
|
let canvasDir = createCanvasDir();
|
||||||
let width = 24;
|
|
||||||
let height = 24;
|
|
||||||
canvasDir.width = width;
|
|
||||||
canvasDir.height = height;
|
|
||||||
let context = canvasDir.getContext('2d');
|
|
||||||
context.strokeStyle = 'white';
|
|
||||||
context.lineJoin = 'round';
|
|
||||||
context.lineWidth = 8;
|
|
||||||
context.moveTo(-4, width - 4);
|
|
||||||
context.lineTo(width / 2, 6);
|
|
||||||
context.lineTo(width + 4, width - 4);
|
|
||||||
context.stroke();
|
|
||||||
const date = ref({
|
const date = ref({
|
||||||
from: moment().startOf('d').format("YYYY-MM-DD HH:mm:ss"),
|
from: moment().startOf('d').format("YYYY-MM-DD HH:mm:ss"),
|
||||||
to: moment().format("YYYY-MM-DD HH:mm:ss"),
|
to: moment().format("YYYY-MM-DD HH:mm:ss"),
|
||||||
@ -101,6 +98,9 @@ const layers = reactive({
|
|||||||
show: false,
|
show: false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const options = reactive({
|
||||||
|
useHighAccuracyLocation: true
|
||||||
|
})
|
||||||
|
|
||||||
const authModel = reactive({
|
const authModel = reactive({
|
||||||
account: "",
|
account: "",
|
||||||
@ -131,6 +131,11 @@ function login(){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleUseHighAccuracyLocation(){
|
||||||
|
clearMap()
|
||||||
|
drawMap()
|
||||||
|
}
|
||||||
|
|
||||||
function toggleSatellite(){
|
function toggleSatellite(){
|
||||||
if (layers.satellite.show) {
|
if (layers.satellite.show) {
|
||||||
layers.satellite.inst.show()
|
layers.satellite.inst.show()
|
||||||
@ -229,16 +234,98 @@ AMapLoader.load({
|
|||||||
console.log(e);
|
console.log(e);
|
||||||
})
|
})
|
||||||
|
|
||||||
function search() {
|
function clearMap(){
|
||||||
console.log(date.value)
|
|
||||||
let params = {
|
|
||||||
startTime: !date.value.from ? undefined : moment(date.value.from).format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
endTime: !date.value.to ? undefined : moment(date.value.to).format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
}
|
|
||||||
map.remove(data.polylines)
|
map.remove(data.polylines)
|
||||||
map.remove(data.polyline)
|
map.remove(data.polyline)
|
||||||
map.remove(data.labelsLayer)
|
map.remove(data.labelsLayer)
|
||||||
map.remove(data.markers)
|
map.remove(data.markers)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function drawMap(){
|
||||||
|
let _data = data.data
|
||||||
|
|
||||||
|
if(options.useHighAccuracyLocation){
|
||||||
|
console.log("[仅使用高精度定位数据]")
|
||||||
|
_data = _data.filter(item=>item.locationType === 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
_data = _data.map(item=>{
|
||||||
|
return {
|
||||||
|
time: moment(item.locationTime),
|
||||||
|
...item,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_data.sort((a,b)=>{
|
||||||
|
return a.time.isBefore(b.time)?-1:1
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log("data", _data)
|
||||||
|
|
||||||
|
data.tmpMarker = new AMap.Marker({
|
||||||
|
anchor: 'bottom-center',
|
||||||
|
offset: [0, -15],
|
||||||
|
});
|
||||||
|
let markers = _data.filter((_, index) => index % 1 === 0).map((item, index) => {
|
||||||
|
let text = {
|
||||||
|
fontSize: 10,
|
||||||
|
content: `时间:${item.locationTime}<br>速度: ${((item.speed || 0) * 3.6).toFixed(2)}km/h 方向角: ${(item.bearing || 0).toFixed(2)}°`
|
||||||
|
}
|
||||||
|
|
||||||
|
let marker = new AMap.LabelMarker({
|
||||||
|
name: item.id,
|
||||||
|
position: [item.longitude, item.latitude],
|
||||||
|
zIndex: 10,
|
||||||
|
icon: {
|
||||||
|
// 图标类型,现阶段只支持 image 类型
|
||||||
|
type: 'image',
|
||||||
|
// 图片 url
|
||||||
|
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
|
||||||
|
// 图片尺寸
|
||||||
|
size: [6, 9],
|
||||||
|
// 图片相对 position 的锚点,默认为 bottom-center
|
||||||
|
anchor: 'bottom-center'
|
||||||
|
},
|
||||||
|
// text,
|
||||||
|
})
|
||||||
|
|
||||||
|
function show(e) {
|
||||||
|
let position = e.data.data && e.data.data.position;
|
||||||
|
|
||||||
|
if (position) {
|
||||||
|
data.tmpMarker.setContent(
|
||||||
|
`<div class="amap-info-window"
|
||||||
|
style="padding: .75rem 1.25rem;font-size:12px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border-radius: .25rem;
|
||||||
|
position: fixed;
|
||||||
|
top: 1rem;
|
||||||
|
background-color: white;
|
||||||
|
width: auto;
|
||||||
|
min-width: 22rem;
|
||||||
|
border-width: 0;
|
||||||
|
right: 1rem;
|
||||||
|
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);">`
|
||||||
|
+ text.content +
|
||||||
|
'<div class="amap-info-sharp"></div>' +
|
||||||
|
'</div>');
|
||||||
|
data.tmpMarker.setPosition(position);
|
||||||
|
map.add(data.tmpMarker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide() {
|
||||||
|
map.remove(data.tmpMarker);
|
||||||
|
}
|
||||||
|
|
||||||
|
marker.on('mouseover', (e)=>show(e));
|
||||||
|
marker.on('touchstart', (e)=>show(e));
|
||||||
|
marker.on('mouseout', ()=>hide());
|
||||||
|
marker.on('touchend', ()=>hide());
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
})
|
||||||
|
data.markers = markers
|
||||||
|
|
||||||
let labelsLayer = new AMap.LabelsLayer({
|
let labelsLayer = new AMap.LabelsLayer({
|
||||||
zooms: [3, 20],
|
zooms: [3, 20],
|
||||||
@ -249,7 +336,76 @@ function search() {
|
|||||||
allowCollision: false,
|
allowCollision: false,
|
||||||
});
|
});
|
||||||
data.labelsLayer = labelsLayer
|
data.labelsLayer = labelsLayer
|
||||||
|
labelsLayer.add(markers)
|
||||||
|
map.add(data.labelsLayer)
|
||||||
|
|
||||||
|
let lines = []
|
||||||
|
let prev = moment(0)
|
||||||
|
for (let i = 0; i < _data.length; i++) {
|
||||||
|
let datum = _data[i]
|
||||||
|
|
||||||
|
console.log(prev,datum.time, datum.time.diff(prev,'m') <= 5)
|
||||||
|
|
||||||
|
if (prev.year() === datum.time.year() && prev.month() === datum.time.month() && prev.date() === datum.time.date() && datum.time.diff(prev,'m') <= 5 ) {
|
||||||
|
prev = datum.time
|
||||||
|
} else {
|
||||||
|
prev = datum.time
|
||||||
|
lines.push([])
|
||||||
|
}
|
||||||
|
lines[lines.length -1].push(datum)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("lines", lines)
|
||||||
|
|
||||||
|
let colorList = Array.from({ length: lines.length })
|
||||||
|
.map(() => COLOR[Math.floor(Math.random() * COLOR.length)]);
|
||||||
|
data.polylines = []
|
||||||
|
lines.forEach((_data,index) => {
|
||||||
|
let path = _data.map((item) => {
|
||||||
|
return new AMap.LngLat(item.longitude, item.latitude)
|
||||||
|
})
|
||||||
|
|
||||||
|
let polyline = new AMap.Polyline({
|
||||||
|
path: path,
|
||||||
|
showDir: true,
|
||||||
|
dirImg: canvasDir,
|
||||||
|
borderWeight: 6, // 线条宽度,默认为 1
|
||||||
|
strokeWeight: 6,
|
||||||
|
strokeOpacity: 0.9, // 透明度
|
||||||
|
strokeColor: colorList[index], // 线条颜色
|
||||||
|
dirColor: 'white',
|
||||||
|
lineJoin: 'round' // 折线拐点连接处样式})
|
||||||
|
})
|
||||||
|
data.polylines.push(polyline)
|
||||||
|
})
|
||||||
|
console.log("polylines",data.polylines)
|
||||||
|
// polyline = new AMap.Polyline({
|
||||||
|
// path: path,
|
||||||
|
// showDir: true,
|
||||||
|
// dirImg: canvasDir,
|
||||||
|
// borderWeight: 6, // 线条宽度,默认为 1
|
||||||
|
// strokeWeight: 6,
|
||||||
|
// strokeColor: 'red', // 线条颜色
|
||||||
|
// dirColor: 'white',
|
||||||
|
// lineJoin: 'round' // 折线拐点连接处样式})
|
||||||
|
// })
|
||||||
|
map.add(data.polylines)
|
||||||
|
setTimeout(()=>{
|
||||||
|
if (data.polylines.length > 0) {
|
||||||
|
map.setFitView()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
fixedLocation()
|
||||||
|
}
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
console.log(date.value)
|
||||||
|
let params = {
|
||||||
|
startTime: !date.value.from ? undefined : moment(date.value.from).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
endTime: !date.value.to ? undefined : moment(date.value.to).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMap();
|
||||||
locationRecord.list(params).then(resp => {
|
locationRecord.list(params).then(resp => {
|
||||||
if(resp.status !== 200){
|
if(resp.status !== 200){
|
||||||
console.log(resp)
|
console.log(resp)
|
||||||
@ -264,139 +420,8 @@ function search() {
|
|||||||
}
|
}
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
let _data = res.data || []
|
data.data = res.data || []
|
||||||
_data = _data.map(item=>{
|
drawMap()
|
||||||
return {
|
|
||||||
time: moment(item.locationTime),
|
|
||||||
...item,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
_data.sort((a,b)=>{
|
|
||||||
return a.time.isBefore(b.time)?-1:1
|
|
||||||
})
|
|
||||||
data.data = _data
|
|
||||||
console.log("data", _data)
|
|
||||||
|
|
||||||
data.tmpMarker = new AMap.Marker({
|
|
||||||
anchor: 'bottom-center',
|
|
||||||
offset: [0, -15],
|
|
||||||
});
|
|
||||||
let markers = _data.filter((_, index) => index % 1 === 0).map((item, index) => {
|
|
||||||
let text = {
|
|
||||||
fontSize: 10,
|
|
||||||
content: `时间:${item.locationTime}<br>速度: ${((item.speed || 0) * 3.6).toFixed(2)}km/h 方向角: ${(item.bearing || 0).toFixed(2)}°`
|
|
||||||
}
|
|
||||||
|
|
||||||
let marker = new AMap.LabelMarker({
|
|
||||||
name: item.id,
|
|
||||||
position: [item.longitude, item.latitude],
|
|
||||||
zIndex: 10,
|
|
||||||
icon: {
|
|
||||||
// 图标类型,现阶段只支持 image 类型
|
|
||||||
type: 'image',
|
|
||||||
// 图片 url
|
|
||||||
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
|
|
||||||
// 图片尺寸
|
|
||||||
size: [6, 9],
|
|
||||||
// 图片相对 position 的锚点,默认为 bottom-center
|
|
||||||
anchor: 'bottom-center'
|
|
||||||
},
|
|
||||||
// text,
|
|
||||||
})
|
|
||||||
|
|
||||||
function show(e) {
|
|
||||||
let position = e.data.data && e.data.data.position;
|
|
||||||
|
|
||||||
if (position) {
|
|
||||||
data.tmpMarker.setContent(
|
|
||||||
`<div class="amap-info-window"
|
|
||||||
style="padding: .75rem 1.25rem;font-size:12px;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
border-radius: .25rem;
|
|
||||||
position: fixed;
|
|
||||||
top: 1rem;
|
|
||||||
background-color: white;
|
|
||||||
width: auto;
|
|
||||||
min-width: 22rem;
|
|
||||||
border-width: 0;
|
|
||||||
right: 1rem;
|
|
||||||
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);">`
|
|
||||||
+ text.content +
|
|
||||||
'<div class="amap-info-sharp"></div>' +
|
|
||||||
'</div>');
|
|
||||||
data.tmpMarker.setPosition(position);
|
|
||||||
map.add(data.tmpMarker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
map.remove(data.tmpMarker);
|
|
||||||
}
|
|
||||||
|
|
||||||
marker.on('mouseover', (e)=>show(e));
|
|
||||||
marker.on('touchstart', (e)=>show(e));
|
|
||||||
marker.on('mouseout', ()=>hide());
|
|
||||||
marker.on('touchend', ()=>hide());
|
|
||||||
|
|
||||||
return marker;
|
|
||||||
})
|
|
||||||
data.markers = markers
|
|
||||||
labelsLayer.add(markers)
|
|
||||||
map.add(data.labelsLayer)
|
|
||||||
|
|
||||||
let days = []
|
|
||||||
let prev = moment(0)
|
|
||||||
for (let i = 0; i < _data.length; i++) {
|
|
||||||
let datum = _data[i]
|
|
||||||
|
|
||||||
if (prev.year() === datum.time.year() && prev.month() === datum.time.month() && prev.date() === datum.time.date() ) {
|
|
||||||
prev = datum.time
|
|
||||||
} else {
|
|
||||||
prev = datum.time
|
|
||||||
days.push([])
|
|
||||||
}
|
|
||||||
days[days.length -1].push(datum)
|
|
||||||
}
|
|
||||||
|
|
||||||
let colorList = Array.from({ length: days.length })
|
|
||||||
.map(() => COLOR[Math.floor(Math.random() * COLOR.length)]);
|
|
||||||
data.polylines = []
|
|
||||||
days.forEach((_data,index) => {
|
|
||||||
let path = _data.map((item) => {
|
|
||||||
return new AMap.LngLat(item.longitude, item.latitude)
|
|
||||||
})
|
|
||||||
|
|
||||||
let polyline = new AMap.Polyline({
|
|
||||||
path: path,
|
|
||||||
showDir: true,
|
|
||||||
dirImg: canvasDir,
|
|
||||||
borderWeight: 6, // 线条宽度,默认为 1
|
|
||||||
strokeWeight: 6,
|
|
||||||
strokeOpacity: 0.9, // 透明度
|
|
||||||
strokeColor: colorList[index], // 线条颜色
|
|
||||||
dirColor: 'white',
|
|
||||||
lineJoin: 'round' // 折线拐点连接处样式})
|
|
||||||
})
|
|
||||||
data.polylines.push(polyline)
|
|
||||||
})
|
|
||||||
console.log("polylines",data.polylines)
|
|
||||||
// polyline = new AMap.Polyline({
|
|
||||||
// path: path,
|
|
||||||
// showDir: true,
|
|
||||||
// dirImg: canvasDir,
|
|
||||||
// borderWeight: 6, // 线条宽度,默认为 1
|
|
||||||
// strokeWeight: 6,
|
|
||||||
// strokeColor: 'red', // 线条颜色
|
|
||||||
// dirColor: 'white',
|
|
||||||
// lineJoin: 'round' // 折线拐点连接处样式})
|
|
||||||
// })
|
|
||||||
map.add(data.polylines)
|
|
||||||
setTimeout(()=>{
|
|
||||||
if (data.polylines.length > 0) {
|
|
||||||
map.setFitView()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
fixedLocation()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
export function createCanvasDir(){
|
||||||
|
let canvasDir = document.createElement('canvas')
|
||||||
|
let width = 24;
|
||||||
|
let height = 24;
|
||||||
|
canvasDir.width = width;
|
||||||
|
canvasDir.height = height;
|
||||||
|
|
||||||
|
let context = canvasDir.getContext('2d')!;
|
||||||
|
context.strokeStyle = 'white';
|
||||||
|
context.lineJoin = 'round';
|
||||||
|
context.lineWidth = 8;
|
||||||
|
context.moveTo(-4, width - 4);
|
||||||
|
context.lineTo(width / 2, 6);
|
||||||
|
context.lineTo(width + 4, width - 4);
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
return canvasDir;
|
||||||
|
}
|
@ -11,7 +11,8 @@ export default defineConfig({
|
|||||||
port: 7868,
|
port: 7868,
|
||||||
proxy:{
|
proxy:{
|
||||||
"^/api/.*":{
|
"^/api/.*":{
|
||||||
target: "http://10.10.10.20:45680/",
|
// target: "http://10.10.10.20:45680/",
|
||||||
|
target: "http://10.10.10.200:45680/",
|
||||||
rewrite: (path) => path.replace(/^\/api\//, ''),
|
rewrite: (path) => path.replace(/^\/api\//, ''),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user