ctdo-trac/TracRendezVous/tracrendezvous/location/utils.py

79 lines
2.9 KiB
Python

# -*- coding: utf-8 -*-
from re import compile as re_compile
from re import match
from decimal import Decimal, Context, getcontext
from datetime import date, time, datetime, timedelta
from os.path import join, dirname
from os.path import exists as path_exists
from os import mkdir
from sys import maxint
from trac.util import Ranges
from trac.wiki import WikiPage, WikiSystem
from trac.util.datefmt import utc, to_timestamp, localtz, format_time, get_timezone, timezone
from PIL import Image, ImageDraw, ImageFont
__all__ = ["validate_dd_coordinates", "validate_dms_coordinates", "convert_dms_2_dd", "convert_dd_2_dms"]
class ValidationError(ValueError):
def __str__(self):
return "ValidationError: value out of bounds!"
def validate_dms_coordinates(value):
mytest=re_compile(u"(N|S)(\d{1,2})°(\d{1,2})'(\d{1,2}\.\d{1,5})\" (E|W)(\d{1,3})°(\d{1,2})'(\d{1,2}\.\d{1,5})\"$")
m = mytest.match(value)
if not m:
raise ValueError(u"validate_rendezvous(): coordinates have wrong format:")
groups = m.groups()
if 0 > groups[1] > 90.0:
raise ValueError(u"validate_rendezvous(): lat not valid:")
if 0 > groups[5] > 180.0:
raise ValueError(u"validate_rendezvous(): lon not valid:")
return groups
def validate_dd_coordinates(value):
mytest=re_compile(u"(-?\d{1,3}\.\d{1,8}),(-?\d{1,3}\.\d{1,8})$")
m = mytest.match(value)
if not m:
raise ValueError(u"validate_rendezvous(): coordinates have wrong format:")
lat, lon = m.groups()
if 0 > lat > 90.0:
raise ValueError(u"validate_rendezvous(): lat not valid:")
if 0 > lon > 180.0:
raise ValueError(u"validate_rendezvous(): lon not valid:")
return lat, lon
def convert_dms_2_dd(ns,a,b,c,ew,d,e,f):
getcontext().prec = 20
r1 = Decimal(a) + Decimal(b) / 60 + Decimal(str(c))/3600
r2 = Decimal(d) + Decimal(e) / 60 + Decimal(str(f))/3600
if ns == u"S":
r1=-r1
if ew == u"W":
r2=-r2
a = round(r1,6)
b = round(r2,6)
return a, b
def convert_dd_2_dms(lat, lon):
def convert(value, pos, neg):
getcontext().prec = 32
dValue = Decimal(value)
tValue = dValue.as_tuple()
valueDir = tValue[0] and neg or pos
# extracting full degrees, keep in mind we want an int
degValue = Decimal((0, tValue[1][:tValue[2]], 0))
# extracting minutes as int
tMinValueRemainder = (Decimal((0, tValue[1][tValue[2]:], tValue[2])) * 60).as_tuple()
minValue = Decimal((0, tMinValueRemainder[1][:tMinValueRemainder[2]], 0))
# extracting sec, we want the remaining seconds as float
secValueRemainder = Decimal((0, tMinValueRemainder[1][tMinValueRemainder[2]:], tMinValueRemainder[2]))
secValueRemainder = secValueRemainder * 60
return valueDir, int(degValue), int(minValue), float(secValueRemainder)
return convert(lat, "N", "S") + convert(lon, "E", "W")