WebGIS(Web Map)基础概念简介

techbrood 发表于 2021-04-11 19:44:18

标签: webgl, gis, map, 地图

- +

大地水准面 (geoid)

大地水准面是海洋表面在排除风力、潮汐等其它影响,只考虑重力和自转影响下的形状,这个形状延伸过陆地,生成一个密闭的曲面。虽然我们通常说地球是一个球体或者椭球体,但是由于地球引力分布不均(因为密度不同等原因),大地水准面是一个不规则的光滑曲面。虽然不规则,但是可以近似地表示为一个椭球体,这个椭球体被 称为参考椭球体(Reference ellipsoid)。大地水准面相对于参考椭球体的高度被称为 Undulation of the geoid 。这个波动并不是非常大,最高在冰岛为85m,最低在印度南部为 −106 m,一共不到200m。

参考椭球体(Reference ellipsoid)

参考椭球体(Reference ellipsoid)是一个数学上定义的地球表面,它近似于大地水准面。因为是几何模型,可以用长半轴、短半轴和扁率来确定。我们通常所说的经度、纬度以及高度都以此为基础。

一方面,我们对地球形状的测量随着时间迁移而不断精确,另一方面,因为大地水准面并不规则,地球上不同地区往往需要使用不同的参考椭球体,来尽可能适合当地的大地水准面。历史上出现了很多不同的参考椭球体,很多还仍然在使用中。国内过去使用过“北京54”和“西安90”两个坐标系,其中北京54使用的是克拉索夫斯基(Krasovsky)1940的参考椭球,西安80使用的是1975年国际大地测量与地球物理联合会第16届大会推荐的参考椭球。当前世界范围内更普遍使用的是WGS所定义的参考椭球。


有了参考椭球体这样的几何模型后,就可以定义坐标系来进行描述位置,测量距离等操作,使用相同的坐标系,可以保证同样坐标下的位置是相同的,同样的测量得到的结果也是相同的。通常有两种坐标系 地理坐标系(geographic coordinate systems) 和 投影坐标系(projected coordinate systems)。

地理坐标系(Geographic coordinate system)

地理坐标系一般是指由经度、纬度和高度组成的坐标系,能够标示地球上的任何一个位置。前面提到了,不同地区可能会使用不同的参考椭球体,即使是使用相同的椭球体,也可能会为了让椭球体更好地吻合当地的大地水准面,而调整椭球体的方位,甚至大小。这就需要使用不同的大地测量系统(Geodetic datum)来标识。因此,对于地球上某一个位置来说,使用不同的测量系统,得到的坐标是不一样的。我们在处理地理数据时,必须先确认数据所用的测量系统。事实上,随着我们对地球形状测量的越来越精确,北美使用的 NAD83 基准和欧洲使用的 ETRS89 基准,与 WGS 84 基准是基本一致的,甚至我国的 CGCS2000 与WGS84之间的差异也是非常小的。但是差异非常小,不代表完全一致,以 NAD83 为例,因为它要保证北美地区的恒定,所以它与 WGS84 之间的差异在不断变化,对于美国大部分地区来说,每年有1-2cm的差异。

投影坐标系(Projected coordinate systems)

地理坐标系是三维的,我们要在地图或者屏幕上显示就需要转化为二维,这被称为投影(Map projection)。显而易见的是,从三维到二维的转化,必然会导致变形和失真,失真是不可避免的,但是不同投影下会有不同的失真,这让我们可以有得选择。常用的投影有等矩矩形投影(Platte Carre)和墨卡托投影(Mercator):

2.png

左图表示地球球面上大小相同的圆形,右上为墨卡托投影,投影后仍然是圆形,但是在高纬度时物体被严重放大了。右下为等距投影,物体的大小变化不是那么明显,但是图像被拉长了。Platte Carre 投影因为在投影上有扭曲,并不适合于航海等活动,但是因为坐标与像素之间的对应关系十分简单,非常适合于栅格图的展示,Platte Carre 投影是很多GIS 软件的默认投影。

