- modified coding style in shape plugin

This commit is contained in:
kunitoki 2011-10-22 15:27:28 +02:00
parent c0273234b6
commit 2a4fe24ea9
7 changed files with 656 additions and 595 deletions

View file

@ -3,7 +3,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -21,15 +21,15 @@
* *
*****************************************************************************/ *****************************************************************************/
// stl
#include <iostream>
// mapnik // mapnik
#include <mapnik/feature_factory.hpp> #include <mapnik/feature_factory.hpp>
// boost // boost
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
// stl
#include <iostream>
#include "shape_featureset.hpp" #include "shape_featureset.hpp"
using mapnik::geometry_type; using mapnik::geometry_type;
@ -42,22 +42,23 @@ shape_featureset<filterT>::shape_featureset(const filterT& filter,
std::string const& encoding, std::string const& encoding,
long file_length, long file_length,
int row_limit) int row_limit)
: filter_(filter), : filter_(filter),
//shape_type_(shape_io::shape_null), //shape_type_(shape_io::shape_null),
shape_(shape_name, false), shape_(shape_name, false),
query_ext_(), query_ext_(),
tr_(new transcoder(encoding)), tr_(new transcoder(encoding)),
file_length_(file_length), file_length_(file_length),
count_(0), count_(0),
row_limit_(row_limit) row_limit_(row_limit)
{ {
shape_.shp().skip(100); shape_.shp().skip(100);
//attributes //attributes
typename std::set<std::string>::const_iterator pos=attribute_names.begin(); typename std::set<std::string>::const_iterator pos = attribute_names.begin();
while (pos!=attribute_names.end()) while (pos != attribute_names.end())
{ {
bool found_name = false; bool found_name = false;
for (int i=0;i<shape_.dbf().num_fields();++i) for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{ {
if (shape_.dbf().descriptor(i).name_ == *pos) if (shape_.dbf().descriptor(i).name_ == *pos)
{ {
@ -66,82 +67,89 @@ shape_featureset<filterT>::shape_featureset(const filterT& filter,
break; break;
} }
} }
if (!found_name)
if (! found_name)
{ {
std::ostringstream s; std::ostringstream s;
s << "no attribute '" << *pos << "' in '" s << "no attribute '" << *pos << "' in '"
<< shape_name << "'. Valid attributes are: "; << shape_name << "'. Valid attributes are: ";
std::vector<std::string> list; std::vector<std::string> list;
for (int i=0;i<shape_.dbf().num_fields();++i) for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{ {
list.push_back(shape_.dbf().descriptor(i).name_); list.push_back(shape_.dbf().descriptor(i).name_);
} }
s << boost::algorithm::join(list, ",") << "."; s << boost::algorithm::join(list, ",") << ".";
throw mapnik::datasource_exception( "Shape Plugin: " + s.str() ); throw mapnik::datasource_exception("Shape Plugin: " + s.str());
} }
++pos; ++pos;
} }
} }
template <typename filterT> template <typename filterT>
feature_ptr shape_featureset<filterT>::next() feature_ptr shape_featureset<filterT>::next()
{ {
if (row_limit_ && count_ > row_limit_) if (row_limit_ && count_ > row_limit_)
{
return feature_ptr(); return feature_ptr();
}
std::streampos pos = shape_.shp().pos();
std::streampos pos=shape_.shp().pos();
// skip null shapes // skip null shapes
while (pos > 0 && pos < std::streampos(file_length_ * 2)) while (pos > 0 && pos < std::streampos(file_length_ * 2))
{ {
shape_.move_to(pos); shape_.move_to(pos);
if (shape_.type() == shape_io::shape_null) if (shape_.type() == shape_io::shape_null)
{ {
pos += std::streampos(12); pos += std::streampos(12);
} }
else break; else
{
break;
}
} }
if (pos < std::streampos(file_length_ * 2)) if (pos < std::streampos(file_length_ * 2))
{ {
int type=shape_.type(); int type = shape_.type();
feature_ptr feature(feature_factory::create(shape_.id_)); feature_ptr feature(feature_factory::create(shape_.id_));
if (type == shape_io::shape_point) if (type == shape_io::shape_point)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointm) else if (type == shape_io::shape_pointm)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
shape_.shp().skip(8); //m // skip m
geometry_type * point = new geometry_type(mapnik::Point); shape_.shp().skip(8);
point->move_to(x,y); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointz) else if (type == shape_io::shape_pointz)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
// skip z // skip z
shape_.shp().skip(8); shape_.shp().skip(8);
// skip m if exists
//skip m if exists if (shape_.reclength_ == 8 + 36)
if ( shape_.reclength_ == 8 + 36)
{ {
shape_.shp().skip(8); shape_.shp().skip(8);
} }
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
@ -153,11 +161,19 @@ feature_ptr shape_featureset<filterT>::next()
std::streampos pos = shape_.shp().pos(); std::streampos pos = shape_.shp().pos();
if (shape_.type() == shape_io::shape_null) if (shape_.type() == shape_io::shape_null)
{ {
pos += std::streampos(12); pos += std::streampos(12);
// TODO handle the shapes
std::cerr << "NULL SHAPE len=" << shape_.reclength_ << std::endl; std::cerr << "NULL SHAPE len=" << shape_.reclength_ << std::endl;
} }
else if (filter_.pass(shape_.current_extent())) break; else if (filter_.pass(shape_.current_extent()))
else pos += std::streampos(2 * shape_.reclength_ - 36); {
break;
}
else
{
pos += std::streampos(2 * shape_.reclength_ - 36);
}
if (pos > 0 && pos < std::streampos(file_length_ * 2)) if (pos > 0 && pos < std::streampos(file_length_ * 2))
{ {
shape_.move_to(pos); shape_.move_to(pos);
@ -176,97 +192,104 @@ feature_ptr shape_featureset<filterT>::next()
case shape_io::shape_multipoint: case shape_io::shape_multipoint:
{ {
int num_points = shape_.shp().read_ndr_integer(); int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
} }
++count_; ++count_;
break; break;
} }
case shape_io::shape_multipointm: case shape_io::shape_multipointm:
{ {
int num_points = shape_.shp().read_ndr_integer(); int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
} }
// skip m // skip m
shape_.shp().skip(2*8 + 8*num_points); shape_.shp().skip(2 * 8 + 8 * num_points);
++count_; ++count_;
break; break;
} }
case shape_io::shape_multipointz: case shape_io::shape_multipointz:
{ {
unsigned num_points = shape_.shp().read_ndr_integer(); int num_points = shape_.shp().read_ndr_integer();
for (unsigned i=0; i< num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
} }
// skip z // skip z
shape_.shp().skip(2*8 + 8*num_points); shape_.shp().skip(2 * 8 + 8 * num_points);
// check if we have measure data // check if we have measure data
if (shape_.reclength_ == (unsigned)(num_points * 16 + 36))
if ( shape_.reclength_ == num_points * 16 + 36)
{ {
// skip m // skip m
shape_.shp().skip(2*8 + 8*num_points); shape_.shp().skip(2 * 8 + 8 * num_points);
} }
++count_; ++count_;
break; break;
} }
case shape_io::shape_polyline: case shape_io::shape_polyline:
{ {
geometry_type * line = shape_.read_polyline(); geometry_type* line = shape_.read_polyline();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinem: case shape_io::shape_polylinem:
{ {
geometry_type * line = shape_.read_polylinem(); geometry_type* line = shape_.read_polylinem();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinez: case shape_io::shape_polylinez:
{ {
geometry_type * line = shape_.read_polylinez(); geometry_type* line = shape_.read_polylinez();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygon: case shape_io::shape_polygon:
{ {
geometry_type * poly = shape_.read_polygon(); geometry_type* poly = shape_.read_polygon();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonm: case shape_io::shape_polygonm:
{ {
geometry_type * poly = shape_.read_polygonm(); geometry_type* poly = shape_.read_polygonm();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonz: case shape_io::shape_polygonz:
{ {
geometry_type * poly = shape_.read_polygonz(); geometry_type* poly = shape_.read_polygonz();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
@ -278,13 +301,13 @@ feature_ptr shape_featureset<filterT>::next()
if (attr_ids_.size()) if (attr_ids_.size())
{ {
shape_.dbf().move_to(shape_.id_); shape_.dbf().move_to(shape_.id_);
std::vector<int>::const_iterator itr=attr_ids_.begin(); std::vector<int>::const_iterator itr = attr_ids_.begin();
std::vector<int>::const_iterator end=attr_ids_.end(); std::vector<int>::const_iterator end = attr_ids_.end();
try try
{ {
for (;itr!=end;++itr) for (; itr != end; ++itr)
{ {
shape_.dbf().add_attribute(*itr,*tr_,*feature);//TODO optimize!!! shape_.dbf().add_attribute(*itr, *tr_, *feature); //TODO optimize!!!
} }
} }
catch (...) catch (...)
@ -292,6 +315,7 @@ feature_ptr shape_featureset<filterT>::next()
std::clog << "Shape Plugin: error processing attributes " << std::endl; std::clog << "Shape Plugin: error processing attributes " << std::endl;
} }
} }
return feature; return feature;
} }
else else
@ -308,5 +332,3 @@ shape_featureset<filterT>::~shape_featureset() {}
template class shape_featureset<mapnik::filter_in_box>; template class shape_featureset<mapnik::filter_in_box>;
template class shape_featureset<mapnik::filter_at_point>; template class shape_featureset<mapnik::filter_at_point>;

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,7 +20,8 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $ // stl
#include <fstream>
// mapnik // mapnik
#include <mapnik/feature_factory.hpp> #include <mapnik/feature_factory.hpp>
@ -29,9 +30,6 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/interprocess/streams/bufferstream.hpp> #include <boost/interprocess/streams/bufferstream.hpp>
// stl
#include <fstream>
#include "shape_index_featureset.hpp" #include "shape_index_featureset.hpp"
using mapnik::feature_factory; using mapnik::feature_factory;
@ -44,26 +42,27 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
std::string const& encoding, std::string const& encoding,
std::string const& shape_name, std::string const& shape_name,
int row_limit) int row_limit)
: filter_(filter), : filter_(filter),
//shape_type_(0), //shape_type_(0),
shape_(shape), shape_(shape),
tr_(new transcoder(encoding)), tr_(new transcoder(encoding)),
count_(0), count_(0),
row_limit_(row_limit) row_limit_(row_limit)
{ {
shape_.shp().skip(100); shape_.shp().skip(100);
boost::shared_ptr<shape_file> index = shape_.index(); boost::shared_ptr<shape_file> index = shape_.index();
if (index) if (index)
{ {
#ifdef SHAPE_MEMORY_MAPPED_FILE #ifdef SHAPE_MEMORY_MAPPED_FILE
//shp_index<filterT,stream<mapped_file_source> >::query(filter,index->file(),ids_); //shp_index<filterT,stream<mapped_file_source> >::query(filter, index->file(), ids_);
shp_index<filterT,boost::interprocess::ibufferstream>::query(filter,index->file(),ids_); shp_index<filterT,boost::interprocess::ibufferstream>::query(filter, index->file(), ids_);
#else #else
shp_index<filterT,std::ifstream>::query(filter,index->file(),ids_); shp_index<filterT,std::ifstream>::query(filter, index->file(), ids_);
#endif #endif
} }
std::sort(ids_.begin(),ids_.end());
std::sort(ids_.begin(), ids_.end());
#ifdef MAPNIK_DEBUG #ifdef MAPNIK_DEBUG
std::clog << "Shape Plugin: query size=" << ids_.size() << std::endl; std::clog << "Shape Plugin: query size=" << ids_.size() << std::endl;
@ -72,11 +71,11 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
itr_ = ids_.begin(); itr_ = ids_.begin();
// deal with attributes // deal with attributes
std::set<std::string>::const_iterator pos=attribute_names.begin(); std::set<std::string>::const_iterator pos = attribute_names.begin();
while (pos!=attribute_names.end()) while (pos != attribute_names.end())
{ {
bool found_name = false; bool found_name = false;
for (int i=0;i<shape_.dbf().num_fields();++i) for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{ {
if (shape_.dbf().descriptor(i).name_ == *pos) if (shape_.dbf().descriptor(i).name_ == *pos)
{ {
@ -85,21 +84,23 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
break; break;
} }
} }
if (!found_name)
if (! found_name)
{ {
std::ostringstream s; std::ostringstream s;
s << "no attribute '" << *pos << "' in '" << shape_name << "'. Valid attributes are: ";
s << "no attribute '" << *pos << "' in '"
<< shape_name << "'. Valid attributes are: ";
std::vector<std::string> list; std::vector<std::string> list;
for (int i=0;i<shape_.dbf().num_fields();++i) for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{ {
list.push_back(shape_.dbf().descriptor(i).name_); list.push_back(shape_.dbf().descriptor(i).name_);
} }
s << boost::algorithm::join(list, ",") << "."; s << boost::algorithm::join(list, ",") << ".";
throw mapnik::datasource_exception( "Shape Plugin: " + s.str() ); throw mapnik::datasource_exception("Shape Plugin: " + s.str());
} }
++pos; ++pos;
} }
} }
@ -108,59 +109,61 @@ template <typename filterT>
feature_ptr shape_index_featureset<filterT>::next() feature_ptr shape_index_featureset<filterT>::next()
{ {
if (row_limit_ && count_ > row_limit_) if (row_limit_ && count_ > row_limit_)
return feature_ptr();
if (itr_!=ids_.end())
{ {
int pos=*itr_++; return feature_ptr();
}
if (itr_ != ids_.end())
{
int pos = *itr_++;
shape_.move_to(pos); shape_.move_to(pos);
int type=shape_.type();
int type = shape_.type();
feature_ptr feature(feature_factory::create(shape_.id_)); feature_ptr feature(feature_factory::create(shape_.id_));
if (type == shape_io::shape_point) if (type == shape_io::shape_point)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointm) else if (type == shape_io::shape_pointm)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
shape_.shp().skip(8);// skip m // skip m
geometry_type * point = new geometry_type(mapnik::Point); shape_.shp().skip(8);
point->move_to(x,y); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointz) else if (type == shape_io::shape_pointz)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
// skip z // skip z
shape_.shp().skip(8); shape_.shp().skip(8);
// skip m if exists
//skip m if exists if (shape_.reclength_ == 8 + 36)
if ( shape_.reclength_ == 8 + 36)
{ {
shape_.shp().skip(8); shape_.shp().skip(8);
} }
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else else
{ {
while(!filter_.pass(shape_.current_extent()) && while(! filter_.pass(shape_.current_extent()) &&
itr_!=ids_.end()) itr_ != ids_.end())
{ {
if (shape_.type() != shape_io::shape_null) if (shape_.type() != shape_io::shape_null)
{ {
pos=*itr_++; pos = *itr_++;
shape_.move_to(pos); shape_.move_to(pos);
} }
else else
@ -176,56 +179,62 @@ feature_ptr shape_index_featureset<filterT>::next()
case shape_io::shape_multipointz: case shape_io::shape_multipointz:
{ {
int num_points = shape_.shp().read_ndr_integer(); int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i) for (int i = 0; i < num_points; ++i)
{ {
double x=shape_.shp().read_double(); double x = shape_.shp().read_double();
double y=shape_.shp().read_double(); double y = shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point); geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x,y); point->move_to(x, y);
feature->add_geometry(point); feature->add_geometry(point);
} }
// ignore m and z for now // ignore m and z for now
++count_; ++count_;
break; break;
} }
case shape_io::shape_polyline: case shape_io::shape_polyline:
{ {
geometry_type * line = shape_.read_polyline(); geometry_type* line = shape_.read_polyline();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinem: case shape_io::shape_polylinem:
{ {
geometry_type * line = shape_.read_polylinem(); geometry_type* line = shape_.read_polylinem();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinez: case shape_io::shape_polylinez:
{ {
geometry_type * line = shape_.read_polylinez(); geometry_type* line = shape_.read_polylinez();
feature->add_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygon: case shape_io::shape_polygon:
{ {
geometry_type * poly = shape_.read_polygon(); geometry_type* poly = shape_.read_polygon();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonm: case shape_io::shape_polygonm:
{ {
geometry_type * poly = shape_.read_polygonm(); geometry_type* poly = shape_.read_polygonm();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonz: case shape_io::shape_polygonz:
{ {
geometry_type * poly = shape_.read_polygonz(); geometry_type* poly = shape_.read_polygonz();
feature->add_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
@ -237,18 +246,18 @@ feature_ptr shape_index_featureset<filterT>::next()
if (attr_ids_.size()) if (attr_ids_.size())
{ {
shape_.dbf().move_to(shape_.id_); shape_.dbf().move_to(shape_.id_);
std::set<int>::const_iterator itr=attr_ids_.begin(); std::set<int>::const_iterator itr = attr_ids_.begin();
std::set<int>::const_iterator end=attr_ids_.end(); std::set<int>::const_iterator end = attr_ids_.end();
try try
{ {
for ( ; itr!=end; ++itr) for (; itr!=end; ++itr)
{ {
shape_.dbf().add_attribute(*itr,*tr_,*feature); shape_.dbf().add_attribute(*itr, *tr_, *feature);
} }
} }
catch (...) catch (...)
{ {
std::clog << "Shape Plugin: error processing attributes" << std::endl; std::cerr << "Shape Plugin: error processing attributes" << std::endl;
} }
} }
return feature; return feature;
@ -269,4 +278,3 @@ shape_index_featureset<filterT>::~shape_index_featureset() {}
template class shape_index_featureset<mapnik::filter_in_box>; template class shape_index_featureset<mapnik::filter_in_box>;
template class shape_index_featureset<mapnik::filter_at_point>; template class shape_index_featureset<mapnik::filter_at_point>;

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -23,13 +23,18 @@
#ifndef SHAPE_INDEX_FEATURESET_HPP #ifndef SHAPE_INDEX_FEATURESET_HPP
#define SHAPE_INDEX_FEATURESET_HPP #define SHAPE_INDEX_FEATURESET_HPP
// stl
#include <set>
#include <vector>
// mapnik
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
// boost
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include "shape_datasource.hpp" #include "shape_datasource.hpp"
#include "shape_io.hpp" #include "shape_io.hpp"
#include <set>
#include <vector>
using mapnik::Featureset; using mapnik::Featureset;
using mapnik::box2d; using mapnik::box2d;
@ -38,32 +43,31 @@ using mapnik::feature_ptr;
template <typename filterT> template <typename filterT>
class shape_index_featureset : public Featureset class shape_index_featureset : public Featureset
{ {
filterT filter_; public:
//int shape_type_; shape_index_featureset(const filterT& filter,
shape_io & shape_; shape_io& shape,
boost::scoped_ptr<transcoder> tr_; const std::set<std::string>& attribute_names,
std::vector<int> ids_; std::string const& encoding,
std::vector<int>::iterator itr_; std::string const& shape_name,
std::set<int> attr_ids_; int row_limit);
mutable box2d<double> feature_ext_; virtual ~shape_index_featureset();
mutable int total_geom_size; feature_ptr next();
mutable int count_;
const int row_limit_;
public: private:
shape_index_featureset(const filterT& filter, filterT filter_;
shape_io& shape, //int shape_type_;
const std::set<std::string>& attribute_names, shape_io & shape_;
std::string const& encoding, boost::scoped_ptr<transcoder> tr_;
std::string const& shape_name, std::vector<int> ids_;
int row_limit); std::vector<int>::iterator itr_;
virtual ~shape_index_featureset(); std::set<int> attr_ids_;
feature_ptr next(); mutable box2d<double> feature_ext_;
mutable int total_geom_size;
private: mutable int count_;
//no copying const int row_limit_;
shape_index_featureset(const shape_index_featureset&); //no copying
shape_index_featureset& operator=(const shape_index_featureset&); shape_index_featureset(const shape_index_featureset&);
shape_index_featureset& operator=(const shape_index_featureset&);
}; };
#endif //SHAPE_INDEX_FEATURESET_HPP #endif // SHAPE_INDEX_FEATURESET_HPP

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,10 +20,9 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id: shape_io.cc 26 2005-03-29 19:18:59Z pavlenko $
#include "shape_io.hpp" #include "shape_io.hpp"
// mapnik
#include <mapnik/datasource.hpp> #include <mapnik/datasource.hpp>
// boost // boost
@ -38,22 +37,22 @@ const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index"; const std::string shape_io::INDEX = ".index";
shape_io::shape_io(const std::string& shape_name, bool open_index) shape_io::shape_io(const std::string& shape_name, bool open_index)
: type_(shape_null), : type_(shape_null),
shp_(shape_name + SHP), shp_(shape_name + SHP),
dbf_(shape_name + DBF), dbf_(shape_name + DBF),
reclength_(0), reclength_(0),
id_(0) id_(0)
{ {
bool ok = (shp_.is_open() && dbf_.is_open()); bool ok = (shp_.is_open() && dbf_.is_open());
if (!ok) if (! ok)
{ {
throw datasource_exception("Shape Plugin: cannot read shape file '" + shape_name + "'"); throw datasource_exception("Shape Plugin: cannot read shape file '" + shape_name + "'");
} }
if (open_index) if (open_index)
{ {
try try
{ {
index_= boost::make_shared<shape_file>(shape_name + INDEX); index_= boost::make_shared<shape_file>(shape_name + INDEX);
} }
catch (...) catch (...)
@ -67,370 +66,398 @@ shape_io::shape_io(const std::string& shape_name, bool open_index)
shape_io::~shape_io() {} shape_io::~shape_io() {}
void shape_io::move_to (int pos) void shape_io::move_to(int pos)
{ {
shp_.seek(pos); shp_.seek(pos);
id_ = shp_.read_xdr_integer(); id_ = shp_.read_xdr_integer();
reclength_ = shp_.read_xdr_integer(); reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer(); type_ = shp_.read_ndr_integer();
if (type_!= shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz) if (type_ != shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{ {
shp_.read_envelope(cur_extent_); shp_.read_envelope(cur_extent_);
} }
} }
int shape_io::type() const int shape_io::type() const
{ {
return type_; return type_;
} }
const box2d<double>& shape_io::current_extent() const const box2d<double>& shape_io::current_extent() const
{ {
return cur_extent_; return cur_extent_;
} }
shape_file& shape_io::shp() shape_file& shape_io::shp()
{ {
return shp_; return shp_;
} }
/*shape_file& shape_io::shx() #if 0
shape_file& shape_io::shx()
{ {
return shx_; return shx_;
}*/ }
#endif
dbf_file& shape_io::dbf() dbf_file& shape_io::dbf()
{ {
return dbf_; return dbf_;
} }
geometry_type * shape_io::read_polyline() geometry_type* shape_io::read_polyline()
{ {
shape_file::record_type record(reclength_*2-36); shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
line->set_capacity(num_points + 1);
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end; int num_parts = record.read_ndr_integer();
for (int k=0;k<num_parts;++k) int num_points = record.read_ndr_integer();
{ geometry_type* line = new geometry_type(mapnik::LineString);
start=parts[k]; line->set_capacity(num_points + num_parts);
if (k==num_parts-1) if (num_parts == 1)
end=num_points; {
else line->set_capacity(num_points + 1);
end=parts[k+1]; record.skip(4);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int i = 1; i < num_points; ++i)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
int start, end;
for (int k = 0; k < num_parts; ++k)
{
start = parts[k];
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x=record.read_double(); double x = record.read_double();
double y=record.read_double(); double y = record.read_double();
line->move_to(x,y); line->move_to(x, y);
for (int j=start+1;j<end;++j) for (int j = start + 1; j < end; ++j)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
line->line_to(x,y); line->line_to(x, y);
} }
} }
} }
return line; return line;
} }
geometry_type * shape_io::read_polylinem() geometry_type* shape_io::read_polylinem()
{ {
shape_file::record_type record(reclength_*2-36); shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
geometry_type* line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int i = 1; i < num_points; ++i)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
int start, end;
for (int k = 0; k < num_parts; ++k)
{
start = parts[k];
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int j = start + 1; j < end; ++j)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_type* shape_io::read_polylinez()
{
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_parts = record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString); int num_points = record.read_ndr_integer();
geometry_type* line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts); line->set_capacity(num_points + num_parts);
if (num_parts == 1) if (num_parts == 1)
{ {
record.skip(4); record.skip(4);
double x=record.read_double(); double x = record.read_double();
double y=record.read_double(); double y = record.read_double();
line->move_to(x,y); line->move_to(x, y);
for (int i=1;i<num_points;++i) for (int i = 1; i < num_points; ++i)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
line->line_to(x,y); line->line_to(x, y);
} }
} }
else else
{ {
std::vector<int> parts(num_parts); std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i) for (int i = 0; i < num_parts; ++i)
{ {
parts[i]=record.read_ndr_integer(); parts[i] = record.read_ndr_integer();
} }
int start,end; int start, end;
for (int k=0;k<num_parts;++k) for (int k = 0; k < num_parts; ++k)
{ {
start=parts[k]; start = parts[k];
if (k==num_parts-1) if (k == num_parts - 1)
end=num_points; {
else end = num_points;
end=parts[k+1]; }
else
double x=record.read_double(); {
double y=record.read_double(); end = parts[k + 1];
line->move_to(x,y); }
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_type * shape_io::read_polylinez()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
double x=record.read_double(); double x = record.read_double();
double y=record.read_double(); double y = record.read_double();
line->move_to(x,y); line->move_to(x, y);
for (int j=start+1;j<end;++j) for (int j = start + 1; j < end; ++j)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
line->line_to(x,y); line->line_to(x, y);
} }
} }
} }
// z-range
//double z0=record.read_double(); // z-range
//double z1=record.read_double(); //double z0=record.read_double();
//for (int i=0;i<num_points;++i) //double z1=record.read_double();
// { //for (int i=0;i<num_points;++i)
// double z=record.read_double(); // {
// } // double z=record.read_double();
// }
// m-range // m-range
//double m0=record.read_double(); //double m0=record.read_double();
//double m1=record.read_double(); //double m1=record.read_double();
//for (int i=0;i<num_points;++i) //for (int i=0;i<num_points;++i)
//{ //{
// double m=record.read_double(); // double m=record.read_double();
//} //}
return line;
return line;
} }
geometry_type * shape_io::read_polygon() geometry_type* shape_io::read_polygon()
{ {
shape_file::record_type record(reclength_*2-36); shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type * poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++) int num_parts = record.read_ndr_integer();
{ int num_points = record.read_ndr_integer();
int start=parts[k]; std::vector<int> parts(num_parts);
int end; geometry_type* poly = new geometry_type(mapnik::Polygon);
if (k==num_parts-1) poly->set_capacity(num_points + num_parts);
{ for (int i = 0; i < num_parts; ++i)
end=num_points; {
} parts[i] = record.read_ndr_integer();
else }
{
end=parts[k+1]; for (int k = 0; k < num_parts; k++)
} {
double x=record.read_double(); int start = parts[k];
double y=record.read_double(); int end;
poly->move_to(x,y); if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++) for (int j=start+1;j<end;j++)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
poly->line_to(x,y); poly->line_to(x, y);
} }
} }
return poly; return poly;
} }
geometry_type * shape_io::read_polygonm() geometry_type* shape_io::read_polygonm()
{ {
shape_file::record_type record(reclength_*2-36); shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_parts = record.read_ndr_integer();
std::vector<int> parts(num_parts); int num_points = record.read_ndr_integer();
geometry_type * poly = new geometry_type(mapnik::Polygon); std::vector<int> parts(num_parts);
poly->set_capacity(num_points + num_parts); geometry_type* poly = new geometry_type(mapnik::Polygon);
for (int i=0;i<num_parts;++i) poly->set_capacity(num_points + num_parts);
{ for (int i = 0; i < num_parts; ++i)
parts[i]=record.read_ndr_integer(); {
} parts[i] = record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++) for (int k = 0; k < num_parts; k++)
{ {
int start=parts[k]; int start = parts[k];
int end; int end;
if (k==num_parts-1) if (k == num_parts - 1)
{ {
end=num_points; end = num_points;
} }
else else
{ {
end=parts[k+1]; end = parts[k + 1];
} }
double x=record.read_double();
double y=record.read_double(); double x = record.read_double();
poly->move_to(x,y); double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++) for (int j = start + 1; j < end; j++)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
poly->line_to(x,y); poly->line_to(x, y);
} }
} }
// m-range
//double m0=record.read_double(); // m-range
//double m1=record.read_double(); //double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{ //for (int i=0;i<num_points;++i)
// double m=record.read_double(); //{
//} // double m=record.read_double();
return poly; //}
return poly;
} }
geometry_type * shape_io::read_polygonz() geometry_type* shape_io::read_polygonz()
{ {
shape_file::record_type record(reclength_*2-36); shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_parts = record.read_ndr_integer();
std::vector<int> parts(num_parts); int num_points = record.read_ndr_integer();
geometry_type * poly = new geometry_type(mapnik::Polygon); std::vector<int> parts(num_parts);
poly->set_capacity(num_points + num_parts); geometry_type* poly = new geometry_type(mapnik::Polygon);
for (int i=0;i<num_parts;++i) poly->set_capacity(num_points + num_parts);
{ for (int i = 0; i < num_parts; ++i)
parts[i]=record.read_ndr_integer(); {
} parts[i] = record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++) for (int k = 0; k < num_parts; k++)
{ {
int start=parts[k]; int start = parts[k];
int end; int end;
if (k==num_parts-1) if (k == num_parts - 1)
{ {
end=num_points; end = num_points;
} }
else else
{ {
end=parts[k+1]; end = parts[k + 1];
} }
double x=record.read_double();
double y=record.read_double(); double x = record.read_double();
poly->move_to(x,y); double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++) for (int j = start + 1; j < end; j++)
{ {
x=record.read_double(); x = record.read_double();
y=record.read_double(); y = record.read_double();
poly->line_to(x,y); poly->line_to(x, y);
} }
} }
// z-range
//double z0=record.read_double(); // z-range
//double z1=record.read_double(); //double z0=record.read_double();
//for (int i=0;i<num_points;++i) //double z1=record.read_double();
//{ //for (int i=0;i<num_points;++i)
// double z=record.read_double(); //{
//} // double z=record.read_double();
//}
// m-range
//double m0=record.read_double(); // m-range
//double m1=record.read_double(); //double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{ //for (int i=0;i<num_points;++i)
// double m=record.read_double(); //{
//} // double m=record.read_double();
return poly; //}
return poly;
} }

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -23,29 +23,16 @@
#ifndef SHAPE_IO_HPP #ifndef SHAPE_IO_HPP
#define SHAPE_IO_HPP #define SHAPE_IO_HPP
// mapnik
#include "dbfile.hpp"
#include "shapefile.hpp"
#include "shp_index.hpp"
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include "dbfile.hpp"
#include "shapefile.hpp"
#include "shp_index.hpp"
struct shape_io : boost::noncopyable struct shape_io : boost::noncopyable
{ {
static const std::string SHP;
//static const std::string SHX;
static const std::string DBF;
static const std::string INDEX;
unsigned type_;
shape_file shp_;
//shape_file shx_;
dbf_file dbf_;
boost::shared_ptr<shape_file> index_;
unsigned reclength_;
unsigned id_;
box2d<double> cur_extent_;
public: public:
enum shapeType enum shapeType
{ {
@ -67,6 +54,7 @@ public:
shape_io(const std::string& shape_name, bool open_index=true); shape_io(const std::string& shape_name, bool open_index=true);
~shape_io(); ~shape_io();
shape_file& shp(); shape_file& shp();
//shape_file& shx(); //shape_file& shx();
dbf_file& dbf(); dbf_file& dbf();
@ -84,12 +72,26 @@ public:
void move_to(int id); void move_to(int id);
int type() const; int type() const;
const box2d<double>& current_extent() const; const box2d<double>& current_extent() const;
mapnik::geometry_type * read_polyline(); mapnik::geometry_type* read_polyline();
mapnik::geometry_type * read_polylinem(); mapnik::geometry_type* read_polylinem();
mapnik::geometry_type * read_polylinez(); mapnik::geometry_type* read_polylinez();
mapnik::geometry_type * read_polygon(); mapnik::geometry_type* read_polygon();
mapnik::geometry_type * read_polygonm(); mapnik::geometry_type* read_polygonm();
mapnik::geometry_type * read_polygonz(); mapnik::geometry_type* read_polygonz();
unsigned type_;
shape_file shp_;
//shape_file shx_;
dbf_file dbf_;
boost::shared_ptr<shape_file> index_;
unsigned reclength_;
unsigned id_;
box2d<double> cur_extent_;
static const std::string SHP;
//static const std::string SHX;
static const std::string DBF;
static const std::string INDEX;
}; };
#endif //SHAPE_IO_HPP #endif //SHAPE_IO_HPP

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -20,11 +20,13 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id: shapefile.hpp 33 2005-04-04 13:01:03Z pavlenko $
#ifndef SHAPEFILE_HPP #ifndef SHAPEFILE_HPP
#define SHAPEFILE_HPP #define SHAPEFILE_HPP
// stl
#include <cstring>
#include <fstream>
// mapnik // mapnik
#include <mapnik/global.hpp> #include <mapnik/global.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
@ -35,10 +37,6 @@
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/interprocess/streams/bufferstream.hpp> #include <boost/interprocess/streams/bufferstream.hpp>
// stl
#include <cstring>
#include <fstream>
using mapnik::box2d; using mapnik::box2d;
using mapnik::read_int32_ndr; using mapnik::read_int32_ndr;
using mapnik::read_int32_xdr; using mapnik::read_int32_xdr;
@ -63,7 +61,7 @@ struct RecordTag
struct MappedRecordTag struct MappedRecordTag
{ {
typedef const char* data_type; typedef const char* data_type;
static data_type alloc(unsigned) { return 0;} static data_type alloc(unsigned) { return 0; }
static void dealloc(data_type ) {} static void dealloc(data_type ) {}
}; };
@ -73,12 +71,18 @@ struct shape_record
typename Tag::data_type data; typename Tag::data_type data;
size_t size; size_t size;
mutable size_t pos; mutable size_t pos;
explicit shape_record(size_t size) explicit shape_record(size_t size)
: : data(Tag::alloc(size)),
data(Tag::alloc(size)),
size(size), size(size),
pos(0) {} pos(0)
{}
~shape_record()
{
Tag::dealloc(data);
}
void set_data(typename Tag::data_type data_) void set_data(typename Tag::data_type data_)
{ {
data = data_; data = data_;
@ -91,42 +95,37 @@ struct shape_record
void skip(unsigned n) void skip(unsigned n)
{ {
pos+=n; pos += n;
} }
int read_ndr_integer() int read_ndr_integer()
{ {
boost::int32_t val; boost::int32_t val;
read_int32_ndr(&data[pos],val); read_int32_ndr(&data[pos], val);
pos+=4; pos += 4;
return val; return val;
} }
int read_xdr_integer() int read_xdr_integer()
{ {
boost::int32_t val; boost::int32_t val;
read_int32_xdr(&data[pos],val); read_int32_xdr(&data[pos], val);
pos+=4; pos += 4;
return val; return val;
} }
double read_double() double read_double()
{ {
double val; double val;
read_double_ndr(&data[pos],val); read_double_ndr(&data[pos], val);
pos+=8; pos += 8;
return val; return val;
} }
long remains() long remains()
{ {
return (size-pos); return (size - pos);
} }
~shape_record()
{
Tag::dealloc(data);
}
}; };
using namespace boost::interprocess; using namespace boost::interprocess;
@ -144,10 +143,10 @@ public:
#endif #endif
file_source_type file_; file_source_type file_;
shape_file() {} shape_file() {}
shape_file(std::string const& file_name) shape_file(std::string const& file_name) :
:
#ifdef SHAPE_MEMORY_MAPPED_FILE #ifdef SHAPE_MEMORY_MAPPED_FILE
file_() file_()
#else #else
@ -155,18 +154,19 @@ public:
#endif #endif
{ {
#ifdef SHAPE_MEMORY_MAPPED_FILE #ifdef SHAPE_MEMORY_MAPPED_FILE
boost::optional<mapnik::mapped_region_ptr> memory =
boost::optional<mapnik::mapped_region_ptr> memory = mapnik::mapped_memory_cache::find(file_name.c_str(),true); mapnik::mapped_memory_cache::find(file_name.c_str(),true);
if (memory) if (memory)
{ {
file_.buffer(static_cast<char*>((*memory)->get_address()),(*memory)->get_size()); file_.buffer(static_cast<char*>((*memory)->get_address()), (*memory)->get_size());
} }
#endif #endif
} }
~shape_file() {} ~shape_file() {}
inline file_source_type & file() inline file_source_type& file()
{ {
return file_; return file_;
} }
@ -184,9 +184,9 @@ public:
{ {
#ifdef SHAPE_MEMORY_MAPPED_FILE #ifdef SHAPE_MEMORY_MAPPED_FILE
rec.set_data(file_.buffer().first + file_.tellg()); rec.set_data(file_.buffer().first + file_.tellg());
file_.seekg(rec.size,std::ios::cur); file_.seekg(rec.size, std::ios::cur);
#else #else
file_.read(rec.get_data(),rec.size); file_.read(rec.get_data(), rec.size);
#endif #endif
} }
@ -195,16 +195,16 @@ public:
char b[4]; char b[4];
file_.read(b, 4); file_.read(b, 4);
boost::int32_t val; boost::int32_t val;
read_int32_xdr(b,val); read_int32_xdr(b, val);
return val; return val;
} }
inline int read_ndr_integer() inline int read_ndr_integer()
{ {
char b[4]; char b[4];
file_.read(b,4); file_.read(b, 4);
boost::int32_t val; boost::int32_t val;
read_int32_ndr(b,val); read_int32_ndr(b, val);
return val; return val;
} }
@ -212,11 +212,11 @@ public:
{ {
double val; double val;
#ifndef MAPNIK_BIG_ENDIAN #ifndef MAPNIK_BIG_ENDIAN
file_.read(reinterpret_cast<char*>(&val),8); file_.read(reinterpret_cast<char*>(&val), 8);
#else #else
char b[8]; char b[8];
file_.read(b,8); file_.read(b, 8);
read_double_ndr(b,val); read_double_ndr(b, val);
#endif #endif
return val; return val;
} }
@ -224,22 +224,22 @@ public:
inline void read_envelope(box2d<double>& envelope) inline void read_envelope(box2d<double>& envelope)
{ {
#ifndef MAPNIK_BIG_ENDIAN #ifndef MAPNIK_BIG_ENDIAN
file_.read(reinterpret_cast<char*>(&envelope),sizeof(envelope)); file_.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
#else #else
char data[4*8]; char data[4 * 8];
file_.read(data,4*8); file_.read(data,4 * 8);
double minx,miny,maxx,maxy; double minx, miny, maxx, maxy;
read_double_ndr(data + 0*8,minx); read_double_ndr(data + 0 * 8, minx);
read_double_ndr(data + 1*8,miny); read_double_ndr(data + 1 * 8, miny);
read_double_ndr(data + 2*8,maxx); read_double_ndr(data + 2 * 8, maxx);
read_double_ndr(data + 3*8,maxy); read_double_ndr(data + 3 * 8, maxy);
envelope.init(minx,miny,maxx,maxy); envelope.init(minx, miny, maxx, maxy);
#endif #endif
} }
inline void skip(std::streampos bytes) inline void skip(std::streampos bytes)
{ {
file_.seekg(bytes,std::ios::cur); file_.seekg(bytes, std::ios::cur);
} }
inline void rewind() inline void rewind()
@ -249,7 +249,7 @@ public:
inline void seek(std::streampos pos) inline void seek(std::streampos pos)
{ {
file_.seekg(pos,std::ios::beg); file_.seekg(pos, std::ios::beg);
} }
inline std::streampos pos() inline std::streampos pos()
@ -263,4 +263,4 @@ public:
} }
}; };
#endif //SHAPEFILE_HPP #endif // SHAPEFILE_HPP

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2006 Artem Pavlenko * Copyright (C) 2011 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -23,9 +23,10 @@
#ifndef SHP_INDEX_HH #ifndef SHP_INDEX_HH
#define SHP_INDEX_HH #define SHP_INDEX_HH
// st // stl
#include <fstream> #include <fstream>
#include <vector> #include <vector>
// mapnik // mapnik
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/query.hpp> #include <mapnik/query.hpp>
@ -43,63 +44,60 @@ private:
~shp_index(); ~shp_index();
shp_index(const shp_index&); shp_index(const shp_index&);
shp_index& operator=(const shp_index&); shp_index& operator=(const shp_index&);
static int read_ndr_integer(IStream & in); static int read_ndr_integer(IStream& in);
static void read_envelope(IStream & in,box2d<double> &envelope); static void read_envelope(IStream& in, box2d<double>& envelope);
static void query_node(const filterT& filter,IStream & in,std::vector<int>& pos); static void query_node(const filterT& filter, IStream& in, std::vector<int>& pos);
}; };
template <typename filterT,typename IStream> template <typename filterT, typename IStream>
void shp_index<filterT, IStream>::query(const filterT& filter,IStream & file,std::vector<int>& pos) void shp_index<filterT, IStream>::query(const filterT& filter, IStream& file, std::vector<int>& pos)
{ {
file.seekg(16,std::ios::beg); file.seekg(16, std::ios::beg);
query_node(filter,file,pos); query_node(filter, file, pos);
} }
template <typename filterT, typename IStream> template <typename filterT, typename IStream>
void shp_index<filterT,IStream>::query_node(const filterT& filter,IStream & file,std::vector<int>& ids) void shp_index<filterT, IStream>::query_node(const filterT& filter, IStream& file, std::vector<int>& ids)
{ {
int offset=read_ndr_integer(file); int offset = read_ndr_integer(file);
box2d<double> node_ext; box2d<double> node_ext;
read_envelope(file,node_ext); read_envelope(file, node_ext);
int num_shapes=read_ndr_integer(file); int num_shapes = read_ndr_integer(file);
if (!filter.pass(node_ext)) if (! filter.pass(node_ext))
{ {
file.seekg(offset+num_shapes*4+4,std::ios::cur); file.seekg(offset + num_shapes * 4 + 4, std::ios::cur);
return; return;
} }
for (int i=0;i<num_shapes;++i) for (int i = 0; i < num_shapes; ++i)
{ {
int id=read_ndr_integer(file); int id = read_ndr_integer(file);
ids.push_back(id); ids.push_back(id);
} }
int children=read_ndr_integer(file); int children = read_ndr_integer(file);
for (int j=0;j<children;++j) for (int j = 0; j < children; ++j)
{ {
query_node(filter,file,ids); query_node(filter, file, ids);
} }
} }
template <typename filterT, typename IStream>
template <typename filterT,typename IStream> int shp_index<filterT, IStream>::read_ndr_integer(IStream& file)
int shp_index<filterT,IStream>::read_ndr_integer(IStream & file)
{ {
char b[4]; char b[4];
file.read(b,4); file.read(b, 4);
return (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24; return (b[0] & 0xff) | (b[1] & 0xff) << 8 | (b[2] & 0xff) << 16 | (b[3] & 0xff) << 24;
} }
template <typename filterT, typename IStream>
template <typename filterT,typename IStream> void shp_index<filterT, IStream>::read_envelope(IStream& file, box2d<double>& envelope)
void shp_index<filterT,IStream>::read_envelope(IStream & file,box2d<double>& envelope)
{ {
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope)); file.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
} }
#endif // SHP_INDEX_HH
#endif //SHP_INDEX_HH