Move fgtools module into it's own subfolder, add scripts to fix ICAO's of apt.dat files (mainly for those pulled from the XPlane gateway) and to generate apt.dat files from OurAirports and OSM data
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
#-*- coding:utf-8 -*-
|
||||
|
||||
EARTH_RADIUS = 6378138.12
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
#-*- coding:utf-8 -*-
|
||||
|
||||
import math
|
||||
|
||||
from fgtools.utils import unit_convert, wrap_period
|
||||
from fgtools.geo import EARTH_RADIUS
|
||||
|
||||
class Coord:
|
||||
def __init__(self, lon, lat):
|
||||
self.lon = lon
|
||||
self.lat = lat
|
||||
|
||||
def distance_m(self, other):
|
||||
lon1, lat1, lon2, lat2 = map(math.radians, (self.lon, self.lat, other.lon, other.lat))
|
||||
return abs(EARTH_RADIUS * math.acos(round(math.sin(lat1) * math.sin(lat2) + math.cos(lat1) * math.cos(lat2) * math.cos(lon1 - lon2), 14)))
|
||||
|
||||
def distance_km(self, other):
|
||||
return self.distance_m(other) / 1000
|
||||
|
||||
def distance_ft(self, other):
|
||||
return unit_convert.m2ft(self.distance_m(other))
|
||||
|
||||
def angle(self, other):
|
||||
dlon = (math.radians(other.lon) - math.radians(self.lon))
|
||||
x = math.sin(dlon) * math.cos(math.radians(other.lat))
|
||||
y = (math.cos(math.radians(self.lat)) * math.sin(math.radians(other.lat)) -
|
||||
math.sin(math.radians(self.lat)) * math.cos(math.radians(other.lat)) * math.cos(dlon))
|
||||
angle = math.degrees(math.fmod(math.atan2(x, y), 2 * math.pi))
|
||||
return wrap_period(angle, 0, 360)
|
||||
|
||||
def apply_angle_distance_m(self, angle, distance):
|
||||
lon = math.radians(self.lon)
|
||||
lat = math.radians(self.lat)
|
||||
heading = math.radians(angle)
|
||||
distance /= EARTH_RADIUS
|
||||
|
||||
if distance < 0:
|
||||
distance = abs(distance)
|
||||
heading -= math.pi
|
||||
|
||||
lat = math.asin(math.sin(lat) * math.cos(distance) + math.cos(lat) * math.sin(distance) * math.cos(heading))
|
||||
|
||||
if math.cos(lat) > 1e-15:
|
||||
lon = math.pi - math.fmod(math.pi - lon - math.asin(math.sin(heading) * math.sin(distance) / math.cos(lat)), (2 * math.pi))
|
||||
|
||||
lon = math.degrees(lon)
|
||||
lat = math.degrees(lat)
|
||||
if lon > 180:
|
||||
lon -= 360
|
||||
elif lon < -180:
|
||||
lon += 360
|
||||
|
||||
return Coord(lon, lat)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
#-*- coding:utf-8 -*-
|
||||
|
||||
from fgtools.geo import coord
|
||||
|
||||
class Rectangle:
|
||||
def __init__(self, ll, ur):
|
||||
if not (isinstance(ll, coord.Coord) and isinstance(ur, coord.Coord)):
|
||||
raise TypeError("loer left or upper right coordinate is not of type fgtools.geo.coord.Coord")
|
||||
self.ll = ll
|
||||
self.ur = ur
|
||||
|
||||
def midpoint(self):
|
||||
return coord.Coord((self.ll.lon + self.ur.lon) / 2, (self.ll.lat + self.ur.lat) / 2)
|
||||
|
||||
def is_inside(self, coord):
|
||||
return self.ll.lon <= coord.lon <= self.ur.lon and self.ll.lat <= coord.lat <= self.ur.lat
|
||||
|
||||
def diagonal_m(self):
|
||||
return self.ll.distance_m(self.ur)
|
||||
|
||||
def length_m(self):
|
||||
return self.ur.distance_m(Coord(self.ur.lon, self.ll.lat))
|
||||
|
||||
def width_m(self):
|
||||
return self.ll.distance_m(Coord(self.ur.lon, self.ll.lat))
|
||||
|
||||
Reference in New Issue
Block a user