private void realtimeCallback( GpsRealTimeData rtData ) { if(!closing) { this.timeLabel.Text = rtData.time.Equals(DateTime.MinValue) ? "" : ("" + Project.zuluToLocal(rtData.time)); this.fixLabel.Text = rtData.fixStr; this.statusLabel.Text = "PC: " + DateTime.Now.ToLongTimeString() + " - " + rtData.comment; switch (rtData.fix) { case 0: case 1: case -1: this.positionLabel.Text = "No GPS fix"; this.altLabel.Text = ""; this.accuracyLabel.Text = ""; this.speedLabel.Text = ""; this.magnHeadingLabel.Text = ""; this.trueHeadingLabel.Text = ""; this.slopeLabel.Text = ""; lastFixLoc = null; gpsBasicsGroupBox.BackColor = Color.Pink; gpsBasicsGroupBox.Text = ""; break; default: if(rtData.location != null) { string sLoc = rtData.location.ToString(); // alt not included this.positionLabel.Text = sLoc.Replace(" ", " "); //LibSys.StatusBar.Trace2(sLoc); Distance dAlt = new Distance(rtData.location.Elev); this.altLabel.Text = "" + dAlt.ToString(Distance.UNITS_DISTANCE_FEET); } else { this.positionLabel.Text = ""; this.altLabel.Text = ""; //LibSys.StatusBar.Trace2("GPS: no fix"); } Distance dAccH = new Distance(rtData.posErrorH); Distance dAccV = new Distance(rtData.posErrorV); this.accuracyLabel.Text = (rtData.posErrorH > 0 ? (dAccH.ToString(Distance.UNITS_DISTANCE_FEET) + "(Horiz)") : "") + " " + (rtData.posErrorV > 0 ? (dAccV.ToString(Distance.UNITS_DISTANCE_FEET) + "(Vert)") : ""); double variation = Math.Round(rtData.location.magneticVariation()); string variationDir = variation > 0.0d ? "W" : "E"; bool hasHeading = false; double headingTrue = 0.0d; double headingMagn = 0.0d; string slopeInfo = ""; if(lastFixLoc != null) { headingTrue = Math.Round(lastFixLoc.bearing(rtData.location) * 180.0d / Math.PI, 1); headingMagn = (headingTrue + variation + 360.0d) % 360.0d; hasHeading = true; double dAlt = rtData.location.Elev - lastFixLoc.Elev; // meters double dDist = rtData.location.distanceFrom(lastFixLoc).Meters; double dSlope = Math.Atan(dAlt / dDist) * 180.0d / Math.PI; double dTimeMs = (DateTime.Now - lastFixDateTime).TotalMilliseconds + 1.0d; // 1.0d to avoid 0 double fpm = dAlt / dTimeMs / Distance.METERS_PER_FOOT * 1000.0d * 60.0d; string fpmFormat = Math.Abs(fpm) > 20.0d ? "1:F0" : "1:F1"; if(fpm > 1.0d || dSlope >= 0.1d) { slopeInfo = String.Format("slope: {0:F1}° (up) - climbing at {" + fpmFormat + "} fpm", dSlope, fpm); } else if(fpm < -1.0d || dSlope <= -0.1d) { slopeInfo = String.Format("slope: {0:F1}° (down) - descending at {" + fpmFormat + "} fpm", -dSlope, -fpm); } } Speed dSpeed = new Speed(rtData.velocity * 3600.0d); // rtData.velocity is in meters/sec, Speed requires meters/hr if(dSpeed.Meters < 300) { this.speedLabel.Text = "0"; this.magnHeadingLabel.Text = ""; this.trueHeadingLabel.Text = ""; } else { this.speedLabel.Text = dSpeed.ToString(); } this.magnHeadingLabel.Text = (hasHeading ? String.Format("{0:000}°", Math.Round(headingMagn)) : ""); this.trueHeadingLabel.Text = (hasHeading ? String.Format("true heading: {0:000}°", Math.Round(headingTrue)) : "") + String.Format(" variation {0:F0}{1}", Math.Abs(variation), variationDir); this.slopeLabel.Text = slopeInfo; lastFixLoc = new GeoCoord(rtData.location); lastFixDateTime = DateTime.Now; gpsBasicsGroupBox.BackColor = Color.LightGreen; gpsBasicsGroupBox.Text = ""; break; } } }
private void adjustTimeShiftByPhotopoint() { try { Waypoint wptToAdjust = PhotoWaypoints.getWaypointById(Project.photoSelectedWptId); long trackId = wptToAdjust.TrackId; Track track = WaypointsCache.getTrackById(trackId); GeoCoord photoDesiredLocation = new GeoCoord(Project.photoSelectedCoord.X, Project.photoSelectedCoord.Y); this.traceLabel.Text = "Adjusting photopoint " + wptToAdjust.Name + " track: " + trackId + " to: " + photoDesiredLocation + "\r\n"; // compute the closest trackpoint (to the click): Waypoint closestTrackpoint1 = null; int closestTrackpointIndex = -1; double closestDistance1 = 100000000.0; double bearing1 = 0.0d; for(int j=0; j < track.Trackpoints.Count ;j++) { Waypoint trkpt = (Waypoint)track.Trackpoints.GetByIndex(j); Distance dst = trkpt.Location.distanceFrom(photoDesiredLocation); if(dst.Meters < closestDistance1) { closestDistance1 = dst.Meters; closestTrackpoint1 = trkpt; closestTrackpointIndex = j; bearing1 = photoDesiredLocation.bearing(closestTrackpoint1.Location); } } // this.traceLabel.Text += "point1: " + closestTrackpoint1.Name + " (" + closestDistance1 + ")"; // measure the previous and next trackpoints, choose the closest of them to the click: Waypoint closestTrackpoint2 = null; double closestDistance2 = 10000000000.0d; double bearing2 = 0.0d; if(closestTrackpointIndex > 0) { // previous: closestTrackpoint2 = (Waypoint)track.Trackpoints.GetByIndex(closestTrackpointIndex - 1); closestDistance2 = closestTrackpoint2.Location.distanceFrom(photoDesiredLocation).Meters; bearing2 = photoDesiredLocation.bearing(closestTrackpoint2.Location); } Waypoint closestTrackpoint3 = null; double closestDistance3 = 10000000000.0d; double bearing3 = 0.0d; if(closestTrackpointIndex < track.Trackpoints.Count - 1) { // next: closestTrackpoint3 = (Waypoint)track.Trackpoints.GetByIndex(closestTrackpointIndex + 1); closestDistance3 = closestTrackpoint3.Location.distanceFrom(photoDesiredLocation).Meters; bearing3 = photoDesiredLocation.bearing(closestTrackpoint3.Location); } bool useNext = closestTrackpoint2 == null || closestTrackpoint3 != null && (Math.Abs(bearing3 - bearing1) > Math.Abs(bearing2 - bearing1)); if(useNext) { // using the next - it's leg is turned more towards the desired point: closestTrackpoint2 = closestTrackpoint3; closestDistance2 = closestDistance3; } // at this point closestTrackpoint3 is irrelevant, all is defined by the 1 and 2 and the ratio: // this.traceLabel.Text += " point2: " + closestTrackpoint2.Name + " (" + closestDistance2 + ")"; Graphics g = PictureManager.This.Graphics; Point p0 = CameraManager.This.toPixelLocation(photoDesiredLocation, null); // Point p1 = CameraManager.This.toPixelLocation(closestTrackpoint1.Location, null); // Point p2 = CameraManager.This.toPixelLocation(closestTrackpoint2.Location, null); // g.DrawLine(Pens.Yellow, p0, p1); // g.DrawLine(Pens.Yellow, p1, p2); // g.DrawLine(Pens.Yellow, p2, p0); // The main point is closestTrackpoint1, the other point is always closestTrackpoint2. // positive ratio means go forward towards the next point, negative - go back towards the previous: double ratio = closestDistance1 / (closestDistance1 + closestDistance2); // this.traceLabel.Text += "\r\nratio: " + ratio; double lat = closestTrackpoint1.Location.Lat + (closestTrackpoint2.Location.Lat - closestTrackpoint1.Location.Lat) * ratio; double lng = closestTrackpoint1.Location.Lng + (closestTrackpoint2.Location.Lng - closestTrackpoint1.Location.Lng) * ratio; long midTicks = (long)Math.Round(closestTrackpoint1.DateTime.Ticks + (closestTrackpoint2.DateTime.Ticks - closestTrackpoint1.DateTime.Ticks) * ratio); GeoCoord midpoint = new GeoCoord(lng, lat); Point pMid = CameraManager.This.toPixelLocation(midpoint, null); g.DrawLine(Pens.Red, pMid, p0); long ticksToAdjust = midTicks - wptToAdjust.DateTime.Ticks; TimeSpan toAdjust = new TimeSpan(ticksToAdjust); this.traceLabel.Text += " midpoint: " + midpoint + " toAdjust=" + toAdjust; // //CameraManager.This.MarkLocation(midpoint, 0); // Waypoint wpt = new Waypoint(wptToAdjust); // wpt.TrackId = -1L; // wpt.Location = midpoint; // wpt.UrlName = "new"; // WaypointsCache.addWaypoint(wpt); // CameraManager.This.ProcessCameraMove(); Project.adjustPhotoTimeShift(m_photoTimeShiftTypeSelected, toAdjust); displayTimeShiftControlValues(); this.setButtonsAgitated(true); } catch (Exception exc) { this.traceLabel.Text = "oops: " + exc; } }