** 百度地图
这个名气太大了, 功能不少而且如今对3d的支持也很不错, 注意GL版v1.0 与以前 v2.0版本地图的api有点不同别掉坑里.
缺点也比较明显, 好比你想要一份干干净净的地图, 上面没有店铺没有任何标识的时候我就建议你用echarts来玩了, 由于百度地图带的东西比较多.
想要使用百度地图的同窗能够看这里, 超级简单就能够完成注册用玩耍.
使用很是简单php
** hcharts
很是牛很是好用, 可是它部分功能是要收费的, 使用以前要让公司帮你买好相应的功能才能用于商用哦.
因为咱们公司地图库是本身研发的最后也就没有这种网上付费的.
详情地址html
** echarts
这个库前端无人不知了, 在需求很简单的状况下建议用这个技术来作, 大部分时候项目中须要绘制柱状图或折线图的时候已经引入了echarts此时不用重复引用来节省空间.
echarts画的地图前端
** 咱们公司本身的2d, 3d地图组件库
这个在这里就不作过多详细介绍了, 一些公司也会有自主研发的地图组件, 设计的思想上可能与上面三个不太相同, 接下来我也会聊到.vue
这里我新建了一个vue工程c++
<template> <div class="home"> <div id="map"></div> </div> </template> <script> import echarts from "echarts"; import mapData from "./geo"; export default { name: "Home", data() { return { myChart: null, }; }, methods: { initMap() { this.myChart = echarts.init(document.getElementById("map")); echarts.registerMap("world", mapData); // 定义名称下面要用, 这样作的好处就是能够很方便的实现切换地图的效果 this.myChart.setOption({ series: [ { type: "map", mapType: "world", // 自定义扩展图表类型 label: { show: false, }, }, ], }); }, }, mounted() { this.initMap(); } }; </script>
echarts.registerMap("world", mapData);
能够理解为把这个数据命名为'world', 方便之后的切换(这里的数据我下面会讲).效果图git
咱们能够看得出来, 地图的绘制也没什么'特殊'的, 最主要的就是那个 mapData
数据, 这个数据通常叫它geojson数据, 那么接下来咱们认识一下它.github
英语好的能够先撸网站
1. 基本结构web
{ // 能够包括点线面, 一个大的集合 "type": "FeatureCollection", // 定义这个是个geojson文件, 这里还能够是其余值下面会说 "features": [] // 这里放要绘制的数据 }
之后咱们看到"type": "FeatureCollection"
这样一行就说明这个文件是geojson规范的文件算法
2. 描述一个点(Feature)
地图上的打点数据apache
{ "type": "FeatureCollection", "features": [ { "type": "Feature", // 表示这个对象是一个要素 "properties": {}, // 这里放样式, 后面会专门说 "geometry": { // 这里面放具体的数据 "type": "Point", // 专指画点 "coordinates": [105.380859375, 31.57853542647338] // 默认是经度与纬度, 三维的话就是xyz三个值, 固然这里也不必定是经纬度(不一样的坐标体系)中会讲为何 } }, ] }
3. 描述多个点(FeatureCollection)
**优势
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPoint", // 多点, 也就是连续画多个一样的点 "coordinates": [[105.380859375, 31.57853542647338], [105.580859375, 31.52853542647338] ] } }, ] }
4. 描述一条线(LineString)
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "LineString", // 这里全部的点会链接在一块儿造成线 "coordinates": [[105.6005859375, 30.65681556429287], [107.95166015624999, 31.98944183792288], [109.3798828125, 30.031055426540206], [107.7978515625, 29.935895213372444]] } }, ] }
5. 描述多条线(MultiLineString)
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "MultiLineString", "coordinates": [ [ [105.6005859375, 30.65681556429287], [107.95166015624999, 31.98944183792288], [109.3798828125, 30.031055426540206], [107.7978515625, 29.935895213372444] ], [ [109.3798828125, 30.031055426540206], [107.1978515625, 31.235895213372444] ] ] } }, ] }
6. 描述一个面(Polygon, 也叫多边形)
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", // 注意这里是三维数组 "coordinates": [ [ [106.10595703125, 33.33970700424026], [106.32568359375, 32.41706632846282], [108.03955078125, 32.2313896627376], [108.25927734375, 33.15594830078649], [106.10595703125, 33.33970700424026] ] ] } }, ] }
7. 一个面里面有多个面(Polygon)
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ [ [ -39.7265625, -3.162455530237848 ], [ 127.96875, -3.162455530237848 ], [ 127.96875, 74.1160468394894 ], [ -39.7265625, 74.1160468394894 ], [ -39.7265625, -3.162455530237848 ] ], [ [ -22.5, 15.961329081596647 ], [ 110.74218749999999, 15.961329081596647 ], [ 110.74218749999999, 70.8446726342528 ], [ -22.5, 70.8446726342528 ], [ -22.5, 15.961329081596647 ] ] ] } } ] }
效果以下:
8. 描述多个面(MultiPolygon)
优点:
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -39.7265625, -3.162455530237848 ], [ 127.96875, -3.162455530237848 ], [ 127.96875, 74.1160468394894 ], [ -39.7265625, 74.1160468394894 ], [ -39.7265625, -3.162455530237848 ] ] ], [ [ [ -22.5, 15.961329081596647 ], [ 110.74218749999999, 15.961329081596647 ], [ 110.74218749999999, 70.8446726342528 ], [ -22.5, 70.8446726342528 ], [ -22.5, 15.961329081596647 ] ] ] ] } } ] }
这里若是重叠了就是颜色的叠加了如图所示:
9. 描述一个组(geometries)
{ "type": "FeatureCollection", "features": [ { // 能够包括点线面, 一个独立的集合 "type": "GeometryCollection", "geometries": [ { "type": "Point", "coordinates": [108.62, 31.02819] }, { "type": "LineString", "coordinates": [[108.896484375, 30.1071178870], [108.2184375, 30.91717870], [109.5184375, 31.2175780]] } ] } ] }
10. 不一样的样式(properties)
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { // 专门放属性 "stroke": "#fa9661", // 外边颜色 "stroke-width": 4.1, // 外边宽 "stroke-opacity": 0.7, // 外边透明度 "fill": "#9e290c", // 填充色 "fill-opacity": 0.7 // 填充色透明度 }, "geometry": { "type": "Point", // 画点 "coordinates": [105.380859375, 31.57853542647338] } }, ] }
** 展现干巴巴的数据你们看着不起劲, 这里我推荐一个绘制geojson的超棒网站地址
那么我来介绍一下如何使用这个网站高效的生成, 以及调试geojson
单击图形能够出现如图所示的操做框.
** 有没有发现我们使用的地图在放大的时候,区域都是一个方块一个方块的被加载成图像的.
** 若是你打开控制台的network还能够看到有好多png的请求.
** 地图这种超大的数据, 超多细节是如何作到快速渲染的?
** 下面是如今比较主流的两种地图的绘制模式.
顾名思义图片像是瓦片同样堆叠起来的格子状成为地图, 有点像拼图, 是否是感受一点也不高大上....
但这里也是有不少问题要解决的, 好比你在俯视世界的视角看地图, 那么出现的就是世界的瓦片图片, 当高度小于必定的数值时就采用另外一套相应的瓦片, 在某个高度范围内是采用放大瓦片图片的方式模拟视野的降低, 每次请求瓦片图片都须要传递: 1: 当前视口所在坐标(经纬度) 2: 当前视口宽高 3: 当前视角高度.
栅格瓦片以 256 256 或 512 512 大小的图片为介质,这种技术一般是在服务端预先将图片渲染好,前端根据地图的缩放等级,按需加载图片加以拼接,目前依旧在大规模使用,但这种方式存在一些劣势:
受到网络带宽开销和存储空间限制的影响大,离线化部署成本高,单套主题将近 500 多 G(中国)。
样式编辑完后端渲染须要时间长。
无三维的建筑数据,在 3D 场景中无高度信息。
数据保密性差。
顾名思义就是矢量绘制出图形, 只要不是照片确定会小不少, 对于矢量为何轻量而且不失真能够参考的上篇文章svg的分享svg实战
矢量瓦片采用和栅格瓦片相同的分级切割方案,不一样的是,瓦片数据传输的是地理数据,包括道路、土地、建筑等,经过在前端作地图的渲染,具备以下优点:
极少占用服务器空间,下降网络开销,本地化部署只需5G空间(中国)。
地图的底图样式更换简单.
由于具备了地理数据自己,可在数据基础上作三维空间的延伸,例如 3D 建筑。
数据保密性强。
** 地球自己是个椭球体, 要把它以平面的方式绘制在一个矩形上也真的很差办, 如今有很多绘制的方式可是都有各自的优缺点, 感兴趣的朋友能够查查看具体的细节, 我这里就简单介绍下比较常见的方式.
火星坐标是国家测绘局为了国家安全在原始坐标的基础上进行偏移获得的坐标,基本国内的电子地图、导航设备都是采用的这一坐标系或在这一坐标的基础上进行二次加密获得的。
火星坐标的真实名称应该是 GCJ-02 坐标,基本上全部的国内的电子地图采用的都是火星坐标系甚至 Google 地图中国部分都特地为中国政府作了偏移。
火星坐标是在国际标准坐标 WGS-84 上进行的一次加密,因为国内的电子地图都要至少使用火星坐标进行一次加密,百度直接就职性一些,直接本身又研究了一套加密算法,来了个 二次加密,这就是咱们所熟知的百度坐标 BD-09,固然只有百度地图使用的是百度坐标
GS-84 坐标是一个国际的标准,通常卫星导航,原始的 GPS 设备中的数据都是采用这一坐标系。国外的 GoogleMap、OpenStreetMap、MapBox、OpenLayer 等采用的都是这一坐标。
geojson设置坐标系
因为坐标系的不一样, 那么就算绘制一个点的坐标也都不会彻底相同了, 那么就须要咱们来告诉使用geojson的人按哪一种坐标系进行解析
{ "type": "FeatureCollection", "crs": { // 定义坐标系 (若是不写就是使用经纬度的坐标系) 默认为EPSG:4326。 "type": "name", // "type" 和 "properties"。为强制拥有 "properties": { "name": "urn: ogc: def: crs: EPSG: 54013" // 这里定义具体的规则 } }, "features": [ {}, ] }
使用上线的规则
{ "type": "FeatureCollection", "crs": { "type": "link", // 这里变成了link "properties": { "href": "http://example.com/crs/42", // 这里是你设置的资源连接 "type": "proj4" // "proj4","ogcwkt",esriwkt" 只能这三种格式 } }, "features": [ {}, ] }
**WebAssembly是一种新的编码方式,文件体积更小,启动速度更快,运行速度也更快,与使用JavaScript构建的Web应用相比,性能提高明显。它是多种编程语言的编译器目标,包括C++、C、Rust等。
WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范。**
WebAssembly 能够明显的提高计算的速率, 还挺适合用在地图库里面的
编译和优化 - 编译和优化所需的时间较少,由于在将文件推送到服务器以前已经进行了更多优化,JavaScript 须要为动态类型屡次编译代码
从新优化 - WebAssembly 代码不须要从新优化,由于编译器有足够的信息能够在第一次运行时得到正确的代码
执行 - 执行能够更快,WebAssembly 指令更接近机器码
垃圾回收 - 目前 WebAssembly 不直接支持垃圾回收,垃圾回收都是手动控制的,因此比自动垃圾回收效率更高。目前浏览器中的 MVP(最小化可行产品) 已经很快了。在接下来的几年里,随着浏览器的发展和新功能的增长,它将在将来几年内变得更快。
说了这些都是概念, 接下来咱们就一块儿实战一下go
中文官网
官网的实现还须要配置环境啥的搞得很正式, 入门级别其实咱们更想的是尝尝鲜, 只要你会点c++就能用我接下来的方法实现.
在线生成
在线生成
引用文件
fetch("/test.wasm") .then((res) => res.arrayBuffer()) // 拿到Buffer格式 .then((bytes) => WebAssembly.compile(bytes)) // 转字节码 .then((mod) => { const instance = new WebAssembly.Instance(mod); const exp = instance.exports; console.log(exp._Z7showNumv()) });
开发成本
这里我在组内展现一下我编写的两个项目的代码结构与遇到的问题, 就不在这里展开了毕竟涉及保密问题, 但大致思路就是把地图分红世界, 国家, 省, 市, 区 几个等级(省市区是中国的分法), 至关于一个状态机, 而后在每一个状态下作相应的事好比打点与连线, 每次变换图层状态都会隐藏其余图层展现相应视野的图层.
地图方面也属于前端比较有用的一环, 我今年刚接触地图相关项目也是一脸蒙, 可是详细学习了geojson等知识以后再用地图相关组件库就很是顺畅了.此次就是这样, 但愿和你一块儿进步.