推荐技术栈

  • amap + g2/ amap + L7
  • mapbox + deck.gl/echarts.gl

地理相关库

amap
mapbox
Leaflet
Cesium
deck.gl
g2 map类
turfjs

工具

http://geojson.io/#map=2/20.0...
地图选择器

地图3D

https://codepen.io/AlexZ33/pe...
https://codepen.io/AlexZ33/pe...
北京市居住人口3D分布

楼宇

https://codepen.io/AlexZ33/pe...  用css实现太累

城市统计

上海城市统计

图层

Mapv - 地理信息可视化开源库
https://github.com/chengquan2...

高德地图api

百度地图api

http://lbsyun.baidu.com/index...
http://mapv.baidu.com/gallery...
vue-baidu-map

注意
百度地图webapi接口文档
百度地图javascript api文档

使用百度地图的服务,需使用BD09坐标。

若使用非BD09坐标、未经过坐标转换(非BD09转成BD09)直接叠加在地图上,地图展示位置会偏移,因此通过其他坐标(WGS84、GCJ02)调用服务时,需先将其他坐标转换为BD09。

非百度坐标系,如何转换成百度坐标系?
http://lbsyun.baidu.com/index...
http://lbsyun.baidu.com/index...

图吧地图api

Mapbox api

地图API和工具

坐标拾取器械

https://codepen.io/AlexZ33/pe...
另外,百度地图api的开发文档下的工具支持中有很多类似的工具
Vue Baidu Map

地图选择器

GeoJSON

turf.js

坐标系统说明

图片描述
高德地图: GCJ-02 我国地图坐标系统 
百度地图: BD-09 (BD-09II/bd09mc)

  • 普通GPS定位出来的数值都是基于WSG-84坐标系标准,这是世界通用的坐标系。(美国的)
  • GCJ-02和WSG-84之间的坐标系转换算法是保密的。

“中国政府为了国家安全在国内 GPS 定位时人为加入一定偏移”这种说法是不正确的。
应该是“我国所发行的地图类产品强制性加入偏移算法,使原本标准的坐标系统(WSG-84)变为国家保密的自定义坐标系统(GCJ-02)”。

坐标系说明

在进行地图开发过程中,我们一般能接触到以下三种类型的地图坐标系:

1.WGS-84原始坐标系,一般用国际GPS纪录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的;但是在国内是不允许直接用WGS84坐标系标注的,必须经过加密后才能使用;

2.GCJ-02坐标系,又名“火星坐标系”,是我国国测局独创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,可以说,GCJ-02是国内最广泛使用的坐标系;

3.百度坐标系:bd-09,百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图。(目前百度API提供了从其它坐标系转换为百度坐标系的API,但却没有从百度坐标系转为其他坐标系的API)

three.js地图

http://blog.csdn.net/u0125393...
Three.js - 用100行javascript代码创建一座城市

G2地图

地图数据

通常情况下,地理数据的可视化会包含多份数据:一份是用于绘制地图的经纬度数据,一份是用户真正想要可视化的用户数据。

  • 实例 中国地图-省市下钻只有经纬度数据,但是特殊的是,这个实例中,我们从amap api获得数据,在左侧绘制地图(其中中国地图直接得到的geoJSON数据,行政区划得到的是TopoJSON数据),在右侧用g2绘制处理行政区划数据(geojson -> json数组 --> dataset) 绘制地图
  • 实例 带气泡的地图 需要在世界地图上标注各个国家的男女比例情况,这个时候就可以使用多视图的可视化方案:详情 戳 --->这

地图数据一般保存为JSON格式,G2和D3常用的有两种:

  • GeoJSON 描述地理信息的一种基本格式 例——> world.geo.json
  • TopoJSOND3作者Mike Bostock制定的格式,符合JSON规范