需要注意的是,对于墨卡托投影来说,越到高纬度,大小扭曲越严重,到两极会被放到无限大,所以,墨卡托投影无法显示极地地区。下图来自维基百科,可以看到墨卡托投影下每个国家的大小和实际大小的差异。但是正形性直角直线这两个特点,让它非常适合于航海导航。

3.gif


对于 WebGIS而言,用得最多的是EPSG:4326 (WGS84) 和 EPSG:3857(Pseudo-Mercator)。

EPSG:4326 (WGS84)

WGS84 是目前最流行的地理坐标系统。在国际上,每个坐标系统都会被分配一个 EPSG 代码,EPSG:4326 就是 WGS84 的代码。GPS是基于WGS84的,所以通常我们得到的坐标数据都是WGS84的。一般我们在存储数据时,仍然按WGS84存储。

EPSG:3857 (Pseudo-Mercator)

伪墨卡托投影,也被称为球体墨卡托,Web Mercator。它是基于墨卡托投影的,把 WGS84坐标系投影到正方形。我们前面已经知道 WGS84 是基于椭球体的,但是伪墨卡托投影把坐标投影到球体上,这导致两极的失真变大,但是却更容易计算。这也许是为什么被称为”伪“墨卡托吧。另外,伪墨卡托投影还切掉了南北85.051129°纬度以上的地区,以保证整个投影是正方形的。因为墨卡托投影等正形性的特点,在不同层级的图层上物体的形状保持不变,一个正方形可以不断被划分为更多更小的正方形以显示更清晰的细节。很明显,伪墨卡托坐标系是非常显示数据,但是不适合存储数据的,通常我们使用WGS84 存储数据,使用伪墨卡托显示数据。

Web Mercator 最早是由 Google 提出的,当前已经成为 Web Map 的事实标准。但是也许是由于上面”伪“的原因,最初 Web Mercator 被拒绝分配EPSG 代码。于是大家普遍使用EPSG:900913的非官方代码来代表它。直到2008年,才被分配了EPSG:3785的代码,但在同一年没多久,又被弃用,重新分配了 EPSG:3857 的正式代码,沿用至今。

possitive(21) views6128 comments23

发送私信

最新评论

CDbException

CDbException

CDbCommand 无法执行 SQL 语句: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 1' at line 1

