ChangeGPSPinPosition.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using TMPro;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. namespace Imagine.WebAR.Demo{
  8. public class ChangeGPSPinPosition : MonoBehaviour
  9. {
  10. [SerializeField] GameObject changePinLocationPopup, pinListItemPrefab;
  11. [SerializeField] TextMeshProUGUI changePinLocationPopupTitle, yourLocationText, pinLocationText;
  12. [SerializeField] TMP_InputField latInput, lonInput;
  13. [SerializeField] Button placeButton, place10MButton, closeButton;
  14. List<GPSPin> pins = new List<GPSPin>();
  15. GPSPin currentPin;
  16. Dictionary<GPSPin, TextMeshProUGUI> pinListTitles = new Dictionary<GPSPin, TextMeshProUGUI>();
  17. private WorldTracker wt;
  18. private const float EarthRadius = 6371000;
  19. IEnumerator Start()
  20. {
  21. wt = FindObjectOfType<WorldTracker>();
  22. wt.geolocationSettings.OnGPSPositionUpdated.AddListener(UpdatePositions);
  23. closeButton.onClick.AddListener(HideEditPopup);
  24. placeButton.onClick.AddListener(()=>{
  25. if(currentPin != null) {
  26. ChangePinLocation(currentPin);
  27. HideEditPopup();
  28. }
  29. });
  30. place10MButton.onClick.AddListener(()=>{
  31. if(currentPin != null){
  32. Add10MetersInFrontToGPS(currentPin);
  33. HideEditPopup();
  34. }
  35. });
  36. yield return new WaitForEndOfFrame();
  37. InitializePinList();
  38. }
  39. public void InitializePinList(){
  40. foreach(var pin in wt.geolocationSettings.gpsPins){
  41. pins.Add(pin);
  42. var pinListItem = Instantiate(pinListItemPrefab, pinListItemPrefab.transform.parent);
  43. var pinListTitle = pinListItem.transform.Find("Title").GetComponent<TextMeshProUGUI>();
  44. pinListTitle.text = pin.id + " - " + "? m away";
  45. pinListTitles.Add(pin, pinListTitle);
  46. pinListItem.transform.Find("Edit Button").GetComponent<Button>().onClick.AddListener(()=>{
  47. ShowEditPopup(pin);
  48. });
  49. }
  50. pinListItemPrefab.SetActive(false);
  51. }
  52. public void ShowEditPopup(GPSPin pin){
  53. changePinLocationPopup.SetActive(true);
  54. changePinLocationPopupTitle.text = "CHANGE " + pin.id + " LOCATION";
  55. currentPin = pin;
  56. }
  57. public void HideEditPopup(){
  58. changePinLocationPopup.SetActive(false);
  59. currentPin = null;
  60. }
  61. public void ChangePinLocation(GPSPin pin){
  62. var lat = Double.Parse(latInput.text);
  63. var lon = Double.Parse(lonInput.text);
  64. if(lat >= -90f && lat <= 90f && lon >= -180f && lon <= 180f){
  65. pin.latitude = lat;
  66. pin.longitude = lon;
  67. HideEditPopup();
  68. UpdatePositions(lastData);
  69. }
  70. }
  71. GPSData lastData;
  72. public void UpdatePositions(GPSData data){
  73. var myLat = data.latitude;
  74. var myLon = data.longitude;
  75. foreach(var pin in pins){
  76. var distance = CalculateDistance((float)myLat, (float)myLon, 0, (float)pin.latitude, (float)pin.longitude, 0);
  77. distance = Mathf.Round(distance / 5) * 5;
  78. var pinListTitle = pinListTitles[pin];
  79. var colorTag = distance > 1000 ? "<color=red>" : "<color=white>";
  80. pinListTitle.text = pin.id + " - " + colorTag + distance + " meters</color> away";
  81. }
  82. lastData = data;
  83. }
  84. public void Add10MetersInFrontToGPS( GPSPin pin)
  85. {
  86. var cam = GameObject.FindObjectOfType<ARCamera>().transform;
  87. var camHeading = Quaternion.Euler(0, cam.eulerAngles.y, 0);
  88. Vector3 displacement = camHeading * new Vector3(0, 0, 10);
  89. double lat = lastData.latitude;
  90. double lon = lastData.longitude;
  91. double alt = lastData.altitude;
  92. // 1 degree of latitude in meters
  93. double metersPerLatDegree = 111320.0;
  94. // 1 degree of longitude in meters, varies based on latitude
  95. double metersPerLonDegree = 111320.0 * Math.Cos(lat * Math.PI / 180.0);
  96. pin.latitude = lat + (displacement.z / metersPerLatDegree);
  97. pin.longitude = lon + (displacement.x / metersPerLonDegree);
  98. pin.altitude = alt + displacement.y;
  99. UpdatePositions(lastData);
  100. }
  101. public static float CalculateDistance(float lat1, float lon1, float alt1, float lat2, float lon2, float alt2)
  102. {
  103. float lat1Rad = lat1 * Mathf.Deg2Rad;
  104. float lon1Rad = lon1 * Mathf.Deg2Rad;
  105. float lat2Rad = lat2 * Mathf.Deg2Rad;
  106. float lon2Rad = lon2 * Mathf.Deg2Rad;
  107. float deltaLat = lat2Rad - lat1Rad;
  108. float deltaLon = lon2Rad - lon1Rad;
  109. float a = Mathf.Sin(deltaLat / 2) * Mathf.Sin(deltaLat / 2) +
  110. Mathf.Cos(lat1Rad) * Mathf.Cos(lat2Rad) *
  111. Mathf.Sin(deltaLon / 2) * Mathf.Sin(deltaLon / 2);
  112. float c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1 - a));
  113. float horizontalDistance = EarthRadius * c;
  114. float altitudeDifference = alt2 - alt1;
  115. float totalDistance = Mathf.Sqrt(horizontalDistance * horizontalDistance + altitudeDifference * altitudeDifference);
  116. return totalDistance;
  117. }
  118. }
  119. }