文档章节

经纬度相关计算

h
 hellofox2000
发布于 2015/03/10 17:15
字数 1204
阅读 72
收藏 1
点赞 0
评论 0

近期做一个与GRPS相关的应用,涉及到经纬度的计算,找资料时颇费了一番功夫,特此将其相关资料整理了一下,发布出来,希望对用到的同学有所帮助。

经纬度算法

经纬度计算主要有两种: 
1. 知道两点的经纬度值,计算两点间的距离
2. 知道一点的经纬度,知道另一点相对于此点的角度,距离。计算另一点的经纬度信息 

对于第一种计算,网上搜索到大概有三种:
1. 把地球当球体,根据球面公式计算

2.根据如下公式进行计算:

其中A点纬度、经度分别为lat1和lon1,B点的纬度、经度分别为lat2和lon2,D为距离。 
这个公式搜索结果挺多,在百度搜索"经纬度 计算距离"很多都是这个公式。 

3. 从Google地图中反推出的算法(详见参考文档1)。公式如下图 

公式中经纬度均用弧度表示;lat1,lon1 表示A点经纬度,lat2,lon2 表示B点经纬度;
a= lat1lat2 为两点纬度之差 ; b= lon1 - lon2 为两点经度之差;
6378.137为地球半径,单位为公里;

第一种没做验证,第二种测试了一下,偏差较大(以圆明园、动物园之间的距离进行测定)目前采用的是第三种算法。
第二种计算,找到的资料很少,倒是找到不少遇到相同问题的朋友。不过最终还是找到了(详见参考文档2)。并使用第一种计算进行反验证,偏差很小。

代码


经纬度类 
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace GeoSite
{
    /// <summary>
    /// 经纬度表示类
    /// 经纬度计算主要有两种:
    /// 1. 知道两点的经纬度值,计算两点间的距离
    /// 2. 知道一点的经纬度,知道另一点相对于此点的角度,距离。计算另一点的经纬度信息
    /// http://blog.csdn.net/fdnike/archive/2007/07/18/1696603.aspx
    /// </summary>
    public class LatLon
    {
        /// <summary>
        /// 赤道半径 earth radius
        /// </summary>
        public const double EARTH_RADIUS = 6378137;

        /// <summary>
        /// 极半径 polar radius
        /// </summary>
        public const double POLAR_RADIUS = 6356725;

        /// <summary>
        /// 
        /// </summary>
        public LatLon()
        { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="lat">维度</param>
        /// <param name="lon">经度</param>
        public LatLon(double lat, double lon)
        {
            this.Lat = lat;
            this.Lon = lon;
        }

        /// <summary>
        /// 纬度
        /// </summary>
        public double Lat { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        public double Lon { get; set; }

        /// <summary>
        /// 纬度的弧度
        /// </summary>
        public double RadLat { get { return Lat * Math.PI / 180; } }

        /// <summary>
        /// 经度的弧度
        /// </summary>
        public double RadLon { get { return Lon * Math.PI / 180; } }

        /// <summary>
        /// ?
        /// </summary>
        public double Ec { get { return POLAR_RADIUS + (EARTH_RADIUS - POLAR_RADIUS) * (90 - Lat) / 90; } }

        /// <summary>
        /// ?
        /// </summary>
        public double Ed { get { return Ec * Math.Cos(RadLat); } }
    }
}


计算类:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace GeoSite
{
    /// <summary>
    /// Geo辅助类
    /// </summary>
    public static class GeoHelper
    {
        /// <summary>
        /// 根据两点的经纬度计算两点距离
        /// </summary>
        /// <param name="src">A点维度</param>        
        /// <param name="dest">B点经度</param>
        /// <returns></returns>
        public static double GetDistance(LatLon src, LatLon dest)
        {
            if (Math.Abs(src.Lat) > 90 || Math.Abs(dest.Lat) > 90 || Math.Abs(src.Lon) > 180 || Math.Abs(dest.Lon) > 180)
                throw new ArgumentException("经纬度信息不正确!");          

            double latDis = src.RadLat - dest.RadLat;
            double lonDis = src.RadLon - dest.RadLon;

            double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(latDis / 2), 2) + Math.Cos(src.Lat) * Math.Cos(dest.Lat) * Math.Pow(Math.Sin(lonDis / 2), 2)));
            s = s * LatLon.EARTH_RADIUS / 1000;
            s = Math.Round(s * 10000) / 10000;

            return s;            
        }

        /// <summary>
        /// 根据两点的经纬度计算两点距离
        /// </summary>
        /// <param name="lat1">A点维度</param>
        /// <param name="lon1">A点经度</param>
        /// <param name="lat2">B点维度</param>
        /// <param name="lon2">B点经度</param>
        /// <returns></returns>
        public static double GetDistance(double lat1, double lon1, double lat2, double lon2)
        {
            LatLon src = new LatLon(lat1, lon1);
            LatLon dest = new LatLon(lat2, lon2);
            return GetDistance(src, dest);
        }
        

        /// <summary>
        /// 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度
        /// </summary>
        /// <param name="a">已知点A</param>
        /// <param name="distance">B点到A点的距离 </param>
        /// <param name="angle">B点相对于A点的方位,12点钟方向为零度,角度顺时针增加</param>
        /// <returns>B点的经纬度坐标</returns>
        public static LatLon GetLatLon(LatLon a, double distance, double angle)
        {
            double dx = distance * 1000 * Math.Sin(angle * Math.PI / 180);
            double dy = distance * 1000 * Math.Cos(angle * Math.PI / 180);

            double lon = (dx / a.Ed + a.RadLon) * 180 / Math.PI;
            double lat = (dy / a.Ec + a.RadLat) * 180 / Math.PI;

            LatLon b = new LatLon(lat, lon);
            return b;
        }

        /// <summary>
        /// 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度
        /// </summary>
        /// <param name="longitude">已知点A经度</param>
        /// <param name="latitude">已知点A纬度</param>
        /// <param name="distance">B点到A点的距离</param>
        /// <param name="angle">B点相对于A点的方位,12点钟方向为零度,角度顺时针增加</param>
        /// <returns>B点的经纬度坐标</returns>
        public static LatLon GetLatLon(double longitude, double latitude, double distance, double angle)
        {
            LatLon a = new LatLon(latitude, longitude);
            return GetLatLon(a, distance, angle);
        }
    }
}


