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