美文网首页地图瓦片
地图技术与Jingoal海外地图业务的实现探索

地图技术与Jingoal海外地图业务的实现探索

作者: 小鱼游儿 | 来源:发表于2017-07-18 10:27 被阅读0次

    这篇文章是我前段时间在组内进行技术分享的一个整理,通过这篇文章可以帮你了解我们常见的地图技术。
    文章内容主要包括三个部分,一是我们常见的地图(百度地图、高德地图等)是如何从基本的底层地图数据展示到前端(浏览器、手机等)的。二是介绍了一整套的开源地图解决框架,并且通过框架模拟了一张魔兽世界地图jpg文件从切片到发布再到解析到浏览器上的一整套流程。第三部分则是回顾了今目标android端在解决海外地图相关业务中的一些尝试。


    一、地图的显示

    1. 卫星,航拍生成原始地图
    • 地图显示的第一步就是获取地图数据了,我们一般通过卫星和航拍获得原始的地图数据,如图,我们得到了一整张的世界地图。
    一张世界地图
    1. 原始地图切片(经纬度,投影)
    • 把一张世界地图显示到手机里是不可能的,所以就引入了金字塔模型的概念(也就是比例尺),我们可以根据不同的缩放比例,显示不同的分辨率。在地图应用中,我们用手指缩放和放大地图,地图显示大小的变换,都是基于金字塔模型来组织瓦片图的。我们一般按照制定的经纬度和投影的规则对地图进行切片,切片和对应级别的组织形式是一整张切成4份,这就是一个级别,然后每一小份在切4份,依次类推。通过下图可以看到,在这种通用的切片规则下,非洲西海岸就是经纬度的(0,0)点。
    按照规则对地图进行切片
    1. 地图切片发布成地图服务
    1. 前端框架解析地图服务展示地图(浏览器,手机view)
    • 大家可以看到,上面的地图服务打开后是以xml的形式提供的,所以,我们需要前端的框架来解析这种服务,展示地图。前端框架有很多,国内百度和高德都提供这种框架,开源世界也有OpenLayers这种免费好用的前端框架。我们打开百度地图的首页,通过浏览器看到的地图,就是通过百度的js框架解析地图服务所展示的。移动端的地图sdk也是一样的道理。
    高德地图
    • 一整套的开源地图解决方案
      1.地图服务发布:GeoServer
      GeoServer是一款基于JAVA的地图发布web应用。
      Geoserver官网
      2.地理解析数据库框架:gisgraphy
      gisgraphy是一款基于基于JAVA的地理解析/逆地理解析web应用,它的内置数据库是PostgreSQL+PostGIS扩展,有了它,你就可以制作基于空间的数据并进行存储,同时通过该框架生成地理解析/逆地理解析服务供其他人使用。
      gisgraphy官网
      3.前端框架:OpenLayers
      OpenLayers 是一个专为Web GIS 客户端开发提供的JavaScript 类库包,用于实现标准格式发布的地图数据访问,有了它,你就可以解析各大服务商的地图服务或者是你自己的,并展示到浏览器。
      OpenLayers官网

    二、制作魔兽地图


    1. 准备一张魔兽地图jpg的图片
    一张魔兽地图的jpg格式文件
    1. 魔兽地图jpg文件切成瓦片
    • 通过地图切片工具对魔兽地图进行切片,我这里切了5-10级别。
    瓦片级别为5-10 10级别下瓦片文件
    1. 发布魔兽地图服务
    • 我这里用开源框架GeoServer发布。
    Geoserver地图服务列表下的魔兽地图服务
    1. 百度api解析瓦片并展示到浏览器
    • 我这里用了百度的js框架解析魔兽地图服务。重点是下图这段代码,我这里加载的是本地瓦片,把它换成地图服务的链接也是一样的。
    tileLayerlei类的getTileUrl方法加载魔兽地图瓦片

    最终效果

    浏览器打开html文件,展示出了魔兽地图

    三、Jingoal海外地图,定位,逆地理解析的实现


    Jingoal安卓端主要用到涉及地图的框架有高德地图SDK,高德定位SDK,和OpenStreetMap的逆地理解析服务。

    1.地图实现

    地图显示遇到的困难

    • 高德地图sdk只提供的国内的地图数据,没有国外数据。

    解决方案

    1. 最开始设想是维护两套地图sdk,国内用高德地图,国外用谷歌地图。但是最大的问题是要想用谷歌地图必须要手机安装谷歌service,很遗憾,国内的android手机是没有的,并且安装需要翻墙。
    2. 解析海外地图的服务地址,通过高德SDK的TileOverLay类中的方法叠加海外地图图层 ,需要支出的是,找到的地图服务的规则必须是球面墨卡托投影的,否则和高德地图叠加的话位置会有偏移,最终找到了OpenStreetMap和GoogleMap的地图服务地址。
      OpenStreetMap:
      OpenStreetMap地图服务瓦片地址
      GoogleMap:
      GoogleMap地图服务瓦片地址
      在高德sdk下调用其他地图服务的关键方法如下图,怎么样,是不是和叠加魔兽地图差不多?其实原理都是一样的,Constants.Google_URL就是地图服务的地址。
    TileOverLay类的getTileUrl方法加载谷歌地图服务 高德地图sdk显示谷歌地图

    2.定位

    定位遇到的困难

    当时版本的定位sdk不支持海外定位,返回的坐标是“火星”坐标。
    小tips:地球坐标系是GPS返回的WGS-84坐标系下的经纬度,“火星”坐标系是我国出于保密出发,讲WGS-84坐标系做了非线性加密处理。
    定位遇到的问题

    解决方案

    地球<-->火星 坐标转换工具类
    https://github.com/wandergis/coordtransform

    3.逆地理解析

    逆地理解析遇到的困难

    1. 如何判断所在的位置是在国内还是国外
    2. 寻找靠谱的海外逆地理解析服务接口

    解决方案

    1. 关于判断坐标点是否在国内,github上有相关类库,通过下图方法判断,但是可以看到,边界区域会非常不准。
    通用解决方案,将中国切割成若干不规则矩形
    1. 海外位置的逆地理解析,基本上是找国外提供的逆地理解析服务来实现的,如下是找到的比较稳定可靠的解决方案
    • 微信的解决方案Foursquar
      Foursquar
    • GoogleMap的googleplace
      GooglePlace
    • OpenStreeMap的逆地理解析服务
      OpenStreeMap
      最终选择了OpenStreeMap的逆地理解析服务,因为返回的数据量小并且比较精确。

    截止到目前的解决方案

    上面的一些问题,其实通过高德不断的更新sdk已经很大程度上解决了,比如海外地图数据,3.2.1版本的高德sdk已经默认会在国外叠加谷歌地图的服务了。高德定位在2.0以后已经支持全球定位了,也就不用我们自己手动的进行火星和地球坐标的转换了。而判断是否在国外,高德定位2.1.0也已经提供的api,准确度也还可以。
    基于以上,今目标android端国外地图相关业务基本完成。
    下图是公司同事在美国出差帮忙测试的考勤应用,地图展示、定位和逆地理解析都比较准确。

    今目标西雅图分中心

    相关文章

      网友评论

        本文标题:地图技术与Jingoal海外地图业务的实现探索

        本文链接:https://www.haomeiwen.com/subject/dwvckxtx.html