using System; using System.Collections.Generic; using UnityEngine; public class MegaShapeOSM { public static List osmnodes = new List(); public static List osmways = new List(); public static List tags = new List(); private MegaShapeOSMNode FindNode(ulong id) { for (int i = 0; i < osmnodes.Count; i++) { if (osmnodes[i].id == id) { return osmnodes[i]; } } return null; } public void AdjustPoints(float scale) { Bounds bounds = new Bounds(osmnodes[0].pos, Vector3.zero); for (int i = 0; i < osmnodes.Count; i++) { bounds.Encapsulate(osmnodes[i].pos); } for (int j = 0; j < osmnodes.Count; j++) { osmnodes[j].pos = ConvertLatLon(osmnodes[j].pos, bounds.center, scale, false); } } private Vector3 ConvertLatLon(Vector3 pos, Vector3 centre, float scale, bool adjust) { double num = 111322.3167 / (double)scale; double num2 = pos.x - centre.x; double num3 = pos.y - centre.y; double num4 = pos.z - centre.z; Vector3 result = default(Vector3); if (adjust) { double num5 = 6378137.0; result.x = (float)(num4 * (2.0 * (double)Mathf.Tan((float)Math.PI / 360f) * num5 * (double)Mathf.Cos((float)Math.PI / 180f * (float)num2))); } else { result.x = (float)(num4 * num); } result.z = (float)(num2 * num); result.y = (float)num3; return result; } public void LoadXMLTags(string sxldata) { osmnodes.Clear(); osmways.Clear(); tags.Clear(); MegaXMLReader megaXMLReader = new MegaXMLReader(); MegaXMLNode node = megaXMLReader.read(sxldata); ParseXML(node); } private bool CanImport(MegaShapeOSMWay way) { for (int i = 0; i < way.tags.Count; i++) { if (way.tags[i].import) { return true; } } return false; } private string GetName(MegaShapeOSMWay way) { string text = string.Empty; for (int i = 0; i < way.tags.Count; i++) { if (way.tags[i].import) { if (text.Length > 0) { text += " "; } text += way.tags[i].k; } } return text; } public void LoadXML(string sxldata, float scale, bool cspeed, string name, float smoothness, bool combine) { GameObject gameObject = new GameObject(); gameObject.name = name; AdjustPoints(scale); for (int i = 0; i < osmways.Count; i++) { MegaShapeOSMWay megaShapeOSMWay = osmways[i]; if (megaShapeOSMWay.nodes.Count > 1 && CanImport(megaShapeOSMWay)) { GameObject gameObject2 = new GameObject(); gameObject2.transform.position = Vector3.zero; gameObject2.transform.parent = gameObject.transform; if (megaShapeOSMWay.name.Length == 0) { megaShapeOSMWay.name = "No Name"; } gameObject2.name = GetName(megaShapeOSMWay); MegaShape megaShape = gameObject2.AddComponent(); megaShape.smoothness = smoothness; megaShape.drawHandles = false; MegaSpline megaSpline = megaShape.splines[0]; megaSpline.knots.Clear(); megaSpline.constantSpeed = cspeed; megaSpline.subdivs = 40; bool closed = false; int num = megaShapeOSMWay.nodes.Count; if (megaShapeOSMWay.nodes[0] == megaShapeOSMWay.nodes[num - 1]) { num--; closed = true; } Vector3[] array = new Vector3[num]; for (int j = 0; j < num; j++) { MegaShapeOSMNode megaShapeOSMNode = FindNode(megaShapeOSMWay.nodes[j]); array[j] = megaShapeOSMNode.pos; } Bounds bounds = new Bounds(array[0], Vector3.zero); for (int k = 0; k < array.Length; k++) { bounds.Encapsulate(array[k]); } for (int l = 0; l < array.Length; l++) { array[l] -= bounds.center; } gameObject2.transform.position = bounds.center; megaShape.BuildSpline(0, array, closed); megaShape.drawTwist = true; megaShape.makeMesh = false; megaShape.imported = true; megaShape.CoordAdjust(scale, new Vector3(1f, 1f, 1f), 0); megaShape.CalcLength(); megaShape.stepdist = megaShape.splines[0].length / (float)megaShape.splines[0].knots.Count / 1f; } } osmnodes.Clear(); osmways.Clear(); tags.Clear(); } public void ParseXML(MegaXMLNode node) { foreach (MegaXMLNode child in node.children) { string tagName = child.tagName; if (tagName != null && tagName == "osm") { ParseOSM(child); } ParseXML(child); } } public void ParseOSM(MegaXMLNode node) { foreach (MegaXMLNode child in node.children) { switch (child.tagName) { case "node": ParseNode(child); break; case "way": ParseWay(child); break; } } } public void ParseNode(MegaXMLNode node) { MegaShapeOSMNode megaShapeOSMNode = new MegaShapeOSMNode(); for (int i = 0; i < node.values.Count; i++) { MegaXMLValue megaXMLValue = node.values[i]; switch (megaXMLValue.name) { case "id": megaShapeOSMNode.id = ulong.Parse(megaXMLValue.value); break; case "lat": megaShapeOSMNode.pos.x = float.Parse(megaXMLValue.value); break; case "lon": megaShapeOSMNode.pos.z = float.Parse(megaXMLValue.value); break; } } osmnodes.Add(megaShapeOSMNode); } public void ParseWay(MegaXMLNode node) { MegaShapeOSMWay megaShapeOSMWay = new MegaShapeOSMWay(); megaShapeOSMWay.name = string.Empty; for (int i = 0; i < node.values.Count; i++) { MegaXMLValue megaXMLValue = node.values[i]; string name = megaXMLValue.name; if (name != null && name == "id") { megaShapeOSMWay.id = ulong.Parse(megaXMLValue.value); } } foreach (MegaXMLNode child in node.children) { switch (child.tagName) { case "nd": ParseND(child, megaShapeOSMWay); break; case "tag": ParseTag(child, megaShapeOSMWay); break; } } osmways.Add(megaShapeOSMWay); } public void ParseND(MegaXMLNode node, MegaShapeOSMWay way) { for (int i = 0; i < node.values.Count; i++) { MegaXMLValue megaXMLValue = node.values[i]; string name = megaXMLValue.name; if (name != null && name == "ref") { way.nodes.Add(ulong.Parse(megaXMLValue.value)); } } } private MegaShapeOSMTag FindTagK(string val) { for (int i = 0; i < tags.Count; i++) { if (tags[i].k == val) { return tags[i]; } } return null; } private MegaShapeOSMTag AddV(MegaShapeOSMTag tag, string v) { if (tag != null) { for (int i = 0; i < tag.vs.Count; i++) { if (tag.vs[i].k == v) { return tag.vs[i]; } } } MegaShapeOSMTag megaShapeOSMTag = new MegaShapeOSMTag(); megaShapeOSMTag.k = v; tag.vs.Add(megaShapeOSMTag); return megaShapeOSMTag; } public void ParseTag(MegaXMLNode node, MegaShapeOSMWay way) { MegaShapeOSMTag megaShapeOSMTag = null; for (int i = 0; i < node.values.Count; i++) { MegaXMLValue megaXMLValue = node.values[i]; switch (megaXMLValue.name) { case "k": megaShapeOSMTag = FindTagK(megaXMLValue.value); if (megaShapeOSMTag == null) { megaShapeOSMTag = new MegaShapeOSMTag(); megaShapeOSMTag.k = megaXMLValue.value; tags.Add(megaShapeOSMTag); } break; case "v": way.tags.Add(AddV(megaShapeOSMTag, megaXMLValue.value)); break; } } } public void importData(string sxldata, float scale, bool cspeed, string name, float smoothness, bool combine) { LoadXML(sxldata, scale, cspeed, name, smoothness, combine); } public void readOSMData(string sxldata) { LoadXMLTags(sxldata); } }