"""
Library for areas.
Basic usage is checking whether a point is inside an area.
-Supports GoogleEarth KML polylines.
+Supports GoogleEarth KML coordinates.
FIXME: It should works using polar coordinated, but now works in 2D.
"""
__all__ = [ 'Area', 'load_area_from_kml_polygon' ]
+import re
+
class Area:
"""
That class defines an area (on the Earth)
def load_area_from_kml_polygon(filename, reverse=False):
"""
Loads a kml file into an Area structure.
- The kml must contains exacly 1 polyline structure.
+ The kml must contains exacly one set of <coordinates>.
The first and last points must be the same.
It must also be counter-clockwise and convex.
Actually, it may be clockwise, but then you need reverse=True.
-
- FIXME: This makes a lot of assumption about the way GoogleEarth output the
- XML file.
"""
- kmlfile = open(filename)
- coordinates_lines = [ line for line in kmlfile.readlines() if '</coordinates>' in line ]
+ kml = open(filename).read()
+ coordinates_lines = re.findall('<coordinates>(.*)</coordinates>', kml, re.IGNORECASE|re.DOTALL)
assert len(coordinates_lines) == 1, \
- 'There should be exactly one line with coordinates in %s' % filename
- coordinates = coordinates_lines[0].replace('</coordinates>', '').replace('\n', '').replace('\r', '').replace('\t', '')
+ 'There should be exactly one set of <coordinates> %s' % filename
+ coordinates = coordinates_lines[0].replace('\n', ' ').replace('\r', ' ').replace('\t', ' ')
coordinates = [ xyz for xyz in coordinates.split(' ') if xyz ]
assert coordinates[0] == coordinates[-1], \
'First and last coordinates of %s should be the same: %s, %s' % \
assert len(coordinates)>3, 'polygon should have 3 edges minimum'
area = Area()
- for xyz in coordinates[0:-1]:
+ for xyz in coordinates[:-1]:
x, y, z = xyz.split(',')
area.addpoint((float(y), float(x)))
if reverse:
assert area.check(), 'Polygon should be counter-clockwise and convex.'
return area
-
-#if __name__ == '__main__':
-# counter clock-wise : Positive
-#pelagos = Area([
-# (42.91, 12.5),
-# (45.3612930132714, 10.01843703552244),
-# (43.6,5.5),
-# (40.57,8.6)
-# ])
-#for p in [
-# (42,9),
-# (41,5),
-# (40,12),
-# (45,13),
-# (45,7),
-# ]:
-# print "testing", p
-# if pelagos.contains(p):
-# print "inside"
-# else:
-# print"outside"
-
+if __name__ == '__main__':
+ # counter clock-wise : Positive
+ pelagos = load_area_from_kml_polygon_2('/var/lib/ais/areas/pelagos.kml')
+ #pelagos = Area([
+ # (42.91, 12.5),
+ # (45.3612930132714, 10.01843703552244),
+ # (43.6,5.5),
+ # (40.57,8.6)
+ # ])
+ for p in [
+ (42,9),
+ (41,5),
+ (40,12),
+ (45,13),
+ (45,7),
+ ]:
+ print "testing", p
+ if pelagos.contains(p):
+ print "inside"
+ else:
+ print"outside"