python实现WGS84平面大地坐标(X,Y)转换经纬度BL类

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 28 09:53:08 2019
@author: Yiqingde
"""
import math

'''####################################################
类XYexchangeBL   进行WGS84坐标系下 的XY转为BL  
                 X已东偏500000
                 需要手动输入中央经线 例如114.152的中央经线是111
####################################################'''
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626  # π
a = 6378245.0  # 长半轴
ee = 0.00669342162296594323  # 扁率
class XYexchangeBL:
    '''###################
    #函数:get_WGS84_af(self)
    #WGS84椭球参数获得 
    #返回长半轴a 扁率f
    ###################'''
    def get_WGS84_af(self):
        '''
         * WGS84
         * 长半轴a=6378137± 2(m)
         * 短半轴b=6356752.3142m
         * 扁率α=1/298.257223563
         * 第一偏心率平方 =0.00669437999013
         * 第二偏心率平方 =0.00673949674223
        '''
        a=6378137.0
        f=1/298.257223563
        return a,f
    
    '''###################
    #函数:Process_Degree(self,dD)
    #输入值 十进制的经纬度(DEG) 
    #输出 度分秒的经纬度(DMS)
    ###################'''
    def Process_Degree(self,dD):
    	iDegree=int(dD)
    	dTmp=(dD-iDegree)*60
    	iMin=int(dTmp)
    	dSec=(dTmp-iMin)*60
    	dDegree=iDegree+float(iMin)/100+dSec/10000
    	return dDegree     
    
    '''###################
    函数:XY2LatLon(self,ellipsoid,X, Y, L0)
    #输入值 ellipsoid指明椭球体: WGS84的参数是 84
    #      X、Y:  大地坐标X Y
    #      L0:中央经线 如:111
    #输出 度分秒的经纬度(DMS)
    ###################'''
    def XY2LatLon(self,ellipsoid,X, Y, L0):
        X=X/0.9996#仅针对UTM投影
        Y=Y/0.9996#针对UTM投影
        #椭圆参数控制
        if(ellipsoid==84):
            a,f=self.get_WGS84_af()

        iPI=0.0174532925199433333333#圆周率/180
        ProjNo=int(X/1000000)
        L0=L0*iPI
  
       
        X0=ProjNo*1000000+500000#东偏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)#第二偏心率平方
        e2=0.00669437999013
        e1=(1.0-math.sqrt(1-e2))/(1.0+math.sqrt(1-e2))
        ee=0.00673949674223
        
        
        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=self.Process_Degree(longitude1/iPI)
        #latitude=self.Process_Degree(latitude1/iPI)
       
        longitude=longitude1/iPI
        latitude=latitude1/iPI
        #return latitude,longitude
        return self.wgs84togcj02(latitude,longitude)
    
    '''###################
    函数:wgs84togcj02(self,lat,lng)
    #输入值 经纬度(DMS)
    #      lng : 经度
    #      lat : 纬度 如:111
    #输出 火星坐标(DMS)
    ###################'''
    def wgs84togcj02(self,lat,lng):
        """
        WGS84转GCJ02(火星坐标系)
        :param lng:WGS84坐标系的经度
        :param lat:WGS84坐标系的纬度
        :return:
        """
        # if out_of_china(self,lng, lat):  # 判断是否在国内
        #    return lng, lat
        dlat = self.transformlat(lng - 105.0, lat - 35.0)
        dlng = self.transformlng(lng - 105.0, lat - 35.0)
        radlat = lat / 180.0 * pi
        magic = math.sin(radlat)
        magic = 1 - ee * magic * magic
        sqrtmagic = math.sqrt(magic)
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
        dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
        mglat = lat + dlat
        mglng = lng + dlng
        return [mglat,mglng]

    '''###################
    函数:transformlat(self,lng, lat)
    #输入值 经纬度(DMS)
    #输出 dlat
    ###################'''
    def transformlat(self,lng, lat):
        ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
            0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
        ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
                math.sin(2.0 * lng * pi)) * 2.0 / 3.0
        ret += (20.0 * math.sin(lat * pi) + 40.0 *
                math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
        ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
                math.sin(lat * pi / 30.0)) * 2.0 / 3.0
        return ret
    

    '''###################
    函数:transformlng(self,lng, lat)
    #输入值 经纬度(DMS)
    #输出 dlng
    ###################''' 
    def transformlng(self,lng, lat):
        ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
            0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
        ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
                math.sin(2.0 * lng * pi)) * 2.0 / 3.0
        ret += (20.0 * math.sin(lng * pi) + 40.0 *
                math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
        ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
                math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
        return ret

'''
#运行示例
temp=XYexchangeBL()

Geo: 28°18'6.69"N,112°56'13.81"E 28.301858333333332,112.93716944444445
Map: 689953.9843,3132164.3037

Geo: 28°10'37.22"N,113°4'18.08"E 28.177005555555557,113.07168888888889
Map: 703384.6243,3118547.1158

Geo: 28°16'45.56"N,113°9'13.04"E 28.279294444444446,113.15362222222222
Map: 711228.7756,3130026.1752

Geo: 28°10'45.66"N,112°57'5.34"E 28.17935,112.95148333333333
Map: 691576.7008,3118611.2265


b,l=temp.XY2LatLon(84,692417.6880,3123815.0629,111)
print(b,l)
print(b-28.133423,l-112.573925)
b,l=temp.XY2LatLon(84,742218.7207,2973934.4385,111)
print(b,l)
print(b-26.515796,l-113.261690)
b,l=temp.XY2LatLon(84,711228.7756,3130026.1752,111)
print(b,l)
print(b-28.279294444444446,l-113.15362222222222)
b,l=temp.XY2LatLon(84,691576.7008,3118611.2265,111)
print(b,l)
print(b-28.17935,l-112.95148333333333)

b,l=temp.XY2LatLon(84,457136.664,2455475.927,114)
print(b,l)
'''

将最后的运行实例取消注释,运行该py截图:

在这里插入图片描述

Welcome to my Github and my CSDN blog , more information will be available about the project!

https://github.com/Yiqingde

  • 4
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值