1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: geos: added support for KML; added coords property to Point.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-08-06 01:13:49 +00:00
parent 5f4ffb369f
commit e982954602
6 changed files with 69 additions and 23 deletions

View File

@ -204,8 +204,9 @@ class GEOSGeometry(object):
def getquoted(self): def getquoted(self):
"Returns a properly quoted string for use in PostgresSQL/PostGIS." "Returns a properly quoted string for use in PostgresSQL/PostGIS."
# GeometryFromText() is ST_GeometryFromText() in PostGIS >= 1.2.2 # GeomFromText() is ST_GeomFromText() in PostGIS >= 1.2.2 to correspond
return "%sGeometryFromText('%s', %s)" % (GEOM_FUNC_PREFIX, self.wkt, self.srid or -1) # to SQL/MM ISO standard.
return "%sGeomFromText('%s', %s)" % (GEOM_FUNC_PREFIX, self.wkt, self.srid or -1)
#### Coordinate Sequence Routines #### #### Coordinate Sequence Routines ####
@property @property
@ -385,6 +386,12 @@ class GEOSGeometry(object):
h = lgeos.GEOSGeomToHEX_buf(self._ptr(), byref(sz)) h = lgeos.GEOSGeomToHEX_buf(self._ptr(), byref(sz))
return string_at(h, sz.value) return string_at(h, sz.value)
@property
def kml(self):
"Returns the KML representation of this Geometry."
gtype = self.geom_type
return '<%s>%s</%s>' % (gtype, self.coord_seq.kml, gtype)
#### Topology Routines #### #### Topology Routines ####
def _unary_topology(self, func, *args): def _unary_topology(self, func, *args):
"Returns a GEOSGeometry for the given unary (only takes one geomtry as a paramter) topological operation." "Returns a GEOSGeometry for the given unary (only takes one geomtry as a paramter) topological operation."

View File

@ -85,7 +85,7 @@ class GeometryCollection(GEOSGeometry):
# Creating a new geometry collection from the list, and # Creating a new geometry collection from the list, and
# re-assigning the pointers. # re-assigning the pointers.
new_collection = self.__class__(*new_geoms) new_collection = self.__class__(*new_geoms, **{'srid':self.srid})
self._reassign(new_collection) self._reassign(new_collection)
def __iter__(self): def __iter__(self):
@ -114,6 +114,13 @@ class GeometryCollection(GEOSGeometry):
for i in xrange(self.num_geom): for i in xrange(self.num_geom):
self._geoms[i] = GEOSPointer(lgeos.GEOSGetGeometryN(self._ptr(), c_int(i))) self._geoms[i] = GEOSPointer(lgeos.GEOSGetGeometryN(self._ptr(), c_int(i)))
@property
def kml(self):
"Returns the KML for this Geometry Collection."
kml = '<MultiGeometry>'
for g in self: kml += g.kml
return kml + '</MultiGeometry>'
# MultiPoint, MultiLineString, and MultiPolygon class definitions. # MultiPoint, MultiLineString, and MultiPolygon class definitions.
class MultiPoint(GeometryCollection): class MultiPoint(GeometryCollection):
_allowed = Point _allowed = Point

View File

@ -161,6 +161,18 @@ class GEOSCoordSeq(object):
"Clones this coordinate sequence." "Clones this coordinate sequence."
return GEOSCoordSeq(GEOSPointer(0, lgeos.GEOSCoordSeq_clone(self._ptr.coordseq())), self.hasz) return GEOSCoordSeq(GEOSPointer(0, lgeos.GEOSCoordSeq_clone(self._ptr.coordseq())), self.hasz)
@property
def kml(self):
"Returns the KML representation for the coordinates."
# Getting the substitution string depending on whether the coordinates have
# a Z dimension.
if self.hasz: substr = '%s,%s,%s '
else: substr = '%s,%s,0 '
kml = '<coordinates>'
for i in xrange(len(self)):
kml += substr % self[i]
return kml.strip() + '</coordinates>'
@property @property
def tuple(self): def tuple(self):
"Returns a tuple version of this coordinate sequence." "Returns a tuple version of this coordinate sequence."

View File

