自定义图标
const url = './static/assets/symbols/code24x24/VIDEO.png'
map.loadImage(url ,(error, image) => {if (error) throw errormap.addImage('video-icon', image)
})
function getStyleImage(fileName: any) {return new URL('/json/style/' + fileName + '.png', import.meta.url).href;
}fetch(new URL('/json/style/' + fileName + '.json', import.meta.url).href).then(response => response.json()).then(spriteJson => {var img = new Image()img.crossOrigin = 'anonymous'img.src = getStyleImage(spriteName)img.onload = function () {Object.keys(spriteJson).forEach((key: any) => {let spriteItem = spriteJson[key]let { X, Y, Width, Height } = spriteItemlet canvas = createCavans(Width, Height)let context: any = canvas.getContext('2d') || ''context.drawImage(img, X, Y, Width, Height, 0, 0, Width, Height)map.addImage(key, canvas.toDataURL('image/png'))})console.log(spriteName, '完成加载...')}
});
vue2.0中自定义弹窗(核心代码)
样式文件
// 地图弹窗
.mapbox-msgBox {position: relative;border: 0;font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB','Microsoft YaHei', '微软雅黑', Arial, sans-serif;// 弹窗内容.mapboxgl-popup-content {padding: 0 !important;}// 弹窗标题h2 {width: 100%;height: 40px !important;line-height: 40px !important;font-size: 18px !important;color: #fff;background: #0057a7;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 0 15px;border-top-left-radius: 4px;border-top-right-radius: 4px;}// 关闭按钮.mapboxgl-popup-close-button {height: 40px;font-size: 3em;padding: 0 5px;color: white;cursor: pointer;&:hover {color: #aaaaaa;}}
}
vue文件
<template><div><h2>{{ title }}</h2></div>
</template>
<script>export default {name: 'popTemplate',components: {},props: ['attrs', 'title'],data() {return {}},mounted() {console.log('props:', this.attrs)},methods: {callback(attrs) {this.$emit('callback', attrs)}
}
</script>
实现代码
const location = [110,30]
const mapboxPopup = new mapboxgl.Popup({closeButton: true,closeOnClick: false,className: 'mapbox-msgBox',maxWidth: '450px',offset: [0, 0]})
const popDetail = Vue.extend(popTemplate)
const vm = new popDetail({propsData: {title,attrs},methods: {callback(config) {console.log('🚀 ~ callback ~ config:', config)}}})vm.$mount() mapboxPopupLayer.setLngLat(location).setDOMContent(vm.$el).addTo(map)
创建自定义标签(核心代码)
定义样式为扩散圆
.mapbox-marker span[class^='pulse'] {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);width: 8px;height: 8px;box-shadow: 0 0 5px #ff0000;border-radius: 50%;animation: pulse 3s linear infinite;
}.mapbox-marker .pulse1 {animation-delay: 0s !important;
}.mapbox-marker .pulse2 {animation-delay: 1s !important;
}.mapbox-marker .pulse3 {animation-delay: 2s !important;
}@keyframes pulse {0% {width: 8px;height: 8px;}40% {width: 40px;height: 40px;opamapbox-marker: 1;}100% {width: 70px;height: 70px;opamapbox-marker: 0;}
}
实现代码
const location = [110,30]const el = document.createElement('div')el.className = 'mapbox-marker'const el1 = document.createElement('span')el1.className = 'pulse1'el.appendChild(el1)const el2 = document.createElement('span')el2.className = 'pulse2'el1.appendChild(el2)const el3 = document.createElement('span')el3.className = 'pulse3'el1.appendChild(el3)const currentMarker = new mapboxgl.Marker(el).setLngLat(location).addTo(map)map.setCenter(location)map.flyTo({center: location,zoom: 18,speed: 1, curve: 1, easing: function (t) {return t} })setTimeout(() => {if (currentMarker) {currentMarker.remove()}}, 5000)
聚合图层
// 添加数据源
map.addSource('videoLayer', {type: 'geojson',data: {type: 'FeatureCollection',features: videoListFeatures},cluster: true,clusterMaxZoom: 14, // 最大缩放级别,超过该级别不再聚合clusterRadius: 50 // 聚合半径,单位为像素
})// 添加聚合图层
map.addLayer({id: 'videoLayer-cluster',type: 'circle',source: 'videoLayer',filter: ['has', 'point_count'],paint: {'circle-color': ['step',['get', 'point_count'],'#51bbd6',100,'#f1f075',750,'#f28cb1'],'circle-radius': ['step',['get', 'point_count'],20,100,30,750,40]}
})// 添加聚合点计数图层
map.addLayer({id: 'videoLayer-cluster-count',type: 'symbol',source: 'videoLayer',filter: ['has', 'point_count'],layout: {'text-field': ['get', 'point_count_abbreviated'],'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],'text-size': 12}
})// 添加非聚合点图层
map.addLayer({id: 'videoLayer-unclustered-point',source: 'videoLayer',filter: ['!', ['has', 'point_count']],type: 'symbol',layout: {'icon-image': 'video-icon','icon-size': 1}
})
分类渲染降雨等值面事例
map.addLayer({id: 'grid_line',type: 'fill',source: {type: 'geojson',data: { type: 'FeatureCollection', features }},paint: {'fill-opacity': 1,'fill-outline-color': 'rgba(255, 255, 255, 0)','fill-color': ['step',['get', 'rain'],'rgba(255, 255, 255, 0)', 0.000001,'rgb(165, 243, 141)', 0.25,'rgb(61, 185, 63)', 0.5,'rgb(99, 184, 249)', 1,'rgb(0, 0, 254)', 2.5,'rgb(243, 5, 238)', 7.5,'rgb(129, 0, 64)' ]}
})