| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- // leaflet 地图组件
- // author: wzx
- // version: 1.0
- import L from 'leaflet'
- // import 'leaflet.motion/dist/leaflet.motion.min.js'
- import patch from '@/utils/map/sub/patch'
- import config from '@/utils/map/sub/config'
- import global from '@/utils/map/sub/global'
- import player from '@/utils/map/sub/player'
- import checkPoint from '@/utils/map/sub/checkPoint'
- import route from '@/utils/map/sub/route'
- import store from '@/store/index'
- export default {
- global: global,
- config: config,
- player: player,
- checkPoint: checkPoint,
- route: route,
- exControlContainer: null,
- elRoute: null,
- elPlayer: null,
- elPlayerTooltip: null,
- elPlayerTrail: null,
- elList: null,
- elFullScreen: null,
- // 地图初始化
- // mapid <string> 地图容器的id
- // mapUrl <string> 地图瓦片的地址
- // options <object> 地图选项
- init(caller, mapid, mapUrl, options) {
- patch.run()
- global.init()
- global.setCaller(caller)
- global.setMapUrl(mapUrl)
- global.mapOptions = Object.assign(config.mapDefaultOptions, options)
- if (global.mapOptions.maxBounds != null) {
- global.setPreloadBounds(global.mapOptions.maxBounds)
- // console.log("preloadBounds: ", global.mapOptions.maxBounds)
- // global.mapOptions.maxBounds = L.latLngBounds(global.mapOptions.maxBounds).pad(0.3)
- global.mapOptions.maxBounds = null
- // console.log("maxBounds: ", global.mapOptions.maxBounds)
- }
- global.map = L.map(mapid, global.mapOptions)
- // global.map = L.map(mapid, {
- // attributionControl: false
- // }).setView(centPoint, zoomNum)
- L.control.attribution({
- // prefix: '© 小飞龙定向', // 地图右下角属性文本的前缀内容
- prefix: false // 地图右下角属性文本的前缀内容
- }).addTo(global.map);
- L.control.scale({
- maxWidth: 120, // 控件的最大宽度,单位是像素
- metric: true, // 是否显示公制比例线(米/公里)
- imperial: false, // 是否显示英制比例线(英里/英尺)
- position: 'topright' // 控件的位置(地图的一个角)。可能的值是 ‘topleft’、 ‘topright’、 ‘bottomleft’ 或 ‘bottomright’
- }).addTo(global.map)
- this.extendControl()
- // 添加地图点击弹窗
- global.map.on('click', (e) => {
- console.log("坐标", e.latlng.toString())
- // L.popup().setLatLng(e.latlng)
- // .setContent("坐标:" + e.latlng.toString())
- // .openOn(global.map);
- });
- // global.map.on('resize', (e) => {
- // console.log("[resize] 地图大小调整", e)
- // this.onWindowResize()
- // });
- // global.map.on('invalidateSize', (e) => {
- // console.log("[invalidateSize] 地图容器大小调整", e)
- // // this.onWindowResize()
- // });
- global.map.on('zoomstart', (e) => {
- // console.log("[zoomstart] 即将开始地图缩放", e)
- player.onZoomStart(e)
- checkPoint.onZoomStart(e)
- route.onZoomStart(e)
- });
- global.map.on('zoom', (e) => {
- // console.log("[zoom] 地图缩放", e)
- player.onZoom(e)
- checkPoint.onZoom(e)
- route.onZoom(e)
- });
- global.map.on('zoomend', (e) => {
- // console.log("[zoomend] 地图缩放结束", e)
- this.preLoadTile()
- player.onZoomEnd(e)
- checkPoint.onZoomEnd(e)
- route.onZoomEnd(e)
- });
- // global.map.on('zoomanim', (e) => {
- // console.log("地图缩放中...", e)
- // // player.onZoomEnd(e)
- // // checkPoint.onZoomEnd(e)
- // // route.onZoomEnd(e)
- // });
- // global.map.on('moveend', (e) => {
- // // console.log("[zoomend] 地图移动结束", e)
- // this.preLoadTile()
- // });
- this.addMapLayer(mapUrl)
- player.init()
- checkPoint.init()
- route.init()
- this.preLoadTile()
- },
- addMapLayer(mapUrl) {
- // console.log('[addMapLayer] mapurl', mapurl)
- // var mapurl = 'static/map/' + mapid + '/{z}/{x}/{y}.png'
- var tileUrl = mapUrl + '/{z}/{x}/{y}.png'
- global.map_layer = L.tileLayer(tileUrl, {
- // minZoom: minZoom,
- // maxZoom: maxZoom,
- errorTileUrl: '/static/image/tileMiss.png',
- tms: false, // 是否反转Y轴坐标,
- // keepBuffer: 20, // 平移地图时,在卸载切片之前,请保留这么多行和几列的切片
- // attribution: '版权所有'
- }).addTo(global.map);
- },
- // onWindowResize() {
- // var centPoint = global.mapOptions.center
- // if (centPoint != null) {
- // console.log("[Leaflet] onWindowResize centPoint:", centPoint)
- // global.map.setView(centPoint)
- // // global.map.panTo(centPoint)
- // }
- // },
- extendControl() {
- var that = this
- L.Control.Search = L.Control.extend({
- options: {
- position: 'topleft' //初始位置
- },
- initialize: function(options) {
- L.Util.extend(this.options, options)
- },
- onAdd: function(map) {
- // var caller = global.getCaller()
- //创建Dom元素 L.DomUtil.create('元素类型', 'class类名')
- that.exControlContainer = L.DomUtil.create('div', 'leaflet-bar')
- that.elRoute = L.DomUtil.create('a', 'leaflet-control-common')
- that.elRoute.innerHTML = '<span>路线</span>'
- if (store.state.mapControlRoute) {
- L.DomUtil.setClass(that.elRoute, 'leaflet-control-selected')
- }
- that.elPlayer = L.DomUtil.create('a', 'leaflet-control-common')
- that.elPlayer.innerHTML = '<span>玩家</span>'
- if (store.state.mapControlPlayer) {
- L.DomUtil.setClass(that.elPlayer, 'leaflet-control-selected')
- }
- that.elPlayerTooltip = L.DomUtil.create('a', 'leaflet-control-common')
- that.elPlayerTooltip.innerHTML = '<span>提示</span>'
- if (store.state.mapControlTooltip) {
- L.DomUtil.setClass(that.elPlayerTooltip, 'leaflet-control-selected')
- }
- that.elPlayerTrail = L.DomUtil.create('a', 'leaflet-control-common')
- that.elPlayerTrail.innerHTML = '<span>轨迹</span>'
- if (store.state.mapControlTrail) {
- L.DomUtil.setClass(that.elPlayerTrail, 'leaflet-control-selected')
- }
- that.elList = L.DomUtil.create('a', 'leaflet-control-common')
- that.elList.innerHTML = '<span>列表</span>'
- if (store.state.mapPopupShow) {
- L.DomUtil.setClass(that.elList, 'leaflet-control-selected')
- }
- that.elFullScreen = L.DomUtil.create('a', 'leaflet-control-common')
- that.elFullScreen.innerHTML = '<span>全屏</span>'
- if (store.state.fullScreen) {
- L.DomUtil.setClass(that.elFullScreen, 'leaflet-control-selected')
- }
- // that.exControlContainer.style.display = 'flex'
- that.exControlContainer.appendChild(that.elRoute)
- that.exControlContainer.appendChild(that.elPlayer)
- that.exControlContainer.appendChild(that.elPlayerTooltip)
- that.exControlContainer.appendChild(that.elPlayerTrail)
- that.exControlContainer.appendChild(that.elList)
- that.exControlContainer.appendChild(that.elFullScreen)
- //注册事件
- L.DomEvent.addListener(that.elRoute, 'click dblclick', function(ev) {
- that.elRouteClick(ev)
- }, that.route)
- L.DomEvent.addListener(that.elPlayer, 'click dblclick', function(ev) {
- that.elPlayerClick(ev)
- }, that.player)
- L.DomEvent.addListener(that.elPlayerTooltip, 'click dblclick', function(ev) {
- that.elPlayerTooltipClick(ev)
- }, that.player)
- L.DomEvent.addListener(that.elPlayerTrail, 'click dblclick', function(ev) {
- that.elPlayerTrailClick(ev)
- }, that.player)
- L.DomEvent.addListener(that.elList, 'click dblclick', function(ev) {
- that.elListClick(ev)
- }, this)
- L.DomEvent.addListener(that.elFullScreen, 'click dblclick', function(ev) {
- that.elFullScreenClick(ev)
- }, this)
- //返回这个主元素
- return that.exControlContainer
- },
- onRemove: function(map) {
- // Clean up the DOM
- },
- })
- //在L.control上添加一个search(封装好的函数)
- L.control.Search = function(options) {
- return new L.Control.Search(options)
- }
- //将自定义控件添加到地图上
- L.control.Search().addTo(global.map)
- },
-
- preventEvent(ev) {
- L.DomEvent.stopPropagation(ev)
- L.DomEvent.preventDefault(ev)
- },
-
- elRouteClick(ev) {
- this.preventEvent(ev)
- this.route.toggle()
- this.toggleControl(this.elRoute)
- },
-
- elPlayerClick(ev) {
- this.preventEvent(ev)
- this.toggleControl(this.elPlayer)
- this.player.togglePlayer()
- },
-
- elPlayerTooltipClick(ev) {
- this.preventEvent(ev)
- this.toggleControl(this.elPlayerTooltip)
- this.player.toggleTooltip()
- console.log("store.state.mapControlPlayer: " + store.state.mapControlPlayer)
- if (!store.state.mapControlPlayer) {
- this.player.togglePlayer(true)
- // this.player.toggleTooltipFlag = false
- this.toggleControl(this.elPlayer)
- }
- },
-
- elPlayerTrailClick(ev) {
- this.preventEvent(ev)
- this.toggleControl(this.elPlayerTrail)
- this.player.toggleTrail()
- },
-
- elListClick(ev) {
- this.preventEvent(ev)
- this.toggleControl(this.elList)
- global.getCaller().popupToggle()
- },
-
- elFullScreenClick(ev) {
- this.preventEvent(ev)
- this.toggleControl(this.elFullScreen)
- global.getCaller().fullScreenToggle()
- },
-
- toggleControl(el) {
- if (L.DomUtil.hasClass(el, 'leaflet-control-selected')) {
- L.DomUtil.removeClass(el, 'leaflet-control-selected')
- } else {
- L.DomUtil.setClass(el, 'leaflet-control-selected')
- }
- },
- long2tile(lon, zoom) {
- return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom)));
- },
- lat2tile(lat, zoom) {
- return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) /
- 2 * Math.pow(2, zoom)));
- },
- // 预加载地图瓦片
- preLoadTile() {
- var zoom = global.map.getZoom()
- if (zoom >= global.mapOptions.maxZoom) {
- console.log("[preLoadTile] 已达到最大缩放级别,无需预加载地图瓦片")
- return
- }
- var preloadZoom = zoom + 1;
- if (global.getPreloadTileMapByZoom(preloadZoom) != null) {
- console.log("[preLoadTile] 跳过,已预加载地图瓦片 Zoom: " + preloadZoom)
- return
- } else {
- console.log("[preLoadTile] 预加载地图瓦片 Zoom: " + preloadZoom)
- global.setPreloadTileMap({
- zoom: preloadZoom
- })
- }
- var bounds = null
- var preloadBounds = global.getPreloadBounds()
- if (preloadBounds != null) {
- // console.log("[preLoadTile] preloadBounds", preloadBounds)
- bounds = L.latLngBounds(preloadBounds)
- } else {
- console.warn("[preLoadTile] preloadBounds == null")
- bounds = global.map.getBounds().pad(0.2)
- }
- var west = bounds.getWest()
- var south = bounds.getSouth()
- var east = bounds.getEast()
- var north = bounds.getNorth()
- // console.log("[preLoadTile] 预加载地图瓦片", bounds, west, south, east, north, zoom)
- // L.circleMarker([south, west], {
- // radius: 18, // 圆的半径 px
- // weight: 1.6, // 描边宽度 px
- // opacity: 1.0, // 描边不透明度
- // fill: true, // 是否填充
- // fillColor: 'red', // 填充颜色
- // fillOpacity: 1.0, // 填充不透明度
- // })
- // .addTo(global.map)
- // console.log("[preLoadTile] circleMarker", [south, west])
- // L.circleMarker([north, east], {
- // radius: 18, // 圆的半径 px
- // weight: 1.6, // 描边宽度 px
- // opacity: 1.0, // 描边不透明度
- // fill: true, // 是否填充
- // fillColor: 'red', // 填充颜色
- // fillOpacity: 1.0, // 填充不透明度
- // })
- // .addTo(global.map)
- // console.log("[preLoadTile] circleMarker", [north, east])
- // Determine which tile we need
- var dataEast = this.long2tile(east, preloadZoom)
- var dataWest = this.long2tile(west, preloadZoom)
- var dataNorth = this.lat2tile(north, preloadZoom)
- var dataSouth = this.lat2tile(south, preloadZoom)
- var mapUrl = global.getMapUrl()
- // console.log("[preLoadTile] dataNorth = " + dataNorth + " dataSouth = " + dataSouth)
- for (let y = dataNorth; y < dataSouth + 1; y++) {
- // console.log("[preLoadTile] y = " + y)
- for (let x = dataWest; x < dataEast + 1; x++) {
- // console.log("[preLoadTile] x = " + x)
- var url = mapUrl + '/' + preloadZoom + '/' + x + '/' + y + '.png'
- var img = new Image()
- img.src = url
- // console.log("[preLoadTile] 预加载地图瓦片", url)
- }
- }
- },
- test() {
- console.log("test ok")
- },
- free() {
- console.log("[Leaflet] free()")
- player.free()
- checkPoint.free()
- route.free()
- }
- }
|