SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.5 KiB

4 years ago
  1. using System.Collections;
  2. using System.Xml;
  3. using UnityEngine;
  4. using UnityEngine.Networking;
  5. // ReSharper disable InconsistentNaming
  6. // ReSharper disable Unity.PerformanceCriticalCodeInvocation
  7. namespace ARLocation.Utils
  8. {
  9. public class POIData
  10. {
  11. public Location location;
  12. public string name;
  13. }
  14. [System.Serializable]
  15. public class OverpassRequestData
  16. {
  17. [Tooltip("The SouthWest end of the bounding box.")]
  18. public Location SouthWest;
  19. [Tooltip("The NorthEast end of the bounding box.")]
  20. public Location NorthEast;
  21. }
  22. [System.Serializable]
  23. public class OpenStreetMapOptions
  24. {
  25. [Tooltip("A XML with the results of a Overpass API query. You can use http://overpass-turbo.eu/ to generate one.")]
  26. public TextAsset OsmXmlFile;
  27. [Tooltip("If true, instead of the XML file above, we fetch the data directly from a Overpass API request to https://www.overpass-api.de/api/interpreter.")]
  28. public bool FetchFromOverpassApi;
  29. [Tooltip("The data configuration used for the Overpass API request. Basically a bounding box rectangle defined by two points.")]
  30. public OverpassRequestData overPassRequestData;
  31. }
  32. public class CreatePointOfInterestTextMeshes : MonoBehaviour
  33. {
  34. [Tooltip("The height of the text mesh, relative to the device.")]
  35. public float height = 1f;
  36. [Tooltip("The TextMesh prefab.")]
  37. public TextMesh textPrefab;
  38. [Tooltip("The smoothing factor for movement due to GPS location adjustments; if set to zero it is disabled."), Range(0, 500)]
  39. public float movementSmoothingFactor = 100.0f;
  40. [Tooltip("Locations where the text will be displayed. The text will be the Label property. (Optional)")]
  41. public Location[] locations;
  42. [Tooltip("Use this to either fetch OpenStreetMap data from a Overpass API request, or via a locally stored XML file. (Optional)")]
  43. public OpenStreetMapOptions openStreetMapOptions;
  44. POIData[] poiData;
  45. // List<ARLocationManagerEntry> entries = new List<ARLocationManagerEntry>();
  46. string xmlFileText;
  47. // Use this for initialization
  48. void Start()
  49. {
  50. // CreateTextObjects();
  51. AddLocationsPOIs();
  52. if (openStreetMapOptions.FetchFromOverpassApi && openStreetMapOptions.overPassRequestData != null)
  53. {
  54. StartCoroutine(nameof(LoadXMLFileFromOverpassRequest));
  55. }
  56. else if (openStreetMapOptions.OsmXmlFile != null)
  57. {
  58. LoadXMLFileFromTextAsset();
  59. }
  60. }
  61. private void LoadXMLFileFromTextAsset()
  62. {
  63. CreateTextObjects(openStreetMapOptions.OsmXmlFile.text);
  64. }
  65. string GetOverpassRequestURL(OverpassRequestData data)
  66. {
  67. var lat1 = data.SouthWest.Latitude;
  68. var lng1 = data.SouthWest.Longitude;
  69. var lat2 = data.NorthEast.Latitude;
  70. var lng2 = data.NorthEast.Longitude;
  71. return "https://www.overpass-api.de/api/interpreter?data=[out:xml];node[amenity](" + lat1 + "," + lng1 + "," + lat2 + "," + lng2 + ");out%20meta;";
  72. }
  73. IEnumerator LoadXMLFileFromOverpassRequest()
  74. {
  75. var www = UnityWebRequest.Get(GetOverpassRequestURL(openStreetMapOptions.overPassRequestData));
  76. yield return www.SendWebRequest();
  77. if (www.isNetworkError || www.isHttpError)
  78. {
  79. Debug.Log(www.error);
  80. Debug.Log(GetOverpassRequestURL(openStreetMapOptions.overPassRequestData));
  81. }
  82. else
  83. {
  84. // Show results as text
  85. Debug.Log(www.downloadHandler.text);
  86. CreateTextObjects(www.downloadHandler.text);
  87. }
  88. }
  89. public string GetNodeTagValue(XmlNode node, string tagName)
  90. {
  91. var children = node.ChildNodes;
  92. foreach (XmlNode nodeTag in children)
  93. {
  94. if (nodeTag.Attributes != null && nodeTag.Attributes["k"].Value == tagName)
  95. {
  96. return nodeTag.Attributes["v"].Value;
  97. }
  98. }
  99. return null;
  100. }
  101. public string GetNodeName(XmlNode node)
  102. {
  103. return (GetNodeTagValue(node, "poiName") ?? GetNodeTagValue(node, "amenity")) ?? "No Name";
  104. }
  105. // Update is called once per frame
  106. void CreateTextObjects(string text)
  107. {
  108. XmlDocument xmlDoc = new XmlDocument();
  109. xmlDoc.LoadXml(text);
  110. var nodes = xmlDoc.GetElementsByTagName("node");
  111. poiData = new POIData[nodes.Count];
  112. var i = 0;
  113. foreach (XmlNode node in nodes)
  114. {
  115. if (node.Attributes != null)
  116. {
  117. float lat = float.Parse(node.Attributes["lat"].Value);
  118. float lng = float.Parse(node.Attributes["lon"].Value);
  119. var nodeName = GetNodeName(node);
  120. poiData[i] = new POIData
  121. {
  122. // location = new Location(lat, lng, height),
  123. location = new Location()
  124. {
  125. Latitude = lat,
  126. Longitude = lng,
  127. AltitudeMode = AltitudeMode.GroundRelative,
  128. Altitude = height
  129. },
  130. name = nodeName
  131. };
  132. }
  133. i++;
  134. }
  135. for (var k = 0; k < poiData.Length; k++)
  136. {
  137. AddPOI(poiData[k].location, poiData[k].name);
  138. }
  139. }
  140. void AddLocationsPOIs()
  141. {
  142. foreach (var location in locations)
  143. {
  144. AddPOI(location, location.Label);
  145. }
  146. }
  147. // ReSharper disable once UnusedParameter.Local
  148. void AddPOI(Location location, string poiName)
  149. {
  150. var textInstance = PlaceAtLocation.CreatePlacedInstance(textPrefab.gameObject, location,
  151. new PlaceAtLocation.PlaceAtOptions()
  152. {
  153. MovementSmoothing = 0.1f,
  154. HideObjectUntilItIsPlaced = true,
  155. MaxNumberOfLocationUpdates = 10,
  156. UseMovingAverage = false
  157. }, true);
  158. textInstance.GetComponent<TextMesh>().text = poiName;
  159. }
  160. }
  161. }