前言
最近在做一个关于某医院能耗的项目,可视化方面需要在地图上展示出医院楼块,并添为各个楼块添加交互事件,实现医院各个楼块乃至楼层的能耗检测。
技术
地图使用高德地图api,前端框架为Vue.js,前端ui组件库使用elementUi,使用npm包管理工具
搭建项目
在一个空文件夹下
vue create name
优化项目目录结构
加载高德地图
在vue中加载高德我们可以直接在public下的index.html中通过script脚本在线导入,这里我们直接用JSAPI Loader
- 在vue项目中下安装Loader:
npm i @amap/amap-jsapi-loader --save
- 项目中新建一个main.vue文件,作为承载地图的组件:
<template>
<div id="container"></div>
</template>
此时一定要为容器div设置宽高,不然地图无法显示
- 我们再新建一个initMap.js文件,将 AMapLoader 导入并将初始化地图initMap方法导出:
Loader的加载方法参考vue中加载高德地图
import AMapLoader from '@amap/amap-jsapi-loader'
const initMap = function () {
window._AMapSecurityConfig = {
securityJsCode: '你的安全密钥'
}
return AMapLoader.load({
'key': '你的key', // 申请好的Web端开发者Key,首次调用 load 时必填
'version': '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
'plugins': [],
'AMapUI': { // 是否加载 AMapUI
'version': '1.1', // AMapUI 缺省 1.1
'plugins': ['overlay/SimpleMarker', 'overlay/SvgMarker'] // 需要加载的 AMapUI ui插件
},
'Loca': { // 是否加载 Loca, 缺省不加载
'version': '2.0.0' // Loca 版本,缺省 1.3.2
}
})
}
export default initMap
- 再刚刚创建的main.vue文件中导入initMap方法
<template>
<div id="map" class="map">
</div>
</template>
<script>
var map //初始化一个map变量存储map对象
import initMap from '@/utils/map/initMap.js'
export default {
name: '',
components: {},
data () {
return {}
},
methods: {
initMap().then((AMap)=>{
map = new AMap.Map('map', {
zIndex: 15,
zoom: 18,
pitch: 50,
rotation: -6,
showIndoorMap: false,
showLabel: false,
center: [114.502009, 36.618939],
features: ['bg', 'point', 'road'],
viewMode: '3D',
})
})
}
}
</script>
地图加载成功:
高德地图支持自定义主题,根据需求自定义合适的地图样式 自定义地图样式
加载geojson
1. 获取楼块的geojson
通过geojson生成工具生成所需要的楼块点位,这里我推荐一些好用的geojson工具网站: geojson在线编辑 json在线编辑bejson
将获取到的json直接复制到项目的一个.json文件中,或者放入数据库通过接口获取。
2. 高德Loca数据可视化
用高德Loca数据可视化加载geojson 将准备好的楼块geojson通过import导入到main.vue文件中, 使用Loca的PolygonLayer图层加载楼块。具体教程参考:高德Loca数据可视化参考手册
<script>
var map //初始化一个map变量存储map对象
import hospitalJson from '@/static/hospital.json' // 事先准备好的geojson
import initMap from '@/utils/map/initMap.js'
export default {
name: '',
components: {},
data () {
return {}
},
methods: {
initMap().then((AMap)=>{
map = new AMap.Map('map', {
zIndex: 15,
zoom: 18,
pitch: 50,
rotation: -6,
showIndoorMap: false,
showLabel: false,
center: [114.502009, 36.618939],
features: ['bg', 'point', 'road'],
viewMode: '3D',
})
this.locaInit(map, Loca)
})
}
locaInit (map, Loca) {
// 设置绘制loca的map对象
var loca = new Loca.Container({
map
})
// 用GeoJSONSource方法处理准备好的geojson
var geo = new Loca.GeoJSONSource({
data: hospitalJson
})
// 设置光源效果
loca.ambLight = {
intensity: 0.55,
color: '#fff'
}
loca.dirLight = {
intensity: 1,
color: '#5BD6EA',
target: [0, 0, 0],
position: [0, -1, 1]
}
loca.pointLight = {
color: '#EFFFFF',
position: [112.028276, 31.58538, 2000000],
intensity: 0.2,
distance: 5000000
}
var pl = new Loca.PolygonLayer({
map: map,
zIndex: 11,
hasSide: true
})
pl.setSource(geo)
// 根据需求设置楼块样式
pl.setStyle({
unit: 'meter',
texture: 'https://a.amap.com/Loca/static/loca-v2/demos/images/windows.jpg',
textureSize: [350, 200],
height: (index, f) => {
const name = f.properties.name
const condition1 = name === '公路' || name === '不重要建筑'
const condition2 = hospitals.indexOf(name) > -1
if (condition1 || condition2) {return 0} else {return f.properties.floor * 1.5 + 15}
},
topColor: (index, f) => {
const name = f.properties.name
return hospitals.indexOf(name) > -1 ? 'rgba(255,255,255,0)' : name.indexOf('公路') > -1 ? '#1C70AF' : '#282B3B'
},
sideTopColor: (index, f) => {
const name = f.properties.name
return hospitals.indexOf(name) > -1 ? '#fff00' : name.indexOf('公路') > -1 ? '#E2FFFF' : '#06477F'
},
sideBottomColor: (index, f) => {
const name = f.properties.name
return hospitals.indexOf(name) > -1 ? '#fff00' : name.indexOf('公路') > -1 ? '#E2FFFF' : '#032653'
}
})
},
}
</script>
最后看一下楼块展示效果吧:
结尾
目前仅仅加载出来了楼快的样式,楼快如何添加事件以及楼块添加展示楼号楼名称标记还正在研究中,解决以上问题后续我会继续更新。