首页 > 其他分享 >经纬度帮助类

经纬度帮助类

时间:2023-10-19 13:56:37浏览次数:26  
标签:DPoint 帮助 return 经纬度 double Points iIndex Math

核心代码

/// <summary>
/// 点位信息
/// </summary>
[DataContract]
public class DPoint
{
    /// <summary>
    /// x坐标,对应经度
    /// </summary>
    public double x;

    /// <summary>
    /// y坐标,对应纬度
    /// </summary>
    public double y;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="lng">经度</param>
    /// <param name="lat">纬度</param>
    public DPoint(double lng, double lat)
    {
        x = lng;
        y = lat;
    }

    public DPoint()
    { }

    #region 已知两点计算距离

    private const double EARTH_RADIUS = 6378.137; //地球半径

    //private static double rad(double d)
    //{
    //    return d * Math.PI / 180.0;
    //}

    /// <summary>
    /// 将弧度转换为度
    /// </summary>
    /// <param name="radians">弧度</param>
    /// <returns>度</returns>
    private static double RadToDeg(double radians)
    {
        return radians * (180 / Math.PI);
    }

    /// <summary>
    /// 将度转换为弧度
    /// </summary>
    /// <param name="degrees">度</param>
    /// <returns>弧度</returns>
    private static double DegToRad(double degrees)
    {
        return degrees * (Math.PI / 180);
    }

    /// <summary>
    /// Calculates the middle point coordinate.
    /// </summary>
    /// <param name="firstCoordinate">The first coordinate.</param>
    /// <param name="secondCoordinate">The second coordinate.</param>
    /// <returns>Middle point coordinate</returns>
    public static DPoint GetMidPoint(DPoint firstCoordinate, DPoint secondCoordinate)
    {
        double lon1 = DegToRad(firstCoordinate.x);
        double lat1 = DegToRad(firstCoordinate.y);

        double lon2 = DegToRad(secondCoordinate.x);
        double lat2 = DegToRad(secondCoordinate.y);

        double deltaLong = lon2 - lon1;

        double Bx = Math.Cos(lat2) * Math.Cos(deltaLong);
        double By = Math.Cos(lat2) * Math.Sin(deltaLong);
        double lat3 = RadToDeg(Math.Atan2(Math.Sin(lat1) + Math.Sin(lat2), Math.Sqrt((Math.Cos(lat1) + Bx) * (Math.Cos(lat1) + Bx) + By * By)));
        double lon3 = RadToDeg(lon1 + Math.Atan2(By, Math.Cos(lat1) + Bx));

        return new DPoint(lon3, lat3);
    }

    /// <summary>
    /// 计算指定两点间的距离(单位KM)
    /// </summary>
    /// <param name="p1">起始点</param>
    /// <param name="p2">终止点</param>
    /// <returns>两点间的公里数</returns>
    public static double GetDistance(DPoint p1, DPoint p2)
    {
        return GetDistance(p1.y, p1.x, p2.y, p2.x);
    }

    /// <summary>
    /// 计算指定两点间的距离(单位KM)
    /// </summary>
    /// <param name="lat1">纬度1</param>
    /// <param name="lng1">经度1</param>
    /// <param name="lat2">纬度2</param>
    /// <param name="lng2">经度2</param>
    /// <returns>两点间距离公里数</returns>
    public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
    {
        double radLat1 = DegToRad(lat1);
        double radLat2 = DegToRad(lat2);
        double a = radLat1 - radLat2;
        double b = DegToRad(lng1) - DegToRad(lng2);

        double dst = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
                                           Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
        dst = dst * EARTH_RADIUS;
        dst = Math.Round(dst * 10000) / 10000;
        return dst;
    }

    /// <summary>
    /// 计算指定两点间的距离(单位M)
    /// </summary>
    /// <param name="lat1">纬度1</param>
    /// <param name="lng1">经度1</param>
    /// <param name="lat2">纬度2</param>
    /// <param name="lng2">经度2</param>
    /// <returns>两点间距离公里数</returns>
    public static double GetDistanceMeter(double lat1, double lng1, double lat2, double lng2)
    {
        return GetDistance(lat1, lng1, lat2, lng2) * 1000;
    }

    /// <summary>
    /// 计算指定两点间的距离(单位M)
    /// </summary>
    /// <param name="lat1">纬度1</param>
    /// <param name="lng1">经度1</param>
    /// <param name="lat2">纬度2</param>
    /// <param name="lng2">经度2</param>
    /// <returns>两点间距离公里数</returns>
    public static double GetDistanceMeter(DPoint p1, DPoint p2)
    {
        return GetDistance(p1.y, p1.x, p2.y, p2.x) * 1000;
    }

