1013 lines
39 KiB
Vue
1013 lines
39 KiB
Vue
/**
|
||
* @Author: tiansiyuan
|
||
* @Date: 2021/2/20 13:12:56
|
||
* @LastEditors: tiansiyuan
|
||
* @LastEditTime: 2021/2/20 17:57:34
|
||
* @Description: 资源上图方法
|
||
*/
|
||
|
||
import { createDefaultFeatureStyle, createDefaultDivIcon } from './map-utils'
|
||
import './js/bouncemarker'
|
||
import './pulse/L.Icon.Pulse'
|
||
import { wgs84LL2bdLL } from '../utils/coordinateSystemTransform'
|
||
import mybus from '@/myplugins/mybus'
|
||
const L = window.L || {}
|
||
const shinningMarker = null
|
||
const SuperMap = window.SuperMap || {}
|
||
const restoreIconObj = {
|
||
layerId: 0,
|
||
restoreIcon: null,
|
||
currentLayer: null,
|
||
}
|
||
const progress = document.getElementById('progress')
|
||
const progressBar = document.getElementById('progress-bar')
|
||
|
||
function updateProgressBar(processed, total, elapsed, layersArray) {
|
||
if (elapsed > 1000) {
|
||
// if it takes more than a second to load, display the progress bar:
|
||
progress.style.display = 'block'
|
||
progressBar.style.width = Math.round((processed / total) * 100) + '%'
|
||
}
|
||
|
||
if (processed === total) {
|
||
// all markers processed - hide the progress bar:
|
||
progress.style.display = 'none'
|
||
}
|
||
}
|
||
/**
|
||
* 构造图标聚合图层
|
||
* @param layerClassName 据此判断是否需要自定义聚合图层的样式
|
||
* @returns {*}
|
||
*/
|
||
function createMarkerClusterLayer(layerClassName, mapObj) {
|
||
let array = [];
|
||
let markerClusterLayer = null
|
||
if (layerClassName) {
|
||
// 如果存在类名,表示需要自定义图标
|
||
markerClusterLayer = L.markerClusterGroup({
|
||
iconCreateFunction(cluster) {
|
||
const markers = cluster.getAllChildMarkers()
|
||
let n = 0
|
||
for (let i = 0; i < markers.length; i++) {
|
||
n += markers[i].number
|
||
}
|
||
return L.divIcon({ html: markers.length, className: layerClassName })
|
||
},
|
||
// 是否允许指定 PolylineOptions 样式 spider
|
||
// spiderfyOnMaxZoom: true,
|
||
// 是否显示标记的边界
|
||
showCoverageOnHover: true,
|
||
// 是否点击展开
|
||
zoomToBoundsOnClick: true,
|
||
chunkProgress: updateProgressBar,
|
||
chunkedLoading: true,
|
||
maxClusterRadius: 80,
|
||
})
|
||
} else {
|
||
// 使用默认图标
|
||
markerClusterLayer = L.markerClusterGroup({
|
||
spiderfyOnMaxZoom: false,
|
||
// 是否显示标记的边界
|
||
showCoverageOnHover: true,
|
||
// 是否点击展开
|
||
zoomToBoundsOnClick: true,
|
||
maxClusterRadius: 80,
|
||
})
|
||
markerClusterLayer.on('clusterclick', function(a) {
|
||
let clusterList = [];
|
||
if (mapObj.getZoom() == mapObj.getMaxZoom()) {
|
||
for (var i = 0; i < a.layer.getAllChildMarkers().length; i++) {
|
||
clusterList.push(a.layer.getAllChildMarkers()[i].resourceData);
|
||
}
|
||
mybus.emit('openOperationPopup', clusterList);
|
||
}
|
||
});
|
||
}
|
||
return markerClusterLayer
|
||
}
|
||
|
||
/**
|
||
* 数据处理方法,每次只处理1000条数据,让其他事件循环有机会执行
|
||
* @param data 要处理的数据
|
||
* @param doChunk 处理数据的函数
|
||
* @param chunkCompleted 数据处理完以后执行的函数
|
||
*/
|
||
function chunkData(data, doChunk, chunkCompleted) {
|
||
const chunk = data.splice(0, 1000)
|
||
doChunk(chunk)
|
||
if (data.length > 0) {
|
||
setTimeout(() => {
|
||
chunkData(data, doChunk, chunkCompleted)
|
||
}, 0)
|
||
} else {
|
||
chunkCompleted()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 把单个点位添加到地图上
|
||
* @param feature 添加到地图上的要素(必要),例 feature: {lat: 36.45876415, lon: 120.354862157}
|
||
* @param iconSize 图标尺寸,如果不传参,则使用默认值
|
||
* @param iconUrl 图标路径,如果不传参,则使用默认值
|
||
* @param isCustomIcon 是否自定义div图标
|
||
* @param iconHtml 自定义图标的div内容
|
||
* @param iconClassName 自定义图标的样式类名
|
||
* @param featurePopupInfo 要素的弹窗信息,例:featurePopupInfo: {entityData, layerConfigInfo, allMapObject}
|
||
* @param createPopupFun 创建要素弹窗的方法
|
||
* @param popupClassName 弹窗的样式类名
|
||
* @param isOpenPopup 是否立即打开弹窗
|
||
* @param mapObj
|
||
* @param featureGroup
|
||
* @param layerGroup
|
||
* @return {*|void} layer对象,可以直接用map的removeLayer删除
|
||
*/
|
||
function addPointOnMap({
|
||
feature,
|
||
iconSize = [48, 48],
|
||
iconUrl = 'poi.png',
|
||
isCustomIcon = '',
|
||
iconHtml = '',
|
||
iconClassName = '',
|
||
featurePopupInfo = null,
|
||
createPopupFun = null,
|
||
popupClassName = 'multi-general-popup-style',
|
||
isOpenPopup = '',
|
||
coordinateSystemFlag = false,
|
||
} = {},
|
||
mapObj,
|
||
featureGroup,
|
||
layerGroup
|
||
) {
|
||
// 创造点位marker
|
||
let icon = null
|
||
// 区分是否是自定义div图标
|
||
if (isCustomIcon) {
|
||
iconHtml = iconHtml || createDefaultDivIcon()
|
||
icon = createDefaultFeatureStyle({ img: iconUrl, iconSize: iconSize },
|
||
iconHtml,
|
||
iconClassName
|
||
)
|
||
} else {
|
||
icon = createDefaultFeatureStyle({ img: iconUrl, iconSize: iconSize })
|
||
}
|
||
// 当前为百度09墨卡托,上图前进行坐标转换
|
||
console.log('当前坐标', feature)
|
||
// if (!coordinateSystemFlag) {
|
||
// const bdLonLat = wgs84LL2bdLL(feature.lon, feature.lat);
|
||
// feature.lon = bdLonLat[0];
|
||
// feature.lat = bdLonLat[1];
|
||
// console.log('转换之后的坐标', feature);
|
||
// }
|
||
const marker = L.marker([feature.lat, feature.lon], {
|
||
icon: icon,
|
||
attribution: feature.attributes,
|
||
})
|
||
let elementHtml = null
|
||
// 如果featurePopInfo不为null,则说明需要弹窗,如果为null,则说明不需要弹窗,则不添加点击事件
|
||
if (featurePopupInfo !== null) {
|
||
featurePopupInfo.allMapObject = {
|
||
mapObj: mapObj,
|
||
}
|
||
elementHtml = createPopupFun(featurePopupInfo)
|
||
marker.on('click', (e) => {
|
||
const location = [e.latlng.lat, e.latlng.lng]
|
||
const latLng = L.latLng(location)
|
||
L.popup({ className: popupClassName })
|
||
.setLatLng(latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(mapObj.map)
|
||
})
|
||
}
|
||
const layer = marker.addTo(mapObj.map);
|
||
featureGroup.addLayer(layer)
|
||
layerGroup.set('potcon', layer)
|
||
// marker
|
||
// .addTo(mapObj.map)
|
||
// .bindPopup(elementHtml, { className: popupClassName })
|
||
// .openPopup() :
|
||
// marker.addTo(mapObj.map)
|
||
}
|
||
|
||
/**
|
||
* 构建promise,使用uuid去超图服务查询features,得到结果就把promise状态置为已决议,并返回features
|
||
* @param idArray 资源的唯一标识数组,视频监控是camera_index_code,其他都是uuid
|
||
* @param layerConfigInfo 图层配置信息
|
||
* @param type 资源类型,视频监控需传值,其他资源不传值即可,只有视频监控用的camera_index_code,其他都是uuid
|
||
* @returns {Promise<any>}
|
||
* @private
|
||
*/
|
||
function createPromiseByQueryService(idArray = [], layerConfigInfo, type = '') {
|
||
const queryUrl = _mapConfig.config.QUERY_URL
|
||
// 构造查询条件authorityFilter
|
||
let authorityFilter = ''
|
||
if (idArray.length === 0) {
|
||
// id数组为空,则默认去超图查询全部点位数据
|
||
authorityFilter = 'SMID > 0'
|
||
} else if (idArray.length <= 1000) {
|
||
const authorityFilter1 = "'" + idArray.join("','") + "'"
|
||
authorityFilter = type ?
|
||
`CAMERA_INDEX_CODE in (${authorityFilter1})` :
|
||
`UUID in (${authorityFilter1})`
|
||
} else {
|
||
// 当UUID的个数大于1000
|
||
const count = Math.floor(idArray.length / 1000) // 向下取整
|
||
// 这里分开处理,如果数据量很大时,可以节省时间
|
||
if (type) {
|
||
for (let i = 0; i <= count; i++) {
|
||
const indexCodeSplice = idArray.slice(i * 1000, (i + 1) * 1000)
|
||
const authorityFilterString = "'" + indexCodeSplice.join("','") + "'"
|
||
const authorityFilterSplice = `CAMERA_INDEX_CODE in (${authorityFilterString})`
|
||
authorityFilter =
|
||
i === 0 ?
|
||
authorityFilterSplice :
|
||
`${authorityFilter} or ${authorityFilterSplice}`
|
||
}
|
||
} else {
|
||
for (let i = 0; i <= count; i++) {
|
||
const indexCodeSplice = idArray.slice(i * 1000, (i + 1) * 1000)
|
||
const authorityFilterString = "'" + indexCodeSplice.join("','") + "'"
|
||
const authorityFilterSplice = `UUID in (${authorityFilterString})`
|
||
authorityFilter =
|
||
i === 0 ?
|
||
authorityFilterSplice :
|
||
`${authorityFilter} or ${authorityFilterSplice}`
|
||
}
|
||
}
|
||
}
|
||
|
||
// 构造查询参数,用于去iServer查询
|
||
console.log('查询条件', authorityFilter)
|
||
const getFeatureBySQLParams = new SuperMap.QueryBySQLParameters({
|
||
queryParams: {
|
||
name: layerConfigInfo.layerName,
|
||
attributeFilter: authorityFilter,
|
||
},
|
||
})
|
||
// 将查询结果储存在promise中,返回这个promise
|
||
return new Promise((resolve, reject) => {
|
||
L.supermap
|
||
.queryService(queryUrl)
|
||
.queryBySQL(getFeatureBySQLParams, (serviceResult) => {
|
||
// debugger;
|
||
try {
|
||
const features = serviceResult.result.recordsets[0].features.features
|
||
resolve(features)
|
||
} catch (e) {
|
||
reject(e)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
/**
|
||
* @description: 新的资源上图
|
||
* @param {*}
|
||
* @return {*}
|
||
*/
|
||
function addResourceOnMapNew(
|
||
features,
|
||
layerConfig,
|
||
getLayerPopupInfo,
|
||
createPopupFun,
|
||
mapObj,
|
||
featureGroup,
|
||
layerGroup
|
||
) {
|
||
// 如果资源要素数量为0,则说明该种资源没有记录
|
||
if (features.length < 1) {
|
||
return Promise.resolve(0)
|
||
}
|
||
|
||
// 创建图层
|
||
let layers = null
|
||
// 判断是否是聚合图层
|
||
layers = layerConfig.cluster.flag ?
|
||
createMarkerClusterLayer(layerConfig.cluster.clusterName) : []
|
||
|
||
// 该promise用于将资源要素聚合图层添加到地图上,添加完毕之后,把状态置为已决议
|
||
return new Promise((resolve) => {
|
||
const doChunk = (chunk) => {
|
||
// 循环构造要素点位,并给每个要素点位绑定点击事件,添加弹窗
|
||
chunk.forEach((feature, index) => {
|
||
let icon = null
|
||
icon = createDefaultFeatureStyle(layerConfig)
|
||
restoreIconObj.restoreIcon = icon
|
||
if (feature.latLng.lng) {
|
||
const marker = L.marker(feature.latLng, { icon })
|
||
// 如果getLayerPopupInfo和createPopupFun不为null,则说明需要弹窗,否则不需要弹窗
|
||
// if (true) {
|
||
marker.uuid = feature.uuid
|
||
marker.layerConfigInfo = layerConfig
|
||
// 小型水库没有点击事件
|
||
// if (feature.size !== 0) {
|
||
marker.on('click', async(e) => {
|
||
console.log('图标点击e', e)
|
||
const uuid = e.sourceTarget.uuid
|
||
const type = layerConfig.resType
|
||
const layerConfigInfo = e.sourceTarget.layerConfigInfo
|
||
const latLng = L.latLng([e.latlng.lat, e.latlng.lng])
|
||
myGetLayerPopupInfo(
|
||
uuid,
|
||
layerConfigInfo,
|
||
type,
|
||
mapObj,
|
||
latLng,
|
||
createPopupFun,
|
||
getLayerPopupInfo,
|
||
layerConfigInfo.popupClassName
|
||
)
|
||
})
|
||
// }
|
||
// }
|
||
// 将该点位添加到聚合图层中
|
||
layers.addLayer(marker)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 当要素点位数据处理完成后,将聚合图层添加到layerGroup中,并将promise的状态置为已决议
|
||
const chunkCompleted = () => {
|
||
featureGroup.addLayer(layers)
|
||
layerGroup.set(layerConfig.superMapLayerName, layers)
|
||
resolve(1)
|
||
}
|
||
|
||
// 分块处理要素点位,当要素数量非常大时,不至于页面卡死
|
||
chunkData(features, doChunk, chunkCompleted)
|
||
})
|
||
}
|
||
/**
|
||
* 资源上图通用方法
|
||
* @param features 资源要素
|
||
* @param layerName 图层名称
|
||
* @param layerConfigInfo 图层配置信息
|
||
* @param isClusterLayer 是否是聚合图层
|
||
* @param getLayerPopupInfo 获取弹窗信息的函数
|
||
* @param layerClassName 聚合图层样式类名
|
||
* @param popupClassName 弹窗样式类名
|
||
* @param createPopupFun 生成弹窗的方法
|
||
* @param createDivIconFun 创建自定义图标的方法
|
||
* @param clickReplaceIcon 选中marker之后是否需要更换图标
|
||
* @param replaceIconUrl 选中marker之后要更换图标路径
|
||
* @param replaceIconSize 选中marker之后要更换图标尺寸
|
||
* @param mapObj
|
||
* @param featureGroup
|
||
* @param layerGroup
|
||
* @return {*}
|
||
* @private
|
||
*/
|
||
function addResourceOnMap({
|
||
features,
|
||
layerName,
|
||
layerConfigInfo,
|
||
isClusterLayer = '',
|
||
getLayerPopupInfo = null,
|
||
layerClassName = '',
|
||
popupClassName = '',
|
||
createPopupFun = null,
|
||
createDivIconFun = null,
|
||
clickReplaceIcon = '',
|
||
replaceIconUrl = '/src/supermap/image/poi.png',
|
||
replaceIconSize = [44, 44],
|
||
} = {},
|
||
mapObj,
|
||
featureGroup,
|
||
layerGroup
|
||
) {
|
||
// debugger;
|
||
console.log('上图数据', layerClassName)
|
||
// 如果资源要素数量为0,则说明该种资源没有记录
|
||
if (features.length < 1) {
|
||
return Promise.resolve(0)
|
||
}
|
||
|
||
// 创建图层
|
||
let layers = null
|
||
// 判断是否是聚合图层
|
||
layers = isClusterLayer ? createMarkerClusterLayer(layerClassName) : []
|
||
|
||
// 该promise用于将资源要素聚合图层添加到地图上,添加完毕之后,把状态置为已决议
|
||
return new Promise((resolve) => {
|
||
const doChunk = (chunk) => {
|
||
// 循环构造要素点位,并给每个要素点位绑定点击事件,添加弹窗
|
||
chunk.forEach((feature, index) => {
|
||
let icon = null
|
||
if (createDivIconFun !== null) {
|
||
const { iconSize, contentHTML, className } = createDivIconFun(
|
||
feature,
|
||
index
|
||
)
|
||
icon = L.divIcon({
|
||
iconSize: iconSize,
|
||
html: contentHTML,
|
||
className: className,
|
||
})
|
||
} else {
|
||
icon = createDefaultFeatureStyle(layerConfigInfo)
|
||
}
|
||
if (feature.size) {
|
||
switch (feature.size) {
|
||
case 0:
|
||
icon = createDefaultFeatureStyle({
|
||
img: 'reservoir_small.png',
|
||
})
|
||
break
|
||
case 1:
|
||
icon = createDefaultFeatureStyle({
|
||
img: 'reservoir_middle.png',
|
||
})
|
||
break
|
||
case 2:
|
||
icon = createDefaultFeatureStyle({
|
||
img: 'reservoir_big.png',
|
||
})
|
||
break
|
||
}
|
||
}
|
||
restoreIconObj.restoreIcon = icon
|
||
// 当前地图为百度09墨卡托坐标系,在此处进行坐标转换
|
||
// const bdLonLat = wgs84LL2bdLL(feature.latLng[1], feature.latLng[0]);
|
||
// feature.latLng[1] = bdLonLat[0];
|
||
// feature.latLng[0] = bdLonLat[1];
|
||
const marker = L.marker(feature.latLng, { icon })
|
||
// 如果getLayerPopupInfo和createPopupFun不为null,则说明需要弹窗,否则不需要弹窗
|
||
if (getLayerPopupInfo !== null && createPopupFun !== null) {
|
||
marker.resId = feature.resId
|
||
marker.layerConfigInfo = layerConfigInfo
|
||
marker.on('click', async(e) => {
|
||
console.log('图标点击e', e)
|
||
// 判断是否需要选中之后更换marker的图标
|
||
if (clickReplaceIcon) {
|
||
// 先把之前选中的图标切换回来
|
||
// const previousLayer = layerGroup.get(layerName).getLayer(restoreIconObj.layerId);
|
||
// if (previousLayer) {
|
||
// previousLayer.setIcon(icon);
|
||
// }
|
||
const layers = layerGroup.get(layerName).getLayers()
|
||
layers.forEach((layer) => {
|
||
layer.setIcon(icon)
|
||
})
|
||
restoreIconObj.layerId = e.sourceTarget._leaflet_id
|
||
const currentLayer = layerGroup
|
||
.get(layerName)
|
||
.getLayer(restoreIconObj.layerId)
|
||
restoreIconObj.currentLayer = currentLayer
|
||
if (currentLayer) {
|
||
currentLayer.setIcon(
|
||
L.icon({ iconUrl: replaceIconUrl, iconSize: replaceIconSize })
|
||
)
|
||
}
|
||
}
|
||
// 使用uuid获取弹窗详情并构造弹窗
|
||
const resId = e.sourceTarget.resId
|
||
let type = null
|
||
// 根据layerName1 传递不同的 resourceType
|
||
switch (e.sourceTarget.layerConfigInfo.layerName1) {
|
||
// 直升机起降点
|
||
case 'f_helicopter':
|
||
type = 'resourceHelicopter'
|
||
break
|
||
// 物资储备库
|
||
case 'f_repository':
|
||
type = 'resourceStorage'
|
||
break
|
||
// 应急队伍
|
||
case 'YJPT_SM_ARMY':
|
||
type = 'resourceTeam'
|
||
break
|
||
case 'f_team':
|
||
type = 'resourceTeam'
|
||
break
|
||
// 危险源
|
||
case 'YJPT_SM_HAZARD':
|
||
type = 'resourceDanger'
|
||
break
|
||
// 水源地
|
||
case 'f_water_source':
|
||
type = 'resourceProtection'
|
||
break
|
||
// 检查站
|
||
case 'f_check_station':
|
||
type = 'resourceProtection'
|
||
break
|
||
// 墓地
|
||
case 'f_cemetery':
|
||
type = 'resourceProtection'
|
||
break
|
||
// 瞭望塔
|
||
case 'f_watch_tower':
|
||
type = 'resourceProtection'
|
||
break
|
||
case 'YJPT_SM_SHELTER':
|
||
type = 'resourceShelter'
|
||
break
|
||
case 'YJPT_SM_STORAGE':
|
||
type = 'resourceStorage'
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
const layerConfigInfo = e.sourceTarget.layerConfigInfo
|
||
const latLng = L.latLng([e.latlng.lat, e.latlng.lng])
|
||
// debugger;
|
||
myGetLayerPopupInfo(
|
||
resId,
|
||
layerConfigInfo,
|
||
type,
|
||
mapObj,
|
||
latLng,
|
||
createPopupFun,
|
||
getLayerPopupInfo,
|
||
popupClassName
|
||
)
|
||
})
|
||
}
|
||
// 将该点位添加到聚合图层中
|
||
layers.addLayer(marker)
|
||
})
|
||
}
|
||
|
||
// 当要素点位数据处理完成后,将聚合图层添加到layerGroup中,并将promise的状态置为已决议
|
||
const chunkCompleted = () => {
|
||
console.log(featureGroup)
|
||
featureGroup.addLayer(layers)
|
||
layerGroup.set(layerName, layers)
|
||
resolve(1)
|
||
}
|
||
|
||
// 分块处理要素点位,当要素数量非常大时,不至于页面卡死
|
||
chunkData(features, doChunk, chunkCompleted)
|
||
})
|
||
}
|
||
// 根据类型返回具体用聚合图层的样式。
|
||
function typeToStyle(layerName) {
|
||
let returnStyle = null
|
||
const typeToImg = {
|
||
fireForest: 'multi-marker-cluster-resource-protection',
|
||
fireRoad: 'multi-marker-cluster-resource-protection',
|
||
fireBreak2: 'multi-marker-cluster-resource-protection',
|
||
fireBreak1: 'multi-marker-cluster-resource-protection',
|
||
|
||
fireWater4: 'multi-marker-cluster-resource-protection',
|
||
fireWater3: 'multi-marker-cluster-resource-protection',
|
||
fireWater5: 'multi-marker-cluster-resource-protection',
|
||
fireWater6: 'multi-marker-cluster-resource-protection',
|
||
|
||
airLine1: 'topic-marker-cluster-video',
|
||
airLine2: 'topic-marker-cluster-video',
|
||
airLine3: 'topic-marker-cluster-video',
|
||
|
||
fireMonitor7: 'topic-marker-cluster-video',
|
||
fireMonitor8: 'topic-marker-cluster-video',
|
||
fireMonitor9: 'topic-marker-cluster-video',
|
||
fireMonitor10: 'topic-marker-cluster-video',
|
||
|
||
fireRisk2: 'topic-marker-cluster-risk-area',
|
||
fireRisk3: 'topic-marker-cluster-risk-area',
|
||
fireRisk4: 'topic-marker-cluster-risk-area',
|
||
fireRisk1: 'topic-marker-cluster-risk-area',
|
||
|
||
fireTeam: 'topic-marker-cluster-team',
|
||
fireStorage: 'topic-marker-cluster-mine',
|
||
}
|
||
returnStyle = typeToImg[layerName]
|
||
if (typeof returnStyle === 'undefined') {
|
||
returnStyle = 'multi-marker-cluster-resource-protection'
|
||
}
|
||
return returnStyle
|
||
}
|
||
// 无聚合上图 =》阳性人员路径
|
||
function addResourceOnMapWithoutSuperMap(
|
||
features,
|
||
url,
|
||
lastOne,
|
||
createPopupFun,
|
||
DS,
|
||
featureGroup,
|
||
layerGroup,
|
||
map
|
||
) {
|
||
// 如果资源要素数量为0,则说明该种资源没有记录
|
||
// if (features.length < 1) {
|
||
// return Promise.resolve(0);
|
||
// }
|
||
// 根据类型返回具体用聚合图层的样式。
|
||
// const defaultStyle = typeToStyle(layerName)
|
||
// 创建图层
|
||
const layers = []
|
||
const numArr = [
|
||
'①',
|
||
'②',
|
||
'③',
|
||
'④',
|
||
'⑤',
|
||
'⑥',
|
||
'⑦',
|
||
'⑧',
|
||
'⑨',
|
||
'⑩',
|
||
'⑪',
|
||
'⑫',
|
||
'⑬',
|
||
'⑭',
|
||
'⑮',
|
||
'⑯',
|
||
'⑰',
|
||
'⑱',
|
||
'⑲',
|
||
'⑳',
|
||
'㉑',
|
||
'㉒',
|
||
'㉓',
|
||
'㉔',
|
||
'㉕',
|
||
'㉖',
|
||
'㉗',
|
||
'㉘',
|
||
'㉙',
|
||
'㉚',
|
||
'㉛',
|
||
'㉜',
|
||
'㉝',
|
||
'㉞',
|
||
'㉟',
|
||
'㊱',
|
||
'㊲',
|
||
'㊳',
|
||
'㊴',
|
||
'㊵',
|
||
'㊶',
|
||
'㊷',
|
||
'㊸',
|
||
'㊹',
|
||
'㊺',
|
||
'㊻',
|
||
'㊼',
|
||
'㊽',
|
||
'㊾',
|
||
'㊿',
|
||
]
|
||
// 判断是否是聚合图层
|
||
// layers = createMarkerClusterLayer(defaultStyle)
|
||
const icon = createDefaultFeatureStyle({
|
||
img: url || 'the-head.png',
|
||
iconSize: [36, 36],
|
||
})
|
||
const arr = []
|
||
features.map((feature, index) => {
|
||
// console.log("看看有没有坐标",feature.latLng);
|
||
if (feature.hasOwnProperty('latLng')) {
|
||
const marker = L.marker(feature.latLng, { icon })
|
||
// marker.zjmc = feature.zjmc
|
||
marker.bindTooltip(
|
||
'<p style="display:flex;align-items:center"><span style="color: red; font-size: 28px;font-weight: 700 margin-bottom: 2px">' +
|
||
numArr[index] +
|
||
'</span><span>' +
|
||
feature.traveladdress +
|
||
'(' +
|
||
feature.count +
|
||
'次)</span></p>', {
|
||
permanent: true,
|
||
}
|
||
)
|
||
L.tooltipLayout.resetMarker(marker)
|
||
if (createPopupFun !== null) {
|
||
marker.on('click', async(e) => {
|
||
const elementHtml = createPopupFun(feature)
|
||
if (elementHtml) {
|
||
L.popup({
|
||
className: 'epidemic-address',
|
||
keepInView: true,
|
||
maxHeight: 300,
|
||
})
|
||
.setLatLng(feature.latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(map)
|
||
}
|
||
})
|
||
}
|
||
layers.push(marker)
|
||
// 处理bounds数据
|
||
arr.push([feature.latLng.lat, feature.latLng.lng])
|
||
}
|
||
})
|
||
// 适配地图
|
||
var polyline = L.polyline(arr)
|
||
if (lastOne) {
|
||
// map.fitBounds(polyline.getBounds())
|
||
} else {
|
||
map.flyTo(features[features.length - 1].latLng, 8)
|
||
}
|
||
var myGroup = L.layerGroup(layers)
|
||
featureGroup.addLayer(myGroup)
|
||
// featureGroup.addLayer(layers)
|
||
// console.log('上图的layerName', layerName,layerGroup);
|
||
// L.layerGroup.addLayer(layers)
|
||
}
|
||
// 道路污染治理专题-点位上图
|
||
function addPointsToMap(
|
||
features,
|
||
url,
|
||
lastOne,
|
||
createPopupFun,
|
||
DS,
|
||
featureGroup,
|
||
layerGroup,
|
||
map
|
||
) {
|
||
// 如果资源要素数量为0,则说明该种资源没有记录
|
||
// if (features.length < 1) {
|
||
// return Promise.resolve(0);
|
||
// }
|
||
// 根据类型返回具体用聚合图层的样式。
|
||
// const defaultStyle = typeToStyle(layerName)
|
||
// 创建图层
|
||
const layers = []
|
||
// 判断是否是聚合图层
|
||
// layers = createMarkerClusterLayer(defaultStyle)
|
||
const icon = createDefaultFeatureStyle({
|
||
img: url || 'the-head.png',
|
||
iconSize: [36, 36],
|
||
})
|
||
const arr = []
|
||
features.map((feature, index) => {
|
||
// console.log("看看有没有坐标",feature.latLng);
|
||
if (feature.hasOwnProperty('latLng')) {
|
||
const marker = L.marker(feature.latLng, { icon })
|
||
// marker.zjmc = feature.zjmc
|
||
// marker.bindTooltip('<p style="display:flex;align-items:center"><span style="color: red; font-size: 28px;font-weight: 700 margin-bottom: 2px">' + index + '</span><span>' +
|
||
// feature.traveladdress + '(' + feature.count + '次)</span></p>'
|
||
// , {
|
||
// permanent: true
|
||
// })
|
||
// L.tooltipLayout.resetMarker(marker)
|
||
if (createPopupFun !== null) {
|
||
marker.on('click', async(e) => {
|
||
const elementHtml = createPopupFun(feature)
|
||
if (elementHtml) {
|
||
if (feature.type == 'road') {
|
||
L.popup({ className: 'roadGovernance-popup', keepInView: true })
|
||
.setLatLng(feature.latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(map)
|
||
} else {
|
||
L.popup({
|
||
className: 'epidemic-address',
|
||
keepInView: true,
|
||
maxHeight: 300,
|
||
})
|
||
.setLatLng(feature.latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(map)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
layers.push(marker)
|
||
// 处理bounds数据
|
||
arr.push([feature.latLng.lat, feature.latLng.lng])
|
||
}
|
||
})
|
||
// 适配地图
|
||
var polyline = L.polyline(arr)
|
||
if (lastOne) {
|
||
// map.fitBounds(polyline.getBounds())
|
||
} else {
|
||
map.flyTo(features[features.length - 1].latLng, 8)
|
||
}
|
||
var myGroup = L.layerGroup(layers)
|
||
featureGroup.addLayer(myGroup)
|
||
layerGroup.set(lastOne, myGroup)
|
||
// featureGroup.addLayer(layers)
|
||
// console.log('上图的layerName', layerName,layerGroup);
|
||
// L.layerGroup.addLayer(layers)
|
||
}
|
||
/**
|
||
* 资源上图通用方法 -> 不走超图服务
|
||
* @param features 资源要素
|
||
* @param layerName 图层名称
|
||
* @param layerConfigInfo 图层配置信息
|
||
* @param isClusterLayer 是否是聚合图层
|
||
* @param getLayerPopupInfo 获取弹窗信息的函数
|
||
* @param layerClassName 聚合图层样式类名
|
||
* @param popupClassName 弹窗样式类名
|
||
* @param createPopupFun 生成弹窗的方法
|
||
* @param createDivIconFun 创建自定义图标的方法
|
||
* @param clickReplaceIcon 选中marker之后是否需要更换图标
|
||
* @param replaceIconUrl 选中marker之后要更换图标路径
|
||
* @param replaceIconSize 选中marker之后要更换图标尺寸
|
||
* @param mapObj
|
||
* @param featureGroup
|
||
* @param layerGroup
|
||
* @return {*}
|
||
* @private
|
||
*/
|
||
function addResourceOnMapWithoutSuper({
|
||
features,
|
||
layerName,
|
||
layerConfigInfo,
|
||
isClusterLayer = '',
|
||
getLayerPopupInfo = null,
|
||
layerClassName = '',
|
||
popupClassName = '',
|
||
createPopupFun = null,
|
||
createDivIconFun = null,
|
||
clickReplaceIcon = '',
|
||
replaceIconUrl = '/src/supermap/image/poi.png',
|
||
replaceIconSize = [44, 44],
|
||
} = {},
|
||
mapObj,
|
||
featureGroup,
|
||
layerGroup
|
||
) {
|
||
console.log('features', features)
|
||
// 如果资源要素数量为0,则说明该种资源没有记录
|
||
if (features.length < 1) {
|
||
return Promise.resolve(0)
|
||
}
|
||
|
||
// 创建图层
|
||
let layers = null
|
||
// 判断是否是聚合图层
|
||
layers = isClusterLayer ? createMarkerClusterLayer(layerClassName) : []
|
||
|
||
// 该promise用于将资源要素聚合图层添加到地图上,添加完毕之后,把状态置为已决议
|
||
return new Promise((resolve) => {
|
||
const doChunk = (chunk) => {
|
||
// 循环构造要素点位,并给每个要素点位绑定点击事件,添加弹窗
|
||
chunk.forEach((feature, index) => {
|
||
let icon = null
|
||
// 水库大中小图标
|
||
if (feature.size) {
|
||
switch (feature.size) {
|
||
case 0:
|
||
layerConfigInfo.img = 'reservoir_small.png'
|
||
break
|
||
case 1:
|
||
layerConfigInfo.img = 'reservoir_middle.png'
|
||
break
|
||
case 2:
|
||
layerConfigInfo.img = 'reservoir_big.png'
|
||
break
|
||
}
|
||
}
|
||
if (createDivIconFun !== null) {
|
||
const { iconSize, contentHTML, className } = createDivIconFun(
|
||
feature,
|
||
index
|
||
)
|
||
icon = L.divIcon({
|
||
iconSize: iconSize,
|
||
html: contentHTML,
|
||
className: className,
|
||
})
|
||
} else {
|
||
icon = createDefaultFeatureStyle(layerConfigInfo)
|
||
}
|
||
restoreIconObj.restoreIcon = icon
|
||
// 当前地图为百度09墨卡托坐标系,在此处进行坐标转换
|
||
const bdLonLat = wgs84LL2bdLL(
|
||
feature.latLng[1] || feature.latLng.lng,
|
||
feature.latLng[0] || feature.latLng.lat
|
||
)
|
||
feature.latLng = []
|
||
feature.latLng[1] = bdLonLat[0]
|
||
feature.latLng[0] = bdLonLat[1]
|
||
// debugger;
|
||
const marker = L.marker(feature.latLng, { icon })
|
||
// 如果getLayerPopupInfo和createPopupFun不为null,则说明需要弹窗,否则不需要弹窗
|
||
if (getLayerPopupInfo !== null && createPopupFun !== null) {
|
||
marker.uuid = feature.uuid || ''
|
||
marker.resId = feature.resId || ''
|
||
marker.layerConfigInfo = layerConfigInfo
|
||
marker.on('click', async(e) => {
|
||
// 判断是否需要选中之后更换marker的图标
|
||
if (clickReplaceIcon) {
|
||
const layers = layerGroup.get(layerName).getLayers()
|
||
layers.forEach((layer) => {
|
||
layer.setIcon(icon)
|
||
})
|
||
restoreIconObj.layerId = e.sourceTarget._leaflet_id
|
||
const currentLayer = layerGroup
|
||
.get(layerName)
|
||
.getLayer(restoreIconObj.layerId)
|
||
restoreIconObj.currentLayer = currentLayer
|
||
if (currentLayer) {
|
||
currentLayer.setIcon(
|
||
L.icon({ iconUrl: replaceIconUrl, iconSize: replaceIconSize })
|
||
)
|
||
}
|
||
}
|
||
// 使用uuid获取弹窗详情并构造弹窗
|
||
const uuid = e.sourceTarget.uuid
|
||
const resId = e.sourceTarget.resId
|
||
let resourceType = null
|
||
// 根据layerName1 传递不同的 resourceType
|
||
switch (e.sourceTarget.layerConfigInfo.layerName1) {
|
||
// 避难场所
|
||
case 'wf_shelter':
|
||
resourceType = 'resourceShelter'
|
||
break
|
||
// 应急物资
|
||
case 'wf_storage':
|
||
resourceType = 'resourceStorage'
|
||
break
|
||
// 应急队伍
|
||
case 'wf_team':
|
||
resourceType = 'resourceTeam'
|
||
break
|
||
// 危险源
|
||
case 'wf_danger':
|
||
resourceType = 'resourceDanger'
|
||
break
|
||
case 'wf_protection':
|
||
resourceType = 'resourceProtection'
|
||
break
|
||
default:
|
||
resourceType =
|
||
e.sourceTarget.layerConfigInfo.resourceType ||
|
||
'resourceProtection'
|
||
break
|
||
}
|
||
|
||
const latLng = L.latLng([e.latlng.lat, e.latlng.lng])
|
||
const response = await getLayerPopupInfo(
|
||
uuid,
|
||
layerConfigInfo,
|
||
resourceType,
|
||
resId
|
||
)
|
||
response.allMapObject = {
|
||
mapObj: mapObj,
|
||
}
|
||
response.layerConfigInfo = layerConfigInfo
|
||
console.log(response)
|
||
const elementHtml = createPopupFun(response)
|
||
if (elementHtml) {
|
||
L.popup({ className: popupClassName })
|
||
.setLatLng(latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(mapObj.map)
|
||
}
|
||
})
|
||
}
|
||
// 将该点位添加到聚合图层中
|
||
layers.addLayer(marker)
|
||
// marker.addTo(mapObj.map);
|
||
})
|
||
}
|
||
|
||
// 当要素点位数据处理完成后,将聚合图层添加到layerGroup中,并将promise的状态置为已决议
|
||
const chunkCompleted = () => {
|
||
// debugger;
|
||
featureGroup.addLayer(layers)
|
||
layerGroup.set(layerName, layers)
|
||
resolve(1)
|
||
}
|
||
|
||
// 分块处理要素点位,当要素数量非常大时,不至于页面卡死
|
||
chunkData(features, doChunk, chunkCompleted)
|
||
})
|
||
}
|
||
async function myGetLayerPopupInfo(
|
||
resId,
|
||
layerConfigInfo,
|
||
type,
|
||
mapObj,
|
||
latLng,
|
||
createPopupFun,
|
||
getLayerPopupInfo,
|
||
popupClassName
|
||
) {
|
||
const response = await getLayerPopupInfo(resId, layerConfigInfo, type)
|
||
// debugger;
|
||
console.log(response)
|
||
if (!response) return
|
||
response.allMapObject = {
|
||
mapObj: mapObj,
|
||
}
|
||
const elementHtml = createPopupFun(response)
|
||
L.popup({ className: popupClassName })
|
||
.setLatLng(latLng)
|
||
.setContent(elementHtml)
|
||
.openOn(mapObj.map)
|
||
}
|
||
export {
|
||
// 复原的图标
|
||
restoreIconObj,
|
||
// 添加单个点位到地图上
|
||
addPointOnMap,
|
||
// 使用uuid集合去超图服务查询资源要素,得到结果就把promise状态置为已决议,并返回features
|
||
createPromiseByQueryService,
|
||
// 资源上图通用方法
|
||
addResourceOnMap,
|
||
// 创建聚合图层
|
||
createMarkerClusterLayer,
|
||
// 创建资源弹窗
|
||
myGetLayerPopupInfo,
|
||
// 头顶库临时
|
||
addResourceOnMapWithoutSuperMap,
|
||
addResourceOnMapWithoutSuper,
|
||
addResourceOnMapNew,
|
||
addPointsToMap,
|
||
}
|