Геодезические системы пространственных координат: различия между версиями
Перейти к навигации
Перейти к поиску
ErnieBoyd (обсуждение | вклад) м (→Ссылки) |
ErnieBoyd (обсуждение | вклад) мНет описания правки |
||
Строка 3: | Строка 3: | ||
{{Аннотация|Рассматривается известный способ вычисления площади сферического полигона по сферическому избытку. Предлагается расширение этого подхода на поверхность эллипсоида. Приводится пример программной реализации на языке Питон.}} | {{Аннотация|Рассматривается известный способ вычисления площади сферического полигона по сферическому избытку. Предлагается расширение этого подхода на поверхность эллипсоида. Приводится пример программной реализации на языке Питон.}} | ||
== Программы == | |||
<syntaxhighlight lang="python"> | |||
import math | |||
def rotate(x, y, a): | |||
c, s = math.cos(a), math.sin(a) | |||
return (x * c + y * s, -x * s + y * c) | |||
def initSpher(a, f): | |||
b = a * (1. - f) | |||
c = a / (1. - f) | |||
e2 = f * (2. - f) | |||
e12 = e2 / (1. - e2) | |||
return (b, c, e2, e12) | |||
def fromLatLong(lat, lon, h, a, f): | |||
b, c, e2, e12 = initSpher(a, f) | |||
cos_lat = math.cos(lat) | |||
n = c / math.sqrt(1. + e12 * cos_lat ** 2) | |||
p = (n + h) * cos_lat | |||
x = p * math.cos(lon) | |||
y = p * math.sin(lon) | |||
z = (n + h - e2 * n) * math.sin(lat) | |||
return (x, y, z) | |||
def toLatLong(x, y, z, a, f): | |||
b, c, e2, e12 = initSpher(a, f) | |||
p = math.hypot(x, y) | |||
if p == 0.: | |||
lat = math.copysign(math.pi / 2., z) | |||
lon = 0. | |||
h = math.fabs(z) - b | |||
else: | |||
t = z / p * (1. + e12 * b / math.hypot(p, z)) | |||
for i in range(2): | |||
t = t * (1. - f) | |||
lat = math.atan(t) | |||
cos_lat = math.cos(lat) | |||
sin_lat = math.sin(lat) | |||
t = (z + e12 * b * sin_lat ** 3) / (p - e2 * a * cos_lat ** 3) | |||
lon = math.atan2(y, x) | |||
lat = math.atan(t) | |||
cos_lat = math.cos(lat) | |||
n = c / math.sqrt(1. + e12 * cos_lat ** 2) | |||
if math.fabs(t) <= 1.: | |||
h = p / cos_lat - n | |||
else: | |||
h = z / math.sin(lat) - n * (1. - e2) | |||
return (lat, lon, h) | |||
def forward3d(lat1, lon1, h1, x, y, z, a, f): | |||
b, c, e2, e12 = initSpher(a, f) | |||
sin_lat = math.sin(lat1) | |||
n = a / math.sqrt(1. - e2 * sin_lat ** 2) | |||
x = -x | |||
z = z + (n + h1) | |||
z, x = rotate(z, x, lat1 - math.pi / 2.) | |||
x, y = rotate(x, y, -lon1) | |||
z = z - e2 * n * sin_lat | |||
return toLatLong(x, y, z, a, f) | |||
def inverse3d(lat1, lon1, h1, lat2, lon2, h2, a, f): | |||
b, c, e2, e12 = initSpher(a, f) | |||
sin_lat = math.sin(lat1) | |||
n = a / math.sqrt(1. - e2 * sin_lat ** 2) | |||
x, y, z = fromLatLong(lat2, lon2, h2, a, f) | |||
z = z + e2 * n * sin_lat | |||
x, y = rotate(x, y, lon1) | |||
z, x = rotate(z, x, math.pi / 2. - lat1) | |||
z = z - (n + h1) | |||
x = -x | |||
return (x, y, z) | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="python"> | |||
# -*- coding: utf-8 -*- | |||
from sys import argv | |||
import math | |||
import latlong | |||
script, fn = argv | |||
a, f = 6378136., 1./298.25784 # ПЗ-90 | |||
lat0, lon0, hgt0 = math.radians(65.), math.radians(45.), 500. | |||
fp = open(fn, 'r') | |||
for line in fp: | |||
x, y, z = map(float, line.split(" ")) | |||
lat, lon, hgt = latlong.forward3d(lat0, lon0, hgt0, x, y, z, a, f) | |||
print "%.8f %.8f %.3f" % (math.degrees(lat), math.degrees(lon), hgt) | |||
fp.close() | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="python"> | |||
# -*- coding: utf-8 -*- | |||
from sys import argv | |||
import math | |||
import latlong | |||
script, fn = argv | |||
a, f = 6378136., 1./298.25784 # ПЗ-90 | |||
lat0, lon0, hgt0 = math.radians(65.), math.radians(45.), 500. | |||
fp = open(fn, 'r') | |||
for line in fp: | |||
lat, lon, hgt = map(float, line.split(" ")) | |||
lat = math.radians(lat) | |||
lon = math.radians(lon) | |||
x, y, z = latlong.inverse3d(lat0, lon0, hgt0, lat, lon, hgt, a, f) | |||
print "%.3f %.3f %.3f" % (x, y, z) | |||
fp.close() | |||
</syntaxhighlight> | |||
== Расчёты == | == Расчёты == |
Версия от 17:44, 23 марта 2014
Эта страница является черновиком статьи.
Рассматривается известный способ вычисления площади сферического полигона по сферическому избытку. Предлагается расширение этого подхода на поверхность эллипсоида. Приводится пример программной реализации на языке Питон.
Программы
import math
def rotate(x, y, a):
c, s = math.cos(a), math.sin(a)
return (x * c + y * s, -x * s + y * c)
def initSpher(a, f):
b = a * (1. - f)
c = a / (1. - f)
e2 = f * (2. - f)
e12 = e2 / (1. - e2)
return (b, c, e2, e12)
def fromLatLong(lat, lon, h, a, f):
b, c, e2, e12 = initSpher(a, f)
cos_lat = math.cos(lat)
n = c / math.sqrt(1. + e12 * cos_lat ** 2)
p = (n + h) * cos_lat
x = p * math.cos(lon)
y = p * math.sin(lon)
z = (n + h - e2 * n) * math.sin(lat)
return (x, y, z)
def toLatLong(x, y, z, a, f):
b, c, e2, e12 = initSpher(a, f)
p = math.hypot(x, y)
if p == 0.:
lat = math.copysign(math.pi / 2., z)
lon = 0.
h = math.fabs(z) - b
else:
t = z / p * (1. + e12 * b / math.hypot(p, z))
for i in range(2):
t = t * (1. - f)
lat = math.atan(t)
cos_lat = math.cos(lat)
sin_lat = math.sin(lat)
t = (z + e12 * b * sin_lat ** 3) / (p - e2 * a * cos_lat ** 3)
lon = math.atan2(y, x)
lat = math.atan(t)
cos_lat = math.cos(lat)
n = c / math.sqrt(1. + e12 * cos_lat ** 2)
if math.fabs(t) <= 1.:
h = p / cos_lat - n
else:
h = z / math.sin(lat) - n * (1. - e2)
return (lat, lon, h)
def forward3d(lat1, lon1, h1, x, y, z, a, f):
b, c, e2, e12 = initSpher(a, f)
sin_lat = math.sin(lat1)
n = a / math.sqrt(1. - e2 * sin_lat ** 2)
x = -x
z = z + (n + h1)
z, x = rotate(z, x, lat1 - math.pi / 2.)
x, y = rotate(x, y, -lon1)
z = z - e2 * n * sin_lat
return toLatLong(x, y, z, a, f)
def inverse3d(lat1, lon1, h1, lat2, lon2, h2, a, f):
b, c, e2, e12 = initSpher(a, f)
sin_lat = math.sin(lat1)
n = a / math.sqrt(1. - e2 * sin_lat ** 2)
x, y, z = fromLatLong(lat2, lon2, h2, a, f)
z = z + e2 * n * sin_lat
x, y = rotate(x, y, lon1)
z, x = rotate(z, x, math.pi / 2. - lat1)
z = z - (n + h1)
x = -x
return (x, y, z)
# -*- coding: utf-8 -*-
from sys import argv
import math
import latlong
script, fn = argv
a, f = 6378136., 1./298.25784 # ПЗ-90
lat0, lon0, hgt0 = math.radians(65.), math.radians(45.), 500.
fp = open(fn, 'r')
for line in fp:
x, y, z = map(float, line.split(" "))
lat, lon, hgt = latlong.forward3d(lat0, lon0, hgt0, x, y, z, a, f)
print "%.8f %.8f %.3f" % (math.degrees(lat), math.degrees(lon), hgt)
fp.close()
# -*- coding: utf-8 -*-
from sys import argv
import math
import latlong
script, fn = argv
a, f = 6378136., 1./298.25784 # ПЗ-90
lat0, lon0, hgt0 = math.radians(65.), math.radians(45.), 500.
fp = open(fn, 'r')
for line in fp:
lat, lon, hgt = map(float, line.split(" "))
lat = math.radians(lat)
lon = math.radians(lon)
x, y, z = latlong.inverse3d(lat0, lon0, hgt0, lat, lon, hgt, a, f)
print "%.3f %.3f %.3f" % (x, y, z)
fp.close()
Расчёты
-40000 30000 0
64.63992455 45.62743333 695.578
-40000.000 30000.000 0.000