MoinSupport

LocationSupport.py

17:4e984fd40300
2012-07-17 Paul Boddie Prevent getHeader from raising an exception when a header is absent, returning None instead.
     1 # -*- coding: iso-8859-1 -*-     2 """     3     MoinMoin - LocationSupport library (derived from EventAggregatorSupport)     4      5     @copyright: 2011, 2012 by Paul Boddie <paul@boddie.org.uk>     6     @license: GNU GPL (v2 or later), see COPYING.txt for details.     7 """     8      9 import operator    10 import re    11     12 __version__ = "0.1"    13     14 location_normalised_regexp = re.compile(    15     ur"(?:\d+\w*\s+)?"          # preceding postcode (optional)    16     ur"(?P<location>"           # start of group of interest    17     ur"\w[\w\s-]+?"             # area or town    18     ur"(?:,(?:\s*[\w-]+)+)?"    # country (optional)    19     ur")$", re.UNICODE)    20     21 # Utility functions.    22     23 def sign(x):    24     if x < 0:    25         return -1    26     else:    27         return 1    28     29 # Location-related functions.    30     31 class Reference:    32     33     "A map reference."    34     35     def __init__(self, degrees, minutes=0, seconds=0):    36         self.degrees = degrees    37         self.minutes = minutes    38         self.seconds = seconds    39     40     def __repr__(self):    41         return "Reference(%d, %d, %f)" % (self.degrees, self.minutes, self.seconds)    42     43     def __str__(self):    44         return "%d:%d:%f" % (self.degrees, self.minutes, self.seconds)    45     46     def __add__(self, other):    47         if not isinstance(other, Reference):    48             return NotImplemented    49         else:    50             s = sign(self.degrees)    51             o = sign(other.degrees)    52             carry, seconds = adc(s * self.seconds, o * other.seconds)    53             carry, minutes = adc(s * self.minutes, o * other.minutes + carry)    54             return Reference(self.degrees + other.degrees + carry, minutes, seconds)    55     56     def __sub__(self, other):    57         if not isinstance(other, Reference):    58             return NotImplemented    59         else:    60             return self.__add__(Reference(-other.degrees, other.minutes, other.seconds))    61     62     def _compare(self, op, other):    63         if not isinstance(other, Reference):    64             return NotImplemented    65         else:    66             return op(self.to_degrees(), other.to_degrees())    67     68     def __eq__(self, other):    69         return self._compare(operator.eq, other)    70     71     def __ne__(self, other):    72         return self._compare(operator.ne, other)    73     74     def __lt__(self, other):    75         return self._compare(operator.lt, other)    76     77     def __le__(self, other):    78         return self._compare(operator.le, other)    79     80     def __gt__(self, other):    81         return self._compare(operator.gt, other)    82     83     def __ge__(self, other):    84         return self._compare(operator.ge, other)    85     86     def to_degrees(self):    87         return sign(self.degrees) * (abs(self.degrees) + self.minutes / 60.0 + self.seconds / 3600.0)    88     89     def to_pixels(self, scale):    90         return self.to_degrees() * scale    91     92 def adc(x, y):    93     result = x + y    94     return divmod(result, 60)    95     96 def getPositionForReference(latitude, longitude, map_y, map_x, map_x_scale, map_y_scale):    97     return (longitude - map_x).to_pixels(map_x_scale), (latitude - map_y).to_pixels(map_y_scale)    98     99 def getPositionForCentrePoint(position, map_x_scale, map_y_scale):   100     x, y = position   101     return x - map_x_scale / 2.0, y - map_y_scale / 2.0   102    103 def getMapReference(value):   104    105     "Return a map reference by parsing the given 'value'."   106    107     if value.find(":") != -1:   108         return getMapReferenceFromDMS(value)   109     else:   110         return getMapReferenceFromDecimal(value)   111    112 def getMapReferenceFromDMS(value):   113    114     """   115     Return a map reference by parsing the given 'value' expressed as degrees,   116     minutes, seconds.   117     """   118    119     values = value.split(":")   120     values = map(int, values[:2]) + map(float, values[2:3])   121     return Reference(*values)   122    123 def getMapReferenceFromDecimal(value):   124    125     "Return a map reference by parsing the given 'value' in decimal degrees."   126    127     value = float(value)   128     degrees, remainder = divmod(abs(value * 3600), 3600)   129     minutes, seconds = divmod(remainder, 60)    130     return Reference(sign(value) * degrees, minutes, seconds)   131    132 # User interface functions.   133    134 def getNormalisedLocation(location):   135    136     """   137     Attempt to return a normalised 'location' of the form "<town>, <country>" or   138     "<town>".   139     """   140    141     match = location_normalised_regexp.search(location)   142     if match:   143         return match.group("location")   144     else:   145         return None   146    147 # vim: tabstop=4 expandtab shiftwidth=4