概述

本文分享如何通过mapboxGL实现三维的室内地图的展示。

效果

实现

1. 数据

精确的数需要通过CAD转换,本文为简单演示,是通过qgis中绘制的,数据主要包括如下字段:

{ "id": 1, "name": "type1","floor": 1, "type": "1" }

其中:

  • floor为楼层数据,建议为数字,方便排序;
  • type为类型,为商户的类型,通过type渲染不同的颜色;文中为了展示楼层地面,加了一个特殊的类型999,;
    示例中用的完整数据如下:
{"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "id": 1, "name": "type1","floor": 1, "type": "1" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.88576766738845, 22.55132808900947 ], [ 113.88689629860265, 22.55132808900947 ], [ 113.888041775058838, 22.550081541101257 ], [ 113.887629066629771, 22.549550915978166 ], [ 113.887283739168709, 22.549525648115164 ], [ 113.886070881744502, 22.549727791019198 ], [ 113.885708709041452, 22.550089963722261 ], [ 113.88576766738845, 22.55132808900947 ] ] ] } },
{ "type": "Feature", "properties": { "id": 2, "name": "type3","floor": 1, "type": "3" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.888269185825877, 22.550536362635334 ], [ 113.888134423889866, 22.550511094772332 ], [ 113.887805941670806, 22.550789041265379 ], [ 113.887014215296674, 22.55160603550252 ], [ 113.886129840091513, 22.551597612881515 ], [ 113.885936119808491, 22.551841868890559 ], [ 113.885986655534495, 22.552692553611703 ], [ 113.886331982995557, 22.552540946433677 ], [ 113.887090018885687, 22.552321958287639 ], [ 113.887511149935747, 22.551892404616567 ], [ 113.887991239332834, 22.551437583082489 ], [ 113.888505019213923, 22.550949071064405 ], [ 113.888715584738961, 22.550957493685406 ], [ 113.888724007359954, 22.55067954719236 ], [ 113.8883871025199, 22.550452136425321 ], [ 113.888269185825877, 22.550536362635334 ] ] ] } },
{ "type": "Feature", "properties": { "id": 3, "name": "type2","floor": 1, "type": "2" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.886171953196524, 22.55290311913674 ], [ 113.887014215296674, 22.553736958615882 ], [ 113.887300584410724, 22.553602196679858 ], [ 113.887595376145768, 22.55366115502687 ], [ 113.889541001597095, 22.551791333164548 ], [ 113.889322013451064, 22.551504964050501 ], [ 113.88943150752408, 22.551353356872475 ], [ 113.889119870547034, 22.551142791347438 ], [ 113.888841924053978, 22.551125946105437 ], [ 113.887704870218784, 22.552246154698626 ], [ 113.887755405944802, 22.552473565465665 ], [ 113.887477459451745, 22.552642017885695 ], [ 113.886972102191663, 22.552515678570675 ], [ 113.886281447269539, 22.552768357200716 ], [ 113.886171953196524, 22.55290311913674 ] ] ] } },
{ "type": "Feature", "properties": { "id": 4, "name": "type3","floor": 2, "type": "3"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.88576766738845, 22.55132808900947 ], [ 113.88689629860265, 22.55132808900947 ], [ 113.888041775058838, 22.550081541101257 ], [ 113.887629066629771, 22.549550915978166 ], [ 113.887283739168709, 22.549525648115164 ], [ 113.886070881744502, 22.549727791019198 ], [ 113.885708709041452, 22.550089963722261 ], [ 113.88576766738845, 22.55132808900947 ] ] ] } },
{ "type": "Feature", "properties": { "id": 5, "name": "type2","floor": 2, "type": "2"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.888269185825877, 22.550536362635334 ], [ 113.888134423889866, 22.550511094772332 ], [ 113.887805941670806, 22.550789041265379 ], [ 113.887014215296674, 22.55160603550252 ], [ 113.886129840091513, 22.551597612881515 ], [ 113.885936119808491, 22.551841868890559 ], [ 113.885986655534495, 22.552692553611703 ], [ 113.886331982995557, 22.552540946433677 ], [ 113.887090018885687, 22.552321958287639 ], [ 113.887511149935747, 22.551892404616567 ], [ 113.887991239332834, 22.551437583082489 ], [ 113.888505019213923, 22.550949071064405 ], [ 113.888715584738961, 22.550957493685406 ], [ 113.888724007359954, 22.55067954719236 ], [ 113.8883871025199, 22.550452136425321 ], [ 113.888269185825877, 22.550536362635334 ] ] ] } },
{ "type": "Feature", "properties": { "id": 6, "name": "type1","floor": 2, "type": "1"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.886171953196524, 22.55290311913674 ], [ 113.887014215296674, 22.553736958615882 ], [ 113.887300584410724, 22.553602196679858 ], [ 113.887595376145768, 22.55366115502687 ], [ 113.889541001597095, 22.551791333164548 ], [ 113.889322013451064, 22.551504964050501 ], [ 113.88943150752408, 22.551353356872475 ], [ 113.889119870547034, 22.551142791347438 ], [ 113.888841924053978, 22.551125946105437 ], [ 113.887704870218784, 22.552246154698626 ], [ 113.887755405944802, 22.552473565465665 ], [ 113.887477459451745, 22.552642017885695 ], [ 113.886972102191663, 22.552515678570675 ], [ 113.886281447269539, 22.552768357200716 ], [ 113.886171953196524, 22.55290311913674 ] ] ] } },
{ "type": "Feature", "properties": { "id": 7, "name": "type2","floor": 3, "type": "2"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.88576766738845, 22.55132808900947 ], [ 113.88689629860265, 22.55132808900947 ], [ 113.888041775058838, 22.550081541101257 ], [ 113.887629066629771, 22.549550915978166 ], [ 113.887283739168709, 22.549525648115164 ], [ 113.886070881744502, 22.549727791019198 ], [ 113.885708709041452, 22.550089963722261 ], [ 113.88576766738845, 22.55132808900947 ] ] ] } },
{ "type": "Feature", "properties": { "id": 8, "name": "type3","floor": 3, "type": "3"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.888269185825877, 22.550536362635334 ], [ 113.888134423889866, 22.550511094772332 ], [ 113.887805941670806, 22.550789041265379 ], [ 113.887014215296674, 22.55160603550252 ], [ 113.886129840091513, 22.551597612881515 ], [ 113.885936119808491, 22.551841868890559 ], [ 113.885986655534495, 22.552692553611703 ], [ 113.886331982995557, 22.552540946433677 ], [ 113.887090018885687, 22.552321958287639 ], [ 113.887511149935747, 22.551892404616567 ], [ 113.887991239332834, 22.551437583082489 ], [ 113.888505019213923, 22.550949071064405 ], [ 113.888715584738961, 22.550957493685406 ], [ 113.888724007359954, 22.55067954719236 ], [ 113.8883871025199, 22.550452136425321 ], [ 113.888269185825877, 22.550536362635334 ] ] ] } },
{ "type": "Feature", "properties": { "id": 9, "name": "type1","floor": 3, "type": "1"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.886171953196524, 22.55290311913674 ], [ 113.887014215296674, 22.553736958615882 ], [ 113.887300584410724, 22.553602196679858 ], [ 113.887595376145768, 22.55366115502687 ], [ 113.889541001597095, 22.551791333164548 ], [ 113.889322013451064, 22.551504964050501 ], [ 113.88943150752408, 22.551353356872475 ], [ 113.889119870547034, 22.551142791347438 ], [ 113.888841924053978, 22.551125946105437 ], [ 113.887704870218784, 22.552246154698626 ], [ 113.887755405944802, 22.552473565465665 ], [ 113.887477459451745, 22.552642017885695 ], [ 113.886972102191663, 22.552515678570675 ], [ 113.886281447269539, 22.552768357200716 ], [ 113.886171953196524, 22.55290311913674 ] ] ] } },
{ "type": "Feature", "properties": { "id": 10, "name": "","floor": 1, "type": "999"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.885632905452397, 22.552818892926712 ], [ 113.885771878698918, 22.553046303693751 ], [ 113.886302503822009, 22.553484279985827 ], [ 113.887106864127674, 22.554212836702447 ], [ 113.887443768967728, 22.554246527186454 ], [ 113.888075465542826, 22.55364430978485 ], [ 113.888214438789362, 22.553412687707311 ], [ 113.890008457062649, 22.551715529575528 ], [ 113.889991611820648, 22.55150075273999 ], [ 113.88778909642879, 22.549538282046655 ], [ 113.88754484041975, 22.549454055836641 ], [ 113.887182667716687, 22.549407731421134 ], [ 113.886353039548055, 22.54956776122016 ], [ 113.885784512630451, 22.549727791019198 ], [ 113.88556552448442, 22.550098386343258 ], [ 113.885632905452397, 22.552818892926712 ] ] ] } },
{ "type": "Feature", "properties": { "id": 11, "name": "","floor": 2, "type": "999"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.885632905452397, 22.552818892926712 ], [ 113.885771878698918, 22.553046303693751 ], [ 113.886302503822009, 22.553484279985827 ], [ 113.887106864127674, 22.554212836702447 ], [ 113.887443768967728, 22.554246527186454 ], [ 113.888075465542826, 22.55364430978485 ], [ 113.888214438789362, 22.553412687707311 ], [ 113.890008457062649, 22.551715529575528 ], [ 113.889991611820648, 22.55150075273999 ], [ 113.88778909642879, 22.549538282046655 ], [ 113.88754484041975, 22.549454055836641 ], [ 113.887182667716687, 22.549407731421134 ], [ 113.886353039548055, 22.54956776122016 ], [ 113.885784512630451, 22.549727791019198 ], [ 113.88556552448442, 22.550098386343258 ], [ 113.885632905452397, 22.552818892926712 ] ] ] } },
{ "type": "Feature", "properties": { "id": 12, "name": "","floor": 3, "type": "999"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 113.885632905452397, 22.552818892926712 ], [ 113.885771878698918, 22.553046303693751 ], [ 113.886302503822009, 22.553484279985827 ], [ 113.887106864127674, 22.554212836702447 ], [ 113.887443768967728, 22.554246527186454 ], [ 113.888075465542826, 22.55364430978485 ], [ 113.888214438789362, 22.553412687707311 ], [ 113.890008457062649, 22.551715529575528 ], [ 113.889991611820648, 22.55150075273999 ], [ 113.88778909642879, 22.549538282046655 ], [ 113.88754484041975, 22.549454055836641 ], [ 113.887182667716687, 22.549407731421134 ], [ 113.886353039548055, 22.54956776122016 ], [ 113.885784512630451, 22.549727791019198 ], [ 113.88556552448442, 22.550098386343258 ], [ 113.885632905452397, 22.552818892926712 ] ] ] } }
]
}