@ -109,16 +109,17 @@ class Point(GEOSGeometry):
z = property(get_z, set_z) z = property(get_z, set_z)
### Tuple setting and retrieval routines. ### ### Tuple setting and retrieval routines. ###
def get_tuple(self): def get_coords(self):
"Returns a tuple of the point." "Returns a tuple of the point."
return self._cs.tuple return self._cs.tuple
def set_tuple(self, tup): def set_coords(self, tup):
"Sets the coordinates of the point with the given tuple." "Sets the coordinates of the point with the given tuple."
self._cs[0] = tup self._cs[0] = tup
# The tuple property # The tuple and coords properties
tuple = property(get_tuple, set_tuple) tuple = property(get_coords, set_coords)
coords = property(get_coords, set_coords)
class LineString(GEOSGeometry): class LineString(GEOSGeometry):
@ -332,7 +333,7 @@ class Polygon(GEOSGeometry):
else: new_rings.append(self[i]) else: new_rings.append(self[i])
# Constructing the new Polygon with the ring parameters, and reassigning the internals. # Constructing the new Polygon with the ring parameters, and reassigning the internals.
new_poly = Polygon(*new_rings) new_poly = Polygon(*new_rings, **{'srid':self.srid})
self._reassign(new_poly) self._reassign(new_poly)
def __iter__(self): def __iter__(self):
@ -401,3 +402,11 @@ class Polygon(GEOSGeometry):
"Gets the tuple for each ring in this Polygon." "Gets the tuple for each ring in this Polygon."
return tuple(self.__getitem__(i).tuple for i in xrange(self.__len__())) return tuple(self.__getitem__(i).tuple for i in xrange(self.__len__()))
@property
def kml(self):
"Returns the KML representation of this Polygon."
inner_kml = ''
if self.num_interior_rings > 0:
for i in xrange(self.num_interior_rings):
inner_kml += "<innerBoundaryIs>%s</innerBoundaryIs>" % self[i+1].kml
return "<Polygon><outerBoundaryIs>%s</outerBoundaryIs>%s</Polygon>" % (self[0].kml, inner_kml)

View File

