sts 的js代码不变色_仅需 70 行代码,做一款属于你的 3D 点击交互可视化地图

f10def498667a93b83153772dfce9976.png

3D 建筑可以点了!

在我们推出关于 3D 地图的两篇可视化教程:3D 建筑显示 和 3D 建筑渐变色调节 之后,很多 Mapbox 开发者们都在询问怎么样能够实现 3D 交互的效果,简单来说,就是能够在不同的建筑上显示不同的信息。

这个问题让我们不得不回想起来,海外的设计公司,用 Mapbox 实现了千万个荷兰建筑的可视化交互效果,就像下面视频展示的那样。

967c87cd37677c6c7a9e1a357ca71d2d.png
https://www.zhihu.com/video/1166027377829744640

地图在线访问地址:https://parallel.co.uk/netherlands/#17.05/52.365835/4.894227/0/40

这篇文章当然不会直接教大家如何实现上面这个包含上 G 数据量的效果,我们会借助一个简单的例子 —— CMU 校园建筑二氧化碳排放统计,通过逐行分析代码结构,解析几个关键函数,希望抛砖引玉启发大家。

最终实现的效果

58cc5deead64abdca6058a73abdc2c56.gif

在 CMU 校园中我们可以看到分布不均的关键建筑,通过移动鼠标的位置,你可以看到每栋建筑的二氧化碳排放量/频率数据。

整个项目是一个轻量的 web 网页,可以拷贝下面的源代码到文档中,命名为.html 进行体验,使用了 Mapbox GL JS 来实现这样的交互效果,下面就来看一下具体的代码是如何的吧!

源代码

源代码不算很长,包括注释在内一共只有 70 行。

<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8' />
    <title>CMU Data</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>

<body>

<div id='map'></div>

<script>

//Mapbox Access Tokens
mapboxgl.accessToken = 'pk.eyJ1IjoibWpkYW5pZWxzb24iLCJhIjoiY2p2bzFlbnZ5MW5pbTN5cGJ2YWp2MW9vaiJ9.kAaZq3iyJwvrMLK7XDs_qw';

var map = new mapboxgl.Map({
    container: 'map', // container id
    style: 'mapbox://styles/mjdanielson/cjzej9la703k51clizztqhjcc', // stylesheet location
    center: [-79.942829, 40.443399], // starting position [lng, lat] 
    pitch: 45, // pitch in degrees
    bearing: -180, // bearing in degrees
    zoom: 15 // starting zoom 
});

map.on('load', function() {

//initialize popup 
var popup = new mapboxgl.Popup({ 
        closeButton: false,
    closeOnClick: false,
});

 // When a click event occurs on a feature in the states layer, open a popup at the
// location of the click, with description HTML from its properties.
map.on('mouseenter', 'CO2 Emissions', function (e) {
//change the cursor style as a UI indicator
map.getCanvas().style.cursor = 'pointer';

// Create variables for your tabular information 
var aggregate = e.features[0].properties.CO2e_Emissions_Aggregate;
var agg_freq = e.features[0].properties.CO2e_Emissions_Aggregate_Frq;

// Populate the popup and set its coordinates
// based on the feature found.
popup.setLngLat(e.lngLat)
.setHTML('<strong> 二氧化碳总排放量: </strong>'+ aggregate + '<p> <strong> 二氧化碳排放频率: </strong>' + agg_freq + '</p>')
.addTo(map);
});

// Change it back to a pointer when it leaves.
map.on('mouseleave', 'CO2 Emissions', function () {
map.getCanvas().style.cursor = '';
popup.remove();
});

});

</script>

</body>

</html>

