5 Basic usage is checking whether a point is inside an area.
6 Supports GoogleEarth KML polylines.
7 FIXME: It should works using polar coordinated, but now works in 2D.
10 __all__ = [ 'Area', 'load_area_from_kml_polygon' ]
14 That class defines an area (on the Earth)
15 It provides testing whether a point is inside or not
17 def __init__(self, points=()):
22 def addpoint(self, point):
26 self.points.append(point)
27 # min/max doesn't work around the change date line...
28 #if len(self.points)==1:
32 #if point[0] < self.min[0]:
33 # self.min = (point[0], self.min[1])
34 #elif point[0] > self.max[0]:
35 # self.max = (point[0], self.max[1])
36 #if point[1] < self.min[1]:
37 # self.min = (self.min[0], point[1])
38 #elif point[1] > self.max[1]:
39 # self.max = (self.max[0], point[1])
43 Area library self-test:
44 We only support counter-clockwise and convex areas.
46 for point in self.points:
47 if not self.contains(point):
51 def contains(self, point):
53 Tests whether a point is in self.
57 # first test the bounding box
58 #if point[0] < self.min[0] \
59 # or point[0] > self.max[0] \
60 # or point[1] < self.min[1] \
61 # or point[1] > self.max[1] :
63 for i in range(len(self.points)):
66 p2 = self.points[(i+1)%len(self.points)]
76 def load_area_from_kml_polygon(filename):
78 Loads a kml file into an Area structure.
79 The kml must contains exacly 1 polyline structure.
80 The first and last points must be the same.
81 It must also be counter-clockwise and convex.
83 FIXME: This makes a lot of assumption about the way GoogleEarth output the
86 kmlfile = open(filename)
87 coordinates_lines = [ line for line in kmlfile.readlines() if '</coordinates>' in line ]
88 assert len(coordinates_lines) == 1, \
89 'There should be exactly one line with coordinates in %s' % filename
90 coordinates = coordinates_lines[0].replace('</coordinates>', '').replace('\n', '').replace('\r', '')
91 coordinates = [ xyz for xyz in coordinates.split(' ') if xyz ]
92 assert coordinates[0] == coordinates[-1], \
93 'First and last coordinates of %s should be the same: %s, %s' % \
94 (filename, coordinates[0], coordinates[-1])
95 assert len(coordinates)>3, 'polygon should have 3 edges minimum'
98 for xyz in coordinates[0:-1]:
99 x, y, z = xyz.split(',')
100 area.addpoint((float(y), float(x)))
101 assert area.check(), 'Polygon should be counter-clockwise and convex.'
105 #if __name__ == '__main__':
106 # counter clock-wise : Positive
109 # (45.3612930132714, 10.01843703552244),
121 # if pelagos.contains(p):