mapnik/tests/python_tests/python_plugin_test.py
artemp a513d3f97d + code: avoid exposing unsafe static methods in datasource_cache ( #1451)
+ python: remove redundent 'instance' method (mapnik.DatasourceCache)
+ python: reflect plugin_directories method
+ tests: update python usage

TODO: consider using similar approach in FontEngine etc..
TODO: consider returning reference from singleton::instance() to
      safeguard from accidental deleting a 'singleton' pointer
2012-09-05 12:53:37 +01:00

156 lines
5.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import math
import mapnik
import sys
from utilities import execution_path
from nose.tools import *
def setup():
# All of the paths used are relative, if we run the tests
# from another directory we need to chdir()
os.chdir(execution_path('.'))
class PointDatasource(mapnik.PythonDatasource):
def __init__(self):
super(PointDatasource, self).__init__(
envelope = mapnik.Box2d(0,-10,100,110)
)
def features(self, query):
return mapnik.PythonDatasource.wkt_features(
keys = ('label',),
features = (
( 'POINT (5 6)', { 'label': 'foo-bar'} ),
( 'POINT (60 50)', { 'label': 'buzz-quux'} ),
)
)
class ConcentricCircles(object):
def __init__(self, centre, bounds, step=1):
self.centre = centre
self.bounds = bounds
self.step = step
class Iterator(object):
def __init__(self, container):
self.container = container
centre = self.container.centre
bounds = self.container.bounds
step = self.container.step
self.radius = step
def next(self):
points = []
for alpha in xrange(0, 361, 5):
x = math.sin(math.radians(alpha)) * self.radius + self.container.centre[0]
y = math.cos(math.radians(alpha)) * self.radius + self.container.centre[1]
points.append('%s %s' % (x,y))
circle = 'POLYGON ((' + ','.join(points) + '))'
# has the circle grown so large that the boundary is entirely within it?
tl = (self.container.bounds.maxx, self.container.bounds.maxy)
tr = (self.container.bounds.maxx, self.container.bounds.maxy)
bl = (self.container.bounds.minx, self.container.bounds.miny)
br = (self.container.bounds.minx, self.container.bounds.miny)
def within_circle(p):
delta_x = p[0] - self.container.centre[0]
delta_y = p[0] - self.container.centre[0]
return delta_x*delta_x + delta_y*delta_y < self.radius*self.radius
if all(within_circle(p) for p in (tl,tr,bl,br)):
raise StopIteration()
self.radius += self.container.step
return ( circle, { } )
def __iter__(self):
return ConcentricCircles.Iterator(self)
class CirclesDatasource(mapnik.PythonDatasource):
def __init__(self, centre_x=-20, centre_y=0, step=10):
super(CirclesDatasource, self).__init__(
geometry_type=mapnik.DataGeometryType.Polygon
)
# note that the plugin loader will set all arguments to strings and will not try to parse them
centre_x = int(centre_x)
centre_y = int(centre_y)
step = int(step)
self.centre_x = centre_x
self.centre_y = centre_y
self.step = step
def features(self, query):
centre = (self.centre_x, self.centre_y)
return mapnik.PythonDatasource.wkt_features(
keys = (),
features = ConcentricCircles(centre, query.bbox, self.step)
)
if 'python' in mapnik.DatasourceCache.plugin_names():
# make sure we can load from ourself as a module
sys.path.append(execution_path('.'))
def test_python_point_init():
ds = mapnik.Python(factory='python_plugin_test:PointDatasource')
e = ds.envelope()
assert_almost_equal(e.minx, 0, places=7)
assert_almost_equal(e.miny, -10, places=7)
assert_almost_equal(e.maxx, 100, places=7)
assert_almost_equal(e.maxy, 110, places=7)
def test_python_circle_init():
ds = mapnik.Python(factory='python_plugin_test:CirclesDatasource')
e = ds.envelope()
assert_almost_equal(e.minx, -180, places=7)
assert_almost_equal(e.miny, -90, places=7)
assert_almost_equal(e.maxx, 180, places=7)
assert_almost_equal(e.maxy, 90, places=7)
def test_python_circle_init_with_args():
ds = mapnik.Python(factory='python_plugin_test:CirclesDatasource', centre_x=40, centre_y=7)
e = ds.envelope()
assert_almost_equal(e.minx, -180, places=7)
assert_almost_equal(e.miny, -90, places=7)
assert_almost_equal(e.maxx, 180, places=7)
assert_almost_equal(e.maxy, 90, places=7)
def test_python_point_rendering():
m = mapnik.Map(512,512)
mapnik.load_map(m,'../data/python_plugin/python_point_datasource.xml')
m.zoom_all()
im = mapnik.Image(512,512)
mapnik.render(m,im)
actual = '/tmp/mapnik-python-point-render1.png'
expected = 'images/support/mapnik-python-point-render1.png'
im.save(actual)
expected_im = mapnik.Image.open(expected)
eq_(im.tostring(),expected_im.tostring(),
'failed comparing actual (%s) and expected (%s)' % (actual,'tests/python_tests/'+ expected))
def test_python_circle_rendering():
m = mapnik.Map(512,512)
mapnik.load_map(m,'../data/python_plugin/python_circle_datasource.xml')
m.zoom_all()
im = mapnik.Image(512,512)
mapnik.render(m,im)
actual = '/tmp/mapnik-python-circle-render1.png'
expected = 'images/support/mapnik-python-circle-render1.png'
im.save(actual)
expected_im = mapnik.Image.open(expected)
eq_(im.tostring(),expected_im.tostring(),
'failed comparing actual (%s) and expected (%s)' % (actual,'tests/python_tests/'+ expected))
if __name__ == "__main__":
setup()
[eval(run)() for run in dir() if 'test_' in run]