# -*- 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")