我们以这个g2 中国地图-省市下钻为例
g2/demos/map-drill-down.html

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>中国地图-省市下钻</title><link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/><style>.button-group{position: fixed;bottom:50%;left: 0px;width: 70%;}</style><script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>
</head>
<body><div id="mountNode"></div><div class='button-group' style="background-color: #fff"><input type='radio' onclick='refresh(this.value)' checked name='mapStyle' value='normal'>标准<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='dark'>幻影黑<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='light'>月光银<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='fresh'>草色青<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='grey'>雅士灰<br><input type='radio' onclick='refresh(this.value)' name='mapStyle' value='graffiti'>涂鸦<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='whitesmoke'>远山黛<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='macaron'>马卡龙<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='blue'>靛青蓝<input type='radio' onclick='refresh(this.value)' name='mapStyle' value='darkblue'>极夜蓝<br><input type='radio' onclick='refresh(this.value)' name='mapStyle' value='wine'>酱籽</div><script>/*Fixing iframe window.innerHeight 0 issue in Safari*/document.body.clientHeight;</script><script src="https://gw.alipayobjects.com/os/antv/assets/g2/3.0.4-beta.2/g2.min.js"></script><script src="https://gw.alipayobjects.com/os/antv/assets/data-set/0.8.3/data-set.min.js"></script><script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script><script src="https://gw.alipayobjects.com/os/antv/assets/lib/lodash-4.17.4.min.js"></script><script src="https://webapi.amap.com/maps?v=1.4.1&key=8c8c021990b332b22254f2f8289a62ef"></script><script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script><script>$('#mountNode').html('<div style="position:relative;">'+'<div id="china" style="width:50%;height:400px;position:absolute;left:0;top:0"></div>' +'<div id="province" style="width:50%;height:400px;position:absolute;right:0;top:0;"></div>'+'</div>');//调用高德api绘制底图以及geo数据const map = new AMap.Map('china',{resizeEnable: true,zoom:4});function refresh(enName) {map.setMapStyle('amap://styles/'+enName);}const colors = [ "#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac" ];// 当前聚焦的区域let currentAreaNode;AMapUI.load(['ui/geo/DistrictExplorer', 'lib/$'], function(DistrictExplorer) {//创建一个实例const districtExplorer = window.districtExplorer = new DistrictExplorer({eventSupport: true, //打开事件支持map});//        //创建一个辅助Marker,提示鼠标内容
//        var tipMarker = new AMap.Marker({
//          //启用冒泡,否则click事件会被marker自己拦截
//          bubble:true
//        });
//// feature 被点击districtExplorer.on('featureClick', function(e, feature) {const props = feature.properties;//如果存在子节点console.log(props);if(props.childrenNum > 0) {//切换聚焦区域switch2AreaNode(props.adcode);}});//外部区域被点击districtExplorer.on('outsideClick', function(e) {districtExplorer.locatePosition(e.originalEvent.lnglat, function(error,routeFeatures) {if(routeFeatures && routeFeatures.length > 1) {//切换到省级区域switch2AreaNode(routeFeatures[1].properties.adcode);}else{//切换到全国switch2AreaNode(100000)}},{levelLimit:2});});//绘制某个区域的边界function renderAreaPolygons(areaNode) {const node = _.cloneDeep(areaNode);districtExplorer.clearFeaturePolygons();districtExplorer.renderSubFeatures(node, function(feature, i) {const fillColor = colors[i % colors.length];const strokeColor = colors[colors.length - 1 -i % colors.length];return {cursor: 'default',bubble:true,strokeColor,//线颜色strokeOpacity:1,//线透明度strokeWeight:1, //线宽fillOpacity: 0.35 //填充透明度};});//绘制父区域districtExplorer.renderParentFeature(node, {cursor: 'default',bubble: true,strokeColor: 'black',//线颜色strokeOpacity: 1, //线透明度strokeWeight: 1, //线宽fillColor: null, //填充色fillOpacity: 0.35 //填充透明度});}//切换区域后刷新显示内容function refreshAreaNode(areaNode) {districtExplorer.setHoverFeature(null);renderAreaPolygons(areaNode)}//切换区域function switch2AreaNode(adcode, callback) {if (currentAreaNode && ('' + currentAreaNode.getAdcode() === '' + adcode)) {return;}loadAreaNode(adcode, function(error, areaNode) {if (error) {if (callback) {callback(error);}return;}currentAreaNode = window.currentAreaNode = areaNode;refreshAreaNode(areaNode);if (callback) {callback(null, areaNode);}});}//加载区域function loadAreaNode(adcode, callback) {districtExplorer.loadAreaNode(adcode, function(error, areaNode) {if(error) {if(callback) {callback(error);}return;}renderG2Map(areaNode); //使用 G2 绘制地图if(callback) {callback(null, areaNode);}});}//浙江switch2AreaNode(330000);});//开始使用G2绘制地图let provinceChart;function renderG2Map(areaNode) {const adcode = areaNode.getAdcode();const geoJSON = areaNode.getSubFeatures(); // 获取 geoJSON 数据const name = areaNode.getName();provinceChart && provinceChart.destroy();provinceChart = null;if (!geoJSON || currentAreaNode && ('' + currentAreaNode.getAdcode() === '' + adcode)) {return;}const dv = processData(geoJSON);// start: 计算地图的最佳宽高const longitudeRange = dv.range('longitude');const lantitudeRange = dv.range('lantitude');const ratio = (longitudeRange[1] - longitudeRange[0]) / (lantitudeRange[1] - lantitudeRange[0]);let width;let height;if (ratio > 1) {width = $('#province').width();height = width / ratio;} else {width = 300 * ratio;height = $('#province').height();}// end: 计算地图的最佳宽高provinceChart = new G2.Chart({container: 'province',width,height,padding: 0});provinceChart.source(dv);provinceChart.axis(false);provinceChart.tooltip({showTitle: false});provinceChart.polygon().position('longitude*lantitude').label('name', {textStyle: {fill: '#fff',fontSize: 10,shadowBlur: 2,shadowColor: 'rgba(0, 0, 0, .45)'}}).style({stroke: '#fff',lineWidth: 1}).color('value', '#BAE7FF-#1890FF-#0050B3');provinceChart.guide().text({position: [ 'min', 'max' ],offsetY: 20,content: name,style: {fontSize: 14,fontWeight: 'bold'}});provinceChart.render();}function processData(geoJSON) {console.log("---------------------geoJSON---------------------------");console.log(geoJSON);const mapData = {type: 'FeatureCollection',features: geoJSON};// 构造虚拟数据const userData = [];for (let i = 0; i < geoJSON.length; i++) {const name = geoJSON[i].properties.name;userData.push({name,value: Math.round(Math.random() * 1000)});}console.log("----------------userData----------------");console.log(userData);const ds = new DataSet();const geoDataView = ds.createView().source(mapData, {type: 'GeoJSON'}); // geoJSON 经纬度数据// 用户数据const dvData = ds.createView().source(userData);dvData.transform({type: 'geo.region',field: 'name',geoDataView,as: [ 'longitude', 'lantitude' ]});console.log('---------------------dvData-------------');console.log(dvData);return dvData;}</script>
</body>
</html>

