Spatial Reference

简介:

空间参考是GIS的基础,失去了空间参考信息,地理空间内所有的信息也就失去了存在的意义,因为它们是不准确的或是错误的。关于ArcGIS坐标系统文件,可以看看这篇文章——《ArcGIS 坐标系统文件》。

    刻画Spatial Reference的精度

    首先,我们主要讨论的是ArcGIS中Spatial Reference的各种精度,看到resolution、tolerance、domain、scale factor、precision,是否很熟悉?为了保证表达的准确性,所有这些关键字使用英文表述,不再译为中文。

    Resolution和domain范围决定了Geometry坐标的存储方式,Resolution和关联的坐标系使用相同的数量单位,如当空间参考使用以米为单位的投影参考时,XY resolution单位为米,默认情况下resolution=0.0001m,不管怎么样resolution值至少应该小于数据精度的1/10。当定位某一坐标到坐标格网时,我们依据如下公式:

    Persisted coordinate = Round((map coordinate - minimum domain extent) / resolution)

    在ArcGIS 9.2之前,resolution=1/precision,ArcGIS 9.2认为resolution和precision几乎相同,在9.2之前坐标的存储精度是31位,9.2中为53位,对于上面的公式而言,当resolution很小时,坐标系统表达数据会更精确,但在9.2之前的ArcGIS中persisted coordinate会受到限制。例如在ArcGIS 9.2之前,当minimum domain value=0,resolution=1时,maximum domain value=231-2,resolution=0.0001时,maximum domain value=(231-2)*0.0001=214748.3647;在ArcGIS 9.2中,当minimum domain value=0,resolution=1时,maximum domain value=253-2,resolution=0.0001时,maximum domain value=(253-2)*0.0001,很显然,ArcGIS 9.1中maximum domain value=214748.3647已经不能满足UTM、State Plane等投影坐标系的要求,ArcGIS 9.2存储的数据可以拥有更高精度的空间参考。

    默认情况下,ArcGIS 9.2为整数坐标采用53位空间存储,当然在编辑没有升级空间参考的空间数据库中的数据时,也可以保持向下兼容。新的COM接口已经可以用来判断数据采用的是低精度的各种空间参考,还是高精度的,同时有新的接口可以在低精度空间参考和高精度空间参考之间转换。

    还是默认情况下,Tolerance=10*resolution,minimum tolerance=2*resolution=2.0/scale factor,tolerance决定在relational和topological操作中,两个坐标之间的最小距离,当小于该距离时,认为这两个坐标为相同的坐标。relational和topological操作采用不同的tolerance会得到不同的处理结果。9.2之前tolerance值受resolution的影响,9.2中必须要明确指定tolerance的值,在IRelationalOperator、ITopologicalOperator等对两个几何对象进行Geometry操作的接口中,使用第一个对象的tolerance来判断两几何体点点之间的关系,如果空间参考是未定义,或没有空间参考和几何体关联,将采用该格网所允许的最小tolerance取值。

    如何编程?

    使用SpatialReferenceEnvironment

private  void PrintPreDefinedProjections()
ExpandedBlockStart.gif {
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
    ISet projectionSet = spatialReferenceFactory.CreatePredefinedProjections();

    System.Windows.Forms.MessageBox.Show("Number of predefined Projections = " + projectionSet.Count);

    projectionSet.Reset();
    for (int i = 0; i < projectionSet.Count; i++)
ExpandedSubBlockStart.gif    {
        IProjection projection = projectionSet.Next() as IProjection;
        System.Windows.Forms.MessageBox.Show(projection.Name);
    }

}


    CreatePredefinedProjections返回AE中所有预定义的投影坐标,一共59个。ISpatialReferenceFactory的CreateESRISpatialReferenceFromPRJFile方法可以从已定义的PRJ文件获取坐标。

private IProjectedCoordinateSystem LoadProjectedCoordinateSystem()
ExpandedBlockStart.gif {
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
    IProjectedCoordinateSystem projectedCoordinateSystem = spatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile("C:\\Program Files\\ArcGIS\\Coordinate Systems\\Projected Coordinate Systems\\World\\Mollweide (world).prj") as IProjectedCoordinateSystem;
    return projectedCoordinateSystem;
}

    除了ISpatialReferenceFactory接口,AE还提供ISpatialReferenceFactory3接口实现了创建垂直坐标系、构建高精度坐标系和低精度坐标系的系列方法。
