arcpy获取国土用地坐标范围的正确路径

昨天尝试了几种获取坐标范围方式,效率都不太高。
昨天的看这里:arcpy获取国土用地坐标范围的几种尝试
考虑到最简便的方法是直接获取当前图层框的范围,然后把投影坐标转换成经纬度坐标是最快捷的,于是在CSDN找,确实有不少高斯投影转经纬度的文章
1、python实现高斯投影正反算
2、Python 高斯坐标转经纬度算法
经测试在我用的用地范围内,第一个误差最小
这里是高斯投影坐标转换经纬度代码,把参数更新成了CGCS2000的,差异很小。

'''
2000国家大地坐标系的大地测量基本常数分别为:
长半轴 a = 6378137 m        
地球引力常数 GM =3.986004418×1014m3s-2
扁率f = 1/ 298.257222101 = 0.0033528106811823  
地球自转角速度X =7.292115×10-5rad s-1
'''

def latlng2xy(latitude, longitude):
    a = 6378137.0
    e2 = 0.00669342162296594323
    #将经纬度转换为弧度
    latitude2Rad = (math.pi / 180.0) * latitude

    beltNo = int((longitude + 1.5) / 3.0) #计算3度带投影度带号
    L = beltNo * 3 #计算中央经线
    l0 = longitude - L #经差
    tsin = math.sin(latitude2Rad)
    tcos = math.cos(latitude2Rad)
    t = math.tan(latitude2Rad)
    m = (math.pi / 180.0) * l0 * tcos
    et2 = e2 * pow(tcos, 2)
    et3 = e2 * pow(tsin, 2)
    X = 111132.9558 * latitude - 16038.6496 * math.sin(2 * latitude2Rad) + 16.8607 * math.sin(
        4 * latitude2Rad) - 0.0220 * math.sin(6 * latitude2Rad)
    N = a / math.sqrt(1 - et3)

    x = X + N * t * (0.5 * pow(m, 2) + (5.0 - pow(t, 2) + 9.0 * et2 + 4 * pow(et2, 2)) * pow(m, 4) / 24.0 + (
    61.0 - 58.0 * pow(t, 2) + pow(t, 4)) * pow(m, 6) / 720.0)
    y = 500000 + N * (m + (1.0 - pow(t, 2) + et2) * pow(m, 3) / 6.0 + (
    5.0 - 18.0 * pow(t, 2) + pow(t, 4) + 14.0 * et2 - 58.0 * et2 * pow(t, 2)) * pow(m, 5) / 120.0)

    return x, y+40000000