你可以把它复制粘贴在 JSFiddle 中预览结果,在这里推荐一下 JSFiddle(https://jsfiddle.net/),是一款很方便进行在线预览结果的编辑工具。

8ad815a2b21b0c8f66dd191c1ef4ff36.gif

将代码粘贴到 HTML 一栏中,点击 Run 即可方便地预览到结果了。

关键函数剖析

70 行代码,其实关键的函数块只有下面几个:

•4-14 行:<head></head> 定义了交互地图的依赖库地址,名字,UI 等信息。

<head>
    <meta charset='utf-8' />
    <title>CMU Data</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>

•23 行:mapboxgl.accessToken=‘xxxx‘,定义了每个 Mapbox 地图独一无二的访问令牌,可以在你的账户信息中找到你的 AccessToken,它是用来方便统计地图的访问情况的。

mapboxgl.accessToken = 'pk.eyJ1IjoibWpkYW5pZWxzb24iLCJhIjoiY2p2bzFlbnZ5MW5pbTN5cGJ2YWp2MW9vaiJ9.kAaZq3iyJwvrMLK7XDs_qw';

•25 - 32 行:new mapboxgl.Map 定义了地图的样式,显示中心经纬度,默认 Zoom 值,倾角等信息,这样底图被打开的默认样式就确认了。

var map = new mapboxgl.Map({
    container: 'map', // container id
    style: 'mapbox://styles/mjdanielson/cjzej9la703k51clizztqhjcc', // stylesheet location
    center: [-79.942829, 40.443399], // starting position [lng, lat] 
    pitch: 45, // pitch in degrees
    bearing: -180, // bearing in degrees
    zoom: 15 // starting zoom 
});

•34 - 66 行:map.on()这里是关键的交互定义区。本文的例子中我们定义了弹框的所显示的文字,鼠标的交互响应等。

map.on('load', function() {

//初始化弹框
var popup = new mapboxgl.Popup({ 
        closeButton: false,
    closeOnClick: false,
});

 // 设置鼠标触发事件
map.on('mouseenter', 'CO2 Emissions', function (e) {
//改变光标的样式
map.getCanvas().style.cursor = 'pointer';

// 创建内容变量
var aggregate = e.features[0].properties.CO2e_Emissions_Aggregate;
var agg_freq = e.features[0].properties.CO2e_Emissions_Aggregate_Frq;

// 在指定的位置填充弹框内的内容
popup.setLngLat(e.lngLat)
.setHTML('<strong> 二氧化碳总排放量: </strong>'+ aggregate + '<p> <strong> 二氧化碳排放频率: </strong>' + agg_freq + '</p>')
.addTo(map);
});

// 当鼠标离开的时候,移除弹框
map.on('mouseleave', 'CO2 Emissions', function () {
map.getCanvas().style.cursor = '';
popup.remove();
});

});

到这里,您可能会有一个疑问,源码中定义了弹框、鼠标响应、地图展示,那么数据是在哪里被加入的呢?

比如这里在定义内容变量的时候,引用了 CO2e_Emissions_Aggregate 和 CO2e_Emissions_Aggregate_Frq,这两个参数是从何而来的呢?

// 创建内容变量
var aggregate = e.features[0].properties.CO2e_Emissions_Aggregate;
var agg_freq = e.features[0].properties.CO2e_Emissions_Aggregate_Frq;

其实数据在底图被创建的时候就已经加入进来了。

在 Mapbox Studio 中,我们上传好了包括 CMU 建筑数据和二氧化碳排放相关数据的 Datasets,并利用 Mapbox Studio 自动转化处理为 Tilesets,可以看到 Tilesets 中包含了我们上述引用的参数。

9048bcbc18ede846e43c26d79c140844.png

下面只需要在 3D 地图中创建一个新的图层作为数据层「CO2 Emissions」,并在数据源中引用这个 Tilesets 就好。

至于 3D 建筑是如何创建的,在这里就不赘述了,可以查看我们之前介绍过的教程。本文的案例,是通过现有的建筑边界和高度数据,做拉伸获得的,你可以手动去描,或者找到现有的 Geojson 数据加入进去。

只可惜,这块数据原作者并没有公开给大家,如果您想直接使用这块数据,可以使用源码中原作者的 AccessToken 和 Style URL,仅限学习使用,请勿用于商业用途哦!

小福利

大家可以转发这篇文章到朋友圈,并截图给 Mapbox 前台小姐姐 Max(微信号:Mapbox_max),即可加入私家群,获得专属本次教程技术支持+源码文件哦,仅限 20 个名额!

欢迎大家进入 Mapbox.cn 留下你的问题、建议、产品想法等,我们会在 1- 3 个工作日内回复你哦!

6905f7ffcbe8111a10ec30c9b98731ee.png

70e7ae9e16d856419a1225fc12113061.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值