316 lines
7.3 KiB
C#
316 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class MegaShapeOSM
|
|
{
|
|
public static List<MegaShapeOSMNode> osmnodes = new List<MegaShapeOSMNode>();
|
|
|
|
public static List<MegaShapeOSMWay> osmways = new List<MegaShapeOSMWay>();
|
|
|
|
public static List<MegaShapeOSMTag> tags = new List<MegaShapeOSMTag>();
|
|
|
|
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>();
|
|
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);
|
|
}
|
|
}
|