• 学习《Building Applications with FME Objects》 之七 坐标系统


    对于GIS来说,二维坐标系统是一个用来测量距离的平面参考网格,三维坐标系统用于在三维空间测量距离。一个坐标系统一般由地图投影,椭球体和基准面定义,一个或多个纬线,一个中央经线,和水平或垂直方向的位移。FME对象的坐标系统概念数据模型:

    image

     

    上图为概念上的FMEOCoordSysManager数据模型,FME对象没有提供概念图中一对一的API,FMEOCoordSysManager提供属性和方法来访问这些类,方法和属性如下图:

     

    image

    大多数FME对象应用程序是不需要关心坐标系统的,因为FME对象的通用转换坐标系统对于大多数应用程序是够用的,但有些程序还是需要的,FMEOCoordSysManager对象提供了强大而灵活的方法来定义坐标系统。

     

    入股欧尼的应用程序需要定义坐标系统,你需要阅读FME Foundation手册中的Coordinate System Support章节,里面介绍了FME对象支持坐标系统的基础信息,还有一些重要信息在FME Readers and Writer 手册中,其中每章都包含一个快速参考表,该表包含Coordinate System Support(支持坐标系统)行,如果该行值为YES,则表示这个格式可以存储坐标系统信息,reader可以从源数据集读取坐标系统信息,并且writer可以向目标数据集写入坐标系统信息,如果值为NO,则不能保存坐标系统信息,并且要素为未知坐标系统,writer将不能保存坐标系统信息。

     

    所有FME对象要素几何图形都关联一个坐标系统,并且可以再两个不同的坐标系统之间转换,首先改变坐标系统不是转换要素自身到新坐标系统,这步操作较tagging(标记),第二步变换坐标系统,并且同时转换要素自身到新坐标系统,这一步叫reprojecting (重投影)

     

    FME对象读取一个不支持坐标系统的格式时,要素几何图形将被关联到一个Unknown坐标系统,reader读这样的坐标系统时可能返回要素关联的是Unknown坐标系统或non-earth坐标系统,无论是哪种,在重投影时都被认为是Unknown做坐标系统,如果重投影一个要素到Unkonwn,其实就是给它标记为Unknown:

     

    在本章里可以学习到:

    • 检查几何要素坐标系统
    • 标记所有要素
    • 重投影所有要素
    • 标记个别要素
    • 重投影个别要素
    • 为一个用户会话创建临时坐标系统
    • 给FME对象添加一个持久化的坐标系统

    检查几何要素坐标系统

    如果从一个支持坐标系统的格式读取要素,你的应用程序需要检测几何图形的坐标系统以确定如何处理要素,下面的代码演示如何使用getCoodrSysParms方法,结合ellipsoid,datum和unit属性,来获得要素的所有坐标系统信息,坐标系统信息返回四个字符串数组,fme_CoordSysParams,fmeUnitParams,fmeDatumParams,fme_EllipsoidParams.

    Sub GetCoordSys(ByRef fmeFeature As FMEOFeature, _
                ByRef fmeCoordSysParams As FMEOStringArray, _
                ByRef fmeUnitParams As FMEOStringArray, _
                ByRef fmeDatumParams As FMEOStringArray, _
                ByRef fmeEllipsoidParams As FMEOStringArray)
        Dim sCoordSysName As String
        Dim sUnitName As String
        Dim sEllipsoidName As String
        Dim sDatumName As String
        Dim fmeCoordSysMan As FMEOCoordSysManager
        Dim lPosition As Long
        sCoordSysName = fmeFeature.coordSys
        Set fmeCoordSysMan = m_fmeSession.coordSysManager
        Set fmeCoordSysParams = fmeCoordSysMan.getCoordSysParms _

                                                (sCoordSysName)
        lPosition = GetIndex(fmeCoordSysParams, "UNIT")
        If lPosition >= 0 Then
            sUnitName = fmeCoordSysParams.element(lPosition + 1)
            Set fmeUnitParams = fmeCoordSysMan.unit(sUnitName)
        End If
        lPosition = GetIndex(fmeCoordSysParams, "DT_NAME")
        If lPosition >= 0 Then
            sDatumName = fmeCoordSysParams.element(lPosition + 1)
            Set fmeDatumParams = fmeCoordSysMan.datum(sDatumName)
            lPosition = GetIndex(fmeDatumParams, "ELLIPSOID")
            If lPosition >= 0 Then
                sEllipsoidName = fmeDatumParams.element( _
                                                    lPosition + 1)
                Set fmeEllipsoidParams = fmeCoordSysMan.ellipsoid _
                                                   (sEllipsoidName)
            End If
        Else
            lPosition = GetIndex(fmeCoordSysParams, "EL_NAME")
            If lPosition >= 0 Then
                sEllipsoidName = fmeCoordSysParams.element( _
                                                     lPosition + 1)
                Set fmeEllipsoidParams = fmeCoordSysMan.ellipsoid _
                                                   (sEllipsoidName)
            End If
        End If
    End Sub

     

    上面代码中GetIndex函数获取字符串数组中元素的索引,如果指定的元素不存在,GetIndex返回-1,GetIndex函数代码在Working with Collections章节。

     

    提示:当你的引用程序读取支持坐标系统的目录型数据集格式时,目录中的所有文件不一定是完全相同的坐标系统,这是FME对象将自动重投影所有的要素到第一个读取的要素坐标系统。

     

    如果你的应用程序需要用WKT格式定义的坐标系统,可以用getCoordSysAsOGCDef方法法代替getCoordSysParms,getCoordSysAsOGCDef支持多种WKT格式。

     

    标记输入要素

    通常需要给源数据集标记新的坐标系统。以下情况需要这样操作:

    • 源数据集没有关联坐标系统,而你想给它标记一个。
    • 源数据集的坐标系统错误,而你想纠正它。

    下面的代码标记所有输入要素到Beijing54.GK3d/CM-108E坐标系:

    fmeDirectives.append(”COORDSYS”)

    fmeDirectives.append(“Beijing54.GK3d/CM-108E”)

    Set m_fmeReader=m_fmeSession.createReader(strSourceFormat,True,fmeDirectives)

    如果FMEODialog的sourcePrompt方法从源数据集读取信息,则用户自行指定坐标系统选项,例如:

    bCompleted = fmeDialog.sourcePrompt("", "", _
    strSourceFormat, strSourceDataset, fmeUserDirectives)

    当方法返回时,用户指定的Beijing54.GK3d/CM-108E坐标系统将被包含在fmeUserDirectives字符串数组的COORDSYS,Beijing54.GK3d/CM-108E名值对中。

    注意:如果有多对COORDSYS传递给createReader方法,则指有第一对被使用。

    重投影要素

    下列代码为重投影所有要素到Beijing54.GK3d/CM-108E坐标系统:

    fmeDirectives.app(“COORDSYS”)

    fmeDirectives.app(“Beijing54.GK3d/CM-108E”)

    Set m_fmeWriter=m_fmeSession.createWriter(_strDestFormat,fmeDirectives)

    如果目标格式不支持坐标系统,重投影仍然执行。

    如果使用destPrompt方法交互获得目标数据集的信息,用户自行设置坐标系统。代码如下:

    bCompleted = fmeDialog.destPrompt("", "", strDestFormat, _
    strDestDataset, fmeUserDirectives)

    如果用户指定了Beijing54.GK3d/CM-108E坐标系统,则在方法返回时,fmeUserDirectives字符串数组将包含COORDSYS,10TM115-83名值对。

    注意:如果有多对COORDSYS传递给createReader方法,则指有第一对被使用。

    标记单个要素

    FMEOFeature的coordSys属性被用来标记要素到一个新的坐标系统,例如下面的代码:

    lFeatureCount = m_fmeFeatureVector.entries
    For i = 0 To lFeatureCount - 1
        m_fmeFeatureVector.element(i).coordSys = "10TM115-27"
    Next i

    创建临时坐标系统

    根据需要,你的应用程序可以创建一个新的坐标系统,使用unit,datum,ellipsoid和defineCoordSys方法完成。

    提示:这种方法创建的坐标系的生命周期和session的生命周期相等,下一节讲解如何创建持久化的坐标系统。

    例如下面的代码,用ellipsoid属性定义了新的椭球体MyEllipsoid,这个椭球体可以应用在session的生命周期中。

    fmeParameters.append ("E_RAD")
    fmeParameters.append ("6376950")
    fmeParameters.append ("P_RAD")
    fmeParameters.append ("6356352.616")
    fmeCoordSysMan.ellipsoid("MyEllipsoid") = fmeParameters

    与上面相似,用datum属性创建一个新的名称为MyDatum的基准面,使用MyEllipsoid椭球体。

    fmeParameters.Clear
    fmeParameters.append ("ELLIPSOID")
    fmeParameters.append ("MyEllipsoid")
    fmeParameters.append ("USE")
    fmeParameters.append ("3PARAMETER")

    最后,下面的代码用defineCoordSys创建新的参考MyDatum的临时坐标系统。

    fmeParameters.Clear
    fmeParameters.append ("PROJ")
    fmeParameters.append ("TM")
    fmeParameters.append ("UNIT")
    fmeParameters.append ("METER")
    fmeParameters.append ("DT_NAME")
    fmeParameters.append ("MyDatum")
    fmeParameters.append ("PARM1")
    fmeParameters.append ("9")
    fmeParameters.append ("ORG_LAT")
    fmeParameters.append ("0")
    fmeParameters.append ("X_OFF")
    fmeParameters.append ("3500000")
    fmeParameters.append ("Y_OFF")
    fmeParameters.append ("0")
    fmeParameters.append ("MAP_SCL")
    fmeParameters.append ("1")
    fmeParameters.append ("SCL_RED")
    fmeParameters.append ("1")
    Call fmeCoordSysMan.defineCoordSys(fmeParameters, _
                                        sCoordSysName)

    如果你的应用程序需要基于WKT格式字符串定义一个临时坐标系统,可以使用带有defineCoordSysParms参数的defineCoordSysFromOGCDef方法,该方法支持多种WKT格式。

     

    创建持久的坐标系统

    一个定义了坐标系统的本地文件被FME Session对象自动装载。该文件FME对象安装目录下Reproject子目录中的LocalCoordSysDefs.fme文件。它包含一系列COORDINATE_SYSTEM_DEF,DATUM_DEF,ELLIPSOID_DEF,UNIT_DEF定义,应用程序特定的坐标系统。

    编辑该文件添加自己的定义,具体方法可以查看FME在线帮助Coordinate Systems部分。

     

     

     

    参考资料:

    《Building Applications with FME Objects》February 2005

    转载请注明文章来源 http://www.cnblogs.com/booolee

  • 相关阅读:
    头指针与头结点的异同
    C:Users用户名AppData里面的文件可以删除吗
    mac os x在PC上安装
    迷宫问题
    对称自反传递
    判断
    离散实验模板
    离散实验二
    tp.5.0.21抛出错误
    php复制整个文件夹,此方法可过滤掉.svn文件夹
  • 原文地址:https://www.cnblogs.com/booolee/p/1550530.html
Copyright © 2020-2023  润新知