程序日志
时间 等级 类别 信息
22:14:56.983637 error system.db.CDbCommand
CDbCommand::fetch() failed: SQLSTATE[42000]: Syntax error or access
violation: 1064 You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near
'LIMIT 1' at line 1. The SQL statement executed was: SELECT * FROM
`user_profiles` `t` WHERE UserId =  LIMIT 1.
22:14:56.986815 error exception.CDbException
CDbException: CDbCommand 无法执行 SQL 语句: SQLSTATE[42000]: Syntax
error or access violation: 1064 You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for the right
syntax to use near 'LIMIT 1' at line 1 in
/home/www/sites/framework/db/CDbCommand.php:541
Stack trace:
#0 /home/www/sites/framework/db/CDbCommand.php(414):
CDbCommand->queryInternal('fetch', Array, Array)
#1 /home/www/sites/framework/db/ar/CActiveRecord.php(1297):
CDbCommand->queryRow()
#2 /home/www/sites/framework/db/ar/CActiveRecord.php(1402):
CActiveRecord->query(Object(CDbCriteria))
#3
/home/www/sites/techbrood/themes/techbrood/Social/views/comment/_view.php(4):
CActiveRecord->find('UserId = ')
#4 /home/www/sites/framework/web/CBaseController.php(130):
require('/home/www/sites...')
#5 /home/www/sites/framework/web/CBaseController.php(95):
CBaseController->renderInternal('/home/www/sites...', Array, false)
#6 /home/www/sites/framework/zii/widgets/CListView.php(281):
CBaseController->renderFile('/home/www/sites...', Array)
#7 /home/www/sites/framework/zii/widgets/CBaseListView.php(160):
CListView->renderItems()
#8 [internal function]: CBaseListView->renderSection(Array)
#9 /home/www/sites/framework/zii/widgets/CBaseListView.php(143):
preg_replace_callback('/{(\\w+)}/', Array, '{summary}\n{sort...')
#10 /home/www/sites/framework/zii/widgets/CBaseListView.php(128):
CBaseListView->renderContent()
#11 /home/www/sites/framework/web/CBaseController.php(173):
CBaseListView->run()
#12
/home/www/sites/techbrood/themes/techbrood/Social/views/comment/commentList.php(13):
CBaseController->widget('zii.widgets.CLi...', Array)
#13 /home/www/sites/framework/web/CBaseController.php(126):
require('/home/www/sites...')
#14 /home/www/sites/framework/web/CBaseController.php(95):
CBaseController->renderInternal('/home/www/sites...', Array, true)
#15 /home/www/sites/techbrood/protected/base/AppWidget.php(162):
CBaseController->renderFile('/home/www/sites...', Array, true)
#16
/home/www/sites/techbrood/themes/techbrood/widgets/News/ArticleDetails.php(79):
AppWidget->renderPartial('Social.views.co...', Array)
#17 /home/www/sites/framework/web/CBaseController.php(126):
require('/home/www/sites...')
#18 /home/www/sites/framework/web/CBaseController.php(95):
CBaseController->renderInternal('/home/www/sites...', Array, true)
#19 /home/www/sites/framework/web/widgets/CWidget.php(243):
CBaseController->renderFile('/home/www/sites...', Array, true)
#20 /home/www/sites/techbrood/protected/base/AppWidget.php(141):
CWidget->render('ArticleDetails', Array, true)
#21
/home/www/sites/techbrood/protected/modules/News/components/ArticleDetailsWidget.php(65):
AppWidget->render('ArticleDetails', Array)
#22
/home/www/sites/techbrood/protected/extensions/helpers/Template.php(38):
ArticleDetailsWidget->run()
#23 /home/www/sites/techbrood/themes/techbrood/views/news-details.php(7):
Template::widget('ARTICLE_DETAIL', 'application.mod...')
#24 /home/www/sites/framework/web/CBaseController.php(126):
require('/home/www/sites...')
#25 /home/www/sites/framework/web/CBaseController.php(95):
CBaseController->renderInternal('/home/www/sites...', NULL, true)
#26 /home/www/sites/framework/web/CController.php(869):
CBaseController->renderFile('/home/www/sites...', NULL, true)
#27 /home/www/sites/framework/web/CController.php(782):
CController->renderPartial('/news-details', NULL, true)
#28
/home/www/sites/techbrood/protected/controllers/CmsBaseController.php(82):
CController->render('/news-details')
#29
/home/www/sites/techbrood/protected/controllers/DefaultController.php(40):
CmsBaseController->showTemplate()
#30 /home/www/sites/framework/web/actions/CInlineAction.php(49):
DefaultController->actionIndex()
#31 /home/www/sites/framework/web/CController.php(308):
CInlineAction->runWithParams(Array)
#32 /home/www/sites/framework/web/CController.php(286):
CController->runAction(Object(CInlineAction))
#33 /home/www/sites/framework/web/CController.php(265):
CController->runActionWithFilters(Object(CInlineAction), Array)
#34 /home/www/sites/framework/web/CWebApplication.php(282):
CController->run('index')
#35 /home/www/sites/framework/web/CWebApplication.php(141):
CWebApplication->runController('default/index')
#36 /home/www/sites/framework/base/CApplication.php(168):
CWebApplication->processRequest()
#37 /home/www/sites/techbrood/index.php(31): CApplication->run()
#38 {main}
REQUEST_URI=/zh/news/webgl/webgis%EF%BC%88web-map%EF%BC%89%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E7%AE%80%E4%BB%8B.html
---