区块链技术博客
www.b2bchain.cn

MapboxGL添加三维柱状图效果

这篇文章主要介绍了MapboxGL添加三维柱状图效果的讲解,通过具体代码实例进行16301 讲解,并且分析了MapboxGL添加三维柱状图效果的详细步骤与相关技巧,需要的朋友可以参考下https://www.b2bchain.cn/?p=16301

本文实例讲述了2、树莓派设置连接WiFi,开启VNC等等的讲解。分享给大家供大家参考文章查询地址https://www.b2bchain.cn/7039.html。具体如下:

MapboxGL添加三维柱状图效果

  • 效果
    • 准备
    • 页面添加图层
    • 点数据转换矩形面数据
    • 加载三维柱形图层
    • 加入事件和气泡
    • 还有一个小问题
    • 下载

效果

MapboxGL添加三维柱状图效果

准备

我们这里只以html+jQuery+css纯demo写法展示如何叠加三维柱状图图层效果!
我们需要mapboxGL的js、css和jQuery.js

    <script type="text/javascript" src="jquery.min.js"></script>     <script type="text/javascript" src="mapbox-gl.min.js"></script>     <link type="text/css" rel="stylesheet" href="mapbox-gl.min.css"> 

还有自己定义的js文件

	 <script type="text/javascript" src="decklayer.js"></script> 	 <script type="text/javascript"> 	     styleLoad(); 	 </script> 

页面添加图层

定义好map容器后在js里将地图添加到容器中

    <div id="map"></div> 
 	var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326";     var map, popup;     var attribution = "3Dbar-demo";      map = new mapboxgl.Map({         container: 'map',         style: {             "version": 8,             "sources": {                 "raster-tiles": {                     "attribution": attribution,                     "type": "raster",                     "tiles": [url + '/zxyTileImage.png?z={z}&x={x}&y={y}'],                     "tileSize": 256,                 },             },             "layers": [{                 "id": "simple-tiles",                 "type": "raster",                 "source": "raster-tiles",                 "minzoom": 0,                 "maxzoom": 22             }]         },         center: [104.038567,30.650149],         zoom: 13,         pitch: 40,         bearing: 0     });     map.addControl(new mapboxgl.NavigationControl(), 'top-left'); 

点数据转换矩形面数据

我的数据集是geojson点数据集格式

  	/**      * 初始化数据      */     var geometry = {         "features":[             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 1,                     "name": "entity1",                     "height": 100,                     "smx":104.038679,                     "smy":30.650071                 }             },             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 2,                     "name": "entity2",                     "height": 500,                     "smx":104.036025,                     "smy":30.640793                 }             },             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 3,                     "name": "entity3",                     "height": 300,                     "smx":104.072101,                     "smy":30.639628                 }             },             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 4,                     "name": "entity4",                     "height": 700,                     "smx":104.071181,                     "smy":30.664718                 }             },             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 5,                     "name": "entity5",                     "height": 1000,                     "smx":104.091878,                     "smy":30.680124                 }             },             {                 "geometry":{                     "coordinates":[                         []                     ],                     "type":"Polygon"                 },                 "type":"Feature",                 "properties":{                     "id": 6,                     "name": "entity6",                     "height": 200,                     "smx":104.099927,                     "smy":30.659747                 }             }         ],         "type":"FeatureCollection"     }; 

如果你的柱状图采用的是点数据集,(面数据集可以忽略此步骤)那么你得定义一个转换数据集的方式

 	/**      * 根据点数据生成矩形面数据      * @param {点数据对象} properties object      * @param {偏移量} offset number      */     function createSquaredByPoint(properties,offset){         var smx = properties.smx;         var smy = properties.smy;         var offset_int = parseFloat(offset);         return [[smx,smy],[smx,smy + offset_int],[smx - offset_int,smy + offset_int],[smx - offset_int,smy],[smx,smy]];     } 

其中,偏移量(offset)代表你希望你的面数据矩形在地图上有多宽。
然后用上面的方式,将点数据集转换成面数据集:

     /**      * 生成面数据      * @param {原始geometry数据} feature       * @param {高度加权值} weight       * @param {宽度加权值} breadth       */     function getGeometry(feature,weight,breadth){         feature.features.forEach(item => {             if (item.geometry && item.geometry.coordinates) {                 item.geometry.coordinates[0] = createSquaredByPoint(item.properties,breadth);                 item.properties.height = item.properties.height * weight;             } else {                 console.log("item.geometry.coordinates 不存在");             }                      })         console.log(feature);     } 

加载三维柱形图层

