Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
map-demo
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
hookehuyr
2023-12-29 17:46:13 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
1e4fcd192b3e582dffdd1ef0368564d163a742eb
1e4fcd19
1 parent
f07268bb
新需求-新增一个活动展示页面
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1742 additions
and
12 deletions
components.d.ts
package.json
src/main.js
src/route.js
src/views/activity.vue
yarn.lock
components.d.ts
View file @
1e4fcd1
...
...
@@ -23,6 +23,7 @@ declare module '@vue/runtime-core' {
VanField
:
typeof
import
(
'vant/es'
)[
'Field'
]
VanIcon
:
typeof
import
(
'vant/es'
)[
'Icon'
]
VanImage
:
typeof
import
(
'vant/es'
)[
'Image'
]
VanPopover
:
typeof
import
(
'vant/es'
)[
'Popover'
]
VanPopup
:
typeof
import
(
'vant/es'
)[
'Popup'
]
VanRow
:
typeof
import
(
'vant/es'
)[
'Row'
]
VRViewer
:
typeof
import
(
'./src/components/VRViewer/index.vue'
)[
'default'
]
...
...
package.json
View file @
1e4fcd1
...
...
@@ -40,7 +40,7 @@
"unplugin-vue-components"
:
"^0.24.1"
,
"uuid"
:
"^8.3.2"
,
"v-viewer"
:
"^3.0.11"
,
"vant"
:
"^4.
6.3
"
,
"vant"
:
"^4.
8.1
"
,
"vconsole"
:
"^3.14.6"
,
"video.js"
:
"^8.3.0"
,
"vite-plugin-dynamic-import"
:
"^0.9.6"
,
...
...
src/main.js
View file @
1e4fcd1
...
...
@@ -2,7 +2,7 @@
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-31 12:06:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-
07-18 14:02
:08
* @LastEditTime: 2023-
12-29 14:00
:08
* @FilePath: /map-demo/src/main.js
* @Description:
*/
...
...
@@ -40,6 +40,7 @@ import {
Checkbox
,
Search
,
ImagePreview
,
Popover
,
}
from
'vant'
;
import
router
from
'./router'
;
import
App
from
'./App.vue'
;
...
...
src/route.js
View file @
1e4fcd1
/*
* @Date: 2023-05-29 11:10:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-
07-27 11:04:44
* @LastEditTime: 2023-
12-29 16:44:30
* @FilePath: /map-demo/src/route.js
* @Description: 文件描述
*/
...
...
@@ -27,4 +27,11 @@ export default [
title
:
'内部地图'
,
},
},
{
path
:
'/activity'
,
component
:
()
=>
import
(
'@/views/activity.vue'
),
meta
:
{
title
:
'活动地图'
,
},
},
];
...
...
src/views/activity.vue
0 → 100644
View file @
1e4fcd1
<!--
* @Date: 2023-05-19 14:54:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-12-29 17:11:38
* @FilePath: /map-demo/src/views/activity.vue
* @Description: 内部地图主体页面
-->
<template>
<div ref="root" style="height: 100vh; position: relative; overflow: hidden;">
<div id="container"></div>
<div class="nav-bar-wrapper">
<div class="hideScrollBar nav-bar-content">
<div v-for="(item, index) in navBarList" :key="index" :class="[isActive === index ? 'checked' : '', 'item']"
@click="setNavLayer(item, index)">
<van-icon :name="isActive === index ? item.icon[1] : item.icon[0]" size="2rem" /><br />
<span style="font-size: 0.85rem; margin-top: 0rem; display: inline-block;">{{ item.name }}</span>
</div>
<div style="width: 4rem;flex-shrink: 0;"></div>
<div style="position: fixed; right: 0; background-color: white; height: 5.5rem; width: 4rem;">
<div style="padding-top: 40%;">
<van-icon v-if="!show_nav_popup" name="arrow-up" @click="handleNavPopup" size="1.15rem" />
<van-icon v-else name="arrow-down" @click="handleNavPopup" size="1.15rem" />
</div>
</div>
</div>
<van-popup v-model:show="show_nav_popup" position="bottom" duration="0" :overlay="false"
:style="{ padding: '1rem', bottom: '5.5rem' }">
<div style="text-align: left;">
<div v-for="(item, index) in navList" :key="index" @click="handleNavMarker(item)"
style="margin-bottom: 1rem; font-size: 1.15rem;">
<van-icon name="fire-o" color="#965f13" /> <span style="color: #000;">{{ item.name }}</span>
</div>
</div>
</van-popup>
</div>
<div class="operate-bar-wrapper">
<div class="box-wrapper">
<div class="item" @click="testFloor">
<span style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">3D</span>
</div>
<div v-if="open_current_location" class="item" @click="handleLocation(true)">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A%E4%BD%8Dloc@2x.png" size="1.25rem"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);" />
</div>
<div v-else class="item" @click="handleLocation(false)">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A%E4%BD%8Dloc@2x.png" size="1.25rem"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);" />
</div>
<van-popover v-model:show="showPopover" @select="onSelect" :actions="actions" placement="right-end">
<template #reference>
<div class="item">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E7%BA%BF%E8%B7%AF01.png" size="1.25rem"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);" />
</div>
</template>
</van-popover>
<!-- <div v-if="open_safe_route" class="item" @click="handleSafeRoute(true)">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E7%BA%BF%E8%B7%AF01.png" size="1.25rem"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);" />
</div>
<div v-else class="item" @click="handleSafeRoute(false)">
<van-icon name="https://cdn.ipadbiz.cn/xys/map/%E7%BA%BF%E8%B7%AF02.png" size="1.25rem"
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);" />
</div> -->
</div>
</div>
<!-- <div v-if="!show_walk_route" @click="removeWalkRoute" class="walk-nav-text">
关闭步行导航
</div> -->
<div v-if="!show_walk_route" @click="removeNavRoute" class="walk-nav-text">
关闭步行导航
</div>
<div v-if="show_activity_route" @click="removeActivityRoute" class="walk-nav-text">
关闭活动导航
</div>
<!-- <van-popup v-model:show="show_popup" position="bottom" :overlay="true" :style="{ padding: '1rem', height: '100%' }">
<van-icon name="cross" size="1.35rem" @click="show_popup = false" style="float: right; color: gray;" />
<div class="popup-wrapper">
<div class="title">
{{ popup_title }}
</div>
<div class="content" v-html="popup_content"></div>
<video-player ref="videoPlayer" style="width: 100%; height: 30vh; margin-top: 1rem;"
poster="https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100"
:src="video_src" class="video-player vjs-big-play-centered" controls :loop="true" :volume="0.6"></video-player>
</div>
</van-popup> -->
<van-dialog v-model:show="dialog_show" title="温馨提示">
<div style="padding: 1rem; text-align: center;">{{ dialog_text }}</div>
</van-dialog>
<!-- 自定义组件InfoWindow,初始时需要隐藏 -->
<!-- 隐藏不要使用v-if,因为我们需要渲染完成后的原生html结构作为信息框的dom对象使用 -->
<InfoWindow v-show="showInfoWindow" ref="infoWindow" :info-window="infoWindow" :info="itemInfo" :rect="rect"
@onLocation="infoWindowLocation" @onPlay="onPlay" @onPause="onPause"></InfoWindow>
<InfoWindowLite v-show="showInfoWindowLite" ref="infoWindowLite" :info-window="infoWindowLite" :info="itemInfo"
:rect="rect" @onLocation="infoWindowLocation"></InfoWindowLite>
<InfoWindowWarn v-show="showInfoWindowWarn" ref="infoWindowWarn" :info-window="infoWindowWarn" :info="itemInfo"
:rect="rect"></InfoWindowWarn>
<InfoWindowYard v-show="showInfoWindowYard" ref="infoWindowYard" :info-window="infoWindowYard" :info="itemInfo"
:rect="rect" @onLocation="infoWindowLocation"></InfoWindowYard>
<van-popup v-model:show="show_member_popup" position="bottom" :overlay="true" :style="{ padding: '1rem 0', height: '80%', background: '#F7F8FA' }">
<van-icon name="cross" size="1.35rem" @click="closeMember" style="float: right; color: gray; margin-right: 1rem;" />
<div id="member-list" class="popup-wrapper" style="clear: both;">
<div style="color: #965f13; text-align: center; margin-bottom: 1rem; font-size: 1.25rem;">
{{ itemInfo.name }}
</div>
<div v-for="(item, index) in itemInfo.details" :key="index" style="margin-bottom: 1rem;">
<div class="van-cell-group van-cell-group--inset">
<div class="van-cell">
<div class="van-cell__title"> <span>姓名</span> </div>
<div class="van-cell__value"> <span>{{ item.name }}</span></div>
</div>
<div class="van-cell">
<div class="van-cell__title"> <span>手机号</span> </div>
<div class="van-cell__value"> <span><a :href="'tel:' + item.contact" style="color: #965f13;">{{ item.contact }}</a></span></div>
</div>
<div class="van-cell">
<div class="van-cell__title"><span>组别</span></div>
<div class="van-cell__value"><span>{{ item.group }}</span></div>
</div>
</div>
</div>
</div>
</van-popup>
<van-popup v-model:show="show_floor_popup" position="bottom" :overlay="true" :style="{ height: '100%', background: '#F7F8FA' }">
<Floor @close="onClose"></Floor>
</van-popup>
</div>
</template>
<script>
// import { mapState } from 'vuex'
import coord from '@/common/map_data'
import map_max from '@/common/max'
import map_yard from '@/common/yard'
import my_router from '@/common/inner_router'
import map_members from '@/common/members'
import _ from 'lodash';
import $ from 'jquery';
//引入定义的信息窗组件
import InfoWindow from '@/components/InfoWindow'
import InfoWindowLite from '@/components/InfoWindowLite'
import InfoWindowWarn from '@/components/InfoWindowWarn'
import InfoWindowYard from '@/components/InfoWindowYard'
import Floor from '@/components/Floor'
import { useRect } from '@vant/use';
import { mapAPI } from '@/api/map.js'
import wx from 'weixin-js-sdk'
const GPS = {
PI: 3.14159265358979324,
x_pi: 3.14159265358979324 * 3000.0 / 180.0,
delta: function (lat, lon) {
var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
var ee = 0.00669342162296594323; // ee: 椭球的偏心率。
var dLat = this.transformLat(lon - 105.0, lat - 35.0);
var dLon = this.transformLon(lon - 105.0, lat - 35.0);
var radLat = lat / 180.0 * this.PI;
var magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
var sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
return {
'lat': dLat,
'lon': dLon
};
},
//WGS-84 to GCJ-02
gcj_encrypt: function (wgsLat, wgsLon) {
if (this.outOfChina(wgsLat, wgsLon))
return {
'lat': wgsLat,
'lon': wgsLon
};
var d = this.delta(wgsLat, wgsLon);
return {
'lat': wgsLat + d.lat,
'lon': wgsLon + d.lon
};
},
outOfChina: function (lat, lon) {
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
},
transformLat: function (x, y) {
var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
return ret;
},
transformLon: function (x, y) {
var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
return ret;
}
};
export default {
components: { InfoWindow, InfoWindowLite, InfoWindowWarn, InfoWindowYard, Floor },
data() {
return {
map: '',
// location_options: {
// 'showButton': true, // 是否显示定位按钮
// 'buttonPosition': 'LB', // 定位按钮的位置
// /* LT LB RT RB */
// 'buttonOffset': new AMap.Pixel(10, 20), // 定位按钮距离对应角落的距离
// 'showMarker': true, // 是否显示定位点
// 'markerOptions': { // 自定义定位点样式,同Marker的Options
// 'offset': new AMap.Pixel(-18, -36),
// 'content': '<img src="https://a.amap.com/jsapi_demos/static/resource/img/user.png" style="width:36px;height:36px"/>'
// },
// 'showCircle': true, // 是否显示定位精度圈
// 'circleOptions': { // 定位精度圈的样式
// 'strokeColor': '#0093FF',
// 'noSelect': true,
// 'strokeOpacity': 0.5,
// 'strokeWeight': 1,
// 'fillColor': '#02B0FF',
// 'fillOpacity': 0.25
// },
// enableHighAccuracy: true
// },
geolocation: '',
current_lng: '',
current_lat: '',
current_route: '',
current_safe_route: '',
// show_popup: false,
show_member_popup: false,
dialog_show: false,
dialog_text: '',
walk_route: '',
isActive: 0,
location_marker: '',
// route_marker: [],
route_safe_marker: [],
open_safe_route: true,
show_walk_route: true,
// popup_title: '',
// popup_content: '',
// video_src: '',
show_nav_popup: false,
showInfoWindow: false,
showInfoWindowLite: false,
showInfoWindowWarn: false,
showInfoWindowYard: false,
infoWindow: {},
infoWindowLite: {},
infoWindowWarn: {},
infoWindowYard: {},
itemInfo: {},
navBarList: [],
rect: {},
navList: [],
navKey: '',
markerSum: [], // marker合集
// titleLayerSet: {
// 17: {
// x: [109439, 109441],
// y: [53519, 53521]
// },
// 18: {
// x: [218879, 218882],
// y: [107039, 107042]
// }
// },
defaultZoom: 18,
defaultCenter: [120.587382, 31.313900],
mapTiles: [],
open_current_location: true,
point_range: [ // 景区范围经纬度
[120.585111, 31.316084], [120.585111, 31.316084], [120.589488, 31.313197], [120.585422, 31.313005]
],
show_floor_popup: false,
showPopover: false,
actions: [
{ id: '1', text: '客堂签到' },
{ id: '2', text: '三慧楼入住' },
{ id: '3', text: '用斋' },
],
current_activity_route: [],
route_activity_marker: [],
show_activity_route: false,
}
},
async mounted() {
const code = this.$route.query.id;
const { data } = await mapAPI({i: code});
// data.list = data.list.concat(map_yard);
// data.list = data.list.concat(map_members);
this.navBarList = data.list; // 底部导航条
this.mapTiles = data.level; // 获取图层
this.navKey = data.list[0]['id']; // 默认选中 第一个 id
this.navList = data.list.filter(item => item.id === this.navKey)[0]['list']; // 返回默认选中项的实体信息
// 初始化地图
this.initMap();
// this.setMapBoundary();
// 使用之前获取当前地址,判断当前是否能够获取经纬度
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: (res) => {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
this.current_lng = GPS.gcj_encrypt(latitude, longitude).lon;
this.current_lat = GPS.gcj_encrypt(latitude, longitude).lat;
},
});
// 设置贴片地图
this.setTitleLayer();
},
watch: {
// show_popup(val) {
// if (!val) {
// this.$nextTick(() => {
// // 弹框关闭时,暂停视频
// $('.vjs-tech')[0].pause();
// $('.vjs-tech')[0].currentTime = 0;
// })
// }
// },
showInfoWindow(val) {
if (val) {
// 元素的大小及其相对于视口的位置
const rect = useRect(this.$refs.root);
this.rect = rect;
}
},
showInfoWindowLite(val) {
if (val) {
// 元素的大小及其相对于视口的位置
const rect = useRect(this.$refs.root);
this.rect = rect;
}
},
showInfoWindowWarn(val) {
if (val) {
// 元素的大小及其相对于视口的位置
const rect = useRect(this.$refs.root);
this.rect = rect;
}
},
showInfoWindowYard(val) {
if (val) {
// 元素的大小及其相对于视口的位置
const rect = useRect(this.$refs.root);
this.rect = rect;
}
}
},
methods: {
initMap() {
// 初始化地图
this.map = new AMap.Map('container', {
viewMode: '2D', // 设置地图模式
turboMode: false,
showIndoorMap: false,
defaultCursor: 'pointer', // 地图默认鼠标样式
showBuildingBlock: false, // 是否展示地图 3D 楼块
zooms: [17, 20], // 地图显示的缩放级别范围, 默认为 [2, 20] ,取值范围 [2 ~ 30]
showLabel: true, // 是否展示地图文字和 POI 信息
zoom: 18, // 设置地图显示的缩放级别
pitch: 0, // 俯仰角度,默认 0,最大值根据地图当前 zoom 级别不断增大,2D地图下无效 。
rotation: 0, // 地图顺时针旋转角度,取值范围 [0-360] ,默认值:0
center: [120.587382, 31.313900], // 设置地图中心点坐标
forceVector: false,
// rotateEnable: true,
layers: [
// new AMap.TileLayer.RoadNet(),
],
features: ['bg', 'road'], // 设置地图上显示的元素种类
animateEnable: false, // 地图平移过程中是否使用动画
resizeEnable: true,
// WebGLParams: {
// preserveDrawingBuffer: true
// }
});
// 添加地图点击事件
this.map.on("click", this.showInfoClick);
// 加载景点图层
this.loadMaker(this.navKey);
//
this.map.setRotation(6, true);
},
setNavLayer({ id }, index) { // 选择地图图层显示
this.isActive = index;
this.navList = this.navBarList.filter(item => item.id === id)[0]['list']; // 返回默认选中项的实体信息
this.removeLayer();
this.loadMaker(id);
this.closeInfoWindow();
setTimeout(() => {
// 地图zooms调整
this.map.setZoom(this.defaultZoom);
this.map.setZoomAndCenter(this.defaultZoom, this.defaultCenter);
}, 100);
this.removeNavRoute();
// 测试选择人员后轮询
if (id === 'members') {
this.testPolling()
}
},
loadMaker (id) {
var zoomStyleMapping = { 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0 };
const entity_info = this.navBarList.filter(item => item.id === id)[0]['list'];
this.markerSum = [];
_.each(entity_info, (x, i) => {
let marker_icon = '';
if (entity_info[i].window_type === 'warn' && entity_info[i].details.length === 1) { // 如果是预警类型并且内部预警项目只有一个取details第一个icon
marker_icon = entity_info[i].details[0]['icon'];
} else {
marker_icon = entity_info[i].icon;
}
// 创建一个 LabelMarker 实例
var labelMarker = new AMap.LabelMarker({
position: entity_info[i].position,
opacity: 1,
zIndex: 2,
opacity: 0.9,
icon: {
image: marker_icon,
anchor: 'bottom-center',
size: [36, 36],
},
text: {
zooms: [18, 20],
content: entity_info[i].name,
direction: 'top',
offset: [0 , 5],
style: {
padding: [10, 10],
fontSize: 14,
fillColor: '#fff',
strokeWidth: 0,
backgroundColor: '#965f13',
borderWidth: 0,
}
}
});
if (clickListener) {
labelMarker.off('click', clickListener)
}
// 绑定景点的点击事件 - 文字出现才能触发
var clickListener = labelMarker.on('click', (e) => {
// 不同弹框类型
if (entity_info[i].window_type === 'normal') {
this.positionMarker(entity_info[i])
} else if (entity_info[i].window_type === 'lite') {
this.positionLiteMarker(entity_info[i])
} else if (entity_info[i].window_type === 'warn') {
this.positionWarnMarker(entity_info[i])
} else if (entity_info[i].window_type === 'yard') {
this.positionYardMarker(entity_info[i])
} else if (entity_info[i].window_type === 'member') {
this.positionMemberMarker(entity_info[i])
}
})
// 使用LabelsLayer包裹缩放地图时,图标不会自动显示和消失需要配置rank排序
// 创建一个 LabelsLayer 实例来承载 LabelMarker,[LabelsLayer 文档](https://lbs.amap.com/api/jsapi-v2/documentation#labelslayer)
var labelsLayer = new AMap.LabelsLayer({
zooms: [3, 20],
zIndex: 1000,
collision: true, // 该层内标注是否避让
allowCollision: true, // 设置 allowCollision:true,可以让标注避让用户的标注
});
// 将 LabelMarker 实例添加到 LabelsLayer 上
labelsLayer.add(labelMarker);
// 将 LabelsLayer 添加到地图上
this.markerSum.push(labelMarker);
})
this.map.add(this.markerSum);
},
removeLayer () {
this.map.remove(this.markerSum);
},
// setMapBoundary() { // 地图描边
// new AMap.Polygon({
// cursor: 'pointer',
// bubble: true,
// path: [[120.587704, 31.312785], [120.587669, 31.313028], [120.587554, 31.313086], [120.586883, 31.313019], [120.586826, 31.314066], [120.586736, 31.314426], [120.585872, 31.314466], [120.585675, 31.315276], [120.585817, 31.315397], [120.586251, 31.31542], [120.586229, 31.31618], [120.588248, 31.316367], [120.588533, 31.314761], [120.588479, 31.31474], [120.588482, 31.314172], [120.588251, 31.314145], [120.588337, 31.313184], [120.588337, 31.313184], [120.588154, 31.313163], [120.588152, 31.312835]],
// map: this.map,
// fillOpacity: 0.5,
// strokeWeight: 1,
// fillColor: '#CFE7AA'
// });
// },
isPointInRing() { // 是否在景区范围
let isPointInRing = AMap.GeometryUtil.isPointInRing([this.current_lng, this.current_lat], this.point_range);
return isPointInRing
},
setLocation() { // 开启定位服务
// TODO: 暂时屏蔽显示
// 获取失败
// if (!this.current_lng || !this.current_lat) {
// this.dialog_show = true;
// this.dialog_text = '获取经纬度失败';
// }
this.getLocation();
},
handleLocation(status) { // 打开/关闭 当前定位
if (status) {
this.setLocation()
this.open_current_location = false;
} else {
this.removeLocation()
this.open_current_location = true;
}
},
removeLocation() { // 移除定位标记
this.current_lng = '';
this.current_lat = '';
this.map.remove(this.location_marker); // 删除当前定位标记
},
getLocation() { // 获取经纬度
// AMap.plugin(['AMap.Geolocation'], () => {
// this.geolocation = new AMap.Geolocation(this.location_options);
// this.geolocation.getCurrentPosition((status, result) => {
// if (status === 'complete') {
// let lat = result.position.lat;
// let lng = result.position.lng;
// // 行动路线
// if (lng && lat) {
// // this.current_lng = GPS.gcj_encrypt(lat, lng).lon;
// // this.current_lat = GPS.gcj_encrypt(lat, lng).lat;
// this.current_lng = lng;
// this.current_lat = lat;
// }
// } else {
// console.warn('获取失败');
// }
// })
// });
// PC端无法获取定位
// 微信获取地址
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: (res) => {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
this.current_lng = GPS.gcj_encrypt(latitude, longitude).lon;
this.current_lat = GPS.gcj_encrypt(latitude, longitude).lat;
// TODO: 测试暂时屏蔽景区提示
// // 判断是否在范围内
// if (!this.isPointInRing()) {
// this.dialog_show = true;
// this.dialog_text = '您不在景区范围内';
// } else {
// // 使用纠正偏移后的地址,打一个定位标记
// this.location_marker = new AMap.LabelMarker({
// icon: {
// image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
// anchor: 'bottom-center',
// size: [36, 36],
// },
// position: new AMap.LngLat(this.current_lng, this.current_lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// });
// this.map.add(this.location_marker);
// // 定位到当前位置中心
// this.map.setZoomAndCenter(this.zoom, [this.current_lng, this.current_lat]);
// }
// 使用纠正偏移后的地址,打一个定位标记
this.location_marker = new AMap.LabelMarker({
icon: {
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
anchor: 'bottom-center',
size: [36, 36],
},
position: new AMap.LngLat(this.current_lng, this.current_lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
});
this.map.add(this.location_marker);
// 定位到当前位置中心
this.map.setZoomAndCenter(this.zoom, [this.current_lng, this.current_lat]);
},
complete: () => {
// 获取失败
if (!this.current_lng || !this.current_lat) {
this.dialog_show = true;
this.dialog_text = '获取经纬度失败';
}
},
});
},
setZoom(type) { // 设置放大缩小地图
const zoom = this.map.getZoom();
if (type === 'plus') {
this.map.setZoom(zoom + 1)
}
if (type === 'minus') {
this.map.setZoom(zoom - 1)
}
},
addSafeRoute() { // 新增路径
// 行动路线
var path = [
[120.587645, 31.314833],
[120.587709, 31.314338],
[120.588211, 31.314377],
];
// 生成折线地图路径
this.current_safe_route = new AMap.Polyline({
path,
isOutline: true,
outlineColor: '#fba601',
borderWeight: 1,
strokeColor: '#fba601',
strokeOpacity: 1,
strokeWeight: 3,
// 折线样式还支持 'dashed'
strokeStyle: 'solid',
// strokeStyle是dashed时有效
strokeDasharray: [10, 5],
lineJoin: 'round',
lineCap: 'round',
zIndex: 50
})
this.map.add([this.current_safe_route]);
// 设置起始点标记
var marker1 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[0][0], path[0][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker1.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>起点</div>", //设置文本标注内容
});
var marker2 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[path.length - 1][0], path[path.length - 1][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker2.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>终点</div>", //设置文本标注内容
});
// 新增逃生路线标记
this.route_safe_marker = [marker1, marker2]
this.map.add(this.route_safe_marker);
},
removeSafeRoute() { // 移除地图路线
this.map.remove([this.current_safe_route]); // 删除地图折线
this.map.remove(this.route_safe_marker); // 删除起始点标记
},
// addNavRoute (path) { // 新增导航路径
// // 生成折线地图路径
// this.current_route = new AMap.Polyline({
// path,
// isOutline: true,
// outlineColor: '#42a5f5',
// borderWeight: 1,
// strokeColor: '#42a5f5',
// strokeOpacity: 1,
// strokeWeight: 2,
// // 折线样式还支持 'dashed'
// strokeStyle: 'dashed',
// // strokeStyle是dashed时有效
// strokeDasharray: [10, 5],
// lineJoin: 'round',
// lineCap: 'round',
// zIndex: 50
// })
// this.map.add([this.current_route]);
// // 设置起始点标记
// var marker1 = new AMap.Marker({
// icon: new AMap.Icon({
// image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A%E4%BD%8D-%E5%B0%8Fz@2x.png',
// size: new AMap.Size(40, 40),
// // 图标所用图片大小
// imageSize: new AMap.Size(40, 40),
// // 图标取图偏移量
// imageOffset: new AMap.Pixel(0, 0)
// }),
// position: new AMap.LngLat(path[0][0], path[0][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// anchor: 'bottom-center',
// offset: new AMap.Pixel(0, 0)
// });
// marker1.setLabel({
// direction: 'right',
// offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
// content: "<div class='info'>终点</div>", //设置文本标注内容
// });
// var marker2 = new AMap.Marker({
// icon: new AMap.Icon({
// image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A%E4%BD%8D-%E5%B0%8Fz@2x.png',
// size: new AMap.Size(40, 40),
// // 图标所用图片大小
// imageSize: new AMap.Size(40, 40),
// // 图标取图偏移量
// imageOffset: new AMap.Pixel(0, 0)
// }),
// position: new AMap.LngLat(path[path.length - 1][0], path[path.length - 1][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// anchor: 'bottom-center',
// offset: new AMap.Pixel(0, 0)
// });
// marker2.setLabel({
// direction: 'right',
// offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
// content: "<div class='info'>起点</div>", //设置文本标注内容
// });
// // 新增逃生路线标记
// this.route_marker = [marker1, marker2]
// this.map.add(this.route_marker);
// // 关闭导航提示
// this.show_walk_route = false;
// },
addNavRoute(position) { // 新增导航路径
function arraysEqual(a, b) {
// 如果两个数组的长度不等,则它们不相等
if (a.length !== b.length) {
return false;
}
// 比较每个元素是否相等
return a.every(function (element, index) {
return element == b[index];
});
}
let array = []; // 导航点所在路径集合
my_router.forEach((route) => {
route.path.forEach((item) => {
if (arraysEqual(position, item)) {
array.push(route);
return false;
}
})
});
let lngLat = [120.587229, 31.315182];
// let lngLat = [120.587234, 31.314147]; // 左边
// let lngLat = [120.588178, 31.314396]; // 右边
// TAG:生成导航路线
// 构建路线结构
// 如果建筑不在导航路径上面需要单独处理, 直接查询建筑离哪个导航路径最近显示出来
const route_obj = array.length ? array : my_router;
if (!array.length) {
lngLat = position; // 当前导航建筑经纬度
}
// 计算距离最近的路径
route_obj.forEach((line) => {
line.distance = AMap.GeometryUtil.distanceToLine(lngLat, line.path);
});
let min = Math.min(...route_obj.map((line) => line.distance))
let result = route_obj.filter((line) => line.distance === min);
// 标记示例
this.current_route = new AMap.Polyline({
path: result[0]['path'],
isOutline: true,
outlineColor: '#42a5f5',
borderWeight: 1,
strokeColor: '#42a5f5',
strokeOpacity: 1,
strokeWeight: 2,
// 折线样式还支持 'dashed'
strokeStyle: 'dashed',
// strokeStyle是dashed时有效
strokeDasharray: [10, 5],
lineJoin: 'round',
lineCap: 'round',
zIndex: 50
})
this.map.add([this.current_route]);
// 获取定位打标记
this.setLocation();
// TEMP:临时显示测试地址
// this.location_marker = new AMap.LabelMarker({
// icon: {
// image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
// anchor: 'bottom-center',
// size: [36, 36],
// },
// position: new AMap.LngLat(...lngLat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// });
this.map.add(this.location_marker);
// 定位到当前位置中心
this.map.setZoomAndCenter(this.zoom, [120.587706, 31.314197]);
// this.location_marker = new AMap.Marker({
// icon: new AMap.Icon({
// image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
// size: new AMap.Size(40, 40),
// // 图标所用图片大小
// imageSize: new AMap.Size(40, 40),
// // 图标取图偏移量
// imageOffset: new AMap.Pixel(0, 0)
// }),
// position: new AMap.LngLat(...lngLat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// anchor: 'bottom-center',
// offset: new AMap.Pixel(0, 0)
// });
// this.map.add([this.location_marker]);
// 关闭导航提示
this.show_walk_route = false;
},
removeNavRoute() { // 移除地图路线
this.map.remove([this.current_route]); // 删除地图折线
// this.map.remove(this.route_marker); // 删除起始点标记
this.map.remove(this.location_marker); // 删除当前定位标记
// 关闭导航提示
this.show_walk_route = true;
},
computedMapSource(x, y, z) { // 根据图层信息生成图层实际地址
for (const id in this.mapTiles) {
if (z == id) {
const scope = this.mapTiles[id];
return scope[`${x}-${y}`]
}
}
},
setTitleLayer() { // 生成瓦片图
// 获取瓦片图渲染范围
function getFirstProperty(obj) {
for (var prop in obj) {
return prop;
}
}
function getLastProperty(obj) {
var props = [];
for (var prop in obj) {
props.push(prop);
}
return props[props.length - 1];
}
let obj_scope = {};
for (const key in this.mapTiles) {
const element = this.mapTiles[key];
let first = getFirstProperty(element).split('-');
let last = getLastProperty(element).split('-');
obj_scope[key] = {
x: [first[0], last[0]],
y: [first[1], last[1]]
}
}
const _this = this;
var layer = new AMap.TileLayer.Flexible({
cacheSize: 50,
opacity: 1,
zIndex: 100,
createTile: function (x, y, z, success, fail) {
// 控制地图等级显示图片范围-过滤不显示的图层渲染
for (const id in obj_scope) {
if (z == id) {
const scope = obj_scope[id];
if (x < scope.x[0] || x > scope.x[1]) {
fail()
return;
}
if (y < scope.y[0] || y > scope.y[1]) {
fail()
return;
}
}
}
var img = document.createElement('img');
img.onload = function () {
success(img)
};
img.crossOrigin = "anonymous";// 必须添加,同时图片要有跨域头
img.onerror = function () {
fail()
};
// img.src = `images/tiles/${z}/${x}_${y}.png`;
img.src = _this.computedMapSource(x, y, z);
},
});
this.map.addLayer(layer);
// Canvas作为切片
var layer1 = new AMap.TileLayer.Flexible({
// tileSize: 128,
cacheSize: 300,
zIndex: 200,
createTile: function (x, y, z, success, fail) {
var c = document.createElement('canvas');
c.width = c.height = 256;
var cxt = c.getContext("2d");
cxt.font = "15px Verdana";
cxt.fillStyle = "#ff0000";
cxt.strokeStyle = "#FF0000";
cxt.strokeRect(0, 0, 256, 256);
cxt.fillText('(' + [x, y, z].join(',') + ')', 10, 30);
// 通知API切片创建完成
success(c);
}
});
// layer1.setMap(this.map);
// 只显示相应区域,移动会回到选定范围
// this.lockMapBounds()
},
// 限制地图范围
lockMapBounds() {
// var bounds = this.map.getBounds();
var myBounds = new AMap.Bounds(
[120.583246, 31.31645],
[120.589973, 31.311949]
);
this.map.setLimitBounds(myBounds);
},
showInfoClick(e) {
// console.log(e);
var zoom = this.map.getZoom(); //获取当前地图级别
// var text =
// "您在 [" +
// e.lnglat.getLng() +
// "," +
// e.lnglat.getLat() +
// "] 的位置单击了地图!当前层级" +
// zoom;
var text =
"[" +
e.lnglat.getLng() +
"," +
e.lnglat.getLat() +
"],"
console.log(text);
// 点击空白处 关闭弹框
this.closeInfoWindow();
// 关闭弹出底部导航弹框
this.show_nav_popup = false;
},
// setWalkRoute(start = { lng: 120.587799, lat: 31.313276 }, end = { lng: 120.587912, lat: 31.315169 }) {
// //步行导航
// let walking_CallBack = (result) => {
// if (result.type === 'complete') {
// console.warn(result);
// console.warn('绘制步行路线完成');
// } else {
// console.error('步行路线数据查询失败' + result);
// }
// }
// AMap.plugin(["AMap.Walking"], () => { //加载步行导航插件
// this.walk_route = new AMap.Walking({
// map: this.map,
// }); //构造步行导航类
// AMap.Event.addListener(this.walk_route, "complete", walking_CallBack); //返回导航查询结果
// //根据起、终点坐标规划步行路线
// this.walk_route.search(new AMap.LngLat(start.lng, start.lat), new AMap.LngLat(end.lng, end.lat));
// });
// this.show_walk_route = false;
// },
// removeWalkRoute() {
// this.walk_route.clear();
// this.show_walk_route = true;
// },
infoWindowLocation(path) { // 监听前往按钮回调
// if (this.walk_route) { // 清除前一条步行导航
// this.walk_route.clear();
// }
// 测试
this.closeInfoWindow(); // 关闭弹框
// this.setWalkRoute({ lng: 120.59014, lat: 31.310306 }, { lng: position[0], lat: position[1] });
if (this.current_route) { // 清除前一条步行导航
this.map.remove([this.current_route]); // 删除地图折线
// this.map.remove(this.route_marker); // 删除起始点标记
this.map.remove(this.location_marker); // 删除当前定位标记
}
if (path.length) {
this.addNavRoute([+path[0], +path[1]])
} else {
this.dialog_show = true;
this.dialog_text = '内部设施';
}
},
handleSafeRoute(status) { // 打开/关闭逃生路线线
if (status) {
this.addSafeRoute()
this.open_safe_route = false;
} else {
this.removeSafeRoute()
this.open_safe_route = true;
}
},
handleNavPopup() {
this.show_nav_popup = !this.show_nav_popup
},
handleNavMarker (item) { // 底部列表点击跳转弹框判断
if (item.window_type === 'normal') {
this.positionMarker(item)
} else if (item.window_type === 'lite') {
this.positionLiteMarker(item)
} else if (item.window_type === 'warn') {
this.positionWarnMarker(item)
} else if (item.window_type === 'yard') {
this.positionYardMarker(item)
} else if (item.window_type === 'member') {
this.positionMemberMarker(item)
}
},
positionMarker(item) {
// 点击后创建自定义信息窗口
this.setInfoWindows(item)
// 把地图中心点设置为当前点击的标记点
this.map.setZoomAndCenter(this.zoom, item.position);
//
this.show_nav_popup = false;
// 禁止缩放
this.map.setStatus({
zoomEnable: false
});
},
positionLiteMarker(item) {
// 点击后创建自定义信息窗口
this.setInfoWindowsLite(item)
// 把地图中心点设置为当前点击的标记点
this.map.setZoomAndCenter(this.zoom, item.position);
//
this.show_nav_popup = false;
// 禁止缩放
this.map.setStatus({
zoomEnable: false
});
},
positionWarnMarker(item) {
// 点击后创建自定义信息窗口
this.setInfoWindowsWarn(item)
// 把地图中心点设置为当前点击的标记点
this.map.setZoomAndCenter(this.zoom, [item.position[0], item.position[1] + 0.000300]);
//
this.show_nav_popup = false;
// 禁止缩放
this.map.setStatus({
zoomEnable: false
});
},
positionYardMarker(item) {
// 点击后创建自定义信息窗口
this.setInfoWindowsYard(item)
// 把地图中心点设置为当前点击的标记点
this.map.setZoomAndCenter(this.zoom, [item.position[0], item.position[1] + 0.000300]);
//
this.show_nav_popup = false;
// 禁止缩放
this.map.setStatus({
zoomEnable: false
});
},
positionMemberMarker(item) {
// 点击后出现弹框
this.setInfoWindowsMember(item)
// 把地图中心点设置为当前点击的标记点
this.map.setZoomAndCenter(this.zoom, [item.position[0], item.position[1] + 0.000300]);
//
this.show_nav_popup = false;
},
setInfoWindows(item) {
// 此时需要把组件的样式设置为可见
this.showInfoWindow = true
// 设置marker头部的标题信息窗口
const infoWindow = new AMap.InfoWindow({
// 使用自定义窗体
isCustom: true,
// 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
content: this.$refs['infoWindow'].$el,
// 设置定位偏移量
offset: new AMap.Pixel(0, -30),
})
this.infoWindow = infoWindow;
this.itemInfo = item;
this.itemInfo.map = this.map;
this.itemInfo.LngLat = {
lng: this.current_lng,
lat: this.current_lat,
}
// 信息窗口打开
infoWindow.open(this.map, item.position)
},
setInfoWindowsLite(item) {
// 此时需要把组件的样式设置为可见
this.showInfoWindowLite = true
// 设置marker头部的标题信息窗口
const infoWindowLite = new AMap.InfoWindow({
// 使用自定义窗体
isCustom: true,
// 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
content: this.$refs['infoWindowLite'].$el,
// 设置定位偏移量
offset: new AMap.Pixel(0, -30),
})
this.infoWindowLite = infoWindowLite;
this.itemInfo = item;
this.itemInfo.map = this.map;
this.itemInfo.LngLat = {
lng: this.current_lng,
lat: this.current_lat,
}
// 信息窗口打开
infoWindowLite.open(this.map, item.position)
},
setInfoWindowsWarn(item) {
// 此时需要把组件的样式设置为可见
this.showInfoWindowWarn = true
// 设置marker头部的标题信息窗口
const infoWindowWarn = new AMap.InfoWindow({
// 使用自定义窗体
isCustom: true,
// 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
content: this.$refs['infoWindowWarn'].$el,
// 设置定位偏移量
offset: new AMap.Pixel(0, -30),
})
this.infoWindowWarn = infoWindowWarn;
this.itemInfo = item;
this.itemInfo.map = this.map;
this.itemInfo.LngLat = {
lng: this.current_lng,
lat: this.current_lat,
}
// 信息窗口打开
infoWindowWarn.open(this.map, item.position);
},
setInfoWindowsYard(item) {
// 此时需要把组件的样式设置为可见
this.showInfoWindowYard = true
// 设置marker头部的标题信息窗口
const infoWindowYard = new AMap.InfoWindow({
// 使用自定义窗体
isCustom: true,
// 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
content: this.$refs['infoWindowYard'].$el,
// 设置定位偏移量
offset: new AMap.Pixel(0, -30),
})
this.infoWindowYard = infoWindowYard;
this.itemInfo = item;
this.itemInfo.map = this.map;
this.itemInfo.LngLat = {
lng: this.current_lng,
lat: this.current_lat,
}
// 信息窗口打开
infoWindowYard.open(this.map, item.position);
},
setInfoWindowsMember(item) {
this.itemInfo = item;
this.show_member_popup = true;
// 列表滚动到顶部
setTimeout(() => {
$('.van-popup').animate({ scrollTop: 0 }, 100);
}, 100);
},
closeInfoWindow() {
if (this.showInfoWindow) {
this.$refs['infoWindow'].close();
}
if (this.showInfoWindowLite) {
this.$refs['infoWindowLite'].close();
}
if (this.showInfoWindowWarn) {
this.$refs['infoWindowWarn'].close();
}
if (this.showInfoWindowYard) {
this.$refs['infoWindowYard'].close();
}
// 打开缩放
this.map.setStatus({
zoomEnable: true
});
},
closeMember () {
this.show_member_popup = false;
},
onPlay (name) {
// var zoomStyleMapping = { 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0 };
// _.each(coord.spotInfo, (x, i) => {
// var marker = new AMap.ElasticMarker({
// position: coord.spotInfo[i].position,
// zooms: [17, 19],
// styles: [{
// icon: {
// img: x.name !== name ?coord.spotInfo[i].icon : 'https://cdn.ipadbiz.cn/xys/map/%E6%92%AD%E6%94%BE%E6%9A%82%E5%81%9C@2x.png',
// size: [28, 28], // 可见区域的大小
// anchor: 'bottom-center', // 锚点
// fitZoom: 14, // 最合适的级别
// scaleFactor: 2, // 地图放大一级的缩放比例系数
// maxScale: 1.4, // 最大放大比例
// minScale: 0.8 // 最小放大比例
// },
// label: {
// content: coord.spotInfo[i].name,
// position: 'TM',
// // position: 'BM',
// // offset: new AMap.Pixel(0, 10),
// minZoom: 18
// }
// }, {
// icon: {},
// label: {}
// }],
// zoomStyleMapping: coord.spotInfo[i].zoom ? coord.spotInfo[i].zoom : zoomStyleMapping
// });
// if (clickListener) {
// marker.off('click', clickListener)
// }
// // 绑定景点的点击事件 - 文字出现才能触发
// var clickListener = marker.on('click', (e) => {
// this.positionMarker(coord.spotInfo[i]);
// })
// this.spotInfo.push(marker);
// })
// this.map.add(this.spotInfo);
},
onPause (name) {},
testFloor () {
this.show_floor_popup = true;
},
onClose () {
this.show_floor_popup = false;
},
testPolling () { // 测试轮询
let index = 1; // 控制何时停止轮询
let timer = 0; // 实现中断轮询
// syncPromise 模拟异步请求
const syncPromise = () => {
return new Promise(resolve => {
setTimeout(() => {
console.log(`第 ${index} 次请求`);
resolve(index < 5 ? true : false); // 当进行 5 次异步请求后,会返回 false 表示拿到数据分析结果,停止数据查询轮询:
index++;
}, 50);
});
}
// pollingPromise 作为 sleep 睡眠函数使用,去控制轮询的间隔时间,并在指定时间执行异步请求
const pollingPromise = () => {
return new Promise(resolve => {
timer = setTimeout(async () => {
const result = await syncPromise();
resolve(result);
}, 1000);
});
}
// startPolling 作为开始轮询的入口
const startPolling = async () => {
// 清除进行中的轮询,重新开启计时轮询
clearTimeout(timer); // !!! 注意:清除计时器后,会导致整个 async/await 链路中断,若计时器的位置下方还存在代码,将不会执行。
index = 1;
// 立刻执行一次异步请求
let needPolling = await syncPromise();
// 根据异步请求结果,判断是否需要开启计时轮询
while (needPolling) {
needPolling = await pollingPromise();
}
console.log('轮询请求处理完成!'); // 若异步请求被 clearTimeout(timer),这里不会被执行打印输出。
}
const start = async () => {
await startPolling();
console.log('若异步请求被 clearTimeout(timer),这里将不会被执行');
}
start();
},
onSelect (action) {
let path = [];
let paths = [];
// 客堂签到
if (action.id === '1') {
path = [
[120.588218,31.314218],
[120.587884,31.314201],
[120.587861,31.314404],
[120.587851,31.314595],
[120.587903,31.314654],
];
}
// 三慧楼入住
if (action.id === '2') {
path = [
[120.587867,31.314676],
[120.587809,31.314803],
[120.587449,31.314765],
[120.587421,31.314933],
[120.587233,31.314997],
[120.587192,31.315596],
[120.58661,31.315508],
[120.586127,31.31536],
[120.585706,31.315334],
[120.585623,31.31539],
];
}
// 用斋
if (action.id === '3') {
paths = [
[
[120.585639,31.315347],
[120.58587,31.315323],
[120.586367,31.315471],
[120.587187,31.31559],
[120.587241,31.315019],
[120.587344,31.314953],
[120.587427,31.314914],
[120.587454,31.314761],
[120.587823,31.314803],
[120.587847,31.314736],
[120.588217,31.314775],
],
[
[120.585639,31.315347],
[120.58587,31.315323],
[120.586367,31.315471],
[120.587187,31.31559],
[120.587565,31.315635],
[120.587922,31.315674],
[120.587929,31.315467],
[120.588114,31.315472],
[120.588171,31.315006],
[120.588217,31.314775],
]
];
}
this.show_activity_route = true;
//
if (path.length) {
this.addActivityRoute(path);
}
if (paths.length) {
this.addActivityRoutes(paths);
}
},
addActivityRoute(path) { // 新增路径
this.map.remove([...this.current_activity_route]); // 删除地图折线
this.map.remove(this.route_activity_marker); // 删除起始点标记
// 生成折线地图路径
this.current_activity_route = [new AMap.Polyline({
path,
isOutline: true,
outlineColor: '#3274EE',
borderWeight: 1,
strokeColor: '#3274EE',
strokeOpacity: 1,
strokeWeight: 3,
// 折线样式还支持 'dashed'
// strokeStyle: 'solid',
strokeStyle: 'dashed',
// strokeStyle是dashed时有效
strokeDasharray: [10, 5],
lineJoin: 'round',
lineCap: 'round',
zIndex: 50
})]
this.map.add([...this.current_activity_route]);
// 设置起始点标记
var marker1 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[0][0], path[0][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker1.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>起点</div>", //设置文本标注内容
});
var marker2 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[path.length - 1][0], path[path.length - 1][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker2.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>终点</div>", //设置文本标注内容
});
// 新增逃生路线标记
this.route_activity_marker = [marker1, marker2]
this.map.add(this.route_activity_marker);
},
addActivityRoutes(paths) { // 新增路径
this.map.remove([...this.current_activity_route]); // 删除地图折线
this.map.remove(this.route_activity_marker); // 删除起始点标记
// 生成折线地图路径
this.current_activity_route = [];
paths.forEach(item => {
this.current_activity_route.push(
new AMap.Polyline({
path: item,
isOutline: true,
outlineColor: '#3274EE',
borderWeight: 1,
strokeColor: '#3274EE',
strokeOpacity: 1,
strokeWeight: 3,
// 折线样式还支持 'dashed'
// strokeStyle: 'solid',
strokeStyle: 'dashed',
// strokeStyle是dashed时有效
strokeDasharray: [10, 5],
lineJoin: 'round',
lineCap: 'round',
zIndex: 50
})
);
})
this.map.add([...this.current_activity_route]);
let path = paths[0];
// 设置起始点标记
var marker1 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[0][0], path[0][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker1.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>起点</div>", //设置文本标注内容
});
var marker2 = new AMap.Marker({
icon: new AMap.Icon({
image: 'https://cdn.ipadbiz.cn/xys/map/%E5%AE%9A.png',
size: new AMap.Size(40, 40),
// 图标所用图片大小
imageSize: new AMap.Size(40, 40),
// 图标取图偏移量
imageOffset: new AMap.Pixel(0, 0)
}),
position: new AMap.LngLat(path[path.length - 1][0], path[path.length - 1][1]), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
anchor: 'bottom-center',
offset: new AMap.Pixel(0, 0)
});
marker2.setLabel({
direction: 'right',
offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
content: "<div class='info'>终点</div>", //设置文本标注内容
});
// 新增逃生路线标记
this.route_activity_marker = [marker1, marker2]
this.map.add(this.route_activity_marker);
},
removeActivityRoute() { // 移除地图路线
this.show_activity_route = false;
this.map.remove([...this.current_activity_route]); // 删除地图折线
this.map.remove(this.route_activity_marker); // 删除起始点标记
},
}
}
</script>
<style lang="less">
#container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
/* 标记文字样式 */
.amap-marker-label {
padding: 0.25rem 0.5rem;
width: auto;
border: none;
border-radius: 2px;
background: rgba(86, 65, 23, 0.8);
color: white;
}
.amap-marker {
.amap-icon {
margin-top: 0.25rem;
}
}
.input-card {
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border-radius: .25rem;
width: 20rem;
border-width: 0;
border-radius: 0.4rem;
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
position: fixed;
top: 4rem;
right: 1rem;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 0.75rem 1.25rem;
}
.tool-bar-wrapper {
position: absolute;
left: 20px;
bottom: 8rem;
width: 20px;
}
.nav-bar-wrapper {
position: fixed;
bottom: 0;
left: 0;
height: 5.5rem;
width: 100%;
background-color: white;
text-align: center;
box-shadow: 0 -1px 0 rgba(80, 80, 80, 0.1);
z-index: 999;
// padding: 0.5rem 0;
padding-bottom: 0.5rem;
.nav-bar-content {
display: flex;
overflow-x: scroll;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
position: relative;
}
.item {
padding-top: 0.5rem;
color: #888;
width: 21.5%;
flex-shrink: 0;
padding-top: 1rem;
}
.checked {
color: #965f13;
}
}
.safe-route-wrapper {
position: absolute;
bottom: 2rem;
right: 1rem;
background-color: white;
}
.operate-bar-wrapper {
position: fixed;
left: 20px;
bottom: 5.5rem;
width: 20px;
height: auto;
z-index: 100;
.box-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.item {
position: relative;
text-align: center;
font-size: 0.85rem;
width: 2rem;
height: 2rem;
background-color: white;
margin-bottom: 1rem;
border-radius: 50%;
padding: 2.5px;
line-height: 2rem;
}
}
}
.popup-wrapper {
margin: 1rem;
.title {
font-size: 1.25rem;
margin-bottom: 0.85rem;
}
.content {
line-height: 1.75;
font-size: 0.95rem;
}
}
.hideScrollBar::-webkit-scrollbar {
display: none;
}
.hideScrollBar {
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
.van-dialog__confirm,
.van-dialog__confirm:active {
color: #AB8F57;
}
.walk-nav-text {
position: fixed;
bottom: 6rem;
left: 50%;
transform: translate(-50%, -50%);
z-index: 999;
background: rgba(86, 65, 23, 0.8);
color: white;
border-radius: 10px;
padding: 5px 12px;
font-size: 0.8rem;
}
.van-cell-group--inset {
margin: 0 0.466667vw;
border-radius: 2.133333vw;
overflow: hidden;
}
.van-cell-group {
background: '#fff';
}
.van-cell {
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
padding: 2.666667vw 4.266667vw;
overflow: hidden;
color: #323233;
font-size: 3.733333vw;
line-height: 6.4vw;
background: #fff;
}
.van-cell__title, .van-cell__value {
flex: 1;
}
.van-cell__value {
position: relative;
overflow: hidden;
color: #969799;
text-align: right;
vertical-align: middle;
word-wrap: break-word;
}
.van-cell:after {
position: absolute;
box-sizing: border-box;
content: " ";
pointer-events: none;
right: 4.266667vw;
bottom: 0;
left: 4.266667vw;
border-bottom: 1px solid #ebedf0;
transform: scaleY(.5);
}
</style>
yarn.lock
View file @
1e4fcd1
...
...
@@ -293,10 +293,10 @@
resolved "https://mirrors.cloud.tencent.com/npm/@vant/popperjs/-/popperjs-1.3.0.tgz"
integrity sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==
"@vant/use@^1.
5.1
":
version "1.
5.1
"
resolved "https://mirrors.cloud.tencent.com/npm/@vant/use/-/use-1.
5.1.tgz
"
integrity sha512-
Zxd7lDz/LliVYEQi3PR9a8CQa/kGCVzF0u9hqDMaTlgXlbG0wHMFPllrcG0ThR6bfs8xrYVuSFM9pJn6HSoUGQ
==
"@vant/use@^1.
6.0
":
version "1.
6.0
"
resolved "https://mirrors.cloud.tencent.com/npm/@vant/use/-/use-1.
6.0.tgz#237df3091617255519552ca311ffdfea9de59001
"
integrity sha512-
PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA
==
"@videojs-player/vue@^1.0.0":
version "1.0.0"
...
...
@@ -3144,13 +3144,13 @@ v-viewer@^3.0.11:
lodash "^4.17.21"
viewerjs "^1.9.0"
vant@^4.
6.3
:
version "4.
6.3
"
resolved "https://mirrors.cloud.tencent.com/npm/vant/-/vant-4.
6.3.tgz#e36a2dc2fa94253b8218094d88e9b0cd62b3437d
"
integrity sha512-
hkiBzM1dhEj9EWSjRnyB7gd6SiVa3/+qthNZtlJdj42C+pXIN+oq0UhKz5PRHWi8fHyPfycnqRzyvEJxouT+zw
==
vant@^4.
8.1
:
version "4.
8.1
"
resolved "https://mirrors.cloud.tencent.com/npm/vant/-/vant-4.
8.1.tgz#b4fce5fb5aa9dfa42143c4122d1e2f92407ec768
"
integrity sha512-
SkFZM3Z3Bwi5do+iQNfRgDi7b+Ka29rUUNzck06W2KoFie3CLTqSifLa5TuZCEoXPSkqR+fRH/VE5G57mmL8sg
==
dependencies:
"@vant/popperjs" "^1.3.0"
"@vant/use" "^1.
5.1
"
"@vant/use" "^1.
6.0
"
"@vue/shared" "^3.0.0"
vconsole@^3.14.6:
...
...
Please
register
or
login
to post a comment