精思入神分享 http://blog.sciencenet.cn/u/chinaontolog 从事生物多样性信息学与软件工程研究。

博文

GPS航迹文件解析与照片地标自动设定

已有 5128 次阅读 2010-8-20 19:14 |个人分类:生物多样性信息学|系统分类:科研笔记

中国自然标本馆已经实现了相关的功能,目前的解析精度有些问题。

中国自然标本馆——野外调查数据坐标的计算与显示

gpicsync   http://code.google.com/p/gpicsync/  功能相似的软件

GPSBabel  http://www.gpsbabel.org   经典的坐标、航迹解析软件

EXIFTool  http://www.sno.phy.queensu.ca/~phil/exiftool/   照片元信息读写工具

临时记录一些测试数据:

http://www.cfh.ac.cn/User/ShowPhoto.aspx?albumid=1f4dcc55-c0b6-4ff0-898d-cb81c99540bd&&page=1&&photoid=1c052d4e-d31e-4bab-a6a7-beb49d6ff061 

照片,

【1】 CFH 中的EXIF解析,表示为  33:29:39.04368     111:56:28.8978

【2】CFH 最给出的是 N33.4942   E111.941

【3】使用 ExifTool 得到的坐标表示为  33°29'39.04"N   111°56'28.90"E

【4】使用 GE ,输入【3】, GE保存为 <coordinates>111.9413611111111,33.49417777777778,0</coordinates>

需要注意的是 GE 当中,无法输入【1】,输入后自动被4舍5入,变成了【3】 

===============================

如果要算地球上任意两地的距离,
公式为:【距离S=经度差*111*cos纬度】

经线上跨纬度1度=111千米
纬线上跨经度1度=111*cosA千米,其中A是纬度

例如,甲乙两地都在亚洲,甲乙的地理坐标分别为 甲30°N,36°E ;乙30°N,48°E,两地经度差为12°,所以两地距离大约为12*111*cos30=1150千米。

结论:

如果使用 GMap 的表示方式(度),则保留到小数后面第5位实际上就够了,再多意义不大。

0.00001  表示 1.1 米(最多);第6位小数表示0.1m,已经超出GPS的精度范围,是无意义的。

==============================

CFH 解析组件当中,使用了 Single 类型,导致精度下降。

修改为 Double 后解析数据正确。

但是如果按照【1】的数据计算,结果与GE不符,实际计算当中,最后的秒部分数据,只保留两位小数,然后计算,结果就与GE相同。

根据经纬度计算距离的在线工具: http://jan.ucc.nau.edu/~cvm/latlongdist.html

具体算法:(引用自 http://jan.ucc.nau.edu/~cvm/latlon_formula.html

Formula and code for calculating distance based on two lat/lon locations

The following is the formula I use in perl to do the calculations.  Perl expects all of the angles to be in radians.

return &acos(cos($a1)*cos($b1)*cos($a2)*cos($b2) + cos($a1)*sin($b1)*cos($a2)*sin($b2) + sin($a1)*sin($a2)) * $r;

Where:

$a1 = lat1 in radians
$
b1 = lon1 in radians
$a2 = lat2 in radians
$b2 = lon2 in radians
$r = radius of the earth in whatever units you want

The values I use for radius of the earth are:

地球半径取值

3963.1 statute miles 英里
3443.9 nautical miles 海里
6378 km 公里

To convert the decimal degrees to radians use the following perl.

# define an accurate value for PI

$pi = atan2(1,1) * 4;

#
# make sure the sign of the angle is correct for the direction
# West an South are negative angles
#

$degrees = $degrees * -1 if $direction =~ /[WwSs]/;
$radians = $degrees*($pi/180);

To convert degree minutes and seconds to decimal degrees use the following perl formula.

$dec_deg = $deg + ($min + $sec/60)/60;

Finally, there is no acos function in perl so here is the function I use.  I don't remember where I got the math for this.

# subroutine acos
#
# input: an angle in radians
#
# output: returns the arc cosine of the angle
#
# description: this is needed because perl does not provide an arc cosine function
sub acos {
   my($x) = @_;
   my $ret = atan2(sqrt(1 - $x**2), $x);
   return $ret;
}


https://blog.sciencenet.cn/blog-344159-354800.html

上一篇:抬头远望,低头走路
下一篇:个人全英文收藏主页
收藏 IP: .*| 热度|

0

发表评论 评论 (1 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-9-27 13:16

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部