private  void ConstructCoordinateSystem( bool highPrecision)
ExpandedBlockStart.gif {
    ISpatialReferenceFactory3 spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
    ISpatialReference3 spatialReference = spatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile("D:\\ArcGIS\\Coordinate Systems\\Geographic Coordinate Systems\\World\\WGS 1984.prj") as ISpatialReference3;

    IControlPrecision2 controlPrecision = spatialReference as IControlPrecision2;

    //Determines whether you are constructing a high or low.
    controlPrecision.IsHighPrecision = highPrecision;
    ISpatialReferenceResolution spatialReferenceResolution = spatialReference as ISpatialReferenceResolution;

    //These three methods are the keys, construct horizon, then set the default x,y resolution and tolerance.
    spatialReferenceResolution.ConstructFromHorizon();

    //Set the default x,y resolution value.
    spatialReferenceResolution.SetDefaultXYResolution();

    //Set the default x,y tolerance value.
    ISpatialReferenceTolerance spatialReferenceTolerance = spatialReference as ISpatialReferenceTolerance;
    spatialReferenceTolerance.SetDefaultXYTolerance();

    double xMin;
    double xMax;
    double yMin;
    double yMax;
    spatialReference.GetDomain(out xMin, out xMax, out yMin, out yMax);

    System.Windows.Forms.MessageBox.Show("Domain : " + xMin + ", " + xMax + ", " + yMin + ", " + yMax);
}

    IControlPrecision2.IsHighPrecision用来判断是否对数据采用高精度坐标,后面的设置空间参考的方法将根据这个判断来决定各种参数的精确程度。highPrecision等于true或false时,返回的Domain分别是:

    highPrecision=true   -400 9006799.25474099    -400 9006799.25474099
    highPrecision=false  -400 793.04646944444426 -400 793.04646944444426

    可以看出两者之间精度差别的大小。

    我们可以创建一个新的投影坐标系并保存为prj文件,同时可以利用这个prj生成一个新的投影坐标系。
private  void ImportExportSR_Example()
ExpandedBlockStart.gif {
    //Instantiate a predefined spatial reference and set its coordinate grid information.
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
    IProjectedCoordinateSystem projectedCoordinateSystem = spatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_WGS1984UTM_10N);
    ISpatialReferenceResolution spatialReferenceResolution = projectedCoordinateSystem as ISpatialReferenceResolution;
    ISpatialReferenceTolerance spatialReferenceTolerance = projectedCoordinateSystem as ISpatialReferenceTolerance;

    spatialReferenceResolution.ConstructFromHorizon();
    spatialReferenceTolerance.SetDefaultXYTolerance();

    //Export the PCS to a .prj file.
    String fileName = "c:\\temp\\utm10.prj";
    spatialReferenceFactory.ExportESRISpatialReferenceToPRJFile(fileName, projectedCoordinateSystem);

    //Rehydrate it as a new spatial reference object.
    ISpatialReference projectedCoordinateSystem2 = spatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile(fileName);

    //See if they are equal.
    IClone comparison = projectedCoordinateSystem as IClone;

    //Should be true, but coordinate grid information has not been checked.
    System.Windows.Forms.MessageBox.Show((comparison.IsEqual(projectedCoordinateSystem2 as IClone)).ToString());

    ISpatialReference2 comparePrecisions = projectedCoordinateSystem as ISpatialReference2;

    //Should be false, PRJ files do not persist coordinate grid information.
    System.Windows.Forms.MessageBox.Show((comparePrecisions.IsXYPrecisionEqual(projectedCoordinateSystem2)).ToString());
}

    两个空间参考是否相等不能简单通过一个方法来确定,IClone.isEqual只能比较坐标系相同,而不能确定坐标格网信息是否相同,因此最后一行代码比较的结果是false(IsXYPrecisionEqual是ISpatialReference2接口中的方法)。最后,看看如何自定义一个完整的投影坐标参考系,地理坐标系和垂直坐标系定义方法类似。
