百度地图--3D棱柱效果---省边界数据抽取---Boundary、Point、Prism

本文介绍了如何使用百度地图API创建3D棱柱效果来展示省级行政区域,但原始代码在处理大量边界数据时性能不佳。作者提出了一种优化方案,通过根据地图缩放级别(zoom)抽取出关键点,减少点的数量,同时保持3D效果。通过计算点与点之间的距离并设定阈值,过滤掉多余点,从而提高性能。这种方法适用于需要在地图上展示多个省级行政区域3D效果的场景。
摘要由CSDN通过智能技术生成

3D棱柱效果

在这里插入图片描述

上代码

 
    var map = new BMapGL.Map("allmap");
    var point = new BMapGL.Point(116.404, 39.925);
    map.centerAndZoom(point, 10);
    map.setTilt(50);
    map.enableScrollWheelZoom();
    var bd = new BMapGL.Boundary();
    bd.get('北京市', function (rs) {
        var count = rs.boundaries.length; //行政区域的点有多少个
        var pointArray = [];
        for (var i = 0; i < count; i++) {
            var path = [];
            str = rs.boundaries[i].replace(' ', '');
            points = str.split(';');
            for (var j = 0; j < points.length; j++) {
                var lng = points[j].split(',')[0];
                var lat = points[j].split(',')[1];
                path.push(new BMapGL.Point(lng, lat));
            }
            var prism = new BMapGL.Prism(path, 5000, {
                topFillColor: '#5679ea',
                topFillOpacity: 0.5,
                sideFillColor: '#5679ea',
                sideFillOpacity: 0.9

            });
            map.addOverlay(prism);
        }
    });

这段代码是 百度地图文档-3D棱柱 的教程,好多人可能好奇,既然有教程,直接粘贴复制不就好了,为什么还要写这篇文章呢?

那是因为,上边的代码确实可以实现我们的想要的3D效果,但是如果你想让34个省级行政区域,都这样显示,那性能上就有点不友好了,要知道每个省的boundaries数据,可是非常非常多。所以这篇文章主要是为了解决边界数据进行抽取

中国34个省级行政区域

// 我国共有34个省级行政区域,包括23个省,5个自治区,4个直辖市,2个特别行政区
// 4个直辖市 北京市、重庆市、上海市、天津市
// 5个自治区:内蒙古自治区、广西壮族自治区、西藏自治区、新疆维吾尔自治区、宁夏回族自治区
// 2个特别行政区:澳门特别行政区、香港特别行政区
// 23个省 : 河北省(冀)、山东省(齐)、辽宁省(辽)、黑龙江省(黑)、甘肃省(陇)、吉林省(吉)、青海省(青)、河南省(豫)、江苏省(苏)、湖北省(鄂)、湖南省(湘)、浙江省(浙)、江西省(赣)、广东省(粤)、云南省(滇)、福建省(福)、台湾省(台)、海南省(琼)、山西省(晋)、四川省(川)、陕西省(陕)、贵州省(黔)、安徽省(皖)

创建过程

这里有个概念需要说一下,想实现3D效果主要需要以下3个点

setTilt:地图倾斜角度(一般设置40-70,这样可以看到棱柱的侧边,出现3d效果)
Point:指定的经度和纬度创建一个地理点坐标
Prism:创建棱柱覆盖物

整体过程:

通过 省名称获取管辖下所有城市经纬度,然后遍历每个lng/lat,创建对应的Point,将所有的Point储存到数组内,当参数传入Prism,最后 addOverlay注入到地图上

在这里插入图片描述
在这里插入图片描述

优化思路

通过上边的描述,我们可以知道Point是点,Prism是覆盖物,setTilt是倾斜的角度。

那么是否可以通过既减少Point,又能实现3D效果呢?

