python實現 經緯度的 各GIS座標系轉換

2021-09-10 23:25:43 字數 4580 閱讀 4922

這裡是gis座標的單點轉換.

下面是利用python反射機制實現的gis座標轉換類.精度不是很完美但一般也夠用啦.

# coding=utf-8

import math, re

class gistransform(object):

"""gis座標轉換類"""

def __init__(self, old_gis_name, new_gis_name):

"""經緯度(谷歌高德):'wgs84'/ 墨卡托:'webmercator'/ 火星座標系(國測局):'gcj02'

"""self.pi = 3.1415926535897932384626 # π 精度比math.pi 還高一些

self.ee = 0.00669342162296594323 # 偏心率平方

self.a = 6378245.0 # 長半軸

func_name = old_gis_name + '_to_' + new_gis_name

if hasattr(self, func_name):

self.transform_func = getattr(self, func_name)

def _out_of_china(self, lng, lat):

"""判斷是否在國內,不在國內不做偏移

:param lng:

:param lat:

:return:

"""return not (lng > 73.66 and lng < 135.05 and lat > 3.86 and lat < 53.55)

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 * self.pi) + 20.0 *

math.sin(2.0 * lng * self.pi)) * 2.0 / 3.0

ret += (20.0 * math.sin(lat * self.pi) + 40.0 *

math.sin(lat / 3.0 * self.pi)) * 2.0 / 3.0

ret += (160.0 * math.sin(lat / 12.0 * self.pi) + 320 *

math.sin(lat * self.pi / 30.0)) * 2.0 / 3.0

return ret

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 * self.pi) + 20.0 *

math.sin(2.0 * lng * self.pi)) * 2.0 / 3.0

ret += (20.0 * math.sin(lng * self.pi) + 40.0 *

math.sin(lng / 3.0 * self.pi)) * 2.0 / 3.0

ret += (150.0 * math.sin(lng / 12.0 * self.pi) + 300.0 *

math.sin(lng / 30.0 * self.pi)) * 2.0 / 3.0

return ret

def wgs84_to_webmercator(self, lon, lat):

"""wgs84座標 轉 墨卡托座標"""

x = lon * 20037508.342789 / 180

y = math.log(math.tan((90 + lat) * self.pi / 360)) / (self.pi / 180)

y = y * 20037508.34789 / 180

return x, y

def gcj02_to_webmercator(self, x, y):

"""火星轉墨卡托"""

wgs84_x, wgs84_y = self.gcj02_to_wgs84(x, y)

webmercator_x, webmercator_y = self.wgs84_to_webmercator(wgs84_x, wgs84_y)

return webmercator_x, webmercator_y

def webmercator_to_webmercator(self, x, y):

return x, y

def webmercator_to_wgs84(self, x, y):

"""墨卡托座標 轉 wgs84座標"""

lon = x / 20037508.34 * 180

lat = y / 20037508.34 * 180

lat = 180 / self.pi * (2 * math.atan(math.exp(lat * self.pi / 180)) - self.pi / 2)

return lon, lat

def gcj02_to_wgs84(self, lng, lat):

"""gcj02(火星座標系)轉gps84

:param lng:火星座標系的經度

:param lat:火星座標系緯度

:return:

"""if self._out_of_china(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 * self.pi

magic = math.sin(radlat)

magic = 1 - self.ee * magic * magic

sqrtmagic = math.sqrt(magic)

dlat = (dlat * 180.0) / ((self.a * (1 - self.ee)) / (magic * sqrtmagic) * self.pi)

dlng = (dlng * 180.0) / (self.a / sqrtmagic * math.cos(radlat) * self.pi)

mglat = lat + dlat

mglng = lng + dlng

new_x = lng * 2 - mglng

new_y = lat * 2 - mglat

return new_x, new_y

def wgs84_to_gcj02(self, lng, lat):

"""wgs84轉gcj02(火星座標系)

:param lng:wgs84座標系的經度

:param lat:wgs84座標系的緯度

:return:

"""if self._out_of_china(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 * self.pi

magic = math.sin(radlat)

magic = 1 - self.ee * magic * magic

sqrtmagic = math.sqrt(magic)

dlat = (dlat * 180.0) / ((self.a * (1 - self.ee)) / (magic * sqrtmagic) * self.pi)

dlng = (dlng * 180.0) / (self.a / sqrtmagic * math.cos(radlat) * self.pi)

mglat = lat + dlat

mglng = lng + dlng

return mglng, mglat

def webmercator_to_gcj02(self, x, y):

"""墨卡托轉火星"""

wgs84_x, wgs84_y = self.webmercator_to_wgs84(x, y)

gcj02_x, gcj02_y = self.wgs84_to_gcj02(wgs84_x, wgs84_y)

return gcj02_x, gcj02_y

if __name__ == '__main__':

gis = gistransform('wgs84', 'webmercator') # 經緯度: wgs84 墨卡托: webmercator 國測局: gcj02

print(gis.transform_func(114.09538, 22.62663))

ThinkPHP實現經緯度範圍查詢

thinkphp實現附近範圍的查詢,如附近的人和附近 之類。首先,要定位使用者的經緯度。客戶端定位的方法可以使用地圖api或者用html5瀏覽器定位 比較不穩定而且不會太精確 然後,將當前經緯度,和需要搜尋的距離範圍,計算乙個經緯度範圍,這個範圍就是 附近 計算這個 附近 的示例如下 param l...

用python 來實現經緯度的測算與輸出

本文採用高德地圖地理標識規範 首先匯入兩個分析包,math和pandas,如果有需要還有numpy,mathplotlib等常用資料分析包 import pandas as pd import math測算一經度和一緯度的距離 地球半徑 r 12713.504 2 1緯度長 wd 2 math.pi...

python經緯度轉化

import requests defgeocode location 引數內容 可以寫成字典的格式 parameters 問號以前的內容 base response requests.get base,parameters print http 請求的狀態 s response.status co...