diff --git a/plugins/input/geos/geos_converter.cpp b/plugins/input/geos/geos_converter.cpp index 339cffea1..b067e4d45 100644 --- a/plugins/input/geos/geos_converter.cpp +++ b/plugins/input/geos/geos_converter.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -90,6 +90,10 @@ void geos_converter::convert_geometry (const GEOSGeometry* geom, feature_ptr fea void geos_converter::convert_point (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_point" << endl; +#endif + double x, y; unsigned int size; @@ -106,6 +110,10 @@ void geos_converter::convert_point (const GEOSGeometry* geom, feature_ptr featur void geos_converter::convert_linestring (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_linestring" << endl; +#endif + double x, y; unsigned int num_points; @@ -130,6 +138,10 @@ void geos_converter::convert_linestring (const GEOSGeometry* geom, feature_ptr f void geos_converter::convert_polygon (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_polygon" << endl; +#endif + double x, y; unsigned int num_points, num_interior; @@ -186,6 +198,10 @@ void geos_converter::convert_polygon (const GEOSGeometry* geom, feature_ptr feat void geos_converter::convert_multipoint (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multipoint" << endl; +#endif + unsigned int num_geometries = GEOSGetNumGeometries(geom); geometry_type* point = new geometry_type(mapnik::Point); @@ -211,6 +227,10 @@ void geos_converter::convert_multipoint (const GEOSGeometry* geom, feature_ptr f void geos_converter::convert_multipoint_2 (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multipoint_2" << endl; +#endif + unsigned int num_geometries = GEOSGetNumGeometries(geom); for (unsigned int i = 0; i < num_geometries; ++i) @@ -226,6 +246,10 @@ void geos_converter::convert_multipoint_2 (const GEOSGeometry* geom, feature_ptr void geos_converter::convert_multilinestring (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multilinestring" << endl; +#endif + double x, y; unsigned int num_points = 0; @@ -279,6 +303,10 @@ void geos_converter::convert_multilinestring (const GEOSGeometry* geom, feature_ void geos_converter::convert_multilinestring_2 (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multilinestring_2" << endl; +#endif + unsigned int num_geometries = GEOSGetNumGeometries(geom); for (unsigned int i = 0; i < num_geometries; ++i) @@ -294,6 +322,10 @@ void geos_converter::convert_multilinestring_2 (const GEOSGeometry* geom, featur void geos_converter::convert_multipolygon (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multipolygon" << endl; +#endif + double x, y; unsigned int num_points, num_interior; unsigned int capacity = 0; @@ -377,6 +409,10 @@ void geos_converter::convert_multipolygon (const GEOSGeometry* geom, feature_ptr void geos_converter::convert_multipolygon_2 (const GEOSGeometry* geom, feature_ptr feature) { +#ifdef MAPNIK_DEBUG + clog << "convert_multipolygon_2" << endl; +#endif + unsigned int num_geometries = GEOSGetNumGeometries(geom); for (unsigned int i = 0; i < num_geometries; ++i) @@ -392,6 +428,10 @@ void geos_converter::convert_multipolygon_2 (const GEOSGeometry* geom, feature_p void geos_converter::convert_collection (const GEOSGeometry* geom, feature_ptr feature, bool multiple_geometries) { +#ifdef MAPNIK_DEBUG + clog << "convert_collection" << endl; +#endif + unsigned int num_geometries = GEOSGetNumGeometries(geom); for (unsigned int i = 0; i < num_geometries; ++i) diff --git a/plugins/input/geos/geos_converter.hpp b/plugins/input/geos/geos_converter.hpp index 7e0033eb1..4bab17e39 100644 --- a/plugins/input/geos/geos_converter.hpp +++ b/plugins/input/geos/geos_converter.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/plugins/input/geos/geos_datasource.cpp b/plugins/input/geos/geos_datasource.cpp index f6cd1dbcb..fdca4c773 100644 --- a/plugins/input/geos/geos_datasource.cpp +++ b/plugins/input/geos/geos_datasource.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -96,7 +96,7 @@ geos_datasource::geos_datasource(parameters const& params, bool bind) { boost::optional geometry = params.get("wkt"); if (!geometry) throw datasource_exception("missing parameter"); - geometry_ = *geometry; + geometry_string_ = *geometry; multiple_geometries_ = *params_.get("multiple_geometries",false); @@ -110,7 +110,17 @@ geos_datasource::~geos_datasource() { if (is_bound_) { + geometry_.set_feature(0); + +#ifdef MAPNIK_DEBUG + clog << "finalizing GEOS..."; +#endif + finishGEOS(); + +#ifdef MAPNIK_DEBUG + clog << " finalized !" << endl; +#endif } } @@ -118,9 +128,33 @@ void geos_datasource::bind() const { if (is_bound_) return; +#ifdef MAPNIK_DEBUG + clog << "initializing GEOS..."; +#endif + // open ogr driver initGEOS(notice, log_and_exit); +#ifdef MAPNIK_DEBUG + clog << " initialized !" << endl; +#endif + + // parse the string into geometry + geometry_.set_feature(GEOSGeomFromWKT(geometry_string_.c_str())); + + if (*geometry_ == NULL || ! GEOSisValid(*geometry_)) + { + //char* reason = GEOSisValidReason(*geometry_); + //std::string reason_string (reason); + //GEOSFree(reason); + + throw datasource_exception("invalid geometry specified"); + } + +#ifdef MAPNIK_DEBUG + clog << "geometry correctly parsed" << endl; +#endif + // initialize envelope boost::optional ext = params_.get("extent"); if (ext) @@ -159,7 +193,29 @@ void geos_datasource::bind() const if (!extent_initialized_) { - // TODO - build the geometry here and compute the extent? + geos_feature_ptr envelope (GEOSEnvelope(*geometry_)); + + if (*envelope != NULL) + { + const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq(*envelope); + if (cs != NULL) + { + double x, y; + unsigned int num_points; + + GEOSCoordSeq_getSize(cs, &num_points); + + for (unsigned int i = 0; i < num_points; ++i) + { + GEOSCoordSeq_getX(cs, i, &x); + GEOSCoordSeq_getY(cs, i, &y); + + clog << x << " " << y << endl; + } + + extent_initialized_ = true; + } + } } is_bound_ = true; @@ -196,14 +252,18 @@ featureset_ptr geos_datasource::features(query const& q) const std::ostringstream s; s << "POLYGON(" << extent.minx() << " " << extent.miny() << "," - << extent.minx() << " " << extent.maxy() << "," - << extent.maxx() << " " << extent.maxy() << "," << extent.maxx() << " " << extent.miny() << "," + << extent.maxx() << " " << extent.maxy() << "," + << extent.minx() << " " << extent.maxy() << "," << extent.minx() << " " << extent.miny() << ")"; - return featureset_ptr(new geos_featureset (geometry_, - s.str(), +#ifdef MAPNIK_DEBUG + clog << "using extent: " << s.str() << endl; +#endif + + return featureset_ptr(new geos_featureset (*geometry_, + GEOSGeomFromWKT(s.str().c_str()), desc_.get_encoding(), multiple_geometries_)); } @@ -215,8 +275,12 @@ featureset_ptr geos_datasource::features_at_point(coord2d const& pt) const std::ostringstream s; s << "POINT(" << pt.x << " " << pt.y << ")"; - return featureset_ptr(new geos_featureset (geometry_, - s.str(), +#ifdef MAPNIK_DEBUG + clog << "using point: " << s.str() << endl; +#endif + + return featureset_ptr(new geos_featureset (*geometry_, + GEOSGeomFromWKT(s.str().c_str()), desc_.get_encoding(), multiple_geometries_)); } diff --git a/plugins/input/geos/geos_datasource.hpp b/plugins/input/geos/geos_datasource.hpp index 0d14fa08c..cc7fdef49 100644 --- a/plugins/input/geos/geos_datasource.hpp +++ b/plugins/input/geos/geos_datasource.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,6 +32,8 @@ // boost #include +#include "geos_feature_ptr.hpp" + class geos_datasource : public mapnik::datasource { public: @@ -49,7 +51,8 @@ private: mutable bool extent_initialized_; int type_; mutable mapnik::layer_descriptor desc_; - mutable std::string geometry_; + mutable geos_feature_ptr geometry_; + std::string geometry_string_; bool multiple_geometries_; }; diff --git a/plugins/input/geos/geos_feature_ptr.hpp b/plugins/input/geos/geos_feature_ptr.hpp index 502a1d7c6..42d9e9976 100644 --- a/plugins/input/geos/geos_feature_ptr.hpp +++ b/plugins/input/geos/geos_feature_ptr.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,11 @@ class geos_feature_ptr { public: + geos_feature_ptr () + : feat_ (NULL) + { + } + explicit geos_feature_ptr (GEOSGeometry* const feat) : feat_ (feat) { @@ -41,6 +46,14 @@ public: GEOSGeom_destroy(feat_); } + void set_feature (GEOSGeometry* const feat) + { + if (feat_ != NULL) + GEOSGeom_destroy(feat_); + + feat_ = feat; + } + GEOSGeometry* operator*() { return feat_; diff --git a/plugins/input/geos/geos_featureset.cpp b/plugins/input/geos/geos_featureset.cpp index 952260097..07f628868 100644 --- a/plugins/input/geos/geos_featureset.cpp +++ b/plugins/input/geos/geos_featureset.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,14 +51,15 @@ using mapnik::geometry_utils; using mapnik::transcoder; -geos_featureset::geos_featureset(const std::string& geometry, - const std::string& extent, +geos_featureset::geos_featureset(GEOSGeometry* geometry, + GEOSGeometry* extent, const std::string& encoding, const bool multiple_geometries) : geometry_(geometry), tr_(new transcoder(encoding)), + extent_(extent), multiple_geometries_(multiple_geometries), - extent_(GEOSGeomFromWKT(extent.c_str())) + already_rendered_(false) { } @@ -66,22 +67,23 @@ geos_featureset::~geos_featureset() {} feature_ptr geos_featureset::next() { - geos_feature_ptr feat (GEOSGeomFromWKT(geometry_.c_str())); - if ((*feat) != NULL) - { - GEOSGeometry* geom = (*feat); - GEOSGeometry* extent = (*extent_); - - if (GEOSisValid(geom) && GEOSisValid(extent) && GEOSWithin(geom, extent)) - { - feature_ptr feature(new Feature(0)); + if (! already_rendered_) + { + already_rendered_ = true; + + if (GEOSisValid(geometry_) && ! GEOSisEmpty(geometry_)) + { + //if (*extent_ != NULL && GEOSWithin(geometry_, *extent_)) + { + feature_ptr feature(new Feature(0)); - geos_converter::convert_geometry (geom, feature, multiple_geometries_); - - return feature; - } - } + geos_converter::convert_geometry (geometry_, feature, multiple_geometries_); + + return feature; + } + } + } - return feature_ptr(); + return feature_ptr(); } diff --git a/plugins/input/geos/geos_featureset.hpp b/plugins/input/geos/geos_featureset.hpp index f08dadcd0..20fe35001 100644 --- a/plugins/input/geos/geos_featureset.hpp +++ b/plugins/input/geos/geos_featureset.hpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2007 Artem Pavlenko + * Copyright (C) 2010 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -40,19 +40,20 @@ class geos_featureset : public mapnik::Featureset { public: - geos_featureset(const std::string& geometry, - const std::string& extent, + geos_featureset(GEOSGeometry* geometry, + GEOSGeometry* extent, const std::string& encoding, const bool multiple_geometries); virtual ~geos_featureset(); mapnik::feature_ptr next(); private: - std::string geometry_; + GEOSGeometry* geometry_; boost::scoped_ptr tr_; - bool multiple_geometries_; - geos_feature_ptr extent_; + bool multiple_geometries_; + bool already_rendered_; + geos_featureset(const geos_featureset&); const geos_featureset& operator=(const geos_featureset&);