implemented query_map_point method on map object:

fs = m.query_map_point(x,y)  # Map (screen) coordinates
   for feature in fs:
       print feature

TODO: provide interface to feature in Python, at the moment only __str__ implemented which dumps attributes
This commit is contained in:
Artem Pavlenko 2006-12-06 20:26:59 +00:00
parent 258b91fad2
commit af44541598
14 changed files with 485 additions and 32 deletions

View File

@ -27,7 +27,6 @@
#include <sstream>
// mapnik
#include <mapnik/envelope.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/feature_layer_desc.hpp>
@ -69,38 +68,11 @@ namespace
}
}
inline object pass_through(object const& o) { return o; }
inline mapnik::feature_ptr next(mapnik::featureset_ptr const& itr)
{
mapnik::feature_ptr f = itr->next();
if (!f)
{
PyErr_SetString(PyExc_StopIteration, "No more features.");
boost::python::throw_error_already_set();
}
return f;
}
void export_datasource()
{
using namespace boost::python;
using mapnik::datasource;
using mapnik::Featureset;
using mapnik::Feature;
class_<Feature,boost::shared_ptr<Feature>,
boost::noncopyable>("Feature",no_init)
.def("id",&Feature::id)
.def("__str__",&Feature::to_string)
;
class_<Featureset,boost::shared_ptr<Featureset>,
boost::noncopyable>("Datasource",no_init)
.def("next",next)
.def("__iter__",pass_through)
;
class_<datasource,boost::shared_ptr<datasource>,
boost::noncopyable>("Datasource",no_init)
.def("envelope",&datasource::envelope)

View File

@ -0,0 +1,39 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp>
// mapnik
#include <mapnik/feature.hpp>
void export_feature()
{
using namespace boost::python;
using mapnik::Feature;
class_<Feature,boost::shared_ptr<Feature>,
boost::noncopyable>("Feature",no_init)
.def("id",&Feature::id)
//.def("__iter__", range<>())
.def("__str__",&Feature::to_string)
;
}

View File

@ -0,0 +1,58 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp>
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
namespace {
using namespace boost::python;
inline object pass_through(object const& o) { return o; }
inline mapnik::feature_ptr next(mapnik::featureset_ptr const& itr)
{
mapnik::feature_ptr f = itr->next();
if (!f)
{
PyErr_SetString(PyExc_StopIteration, "No more features.");
boost::python::throw_error_already_set();
}
return f;
}
}
void export_featureset()
{
using namespace boost::python;
using mapnik::Feature;
using mapnik::Featureset;
class_<Featureset,boost::shared_ptr<Featureset>,
boost::noncopyable>("Featureset",no_init)
.def("next",next)
.def("__iter__",pass_through)
;
}

View File

@ -110,6 +110,7 @@ void export_map()
.def("pan_and_zoom",&Map::pan_and_zoom)
.def("append_style",&Map::insert_style)
.def("remove_style",&Map::remove_style)
.def("query_map_point",&Map::query_map_point)
.add_property("layers",make_function
(layers_nonconst,return_value_policy<reference_existing_object>()),
"Get the list of layers in this map.")

View File

@ -39,6 +39,8 @@ void export_filter();
void export_rule();
void export_style();
void export_stroke();
void export_feature();
void export_featureset();
void export_datasource();
void export_datasource_cache();
void export_point_symbolizer();
@ -97,6 +99,8 @@ BOOST_PYTHON_MODULE(_mapnik)
using mapnik::save_map;
export_query();
export_feature();
export_featureset();
export_datasource();
export_parameters();
export_color();
@ -124,6 +128,7 @@ BOOST_PYTHON_MODULE(_mapnik)
def("render_to_file",&render_to_file);
def("render_tile_to_file",&render_tile_to_file);
def("render",&render);
def("render",&render2);
def("load_map",&load_map,"load Map object from XML");

View File

@ -48,12 +48,14 @@ namespace mapnik {
public:
typedef T1 geometry_type;
typedef T2 raster_type;
private:
int id_;
geometry_type geom_;
raster_type raster_;
std::map<std::string,value> props_;
public:
typedef std::map<std::string,value>::iterator iterator;
explicit feature(int id)
: properties(props_),
id_(id),
@ -70,7 +72,7 @@ namespace mapnik {
{
return id_;
}
void set_geometry(geometry_type& geom)
{
geom_=geom;
@ -94,7 +96,17 @@ namespace mapnik {
{
return props_;
}
iterator begin() const
{
return props_.begin();
}
iterator end() const
{
return props_.end();
}
std::string to_string() const
{
std::stringstream ss;

View File

@ -0,0 +1,52 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <mapnik/datasource.hpp>
namespace mapnik {
template <typename T>
class filter_featureset : public Featureset
{
typedef T filter_type;
public:
filter_featureset(featureset_ptr fs, filter_type const& filter)
: fs_(fs), filter_(filter) {}
feature_ptr next()
{
feature_ptr feature = fs_->next();
while (feature && !filter_.pass(*feature))
{
feature = fs_->next();
}
return feature;
}
private:
featureset_ptr fs_;
filter_type filter_;
};
}

View File

@ -0,0 +1,54 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#ifndef HIT_TEST_FILTER_HPP
#define HIT_TEST_FILTER_HPP
#include <mapnik/feature.hpp>
namespace mapnik {
class hit_test_filter
{
public:
hit_test_filter(double x, double y, double tol)
: x_(x),
y_(y),
tol_(tol) {}
bool pass(Feature const& feature)
{
geometry_ptr geom = feature.get_geometry();
if (geom && geom->hit_test(x_,y_,tol_))
return true;
return false;
}
private:
double x_;
double y_;
double tol_;
};
}
#endif // HIT_TEST_FILTER_HPP

View File

@ -25,6 +25,7 @@
#define MAP_HPP
#include <mapnik/feature_type_style.hpp>
#include <mapnik/datasource.hpp>
namespace mapnik
{
@ -79,6 +80,7 @@ namespace mapnik
const Envelope<double>& getCurrentExtent() const;
double scale() const;
CoordTransform view_transform() const;
featureset_ptr query_map_point(unsigned index, double x, double y) const;
~Map();
private:
void fixAspectRatio();

View File

@ -0,0 +1,51 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#ifndef MEMORY_DATASOURCE_HPP
#define MEMORY_DATASOURCE_HPP
#include <vector>
#include <mapnik/datasource.hpp>
namespace mapnik {
class memory_datasource : public datasource
{
friend class memory_featureset;
public:
memory_datasource();
virtual ~memory_datasource();
void push(feature_ptr feature);
int type() const;
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
Envelope<double> envelope() const;
layer_descriptor get_descriptor() const;
size_t size() const;
private:
std::vector<mapnik::feature_ptr> features_;
};
}
#endif // MEMORY_DATASOURCE_HPP

View File

@ -0,0 +1,63 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#ifndef MEMORY_FEATURESET_HPP
#define MEMORY_FEATURESET_HPP
#include <boost/utility.hpp>
#include <mapnik/memory_datasource.hpp>
namespace mapnik {
class memory_featureset : public Featureset, private boost::noncopyable
{
public:
memory_featureset(Envelope<double> const& bbox, memory_datasource const& ds)
: bbox_(bbox),
pos_(ds.features_.begin()),
end_(ds.features_.end())
{}
virtual ~memory_featureset() {}
feature_ptr next()
{
while (pos_ != end_)
{
geometry_ptr geom = (*pos_)->get_geometry();
if (geom && bbox_.intersects(geom->envelope()))
{
return *pos_++;
}
++pos_;
}
return feature_ptr();
}
private:
Envelope<double> const& bbox_;
std::vector<feature_ptr>::const_iterator pos_;
std::vector<feature_ptr>::const_iterator end_;
};
}
#endif // MEMORY_FEATURESET_HPP

View File

@ -60,6 +60,7 @@ source = Split(
proj_transform.cpp
distance.cpp
scale_denominator.cpp
memory_datasource.cpp
"""
)
source += Split(

View File

@ -26,6 +26,8 @@
#include <mapnik/datasource.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/filter_featureset.hpp>
#include <mapnik/hit_test_filter.hpp>
#include <mapnik/map.hpp>
namespace mapnik
@ -305,6 +307,52 @@ namespace mapnik
{
return CoordTransform(width_,height_,currentExtent_);
}
featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
{
if ( index< layers_.size())
{
mapnik::Layer const& layer = layers_[index];
CoordTransform tr = view_transform();
tr.backward(&x,&y);
try
{
mapnik::projection dest(srs_);
mapnik::projection source(layer.srs());
proj_transform prj_trans(source,dest);
double z;
prj_trans.backward(x,y,z);
double minx = currentExtent_.minx();
double miny = currentExtent_.miny();
double maxx = currentExtent_.maxx();
double maxy = currentExtent_.maxy();
prj_trans.backward(minx,miny,z);
prj_trans.backward(maxx,maxy,z);
double tol = (maxx - minx) / width_ * 3;
mapnik::datasource_ptr ds = layer.datasource();
if (ds)
{
#ifdef MAPNIK_DEBUG
std::clog << " query at point tol = " << tol << " (" << x << "," << y << ")\n";
#endif
featureset_ptr fs(new filter_featureset<hit_test_filter>(ds->features_at_point(mapnik::coord2d(x,y)),
hit_test_filter(x,y,tol)));
return fs;
}
}
catch (...)
{
#ifdef MAPNIK_DEBUG
std::clog << "exception caught in \"query_map_point\"\n";
#endif
}
}
return featureset_ptr();
}
Map::~Map() {}
}

95
src/memory_datasource.cpp Normal file
View File

@ -0,0 +1,95 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
//$Id$
#include <algorithm>
#include <mapnik/memory_featureset.hpp>
namespace mapnik {
struct accumulate_extent
{
accumulate_extent(Envelope<double> & ext)
: ext_(ext),first_(true) {}
void operator() (feature_ptr feat)
{
geometry_ptr geom = feat->get_geometry();
if ( !geom ) return;
if ( first_ )
{
first_ = false;
ext_ = geom->envelope();
}
else
{
ext_.expand_to_include(geom->envelope());
}
}
Envelope<double> & ext_;
bool first_;
};
memory_datasource::memory_datasource()
: datasource(parameters()) {}
memory_datasource::~memory_datasource() {}
void memory_datasource::push(feature_ptr feature)
{
features_.push_back(feature);
}
int memory_datasource::type() const
{
return datasource::Vector;
}
featureset_ptr memory_datasource::features(const query& q) const
{
return featureset_ptr(new memory_featureset(q.get_bbox(),*this));
}
featureset_ptr memory_datasource::features_at_point(coord2d const& pt) const
{
return featureset_ptr();
}
Envelope<double> memory_datasource::envelope() const
{
Envelope<double> ext;
accumulate_extent func(ext);
std::for_each(features_.begin(),features_.end(),func);
return ext;
}
layer_descriptor memory_datasource::get_descriptor() const
{
return layer_descriptor("in-memory datasource");
}
size_t memory_datasource::size() const
{
return features_.size();
}
}