有了面数据集,那我们直接用mapbox的 拉面图层 fill-extrusion 拉起面数据集

		// 这里我们高度加权值为5倍,宽度加权值为0.0025经纬度(大约为经度0.21km-纬度0.27km)  		getGeometry(feature,5,0.0025);         var BoxMap = map;          if(BoxMap.getLayer('entity_layer')){             BoxMap.removeLayer('entity_layer');         };         if(BoxMap.getLayer('entity_borders')){             BoxMap.removeLayer('entity_borders');         };          feature.features.forEach(item => {             let he = 0;           if (item.properties.height === "" || item.properties.height == 0) {             he = 5;   //默认高度         }else {             he = item.properties.height;         }         //属性数据         item.properties.id = parseInt(item.properties.id);         item.properties.height = parseInt(he);         });          if(BoxMap.getSource("states")){             BoxMap.getSource("states").setData(feature)         }else{             BoxMap.addSource("states", {                 "type": "geojson",                 "data": feature             });         }          BoxMap.addLayer({             'id': 'entity_layer',             'source': 'states',             'type': 'fill-extrusion',             'layout': {},             'minzoom': 2,       //最小可见级别             'paint': {                 //设置主体默认颜色                 'fill-extrusion-color': [                     "interpolate",                     ["exponential",1],                     ["get", "height"],                     //分类颜色设置(必须按顺序)                     500,                     '#d6debf',                     1000,                     '#aecea1',                     1500,                     '#82bb92',                     2500,                     '#49838a',                     3500,                     '#383c65',                     5000,                     '#2b1e3d'                 ],                 'fill-extrusion-height': [                     "interpolate", ["linear"], ["zoom"],4, 0,14.05, ["get", "height"]                                     ],                 'fill-extrusion-base': [                     "interpolate", ["linear"], ["zoom"],4, 0,14.05, ["get", "base_height"]                 ],                 'fill-extrusion-opacity': .8         //透明度             }         });  		//添加一个鼠标点击变色的同数据图层(这个默认隐藏)         BoxMap.addLayer({             'id': 'entity_borders',             'source': 'states',             'type': 'fill-extrusion',             'layout': {},             'minzoom': 2,         //最小可见级别             'paint': {                 'fill-extrusion-color': '#b8c9dd',                 'fill-extrusion-height': ['get', 'height'],                 'fill-extrusion-base': ['get', 'base_height'],                 'fill-extrusion-opacity': 0.7       //图层透明度             },             "filter": ["in", "id", ""]         }); 

加入事件和气泡

 		let popups = new mapboxgl.Popup({closeButton: false,closeOnClick: false});          BoxMap.on("mousemove", "entity_layer", function(e) {             BoxMap.getCanvas().style.cursor = 'pointer';             let feature = e.features[0];                  let relatedFeatures = BoxMap.querySourceFeatures('states', {               filter: ['in', 'id', feature.properties.id]             });                  let filter = relatedFeatures.reduce(function(memo, feature) {               memo.push(feature.properties.id);               return memo;             }, ['in', 'id']);                  BoxMap.setFilter("entity_borders", filter);                  //气泡信息(自定义html样式)             let html =                "<h2 style='color: white'> 主键:<a style='color: orange'>"+feature.properties.id+"</a> </h2>" +               "<h2 style='color: white'> 名称:<a style='color: orange'>" +  feature.properties.name + "</a></h2>" +               "<h2 style='color: white'> 数量:<a style='color: orange'>" +  feature.properties.height + " 米</a></h2>";                  popups.setLngLat([feature.properties.smx, feature.properties.smy])               .setHTML(html)               .addTo(BoxMap);                });            BoxMap.on("mouseleave", "entity_layer", function() {             BoxMap.getCanvas().style.cursor = '';             BoxMap.setFilter('entity_borders', ['in', 'id', '']);             popups.remove();                }); 

还有一个小问题

我们发现,每次页面刷新的时候地图style并不是马上就加载完成,但是此图层需要等到style加载完成后才能显示出来,不然会报style not loaded错误!所有我们需要一个监听(递归)图层样式加载完成方法,等style加载完成后再来加载图层!

     /**      * 等mapbox.style加载完再执行添加图层      */     function styleLoad(){         setTimeout(function(){             if (map.isStyleLoaded()) {                 addLayer(geometry);             } else {                 console.log("wait...");                 styleLoad();             }         },1000)     } 

下载

demo地址

本文转自互联网,侵权联系删除MapboxGL添加三维柱状图效果

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » MapboxGL添加三维柱状图效果
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们