private  void SetProjectionParameters()
ExpandedBlockStart.gif {
    //Create a factory.
    ISpatialReferenceFactory2 spatialReferenceFactory = new SpatialReferenceEnvironmentClass();

    //Create a projection, GeographicCoordinateSystem, and unit using the factory.
    IProjectionGEN projection = spatialReferenceFactory.CreateProjection((int)esriSRProjectionType.esriSRProjection_Sinusoidal) as IProjectionGEN;
    IGeographicCoordinateSystem geographicCoordinateSystem = spatialReferenceFactory.CreateGeographicCoordinateSystem((int)
esriSRGeoCSType.esriSRGeoCS_WGS1984);
    ILinearUnit unit = spatialReferenceFactory.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;

    //Get the default parameters from the projection.
    IParameter[] parameters = projection.GetDefaultParameters();

    //Iterate through the parameters and print out their name and value.
    for (int i = 0; i < parameters.Length; i++)
ExpandedSubBlockStart.gif    {
        IParameter currentParameter = parameters[i];
        if (currentParameter != null)
ExpandedSubBlockStart.gif        {
            System.Windows.Forms.MessageBox.Show(currentParameter.Name + ", " + currentParameter.Index + ", " + currentParameter.Value);
        }

    }


    //Reset one of the parameter values.
    IParameter parameter = parameters[2];
    parameter.Value = 45;

    //Create a projected coordinate system using the Define method.
    IProjectedCoordinateSystemEdit projectedCoordinateSystemEdit = new ProjectedCoordinateSystemClass();
    object name = "Newfoundland";
    object alias = "NF_LAB";
    object abbreviation = "NF";
    object remarks = "Most Eastern Province in Canada";
    object usage = "When making maps of Newfoundland";
    object geographicCoordinateSystemObject = geographicCoordinateSystem as object;
    object unitObject = unit as object;
    object projectionObject = projection as object;
    object parametersObject = parameters as object;

    projectedCoordinateSystemEdit.Define(ref name,
                                  ref alias,
                                  ref abbreviation,
                                  ref remarks,
                                  ref usage,
                                  ref geographicCoordinateSystemObject,
                                  ref unitObject,
                                  ref projectionObject,
                                  ref parametersObject);

    IProjectedCoordinateSystem4GEN projectedCoordinateSystem = projectedCoordinateSystemEdit as IProjectedCoordinateSystem4GEN;

    //Get the parameters from your new projected coordinate system and verify
    
//that the parameter value was changed.
    
//Create an array of IParameters with 16 elements.
    IParameter[] newParameters = new IParameter[16];

    //Get the parameters.
    projectedCoordinateSystem.GetParameters(ref newParameters);

    //Iterate through the parameters and print out their name and value.
    for (int i = 0; i < newParameters.Length; i++)
ExpandedSubBlockStart.gif    {
        IParameter currentNewParameter = newParameters[i];
        if (currentNewParameter != null)
ExpandedSubBlockStart.gif        {
            System.Windows.Forms.MessageBox.Show(currentNewParameter.Name + ", " + currentNewParameter.Index + ", " + currentNewParameter.Value);
        }

    }

}


    具体的可以设置每一个参数,精确定义空间参考。

    可以看到,关于Spatial Reference编程与实现无非就是在几个接口之间实现,了解了这几个接口及它们之间的联系(参考GeometryObjectModel.pdf文档),也就了解了Spatial Reference编程的方法,当然基础是地理空间参考的基本理论知识。

本文转自Flyingis博客园博客,原文链接:http://www.cnblogs.com/flyingis/archive/2007/05/10/741602.html,如需转载请自行联系原作者

相关文章
HALCON error #1302: Wrong value of control parameter: 2 in operator affine_trans_region
HALCON error #1302: Wrong value of control parameter: 2 in operator affine_trans_region
|
10天前
|
算法 数据挖掘
文献解读-Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency
Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency,大panel二代测序的一致性和重复性:对具有错配修复和校对缺陷的参考物质进行体细胞突变检测的多实验室评估
22 6
文献解读-Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency
|
5月前
|
iOS开发
Xcode报错“compact unwind compressed function offset doesn‘t fit in 24 bits
Xcode报错“compact unwind compressed function offset doesn‘t fit in 24 bits
53 1
|
12月前
|
C++
Reference Parameter
Reference Parameter(引用参数)是一种 C++ 编程语言中的参数传递方式。它允许将一个变量的引用(而不是副本)作为函数参数传递。引用参数的主要优点是可以避免在函数内部对实参进行拷贝操作,从而提高代码的效率。
59 1
|
机器学习/深度学习 自然语言处理 算法
TPLinker: Single-stage Joint Extraction of Entities and Relations Through Token Pair Linking 论文解读
近年来,从非结构化文本中提取实体和关系引起了越来越多的关注,但由于识别共享实体的重叠关系存在内在困难,因此仍然具有挑战性。先前的研究表明,联合学习可以显著提高性能。然而,它们通常涉及连续的相互关联的步骤,并存在暴露偏差的问题。
188 0
|
人工智能 编解码 自然语言处理
论文解读:Inpaint Anything: Segment Anything Meets Image Inpainting
论文解读:Inpaint Anything: Segment Anything Meets Image Inpainting
390 0
|
机器学习/深度学习 自然语言处理 数据可视化
M2E2: Cross-media Structured Common Space for Multimedia Event Extraction 论文解读
我们介绍了一个新的任务,多媒体事件抽取(M2E2),旨在从多媒体文档中抽取事件及其参数。我们开发了第一个基准测试
91 0
|
机器学习/深度学习 自然语言处理 算法
ACL 2022:Graph Pre-training for AMR Parsing and Generation
抽象语义表示(AMR)以图形结构突出文本的核心语义信息。最近,预训练语言模型(PLM)分别具有AMR解析和AMR到文本生成的高级任务。
146 0
|
存储 Shell
Understanding parameters:理解参数(Parameter)
Understanding parameters:理解参数(Parameter)
109 0
【问题记录】utureWarning: Function get_feature_names is deprecated; get_feature_names is deprecated in 1.0
【问题记录】utureWarning: Function get_feature_names is deprecated; get_feature_names is deprecated in 1.0