对上面的数据加以处理,添加heightbase字段,用以展示楼层3d效果。

let floors = []
const floorHeight = 55, buildHeight = 7, baseHeight = 1
res.features.forEach(feature => {const {properties} = featureconst {floor, type} = propertiesif(!floors.includes(floor)) floors.push(floor)let height = (floor - 1) * floorHeight + buildHeightlet base = height - buildHeightif(type === '999') height = base + baseHeightproperties.height = heightproperties.base = base
})

2. 添加图层

通过mapboxGL中的fill-extrusion图层实现楼层和商户的展示,初始化style如下:

const style = {version: 8,glyphs: "https://lzugis.cn/fonts/{fontstack}/{range}.pbf",sources: {'building': {type: 'geojson',data: res}},layers: [{"id": "sky","type": "sky","paint": {"sky-gradient": "rgba(0, 0, 0, 1)","sky-opacity": 0.1}},{'id': 'building','source': 'building','type': 'fill-extrusion','filter': ["==", ['get', 'floor'], 0],'paint': {'fill-extrusion-color': ['match',['get', 'type'],'999', '#ccc','1', '#FFD273','2', '#E86D68','#A880FF'],'fill-extrusion-base': ['get', 'base'],'fill-extrusion-height': ['get', 'height'],'fill-extrusion-opacity': 0.45}},{'id': 'building-height','source': 'building','type': 'fill-extrusion','filter': ["==", ['get', 'floor'], 0],'paint': {'fill-extrusion-color': '#0ff','fill-extrusion-base': ['get', 'base'],'fill-extrusion-height': ['get', 'height'],'fill-extrusion-opacity': 0.45}},{'id': 'building-label','type': 'symbol','source': 'building','filter': ["==", ['get', 'floor'], 0],'layout': {'text-field': ['get', 'name'],"text-size": 14},paint: {'text-color': '#999'}}]
}