示例运行结果:  

参考文档:

1. 通过经纬度计算距离的公式
http://www.storyday.com/html/y2009/2212_according-to-latitude-and-longitude-distance-calculation-formula.html
2. 经纬度距离计算
http://blog.csdn.net/fdnike/archive/2007/07/18/1696603.aspx

源码下载

http://files.cnblogs.com/hellofox2000/GeoSite.rar

© 著作权归作者所有

共有 人打赏支持
h
粉丝 2
博文 5
码字总数 4611
作品 0
海淀
PHP实现搜索附近的人

最近的一个项目要求根据用户当前位置的经纬度来查询该用户方圆十公里以内的人,这个功能并不是什么很有技术含量的实现(当然,我们仅仅指的是该功能本身和数据量较小的时候,并不包括长期以来...

攻城狮丶
2017/11/10
0
0
根据给定点的经纬度和特定距离取范围类的数据

一、计算两个经纬度的距离 根据经纬度计算距离 R为地球半径,可取平均值 6371km; φ1, φ2 表示两点的纬度; Δλ 表示两点经度的差值。 二、根据某一经纬度和距离计算附近的经纬度 R为地球...

南烟阁
2017/11/28
0
0
iOS 地理信息计算--BDAstroCalc

BDAstroCalc 是一个用 Swift 写成的低精度结构,它能计算与太阳和月亮相关的地理信息,比如日出日落时间,海拔高度、经纬度等。

孔小菜
2015/05/20
254
0
SQL Server 利用 geography 计算地理位置距离、距我最近排序

SQL Server 有个字段类型为 geography,这个类型存经纬度,就可以利用经纬度排序了。 (注意,还有一个近似类型:geometry,这个是用来计算二维平面的,不适合经纬度) 如何往 geography 存储...

鱼煎
04/11
0
0
java 实现微信搜索附近人功能

最近给andorid做后台查询数据功能,有一个需求是模仿微信的查找附近人功能。 数据库中存储每个用户的经纬度信息及用户信息,通过当前用户传递过来的经纬度查询这个用户半径N公里以内的用户信...

凯文加内特
2015/09/08
333
2
PHP轻松实现"附近的人"功能,根据IP确定经纬度,根据经纬度计算距离

PHP安装GeoIP扩展和数据库根据IP获取访客所在国家/城市/经纬度等信息 然后就可以用geoiprecordbyname($SERVER['REMOTE_ADDR'])根据用户IP确定经纬度了. 注意:geoiprecordby_name()返回的西经...

eechen
2016/06/04
2.2K
2
移动端地图:屏幕边沿方向指示图标

写在前面 在我们打游戏的时候,队友跑出我们的屏幕可视区域外时,经常会有一个头像图标在屏幕的边沿,并且起着指示队友方向的作用。 在移动端地图应用的开发中,同样可能会有这种需求,下面将...

indulge_in
2017/11/23
0
0
Android获取经纬度、计算距离、方位角

最近在Android上做GPS的东西,获取经纬度、计算距离、方位角,感觉在搞GIS样。当然,玩笑了,玩玩而已,稍微总结一下。 经度指示南北方向,纵向。 纬度指示东西方向,横向. 获取经纬度 使用G...

冯京宝
2012/08/28
0
0
请问 定位的周边服务(附近、周边)是怎么实现的?

比如 说 附近酒店,附近医院一类的。 这个是怎么实现的? 倒也不用手具体的算法,我大概知道 是 说 使用 经纬度,然后就 使用 一些算法 计算距离一类的。 是不是 所有的都是这样的呢? 可是 ...

Inszt
2016/03/24
357
3
php通过经纬度计算距离及其逆运算

有朋友遇到这样一个问题,自己数据库里面有一些商家,需要根据用户提交的地理位置找出一定范围内的商家来返回个用户。解决这个问题有两种思路。 第一种思路,从数据库提取出商家的经纬度,然...

990653058
2015/05/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

代码生成利器:IDEA 强大的 Live Templates

代码生成利器:IDEA 强大的 Live Templates

qwfys
23分钟前
1
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
26分钟前
1
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
29分钟前
0
0
日常运维--rsync同步工具

rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而...

chencheng-linux
33分钟前
1
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
46分钟前
1
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
0
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
1
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
0
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
1
0
rsync工具介绍/rsync通过ssh同步

rsync工具介绍 数据备份是必不可少,在Linux系统下数据备份的工具很多,其中重点介绍就是rsync工具,rsync不仅可以远程同步数据,还可以本地同步数据,且不会覆盖以前的数据在已经存在的数据...

Hi_Yolks
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部