Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updating with code from JIT Datasource

  • Loading branch information...
commit 54c0a7e7aba702fae4835f7c6135fd9ec1ddab74 1 parent 24a065e
@tmcw tmcw authored
View
14 geojson_datasource.cpp
@@ -27,7 +27,7 @@ geojson_datasource::geojson_datasource(parameters const& params, bool bind)
file_(*params_.get<std::string>("file","")),
extent_()
{
- if (file_.empty()) throw mapnik::datasource_exception("JIT Plugin: missing <file> parameter");
+ if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");
if (bind)
{
this->bind();
@@ -54,11 +54,19 @@ std::string geojson_datasource::name()
return name_;
}
-int geojson_datasource::type() const
-{
+
+boost::optional<mapnik::datasource::geometry_t> geojson_datasource::get_geometry_type() const {
+ return boost::optional<mapnik::datasource::geometry_t>();
+}
+
+mapnik::datasource::datasource_t geojson_datasource::type() const {
return type_;
}
+std::map<std::string, mapnik::parameters> geojson_datasource::get_statistics() const {
+ return statistics_;
+}
+
// FIXME: implement
mapnik::box2d<double> geojson_datasource::envelope() const
{
View
7 geojson_datasource.hpp
@@ -12,19 +12,22 @@ class geojson_datasource : public mapnik::datasource
// constructor
geojson_datasource(mapnik::parameters const& params, bool bind=true);
virtual ~geojson_datasource ();
- int type() const;
+ mapnik::datasource::datasource_t type() const;
static std::string name();
mapnik::featureset_ptr features(mapnik::query const& q) const;
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
mapnik::box2d<double> envelope() const;
mapnik::layer_descriptor get_descriptor() const;
+ std::map<std::string, mapnik::parameters> get_statistics() const;
+ boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
void bind() const;
private:
// recommended naming convention of datasource members:
// name_, type_, extent_, and desc_
static const std::string name_;
- int type_;
+ mapnik::datasource::datasource_t type_;
+ mutable std::map<std::string, mapnik::parameters> statistics_;
mutable mapnik::layer_descriptor desc_;
mutable std::string file_;
mutable mapnik::box2d<double> extent_;
View
294 geojson_featureset.cpp
@@ -1,166 +1,145 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2011 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
+ *
+ *****************************************************************************/
// mapnik
#include <mapnik/feature_factory.hpp>
#include <mapnik/geometry.hpp>
+#include <mapnik/util/geometry_to_wkt.hpp>
-#include <fstream>
-#include <iostream>
+#include <string>
+#include <vector>
+// yajl
#include "yajl/yajl_parse.h"
-
#include "geojson_featureset.hpp"
+#ifdef MAPNIK_DEBUG
+#include <mapnik/timer.hpp>
+#include <iomanip>
+#include <sstream>
+#endif
+
mapnik::transcoder* tr = new mapnik::transcoder("utf-8");
-static int gj_start_map(void * ctx)
-{
+static int gj_start_map(void * ctx) {
return 1;
}
-static int gj_map_key(void * ctx, const unsigned char* key, size_t t)
-{
+static int gj_map_key(void * ctx, const unsigned char* key, size_t t) {
std::string key_ = std::string((const char*) key, t);
- if (((fm *) ctx)->state == parser_in_properties)
- {
- ((fm *) ctx)->property_name = key_;
- }
- else
- {
- if (key_ == "features")
- {
- ((fm *) ctx)->state = parser_in_features;
- }
- else if (key_ == "geometry")
- {
- ((fm *) ctx)->state = parser_in_geometry;
- }
- else if ((((fm *) ctx)->state == parser_in_geometry) && (key_ == "type"))
- {
- ((fm *) ctx)->state = parser_in_type;
- }
- else if (key_ == "properties")
- {
- ((fm *) ctx)->state = parser_in_properties;
- }
- else if (key_ == "coordinates")
- {
- ((fm *) ctx)->state = parser_in_coordinates;
+ pstate *cs = static_cast<pstate*>(ctx);
+ if (cs->state == parser_in_properties) {
+ cs->property_name = key_;
+ } else {
+ if (key_ == "features") {
+ cs->state = parser_in_features;
+ } else if (key_ == "geometry") {
+ cs->state = parser_in_geometry;
+ } else if ((cs->state == parser_in_geometry) &&
+ (key_ == "type")) {
+ cs->state = parser_in_type;
+ } else if (key_ == "properties") {
+ cs->state = parser_in_properties;
+ } else if (key_ == "coordinates") {
+ cs->state = parser_in_coordinates;
}
}
return 1;
}
-static int gj_end_map(void * ctx)
-{
- if ((((fm *) ctx)->state == parser_in_properties) ||
- (((fm *) ctx)->state == parser_in_geometry))
- {
- ((fm *) ctx)->state = parser_in_feature;
- }
- else if (((fm *) ctx)->state == parser_in_feature)
- {
- if (((fm *) ctx)->geometry_type == "Point")
- {
- mapnik::geometry_type * pt;
- pt = new mapnik::geometry_type(mapnik::Point);
- pt->move_to(
- ((fm *) ctx)->point_cache.at(0),
- ((fm *) ctx)->point_cache.at(1));
- ((fm *) ctx)->feature->add_geometry(pt);
- }
- if (((fm *) ctx)->geometry_type == "LineString")
- {
- mapnik::geometry_type * pt;
- pt = new mapnik::geometry_type(mapnik::LineString);
-
- pt->set_capacity(((fm *) ctx)->point_cache.size() / 2);
- pt->move_to(
- ((fm *) ctx)->point_cache.at(0),
- ((fm *) ctx)->point_cache.at(1));
+static int gj_end_map(void * ctx) {
+ pstate *cs = static_cast<pstate*>(ctx);
- for (int i = 2; i < ((fm *) ctx)->point_cache.size(); i += 2) {
- pt->line_to(
- ((fm *) ctx)->point_cache.at(i),
- ((fm *) ctx)->point_cache.at(i + 1));
- }
- ((fm *) ctx)->feature->add_geometry(pt);
- }
- ((fm *) ctx)->state = parser_in_features;
- ((fm *) ctx)->done = 1;
+ if ((cs->state == parser_in_properties) ||
+ (cs->state == parser_in_geometry)) {
+ cs->state = parser_in_feature;
+ } else if (cs->state == parser_in_feature) {
+ cs->state = parser_in_features;
+ cs->done = 1;
}
return 1;
}
-static int gj_null(void * ctx)
-{
- if (((fm *) ctx)->state == parser_in_properties)
- {
- boost::put(*((fm *) ctx)->feature, ((fm *) ctx)->property_name, mapnik::value_null());
+static int gj_null(void * ctx) {
+ pstate *cs = static_cast<pstate*>(ctx);
+ if (cs->state == parser_in_properties) {
+ boost::put(*(cs->feature),
+ cs->property_name, mapnik::value_null());
}
return 1;
}
-static int gj_boolean(void * ctx, int x)
-{
- if (((fm *) ctx)->state == parser_in_properties)
- {
- boost::put(*((fm *) ctx)->feature, ((fm *) ctx)->property_name, x);
+static int gj_boolean(void * ctx, int x) {
+ pstate *cs = static_cast<pstate*>(ctx);
+ if (cs->state == parser_in_properties) {
+ boost::put(*(cs->feature), cs->property_name, x);
}
return 1;
}
-static int gj_number(void * ctx, const char* str, size_t t)
-{
- std::string str_ = std::string((const char*) str, t);
- double x = boost::lexical_cast<double>(str_);
+static int gj_number(void * ctx, const char* str, size_t t) {
+ pstate *cs = static_cast<pstate*>(ctx);
+ double x = strtod(str, NULL);
- if (((fm *) ctx)->state == parser_in_coordinates)
- {
- ((fm *) ctx)->point_cache.push_back(x);
- }
- if (((fm *) ctx)->state == parser_in_properties)
- {
- boost::put(*((fm *) ctx)->feature, ((fm *) ctx)->property_name, x);
+ if (cs->state == parser_in_coordinates) {
+ cs->point_cache.push_back(x);
+ } else if (cs->state == parser_in_properties) {
+ boost::put(*(cs->feature), cs->property_name, x);
}
return 1;
}
-static int gj_string(void * ctx, const unsigned char* str, size_t t)
-{
+static int gj_string(void * ctx, const unsigned char* str, size_t t) {
+ pstate *cs = static_cast<pstate*>(ctx);
std::string str_ = std::string((const char*) str, t);
- if (((fm *) ctx)->state == parser_in_type)
- {
- ((fm *) ctx)->geometry_type = str_;
- }
- else if (((fm *) ctx)->state == parser_in_properties)
- {
+ if (cs->state == parser_in_type) {
+ // TODO: change geometry type at this point
+ cs->geometry_type = str_;
+ } else if (cs->state == parser_in_properties) {
UnicodeString ustr = tr->transcode(str_.c_str());
- boost::put(*((fm *) ctx)->feature, ((fm *) ctx)->property_name, ustr);
+ boost::put(*(cs->feature), cs->property_name, ustr);
}
return 1;
}
-static int gj_start_array(void * ctx)
-{
- if (((fm *) ctx)->state == parser_in_coordinates)
- {
- ((fm *) ctx)->coord_dimensions++;
+static int gj_start_array(void * ctx) {
+ pstate *cs = static_cast<pstate*>(ctx);
+ if (cs->state == parser_in_coordinates) {
+ cs->coord_dimensions++;
}
return 1;
}
-static int gj_end_array(void * ctx)
-{
- if (((fm *) ctx)->state == parser_in_coordinates)
- {
- ((fm *) ctx)->coord_dimensions--;
- if (((fm *) ctx)->coord_dimensions < 1)
- {
- ((fm *) ctx)->state = parser_in_geometry;
+static int gj_end_array(void * ctx) {
+ pstate *cs = static_cast<pstate*>(ctx);
+ if (cs->state == parser_in_coordinates) {
+ cs->coord_dimensions--;
+ cs->feature->get_geometry(0).move_to(
+ cs->point_cache.at(0),
+ cs->point_cache.at(1));
+ if (cs->coord_dimensions < 1) {
+ cs->state = parser_in_geometry;
}
- }
- else if (((fm *) ctx)->state == parser_in_features)
- {
- ((fm *) ctx)->state = parser_outside;
+ } else if (cs->state == parser_in_features) {
+ cs->state = parser_outside;
}
return 1;
}
@@ -181,90 +160,79 @@ static yajl_callbacks callbacks = {
geojson_featureset::geojson_featureset(
mapnik::box2d<double> const& box,
- std::string const& encoding,
- std::string const& file)
+ std::string input_string,
+ std::string const& encoding)
: box_(box),
feature_id_(1),
- file_length_(0),
- file_(file),
- itt_(0),
- tr_(new mapnik::transcoder(encoding)) {
-
- std::ifstream in_(file_.c_str(), std::ios_base::in | std::ios_base::binary);
+ input_string_(input_string),
+ tr_(new mapnik::transcoder(encoding)),
+ features_(),
+ itt_(),
+ hand() {
- if (!in_.is_open()) {
- throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + file_ + "'");
- }
-
- in_.seekg(0, std::ios::end);
- file_length_ = in_.tellg();
- in_.seekg(0, std::ios::beg);
+ struct pstate state_bundle;
state_bundle.state = parser_outside;
state_bundle.done = 0;
- // FIXME: manually free
hand = yajl_alloc(
&callbacks, NULL,
&state_bundle);
yajl_config(hand, yajl_allow_comments, 1);
-
- std::getline(in_, input_buffer_);
-
+ yajl_config(hand, yajl_allow_trailing_garbage, 1);
mapnik::feature_ptr feature(mapnik::feature_factory::create(feature_id_));
-
+ // This is just a stand-in geometry whose type can be changed later.
+ mapnik::geometry_type * pt;
+ pt = new mapnik::geometry_type(mapnik::LineString);
+ feature->add_geometry(pt);
state_bundle.feature = feature;
- for (; itt_ < input_buffer_.length(); itt_++) {
-
- int parse_result;
-
+ int parse_result;
+ for (itt_ = 0; itt_ < input_string_.length(); itt_++) {
parse_result = yajl_parse(hand,
- (const unsigned char*) &input_buffer_[itt_],
- 1);
-
- if (parse_result == yajl_status_error)
- {
- //char* s;
- //unsigned char *str = yajl_get_error(hand, 1, (const unsigned char*) s, strlen(s));
- // throw mapnik::datasource_exception("GeoJSON Plugin: invalid GeoJSON detected:" +
- // std::string((const char*) str));
- throw mapnik::datasource_exception("GeoJSON Plugin: invalid GeoJSON detected");
- // yajl_free_error(hand, str);
- }
- else if (state_bundle.done == 1)
- {
+ (const unsigned char*) &input_string_[itt_], 1);
+
+ if (parse_result == yajl_status_error) {
+ unsigned char *str = yajl_get_error(hand,
+ 1, (const unsigned char*) input_string_.c_str(),
+ input_string_.length());
+ std::ostringstream errmsg;
+ errmsg << "GeoJSON Plugin: invalid GeoJSON detected: " << (const char*) str << "\n";
+ yajl_free_error(hand, str);
+ throw mapnik::datasource_exception(errmsg.str());
+ } else if (state_bundle.done == 1) {
features_.push_back(state_bundle.feature);
feature_id_++;
- mapnik::feature_ptr feature(mapnik::feature_factory::create(feature_id_));
+ mapnik::feature_ptr
+ feature(mapnik::feature_factory::create(feature_id_));
+
+ // This is just a stand-in geometry whose type can be changed later.
+ mapnik::geometry_type * pt;
+ pt = new mapnik::geometry_type(mapnik::LineString);
+ feature->add_geometry(pt);
// reset
state_bundle.point_cache.clear();
state_bundle.done = 0;
state_bundle.geometry_type = "";
state_bundle.feature = feature;
-
}
-
}
+ yajl_free(hand);
feature_id_ = 0;
}
geojson_featureset::~geojson_featureset() { }
-mapnik::feature_ptr geojson_featureset::next()
-{
+mapnik::feature_ptr geojson_featureset::next() {
feature_id_++;
- if (feature_id_ <= features_.size())
- {
+ if (feature_id_ <= features_.size()) {
return features_.at(feature_id_ - 1);
- }
- else
- {
+ } else {
return mapnik::feature_ptr();
}
}
View
51 geojson_featureset.hpp
@@ -1,16 +1,9 @@
#ifndef GEOJSON_FEATURESET_HPP
#define GEOJSON_FEATURESET_HPP
-#include <fstream>
-
-// mapnik
#include <mapnik/datasource.hpp>
#include "yajl/yajl_parse.h"
-
-// boost
-#include <boost/scoped_ptr.hpp> // needed for wrapping the transcoder
-
-// stl
+#include <boost/scoped_ptr.hpp>
#include <vector>
enum parser_state {
@@ -25,42 +18,42 @@ enum parser_state {
parser_in_type
};
-struct fm {
- mapnik::feature_ptr feature;
+struct pstate {
int done;
int coord_dimensions;
std::string property_name;
std::string geometry_type;
- mutable std::vector<double> point_cache;
+ mapnik::feature_ptr feature;
+ std::vector< double > point_cache;
parser_state state;
+ pstate() :
+ done(0),
+ coord_dimensions(0),
+ property_name(""),
+ geometry_type(""),
+ feature(),
+ point_cache(),
+ state()
+ { };
};
-// extend the mapnik::Featureset defined in include/mapnik/datasource.hpp
class geojson_featureset : public mapnik::Featureset
{
public:
geojson_featureset(mapnik::box2d<double> const& box,
- std::string const& encoding,
- std::string const& file);
+ std::string input_string,
+ std::string const& encoding);
virtual ~geojson_featureset();
mapnik::feature_ptr next();
-private:
- mapnik::box2d<double> const& box_;
- mutable int feature_id_;
- mutable int file_length_;
+private:
+ mapnik::box2d<double> box_;
+ mutable unsigned int feature_id_;
+ mutable std::string input_string_;
+ boost::shared_ptr<mapnik::transcoder> tr_;
mutable std::vector<mapnik::feature_ptr> features_;
-
- mutable std::ifstream in_;
- mutable std::string file_;
-
- // parsing related
- mutable std::string input_buffer_;
- int itt_;
+ unsigned itt_;
yajl_handle hand;
- fm state_bundle;
-
- boost::scoped_ptr<mapnik::transcoder> tr_;
};
-#endif // HELLO_FEATURESET_HPP
+#endif // GEOJSON_FEATURESET_HPP
Please sign in to comment.
Something went wrong with that request. Please try again.