GIS中圖斑橢球面積的計算


我們都知道投影就是將球面通過一定的規則展開成平面,方便瀏覽和計算,投影就會產生變化,無論是角度、面積還是長度。在實際工作中,經常要計算圖斑面積,這里簡單總結一下常用的計算方法。

面積量算

先來看一下ArcMap中不同坐標系統通過面積量算得到的結果。

情況一:無空間參考,在空白地圖中加載一個沒有定義坐標系統的圖斑(雖然沒有坐標系統,但有坐標值,只不過坐標單位是未知單位),在加入時會彈出"未知的空間參考"的警告。

使用測量工具能夠量算距離和面積,雖然量測值,但是量測單位為未知,當然也就不能切換距離或面積單位了。

情況二:地理坐標。我們將上述圖斑文件定義正確的地理坐標,重新打開一個空白地圖添加定義空間參考后的圖斑文件,發現可以測量距離,坐標單位可以由度(數據本身的單位)切換成平面單位,但無法量測面積。

情況三:投影坐標。我們將上述定義了地理坐標的文件投影成合適的投影坐標(38帶),就可以正常量取距離和面積了。

情況四:不同投影坐標。我們再將上述定義了地理坐標的文件投影另外一個投影帶(30帶),對比可看出它們二者的形變。

通過計算幾何,可看到它們的面積差距是有差距的。

計算幾何和通過!shape.Area!計算的結果都一樣,都是投影面積。

一般地,采用高斯3度投影,相鄰的兩個投影帶計算的面積差距可能幾十到幾百平方不等。因此,這個面積只能是一個粗略值,在一些對面積精度要求比較高的項目中(如承包地)則不能采用投影面積。

橢球面積

那么,更准確一點的就是橢球面積,這里不講橢球面積的計算公式,在二調項目時,國土資源部下發了《關於統一圖幅理論面積與圖斑橢球面積計算要求》的通知,對圖幅理論面積與圖斑橢球面積計算公式進行了細化,明確了面積計算方法,統一了公式中的有關參數,有興趣的可以自行查詢和編程實現。

在ArcMap使用!shape.geodesicArea!即可計算,可以看出,面積1(38帶)更接近橢球面積,而面積2(30帶)則差距很大,因此選擇一個正確的投影非常重要。

值得注意的:

(1)同一個數據,在其地理坐標系統和投影坐標系統下計算的橢球面積有細微差距,原因是投影坐標計算橢球面積時,要先將投影轉換成地理坐標模型,這個轉換會有誤差。

(2)如果需要生成指定單位的橢球面積,可以在后面@單位,如!shape.geodesicArea@SQUAREMETERS!,表示的單位是平方米,如果不定,則是坐標系統的默認單位。

(3)未定義任何坐標系統的數據無法計算橢球面積。

代碼實現

使用Python代碼,利用ArcPy計算:

# 投影面積計算
arcpy.CalculateField_management(fc,"ProjectArea","!shape.Area!","PYTHON_9.3")
# 橢球面積計算
arcpy.CalculateField_management(fc,"GeoArea","!shape.geodesicArea@SQUAREKILOMETERS!","PYTHON_9.3")

使用C#代碼,利用ArcObject接口計算:

線接口:IPolycurveGeodetic.LengthGeodetic

面接口:IAreaGeodetic.AreaGeodetic

private void GetArea(IFeatureClass featureClass)
{
    IFeatureCursor featureCursor = featureClass.Search(null, true);
    IFeature feature = featureCursor.NextFeature();
    Console.WriteLine($@"序號          投影面積         正截面          測地線        等角航線        大橢圓面積");
    while (feature != null)
    {
        IArea area = (IArea)feature.Shape;
        IAreaGeodetic areaGeodetic = (IAreaGeodetic)feature.Shape;
        ILinearUnit linearUnit = new LinearUnitClass();
        double geodeticArea1 = areaGeodetic.AreaGeodetic[esriGeodeticType.esriGeodeticTypeNormalSection, linearUnit];
        double geodeticArea2 = areaGeodetic.AreaGeodetic[esriGeodeticType.esriGeodeticTypeGeodesic, linearUnit];
        double geodeticArea3 = areaGeodetic.AreaGeodetic[esriGeodeticType.esriGeodeticTypeLoxodrome, linearUnit];
        double geodeticArea4 = areaGeodetic.AreaGeodetic[esriGeodeticType.esriGeodeticTypeGreatElliptic, linearUnit];
        Console.WriteLine($@"{feature.OID}           {area.Area}         {geodeticArea1}         {geodeticArea2}         {geodeticArea3}           {geodeticArea4}");
        feature = featureCursor.NextFeature();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM