【MapBox实战】生成地图+绘制区域+纠偏

  • mapbox介绍
  • 生成地图过程
    • 基础配置
      • 坐标
      • 在地图上绘制一块区域
      • 在地图上画上点
  • 瓦片地图原理理解
    • 原理
    • 瓦片地图背景理解
    • 编码方式
      • 谷歌xyz
      • 百度xyz
    • mapbpx-gl纠偏
      • 坐标系转换方法
      • 学习整合高德地图的方法
      • 学习使用纠偏插件
  • 最后 + 实例仓库地址

mapbox介绍

mapbox-gl.js - leaflet的插件
前端渲染矢量瓦片交互地图的工具

mapbox-gl.js必须要支持WebGL(旧浏览器不支持)

GIS需要处理的两部分:数据来源+数据在界面显示的样子,style中的source、layer对应这两个部分

生成地图过程

首先是注册登录,银行卡号的部分使用了随机生成器,邮编随便填一个,可能会报错但依然会发送确认邮件,确认后可以成功注册。

随机生成器网址:银行卡随机生成器

1、头部引入mapbox

<script src='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css' rel='stylesheet' />

2、定义一个容器来显示地图

<div id='map' style='width: 100%; height: 100%;'></div>

3、script里设置map对象和相关参数

<script>mapboxgl.accessToken = '这里填官网获取的token';var map = new mapboxgl.Map({container: 'map',style: 'mapbox://styles/mapbox/streets-v11',center: [118.38, 31.33],//芜湖市的经纬度(可以填你想要显示的城市经纬度)zoom: 9});

此时可以显示芜湖为中心的地图了

在头部引入mapbox-gl-language.js,将地图上显示的文字转换为中文

<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-language/v1.0.0/mapbox-gl-language.js'></script>

在srcipt内部设置:

mapboxgl.setRTLTextPlugin('https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.1.0/mapbox-gl-rtl-text.js');
map.addControl(new MapboxLanguage({defaultLanguage: "zh-Hans"}));

基础配置

坐标

数组形式[A,B],A是经度,B是维度

在地图上绘制一块区域

1、获取想显示的区域json数据:进入阿里云数据可视化平台获取DataV.GeoAtlas地理小工具系列 (aliyun.com)
在jiujiang.js文件中定义变量

var jiujiangJSON = {...}//此处放从网站上复制下来的json数据

2、在头部引入区域的js文件

<script src="./jiujiang.js"></script>

3、在地图加载后,增加图层,在这个图层上绘制type='fill'也就是区域,在'paint'里设置绘制的区域样式

map.on('load', function () {map.addLayer({'id': 'jiujiang','type': 'fill','source': {'type': 'geojson','data': jiujiangJSON},'layout': {},'paint': {'fill-color': '#088','fill-opacity': 0.4,}});
});

其中:
type - 放的是绘制的类型,此处是fill,如果要绘制线条,就设置为line

source - 其中的data放json数据,由于头部引入了js文件,直接使用js文件里的变量名jiujiang JSON来获取json数据

paint - 在这里配置绘图的样式,比如区域颜色,透明度等,这里设置的属性应该和type对应,可以去查看开发文档,有详细说明。或者看此链接地图样式有详细整理

4、如果希望区域的边界线条更明显,则需要另外实现一个图层来绘制线条,因为fill相关属性没有设置线条宽度的属性

map.addLayer({'id': 'jiujiangline','type': 'line','source': {'type': 'geojson','data': jiujiangJSON},'layout': {},'paint': {'line-color': 'blue','line-width': 3}
});

效果如下:

在地图上画上点

1、获取这个区域的一些点坐标,放入json文件

 var pointsJSON = {"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "Point","coordinates": [118.176944, 31.18]},}, {"type": "Feature","geometry": {"type": "Point","coordinates": [118.103611, 31.261944]},},{"type": "Feature","geometry": {"type": "Point","coordinates": [118.039654, 31.19909]},},{"type": "Feature","geometry": {"type": "Point","coordinates": [118.0209734, 31.282277]},},{"type": "Feature","geometry": {"type": "Point","coordinates": [118.109444, 31.284444]},}]}

2、由于要使用自定义的点图标,因此使用loadImage方法,加载图标

*注意:如果使用vscode练习,会出现本地路径访问异常的问题,下载一个Live Server的插件,并点击右下角GoLive可以解决问题。

map.loadImage('./site.png', function(error, image) {if (error) throw error;map.addImage('pointImg', image);map.addLayer({"id": "points","type": "symbol","source": {"type": "geojson","data": pointsJSON},"layout": {"icon-image": "pointImg","icon-size": 0.1}});
});

data里的数据和区域部分处理方式相同,icon-size设置图标在地图上的显示大小,效果如下:

瓦片地图原理理解

原理

正确加载主要是依托经纬度和瓦片的互转算法

瓦片地图背景理解


瓦片分层理解:

图上分了三层,可以想象最开始地图展示的中国地图是最上层,只需要一张瓦片(256px*256px);接着对地图进行放大,页面展示出了某省地图,此时信息量变多,像素变高,需要很多张瓦片显示。

编码方式

谷歌xyz

瓦片的坐标原点在世界地图的左上角,西经180 º北纬85 º左右,Z表示缩放层级,瓦片编号规则如下图所示:

使用的地图商:
高德地图、谷歌地图、OpenStreetMap

百度xyz

瓦片坐标的原点在本初子午线和赤道的交汇处(经度0纬度0),Z从1开始,在最高级就把地图分为四块瓦片,瓦片编号规则如下图所示:

mapbpx-gl纠偏

mapbox的地图资源基于OSM,其坐标系使用的是WGS84
高德地图和腾讯地图坐标系是GCJ02

坐标系转换方法

  • 方法定义
const {PI} = Math// 球体长半径const SPHERE_RADIUS = 6378245.0// 扁率const FLATNESS = 0.00669342162296594323const ER = 20037508.342789function transformLat(inputLng, inputLat) {const lat = +inputLatconst lng = +inputLnglet ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0return ret}function transformLng(inputLng, inputLat) {const lat = +inputLatconst lng = +inputLnglet ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0return ret}/*** 判断是否在国内,不在国内则不做偏移* @param lng* @param lat* @returns {boolean}*/function outOfChina(inputLng, inputLat) {const lat = +inputLatconst lng = +inputLng// 纬度 3.86~53.55, 经度 73.66~135.05return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55)}
  • wgs84 转 gcj02
function wgs84ToGcj02(inputLng, inputLat) {const lat = +inputLatconst lng = +inputLngif (outOfChina(lng, lat)) {return [lng, lat]} else {let dLat = transformLat(lng - 105.0, lat - 35.0)let dLng = transformLng(lng - 105.0, lat - 35.0)const radLat = lat / 180.0 * PIlet magic = Math.sin(radLat)magic = 1 - FLATNESS * magic * magicconst sqrtMagic = Math.sqrt(magic)dLat = (dLat * 180.0) / ((SPHERE_RADIUS * (1 - FLATNESS)) / (magic * sqrtMagic) * PI)dLng = (dLng * 180.0) / (SPHERE_RADIUS / sqrtMagic * Math.cos(radLat) * PI)const mgLat = lat + dLatconst mgLng = lng + dLngreturn [mgLng, mgLat]}}
  • gcj02 转 wgs84
function gcj02towgs84(lng, lat){if (outOfChina(lng, lat)){return [lng, lat]}else {dlat = transformLat(lng - 105.0, lat - 35.0)dlng = transformLng(lng - 105.0, lat - 35.0)radlat = lat / 180.0 * PImagic = Math.sin(radlat)magic = 1 - FLATNESS * magic * magicsqrtmagic = Math.sqrt(magic)dlat = (dlat * 180.0) / ((SPHERE_RADIUS * (1 - FLATNESS)) / (magic * sqrtmagic) * PI)dlng = (dlng * 180.0) / (SPHERE_RADIUS / sqrtmagic * Math.cos(radlat) * PI)mglat = lat + dlatmglng = lng + dlngreturn [lng * 2 - mglng, lat * 2 - mglat]}    }

学习整合高德地图的方法

1、尝试在mapbox上再加载高德API(更美观,道路等更全)

//头部加上
<!-- 加载地图JSAPI脚本 --><script src="https://webapi.amap.com/maps?v=2.0&key=096ec74ca9fc2c8f7958c064fc918827"></script>

2、设置全局变量,确定中心和图层

const center = [118.450393,31.341593]
const zoom = 11

3、初始化地图

const amapMap = new AMap.Map('amap', {viewMode: '3D',pitch: 0,zoom: zoom + 1, //初始化地图层级center: aMapCenter //初始化地图中心点
})

4、由于center此时的经纬度是WGS84下的,因此需要通过转换的方法,转换成GJC02,这样高德地图的中心就可以定在正确的位置

const aMapCenter = wgs84ToGcj02(center[0],center[1])

5、监听mapbox的move和zoom事件(也就是拖动和放大缩小)

mapboxMap.on('move', () => {linkAMap()
})mapboxMap.on('zoom', () => {linkAMap()
});

6、linkAMap方法,就是让地图的中心变化,setZoom和setCenter方法中第二个参数定为true,作用是地图不是缓慢变化的,不会呈现移动的效果

function linkAMap(){const mapboxZoom = mapboxMap.getZoom() + 1const mapboxCenter = mapboxMap.getCenter()amapMap.setZoom(mapboxZoom,true)amapMap.setCenter(wgs84ToGcj02(mapboxCenter.lng,mapboxCenter.lat),true)
}

其中调用了坐标系转换方法

同步去通过转换让高德的定位和mapbox重合,此时两个容器就重叠了

此时上点,由于是以WGS84为坐标系,因此坐标还应是wgs84下坐标可以看到成功显示,位置正确:

学习使用纠偏插件

结果也显示正确

插件介绍地址:mapboxgl 纠偏百度地图 - 知乎 (zhihu.com)
效果:

此原理和整合不同,是加载每张瓦片时进行一个对应

最后 + 实例仓库地址

此文主要是我对于mapbox的学习和实验,在实践中加强对地图知识的认知,其中借鉴了许多优秀的文章,希望能帮助到有需要的人,如有问题欢迎交流~

个人demo链接,可供参考:mapbox本文demo

【MapBox实战】生成地图+绘制区域+纠偏相关推荐

  1. Android高德地图绘制区域,Android高德地图多边形的绘制与编辑

    最近项目中用到了一个高德地图画地块的功能,差了一下api,发现只有js有相关的方法,所以仿照js的交互方式做了一个android版的多边形绘制与编辑. 先不说,上一张效果图 完成效果图 1.通过观察, ...

  2. 【unity实战】随机地下城生成2——绘制地图Tilemap的使用及一些技巧的使用(含源码)

    绘制房间 修改素材配置 切割图片 绘制瓦片地图 先新建我们的调色盘,保存好位置 拖入我们刚才切片好的素材 在房间预设体创建我们的瓦片地图 绘制地图的小技巧 点选移动适合的瓦片移动到位置上绘画 框选复制 ...

  3. Echarts地图 绘制自定义区域 - geojson.io使用方法

    Echarts地图 绘制自定义区域 & 解决区域点击无效 1. 绘制地图自定义区域 需求:绘制带高新区的河源市地图,目前百度地图json还没有此新区.需手动绘制. STEP1:获取市区json ...

  4. vue+echarts 区域地图绘制(街道)

    vue+echarts 区域地图绘制(街道) 1.以下是本人参考别的博主的链接 2.需要用到的资源 3.获取地图JSON (1)[阿里云](http://datav.aliyun.com/portal ...

  5. 【vue项目使用echarts实现区域地图绘制,且可点击单独区域】

    vue项目使用echarts实现区域地图绘制,且可点击单独区域 - 菜鸟程序员的总结 - 博客园

  6. 2020统计局的行政划分表_天津市第七次全国人口普查区域划分与地图绘制试点工作在西青区开展...

    1 日前,天津市第七次全国人口普查区域划分与地图绘制试点工作在西青区张家窝镇顺利完成.天津市统计局人口处二级调研员梁振华同志亲临试点现场,主持召开试点工作培训及相关工作的开展,市统计局人口处.西青区统 ...

  7. leaflet地图原理_leaflet绘制区域(仿高德地图效果)

    效果: 脚本: var map = L.map('map', { center: [25.1026993454,102.9312515259], // 地图中心点(昆明) zoom: 16, // 地 ...

  8. 使用 Cartopy 绘制区域地图

    使用 Cartopy 绘制区域地图 绘制亚洲地区的地形图(Miller 投影),并根据中国地区的 shapefile 绘制各个省份自治区的边界. import matplotlib.pyplot as ...

  9. 解决高德地图锁屏黑屏定位不更新,高德地图绘制定位轨迹,高德定位判断定位停留点,高德地图将所有坐标绘制在可视区域内

    本文章主要介绍 高德定位锁屏黑屏定位不更新的问题. 实现流程是:程序开始阶段正常执行定位,注册监听锁屏监听,唤醒cpu监听,当锁屏 广播每2秒发起一起单次定位唤醒.源码如下: package net. ...

最新文章

  1. R语言str_flatten函数通过自定义字符连接(concatenate)字符串向量中的字符串
  2. codeforces水题100道 第十一题 Codeforces Round #143 (Div. 2) A. Team (brute force)
  3. pytorch笔记:pytorch的乘法
  4. 【LeetCode】5.最长回文子串
  5. golang获取结构体中的tag_26. Go 语言中结构体的 Tag 用法
  6. VC 2010的MFC函数,CMFCVisualManager::GetInstance()可能导致内存泄露
  7. 数组索引必须为正整数或逻辑值_Office 365函数新世界——动态数组
  8. Linux内核分析 - 网络[八补]:IP协议补充
  9. 计算机毕业设计中用Java 实现系统权限控制
  10. 转 Ubuntu16.04+QT4.8.7开发环境搭建
  11. Shell脚本:Linux Shell脚本学习指南(超详细)
  12. CAD 开发 图案填充
  13. 小颖java源代码反编译_小颖JAVA源代码反编译工具下载|
  14. 单纯形法中大m法_单纯形法(大M法)
  15. IDL处理葵花8Himawari-8标准HSD数据——制作大气校正数据集(卫星角度数据)
  16. Mysql海量数据处理
  17. 机器学习第九章聚类Kmeans练习(西瓜数据集4.0)
  18. C盘用户文件夹下的AppData文件夹里放的是什么?
  19. Selenium 导航操作 Navigating
  20. 测试开发是什么?为什么现在那么多公司都要招聘测试开发?

热门文章

  1. 无法打开内核设备“\.\VMCIDev\VMX”: 操作成功完成。是否在安装 VMware Workstation 后重新引导? 模块“DevicePowerOn”启动失败。 未能启动虚拟机。
  2. git撤回上一次的提交
  3. 计算机系统瘫痪重装系统文件怎么保存,我的电脑已经瘫痪,进不去了,要重做系统,现在应该怎么把C盘备份呢? 爱问知识人...
  4. You Only Look Once: Unified, Real-Time Object Detection (YOLO 论文翻译)
  5. Frame 与JFrame 的区别
  6. 【Multisim仿真】二极管加正向和反向电压测量实验
  7. 第一周-2.3成绩排序
  8. m基于ACO蚁群优化的FCM模糊聚类算法matlab仿真
  9. ue4网格转地形_不用建模就能生成地形,SU怎么办到的?!
  10. matlab换挡程序,一种基于MATLAB换挡过程中快速锁定分析数据的方法与流程