    /// <summary>
    /// 判断点是否在多边形内或多边形上
    /// </summary>
    /// <param name="point">当前点</param>
    /// <param name="Points">多边形边界点集合</param>
    /// <returns></returns>
    public static bool IsPtInPoly(DPoint point, DPoint[] Points)
    {
        int iIndex;
        double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
        if (Points.Length < 3)
        {
            return false;
        }
        var iSum = 0;
        var iCount = Points.Length;
        for (iIndex = 0; iIndex < iCount; iIndex++)
        {
            if (point.x == Points[iIndex].x && point.y == Points[iIndex].y)  //A点在多边形上    
                return true;

            if (iIndex == iCount - 1)
            {
                dLon1 = Points[iIndex].x;
                dLat1 = Points[iIndex].y;
                dLon2 = Points[0].x;
                dLat2 = Points[0].y;
            }
            else
            {
                dLon1 = Points[iIndex].x;
                dLat1 = Points[iIndex].y;
                dLon2 = Points[iIndex + 1].x;
                dLat2 = Points[iIndex + 1].y;
            }

            //以下语句判断A点是否在边的两端点的纬度之间,在则可能有交点
            if (((point.y > dLat1) && (point.y < dLat2)) || ((point.y > dLat2) && (point.y < dLat1)))
            {
                if (Math.Abs(dLat1 - dLat2) > 0)
                {
                    //获取A点向左射线与边的交点的x坐标:
                    dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - point.y)) / (dLat1 - dLat2);
                    //如果交点在A点左侧,则射线与边的全部交点数加一:
                    if (dLon < point.x)
                    {
                        iSum++;
                    }
                    //如果相等,则说明A点在边上
                    if (dLon == point.x)
                        return true;
                }
            }
        }
        if ((iSum % 2) != 0)
        {
            return true;
        }
        return false;
    }


    #endregion
}

标签:DPoint,帮助,return,经纬度,double,Points,iIndex,Math
From: https://www.cnblogs.com/wml-it/p/17774520.html

相关文章

  • 开源项目 | 美团开源监控告警服务,Java 开发的实时应用监控平台,能够帮助开发者快速定位
     一、项目概述        CAT是基于Java开发的实时应用监控平台,为美团点评提供了全面的实时监控告警服务。        CAT作为服务端项目基础组件,提供了Java,C/C++,Node.js,Python,Go等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框架,RPC框架,数据......
  • 压缩文件帮助类
    核心代码publicclassZipHelper{#region基础参数publicdelegatevoidUnZipProgressEventHandler(objectsender,UnZipProgressEventArgse);publiceventUnZipProgressEventHandlerunZipProgress;publicdelegatevoidCompressProgr......
  • GPS帮助类
    核心代码publicclassGpsHelper{privateconstdoubleEARTH_RADIUS=6378137;///<summary>///计算两点位置的距离,返回两点的距离,单位米///该公式为GOOGLE提供,误差小于0.2米///</summary>///<paramname="lat1">第一点纬度</para......
  • 2023年10月最新全国省市区县和乡镇街道行政区划矢量边界坐标经纬度地图数据 shp geojs
    发现个可以免费下载全国 geojson 数据的网站,推荐一下。支持全国、省级、市级、区/县级、街道/乡镇级以及各级的联动数据,支持导入矢量地图渲染框架中使用,例如:D3、Echarts等geojson数据下载地址:https://geojson.hxkj.vip该项目github地址:https://github.com/TangSY/echarts-m......
  • 直播间频繁被封禁是什么原因?有什么方法能够减少违规?干货分享,希望能对正在做无人直播的
    你的直播间为什么频繁被判违规?特别是新手用户建议来看一下这篇文章,为了更好地理解这个问题,我们首先需要了解直播平台的检测原理。其实也很简单,就是对视频和音频进行抽帧跟之前的直播和其他的直播间进行对比,如果画面和语音重复度过高,就有可能被判定违规,下面就分享一下我自己做去重......
  • AI如何帮助Salesforce从业者找工作?
    在当今竞争激烈的就业市场中,找到满意的工作是一项艰巨的任务。成千上万的候选人竞争一个岗位,你需要利用一切优势从求职大军中脱颖而出。这就是AI的用武之地,特别是像ChatGPT这样的人工智能工具,可以成为你的秘密武器。本篇文章将探讨AI如何帮助你加快Salesforce求职速度。01即时......
  • ABAP:年份+月份搜索帮助
    *&---------------------------------------------------------------------**&包含ZPPR011_S01*&---------------------------------------------------------------------*SELECTION-SCREENBEGINOFBLOCKblk1WITHFRAMETITLETEXT-001.......
  • 公园视频监控系统如何改造?人工智能又能提供哪些帮助?
    近日合肥市骆岗公园宣布正式开园,作为目前世界最大的城市公园,占地12.7万平方公里,如此壮观宏伟的建设,也吸引到了不少市民进行参观打卡。不管大型小型,城市里的公园都是随处可见的,那么,公园安防管控如何做到位?这是一个难题。在公园的安防视频监控方案方面,较为成熟的还属旭帆科技的智能......
  • 数据结构的思维导图(帮助梳理脉络)
    编辑......
  • Mojo帮助Python 的性能提升了近 250 倍
    导读AydynTairov是一名开源作者,也是Meta前工程师,他此前将GitHub上火热的纯C语言实现的llama2.c项目移植到了Python——llama2.py。近期 Mojo编程语言正式开放下载,并且声称比Python快68000倍。于是 AydynTairov马不停蹄地就开始将 llama2.py 移植到......