Files
2026-02-21 16:45:37 +08:00

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);
}
}