计算球面上两点间最短距离多语言版本

来源:互联网 发布:bestv百视通第三方软件 编辑:程序博客网 时间:2024/04/26 00:41

Haversine球面半正矢公式,用来计算球面上连点之间的最短距离,
这里有几种语言版本的实现方式,就摘了几种,还有其他例如Smalltalk, Tcl, NCL的就不贴了。

//C#using System;namespace HaversineFormula{    /// <summary>    /// 距离类型,英里/公里    /// </summary>    public enum DistanceType { Miles, Kilometers };    /// <summary>    /// Specifies a Latitude / Longitude point.    /// </summary>    public struct Position    {        public double Latitude;        public double Longitude;    }    class Haversine    {        /// <summary>        /// 返回英里或者公里的距离        /// latitude / longitude points.        /// </summary>        /// <param name=”pos1″></param>        /// <param name=”pos2″></param>        /// <param name=”type”></param>        /// <returns></returns>        public double Distance(Position pos1, Position pos2, DistanceType type)        {            double R = (type == DistanceType.Miles)&nbsp;? 3960&nbsp;: 6371;            double dLat = this.toRadian(pos2.Latitude - pos1.Latitude);            double dLon = this.toRadian(pos2.Longitude - pos1.Longitude);            double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +                Math.Cos(this.toRadian(pos1.Latitude)) * Math.Cos(this.toRadian(pos2.Latitude)) *                Math.Sin(dLon / 2) * Math.Sin(dLon / 2);            double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));            double d = R * c;            return d;        }        /// <summary>        /// 转换成弧度        /// </summary>        /// <param name="val"></param>        /// <returns></returns>        private double toRadian(double val)        {            return (Math.PI / 180) * val;        }    }}//调用方法Position pos1 = new Position();pos1.Latitude = 40.7486;pos1.Longitude = -73.9864;Position pos2 = new Position();pos2.Latitude = 24.7486;pos2.Longitude = -72.9864;Haversine hv = new Haversine();double result = hv.Distance(pos1, pos2, DistanceType.Kilometers);
//ExcelPublic Function getDistance(latitude1, longitude1, latitude2, longitude2)earth_radius = 6371Pi = 3.14159265deg2rad = Pi / 180dLat = deg2rad * (latitude2 - latitude1)dLon = deg2rad * (longitude2 - longitude1)a = Sin(dLat / 2) * Sin(dLat / 2) + Cos(deg2rad * latitude1) * Cos(deg2rad * latitude2) * Sin(dLon / 2) * Sin(dLon / 2)c = 2 * WorksheetFunction.Asin(Sqr(a))d = earth_radius * cgetDistance = dEnd Function
//PHPfunction getDistance($latitude1, $longitude1, $latitude2, $longitude2) {    $earth_radius = 6371;    $dLat = deg2rad($latitude2 - $latitude1);    $dLon = deg2rad($longitude2 - $longitude1);    $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);    $c = 2 * asin(sqrt($a));    $d = $earth_radius * $c;    return $d;}
//Javaimport com.google.android.maps.GeoPoint;public class DistanceCalculator {   private double Radius;   // R = earth's radius (mean radius = 6,371km)   // Constructor   DistanceCalculator(double R) {      Radius = R;   }   public double CalculationByDistance(GeoPoint StartP, GeoPoint EndP) {      double lat1 = StartP.getLatitudeE6()/1E6;      double lat2 = EndP.getLatitudeE6()/1E6;      double lon1 = StartP.getLongitudeE6()/1E6;      double lon2 = EndP.getLongitudeE6()/1E6;      double dLat = Math.toRadians(lat2-lat1);      double dLon = Math.toRadians(lon2-lon1);      double a = Math.sin(dLat/2) * Math.sin(dLat/2) +         Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *         Math.sin(dLon/2) * Math.sin(dLon/2);      double c = 2 * Math.asin(Math.sqrt(a));      return Radius * c;   }}
//MSSQLCREATE FUNCTION [dbo].[GetDistance](      @lat1 Float(8),      @long1 Float(8),      @lat2 Float(8),      @long2 Float(8))RETURNS Float(8)ASBEGIN      DECLARE @R Float(8);      DECLARE @dLat Float(8);      DECLARE @dLon Float(8);      DECLARE @a Float(8);      DECLARE @c Float(8);      DECLARE @d Float(8);      SET @R = 3960;      SET @dLat = RADIANS(@lat2 - @lat1);      SET @dLon = RADIANS(@long2 - @long1);      SET @a = SIN(@dLat / 2) * SIN(@dLat / 2) + COS(RADIANS(@lat1))                        * COS(RADIANS(@lat2)) * SIN(@dLon / 2) *SIN(@dLon / 2);      SET @c = 2 * ASIN(MIN(SQRT(@a)));      SET @d = @R * @c;      RETURN @d;ENDGO
//Python#coding:UTF-8"""  Python implementation of Haversine formula  Copyright (C) <2009>  Bartek Górny <bartek@gorny.edu.pl>  This program is free software: you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation, either version 3 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program.  If not, see <http://www.gnu.org/licenses/>."""import mathdef recalculate_coordinate(val,  _as=None):  """    Accepts a coordinate as a tuple (degree, minutes, seconds)    You can give only one of them (e.g. only minutes as a floating point number) and it will be duly    recalculated into degrees, minutes and seconds.    Return value can be specified as 'deg', 'min' or 'sec'; default return value is a proper coordinate tuple.  """  deg,  min,  sec = val  # pass outstanding values from right to left  min = (min or 0) + int(sec) / 60  sec = sec&nbsp;% 60  deg = (deg or 0) + int(min) / 60  min = min&nbsp;% 60  # pass decimal part from left to right  dfrac,  dint = math.modf(deg)  min = min + dfrac * 60  deg = dint  mfrac,  mint = math.modf(min)  sec = sec + mfrac * 60  min = mint  if _as:    sec = sec + min * 60 + deg * 3600    if _as == 'sec': return sec    if _as == 'min': return sec / 60    if _as == 'deg': return sec / 3600  return deg,  min,  secdef points2distance(start,  end):  """    Calculate distance (in kilometers) between two points given as (long, latt) pairs    based on Haversine formula (http://en.wikipedia.org/wiki/Haversine_formula).    Implementation inspired by JavaScript implementation from http://www.movable-type.co.uk/scripts/latlong.html    Accepts coordinates as tuples (deg, min, sec), but coordinates can be given in any form - e.g.    can specify only minutes:    (0, 3133.9333, 0)     is interpreted as     (52.0, 13.0, 55.998000000008687)    which, not accidentally, is the lattitude of Warsaw, Poland.  """  start_long = math.radians(recalculate_coordinate(start[0],  'deg'))  start_latt = math.radians(recalculate_coordinate(start[1],  'deg'))  end_long = math.radians(recalculate_coordinate(end[0],  'deg'))  end_latt = math.radians(recalculate_coordinate(end[1],  'deg'))  d_latt = end_latt - start_latt  d_long = end_long - start_long  a = math.sin(d_latt/2)**2 + math.cos(start_latt) * math.cos(end_latt) * math.sin(d_long/2)**2  c = 2 * math.asin(math.sqrt(a))  return 6371 * cif __name__ == '__main__': warsaw = ((21,  0,  30),  (52, 13, 56)) cracow = ((19, 56, 18),  (50, 3, 41)) print points2distance(warsaw,  cracow)
0 0
原创粉丝点击