GDAL在Unity3D中的使用(二)
  ZcJgkb1g5qMe 2023年11月02日 52 0

我使用GDAL最终目的是为了获取OSGB数据中的GPS.

首先,我们需要配置环境变量

public class GameManager : MonoBehaviour
{
    private void Awake()
    {
        string str = Application.streamingAssetsPath + @"/Data/proj9";
        str = str.Replace("/", "\\");

        var abc = Environment.GetEnvironmentVariable("PROJ_LIB", EnvironmentVariableTarget.User);
        if (!string.IsNullOrEmpty(abc))
        {
            if(abc != str)
            {
                Environment.SetEnvironmentVariable("PROJ_LIB", str, EnvironmentVariableTarget.User);
                Debug.LogError("重新配置环境变量:" + str);
                Osr.SetPROJSearchPath(str);
                Gdal.SetConfigOption("PROJ_LIB", str);
            }
        }
        else
        {
            Environment.SetEnvironmentVariable("PROJ_LIB", str, EnvironmentVariableTarget.User);
            Debug.LogError("配置环境变量:" + str);
            Osr.SetPROJSearchPath(str);
            Gdal.SetConfigOption("PROJ_LIB", str);
        }
        Gdal.AllRegister();
    }
}

其次,我们要解析OSGB数据中的 metadata.xml

GDAL在Unity3D中的使用(二)_Unity

/// <summary>
/// 定义对象 OSGB数据文件中的 metadata.xml
/// </summary>
public class OSGBDataXml
{
    private string data;
    private double x;
    private double y;

    public string Data { get => data; set => data = value; }
    public double X { get => x; set => x = value; }
    public double Y { get => y; set => y = value; }
}

/// <summary>
/// 解析OSGB的XML
/// </summary>
/// <param name="path"> metadata.xml 路径</param>
/// <returns></returns>
private OSGBDataXml XMLAnalyzed(string path)
{
    XmlDocument xml = new XmlDocument();    //xml文件对象
    XmlReaderSettings set = new XmlReaderSettings();    //一个读取xml设置的对象
    set.IgnoreComments = true;  //设置忽略xml注释文档的影响,有时候注释会影响到xml的读取

    string xmlPath = path + "metadata.xml";
    if (!File.Exists(xmlPath))
    {
        Debug.LogError("metadata.xml 不存在!");
        return null;
    }

    XmlReader reader = XmlReader.Create(xmlPath, set);   //xml读取对象
    xml.Load(reader);   //加载xml文件
    XmlNode nodeSRS = xml.SelectSingleNode("//SRS");
    XmlNode nodeSRSOrigin = xml.SelectSingleNode("//SRSOrigin");
    string[] strs = nodeSRSOrigin.InnerText.Split(',');

    OSGBDataXml oSGBDataXml = new OSGBDataXml();
    oSGBDataXml.Data = nodeSRS.InnerText;
    oSGBDataXml.X = double.Parse(strs[0]);
    oSGBDataXml.Y = double.Parse(strs[1]);
    //Debug.Log($"OSGBDataXml.data: {oSGBDataXml.Data}    X:{oSGBDataXml.X}    Y:{oSGBDataXml.Y}");
    return oSGBDataXml;
}

最后,我们就要转换坐标系,就可以获得我们想要的坐标值了

/// <summary>
/// 坐标系转换
/// </summary>
/// <param name="metadata">OSGB中 metadata.xml</param>
/// <param name="epsg">目标坐标系代号</param>
 public void CoordinateSystemTransformation1(OSGBDataXml metadata, int epsg = 4490)
 {
     //不同椭球下进行坐标转换
     SpatialReference sourceSr = new SpatialReference(string.Empty);
     //OSGB中metadata.xml文件,内容可能会不一样,分地方坐标系和标准坐标系
     if (metadata.Data.StartsWith("EPSG"))//如果开头是EPSG  则为标准坐标系
     {
         int epsgValue = 4490;
         int.TryParse(metadata.Data.Substring(5), out epsgValue);//需要获取坐标系代号
         sourceSr.ImportFromEPSG(epsgValue);//设置代号为xxxx的坐标系
     }
     else//否则为地方坐标系
     {
         var xmlData = metadata.Data;
         sourceSr.ImportFromWkt(ref xmlData);//如果是地方坐标系则不是代号,而是一段str
     }

     SpatialReference targetSr = new SpatialReference(string.Empty);
     targetSr.ImportFromEPSG(epsg); //CGCS2000  目标坐标系
     // 获取该投影坐标系统中的地理坐标系统
     var targetSr1 = targetSr.CloneGeogCS();
     //转换到投影坐标系
     CoordinateTransformation coordinateTransformation = new CoordinateTransformation(sourceSr, targetSr1);
     if (coordinateTransformation == null)
     {
         Debug.LogError("创建坐标转换关系失败!");
     }

	  ///转换方式为单点
     double[] p = new double[3] { metadata.X, metadata.Y, 0 };
     Debug.LogError("平面坐标:" + p[1] + "  " + p[0]);
     coordinateTransformation.TransformPoint(p);
     Debug.LogError("经纬度坐标:" + p[0] + "  " + p[1]);
 }

转换坐标系这块,参考的这篇文章:

https://blog.csdn.net/qq_37390625/article/details/105082852

地方坐标系与标准坐标系 metadata.xml 示例(数据是假的)

标准的:

GDAL在Unity3D中的使用(二)_Unity_02

地方的:

GDAL在Unity3D中的使用(二)_Unity_03

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论