对于GIS来说,二维坐标系统是一个用来测量距离的平面参考网格,三维坐标系统用于在三维空间测量距离。一个坐标系统一般由地图投影,椭球体和基准面定义,一个或多个纬线,一个中央经线,和水平或垂直方向的位移。FME对象的坐标系统概念数据模型:
上图为概念上的FMEOCoordSysManager数据模型,FME对象没有提供概念图中一对一的API,FMEOCoordSysManager提供属性和方法来访问这些类,方法和属性如下图:
大多数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