学习《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

posted @ 2009-08-20 12:27  电电儿  阅读(747)  评论(0编辑  收藏  举报