GPS圈&细分计时器

时间:2017-09-12 13:40:18

标签: c# gps geocoding line-intersection

我一直在寻找一段时间,但我找不到我正在寻找的东西。

我正在开发一款可以进入赛车的应用。它将使驾驶员能够按下按钮来标记开始/结束线。它还有一个按钮,允许驱动程序设置段时间。

请记住,轨道可以是我首先处理的椭圆形。它可以是道路路线,也可以是自动十字路口,起点和终点线不是完全相同的位置。它们可能相距50英尺左右,但汽车从未穿过它开始的地方。

我有我的gps数据,我将NMea消息转换为我的课程,我存储了Lat,Lon,Speed,Course等。在我的研究中,我遇到过这个有趣的事情。 GPS将安装在屋顶外,以获得更好的信号。它每秒产生10次点击。 (Garmin Glo)

http://www.drdobbs.com/windows/gps-programming-net/184405690?pgno=1

它已经陈旧但它谈到了UTM和笛卡尔坐标系。所以使用DecDeg2UTM,我转换Lat& Lon to X&也是坐标。

我也一直试图使用我找到的相交公式Here我拿了相交并尝试将其转换为C#,我将在最后发布。但是,输入椭圆形轨道的坐标,它似乎并没有起作用。而且,我不确定它应该做什么。但是当它像-35.xxx& 98.xxxx出自距离赛道1000英里的海洋。

我正在寻找以下答案。

  1. 我假设我需要在按下开始/结束或分段按钮时记录所记录的位置,并计算垂直于汽车方向的线,以便能够进行某种线交点计算。笛卡尔坐标似乎很好地计算了轴承。但问题是你如何得到左右坐标"。另外,请记住,椭圆形轨道可能是60英尺宽。但如上所述,自动交叉轨道可能只有20英尺宽,部分轨道可能有50英尺。注意我可以指示设置点数,车辆需要缓慢或停在点获得准确的坐标。他们在走轨道时必须设置一些轨道。
  2. 基于此,我是否应该尝试使用十进制lat lon或者使用基于UTM的笛卡尔坐标系统是一种更准确的方法来处理我想要做的事情?
  3. 是否有一个.Net库或基于C的库,其源代码具有进行这些计算的方法?
  4. 如何准确处理。 (使用Math不太好,链接到代码示例会有很大帮助。)
  5. 接下来,在我获得了开始/结束和段所需的线路或任何内容后,当我从赛车中获得GPS标志时,我需要找出最准确的方式来判断汽车何时越过这些段。如果我很幸运,我每秒会得到10次点击,但可能会更低。然后,车辆速度可以根据轨道和车辆的类型而显着变化。因此GPS击中可能是很多英尺,而左边或右边是#34;一段。此外,它可能在一段之前或之后很多英尺。
  6. 同样,如果有一个GIS库,那么我可以提供坐标并计算所有这些,只要它具有高效性,它就会起作用。如果不是这样的话,我会尝试决定是否最好将坐标分解为X Y或几何公式为十进制格式的坐标。 Mods,我认为有硬数据支持任何一种方式的答案,这不是对意见完全主观的反应。

    这是我从上面的脚本页面中提出的C#代码。我开始感觉到UTM,而笛卡尔坐标系统对于准确性和性能会更好。但是,如果它存在,我还可以接受相反的证据。

    由于

    P.S。注意GeoCoordinate来自.Net System.Device.Location汇编。 GpsData只是我用来将NMEA消息转换为Lat,Lon,Course,NumSats,DateTime等的类。

    Radian方法的扩展如下:

    public static double DegreeToRadians(this double angle)
        {
            return Math.PI * angle / 180.0;
        }
    
        public static double RadianToDegree(this double angle)
        {
            return angle * (180.0 / Math.PI);
        }
    }
    
     public static GeoCoordinate CalculateIntersection(GpsData p1, double brng1, GpsData p2, double brng2)
        {
            // see http://williams.best.vwh.net/avform.htm#Intersection
    
            // Not sure I need to use Cosine
            double _p1LatRadians = p1.Latitude.DegreeToRadians();
            double _p1LonToRadians = p1.Longitude.DegreeToRadians();
            double _p2LatToRadians = p2.Latitude.DegreeToRadians();
            double _p2LonToRadians = p2.Longitude.DegreeToRadians();
            double _brng1ToRadians = brng1.DegreeToRadians();
            double _brng2ToRadians = brng2.DegreeToRadians();
            double _deltaLat = _p2LatToRadians - _p1LatRadians;
            double _deltaLon = _p2LonToRadians - _p1LonToRadians;
    
                var _var1 = 2 * Math.Asin(Math.Sqrt(Math.Sin(_deltaLat / 2) * Math.Sin(_deltaLat / 2)
                    + Math.Cos(_p1LatRadians) * Math.Cos(_p2LatToRadians) * Math.Sin(_deltaLon / 2) * Math.Sin(_deltaLon / 2)));
    
                if (_var1 == 0) return null;
    
                // initial/final bearings between points
                var _finalBrng = Math.Acos((Math.Sin(_p2LatToRadians) - Math.Sin(_p1LatRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p1LatRadians)));
                //if (isNaN(θa)) θa = 0; // protect against rounding
    
                var θb = Math.Acos((Math.Sin(_p1LatRadians) - Math.Sin(_p2LatToRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p2LatToRadians)));
    
                var θ12 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? _finalBrng : 2 * Math.PI - _finalBrng;
                var θ21 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? 2 * Math.PI - θb : θb;
    
                var α1 = (_brng1ToRadians - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3
                var α2 = (θ21 - _brng2ToRadians + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3
    
                if (Math.Sin(α1) == 0 && Math.Sin(α2) == 0) return null; // infinite intersections
                if (Math.Sin(α1) * Math.Sin(α2) < 0) return null;      // ambiguous intersection
    
                α1 = Math.Abs(α1);
                α2 = Math.Abs(α2);
                // ... Ed Williams takes abs of α1/α2, but seems to break calculation?
    
                var α3 = Math.Acos(-Math.Cos(α1) * Math.Cos(α2) + Math.Sin(α1) * Math.Sin(α2) * Math.Cos(_var1));
                var δ13 = Math.Atan2(Math.Sin(_var1) * Math.Sin(α1) * Math.Sin(α2), Math.Cos(α2) + Math.Cos(α1) * Math.Cos(α3));
                var _finalLatRadians = Math.Asin(Math.Sin(_p1LatRadians) * Math.Cos(δ13) + Math.Cos(_p1LatRadians) * Math.Sin(δ13) * Math.Cos(_brng1ToRadians));
                var _lonBearing = Math.Atan2(Math.Sin(_brng1ToRadians) * Math.Sin(δ13) * Math.Cos(_p1LatRadians), Math.Cos(δ13) - Math.Sin(_p1LatRadians) * Math.Sin(_finalLatRadians));
                var _finalLon = _p1LonToRadians + _lonBearing;
    
            var _returnLat = _finalLatRadians.RadianToDegree();
    
            var _latToDegree = _finalLon.RadianToDegree();
            var _returnLon = ( _latToDegree + 540) % 360 - 180;
    
            return new GeoCoordinate(_returnLat, _returnLon);
            //return new LatLon(φ3.toDegrees(), (λ3.toDegrees() + 540) % 360 - 180); // normalise to −180..+180°
    
        }
    

0 个答案:

没有答案
相关问题