[轉載]ArcEngine中的Spatial Refrence

空間參考是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()
{
    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++)
     
{
        IProjection projection 
= projectionSet.Next() as IProjection;
        System.Windows.Forms.MessageBox.Show(projection.Name);
    }

}


    //CreatePredefinedProjections返回AE中所有預定義的投影座標,一共59個。ISpatialReferenceFactory的CreateESRISpatialReferenceFromPRJFile方法可以從已定義的PRJ文件獲取座標。

private IProjectedCoordinateSystem LoadProjectedCoordinateSystem()
{
    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)
{
    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()
{
    //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());
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章