@ -34,13 +34,13 @@ hex_wkt = (TestGeom('POINT(0 1)', hex='01010000000000000000000000000000000000F03
) )
# WKT Output # WKT Output
wkt_out = (TestGeom('POINT(110 130)', ewkt='POINT (110.0000000000000000 130.0000000000000000)'), wkt_out = (TestGeom('POINT(110 130)', ewkt='POINT (110.0000000000000000 130.0000000000000000)', kml='<Point><coordinates>110.0,130.0,0</coordinates></Point>'),
TestGeom('LINESTRING(40 40, 50 130, 130 130)', ewkt='LINESTRING (40.0000000000000000 40.0000000000000000, 50.0000000000000000 130.0000000000000000, 130.0000000000000000 130.0000000000000000)'), TestGeom('LINESTRING(40 40, 50 130, 130 130)', ewkt='LINESTRING (40.0000000000000000 40.0000000000000000, 50.0000000000000000 130.0000000000000000, 130.0000000000000000 130.0000000000000000)', kml='<LineString><coordinates>40.0,40.0,0 50.0,130.0,0 130.0,130.0,0</coordinates></LineString>'),
TestGeom('POLYGON((150 150, 410 150, 280 20, 20 20, 150 150),(170 120, 330 120, 260 50, 100 50, 170 120))', ewkt='POLYGON ((150.0000000000000000 150.0000000000000000, 410.0000000000000000 150.0000000000000000, 280.0000000000000000 20.0000000000000000, 20.0000000000000000 20.0000000000000000, 150.0000000000000000 150.0000000000000000), (170.0000000000000000 120.0000000000000000, 330.0000000000000000 120.0000000000000000, 260.0000000000000000 50.0000000000000000, 100.0000000000000000 50.0000000000000000, 170.0000000000000000 120.0000000000000000))'), TestGeom('POLYGON((150 150, 410 150, 280 20, 20 20, 150 150),(170 120, 330 120, 260 50, 100 50, 170 120))', ewkt='POLYGON ((150.0000000000000000 150.0000000000000000, 410.0000000000000000 150.0000000000000000, 280.0000000000000000 20.0000000000000000, 20.0000000000000000 20.0000000000000000, 150.0000000000000000 150.0000000000000000), (170.0000000000000000 120.0000000000000000, 330.0000000000000000 120.0000000000000000, 260.0000000000000000 50.0000000000000000, 100.0000000000000000 50.0000000000000000, 170.0000000000000000 120.0000000000000000))', kml='<Polygon><outerBoundaryIs><LinearRing><coordinates>150.0,150.0,0 410.0,150.0,0 280.0,20.0,0 20.0,20.0,0 150.0,150.0,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>170.0,120.0,0 330.0,120.0,0 260.0,50.0,0 100.0,50.0,0 170.0,120.0,0</coordinates></LinearRing></innerBoundaryIs></Polygon>'),
TestGeom('MULTIPOINT(10 80, 110 170, 110 120)', ewkt='MULTIPOINT (10.0000000000000000 80.0000000000000000, 110.0000000000000000 170.0000000000000000, 110.0000000000000000 120.0000000000000000)'), TestGeom('MULTIPOINT(10 80, 110 170, 110 120)', ewkt='MULTIPOINT (10.0000000000000000 80.0000000000000000, 110.0000000000000000 170.0000000000000000, 110.0000000000000000 120.0000000000000000)', kml='<MultiGeometry><Point><coordinates>10.0,80.0,0</coordinates></Point><Point><coordinates>110.0,170.0,0</coordinates></Point><Point><coordinates>110.0,120.0,0</coordinates></Point></MultiGeometry>'),
TestGeom('MULTILINESTRING((110 100, 40 30, 180 30),(170 30, 110 90, 50 30))', ewkt='MULTILINESTRING ((110.0000000000000000 100.0000000000000000, 40.0000000000000000 30.0000000000000000, 180.0000000000000000 30.0000000000000000), (170.0000000000000000 30.0000000000000000, 110.0000000000000000 90.0000000000000000, 50.0000000000000000 30.0000000000000000))'), TestGeom('MULTILINESTRING((110 100, 40 30, 180 30),(170 30, 110 90, 50 30))', ewkt='MULTILINESTRING ((110.0000000000000000 100.0000000000000000, 40.0000000000000000 30.0000000000000000, 180.0000000000000000 30.0000000000000000), (170.0000000000000000 30.0000000000000000, 110.0000000000000000 90.0000000000000000, 50.0000000000000000 30.0000000000000000))', kml='<MultiGeometry><LineString><coordinates>110.0,100.0,0 40.0,30.0,0 180.0,30.0,0</coordinates></LineString><LineString><coordinates>170.0,30.0,0 110.0,90.0,0 50.0,30.0,0</coordinates></LineString></MultiGeometry>'),
TestGeom('MULTIPOLYGON(((110 110, 70 200, 150 200, 110 110),(110 110, 100 180, 120 180, 110 110)),((110 110, 150 20, 70 20, 110 110),(110 110, 120 40, 100 40, 110 110)))', ewkt='MULTIPOLYGON (((110.0000000000000000 110.0000000000000000, 70.0000000000000000 200.0000000000000000, 150.0000000000000000 200.0000000000000000, 110.0000000000000000 110.0000000000000000), (110.0000000000000000 110.0000000000000000, 100.0000000000000000 180.0000000000000000, 120.0000000000000000 180.0000000000000000, 110.0000000000000000 110.0000000000000000)), ((110.0000000000000000 110.0000000000000000, 150.0000000000000000 20.0000000000000000, 70.0000000000000000 20.0000000000000000, 110.0000000000000000 110.0000000000000000), (110.0000000000000000 110.0000000000000000, 120.0000000000000000 40.0000000000000000, 100.0000000000000000 40.0000000000000000, 110.0000000000000000 110.0000000000000000)))'), TestGeom('MULTIPOLYGON(((110 110, 70 200, 150 200, 110 110),(110 110, 100 180, 120 180, 110 110)),((110 110, 150 20, 70 20, 110 110),(110 110, 120 40, 100 40, 110 110)))', ewkt='MULTIPOLYGON (((110.0000000000000000 110.0000000000000000, 70.0000000000000000 200.0000000000000000, 150.0000000000000000 200.0000000000000000, 110.0000000000000000 110.0000000000000000), (110.0000000000000000 110.0000000000000000, 100.0000000000000000 180.0000000000000000, 120.0000000000000000 180.0000000000000000, 110.0000000000000000 110.0000000000000000)), ((110.0000000000000000 110.0000000000000000, 150.0000000000000000 20.0000000000000000, 70.0000000000000000 20.0000000000000000, 110.0000000000000000 110.0000000000000000), (110.0000000000000000 110.0000000000000000, 120.0000000000000000 40.0000000000000000, 100.0000000000000000 40.0000000000000000, 110.0000000000000000 110.0000000000000000)))', kml='<MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>110.0,110.0,0 70.0,200.0,0 150.0,200.0,0 110.0,110.0,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>110.0,110.0,0 100.0,180.0,0 120.0,180.0,0 110.0,110.0,0</coordinates></LinearRing></innerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>110.0,110.0,0 150.0,20.0,0 70.0,20.0,0 110.0,110.0,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>110.0,110.0,0 120.0,40.0,0 100.0,40.0,0 110.0,110.0,0</coordinates></LinearRing></innerBoundaryIs></Polygon></MultiGeometry>'),
TestGeom('GEOMETRYCOLLECTION(POINT(110 260), LINESTRING(110 0, 110 60))', ewkt='GEOMETRYCOLLECTION (POINT (110.0000000000000000 260.0000000000000000), LINESTRING (110.0000000000000000 0.0000000000000000, 110.0000000000000000 60.0000000000000000))'), TestGeom('GEOMETRYCOLLECTION(POINT(110 260), LINESTRING(110 0, 110 60))', ewkt='GEOMETRYCOLLECTION (POINT (110.0000000000000000 260.0000000000000000), LINESTRING (110.0000000000000000 0.0000000000000000, 110.0000000000000000 60.0000000000000000))', kml='<MultiGeometry><Point><coordinates>110.0,260.0,0</coordinates></Point><LineString><coordinates>110.0,0.0,0 110.0,60.0,0</coordinates></LineString></MultiGeometry>'),
) )
# Errors # Errors

