Guest User

Untitled

a guest
Jan 4th, 2025
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.49 KB | Source Code | 0 0
  1. using Toybox.System as System;
  2. using Toybox.WatchUi as WatchUi;
  3. using Toybox.Graphics as Graphics;
  4. using Toybox.Position as Position;
  5. using Toybox.Lang as Lang;
  6.  
  7. class MyWaypointsApp extends WatchUi.AppBase {
  8.  
  9. private var mainView;
  10.  
  11. function initialize() {
  12. WatchUi.AppBase.initialize();
  13. }
  14.  
  15. function onStart(state) {
  16. // Push our main view that handles location + bearing logic
  17. mainView = new WaypointsMainView();
  18. WatchUi.pushView(mainView);
  19. }
  20.  
  21. function onStop(state) {
  22. // Clean up if needed
  23. }
  24. }
  25.  
  26. // The main view that displays “bearing to next waypoint”
  27. class WaypointsMainView extends WatchUi.View {
  28.  
  29. // Hardcoded route: an array of lat/lon dictionaries
  30. private var routePoints = [
  31. { :lat => 40.7128, :lon => -74.0060 }, // example: New York
  32. { :lat => 39.9526, :lon => -75.1652 }, // example: Philadelphia
  33. { :lat => 38.9072, :lon => -77.0369 }, // example: DC
  34. ];
  35.  
  36. private var waypointIndex = 0; // Start with the first route point
  37. private var currentBearing = 0; // Bearing in degrees
  38. private var distanceThreshold = 0.01; // ~0.01 km or some radius you want
  39.  
  40. private var locationListener;
  41.  
  42. function initialize() {
  43. WatchUi.View.initialize();
  44.  
  45. // Listen to user’s location
  46. locationListener = new MyLocationListener(self);
  47. // EITHER (A) older approach
  48. Position.enableLocationEvents(locationListener);
  49. // OR (B) newer approach if your device supports it:
  50. // Position.setEnabled(true);
  51. // Position.setListener(locationListener);
  52. Position.start();
  53. }
  54.  
  55. function onShow() as Void {
  56. WatchUi.requestUpdate();
  57. }
  58.  
  59. function onHide() as Void {
  60. // Stop location to save battery
  61. Position.disableLocationEvents();
  62. Position.stop();
  63. }
  64.  
  65. function onUpdate(dc as Graphics.Dc) as Void {
  66. dc.clear();
  67. dc.setColor(Graphics.COLOR_WHITE);
  68. dc.setFont(Graphics.FONT_LARGE);
  69.  
  70. // If we've reached the end of our routePoints
  71. if (waypointIndex >= routePoints.size()) {
  72. dc.drawText(dc.getWidth()/2,
  73. dc.getHeight()/2,
  74. Graphics.FONT_LARGE,
  75. "Route Completed!",
  76. Graphics.TEXT_JUSTIFY_CENTER);
  77. return;
  78. }
  79.  
  80. // Display current bearing and the name or index of the next waypoint
  81. var text = "Next WP " + waypointIndex + "\n" +
  82. "Bearing: " + Lang.formatNumber(currentBearing,0) + "°";
  83.  
  84. dc.drawText(dc.getWidth()/2,
  85. dc.getHeight()/2,
  86. Graphics.FONT_LARGE,
  87. text,
  88. Graphics.TEXT_JUSTIFY_CENTER);
  89. }
  90.  
  91. // Called by the location listener when user’s lat/lon changes
  92. function onUserLocation(lat as Number, lon as Number) as Void {
  93.  
  94. // If we’re done
  95. if (waypointIndex >= routePoints.size()) {
  96. return;
  97. }
  98.  
  99. var targetWp = routePoints[waypointIndex];
  100. var wpLat = targetWp[:lat];
  101. var wpLon = targetWp[:lon];
  102.  
  103. // Compute the bearing
  104. currentBearing = calculateBearing(lat, lon, wpLat, wpLon);
  105.  
  106. // Check distance to see if we’re “close enough” to move on
  107. var distKm = distanceBetween(lat, lon, wpLat, wpLon);
  108. if (distKm <= distanceThreshold) {
  109. // Move to next waypoint
  110. waypointIndex++;
  111. }
  112.  
  113. WatchUi.requestUpdate();
  114. }
  115.  
  116. // Haversine formula or simpler approach for distance in km
  117. function distanceBetween(lat1, lon1, lat2, lon2) as Number {
  118. var R = 6371; // Earth radius in km
  119. var dLat = toRadians(lat2 - lat1);
  120. var dLon = toRadians(lon2 - lon1);
  121. var a = Math.sin(dLat/2)*Math.sin(dLat/2)
  122. + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2))
  123. * Math.sin(dLon/2)*Math.sin(dLon/2);
  124. var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  125. return R * c;
  126. }
  127.  
  128. // Basic formula for bearing from (lat1,lon1) to (lat2,lon2)
  129. function calculateBearing(lat1, lon1, lat2, lon2) as Number {
  130. var phi1 = toRadians(lat1);
  131. var phi2 = toRadians(lat2);
  132. var dLon = toRadians(lon2 - lon1);
  133.  
  134. var y = Math.sin(dLon) * Math.cos(phi2);
  135. var x = Math.cos(phi1)*Math.sin(phi2)
  136. - Math.sin(phi1)*Math.cos(phi2)*Math.cos(dLon);
  137. var brng = Math.atan2(y, x); // -pi..+pi
  138. var deg = toDegrees(brng); // Convert to 0..360
  139. return (deg + 360) mod 360;
  140. }
  141.  
  142. function toRadians(deg as Number) as Number {
  143. return deg * Math.PI / 180;
  144. }
  145.  
  146. function toDegrees(rad as Number) as Number {
  147. return rad * 180 / Math.PI;
  148. }
  149. }
  150.  
  151. // The location listener
  152. class MyLocationListener extends Position.LocationListener {
  153. private var parentView;
  154.  
  155. function initialize(pv as WaypointsMainView) {
  156. Position.LocationListener.initialize();
  157. parentView = pv;
  158. }
  159.  
  160. function onLocation(loc as Position.Location) as Void {
  161. if (loc != null && loc.valid) {
  162. parentView.onUserLocation(loc.latitude, loc.longitude);
  163. } else {
  164. System.println("Invalid location.");
  165. }
  166. }
  167.  
  168. function onStateChange(newState as Position.State) as Void {
  169. // E.g. handle transitions
  170. }
  171. }
  172.  
Advertisement
Add Comment
Please, Sign In to add comment