地图的初始化配置如下:

{container: 'map',center: [113.88768248794844, 22.551640034479163],hash: false,zoom: 16.6,style,pitch: 65,bearing: 120
}

3. 添加楼层控制UI

此处,单楼层和展示全部楼层的fill-extrusion-basefill-extrusion-height配置有区别。

const ul = document.createElement('ul')
ul.classList.add('floor-control')
const showFloor = (floor = 'All') => {floor = floor === 'All' ? floor : parseInt(floor)const lis = ul.childrenfor (let i = 0; i < lis.length; i++) {const li = lis[i]li.classList.remove('active')if(floors.indexOf(floor) === i) li.classList.add('activ}map.setFilter('building', [floor === 'All' ? '!=' : '==',map.setFilter('building-label', ['==', ['get', 'floor'], if(floor === 'All') {map.setPaintProperty('building', 'fill-extrusion-base',map.setPaintProperty('building', 'fill-extrusion-heightmap.setPaintProperty('building-height', 'fill-extrusionmap.setPaintProperty('building-height', 'fill-extrusion} else {map.setPaintProperty('building', 'fill-extrusion-base',map.setPaintProperty('building', 'fill-extrusion-height'match',['get', 'type'],'999', baseHeight,buildHeight]);map.setPaintProperty('building-height', 'fill-extrusionmap.setPaintProperty('building-height', 'fill-extrusion'match',['get', 'type'],'999', baseHeight,buildHeight]);}
}
const addFloorsUI = function () {floors.splice(0, 0, 'All')floors.forEach(floor => {const li = document.createElement('li')ul.appendChild(li)li.innerText = floor === 'All' ? floor : floor + 'F'li.setAttribute('floor', floor)li.onclick = function () {const floor = this.getAttribute('floor')showFloor(floor)}})document.body.appendChild(ul)showFloor()
}
map.on('load', addFloorsUI)

4. 添加点击交互

注册地图的click事件,用以取消选中,注册图层的click事件,用以选中。

map.on('click', e => {map.setFilter('building-height', ['==', ['get', 'id'], null]);
})
map.on('click', 'building', e => {const { properties } = e.features[0]let {id, type} = propertiesid = type === '999' ? null : idmap.setFilter('building-height', ['==', ['get', 'id'], id]);
})

mapboxGL实现室内地图相关推荐

  1. android 百度室内地图开发,androidsdk | 百度地图API SDK

    更新时间:2020-06-23 室内地图简介 自v4.0版起,百度地图SDK室内图功能正式上线,辅助开发者实现全新的地理位置服务体验,室内地图与百度地图App同步更新. 支持的公众建筑包含购物商场.机 ...

  2. 如何使用JS来开发室内地图商场停车场车位管理系统

    在线体验到室内地图的功能后,手机对室内地图加载一个字,要显示"快",目前微信和电脑都可以打开室内地图的要求是3秒内打开,能有定位导航的功能最好,这样方便找到要去的地方. 对于经常逛 ...

  3. js室内地图开发_使用JS+Three.js+Echart开发商场室内地图客流信息统计功能(下)...

    (2)实时视频及全景漫游的实现: 首先创建实时视频的摄像头图片标注和全景漫游的360°图片标注,标注实现后可在地图上点击相应的图片标注从而显示实时视频画面或360°全景画面,画面可拖拽可放大缩小. 各 ...

  4. java 室内3d_室内地图制作-首款实时室内绘制室内地图-3D室内地图

    室内地图制作经过易景空间地图团队的持续优化迭代,新版本地图编辑器中的画圆柱体.模型库.快速画道路.房间直接换纹理贴图等功能终于上线了,目前市面上一款无需安装软件就能直接使用浏览器访问的在线 室内地图 ...

  5. 高德地图PC版国内首发室内地图

    近日,高德地图PC版上线了室内地图功能,以往商场.交通枢纽等在地图上仅显示轮廓的地点,现在也能显示详细的室内信息了.使用此功能,用户不仅能够清晰地看到商场内的平面地图,快速找到各商铺或候车室.登机口的 ...

  6. 选择室内地图提供商时需要考虑的12件事

    当你在户外导航时,没有比通过GPS技术更好的方法来确定你的位置.从航海船只到客机,甚至是徒步旅行的个人,每个人都在使用户外地图解决方案. 但是GPS不能穿透建筑物,那么如果你需要绘制一个室内空间的地图 ...

  7. android室内地图,概述-Android 室内地图SDK | 高德地图API

    Android 室内地图 SDK 简介 说明: 室内地图数据对新用户暂停开放,建议您使用 Android地图SDK 可实现室内外一体化效果. 高德地图 Android 室内地图SDK 是一套室内地图开 ...

  8. 室内地图导航系统基础功能与衍生服务详解

    室内地图导航系统的开发和使用不仅弥补了室内寻路困难的问题,室内地图作为信息化.智能化应用的基础,在其基础上开发出如:人员位置.营销推广.公共安全等衍生功能,为智慧生活添砖加瓦.随着智慧城市的推进,室内 ...

  9. 使用室内地图提升体育场体验的4种方式

    你已经拿到了门票,正前往大赛现场!体育场如何使用数字地图为您提供难忘的球迷体验? 今天是比赛日!你的票买好了,球衣穿上了,你准备好为你的球队加油了. 虽然这种仪式并不新鲜,但体育场及其团队利用技术的方 ...

最新文章

  1. 轻松掌控全链路服务监控:方案概述与对比 | 真的很干!
  2. Paddle 环境中 使用LeNet在MNIST数据集实现图像分类
  3. queue java 判断重复值_java集合类深入分析之Queue篇(Q,DQ)
  4. mac安装git客户端
  5. 怎么在linux上装java,如何在Ubuntu Linux上安装Java
  6. CPU乱序执行(指令重排序)
  7. 怎样把python源程序发给别人_如何把Python源码打包成EXE文件?以及bug
  8. run (牛客多校第二场)计数DP
  9. 有关SQL Server事务日志的十大文章
  10. p44_IP数据包格式
  11. java线程wait_Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
  12. XHTML中button加入超链接以及使插入图片与屏幕一样大
  13. oracle日期型to_char,Oracle 日期函数to_char
  14. 软件poc测试方案,华为fusioncloud桌面云解决方案5.3poc测试方案v1.0
  15. ZZULIOJ 1047: 对数表
  16. 用过的几款步进电机驱动IC
  17. python模块导入详解
  18. 《军团要塞2》绘画渲染
  19. 如何快速上手强化学习?
  20. jquery实现图片上传预览

热门文章

  1. 对外经贸大学研究生院计算机考研,对外经济贸易大学研究生院
  2. 被严重忽略的一款《经济学人》官方产品
  3. Android Textview缩进之悬挂缩进
  4. 1132: [POI2008]Tro 计算几何
  5. Java节假日接口,增加天数跳过节假日
  6. 快递机器人为何刚刚在旧金山上路就被叫停了? | 精选
  7. win10 虚拟环境
  8. html5支持drag的拖放排序插件sortable.js
  9. 利用phantomjs模拟QQ自动登录
  10. 高频、射频、微波的区别