View File

@ -22,7 +22,14 @@ class GEOSTest(unittest.TestCase):
geom = GEOSGeometry(g.wkt) geom = GEOSGeometry(g.wkt)
self.assertEqual(g.hex, geom.hex) self.assertEqual(g.hex, geom.hex)
def test01c_errors(self): def test01c_kml(self):
"Testing KML output."
for tg in wkt_out:
geom = fromstr(tg.wkt)
kml = getattr(tg, 'kml', False)
if kml: self.assertEqual(kml, geom.kml)
def test01d_errors(self):
"Testing the Error handlers." "Testing the Error handlers."
print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n" print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n"
for err in errors: for err in errors:
@ -55,12 +62,14 @@ class GEOSTest(unittest.TestCase):
self.assertEqual(p.z, pnt.z) self.assertEqual(p.z, pnt.z)
self.assertEqual(p.z, pnt.tuple[2], 9) self.assertEqual(p.z, pnt.tuple[2], 9)
tup_args = (p.x, p.y, p.z) tup_args = (p.x, p.y, p.z)
set_tup = (2.71, 3.14, 5.23) set_tup1 = (2.71, 3.14, 5.23)
set_tup2 = (5.23, 2.71, 3.14)
else: else:
self.assertEqual(False, pnt.hasz) self.assertEqual(False, pnt.hasz)
self.assertEqual(None, pnt.z) self.assertEqual(None, pnt.z)
tup_args = (p.x, p.y) tup_args = (p.x, p.y)
set_tup = (2.71, 3.14) set_tup1 = (2.71, 3.14)
set_tup2 = (3.14, 2.71)
# Centroid operation on point should be point itself # Centroid operation on point should be point itself
self.assertEqual(p.centroid, pnt.centroid.tuple) self.assertEqual(p.centroid, pnt.centroid.tuple)
@ -77,10 +86,12 @@ class GEOSTest(unittest.TestCase):
self.assertEqual(3.14, pnt.y) self.assertEqual(3.14, pnt.y)
self.assertEqual(2.71, pnt.x) self.assertEqual(2.71, pnt.x)
# Setting via the tuple property # Setting via the tuple/coords property
pnt.tuple = set_tup pnt.tuple = set_tup1
self.assertEqual(set_tup, pnt.tuple) self.assertEqual(set_tup1, pnt.tuple)
pnt.coords = set_tup2
self.assertEqual(set_tup2, pnt.coords)
prev = pnt # setting the previous geometry prev = pnt # setting the previous geometry
def test02b_multipoints(self): def test02b_multipoints(self):
@ -307,7 +318,7 @@ class GEOSTest(unittest.TestCase):
del mp del mp
for p in pts: for p in pts:
self.assertRaises(GEOSException, str, p) # tests p's geometry pointer self.assertRaises(GEOSException, str, p) # tests p's geometry pointer
self.assertRaises(GEOSException, p.get_tuple) # tests p's coordseq pointer self.assertRaises(GEOSException, p.get_coords) # tests p's coordseq pointer
# Now doing this with a GeometryCollection # Now doing this with a GeometryCollection
polywkt = polygons[3].wkt # a 'real life' polygon. polywkt = polygons[3].wkt # a 'real life' polygon.