/gdata/geo/__init__.py

http://radioappz.googlecode.com/ · Python · 185 lines · 126 code · 12 blank · 47 comment · 9 complexity · 1ccfa610b495300bbf978376fdcb2f23 MD5 · raw file

  1. # -*-*- encoding: utf-8 -*-*-
  2. #
  3. # This is gdata.photos.geo, implementing geological positioning in gdata structures
  4. #
  5. # $Id: __init__.py 81 2007-10-03 14:41:42Z havard.gulldahl $
  6. #
  7. # Copyright 2007 H?vard Gulldahl
  8. # Portions copyright 2007 Google Inc.
  9. #
  10. # Licensed under the Apache License, Version 2.0 (the "License");
  11. # you may not use this file except in compliance with the License.
  12. # You may obtain a copy of the License at
  13. #
  14. # http://www.apache.org/licenses/LICENSE-2.0
  15. #
  16. # Unless required by applicable law or agreed to in writing, software
  17. # distributed under the License is distributed on an "AS IS" BASIS,
  18. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. # See the License for the specific language governing permissions and
  20. # limitations under the License.
  21. """Picasa Web Albums uses the georss and gml namespaces for
  22. elements defined in the GeoRSS and Geography Markup Language specifications.
  23. Specifically, Picasa Web Albums uses the following elements:
  24. georss:where
  25. gml:Point
  26. gml:pos
  27. http://code.google.com/apis/picasaweb/reference.html#georss_reference
  28. Picasa Web Albums also accepts geographic-location data in two other formats:
  29. W3C format and plain-GeoRSS (without GML) format.
  30. """
  31. #
  32. #Over the wire, the Picasa Web Albums only accepts and sends the
  33. #elements mentioned above, but this module will let you seamlessly convert
  34. #between the different formats (TODO 2007-10-18 hg)
  35. __author__ = u'havard@gulldahl.no'# (H?vard Gulldahl)' #BUG: api chokes on non-ascii chars in __author__
  36. __license__ = 'Apache License v2'
  37. import atom
  38. import gdata
  39. GEO_NAMESPACE = 'http://www.w3.org/2003/01/geo/wgs84_pos#'
  40. GML_NAMESPACE = 'http://www.opengis.net/gml'
  41. GEORSS_NAMESPACE = 'http://www.georss.org/georss'
  42. class GeoBaseElement(atom.AtomBase):
  43. """Base class for elements.
  44. To add new elements, you only need to add the element tag name to self._tag
  45. and the namespace to self._namespace
  46. """
  47. _tag = ''
  48. _namespace = GML_NAMESPACE
  49. _children = atom.AtomBase._children.copy()
  50. _attributes = atom.AtomBase._attributes.copy()
  51. def __init__(self, name=None, extension_elements=None,
  52. extension_attributes=None, text=None):
  53. self.name = name
  54. self.text = text
  55. self.extension_elements = extension_elements or []
  56. self.extension_attributes = extension_attributes or {}
  57. class Pos(GeoBaseElement):
  58. """(string) Specifies a latitude and longitude, separated by a space,
  59. e.g. `35.669998 139.770004'"""
  60. _tag = 'pos'
  61. def PosFromString(xml_string):
  62. return atom.CreateClassFromXMLString(Pos, xml_string)
  63. class Point(GeoBaseElement):
  64. """(container) Specifies a particular geographical point, by means of
  65. a <gml:pos> element."""
  66. _tag = 'Point'
  67. _children = atom.AtomBase._children.copy()
  68. _children['{%s}pos' % GML_NAMESPACE] = ('pos', Pos)
  69. def __init__(self, pos=None, extension_elements=None, extension_attributes=None, text=None):
  70. GeoBaseElement.__init__(self, extension_elements=extension_elements,
  71. extension_attributes=extension_attributes,
  72. text=text)
  73. if pos is None:
  74. pos = Pos()
  75. self.pos=pos
  76. def PointFromString(xml_string):
  77. return atom.CreateClassFromXMLString(Point, xml_string)
  78. class Where(GeoBaseElement):
  79. """(container) Specifies a geographical location or region.
  80. A container element, containing a single <gml:Point> element.
  81. (Not to be confused with <gd:where>.)
  82. Note that the (only) child attribute, .Point, is title-cased.
  83. This reflects the names of elements in the xml stream
  84. (principle of least surprise).
  85. As a convenience, you can get a tuple of (lat, lon) with Where.location(),
  86. and set the same data with Where.setLocation( (lat, lon) ).
  87. Similarly, there are methods to set and get only latitude and longitude.
  88. """
  89. _tag = 'where'
  90. _namespace = GEORSS_NAMESPACE
  91. _children = atom.AtomBase._children.copy()
  92. _children['{%s}Point' % GML_NAMESPACE] = ('Point', Point)
  93. def __init__(self, point=None, extension_elements=None, extension_attributes=None, text=None):
  94. GeoBaseElement.__init__(self, extension_elements=extension_elements,
  95. extension_attributes=extension_attributes,
  96. text=text)
  97. if point is None:
  98. point = Point()
  99. self.Point=point
  100. def location(self):
  101. "(float, float) Return Where.Point.pos.text as a (lat,lon) tuple"
  102. try:
  103. return tuple([float(z) for z in self.Point.pos.text.split(' ')])
  104. except AttributeError:
  105. return tuple()
  106. def set_location(self, latlon):
  107. """(bool) Set Where.Point.pos.text from a (lat,lon) tuple.
  108. Arguments:
  109. lat (float): The latitude in degrees, from -90.0 to 90.0
  110. lon (float): The longitude in degrees, from -180.0 to 180.0
  111. Returns True on success.
  112. """
  113. assert(isinstance(latlon[0], float))
  114. assert(isinstance(latlon[1], float))
  115. try:
  116. self.Point.pos.text = "%s %s" % (latlon[0], latlon[1])
  117. return True
  118. except AttributeError:
  119. return False
  120. def latitude(self):
  121. "(float) Get the latitude value of the geo-tag. See also .location()"
  122. lat, lon = self.location()
  123. return lat
  124. def longitude(self):
  125. "(float) Get the longtitude value of the geo-tag. See also .location()"
  126. lat, lon = self.location()
  127. return lon
  128. longtitude = longitude
  129. def set_latitude(self, lat):
  130. """(bool) Set the latitude value of the geo-tag.
  131. Args:
  132. lat (float): The new latitude value
  133. See also .set_location()
  134. """
  135. _lat, lon = self.location()
  136. return self.set_location(lat, lon)
  137. def set_longitude(self, lon):
  138. """(bool) Set the longtitude value of the geo-tag.
  139. Args:
  140. lat (float): The new latitude value
  141. See also .set_location()
  142. """
  143. lat, _lon = self.location()
  144. return self.set_location(lat, lon)
  145. set_longtitude = set_longitude
  146. def WhereFromString(xml_string):
  147. return atom.CreateClassFromXMLString(Where, xml_string)