/// <summary> /// Calculates the scaling factor of a route as well as x/y offset for correct points positioning /// </summary> private static void CalculateFactorAndOffset() { GpsPoint firstGpsPoint = new GpsPoint(_params.GpsStartPoint.Lon, _params.GpsStartPoint.Lat, null); firstGpsPoint = TransposePoint(firstGpsPoint); GpsPoint lastGpsPoint = new GpsPoint (_params.GpsEndPoint.Lon, _params.GpsEndPoint.Lat, null); lastGpsPoint = TransposePoint(lastGpsPoint); _scalingFactorX = Math.Abs(_params.ImgStartPoint.X - _params.ImgEndPoint.X) / Math.Abs(firstGpsPoint.Lon - lastGpsPoint.Lon); _scalingFactorY = Math.Abs(_params.ImgStartPoint.Y - _params.ImgEndPoint.Y) / Math.Abs(firstGpsPoint.Lat - lastGpsPoint.Lat); firstGpsPoint = DislocatePointByFactor(firstGpsPoint); _offsetX = _params.ImgStartPoint.X > firstGpsPoint.Lon ? _params.ImgStartPoint.X - firstGpsPoint.Lon : firstGpsPoint.Lon - _params.ImgStartPoint.X; _offsetY = _params.ImgStartPoint.Y > firstGpsPoint.Lat ? _params.ImgStartPoint.Y - firstGpsPoint.Lat : firstGpsPoint.Lat - _params.ImgStartPoint.Y; }
// pomnoži koordinate točke s koeficijentom za ispravnu veličinu rute (scaling) /// <summary> /// Corrects the position of the point by a calculated offset /// </summary> /// <param name="point">Input point</param> /// <returns>Correctly positioned point after offset is applied</returns> private static GpsPoint DislocatePointByFactor(GpsPoint point) { point.Lon *= _scalingFactorX; point.Lat *= _scalingFactorY; return point; }
/// <summary> /// Transposes a GPS point into a coordinate system point /// </summary> /// <param name="point">GPS point</param> /// <returns>Transposed point for coordinate system</returns> private static GpsPoint TransposePoint(GpsPoint point) { double factorX = _maxLng < 0 ? Math.Abs(_maxLng) : _maxLng * -1; double factorY = _maxLat < 0 ? Math.Abs(_maxLat) : _maxLat * -1; point.Lon += factorX; point.Lat = Math.Abs(point.Lat + factorY); return point; }
public TransposerParams(ImgPoint imgA, ImgPoint imgB, GpsPoint gpsA, GpsPoint gpsB, int step) { _imgStartPoint = imgA; _imgEndPoint = imgB; _gpsStartPoint = gpsA; _gpsEndPoint = gpsB; _stepLength = step; }
/// <summary> /// Optimizes the distance between points so that too dense and too sparse areas of points are evened-out. /// </summary> private static void PointDistanceOptimization() { GpsPoint lastPushed = new GpsPoint(); GpsPoint current = new GpsPoint(); for(int i = 0; i < GpsPoints.Count; i++) { current = TransposePoint(GpsPoints[i]); current = DislocatePointByFactor(current); current.Lon = Math.Abs(current.Lon) + _offsetX; current.Lat = Math.Abs(current.Lat) + _offsetY; // check if this is the last point of the list to optimize, if yes then add it and break the loop if (Math.Sqrt(Math.Pow(current.Lon - _params.ImgEndPoint.X, 2) + Math.Pow(current.Lat - _params.ImgEndPoint.Y, 2)) < _params.StepLength / 1000) { if (i == GpsPoints.Count - 1) { current.Lon = _params.ImgEndPoint.X; current.Lat = _params.ImgEndPoint.Y; _imgPoints.Add(new ImgPoint(current.Lon, current.Lat, current.Elev)); break; } } if (i == 0) { lastPushed = current; _imgPoints.Add(new ImgPoint(lastPushed.Lon, lastPushed.Lat, lastPushed.Elev)); } else { double distPx = Math.Sqrt(Math.Pow(current.Lon - lastPushed.Lon, 2) + Math.Pow(current.Lat - lastPushed.Lat, 2)); // distance between the current and the preceeding point double angle = Math.Acos(Math.Abs(current.Lon - lastPushed.Lon) / distPx); // angle between the current and the preceeding point double distPxRnded = Math.Round(distPx * 1000); double offsetX = Math.Cos(angle) * (_params.StepLength / 1000); double offsetY = Math.Sin(angle) * (_params.StepLength / 1000); GpsPoint filler = new GpsPoint(); if (distPxRnded >= _params.StepLength && distPxRnded < 2 * _params.StepLength) { // acceptable point distance, add the point to the list lastPushed = current; _imgPoints.Add(new ImgPoint(lastPushed.Lon, lastPushed.Lat, lastPushed.Elev)); } else if (distPxRnded >= 2 * _params.StepLength) { // add additional points to fill up too scarse area of points if (lastPushed.Lon == current.Lon) // if the points are on the same vertical line { filler.Lon = lastPushed.Lon; filler.Lat = lastPushed.Lat < current.Lat ? lastPushed.Lat + _params.StepLength / 1000 : lastPushed.Lat - _params.StepLength / 1000; filler.Elev = lastPushed.Elev; lastPushed = filler; _imgPoints.Add(new ImgPoint(lastPushed.Lon, lastPushed.Lat, lastPushed.Elev)); } else if (lastPushed.Lat == current.Lat) // if the points are on the same horizontal line { filler.Lat = lastPushed.Lat; filler.Lon = lastPushed.Lon < current.Lon ? lastPushed.Lon + _params.StepLength / 1000 : lastPushed.Lon - _params.StepLength / 1000; filler.Elev = lastPushed.Elev; lastPushed = filler; _imgPoints.Add(new ImgPoint(lastPushed.Lon, lastPushed.Lat, lastPushed.Elev)); } else { // calculate and add the "filler" point do { filler.Lon = lastPushed.Lon < current.Lon ? lastPushed.Lon + offsetX : lastPushed.Lon - offsetX; filler.Lat = lastPushed.Lat < current.Lat ? lastPushed.Lat + offsetY : lastPushed.Lat - offsetY; filler.Elev = lastPushed.Elev; lastPushed = filler; _imgPoints.Add(new ImgPoint(lastPushed.Lon, lastPushed.Lat, lastPushed.Elev)); distPx = Math.Sqrt(Math.Pow(current.Lon - lastPushed.Lon, 2) + Math.Pow(current.Lat - lastPushed.Lat, 2)); distPxRnded = Math.Round(distPx * 1000); } while (distPxRnded >= 2 * _params.StepLength); } } } } }