mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
Merge branch 'feature_impl' of github.com:mapnik/mapnik into feature_impl
This commit is contained in:
commit
79d44e1bf8
@ -247,44 +247,6 @@ class _Datasource(Datasource,_injector):
|
||||
query.add_property_name(fld)
|
||||
return self.features(query)
|
||||
|
||||
class _DeprecatedFeatureProperties(object):
|
||||
|
||||
def __init__(self, feature):
|
||||
self._feature = feature
|
||||
|
||||
def __getitem__(self, name):
|
||||
warnings.warn("indexing feature.properties is deprecated, index the "
|
||||
"feature object itself for the same effect", DeprecationWarning, 2)
|
||||
return self._feature[name]
|
||||
|
||||
def __iter__(self):
|
||||
warnings.warn("iterating feature.properties is deprecated, iterate the "
|
||||
"feature object itself for the same effect", DeprecationWarning, 2)
|
||||
return iter(self._feature)
|
||||
|
||||
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)
|
||||
|
||||
def __init__(self, ctx, id, wkt=None, **properties):
|
||||
Feature._c___init__(self, ctx, id)
|
||||
if wkt is not None:
|
||||
self.add_geometries_from_wkt(wkt)
|
||||
for k, v in properties.iteritems():
|
||||
self[k] = v
|
||||
|
||||
class _Color(Color,_injector):
|
||||
def __repr__(self):
|
||||
return "Color(R=%d,G=%d,B=%d,A=%d)" % (self.r,self.g,self.b,self.a)
|
||||
|
||||
@ -78,12 +78,22 @@ void __setitem__(Feature & feature, std::string const& name, mapnik::value const
|
||||
feature.put(name,val);
|
||||
}
|
||||
|
||||
boost::python::dict describe(Feature const& feature)
|
||||
{
|
||||
boost::python::dict attributes;
|
||||
feature_kv_iterator itr(feature,true);
|
||||
feature_kv_iterator end(feature);
|
||||
|
||||
for ( ;itr!=end; ++itr)
|
||||
{
|
||||
attributes[boost::get<0>(*itr)] = boost::get<1>(*itr);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
}}
|
||||
|
||||
struct UnicodeString_from_python_str
|
||||
{
|
||||
UnicodeString_from_python_str()
|
||||
@ -168,6 +178,7 @@ void export_feature()
|
||||
.def("geometries",make_function(get_paths_by_const_ref,return_value_policy<reference_existing_object>()))
|
||||
.def("envelope", &Feature::envelope)
|
||||
.def("has_key", &Feature::has_key)
|
||||
.def("describe",&describe)
|
||||
.def("__setitem__",&__setitem__)
|
||||
.def("__getitem__",&__getitem__)
|
||||
.def("__getitem__",&__getitem2__)
|
||||
|
||||
@ -67,6 +67,7 @@ gdal_featureset::gdal_featureset(GDALDataset& dataset,
|
||||
filter_factor_(filter_factor),
|
||||
first_(true)
|
||||
{
|
||||
ctx_->push("value");
|
||||
ctx_->push("NODATA");
|
||||
}
|
||||
|
||||
|
||||
@ -581,12 +581,10 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
|
||||
unsigned size=0;
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,itr->get_name());
|
||||
ctx->push(itr->get_name());
|
||||
++size;
|
||||
}
|
||||
|
||||
box2d<double> box(pt.x,pt.y,pt.x,pt.y);
|
||||
|
||||
@ -547,19 +547,24 @@ featureset_ptr sqlite_datasource::features(query const& q) const
|
||||
mapnik::box2d<double> const& e = q.get_bbox();
|
||||
|
||||
std::ostringstream s;
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
s << "SELECT " << geometry_field_;
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
s << "," << key_field_;
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
std::set<std::string> const& props = q.property_names();
|
||||
std::set<std::string>::const_iterator pos = props.begin();
|
||||
std::set<std::string>::const_iterator end = props.end();
|
||||
while (pos != end)
|
||||
|
||||
for ( ;pos != end;++pos)
|
||||
{
|
||||
// TODO - should we restrict duplicate key query?
|
||||
//if (*pos != key_field_)
|
||||
s << ",[" << *pos << "]";
|
||||
++pos;
|
||||
ctx->push(*pos);
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
@ -601,6 +606,7 @@ featureset_ptr sqlite_datasource::features(query const& q) const
|
||||
boost::shared_ptr<sqlite_resultset> rs(dataset_->execute_query(s.str()));
|
||||
|
||||
return boost::make_shared<sqlite_featureset>(rs,
|
||||
ctx,
|
||||
desc_.get_encoding(),
|
||||
format_,
|
||||
using_subquery_);
|
||||
@ -619,20 +625,26 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
|
||||
mapnik::box2d<double> const e(pt.x, pt.y, pt.x, pt.y);
|
||||
|
||||
std::ostringstream s;
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
s << "SELECT " << geometry_field_;
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
s << "," << key_field_;
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
while (itr != end)
|
||||
|
||||
for ( ; itr != end; ++itr)
|
||||
{
|
||||
std::string fld_name = itr->get_name();
|
||||
if (fld_name != key_field_)
|
||||
{
|
||||
s << ",[" << itr->get_name() << "]";
|
||||
ctx->push(itr->get_name());
|
||||
}
|
||||
|
||||
++itr;
|
||||
}
|
||||
|
||||
s << " FROM ";
|
||||
@ -674,6 +686,7 @@ featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
|
||||
boost::shared_ptr<sqlite_resultset> rs(dataset_->execute_query(s.str()));
|
||||
|
||||
return boost::make_shared<sqlite_featureset>(rs,
|
||||
ctx,
|
||||
desc_.get_encoding(),
|
||||
format_,
|
||||
using_subquery_);
|
||||
|
||||
@ -45,6 +45,7 @@ using mapnik::transcoder;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
sqlite_featureset::sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
mapnik::wkbFormat format,
|
||||
bool using_subquery)
|
||||
@ -52,12 +53,8 @@ sqlite_featureset::sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
|
||||
tr_(new transcoder(encoding)),
|
||||
format_(format),
|
||||
using_subquery_(using_subquery),
|
||||
ctx_(boost::make_shared<mapnik::context_type>())
|
||||
ctx_(ctx)
|
||||
{
|
||||
for (int i = 2; i < rs_->column_count(); ++i)
|
||||
{
|
||||
ctx_->push(rs_->column_name(i));
|
||||
}
|
||||
}
|
||||
|
||||
sqlite_featureset::~sqlite_featureset()
|
||||
|
||||
@ -40,6 +40,7 @@ class sqlite_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
|
||||
mapnik::context_ptr const& ctx,
|
||||
std::string const& encoding,
|
||||
mapnik::wkbFormat format,
|
||||
bool using_subquery);
|
||||
|
||||
@ -52,7 +52,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||
eq_(ds.field_types(),['str','str','str','str','float','float','str'])
|
||||
feat = ds.featureset().next()
|
||||
attr = {'City': u'New York, NY', 'geo_accuracy': u'house', 'Phone': u'(212) 334-0711', 'Address': u'19 Elizabeth Street', 'Precinct': u'5th Precinct', 'geo_longitude': -70, 'geo_latitude': 40}
|
||||
eq_(feat.attributes,attr)
|
||||
eq_(feat.describe(),attr)
|
||||
eq_(len(ds.all_features()),2)
|
||||
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||
|
||||
@ -72,7 +72,7 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||
fs = ds.featureset()
|
||||
feat = fs.next()
|
||||
attr = {'x': 0, 'empty_column': u'', 'text': u'a b', 'float': 1.0, 'datetime': u'1971-01-01T04:14:00', 'y': 0, 'boolean': u'True', 'time': u'04:14:00', 'date': u'1971-01-01', 'integer': 40}
|
||||
eq_(feat.attributes,attr)
|
||||
eq_(feat.describe(),attr)
|
||||
while feat:
|
||||
eq_(len(feat),10)
|
||||
eq_(feat['empty_column'],u'')
|
||||
@ -83,9 +83,9 @@ if 'csv' in mapnik.DatasourceCache.instance().plugin_names():
|
||||
ds = get_csv_ds('has_attributes_with_slashes.csv')
|
||||
eq_(len(ds.fields()),3)
|
||||
fs = ds.all_features()
|
||||
eq_(fs[0].attributes,{'x':0,'y':0,'name':u'a/a'})
|
||||
eq_(fs[1].attributes,{'x':1,'y':4,'name':u'b/b'})
|
||||
eq_(fs[2].attributes,{'x':10,'y':2.5,'name':u'c/c'})
|
||||
eq_(fs[0].describe(),{'x':0,'y':0,'name':u'a/a'})
|
||||
eq_(fs[1].describe(),{'x':1,'y':4,'name':u'b/b'})
|
||||
eq_(fs[2].describe(),{'x':10,'y':2.5,'name':u'c/c'})
|
||||
eq_(ds.describe(),{'geometry_type': mapnik.DataGeometryType.Point, 'type': mapnik.DataType.Vector, 'name': 'csv', 'encoding': 'utf-8'})
|
||||
|
||||
def test_wkt_field(**kwargs):
|
||||
|
||||
@ -69,7 +69,7 @@ def test_feature_attributes():
|
||||
features = ds.all_features()
|
||||
feat = features[0]
|
||||
attrs = {'PRFEDEA': u'35043411', 'EAS_ID': 168, 'AREA': 215229.266}
|
||||
eq_(feat.attributes, attrs)
|
||||
eq_(feat.describe(), attrs)
|
||||
eq_(ds.fields(),['AREA', 'EAS_ID', 'PRFEDEA'])
|
||||
eq_(ds.field_types(),['float','int','str'])
|
||||
|
||||
|
||||
@ -32,10 +32,8 @@ def compare_shape_between_mapnik_and_ogr(shapefile,query=None):
|
||||
#import pdb;pdb.set_trace()
|
||||
eq_(feat1.id(),feat2.id(),
|
||||
'%s : ogr feature id %s "%s" does not equal shapefile feature id %s "%s"'
|
||||
% (count,feat1.id(),str(feat1.attributes), feat2.id(),str(feat2.attributes)) )
|
||||
|
||||
% (count,feat1.id(),str(feat1.describe()), feat2.id(),str(feat2.describe())))
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def test_shapefile_line_featureset_id():
|
||||
|
||||
@ -6,71 +6,50 @@ from nose.tools import *
|
||||
import mapnik
|
||||
from binascii import unhexlify
|
||||
|
||||
class FeatureTest(unittest.TestCase):
|
||||
def makeOne(self, *args, **kw):
|
||||
return mapnik.Feature(*args, **kw)
|
||||
|
||||
def test_default_constructor(self):
|
||||
f = self.makeOne(1)
|
||||
self.failUnless(f is not None)
|
||||
def test_default_constructor():
|
||||
f = mapnik.Feature(mapnik.Context(),1)
|
||||
eq_(f is not None,True)
|
||||
|
||||
def test_python_extended_constructor(self):
|
||||
f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar")
|
||||
self.failUnlessEqual(f['foo'], 'bar')
|
||||
self.failUnlessEqual(f.envelope(),mapnik.Box2d(10.0,10.0,45.0,45.0))
|
||||
|
||||
def test_set_get_properties(self):
|
||||
f = self.makeOne(1)
|
||||
counter = itertools.count(0)
|
||||
def test_val(expected):
|
||||
key = 'prop%d'%counter.next()
|
||||
try:
|
||||
f[key] = expected
|
||||
except TypeError:
|
||||
self.fail("%r (%s)"%(expected, type(expected)))
|
||||
self.failUnlessEqual(f[key], expected)
|
||||
for v in (1, True, 1.4, "foo", u"avión"):
|
||||
test_val(v)
|
||||
|
||||
def test_add_wkt_geometry(self):
|
||||
def add_geom_wkt(wkt):
|
||||
f = self.makeOne(1)
|
||||
self.failUnlessEqual(len(f.geometries()), 0)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
self.failUnlessEqual(len(f.geometries()), 3)
|
||||
e = mapnik.Box2d()
|
||||
self.failUnlessEqual(e.valid(), False)
|
||||
for g in f.geometries():
|
||||
if not e.valid():
|
||||
e = g.envelope()
|
||||
else:
|
||||
e +=g.envelope()
|
||||
|
||||
self.failUnlessEqual(e, f.envelope())
|
||||
|
||||
def add_geom_wkb(wkb):
|
||||
f = self.makeOne(1)
|
||||
self.failUnlessEqual(len(f.geometries()), 0)
|
||||
f.add_geometries_from_wkb(unhexlify(wkb))
|
||||
self.failUnlessEqual(len(f.geometries()), 1)
|
||||
e = mapnik.Box2d()
|
||||
self.failUnlessEqual(e.valid(), False)
|
||||
for g in f.geometries():
|
||||
if not e.valid():
|
||||
e = g.envelope()
|
||||
else:
|
||||
e +=g.envelope()
|
||||
|
||||
self.failUnlessEqual(e, f.envelope())
|
||||
|
||||
def run() :
|
||||
add_geom_wkt('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10),POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10)))')
|
||||
add_geom_wkb('010300000001000000050000000000000000003e4000000000000024400000000000002440000000000000344000000000000034400000000000004440000000000000444000000000000044400000000000003e400000000000002440') # POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))
|
||||
run()
|
||||
def test_python_extended_constructor():
|
||||
context = mapnik.Context()
|
||||
context.push('foo')
|
||||
context.push('foo')
|
||||
f = mapnik.Feature(context,1)
|
||||
wkt = 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))'
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
f['foo'] = 'bar'
|
||||
eq_(f['foo'], 'bar')
|
||||
eq_(f.envelope(),mapnik.Box2d(10.0,10.0,45.0,45.0))
|
||||
# reset
|
||||
f['foo'] = u"avión"
|
||||
eq_(f['foo'], u"avión")
|
||||
f['foo'] = 1.4
|
||||
eq_(f['foo'], 1.4)
|
||||
f['foo'] = True
|
||||
eq_(f['foo'], True)
|
||||
|
||||
def test_add_geom_wkb():
|
||||
# POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))
|
||||
wkb = '010300000001000000050000000000000000003e4000000000000024400000000000002440000000000000344000000000000034400000000000004440000000000000444000000000000044400000000000003e400000000000002440'
|
||||
context = mapnik.Context()
|
||||
f = mapnik.Feature(context,1)
|
||||
eq_(len(f.geometries()), 0)
|
||||
f.add_geometries_from_wkb(unhexlify(wkb))
|
||||
eq_(len(f.geometries()), 1)
|
||||
e = mapnik.Box2d()
|
||||
eq_(e.valid(), False)
|
||||
for g in f.geometries():
|
||||
if not e.valid():
|
||||
e = g.envelope()
|
||||
else:
|
||||
e +=g.envelope()
|
||||
|
||||
eq_(e, f.envelope())
|
||||
|
||||
def test_feature_expression_evaluation():
|
||||
f = mapnik.Feature(1)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['name'] = 'a'
|
||||
eq_(f['name'],u'a')
|
||||
expr = mapnik.Expression("[name]='a'")
|
||||
@ -82,7 +61,9 @@ def test_feature_expression_evaluation():
|
||||
|
||||
# https://github.com/mapnik/mapnik/issues/933
|
||||
def test_feature_expression_evaluation_missing_attr():
|
||||
f = mapnik.Feature(1)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['name'] = u'a'
|
||||
eq_(f['name'],u'a')
|
||||
expr = mapnik.Expression("[fielddoesnotexist]='a'")
|
||||
@ -94,7 +75,9 @@ def test_feature_expression_evaluation_missing_attr():
|
||||
|
||||
# https://github.com/mapnik/mapnik/issues/934
|
||||
def test_feature_expression_evaluation_attr_with_spaces():
|
||||
f = mapnik.Feature(1)
|
||||
context = mapnik.Context()
|
||||
context.push('name with space')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['name with space'] = u'a'
|
||||
eq_(f['name with space'],u'a')
|
||||
expr = mapnik.Expression("[name with space]='a'")
|
||||
|
||||
@ -93,25 +93,33 @@ def test_filter_init():
|
||||
|
||||
|
||||
def test_regex_match():
|
||||
f = mapnik.Feature(0)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,0)
|
||||
f["name"] = 'test'
|
||||
expr = mapnik.Expression("[name].match('test')")
|
||||
eq_(expr.evaluate(f),True) # 1 == True
|
||||
|
||||
def test_unicode_regex_match():
|
||||
f = mapnik.Feature(0)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,0)
|
||||
f["name"] = 'Québec'
|
||||
expr = mapnik.Expression("[name].match('Québec')")
|
||||
eq_(expr.evaluate(f),True) # 1 == True
|
||||
|
||||
def test_regex_replace():
|
||||
f = mapnik.Feature(0)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,0)
|
||||
f["name"] = 'test'
|
||||
expr = mapnik.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
eq_(expr.evaluate(f),'t e s t')
|
||||
|
||||
def test_unicode_regex_replace():
|
||||
f = mapnik.Feature(0)
|
||||
context = mapnik.Context()
|
||||
context.push('name')
|
||||
f = mapnik.Feature(context,0)
|
||||
f["name"] = 'Québec'
|
||||
expr = mapnik.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
eq_(expr.evaluate(f), u'Q u é b e c')
|
||||
|
||||
@ -34,7 +34,7 @@ def compare_wkb_from_wkt(wkt,num=None):
|
||||
paths = mapnik.Path.from_wkt(wkt)
|
||||
|
||||
# add geometry(s) to feature from wkt
|
||||
f = mapnik.Feature(1)
|
||||
f = mapnik.Feature(mapnik.Context(),1)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
|
||||
# ensure both have same result
|
||||
@ -65,7 +65,7 @@ def compare_wkt_from_wkt(wkt,num=None):
|
||||
paths = mapnik.Path.from_wkt(wkt)
|
||||
|
||||
# add geometry(s) to feature from wkt
|
||||
f = mapnik.Feature(1)
|
||||
f = mapnik.Feature(mapnik.Context(),1)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
|
||||
# compare to original, which may not have significant digits
|
||||
@ -113,14 +113,14 @@ def test_geometry_index_error():
|
||||
wkt = 'Point (0 0)'
|
||||
paths = mapnik.Path.from_wkt(wkt)
|
||||
paths[3]
|
||||
f = mapnik.Feature(1)
|
||||
f = mapnik.Feature(mapnik.Context(),1)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
f.geometries()[3]
|
||||
|
||||
@raises(IndexError)
|
||||
def test_geometry_index_error2():
|
||||
wkt = 'Point (0 0)'
|
||||
f = mapnik.Feature(1)
|
||||
f = mapnik.Feature(mapnik.Context(),1)
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
f.geometries()[3]
|
||||
|
||||
|
||||
@ -1,40 +1,34 @@
|
||||
#encoding: utf8
|
||||
import itertools
|
||||
import unittest
|
||||
import mapnik
|
||||
from nose.tools import *
|
||||
|
||||
class MemoryDatasource(unittest.TestCase):
|
||||
ids = itertools.count(0)
|
||||
def test_add_feature():
|
||||
md = mapnik.MemoryDatasource()
|
||||
eq_(md.num_features(), 0)
|
||||
context = mapnik.Context()
|
||||
context.push('foo')
|
||||
feature = mapnik.Feature(context,1)
|
||||
feature['foo'] = 'bar'
|
||||
feature.add_geometries_from_wkt('POINT(2 3)')
|
||||
md.add_feature(feature)
|
||||
eq_(md.num_features(), 1)
|
||||
|
||||
def makeOne(self, *args, **kw):
|
||||
from mapnik import MemoryDatasource
|
||||
return MemoryDatasource(*args, **kw)
|
||||
featureset = md.features_at_point(mapnik.Coord(2,3))
|
||||
retrieved = []
|
||||
feat = featureset.next()
|
||||
while featureset.next():
|
||||
retrieved.append(feat)
|
||||
|
||||
eq_(len(retrieved), 1)
|
||||
f = retrieved[0]
|
||||
eq_(f['foo'], 'bar')
|
||||
|
||||
def makeFeature(self, wkt, **properties):
|
||||
from mapnik import Feature
|
||||
f = Feature(self.ids.next())
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
for k,v in properties.iteritems():
|
||||
f[k] = v
|
||||
return f
|
||||
|
||||
def test_default_constructor(self):
|
||||
f = self.makeOne()
|
||||
self.failUnless(f is not None)
|
||||
|
||||
def test_add_feature(self):
|
||||
md = self.makeOne()
|
||||
self.failUnlessEqual(md.num_features(), 0)
|
||||
md.add_feature(self.makeFeature('Point(2 3)', foo='bar'))
|
||||
self.failUnlessEqual(md.num_features(), 1)
|
||||
|
||||
from mapnik import Coord
|
||||
retrieved = md.features_at_point(Coord(2,3)).features
|
||||
self.failUnlessEqual(len(retrieved), 1)
|
||||
f = retrieved[0]
|
||||
self.failUnlessEqual(f['foo'], 'bar')
|
||||
|
||||
retrieved = md.features_at_point(Coord(20,30)).features
|
||||
self.failUnlessEqual(len(retrieved), 0)
|
||||
featureset = md.features_at_point(Coord(20,30)).features
|
||||
retrieved = []
|
||||
feat = featureset.next()
|
||||
while featureset.next():
|
||||
retrieved.append(feat)
|
||||
eq_(len(retrieved), 0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
||||
|
||||
@ -37,11 +37,28 @@ def resolve(grid,x,y):
|
||||
|
||||
|
||||
def create_grid_map(width,height):
|
||||
places_ds = mapnik.MemoryDatasource()
|
||||
places_ds.add_point(143.10,-38.60,'Name','South East')
|
||||
places_ds.add_point(142.48,-38.60,'Name','South West')
|
||||
places_ds.add_point(142.48,-38.38,'Name','North West')
|
||||
places_ds.add_point(143.10,-38.38,'Name','North East')
|
||||
ds = mapnik.MemoryDatasource()
|
||||
context = mapnik.Context()
|
||||
context.push('Name')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['Name'] = 'South East'
|
||||
f.add_geometries_from_wkt('POINT (143.10 -38.60)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,2)
|
||||
f['Name'] = 'South West'
|
||||
f.add_geometries_from_wkt('POINT (142.48 -38.60)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,3)
|
||||
f['Name'] = 'North West'
|
||||
f.add_geometries_from_wkt('POINT (142.48 -38.38)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,4)
|
||||
f['Name'] = 'North East'
|
||||
f.add_geometries_from_wkt('POINT (143.10 -38.38)')
|
||||
ds.add_feature(f)
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
#symb = mapnik.PointSymbolizer()
|
||||
@ -59,7 +76,7 @@ def create_grid_map(width,height):
|
||||
|
||||
s.rules.append(r)
|
||||
lyr = mapnik.Layer('Places')
|
||||
lyr.datasource = places_ds
|
||||
lyr.datasource = ds
|
||||
lyr.styles.append('places_labels')
|
||||
m = mapnik.Map(width,height)
|
||||
m.append_style('places_labels',s)
|
||||
|
||||
@ -120,29 +120,37 @@ def resolve(grid,x,y):
|
||||
|
||||
|
||||
def test_render_grid():
|
||||
places_ds = mapnik.MemoryDatasource()
|
||||
places_ds.add_point(143.10,-38.60,'Name','South East')
|
||||
places_ds.add_point(142.48,-38.60,'Name','South West')
|
||||
places_ds.add_point(142.48,-38.38,'Name','North West')
|
||||
places_ds.add_point(143.10,-38.38,'Name','North East')
|
||||
ds = mapnik.MemoryDatasource()
|
||||
context = mapnik.Context()
|
||||
context.push('Name')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['Name'] = 'South East'
|
||||
f.add_geometries_from_wkt('POINT (143.10 -38.60)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,2)
|
||||
f['Name'] = 'South West'
|
||||
f.add_geometries_from_wkt('POINT (142.48 -38.60)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,3)
|
||||
f['Name'] = 'North West'
|
||||
f.add_geometries_from_wkt('POINT (142.48 -38.38)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,4)
|
||||
f['Name'] = 'North East'
|
||||
f.add_geometries_from_wkt('POINT (143.10 -38.38)')
|
||||
ds.add_feature(f)
|
||||
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
#symb = mapnik.PointSymbolizer()
|
||||
symb = mapnik.MarkersSymbolizer()
|
||||
symb.allow_overlap = True
|
||||
r.symbols.append(symb)
|
||||
label = mapnik.TextSymbolizer(mapnik.Expression('[Name]'),
|
||||
'DejaVu Sans Book',
|
||||
10,
|
||||
mapnik.Color('black')
|
||||
)
|
||||
label.allow_overlap = True
|
||||
label.displacement = (0,-10)
|
||||
#r.symbols.append(label)
|
||||
|
||||
s.rules.append(r)
|
||||
lyr = mapnik.Layer('Places')
|
||||
lyr.datasource = places_ds
|
||||
lyr.datasource = ds
|
||||
lyr.styles.append('places_labels')
|
||||
m = mapnik.Map(256,256)
|
||||
m.append_style('places_labels',s)
|
||||
@ -184,9 +192,19 @@ def test_render_points():
|
||||
if not mapnik.has_cairo(): return
|
||||
|
||||
# create and populate point datasource (WGS84 lat-lon coordinates)
|
||||
places_ds = mapnik.MemoryDatasource()
|
||||
places_ds.add_point(142.48,-38.38,'Name','Westernmost Point') # westernmost
|
||||
places_ds.add_point(143.10,-38.60,'Name','Southernmost Point') # southernmost
|
||||
ds = mapnik.MemoryDatasource()
|
||||
context = mapnik.Context()
|
||||
context.push('Name')
|
||||
f = mapnik.Feature(context,1)
|
||||
f['Name'] = 'Westernmost Point'
|
||||
f.add_geometries_from_wkt('POINT (142.48 -38.38)')
|
||||
ds.add_feature(f)
|
||||
|
||||
f = mapnik.Feature(context,2)
|
||||
f['Name'] = 'Southernmost Point'
|
||||
f.add_geometries_from_wkt('POINT (143.10,-38.60)')
|
||||
ds.add_feature(f)
|
||||
|
||||
# create layer/rule/style
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
@ -195,7 +213,7 @@ def test_render_points():
|
||||
r.symbols.append(symb)
|
||||
s.rules.append(r)
|
||||
lyr = mapnik.Layer('Places','+proj=latlon +datum=WGS84')
|
||||
lyr.datasource = places_ds
|
||||
lyr.datasource = ds
|
||||
lyr.styles.append('places_labels')
|
||||
# latlon bounding box corners
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
@ -216,7 +234,7 @@ def test_render_points():
|
||||
# Render to SVG so that it can be checked how many points are there with string comparison
|
||||
svg_file = os.path.join(tempfile.gettempdir(),'%s.svg')
|
||||
mapnik.render_to_file(m, svg_file)
|
||||
num_points_present = len(places_ds.all_features())
|
||||
num_points_present = len(ds.all_features())
|
||||
svg = open(svg_file,'r').read()
|
||||
num_points_rendered = svg.count('<image ')
|
||||
eq_(num_points_present, num_points_rendered, "Not all points were rendered (%d instead of %d) at projection %s" % (num_points_rendered, num_points_present, projdescr))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user