def xy2latlng(X, Y, L0):

    iPI = 0.0174532925199433
    a = 6378137.0
    f= 0.0033528106811823
    ZoneWide = 3 #按3度带进行投影

    ProjNo = int(X / 1000000)
    L0 = L0 * iPI
    X0 = ProjNo * 1000000 + 500000
    Y0 = 0
    xval = X - X0
    yval = Y - Y0

    e2 = 2 * f - f * f #第一偏心率平方
    e1 = (1.0 - math.sqrt(1 - e2)) / (1.0 + math.sqrt(1 - e2))
    ee = e2 / (1 - e2) #第二偏心率平方

    M = yval
    u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256))

    fai = u \
          + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * math.sin(2 * u) \
          + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * math.sin(4 * u) \
          + (151 * e1 * e1 * e1 / 96) * math.sin(6 * u)\
          + (1097 * e1 * e1 * e1 * e1 / 512) * math.sin(8 * u)
    C = ee * math.cos(fai) * math.cos(fai)
    T = math.tan(fai) * math.tan(fai)
    NN = a / math.sqrt(1.0 - e2 * math.sin(fai) * math.sin(fai))
    R = a * (1 - e2) / math.sqrt(
        (1 - e2 * math.sin(fai) * math.sin(fai)) * (1 - e2 * math.sin(fai) * math.sin(fai)) * (1 - e2 * math.sin(fai) * math.sin(fai)))
    D = xval / NN

    #计算经纬度(弧度单位的经纬度)
    longitude1 = L0 + (D - (1 + 2 * T + C) * D * D * D / 6 + (
    5 - 2 * C + 28 * T - 3 * C * C + 8 * ee + 24 * T * T) * D * D * D * D * D / 120) / math.cos(fai)
    latitude1 = fai - (NN * math.tan(fai) / R) * (
    D * D / 2 - (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D * D * D * D / 24 + (
    61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720)

    #换换为deg
    longitude = longitude1 / iPI
    latitude = latitude1 / iPI

    return latitude, longitude

用昨天第2种获取图层范围来获取投影范围,适合全覆盖,由于坐标转换有细微偏差,增加了一圈范围,这样就能全覆盖。
注意:昨天第1种获取图层框投影范围,是获取的屏幕显示范围,如果是需要局部范围也可以使用。
昨天的看这里:arcpy获取国土用地坐标范围的几种尝试

def get_extent(add = 0.0005): 
    mxd = arcpy.mapping.MapDocument("CURRENT")
    layer =  arcpy.mapping.ListLayers(mxd, ly_name)[0]
    extent = str(layer.getExtent(False)).split()
    for i in range(4):
        extent[i]= float(extent[i])
    extent = extent[:4]
    
    latmin,lngmin = xy2latlng(extent[0],extent[1], 120) #上面的转换函数
    latmax,lngmax = xy2latlng(extent[2],extent[3], 120)
    
    return latmin-add,lngmin-add,latmax+add,lngmax+add

测试一下,够快了!

if __name__ == '__main__':
    s_time=time.time()
    ly_name = '佴池三调'
    ex = get_extent()
    e_time=time.time()
    print("耗时: %.4f s!" % (e_time - s_time)) 
>>>耗时: 0.0040 s!

画框子看看,扩了一点范围

#画个范围框
def kuang(ymin,xmin,ymax,xmax):
    kuang = [[xmin,ymin],[xmin,ymax],[xmax,ymax],[xmax,ymin]]
    mxd = arcpy.mapping.MapDocument("CURRENT")
    sd_layer =  arcpy.mapping.ListLayers(mxd, ly_name)[0]
    path = sd_layer.workspacePath
    coordinate = arcpy.SpatialReference(4490) #CGCS2000
    arcpy.CreateFeatureclass_management (path, 'k_dian',"POINT", "", "","", coordinate)
    rows=arcpy.InsertCursor('k_dian')
    for i in range(len(kuang)):
        row = rows.newRow()
        vertex = arcpy.CreateObject("Point")
        vertex.X = kuang[i][0]
        vertex.Y = kuang[i][1]
        row.shape = vertex
        rows.insertRow(row)
    
    arcpy.PointsToLine_management("k_dian", path+'\\kuang',"","" ,"CLOSE" )
 
 kuang(ex[0],ex[1],ex[2],ex[3])

在这里插入图片描述

话不多说,直接上代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace _高斯投影 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } double DD2RAD(double n) { double DD; double MM; double SS; DD = Math.Floor(n); MM = Math.Floor((n - DD) * 100); SS = ((n - DD) * 100 - MM) * 100; n = (DD + MM / 60.0 + SS / 3600.0) * Math.PI / 180.0; return n; } private void Form2_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { double B, L; B = double.Parse(textBox1.Text); B = DD2RAD(B); L = double.Parse(textBox2.Text); L = DD2RAD(L); double L0 = double.Parse(textBox3.Text); L0 = DD2RAD(L0); double a = double.Parse(textBoxa.Text); double e2 = double.Parse(textBoxe2.Text); double A = 1.0 + 3.0 * e2 / 4 + 45.0 * e2 * e2 / 64 + 175.0 * Math.Pow(e2, 3) / 256 + 11025.0 * Math.Pow(e2, 4) / 16384 + 43659.0 * Math.Pow(e2, 5) / 65536; double B0 = 3.0 * e2 / 4 + 15.0 * e2 * e2 / 16 + 525.0 * Math.Pow(e2, 3) / 512 + 2205.0 * Math.Pow(e2, 4) / 2048 + 72765.0 * Math.Pow(e2, 5) / 65536; double C = 15.0 * e2 * e2 / 64 + 105.0 * Math.Pow(e2, 3) / 256 + 2205.0 * Math.Pow(e2, 4) / 4096 + 10395.0 * Math.Pow(e2, 5) / 16384; double D = 35.0 * Math.Pow(e2, 3) / 512 + 315.0 * Math.Pow(e2, 4) / 2048 + 31185.0 * Math.Pow(e2, 5) / 131072; double α = A * a * (1 - e2);//α double β = -B0 * a * (1 - e2) / 2.0;//β double γ = C * a * (1 - e2) / 4.0; double σ = -D * a * (1 - e2) / 6.0; double X
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

规划酱

谢谢鼓励!一起自动化!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值