这里的代码

AMapUI.load(['ui/geo/DistrictExplorer', 'lib/$'], function(DistrictExplorer) {}

是对高德地图ui的组件调用,DistrictExplorer是行政区划浏览

  • 自有组件还有:参考组件 UI组件库
  • 我们还可以自定义组件模块,AMapUI组件库的扩展 ,详情戳这里————> AMapUI组件库高级功能
  • ui/geo/DistrictExplorer是扩展的模块路径
  • lib/$, 即DomLibrary(jQuery或者Zepto)

图片描述
这里load的json数据是这样的,其中的topo内的就是TopoJSON数据
geo/DistrictExplorer.json

图片描述

  • type 是Topology,表示文件类型
  • transform用于描述缩放量和平移量,分别用一个只有两项的数组来表示
  • objects里存有几何体模块,此处只有浙江省

    • parent 是全省
    • sub 是各市县
    • arcs表示如何从最外层的数组arcs里提取地形.

注意
相比GeoJSON直接使用Polygon、Point之类的几何体来表示图形的方法,TopoJSON中的每一个几何体都是通过将共享边(被称为arcs)整合后组成
TopoJSON消除了冗余,文件大小缩小了80%,因为:

  • 边界线只记录一次
  • 地理坐标使用整数,不使用浮点数

地图投影

我们再看一看 g2的另一个实例 : 带气泡的地图


const dv = ds.createView('back').source(mapData,{type: 'GeoJSON'}).transform({type:'geo.projection',projection: 'geoMercator',as:['x','y','centroidX','centroidY']});

这里的 projection: 'geoMecator',表示投影是墨卡托投影

墨卡托投影、高斯-克吕格投影、UTM投影

我们可以看看d3里面关于地图的投影api,看看有哪些地图投影:
d3.js Azimuthal Projections

绘制过程

图片描述
图片描述
相比2.0版本 3.0版本的container是支持string 也支持dom对象的

从上面两个例子我们可以看出来,在载入地图时候我们可以

  • 调用amap api地图
  • 本地GeoJSON或TopoJSON生成

这里我们说一说如何载入数据
如何装载数据
图片描述
图片描述

这里我们可以看到 g2中绘制地图时候需要 传入一个JSON数组
所以上面例子中国地图-省市下钻 的 const dv = processData(geoJSON); processData函数应该有这样一个转换过程 GeoJSON --> JSON数组 --> DataSet,我们来看一看是不是这样(即userData应该是JSON数组,dvData应该是DataSet)
图片描述
图片描述
图片描述

const geoDataView = ds.createView().source(mapData, {type: 'GeoJSON'}); // geoJSON 经纬度数据

为什么是转换为Dataset?

自 G2 3.0 版本开始,原先内置的数据处理模块 frame 从 G2 包中抽离出来,独立成为 DataSet 包。DataSet 的目标是为数据可视化场景提供状态驱动(state driven)的 -->DataSet

<script src="https://gw.alipayobjects.com/os/antv/assets/data-set/0.8.1/data-set.js"></script>

在DataSet包中

  • 我们把数据处理分为两个大的步骤:数据连接(Connector)和数据转换(Transform)。Connector 负责导入和归一化数据(譬如导入 CSV 数据,导入 GeoJSON 数据等),Transform 负责进行各种数据转换操作(譬如图布局、数据统计、数据补全等)。

想要了解G2中数据的处理流程直接点击

常用实例

基于baidu、google、arcgis、高德地图、canvas数据可视化
GeoHey gallery

文章

基于WebGL的大数据二三维可视化--uber的deck.gl介绍
deck.gl example
可视化篇:mapbox + echarts-gl 展示血脉交通
从Mapbox的开源工具看Web GIS的发展
ECharts 地图博客
echarts结合高德API进行地图下钻

参考

Map Projection Overview
[python处理地理数据-geopandas和pyshp]()
mapbox/node-fontnik工具使用介绍
Mapbox GL JS本地化实践
GIS文章集
Geomatics(GIS,GPS,RS,Surveying)
地图应用API(GIS+LBS)
antv g2的理解总结
Maps
inMap
https://codepen.io/stevepeppl...
https://codepen.io/AlexZ33/pe...
https://codepen.io/pbeshai/pr...
https://codepen.io/jakealbaug...
https://github.com/LylaYuKako...

数据可视化:地图使用案例相关推荐

  1. pyecharts实践--2019-nCoV疫情数据可视化地图(实时更新)

    2019-nCoV疫情数据可视化地图效果如下: 获取数据(本文数据获取自腾讯的疫情实时追踪) 腾讯的疫情实时追踪网页: 点击查看. 这里我使用的是Google,追踪得到的数据如下图: 双击左边的 ge ...

  2. vue 开发数据可视化地图

    vue 项目: 安装 axios: npm install axios -D 安装 echarts npm install echarts@4.9.0 -D 其中,@+版本号! 当然,npm 的安装方 ...

  3. 第十一章 数据可视化 - 地图可视化

    目录 疫情地图的使用 疫情地图-国内疫情地图 疫情地图-省级疫情地图 疫情地图的使用 第一阶段-第十一章-01-数据可视化案例-地图-基础地图使用_哔哩哔哩_bilibili "" ...

  4. python数据可视化地图_python--地图可视化

    python地图可视化可用python包Basemap:本篇总结用到百度的Echars,http://echarts.baidu.com/:Echarts 是百度开源的一个数据可视化 JS 库. 安装 ...

  5. 基于Echarts数据可视化地图模块(地图下钻+地图迁徙线)

    数据可视化大屏展示使用频率最高的应该就是地图了,无论是做功能性的还是做装饰用的,都是非常实用的,放上它项目才有了灵魂,显得非常的炫酷.这里分别对地图下钻,迁徙图,地图下钻+迁徙图的合并,记录介绍一下: ...

  6. 数据可视化之特别案例的运用与分析

    数据可视化作为一个新研究领域也变得越来越火.成功的数据可视化,不仅停留在做得漂亮,更是富含的深意,哪怕是数据错综复杂,也能让观看者一眼就能洞察其所代表的含义并产生新的理解. 传统的数据图表很难对复杂的 ...

  7. 拿走不谢,数据可视化地图制作教程

    ​地图,是一种基于地理位置使用不同深浅的颜色来表示不同范围的分布情况的可视化图形,直观的展现各区域分析指标的分布.它也是数据大屏可视化展示的重要图形类型之一. 比如下面大屏,以全国销售分析地图作为中心 ...

  8. 凌晨4点的中国人都在干什么?这份数据可视化地图给你答案

    导读:睡什么睡起来high!这句玩笑话现在算是实现了,最近一组中国主要城市夜间消费数据出炉:北京最"中年不易",睡得最早起得最早:成都吃货最拼,一边烫火锅一边吃健胃消食片:深圳最L ...

  9. python数据可视化案例销售数据_3-5 用python进行数据可视化 朝阳医院销售案例

    本篇是3-2-2数据分析文章的扩展版.spoonhead:3-3-2 Python数据分析实战第一步​zhuanlan.zhihu.com 本文在原文章的基础上提出了问题4-问题8的5个新问题,并用m ...

  10. Python学习笔记——数据分析之数据可视化工具实战案例:世界高峰数据可视化

    世界高峰数据可视化 (World's Highest Mountains) 参考:https://www.kaggle.com/alex64/d/abcsds/highest-mountains/le ...

最新文章

  1. SVO: 视觉SLAM中特征点法与直接法结合
  2. 从JVM的常见异常来看Tomcat中内存的设置
  3. 网络发现不了计算机 但是输入IP可以看到,启用了网络发现为什么还是发现不了其他计算机 其他计算机也发现不了我...
  4. Python基础day02【if结构、if elif 结构、while循环、for循环、Break和continue、Debug 调试、三目运算、循环 else 结构】
  5. 如何使用ngTemplateOutlet给ng-template模板传递参数
  6. nginx负载均衡 页面缓存
  7. java socket实现简单即时通讯
  8. webpack那些事儿
  9. leetcode解题记录(一)
  10. python简单命令语句_Python语言----linux常用命令(13)
  11. Redis与数据库缓存一致性问题
  12. 自学导航页(待续ing)
  13. vue学习-动态组件和异步组件显示
  14. Android Studio的反编译工具使用。
  15. Java - 批量生成二维码压缩包
  16. php tracert,使用tracert查看网络状况
  17. js判断是否微信登陆
  18. activity串行多实例会签
  19. win10系统无法连接远程服务器,笔者修复win10系统无法连接远程服务器的图文教程...
  20. Python生成对角矩阵和对角块矩阵

热门文章

  1. 金融量化数据接口API汇总
  2. C# 操作Word页眉页脚——奇偶页/首页不同、不连续设置页码、复制页眉页脚、锁定页眉页脚、删除页眉...
  3. 微软软件实现技术授课系列内容之五:软件测试基础
  4. 解决电脑开机后打印机会自动打印的问题
  5. Layui表格排序例子
  6. 实验室计算机化系统操作规程,gmp附录:计算机化系统.pptx
  7. 上一步,下一步(撤销和恢复)
  8. webstorm配置环境变量_Webstorm 配置与使用 Less
  9. s3 java sdk_s3javasdk文档.pdf
  10. 机器学习进阶——数据清洗