// 百度地图API功能
    var map = new BMapGL.Map("allmap");
    var point = new BMapGL.Point(116.404, 39.925);
    map.centerAndZoom(point, 10);
    map.setTilt(50);
    map.enableScrollWheelZoom();
	var str='116.06028395672872,40.456532235828135;115.93135041154004,39.694265742564866;117.23750328236457,39.5034425351181;117.40567747174113,40.36225554457048';
    
    var path=[];
  
     var points = str.split(';');
     for (var j = 0; j < points.length; j++) {
         var lng = points[j].split(',')[0];
         var lat = points[j].split(',')[1];
       
         path.push(new BMapGL.Point(lng, lat));
     }
     var prism = new BMapGL.Prism(path, 5000, {
         topFillColor: '#5679ea',
         topFillOpacity: 0.5,
         sideFillColor: '#5679ea',
         sideFillOpacity: 0.9

     });
     map.addOverlay(prism);

效果

在这里插入图片描述

地图换算比例

说道这里,大家应该已经知道我的思路了,上边我说了所有城市经纬度boundaries数据,可是非常非常多,地图放大、缩小是有zoom级别的,我们肯定不需要在地图放大到最大状态下省边界数据,那么我能根据自己想放大的级别,做一下数据抽取就好了

'zoom6': 200000,
'zoom7': 100000,
'zoom8': 50000,
'zoom9': 25000,
'zoom10': 20000,
'zoom11': 10000,
'zoom12': 5000,
'zoom13': 2000,
'zoom14': 1000,
'zoom15': 500,
'zoom16': 200,
'zoom17': 100,
'zoom18': 50,
'zoom19': 20

动手优化

我们根据地图不同zoom级别下的换算比例,计算点与点的距离getDistance,如果小于xxx距离,我们就不在排除该经纬度,这样我们就可以抽取到缩减后的经纬度,效果是一样的!!!

export default {
   data () {
     return {
       mapv_point:{},
       zoomObj: {
        'zoom6': 200000,
        'zoom7': 100000,
        'zoom8': 50000,
        'zoom9': 25000,
        'zoom10': 20000,
        'zoom11': 10000,
        'zoom12': 5000,
        'zoom13': 2000,
        'zoom14': 1000,
        'zoom15': 500,
        'zoom16': 200,
        'zoom17': 100,
        'zoom18': 50,
        'zoom19': 20
      },
      zoom :6
     }
   },
	mounted (){
	
		this.map_boundary_fn('北京',this.zoom)
	},
	methods: {
		map_boundary_fn (name,id) {
		  var bd= new BMapGL.Boundary()
		
		  var _this = this
		
		  bd.get(name, async function (rs) {
		    // 行政区域的点有多少个
		    var count = rs.boundaries.length 
		
		    console.log(name, count, '-----------城市')
		    
		    for (var i = 0; i < count; i++) {
		      var path = []
		      var str = rs.boundaries[i].replace(' ', '')
		      var points = str.split(';')
		
		      for (var j = 0; j < points.length; j++) {
		        var lng = points[j].split(',')[0]
		        var lat = points[j].split(',')[1]
		
		        const obj = await _this.mapv_point_fn({ lng, lat }, points, j)
		
		        j = obj.ind
		
		        path.push({ lng, lat })
		      }
		      _this.mapv_point['city' + id].arr.push(path)
		    }
		  })
		},
		mapv_point_fn (start, arr, ind) {
		  return new Promise((resolve, reject) => {
		    for (var i = ind; i < arr.length; i++) {
		      const obj = arr[i].split(',')
		      var pointA = new BMapGL.Point(start.lng, start.lat) // 创建点坐标A
		      var pointB = new BMapGL.Point(obj[0], obj[1]) // 创建点坐标B
		     
		      var distance = this.map.getDistance(pointA, pointB).toFixed(1) * 1 // 获取两点距离,保留小数点后两位
		
		      if (distance > this.zoomObj['zoom' + this.zoom] / 100) {
		        resolve({
		          start,
		          end: { lng: obj[0], lat: obj[1] },
		          ind: i
		        })
		
		        i = arr.length + 1
		      } else if (i == arr.length - 1) {
		        console.log('-------结束了')
		        resolve({
		          start,
		          end: { lng: obj[0], lat: obj[1] },
		          ind: i
		        })
		      }
		    }
		  })
		}
	}
}

到这里就基本完成了,如果小伙伴们有不清楚、不同建议的地方,欢迎评论区留言~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值