Unity解析OSM数据,并生成简单模型

这篇博客介绍了如何在Unity中解析OpenStreetMap(OSM)的XML数据,包括XML解析方法、OSM数据结构、节点和路径的定义,以及使用LineRenderer组件对OSM数据进行简单可视化,最后展示了如何基于OSM数据创建道路和建筑的简单3D模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、介绍XML数据格式

因为OSM数据就是XML数据格式,所以先介绍一下XML数据格式。

XML 指可扩展标记语言(eXtensible Markup Language)。

  • XML 被设计用来传输和存储数据。
  • XML 文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶"。
  • XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。
    • XML 文档必须包含根元素。该元素是所有其他元素的父元素。
    • 所有的元素都可以有文本内容和属性(类似 HTML 中)。
    • 在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签。

XML 文档实例

<?xml version="1.0" encoding="UTF-8"?> <!-- XML声明:定义 XML 的版本和所使用的编码 -->
<note date="12/11/2007"> <!--根元素-->
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

以上显示了根元素note及它的四个子元素(Element)。

二、Unity解析XML数据格式的方法

1.C#自带的方法
//引入命名空间
using System.Xml;

public class Parser : MonoBehaviour
{
   
	//创建xml文档对象
    private XmlDocument doc = new XmlDocument();
    
    private void Start()
    {
   
    	//读入xml文件
    	XmlTextReader reader= new XmlTextReader("Assets/" + mapName);    	
    	//加载到xml文档对象中
    	doc.Load(reader);
    	
    	
    	//根据元素名称获取元素list
    	XmlNodeList elemList = doc.GetElementsByTagName("node");
		//获取元素的子元素们
		foreach (XmlNode node in elemList )
        {
   
            XmlNodeList children = node.ChildNodes;
        }
        
        
		//获取元素的某一属性名称
		string attrName = elemList[0].Attributes[0].Name;
		//获取元素的某一属性值
		string idStr = elemList[0].Attributes["id"].InnerText;
		//把string转为int
		int id = int.Parse(idStr);
    }
}
2.Unity读取TextAsset方法

TextAsset是用于导入文本文件的格式。当您将文本文件放入项目文件夹时,它将被转换为TextAsset。支持的文本格式有:.txt.html.htm.xml.bytes.json.csv.yaml.fnt

using System.Xml;

[Tooltip("The resource file that contains the OSM map data")]
public string resourceFile;

[HideInInspector]    public Dictionary<ulong, OsmNode> nodes;

void Start()
{
   
	//读取文件
	var txtAsset = Resources.Load<TextAsset>(resourceFile);
	//加载xml内容到xml文件对象
	XmlDocument doc = new XmlDocument();
    doc.LoadXml(txtAsset.text);
    //获取单个元素
    XmlNode xmlNode = doc.SelectSingleNode("/osm/bounds");
    //获取元素list
    XmlNodeList xmlNodeList = doc.SelectNodes("/osm/node"));
}

三、OSM数据介绍

OpenStreetMap的元素(数据基元)主要包括三种:

  • 点(Nodes)
  • 路(Ways)
  • 关系(Relations)

这三种元素构成了整个地图画面。其中,Nodes定义了空间中点的位置;Ways定义了线或区域;Relations(可选的)定义了元素间的关系。

根元素:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.0.2">
	<bounds minlat="34.1362000" minlon="-118.4360000" maxlat="34.2371000" maxlon="-118.2938000"/>
</osm>

node元素:

<node id="10537778" lat="34.1650043" lon="-118.2969154" user="mattmaxon" uid="96974" visible="true" version="18" changeset="787046" timestamp="2009-03-11T12:10:18Z"/>
<node id="10537785" lat="34.1732598" lon="-118.3062396" user="mattmaxon" uid="96974" visible="true" version="4" changeset="768622" timestamp="2009-03-09T13:57:18Z">
 	<tag k="highway" v="traffic_signals"/>
</node>

可以看到,node元素的属性有:idlatlonuseruidvisibleversionchangesettimestamp。我们实际上需要的只有前三个属性。其他属性的介绍可以看官方介绍

关于Tag元素:

Tags describe the meaning of the particular element to which they are attached.

简单来说就是用一些键值对表示这些元素的地图特征。并没有一个固定的字典来表示这些tag,但是可以参考这里:Map Features page

way元素:

<way id="40779547" user="NE2" uid="207745" visible="true" version="2" changeset="4563211" timestamp="2010-04-30T05:30:59Z">
  <nd ref="495645323"/>
  <nd ref="358076071"/>
  <nd ref="358076070"/>
  <nd ref="122950026"/>
  <nd ref="123377574"/>
  <nd ref="495645323"/>
  <tag k="landuse" v="residential"/>
  <tag k="source" v="City of Burbank"/>
</way>

每个way包含了多个nd元素。way的属性中我们也只需要id。

relation元素:

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值