mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
implemented a mechanism in mapnik2._injector to be able to override c++ methods (at the python layer only). Used it to implement a friendlier constructor for Feature and a add_geometry() method that accepts shapely.geometry.Geometrys, and wkb/wkt strings
This commit is contained in:
parent
a613dc6397
commit
18b811d19d
@ -63,6 +63,8 @@ class _injector(object):
|
||||
for b in bases:
|
||||
if type(b) not in (self, type):
|
||||
for k,v in dict.items():
|
||||
if hasattr(b, k):
|
||||
setattr(b, '_c_'+k, getattr(b, k))
|
||||
setattr(b,k,v)
|
||||
return type.__init__(self, name, bases, dict)
|
||||
|
||||
@ -250,15 +252,56 @@ class _DeprecatedFeatureProperties(object):
|
||||
"feature object itself for the same effect", DeprecationWarning, 2)
|
||||
return iter(self._feature)
|
||||
|
||||
class _Feature(Feature,_injector):
|
||||
class _Feature(Feature, _injector):
|
||||
"""
|
||||
A Feature.
|
||||
|
||||
TODO: docs
|
||||
"""
|
||||
@property
|
||||
def properties(self):
|
||||
return _DeprecatedFeatureProperties(self)
|
||||
|
||||
@property
|
||||
def attributes(self):
|
||||
#XXX Returns a copy! changes to it won't affect feat.'s attrs.
|
||||
# maybe deprecate?
|
||||
return dict(self)
|
||||
|
||||
@property
|
||||
def geometry(self):
|
||||
if self.num_geometries() > 0:
|
||||
return self.get_geometry(0)
|
||||
|
||||
@property
|
||||
def geometries(self):
|
||||
return [self.get_geometry(i) for i in xrange(self.num_geometries())]
|
||||
|
||||
def __init__(self, id, geometry=None, **properties):
|
||||
Feature._c___init__(self, id)
|
||||
if geometry is not None:
|
||||
self.add_geometry(geometry)
|
||||
for k, v in properties.iteritems():
|
||||
self[k] = v
|
||||
|
||||
def add_geometry(self, geometry):
|
||||
geometry = self._as_wkb(geometry)
|
||||
Feature._c_add_geometry(self, geometry)
|
||||
|
||||
def _as_wkb(self, geometry):
|
||||
if hasattr(geometry, 'wkb'):
|
||||
# a shapely.geometry.Geometry
|
||||
geometry = geometry.wkb
|
||||
if isinstance(geometry, str):
|
||||
# ignoring unicode un purpose
|
||||
for type_ in ('POINT', 'POLYGON', 'LINE'):
|
||||
if type_ in geometry:
|
||||
# A WKT encoded string
|
||||
from shapely import wkt
|
||||
geometry = wkt.loads(geometry).wkb
|
||||
return geometry
|
||||
raise TypeError("%r (%s) not supported" % (geometry, type(geometry)))
|
||||
|
||||
class _Symbolizer(Symbolizer,_injector):
|
||||
def symbol(self):
|
||||
return getattr(self,self.type())()
|
||||
|
||||
@ -13,6 +13,18 @@ class FeatureTest(unittest.TestCase):
|
||||
f = self.makeOne(1)
|
||||
self.failUnless(f is not None)
|
||||
|
||||
def test_python_extended_constructor(self):
|
||||
try:
|
||||
from shapely.geometry import Point
|
||||
except ImportError:
|
||||
raise Todo("Make this test not dependant on shapely")
|
||||
|
||||
f = self.makeOne(1, Point(3,6), foo="bar")
|
||||
self.failUnlessEqual(f['foo'], 'bar')
|
||||
env = f.geometry.envelope()
|
||||
self.failUnlessEqual(env.minx, 3)
|
||||
self.failUnlessEqual(env.miny, 6)
|
||||
|
||||
def test_set_get_properties(self):
|
||||
f = self.makeOne(1)
|
||||
counter = itertools.count(0)
|
||||
@ -26,19 +38,24 @@ class FeatureTest(unittest.TestCase):
|
||||
for v in (1, True, 1.4, "foo", u"avión"):
|
||||
test_val(v)
|
||||
|
||||
def test_add_wkb_geometry_(self):
|
||||
|
||||
def test_add_wkb_geometry(self):
|
||||
try:
|
||||
from shapely.geometry import Point
|
||||
except ImportError:
|
||||
raise Todo("Make this test not dependant on shapely")
|
||||
|
||||
f = self.makeOne(1)
|
||||
self.failUnlessEqual(f.num_geometries(), 0)
|
||||
f.add_geometry(Point(3,6).wkb)
|
||||
self.failUnlessEqual(f.num_geometries(), 1)
|
||||
geom = f.get_geometry(0)
|
||||
env = geom.envelope()
|
||||
self.failUnlessEqual(env.minx, 3)
|
||||
self.failUnlessEqual(env.minx, env.maxx)
|
||||
self.failUnlessEqual(env.miny, 6)
|
||||
self.failUnlessEqual(env.miny, env.maxy)
|
||||
def add_it(geometry):
|
||||
f = self.makeOne(1)
|
||||
self.failUnlessEqual(len(f.geometries), 0)
|
||||
f.add_geometry(geometry)
|
||||
self.failUnlessEqual(len(f.geometries), 1)
|
||||
env = f.geometry.envelope()
|
||||
self.failUnlessEqual(env.minx, 3)
|
||||
self.failUnlessEqual(env.minx, env.maxx)
|
||||
self.failUnlessEqual(env.miny, 6)
|
||||
self.failUnlessEqual(env.miny, env.maxy)
|
||||
|
||||
geometries = (Point(3,6), 'POINT(3 6)', Point(3,6).wkb)
|
||||
for geom in geometries:
|
||||
add_it(geom)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user