From a1dde7eff9a0d44e057afb556d6eba697482c573 Mon Sep 17 00:00:00 2001 From: Manel Clos Date: Tue, 25 Sep 2012 10:51:49 +0200 Subject: [PATCH 1/3] Query tolerance test --- tests/python_tests/query_tolerance_test.py | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/python_tests/query_tolerance_test.py diff --git a/tests/python_tests/query_tolerance_test.py b/tests/python_tests/query_tolerance_test.py new file mode 100644 index 000000000..160efb05f --- /dev/null +++ b/tests/python_tests/query_tolerance_test.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +from nose.tools import * +from utilities import execution_path + +import os, mapnik + +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('.')) + +def test_query_tolerance(): + srs = '+init=epsg:4326' + lyr = mapnik.Layer('test') + lyr.datasource = mapnik.Shapefile(file='../data/shp/arrows.shp') + lyr.srs = srs + _width = 256 + _map = mapnik.Map(_width,_width, srs) + _map.layers.append(lyr) + + # zoom determines tolerance + _map.zoom_all() + _map_env = _map.envelope() + tol = (_map_env.maxx - _map_env.minx) / _width * 3 + # 0.046875 for arrows.shp and zoom_all + assert tol == 0.046875 + + # check point really exists + x, y = 2.0, 4.0 + features = _map.query_point(0,x,y).features + assert len(features) == 1 + + # check inside tolerance limit + x = 2.0 + tol * 0.9 + features = _map.query_point(0,x,y).features + assert len(features) == 1 + + # check outside tolerance limit + x = 2.0 + tol * 1.1 + features = _map.query_point(0,x,y).features + assert len(features) == 0 + From f4934e62ea31a5125325b2b2d51c9d5c1ac9a7ef Mon Sep 17 00:00:00 2001 From: Manel Clos Date: Tue, 25 Sep 2012 10:51:49 +0200 Subject: [PATCH 2/3] Query tolerance test --- tests/python_tests/query_tolerance_test.py | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/python_tests/query_tolerance_test.py diff --git a/tests/python_tests/query_tolerance_test.py b/tests/python_tests/query_tolerance_test.py new file mode 100644 index 000000000..160efb05f --- /dev/null +++ b/tests/python_tests/query_tolerance_test.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +from nose.tools import * +from utilities import execution_path + +import os, mapnik + +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('.')) + +def test_query_tolerance(): + srs = '+init=epsg:4326' + lyr = mapnik.Layer('test') + lyr.datasource = mapnik.Shapefile(file='../data/shp/arrows.shp') + lyr.srs = srs + _width = 256 + _map = mapnik.Map(_width,_width, srs) + _map.layers.append(lyr) + + # zoom determines tolerance + _map.zoom_all() + _map_env = _map.envelope() + tol = (_map_env.maxx - _map_env.minx) / _width * 3 + # 0.046875 for arrows.shp and zoom_all + assert tol == 0.046875 + + # check point really exists + x, y = 2.0, 4.0 + features = _map.query_point(0,x,y).features + assert len(features) == 1 + + # check inside tolerance limit + x = 2.0 + tol * 0.9 + features = _map.query_point(0,x,y).features + assert len(features) == 1 + + # check outside tolerance limit + x = 2.0 + tol * 1.1 + features = _map.query_point(0,x,y).features + assert len(features) == 0 + From 8f7083d14d35b9b68b458e1c314b8003f3799d0d Mon Sep 17 00:00:00 2001 From: Manel Clos Date: Fri, 28 Sep 2012 15:12:10 +0200 Subject: [PATCH 3/3] Add tolerance parameter to features_at_point Make map.query_point() always pass tolerance to datasources --- include/mapnik/datasource.hpp | 2 +- include/mapnik/memory_datasource.hpp | 2 +- plugins/input/csv/csv_datasource.cpp | 2 +- plugins/input/csv/csv_datasource.hpp | 2 +- plugins/input/gdal/gdal_datasource.cpp | 2 +- plugins/input/gdal/gdal_datasource.hpp | 2 +- plugins/input/geojson/geojson_datasource.cpp | 2 +- plugins/input/geojson/geojson_datasource.hpp | 2 +- plugins/input/geos/geos_datasource.cpp | 2 +- plugins/input/geos/geos_datasource.hpp | 2 +- plugins/input/kismet/kismet_datasource.cpp | 2 +- plugins/input/kismet/kismet_datasource.hpp | 2 +- plugins/input/occi/occi_datasource.cpp | 2 +- plugins/input/occi/occi_datasource.hpp | 2 +- plugins/input/ogr/ogr_datasource.cpp | 2 +- plugins/input/ogr/ogr_datasource.hpp | 2 +- plugins/input/osm/osm_datasource.cpp | 2 +- plugins/input/osm/osm_datasource.hpp | 2 +- plugins/input/postgis/postgis_datasource.cpp | 4 +-- plugins/input/postgis/postgis_datasource.hpp | 2 +- plugins/input/python/python_datasource.cpp | 2 +- plugins/input/python/python_datasource.hpp | 2 +- plugins/input/raster/raster_datasource.cpp | 2 +- plugins/input/raster/raster_datasource.hpp | 2 +- .../rasterlite/rasterlite_datasource.cpp | 2 +- .../rasterlite/rasterlite_datasource.hpp | 2 +- plugins/input/shape/shape_datasource.cpp | 2 +- plugins/input/shape/shape_datasource.hpp | 2 +- plugins/input/sqlite/sqlite_datasource.cpp | 2 +- plugins/input/sqlite/sqlite_datasource.hpp | 2 +- .../templates/helloworld/hello_datasource.cpp | 2 +- .../templates/helloworld/hello_datasource.hpp | 2 +- src/map.cpp | 32 +++++++++---------- src/memory_datasource.cpp | 2 +- 34 files changed, 50 insertions(+), 50 deletions(-) diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index 309f9d6c7..014cc99e6 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -115,7 +115,7 @@ public: virtual void bind() const {} virtual featureset_ptr features(query const& q) const = 0; - virtual featureset_ptr features_at_point(coord2d const& pt) const = 0; + virtual featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const = 0; virtual box2d envelope() const = 0; virtual boost::optional get_geometry_type() const = 0; virtual layer_descriptor get_descriptor() const = 0; diff --git a/include/mapnik/memory_datasource.hpp b/include/mapnik/memory_datasource.hpp index 5da68e4c0..8966fe036 100644 --- a/include/mapnik/memory_datasource.hpp +++ b/include/mapnik/memory_datasource.hpp @@ -41,7 +41,7 @@ public: void push(feature_ptr feature); datasource::datasource_t type() const; featureset_ptr features(const query& q) const; - featureset_ptr features_at_point(coord2d const& pt) const; + featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const; box2d envelope() const; boost::optional get_geometry_type() const; layer_descriptor get_descriptor() const; diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index a08dc833a..a7490f6ea 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -959,7 +959,7 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const return boost::make_shared(q.get_bbox(),features_); } -mapnik::featureset_ptr csv_datasource::features_at_point(mapnik::coord2d const& pt) const +mapnik::featureset_ptr csv_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp index 0fa8ede27..991a005a1 100644 --- a/plugins/input/csv/csv_datasource.hpp +++ b/plugins/input/csv/csv_datasource.hpp @@ -47,7 +47,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/gdal/gdal_datasource.cpp b/plugins/input/gdal/gdal_datasource.cpp index 048edf1c0..3a7ea2122 100644 --- a/plugins/input/gdal/gdal_datasource.cpp +++ b/plugins/input/gdal/gdal_datasource.cpp @@ -246,7 +246,7 @@ featureset_ptr gdal_datasource::features(query const& q) const nodata_value_)); } -featureset_ptr gdal_datasource::features_at_point(coord2d const& pt) const +featureset_ptr gdal_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) bind(); diff --git a/plugins/input/gdal/gdal_datasource.hpp b/plugins/input/gdal/gdal_datasource.hpp index 15654fae9..1152c5849 100644 --- a/plugins/input/gdal/gdal_datasource.hpp +++ b/plugins/input/gdal/gdal_datasource.hpp @@ -50,7 +50,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/geojson/geojson_datasource.cpp b/plugins/input/geojson/geojson_datasource.cpp index 27c6973c9..a118bd088 100644 --- a/plugins/input/geojson/geojson_datasource.cpp +++ b/plugins/input/geojson/geojson_datasource.cpp @@ -217,7 +217,7 @@ mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) cons } // FIXME -mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt) const +mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const { if (!is_bound_) bind(); throw mapnik::datasource_exception("GeoJSON Plugin: features_at_point is not supported yet"); diff --git a/plugins/input/geojson/geojson_datasource.hpp b/plugins/input/geojson/geojson_datasource.hpp index bc479f4e0..e3d0e491c 100644 --- a/plugins/input/geojson/geojson_datasource.hpp +++ b/plugins/input/geojson/geojson_datasource.hpp @@ -60,7 +60,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; mapnik::layer_descriptor get_descriptor() const; boost::optional get_geometry_type() const; diff --git a/plugins/input/geos/geos_datasource.cpp b/plugins/input/geos/geos_datasource.cpp index 8bd2bcff8..e13e563c3 100644 --- a/plugins/input/geos/geos_datasource.cpp +++ b/plugins/input/geos/geos_datasource.cpp @@ -315,7 +315,7 @@ featureset_ptr geos_datasource::features(query const& q) const desc_.get_encoding()); } -featureset_ptr geos_datasource::features_at_point(coord2d const& pt) const +featureset_ptr geos_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) bind(); diff --git a/plugins/input/geos/geos_datasource.hpp b/plugins/input/geos/geos_datasource.hpp index 6127e9fbd..463ed497f 100644 --- a/plugins/input/geos/geos_datasource.hpp +++ b/plugins/input/geos/geos_datasource.hpp @@ -50,7 +50,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/kismet/kismet_datasource.cpp b/plugins/input/kismet/kismet_datasource.cpp index b4f5f6369..cfd149ed7 100644 --- a/plugins/input/kismet/kismet_datasource.cpp +++ b/plugins/input/kismet/kismet_datasource.cpp @@ -166,7 +166,7 @@ featureset_ptr kismet_datasource::features(query const& q) const // return featureset_ptr(); } -featureset_ptr kismet_datasource::features_at_point(coord2d const& pt) const +featureset_ptr kismet_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) bind(); diff --git a/plugins/input/kismet/kismet_datasource.hpp b/plugins/input/kismet/kismet_datasource.hpp index cebbc4d84..28d3c335b 100644 --- a/plugins/input/kismet/kismet_datasource.hpp +++ b/plugins/input/kismet/kismet_datasource.hpp @@ -52,7 +52,7 @@ public: datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/occi/occi_datasource.cpp b/plugins/input/occi/occi_datasource.cpp index daa7dcd4a..8f23675ae 100644 --- a/plugins/input/occi/occi_datasource.cpp +++ b/plugins/input/occi/occi_datasource.cpp @@ -590,7 +590,7 @@ featureset_ptr occi_datasource::features(query const& q) const row_prefetch_); } -featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const +featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) bind(); diff --git a/plugins/input/occi/occi_datasource.hpp b/plugins/input/occi/occi_datasource.hpp index 7e85de7b0..4d0d2ba22 100644 --- a/plugins/input/occi/occi_datasource.hpp +++ b/plugins/input/occi/occi_datasource.hpp @@ -51,7 +51,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index ea35829cf..50fb633e3 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -519,7 +519,7 @@ featureset_ptr ogr_datasource::features(query const& q) const return featureset_ptr(); } -featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const +featureset_ptr ogr_datasource::features_at_point(coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/ogr/ogr_datasource.hpp b/plugins/input/ogr/ogr_datasource.hpp index 67dc5799c..3b383f053 100644 --- a/plugins/input/ogr/ogr_datasource.hpp +++ b/plugins/input/ogr/ogr_datasource.hpp @@ -52,7 +52,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/osm/osm_datasource.cpp b/plugins/input/osm/osm_datasource.cpp index dbc8dfd7d..ba5b4d08c 100644 --- a/plugins/input/osm/osm_datasource.cpp +++ b/plugins/input/osm/osm_datasource.cpp @@ -158,7 +158,7 @@ featureset_ptr osm_datasource::features(const query& q) const desc_.get_encoding()); } -featureset_ptr osm_datasource::features_at_point(coord2d const& pt) const +featureset_ptr osm_datasource::features_at_point(coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/osm/osm_datasource.hpp b/plugins/input/osm/osm_datasource.hpp index fc79faa88..2ef8b5841 100644 --- a/plugins/input/osm/osm_datasource.hpp +++ b/plugins/input/osm/osm_datasource.hpp @@ -58,7 +58,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); featureset_ptr features(const query& q) const; - featureset_ptr features_at_point(coord2d const& pt) const; + featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const; box2d envelope() const; boost::optional get_geometry_type() const; layer_descriptor get_descriptor() const; diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index ad5e09386..8a2e56764 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -709,7 +709,7 @@ featureset_ptr postgis_datasource::features(const query& q) const return featureset_ptr(); } -featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const +featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) { @@ -778,7 +778,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const } } - box2d box(pt.x, pt.y, pt.x, pt.y); + box2d box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0); s << " FROM " << table_with_bbox; diff --git a/plugins/input/postgis/postgis_datasource.hpp b/plugins/input/postgis/postgis_datasource.hpp index 61fc29bed..9885ca3c2 100644 --- a/plugins/input/postgis/postgis_datasource.hpp +++ b/plugins/input/postgis/postgis_datasource.hpp @@ -63,7 +63,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); featureset_ptr features(const query& q) const; - featureset_ptr features_at_point(coord2d const& pt) const; + featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; layer_descriptor get_descriptor() const; diff --git a/plugins/input/python/python_datasource.cpp b/plugins/input/python/python_datasource.cpp index 8f5c48ec7..5517cb58e 100644 --- a/plugins/input/python/python_datasource.cpp +++ b/plugins/input/python/python_datasource.cpp @@ -189,7 +189,7 @@ mapnik::featureset_ptr python_datasource::features(mapnik::query const& q) const return mapnik::featureset_ptr(); } -mapnik::featureset_ptr python_datasource::features_at_point(mapnik::coord2d const& pt) const +mapnik::featureset_ptr python_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const { using namespace boost::python; diff --git a/plugins/input/python/python_datasource.hpp b/plugins/input/python/python_datasource.hpp index 6f23fcfc8..1b9980dfe 100644 --- a/plugins/input/python/python_datasource.hpp +++ b/plugins/input/python/python_datasource.hpp @@ -29,7 +29,7 @@ public: // mandatory: function to query features by point (coord2d) // not used by rendering, but available to calling applications - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; // mandatory: return the box2d of the datasource // called during rendering to determine if the layer should be processed diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index f758ae736..d188c1de7 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -220,7 +220,7 @@ featureset_ptr raster_datasource::features(query const& q) const } } -featureset_ptr raster_datasource::features_at_point(coord2d const&) const +featureset_ptr raster_datasource::features_at_point(coord2d const&, double tol) const { MAPNIK_LOG_WARN(raster) << "raster_datasource: feature_at_point not supported"; diff --git a/plugins/input/raster/raster_datasource.hpp b/plugins/input/raster/raster_datasource.hpp index c79afbbe6..91306ca14 100644 --- a/plugins/input/raster/raster_datasource.hpp +++ b/plugins/input/raster/raster_datasource.hpp @@ -49,7 +49,7 @@ public: datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(const mapnik::query& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/rasterlite/rasterlite_datasource.cpp b/plugins/input/rasterlite/rasterlite_datasource.cpp index bc8817745..803090635 100644 --- a/plugins/input/rasterlite/rasterlite_datasource.cpp +++ b/plugins/input/rasterlite/rasterlite_datasource.cpp @@ -201,7 +201,7 @@ featureset_ptr rasterlite_datasource::features(query const& q) const return boost::make_shared(open_dataset(), gq); } -featureset_ptr rasterlite_datasource::features_at_point(coord2d const& pt) const +featureset_ptr rasterlite_datasource::features_at_point(coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/rasterlite/rasterlite_datasource.hpp b/plugins/input/rasterlite/rasterlite_datasource.hpp index 4ed4ef4e3..7c046e582 100644 --- a/plugins/input/rasterlite/rasterlite_datasource.hpp +++ b/plugins/input/rasterlite/rasterlite_datasource.hpp @@ -50,7 +50,7 @@ public: mapnik::datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index caf401e81..366ea46f5 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -286,7 +286,7 @@ featureset_ptr shape_datasource::features(const query& q) const } } -featureset_ptr shape_datasource::features_at_point(coord2d const& pt) const +featureset_ptr shape_datasource::features_at_point(coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index 56ea052fc..ea3e10587 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.hpp @@ -57,7 +57,7 @@ public: datasource::datasource_t type() const; static const char * name(); featureset_ptr features(const query& q) const; - featureset_ptr features_at_point(coord2d const& pt) const; + featureset_ptr features_at_point(coord2d const& pt, double tol = 0) const; box2d envelope() const; boost::optional get_geometry_type() const; layer_descriptor get_descriptor() const; diff --git a/plugins/input/sqlite/sqlite_datasource.cpp b/plugins/input/sqlite/sqlite_datasource.cpp index 1b769af53..eea779c92 100644 --- a/plugins/input/sqlite/sqlite_datasource.cpp +++ b/plugins/input/sqlite/sqlite_datasource.cpp @@ -632,7 +632,7 @@ featureset_ptr sqlite_datasource::features(query const& q) const return featureset_ptr(); } -featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const +featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt, double tol) const { if (! is_bound_) bind(); diff --git a/plugins/input/sqlite/sqlite_datasource.hpp b/plugins/input/sqlite/sqlite_datasource.hpp index f54eb4c22..c87d94d04 100644 --- a/plugins/input/sqlite/sqlite_datasource.hpp +++ b/plugins/input/sqlite/sqlite_datasource.hpp @@ -53,7 +53,7 @@ public: datasource::datasource_t type() const; static const char * name(); mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; mapnik::box2d envelope() const; boost::optional get_geometry_type() const; mapnik::layer_descriptor get_descriptor() const; diff --git a/plugins/input/templates/helloworld/hello_datasource.cpp b/plugins/input/templates/helloworld/hello_datasource.cpp index 897b40829..9b9b4437a 100644 --- a/plugins/input/templates/helloworld/hello_datasource.cpp +++ b/plugins/input/templates/helloworld/hello_datasource.cpp @@ -82,7 +82,7 @@ mapnik::featureset_ptr hello_datasource::features(mapnik::query const& q) const return mapnik::featureset_ptr(); } -mapnik::featureset_ptr hello_datasource::features_at_point(mapnik::coord2d const& pt) const +mapnik::featureset_ptr hello_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const { if (!is_bound_) bind(); diff --git a/plugins/input/templates/helloworld/hello_datasource.hpp b/plugins/input/templates/helloworld/hello_datasource.hpp index b7e3dfbbc..969c07332 100644 --- a/plugins/input/templates/helloworld/hello_datasource.hpp +++ b/plugins/input/templates/helloworld/hello_datasource.hpp @@ -39,7 +39,7 @@ public: // mandatory: function to query features by point (coord2d) // not used by rendering, but available to calling applications - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const; + mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; // mandatory: return the box2d of the datasource // called during rendering to determine if the layer should be processed diff --git a/src/map.cpp b/src/map.cpp index 5c27fd5f0..3a5219955 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -548,24 +548,24 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const { throw std::runtime_error("query_point: could not project x,y into layer srs"); } - // TODO - pass tolerance to features_at_point as well - featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y)); + // calculate default tolerance + mapnik::box2d map_ex = current_extent_; + if (maximum_extent_) + { + map_ex.clip(*maximum_extent_); + } + if (!prj_trans.backward(map_ex,PROJ_ENVELOPE_POINTS)) + { + std::ostringstream s; + s << "query_point: could not project map extent '" << map_ex + << "' into layer srs for tolerance calculation"; + throw std::runtime_error(s.str()); + } + double tol = (map_ex.maxx() - map_ex.minx()) / width_ * 3; + featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y), tol); + MAPNIK_LOG_DEBUG(map) << "map: Query at point tol=" << tol << "(" << x << "," << y << ")"; if (fs) { - mapnik::box2d map_ex = current_extent_; - if (maximum_extent_) - { - map_ex.clip(*maximum_extent_); - } - if (!prj_trans.backward(map_ex,PROJ_ENVELOPE_POINTS)) - { - std::ostringstream s; - s << "query_point: could not project map extent '" << map_ex - << "' into layer srs for tolerance calculation"; - throw std::runtime_error(s.str()); - } - double tol = (map_ex.maxx() - map_ex.minx()) / width_ * 3; - MAPNIK_LOG_DEBUG(map) << "map: Query at point tol=" << tol << "(" << x << "," << y << ")"; return boost::make_shared >(fs, hit_test_filter(x,y,tol)); } diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp index 8bee607ac..0549a92d0 100644 --- a/src/memory_datasource.cpp +++ b/src/memory_datasource.cpp @@ -86,7 +86,7 @@ featureset_ptr memory_datasource::features(const query& q) const } -featureset_ptr memory_datasource::features_at_point(coord2d const& pt) const +featureset_ptr memory_datasource::features_at_point(coord2d const& pt, double tol) const { box2d box = box2d(pt.x, pt.y, pt.x, pt.y);