基于PostGIS的火星坐标,百度坐标批量互转

一 背景

GIS项目中底图是必不可少的,绝大部分GIS项目使用的底图是基于高德,谷歌,百度,天地图等互联网(在线/离线)底图。由于我国特殊国情,公众版地理信息服务(包括电子底图)都要进行各种坐标偏移旋转等数据加密处理,并获取国土资源部数据审查并颁发审图号才可公开发布。企业的GIS数据都是通过传感器或者实地测量获得的非加密的WGS84坐标(即常用的gps那种坐标),当企业将自己的业务数据叠加到互联网底图时,不可避免出现图层叠加偏移问题,如下图:

图层叠加偏移.png

底图偏移情况总结如下:

  • 百度底图,最坑爹的,bd-09坐标,二次加偏。
  • 高德,谷歌底图,GCJ-02坐标,俗称的“火星坐标系”。
  • 天地图,osm底图,通常认为是不偏移底图。

二 解决方案与存在问题

2.1 解决方案

由于底图是不可改变的,唯一能解决叠加偏移问题的方法是:将自己的业务数据根据一定的偏移公式转换,从而使数据的坐标与底图达到相对对齐。当前主流编程语言,都有类似处理坐标偏移的公式换算库,满足不同语言开发的GIS项目需求。比如如下几个地址:
https://github.com/FreeGIS/CoordinateTransform
https://github.com/wandergis/coordtransform

2.2 存在问题

  • 不支持批量计算。
    当前各种坐标转换库,都是实现单个点坐标转到底图对应的坐标。但实际上,GIS存在 图形复杂数据量大的通用特征,每个图层都有大量图形记录,每个图形记录,其图形常用分类就有点线面多点多线多面等六种,每个图形都可能由非常多的坐标点组成。业务需求最好是支持批量计算。
  • 动态计算,显示效率低。
    当前各种坐标转换库,都是基于前后台的语言实现的,每次都要获取数据源数据,再通过实时计算展示,当数据复杂,数据量大时候,效率很成问题。解决办法通常是,后台先读取数据源,然后计算好,最后将计算结果重新存入库里,项目使用时,直接读取计算好的结果。 捯饬的费劲不?
  • 数据转换服务维护复杂。
    当数据库数据发生变更时,转换服务要能增量得到变更的数据,然后计算,然后再更新数据库已存储的转换结果。整个架构要是能自动维护好,还是很复杂的。

三 PostGIS方案

基于现有方案普遍存在的问题,笔者基于最常用的开源GIS空间数据库PostGIS开发了一个function,基于一行sql搞定一切的是思想,满足使用PostGIS的开发者,简单的处理这些坐标转换问题。PostGIS实现的仓库如下:
https://github.com/FreeGIS/Postgis_Coordinate_Transform
实现功能列表如下:

  • 支持WGS84与bd-09,gcj-02坐标系,百度经纬度与百度墨卡托之间互转。
  • 支持点线面多点多线多面的复杂图形批量转换。
  • 支持对整个表批处理转换。

约束:

  • 要求转换的表是基于PostGIS创建的空间关系表
    示例支持的表:
create table point_test(
  gid serial primary key,
  name text,
  geom geometry(Point,4326)
);

不支持的表:

create table point_test(
  gid serial primary key,
  name text,
  lon numeric,   --经度
  lat numeric     --纬度
);

不支持的表是普通关系表,非空间图形表。

  • 要求转换的图形必须是二维图形
    当前暂不支持三维或者多维,如带Z值的高程,带M值的测量值等,由于过于复杂,目前笔者暂未有时间去过多实现。
  • 转换表图形坐标系必须是epsg:4326
    除了将百度墨卡托坐标转百度经纬度外,其他转换方式,必须保证转换表的坐标系是4326,其他坐标系,需要用户使用ST_Transform函数,将其数据先转到4326坐标系下,再使用该工具。百度墨卡托坐标转百度经纬度转换,数据源必须是3857的。
  • 图形数据是点线面多点多线多面
    仅仅支持Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon六种明确类型。其他的PostGIS类型由于不常用,且不严格规范,通常不用于标准的空间数据库类型,暂时不考虑实现。

3.1 安装应用

前提:PostGIS用户,图形表是基于PostGIS的空间关系表。
示例:在test库安装转换方法

[postgres@sss~]$ psql -d test
psql (11.1)
Type "help" for help.

test=# \i FreeGIS_Coordinate_Transform.sql
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE TYPE
CREATE FUNCTION

方法简介:

FreeGIS_Coordinate_Transform(
    in schema_name text,
    in table_name text,
    in transform_type FreeGIS_coordinate_transform_type
)

schema_name:表的schema名称。
table_name:表的名称。
transform_type:转换类型,枚举型,类型如下:

BD2GCJ:百度经纬度 转 火星经纬度。
GCJ2BD:火星经纬度 转 百度经纬度。
WGS2GCJ:WGS84经纬度 转 火星经纬度
GCJ2WGS:火星经纬度 转 WGS84经纬度。
BD2WGS:百度经纬度 转 WGS84经纬度。
WGS2BD:WGS84经纬度 转 百度经纬度。
BDWGS2BDMKT:百度经纬度 转 百度墨卡托。
BDMKT2BDWGS:百度墨卡托 转 百度经纬度。
WGS2BDMKT: WGS84经纬度 转 百度墨卡托。
BDMKT2WGS:百度墨卡托 转 WGS84经纬度。
转换批处理执行:

--将public.test表从wgs84坐标转火星坐标。
select FreeGIS_Coordinate_Transform('public','test','WGS2GCJ');

执行后,test表新增了一个transform_geom字段,就是转换后的结果。


转换结果

3.2 底图叠加示例

3.2.1 叠加osm,天地图底图

企业的坐标,可不做处理,直接叠加。


点叠加osm

3.2.2 叠加谷歌,高德底图

将企业的数据,使用wgs84转火星坐标,然后叠加:

select FreeGIS_Coordinate_Transform('public','test_pt','WGS2GCJ');

执行展示:

--transform_geom字段存储了转换结果,示例使用如下:
create or replace view v_test_pt as select gid,name,transform_geom as geom from test_pt;

将v_test_pt 发布成地理服务后,叠加地图如下:


转换后叠加osm,发生偏移

转换后叠加谷歌或高德,位置匹配

依次制作了测试线和面,测试情况如下


线 osm

线 谷歌
面 osm

面 谷歌

3.2.3 叠加百度底图

将企业的数据,使用wgs84转百度墨卡托坐标,然后叠加:

select FreeGIS_Coordinate_Transform('public','test_pg','WGS2BDMKT');
面 百度

说明下:将wgs批量转到百度地图上,需要先转到百度经纬,再从百度经纬转到百度墨卡托,这些步骤被WGS2BDMKT封装了。
百度很麻烦很麻烦!!!
其他底图的偏移操作是,将wgs偏移到对应的底图,然后使用标准的墨卡托投影函数叠加到底图上即可。
百度底图操作是,将wgs偏移到对应的底图,但是底图是墨卡托坐标系,百度经纬度不能使用标准的墨卡托投影函数,二次加密的,所以要写个自定义函数,将百度经纬度自己转到百度墨卡托,才能叠加到百度底图。
这是其他转换库都没注意到,没涉及到的,坑爹的百度!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容