zoukankan      html  css  js  c++  java
  • 学习《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

  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/booolee/p/1550530.html
Copyright © 2011-2022 走看看