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:
parent
5f4ffb369f
commit
e982954602
@ -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."
|
||||||
|
@ -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
|
||||||
|
@ -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."
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user