apply alternative method of comparing map and layer bounds to support PointDatasource (patch from phispi, test from JRohrer), closes #402
This commit is contained in:
parent
6720a031cf
commit
34f2214396
3 changed files with 67 additions and 18 deletions
1
AUTHORS
1
AUTHORS
|
@ -48,6 +48,7 @@ Patches
|
||||||
- Ehud Shabtai
|
- Ehud Shabtai
|
||||||
- Steve Singer
|
- Steve Singer
|
||||||
- Paul Smith
|
- Paul Smith
|
||||||
|
- Philipp Spitzer
|
||||||
- Dave Stubbs
|
- Dave Stubbs
|
||||||
- River Tarnell
|
- River Tarnell
|
||||||
- Alberto Valverde
|
- Alberto Valverde
|
||||||
|
|
|
@ -117,32 +117,31 @@ namespace mapnik
|
||||||
projection proj1(lay.srs());
|
projection proj1(lay.srs());
|
||||||
proj_transform prj_trans(proj0,proj1);
|
proj_transform prj_trans(proj0,proj1);
|
||||||
|
|
||||||
Envelope<double> layer_ext = lay.envelope();
|
double mx0 = ext.minx();
|
||||||
double lx0 = layer_ext.minx();
|
double my0 = ext.miny();
|
||||||
double ly0 = layer_ext.miny();
|
double mz0 = 0.0;
|
||||||
double lz0 = 0.0;
|
double mx1 = ext.maxx();
|
||||||
double lx1 = layer_ext.maxx();
|
double my1 = ext.maxy();
|
||||||
double ly1 = layer_ext.maxy();
|
double mz1 = 0.0;
|
||||||
double lz1 = 0.0;
|
|
||||||
// back project layers extent into main map projection
|
// project main map projection into layers extent
|
||||||
prj_trans.backward(lx0,ly0,lz0);
|
prj_trans.forward(mx0,my0,mz0);
|
||||||
prj_trans.backward(lx1,ly1,lz1);
|
prj_trans.forward(mx1,my1,mz1);
|
||||||
|
|
||||||
// if no intersection then nothing to do for layer
|
// if no intersection then nothing to do for layer
|
||||||
if ( lx0 > ext.maxx() || lx1 < ext.minx() || ly0 > ext.maxy() || ly1 < ext.miny() )
|
Envelope<double> layer_ext = lay.envelope();
|
||||||
|
if ( mx0 > layer_ext.maxx() || mx1 < layer_ext.minx() || my0 > layer_ext.maxy() || my1 < layer_ext.miny() )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip query bbox
|
// clip query bbox
|
||||||
lx0 = std::max(ext.minx(),lx0);
|
mx0 = std::max(layer_ext.minx(),mx0);
|
||||||
ly0 = std::max(ext.miny(),ly0);
|
my0 = std::max(layer_ext.miny(),my0);
|
||||||
lx1 = std::min(ext.maxx(),lx1);
|
mx1 = std::min(layer_ext.maxx(),mx1);
|
||||||
ly1 = std::min(ext.maxy(),ly1);
|
my1 = std::min(layer_ext.maxy(),my1);
|
||||||
|
|
||||||
prj_trans.forward(lx0,ly0,lz0);
|
Envelope<double> bbox(mx0,my0,mx1,my1);
|
||||||
prj_trans.forward(lx1,ly1,lz1);
|
|
||||||
Envelope<double> bbox(lx0,ly0,lx1,ly1);
|
|
||||||
|
|
||||||
double resolution = m_.getWidth()/bbox.width();
|
double resolution = m_.getWidth()/bbox.width();
|
||||||
query q(bbox,resolution); //BBOX query
|
query q(bbox,resolution); //BBOX query
|
||||||
|
|
|
@ -65,3 +65,52 @@ def test_render_from_serialization():
|
||||||
|
|
||||||
i,i2 = get_paired_images(100,100,'../data/good_maps/polygon_symbolizer.xml')
|
i,i2 = get_paired_images(100,100,'../data/good_maps/polygon_symbolizer.xml')
|
||||||
eq_(i.tostring(),i2.tostring())
|
eq_(i.tostring(),i2.tostring())
|
||||||
|
|
||||||
|
def test_render_points():
|
||||||
|
# Test for effectivenes of ticket #402 (borderline points get lost on reprojection)
|
||||||
|
if not mapnik.has_pycairo(): return
|
||||||
|
|
||||||
|
# create and populate point datasource (WGS84 lat-lon coordinates)
|
||||||
|
places_ds = mapnik.PointDatasource()
|
||||||
|
places_ds.add_point(142.48,-38.38,'Name','Westernmost Point') # westernmost
|
||||||
|
places_ds.add_point(143.10,-38.60,'Name','Southernmost Point') # southernmost
|
||||||
|
# create layer/rule/style
|
||||||
|
s = mapnik.Style()
|
||||||
|
r = mapnik.Rule()
|
||||||
|
symb = mapnik.PointSymbolizer()
|
||||||
|
symb.allow_overlap = True
|
||||||
|
r.symbols.append(symb)
|
||||||
|
s.rules.append(r)
|
||||||
|
lyr = mapnik.Layer('Places','+proj=latlon +datum=WGS84')
|
||||||
|
lyr.datasource = places_ds
|
||||||
|
lyr.styles.append('places_labels')
|
||||||
|
# latlon bounding box corners
|
||||||
|
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||||
|
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||||
|
# render for different projections
|
||||||
|
projs = {
|
||||||
|
'latlon': '+proj=latlon +datum=WGS84',
|
||||||
|
'merc': '+proj=merc +datum=WGS84 +k=1.0 +units=m +over +no_defs',
|
||||||
|
'google': '+proj=merc +ellps=sphere +R=6378137 +a=6378137 +units=m',
|
||||||
|
'utm': '+proj=utm +zone=54 +datum=WGS84'
|
||||||
|
}
|
||||||
|
from cairo import SVGSurface
|
||||||
|
for projdescr in projs.iterkeys():
|
||||||
|
m = mapnik.Map(1000, 500, projs[projdescr])
|
||||||
|
m.append_style('places_labels',s)
|
||||||
|
m.layers.append(lyr)
|
||||||
|
p = mapnik.Projection(projs[projdescr])
|
||||||
|
m.zoom_to_box(p.forward(mapnik.Envelope(ul_lonlat,lr_lonlat)))
|
||||||
|
# Render to SVG so that it can be checked how many points are there with string comparison
|
||||||
|
import StringIO
|
||||||
|
svg_memory_file = StringIO.StringIO()
|
||||||
|
surface = SVGSurface(svg_memory_file, m.width, m.height)
|
||||||
|
mapnik.render(m, surface)
|
||||||
|
surface.flush()
|
||||||
|
surface.finish()
|
||||||
|
svg = svg_memory_file.getvalue()
|
||||||
|
svg_memory_file.close()
|
||||||
|
num_points_present = len(places_ds.all_features())
|
||||||
|
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…
Reference in a new issue