MegaShapeOSM.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. using UnityEngine;
  2. using System;
  3. using System.Collections.Generic;
  4. public class MegaShapeOSMTag
  5. {
  6. public bool show = true;
  7. public bool import = false;
  8. public MegaShapeOSMWay way;
  9. public string k;
  10. public List<MegaShapeOSMTag> vs = new List<MegaShapeOSMTag>();
  11. }
  12. public class MegaShapeOSMNode
  13. {
  14. //public int id;
  15. public ulong id;
  16. public Vector3 pos = Vector3.zero;
  17. }
  18. public class MegaShapeOSMWay
  19. {
  20. //public int id;
  21. public ulong id;
  22. public List<ulong> nodes = new List<ulong>();
  23. public string name = "None";
  24. public List<MegaShapeOSMTag> tags = new List<MegaShapeOSMTag>();
  25. }
  26. public class MegaShapeOSM
  27. {
  28. static public List<MegaShapeOSMNode> osmnodes = new List<MegaShapeOSMNode>();
  29. static public List<MegaShapeOSMWay> osmways = new List<MegaShapeOSMWay>();
  30. static public List<MegaShapeOSMTag> tags = new List<MegaShapeOSMTag>();
  31. MegaShapeOSMNode FindNode(ulong id)
  32. {
  33. for ( int i = 0; i < osmnodes.Count; i++ )
  34. {
  35. if ( osmnodes[i].id == id )
  36. {
  37. return osmnodes[i];
  38. }
  39. }
  40. return null;
  41. }
  42. public void AdjustPoints(float scale)
  43. {
  44. Bounds bounds = new Bounds(osmnodes[0].pos, Vector3.zero);
  45. for ( int i = 0; i < osmnodes.Count; i++ )
  46. bounds.Encapsulate(osmnodes[i].pos);
  47. for ( int i = 0; i < osmnodes.Count; i++ )
  48. osmnodes[i].pos = ConvertLatLon(osmnodes[i].pos, bounds.center, scale, false);
  49. }
  50. Vector3 ConvertLatLon(Vector3 pos, Vector3 centre, float scale, bool adjust)
  51. {
  52. double scl = (111322.3167 / scale);
  53. double x = pos.x - centre.x;
  54. double y = pos.y - centre.y;
  55. double z = pos.z - centre.z;
  56. Vector3 p;
  57. if ( adjust )
  58. {
  59. double r = 6378137.0;
  60. p.x = (float)(z * (2.0 * Mathf.Tan(Mathf.Deg2Rad * (0.5f)) * r * Mathf.Cos(Mathf.Deg2Rad * (float)x)));
  61. }
  62. else
  63. p.x = (float)(z * scl);
  64. p.z = (float)(x * scl);
  65. p.y = (float)y;
  66. return p;
  67. }
  68. public void LoadXMLTags(string sxldata) //, float scale, bool cspeed, string name, float smoothness)
  69. {
  70. osmnodes.Clear();
  71. osmways.Clear();
  72. tags.Clear();
  73. MegaXMLReader xml = new MegaXMLReader();
  74. MegaXMLNode node = xml.read(sxldata);
  75. ParseXML(node);
  76. }
  77. bool CanImport(MegaShapeOSMWay way)
  78. {
  79. for ( int i = 0; i < way.tags.Count; i++ )
  80. {
  81. if ( way.tags[i].import )
  82. return true;
  83. }
  84. return false;
  85. }
  86. string GetName(MegaShapeOSMWay way)
  87. {
  88. string name = "";
  89. for ( int i = 0; i < way.tags.Count; i++ )
  90. {
  91. if ( way.tags[i].import )
  92. {
  93. if ( name.Length > 0 )
  94. name += " ";
  95. name += way.tags[i].k;
  96. }
  97. }
  98. return name;
  99. }
  100. public void LoadXML(string sxldata, float scale, bool cspeed, string name, float smoothness, bool combine)
  101. {
  102. GameObject root = new GameObject();
  103. root.name = name;
  104. // Get bounds for imports
  105. AdjustPoints(scale);
  106. // Create a new shape object for each way
  107. for ( int i = 0; i < osmways.Count; i++ )
  108. {
  109. MegaShapeOSMWay way = osmways[i];
  110. if ( way.nodes.Count > 1 && CanImport(way) )
  111. {
  112. GameObject osmobj = new GameObject();
  113. osmobj.transform.position = Vector3.zero;
  114. osmobj.transform.parent = root.transform;
  115. if ( way.name.Length == 0 )
  116. way.name = "No Name";
  117. osmobj.name = GetName(way); //way.name;
  118. MegaShape shape = (MegaShape)osmobj.AddComponent<MegaShape>();
  119. shape.smoothness = smoothness; //smooth;
  120. shape.drawHandles = false;
  121. MegaSpline spline = shape.splines[0]; //NewSpline(shape);
  122. spline.knots.Clear();
  123. spline.constantSpeed = cspeed;
  124. spline.subdivs = 40;
  125. bool closed = false;
  126. int count = way.nodes.Count;
  127. if ( way.nodes[0] == way.nodes[count - 1] )
  128. {
  129. count--;
  130. closed = true;
  131. }
  132. Vector3[] points = new Vector3[count];
  133. for ( int j = 0; j < count; j++ )
  134. {
  135. MegaShapeOSMNode nd = FindNode(way.nodes[j]);
  136. points[j] = nd.pos;
  137. }
  138. Bounds bounds = new Bounds(points[0], Vector3.zero);
  139. for ( int k = 0; k < points.Length; k++ )
  140. bounds.Encapsulate(points[k]);
  141. for ( int k = 0; k < points.Length; k++ )
  142. points[k] -= bounds.center;
  143. osmobj.transform.position = bounds.center; //Vector3.zero;
  144. shape.BuildSpline(0, points, closed);
  145. shape.drawTwist = true;
  146. shape.makeMesh = false;
  147. shape.imported = true;
  148. shape.CoordAdjust(scale, new Vector3(1.0f, 1.0f, 1.0f), 0);
  149. shape.CalcLength(); //10);
  150. shape.stepdist = (shape.splines[0].length / shape.splines[0].knots.Count) / 1.0f;
  151. }
  152. }
  153. osmnodes.Clear();
  154. osmways.Clear();
  155. tags.Clear();
  156. }
  157. public void ParseXML(MegaXMLNode node)
  158. {
  159. foreach ( MegaXMLNode n in node.children )
  160. {
  161. switch ( n.tagName )
  162. {
  163. case "osm": ParseOSM(n); break;
  164. }
  165. ParseXML(n);
  166. }
  167. }
  168. public void ParseOSM(MegaXMLNode node)
  169. {
  170. foreach ( MegaXMLNode n in node.children )
  171. {
  172. switch ( n.tagName )
  173. {
  174. case "node": ParseNode(n); break;
  175. case "way": ParseWay(n); break;
  176. }
  177. }
  178. }
  179. public void ParseNode(MegaXMLNode node)
  180. {
  181. MegaShapeOSMNode onode = new MegaShapeOSMNode();
  182. for ( int i = 0; i < node.values.Count; i++ )
  183. {
  184. MegaXMLValue val = node.values[i];
  185. switch ( val.name )
  186. {
  187. case "id":
  188. //Debug.Log("id " + val.value);
  189. onode.id = ulong.Parse(val.value);
  190. break;
  191. case "lat": onode.pos.x = float.Parse(val.value); break;
  192. case "lon": onode.pos.z = float.Parse(val.value); break;
  193. }
  194. }
  195. osmnodes.Add(onode);
  196. }
  197. public void ParseWay(MegaXMLNode node)
  198. {
  199. MegaShapeOSMWay way = new MegaShapeOSMWay();
  200. way.name = "";
  201. for ( int i = 0; i < node.values.Count; i++ )
  202. {
  203. MegaXMLValue val = node.values[i];
  204. switch ( val.name )
  205. {
  206. case "id": way.id = ulong.Parse(val.value); break;
  207. }
  208. }
  209. foreach ( MegaXMLNode n in node.children )
  210. {
  211. switch ( n.tagName )
  212. {
  213. case "nd": ParseND(n, way); break;
  214. case "tag": ParseTag(n, way); break;
  215. }
  216. }
  217. osmways.Add(way);
  218. }
  219. public void ParseND(MegaXMLNode node, MegaShapeOSMWay way)
  220. {
  221. for ( int i = 0; i < node.values.Count; i++ )
  222. {
  223. MegaXMLValue val = node.values[i];
  224. switch ( val.name )
  225. {
  226. case "ref": way.nodes.Add(ulong.Parse(val.value)); break;
  227. }
  228. }
  229. }
  230. MegaShapeOSMTag FindTagK(string val)
  231. {
  232. for ( int i = 0; i < tags.Count; i++ )
  233. {
  234. if ( tags[i].k == val )
  235. {
  236. return tags[i];
  237. }
  238. }
  239. return null;
  240. }
  241. MegaShapeOSMTag AddV(MegaShapeOSMTag tag, string v)
  242. {
  243. if ( tag != null )
  244. {
  245. for ( int i = 0; i < tag.vs.Count; i++ )
  246. {
  247. if ( tag.vs[i].k == v )
  248. return tag.vs[i];
  249. }
  250. }
  251. MegaShapeOSMTag vtag = new MegaShapeOSMTag();
  252. vtag.k = v;
  253. tag.vs.Add(vtag);
  254. return vtag;
  255. }
  256. public void ParseTag(MegaXMLNode node, MegaShapeOSMWay way)
  257. {
  258. MegaShapeOSMTag tag = null;
  259. for ( int i = 0; i < node.values.Count; i++ )
  260. {
  261. MegaXMLValue val = node.values[i];
  262. switch ( val.name )
  263. {
  264. case "k":
  265. tag = FindTagK(val.value);
  266. if ( tag == null )
  267. {
  268. tag = new MegaShapeOSMTag();
  269. tag.k = val.value;
  270. tags.Add(tag);
  271. }
  272. break;
  273. case "v":
  274. way.tags.Add(AddV(tag, val.value));
  275. break;
  276. }
  277. }
  278. }
  279. public void importData(string sxldata, float scale, bool cspeed, string name, float smoothness, bool combine)
  280. {
  281. LoadXML(sxldata, scale, cspeed, name, smoothness, combine);
  282. }
  283. public void readOSMData(string sxldata)
  284. {
  285. LoadXMLTags(sxldata);
  286. }
  287. }