+ added index facility by using a *.index file to OGR layers (10-15% faster than internal OGR spatial filter)
This commit is contained in:
parent
e4aab13cb7
commit
539f1bcf9b
11 changed files with 869 additions and 294 deletions
|
@ -26,8 +26,10 @@ install_prefix = env['DESTDIR'] + '/' + prefix
|
|||
|
||||
ogr_src = Split(
|
||||
"""
|
||||
ogr_converter.cpp
|
||||
ogr_datasource.cpp
|
||||
ogr_featureset.cpp
|
||||
ogr_index_featureset.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
|
|
277
plugins/input/ogr/ogr_converter.cpp
Normal file
277
plugins/input/ogr/ogr_converter.cpp
Normal file
|
@ -0,0 +1,277 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 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/global.hpp>
|
||||
#include <mapnik/envelope.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
|
||||
// ogr
|
||||
#include "ogr_converter.hpp"
|
||||
|
||||
using std::clog;
|
||||
using std::endl;
|
||||
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::geometry2d;
|
||||
using mapnik::point_impl;
|
||||
using mapnik::line_string_impl;
|
||||
using mapnik::polygon_impl;
|
||||
|
||||
/*
|
||||
using mapnik::query;
|
||||
using mapnik::Envelope;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
*/
|
||||
|
||||
void ogr_converter::convert_geometry (OGRGeometry* geom, feature_ptr feature, bool multiple_geometries)
|
||||
{
|
||||
switch (wkbFlatten (geom->getGeometryType()))
|
||||
{
|
||||
case wkbPoint:
|
||||
convert_point (static_cast<OGRPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbLineString:
|
||||
convert_linestring (static_cast<OGRLineString*>(geom), feature);
|
||||
break;
|
||||
case wkbPolygon:
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiPoint:
|
||||
if (multiple_geometries)
|
||||
convert_multipoint_2 (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
else
|
||||
convert_multipoint (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiLineString:
|
||||
if (multiple_geometries)
|
||||
convert_multilinestring_2 (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
else
|
||||
convert_multilinestring (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
|
||||
break;
|
||||
case wkbMultiPolygon:
|
||||
if (multiple_geometries)
|
||||
convert_multipolygon_2 (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
else
|
||||
convert_multipolygon (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbGeometryCollection:
|
||||
convert_collection (static_cast<OGRGeometryCollection*>(geom), feature, multiple_geometries);
|
||||
break;
|
||||
case wkbLinearRing:
|
||||
convert_linestring (static_cast<OGRLinearRing*>(geom), feature);
|
||||
break;
|
||||
case wkbNone:
|
||||
case wkbUnknown:
|
||||
default:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unknown <ogr> geometry_type=" << wkbFlatten (geom->getGeometryType()) << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_point (OGRPoint* geom, feature_ptr feature)
|
||||
{
|
||||
geometry2d* point = new point_impl;
|
||||
point->move_to (geom->getX(), geom->getY());
|
||||
feature->add_geometry (point);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_linestring (OGRLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_points = geom->getNumPoints ();
|
||||
geometry2d * line = new line_string_impl;
|
||||
line->set_capacity (num_points);
|
||||
line->move_to (geom->getX (0), geom->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
line->line_to (geom->getX (i), geom->getY (i));
|
||||
}
|
||||
feature->add_geometry (line);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_polygon (OGRPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
OGRLinearRing* exterior = geom->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = geom->getNumInteriorRings ();
|
||||
int capacity = 0;
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
}
|
||||
|
||||
geometry2d * poly = new polygon_impl;
|
||||
poly->set_capacity (num_points + capacity);
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
}
|
||||
}
|
||||
feature->add_geometry (poly);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipoint (OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
geometry2d* point = new point_impl;
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPoint* ogrpoint = static_cast<OGRPoint*>(geom->getGeometryRef (i));
|
||||
point->move_to (ogrpoint->getX(), ogrpoint->getY());
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipoint_2 (OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_point (static_cast<OGRPoint*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multilinestring (OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
|
||||
int num_points = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points += ls->getNumPoints ();
|
||||
}
|
||||
|
||||
geometry2d * line = new line_string_impl;
|
||||
line->set_capacity (num_points);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points = ls->getNumPoints ();
|
||||
line->move_to (ls->getX (0), ls->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
line->line_to (ls->getX (i), ls->getY (i));
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (line);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multilinestring_2 (OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_linestring (static_cast<OGRLineString*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipolygon (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
|
||||
int capacity = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
capacity += exterior->getNumPoints ();
|
||||
for (int r=0;r<p->getNumInteriorRings ();r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
}
|
||||
}
|
||||
|
||||
geometry2d * poly = new polygon_impl;
|
||||
poly->set_capacity (capacity);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = p->getNumInteriorRings ();
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (poly);
|
||||
}
|
||||
|
||||
void ogr_converter::convert_multipolygon_2 (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_converter::convert_collection (OGRGeometryCollection* geom, feature_ptr feature, bool multiple_geometries)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRGeometry* g = geom->getGeometryRef (i);
|
||||
if (g != NULL)
|
||||
{
|
||||
convert_geometry (g, feature, multiple_geometries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
plugins/input/ogr/ogr_converter.hpp
Normal file
50
plugins/input/ogr/ogr_converter.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 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 OGR_CONVERTER_HPP
|
||||
#define OGR_CONVERTER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
|
||||
// ogr
|
||||
#include <ogrsf_frmts.h>
|
||||
|
||||
class ogr_converter
|
||||
{
|
||||
public:
|
||||
|
||||
static void convert_geometry (OGRGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_collection (OGRGeometryCollection* geom, mapnik::feature_ptr feature, bool multiple_geometries);
|
||||
static void convert_point (OGRPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_linestring (OGRLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_polygon (OGRPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipoint_2 (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multilinestring_2 (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
static void convert_multipolygon_2 (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
|
@ -21,11 +21,20 @@
|
|||
*****************************************************************************/
|
||||
// $Id$
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "ogr_datasource.hpp"
|
||||
#include "ogr_featureset.hpp"
|
||||
#include "ogr_index_featureset.hpp"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
using std::clog;
|
||||
|
@ -43,13 +52,16 @@ using mapnik::featureset_ptr;
|
|||
using mapnik::layer_descriptor;
|
||||
using mapnik::attribute_descriptor;
|
||||
using mapnik::datasource_exception;
|
||||
using mapnik::filter_in_box;
|
||||
using mapnik::filter_at_point;
|
||||
|
||||
|
||||
ogr_datasource::ogr_datasource(parameters const& params)
|
||||
: datasource(params),
|
||||
extent_(),
|
||||
type_(datasource::Vector),
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))
|
||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")),
|
||||
indexed_(false)
|
||||
{
|
||||
OGRRegisterAll();
|
||||
|
||||
|
@ -63,7 +75,8 @@ ogr_datasource::ogr_datasource(parameters const& params)
|
|||
dataset_name_ = *base + "/" + *file;
|
||||
else
|
||||
dataset_name_ = *file;
|
||||
|
||||
|
||||
// open ogr driver
|
||||
dataset_ = OGRSFDriverRegistrar::Open ((dataset_name_).c_str(), FALSE);
|
||||
if (!dataset_)
|
||||
{
|
||||
|
@ -76,6 +89,7 @@ ogr_datasource::ogr_datasource(parameters const& params)
|
|||
}
|
||||
}
|
||||
|
||||
// initialize layer
|
||||
boost::optional<std::string> layer = params.get<std::string>("layer");
|
||||
if (!layer)
|
||||
{
|
||||
|
@ -100,10 +114,23 @@ ogr_datasource::ogr_datasource(parameters const& params)
|
|||
layer_ = dataset_->GetLayerByName (layerName_.c_str());
|
||||
if (! layer_) throw datasource_exception("cannot find <layer> in dataset");
|
||||
|
||||
// initialize envelope
|
||||
OGREnvelope envelope;
|
||||
layer_->GetExtent (&envelope);
|
||||
extent_.init (envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY);
|
||||
|
||||
// scan for index file
|
||||
int breakpoint = dataset_name_.find_last_of (".");
|
||||
if (breakpoint == std::string::npos) breakpoint = dataset_name_.length();
|
||||
index_name_ = dataset_name_.substr(0, breakpoint) + ".index";
|
||||
std::ifstream index_file (index_name_.c_str(), std::ios::in | std::ios::binary);
|
||||
if (index_file)
|
||||
{
|
||||
indexed_=true;
|
||||
index_file.close();
|
||||
}
|
||||
|
||||
// deal with attributes descriptions
|
||||
OGRFeatureDefn* def = layer_->GetLayerDefn ();
|
||||
if (def != 0)
|
||||
{
|
||||
|
@ -191,13 +218,6 @@ featureset_ptr ogr_datasource::features(query const& q) const
|
|||
{
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
mapnik::Envelope<double> const& query_extent = q.get_bbox();
|
||||
|
||||
layer_->SetSpatialFilterRect (query_extent.minx(),
|
||||
query_extent.miny(),
|
||||
query_extent.maxx(),
|
||||
query_extent.maxy());
|
||||
|
||||
#if 0
|
||||
std::ostringstream s;
|
||||
|
||||
|
@ -219,7 +239,25 @@ featureset_ptr ogr_datasource::features(query const& q) const
|
|||
dataset_->ReleaseResultSet (layer);
|
||||
#endif
|
||||
|
||||
return featureset_ptr(new ogr_featureset(*dataset_, *layer_, desc_.get_encoding(), multiple_geometries_));
|
||||
if (indexed_)
|
||||
{
|
||||
filter_in_box filter(q.get_bbox());
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_in_box> (*dataset_,
|
||||
*layer_,
|
||||
filter,
|
||||
index_name_,
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
else
|
||||
{
|
||||
return featureset_ptr(new ogr_featureset (*dataset_,
|
||||
*layer_,
|
||||
q.get_bbox(),
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
@ -228,13 +266,29 @@ featureset_ptr ogr_datasource::features_at_point(coord2d const& pt) const
|
|||
{
|
||||
if (dataset_ && layer_)
|
||||
{
|
||||
OGRPoint point;
|
||||
point.setX (pt.x);
|
||||
point.setY (pt.y);
|
||||
if (indexed_)
|
||||
{
|
||||
filter_at_point filter(pt);
|
||||
|
||||
return featureset_ptr(new ogr_index_featureset<filter_at_point> (*dataset_,
|
||||
*layer_,
|
||||
filter,
|
||||
index_name_,
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
else
|
||||
{
|
||||
OGRPoint point;
|
||||
point.setX (pt.x);
|
||||
point.setY (pt.y);
|
||||
|
||||
layer_->SetSpatialFilter (&point);
|
||||
|
||||
return featureset_ptr(new ogr_featureset(*dataset_, *layer_, desc_.get_encoding(), multiple_geometries_));
|
||||
return featureset_ptr(new ogr_featureset (*dataset_,
|
||||
*layer_,
|
||||
point,
|
||||
desc_.get_encoding(),
|
||||
multiple_geometries_));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
|
|
@ -50,11 +50,13 @@ class ogr_datasource : public mapnik::datasource
|
|||
mapnik::Envelope<double> extent_;
|
||||
int type_;
|
||||
std::string dataset_name_;
|
||||
std::string index_name_;
|
||||
OGRDataSource* dataset_;
|
||||
OGRLayer* layer_;
|
||||
std::string layerName_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
bool multiple_geometries_;
|
||||
bool indexed_;
|
||||
};
|
||||
|
||||
|
||||
|
|
54
plugins/input/ogr/ogr_feature_ptr.hpp
Normal file
54
plugins/input/ogr/ogr_feature_ptr.hpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 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 OGR_FEATURE_PTR_HPP
|
||||
#define OGR_FEATURE_PTR_HPP
|
||||
|
||||
// ogr
|
||||
#include <ogrsf_frmts.h>
|
||||
|
||||
class ogr_feature_ptr
|
||||
{
|
||||
public:
|
||||
ogr_feature_ptr (OGRFeature* const feat)
|
||||
: feat_ (feat)
|
||||
{
|
||||
}
|
||||
|
||||
~ogr_feature_ptr ()
|
||||
{
|
||||
if (feat_ != NULL)
|
||||
OGRFeature::DestroyFeature (feat_);
|
||||
}
|
||||
|
||||
OGRFeature* operator*()
|
||||
{
|
||||
return feat_;
|
||||
}
|
||||
|
||||
private:
|
||||
OGRFeature* feat_;
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURE_PTR_HPP
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
// ogr
|
||||
#include "ogr_featureset.hpp"
|
||||
#include "ogr_converter.hpp"
|
||||
#include "ogr_feature_ptr.hpp"
|
||||
|
||||
using std::clog;
|
||||
using std::endl;
|
||||
|
@ -41,50 +43,43 @@ using mapnik::Envelope;
|
|||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::point_impl;
|
||||
using mapnik::line_string_impl;
|
||||
using mapnik::polygon_impl;
|
||||
using mapnik::geometry2d;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::transcoder;
|
||||
|
||||
|
||||
class ogr_feature_ptr
|
||||
{
|
||||
public:
|
||||
ogr_feature_ptr (OGRFeature* const feat)
|
||||
: feat_ (feat)
|
||||
{
|
||||
}
|
||||
|
||||
~ogr_feature_ptr ()
|
||||
{
|
||||
if (feat_ != NULL)
|
||||
OGRFeature::DestroyFeature (feat_);
|
||||
}
|
||||
|
||||
OGRFeature* operator*()
|
||||
{
|
||||
return feat_;
|
||||
}
|
||||
|
||||
private:
|
||||
OGRFeature* feat_;
|
||||
};
|
||||
|
||||
|
||||
ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries)
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
multiple_geometries_(multiple_geometries)
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
{
|
||||
layer_.ResetReading ();
|
||||
layer_.SetSpatialFilter (&extent);
|
||||
}
|
||||
|
||||
ogr_featureset::ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::Envelope<double> & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
{
|
||||
layer_.SetSpatialFilterRect (extent.minx(),
|
||||
extent.miny(),
|
||||
extent.maxx(),
|
||||
extent.maxy());
|
||||
}
|
||||
|
||||
ogr_featureset::~ogr_featureset() {}
|
||||
|
@ -99,7 +94,8 @@ feature_ptr ogr_featureset::next()
|
|||
{
|
||||
feature_ptr feature(new Feature((*feat)->GetFID()));
|
||||
|
||||
convert_geometry (geom, feature);
|
||||
ogr_converter::convert_geometry (geom, feature, multiple_geometries_);
|
||||
++count_;
|
||||
|
||||
int fld_count = layerdef_->GetFieldCount();
|
||||
for (int i = 0; i < fld_count; i++)
|
||||
|
@ -174,232 +170,9 @@ feature_ptr ogr_featureset::next()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << count_ << " features" << endl;
|
||||
#endif
|
||||
return feature_ptr();
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_geometry (OGRGeometry* geom, feature_ptr feature)
|
||||
{
|
||||
switch (wkbFlatten (geom->getGeometryType()))
|
||||
{
|
||||
case wkbPoint:
|
||||
convert_point (static_cast<OGRPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbLineString:
|
||||
convert_linestring (static_cast<OGRLineString*>(geom), feature);
|
||||
break;
|
||||
case wkbPolygon:
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiPoint:
|
||||
if (multiple_geometries_)
|
||||
convert_multipoint_2 (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
else
|
||||
convert_multipoint (static_cast<OGRMultiPoint*>(geom), feature);
|
||||
break;
|
||||
case wkbMultiLineString:
|
||||
if (multiple_geometries_)
|
||||
convert_multilinestring_2 (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
else
|
||||
convert_multilinestring (static_cast<OGRMultiLineString*>(geom), feature);
|
||||
|
||||
break;
|
||||
case wkbMultiPolygon:
|
||||
if (multiple_geometries_)
|
||||
convert_multipolygon_2 (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
else
|
||||
convert_multipolygon (static_cast<OGRMultiPolygon*>(geom), feature);
|
||||
break;
|
||||
case wkbGeometryCollection:
|
||||
convert_collection (static_cast<OGRGeometryCollection*>(geom), feature);
|
||||
break;
|
||||
case wkbLinearRing:
|
||||
convert_linestring (static_cast<OGRLinearRing*>(geom), feature);
|
||||
break;
|
||||
case wkbNone:
|
||||
case wkbUnknown:
|
||||
default:
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unknown <ogr> geometry_type=" << wkbFlatten (geom->getGeometryType()) << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_point (OGRPoint* geom, feature_ptr feature)
|
||||
{
|
||||
geometry2d* point = new point_impl;
|
||||
point->move_to (geom->getX(), geom->getY());
|
||||
feature->add_geometry (point);
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_linestring (OGRLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_points = geom->getNumPoints ();
|
||||
geometry2d * line = new line_string_impl;
|
||||
line->set_capacity (num_points);
|
||||
line->move_to (geom->getX (0), geom->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
line->line_to (geom->getX (i), geom->getY (i));
|
||||
}
|
||||
feature->add_geometry (line);
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_polygon (OGRPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
OGRLinearRing* exterior = geom->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = geom->getNumInteriorRings ();
|
||||
int capacity = 0;
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
}
|
||||
|
||||
geometry2d * poly = new polygon_impl;
|
||||
poly->set_capacity (num_points + capacity);
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = geom->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
}
|
||||
}
|
||||
feature->add_geometry (poly);
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multipoint (OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
geometry2d* point = new point_impl;
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPoint* ogrpoint = static_cast<OGRPoint*>(geom->getGeometryRef (i));
|
||||
point->move_to (ogrpoint->getX(), ogrpoint->getY());
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multipoint_2 (OGRMultiPoint* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_point (static_cast<OGRPoint*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multilinestring (OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
|
||||
int num_points = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points += ls->getNumPoints ();
|
||||
}
|
||||
|
||||
geometry2d * line = new line_string_impl;
|
||||
line->set_capacity (num_points);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRLineString* ls = static_cast<OGRLineString*>(geom->getGeometryRef (i));
|
||||
num_points = ls->getNumPoints ();
|
||||
line->move_to (ls->getX (0), ls->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
line->line_to (ls->getX (i), ls->getY (i));
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (line);
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multilinestring_2 (OGRMultiLineString* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_linestring (static_cast<OGRLineString*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multipolygon (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
|
||||
int capacity = 0;
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
capacity += exterior->getNumPoints ();
|
||||
for (int r=0;r<p->getNumInteriorRings ();r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
capacity += interior->getNumPoints ();
|
||||
}
|
||||
}
|
||||
|
||||
geometry2d * poly = new polygon_impl;
|
||||
poly->set_capacity (capacity);
|
||||
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRPolygon* p = static_cast<OGRPolygon*>(geom->getGeometryRef (i));
|
||||
OGRLinearRing* exterior = p->getExteriorRing ();
|
||||
int num_points = exterior->getNumPoints ();
|
||||
int num_interior = p->getNumInteriorRings ();
|
||||
poly->move_to (exterior->getX (0), exterior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to (exterior->getX (i), exterior->getY (i));
|
||||
}
|
||||
for (int r=0;r<num_interior;r++)
|
||||
{
|
||||
OGRLinearRing* interior = p->getInteriorRing (r);
|
||||
num_points = interior->getNumPoints ();
|
||||
poly->move_to(interior->getX (0), interior->getY (0));
|
||||
for (int i=1;i<num_points;++i)
|
||||
{
|
||||
poly->line_to(interior->getX (i), interior->getY (i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feature->add_geometry (poly);
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_multipolygon_2 (OGRMultiPolygon* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
convert_polygon (static_cast<OGRPolygon*>(geom->getGeometryRef (i)), feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ogr_featureset::convert_collection (OGRGeometryCollection* geom, feature_ptr feature)
|
||||
{
|
||||
int num_geometries = geom->getNumGeometries ();
|
||||
for (int i=0;i<num_geometries;i++)
|
||||
{
|
||||
OGRGeometry* g = geom->getGeometryRef (i);
|
||||
if (g != NULL)
|
||||
{
|
||||
convert_geometry (g, feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
@ -36,31 +37,30 @@
|
|||
|
||||
class ogr_featureset : public mapnik::Featureset
|
||||
{
|
||||
public:
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries);
|
||||
virtual ~ogr_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
void convert_geometry (OGRGeometry* geom, mapnik::feature_ptr feature);
|
||||
void convert_point (OGRPoint* geom, mapnik::feature_ptr feature);
|
||||
void convert_linestring (OGRLineString* geom, mapnik::feature_ptr feature);
|
||||
void convert_polygon (OGRPolygon* geom, mapnik::feature_ptr feature);
|
||||
void convert_multipoint (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
void convert_multipoint_2 (OGRMultiPoint* geom, mapnik::feature_ptr feature);
|
||||
void convert_multilinestring (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
void convert_multilinestring_2 (OGRMultiLineString* geom, mapnik::feature_ptr feature);
|
||||
void convert_multipolygon (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
void convert_multipolygon_2 (OGRMultiPolygon* geom, mapnik::feature_ptr feature);
|
||||
void convert_collection (OGRGeometryCollection* geom, mapnik::feature_ptr feature);
|
||||
OGRDataSource & dataset_;
|
||||
OGRLayer & layer_;
|
||||
OGRFeatureDefn * layerdef_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
mutable int count_;
|
||||
public:
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
OGRGeometry & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
|
||||
ogr_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const mapnik::Envelope<double> & extent,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
ogr_featureset(const ogr_featureset&);
|
||||
const ogr_featureset& operator=(const ogr_featureset&);
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
||||
|
|
105
plugins/input/ogr/ogr_index.hpp
Normal file
105
plugins/input/ogr/ogr_index.hpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef OGR_INDEX_HH
|
||||
#define OGR_INDEX_HH
|
||||
|
||||
// st
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
// mapnik
|
||||
#include <mapnik/envelope.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
|
||||
using mapnik::Envelope;
|
||||
using mapnik::query;
|
||||
|
||||
template <typename filterT, typename IStream = std::ifstream>
|
||||
class ogr_index
|
||||
{
|
||||
public:
|
||||
static void query(const filterT& filter, IStream& file,std::vector<int>& pos);
|
||||
private:
|
||||
ogr_index();
|
||||
~ogr_index();
|
||||
ogr_index(const ogr_index&);
|
||||
ogr_index& operator=(const ogr_index&);
|
||||
static int read_ndr_integer(IStream & in);
|
||||
static void read_envelope(IStream & in,Envelope<double> &envelope);
|
||||
static void query_node(const filterT& filter,IStream & in,std::vector<int>& pos);
|
||||
};
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
void ogr_index<filterT, IStream>::query(const filterT& filter,IStream & file,std::vector<int>& pos)
|
||||
{
|
||||
file.seekg(16,std::ios::beg);
|
||||
query_node(filter,file,pos);
|
||||
}
|
||||
|
||||
template <typename filterT, typename IStream>
|
||||
void ogr_index<filterT,IStream>::query_node(const filterT& filter,IStream & file,std::vector<int>& ids)
|
||||
{
|
||||
int offset=read_ndr_integer(file);
|
||||
|
||||
Envelope<double> node_ext;
|
||||
read_envelope(file,node_ext);
|
||||
|
||||
int num_shapes=read_ndr_integer(file);
|
||||
|
||||
if (!filter.pass(node_ext))
|
||||
{
|
||||
file.seekg(offset+num_shapes*4+4,std::ios::cur);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0;i<num_shapes;++i)
|
||||
{
|
||||
int id=read_ndr_integer(file);
|
||||
ids.push_back(id);
|
||||
}
|
||||
|
||||
int children=read_ndr_integer(file);
|
||||
|
||||
for (int j=0;j<children;++j)
|
||||
{
|
||||
query_node(filter,file,ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
int ogr_index<filterT,IStream>::read_ndr_integer(IStream & file)
|
||||
{
|
||||
char b[4];
|
||||
file.read(b,4);
|
||||
return (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24;
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT,typename IStream>
|
||||
void ogr_index<filterT,IStream>::read_envelope(IStream & file,Envelope<double>& envelope)
|
||||
{
|
||||
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
|
||||
}
|
||||
|
||||
|
||||
#endif //SHP_INDEX_HH
|
197
plugins/input/ogr/ogr_index_featureset.cpp
Normal file
197
plugins/input/ogr/ogr_index_featureset.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 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$
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/envelope.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/feature_layer_desc.hpp>
|
||||
#include <mapnik/wkb.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/file.hpp>
|
||||
#include <boost/iostreams/device/mapped_file.hpp>
|
||||
|
||||
// ogr
|
||||
#include "ogr_index_featureset.hpp"
|
||||
#include "ogr_converter.hpp"
|
||||
#include "ogr_index.hpp"
|
||||
#include "ogr_feature_ptr.hpp"
|
||||
|
||||
using std::clog;
|
||||
using std::endl;
|
||||
|
||||
using mapnik::query;
|
||||
using mapnik::Envelope;
|
||||
using mapnik::CoordTransform;
|
||||
using mapnik::Feature;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::geometry_utils;
|
||||
using mapnik::transcoder;
|
||||
|
||||
using namespace boost::iostreams;
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
ogr_index_featureset<filterT>::ogr_index_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries)
|
||||
: dataset_(dataset),
|
||||
layer_(layer),
|
||||
layerdef_(layer.GetLayerDefn()),
|
||||
filter_(filter),
|
||||
tr_(new transcoder(encoding)),
|
||||
fidcolumn_(layer_.GetFIDColumn ()),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
count_(0)
|
||||
{
|
||||
stream<mapped_file_source> file (index_file);
|
||||
if (file)
|
||||
{
|
||||
ogr_index<filterT,stream<mapped_file_source> >::query(filter,file,ids_);
|
||||
file.close();
|
||||
}
|
||||
std::sort(ids_.begin(),ids_.end());
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::clog<< "query size=" << ids_.size() << "\n";
|
||||
#endif
|
||||
|
||||
itr_ = ids_.begin();
|
||||
|
||||
// reset reading
|
||||
layer_.ResetReading();
|
||||
}
|
||||
|
||||
template <typename filterT>
|
||||
ogr_index_featureset<filterT>::~ogr_index_featureset() {}
|
||||
|
||||
template <typename filterT>
|
||||
feature_ptr ogr_index_featureset<filterT>::next()
|
||||
{
|
||||
if (itr_ != ids_.end())
|
||||
{
|
||||
int pos = *itr_++;
|
||||
layer_.SetNextByIndex (pos);
|
||||
|
||||
ogr_feature_ptr feat (layer_.GetNextFeature());
|
||||
if ((*feat) != NULL)
|
||||
{
|
||||
OGRGeometry* geom=(*feat)->GetGeometryRef();
|
||||
if (!geom->IsEmpty())
|
||||
{
|
||||
feature_ptr feature(new Feature((*feat)->GetFID()));
|
||||
|
||||
ogr_converter::convert_geometry (geom, feature, multiple_geometries_);
|
||||
++count_;
|
||||
|
||||
int fld_count = layerdef_->GetFieldCount();
|
||||
for (int i = 0; i < fld_count; i++)
|
||||
{
|
||||
OGRFieldDefn* fld = layerdef_->GetFieldDefn (i);
|
||||
OGRFieldType type_oid = fld->GetType ();
|
||||
std::string fld_name = fld->GetNameRef ();
|
||||
|
||||
switch (type_oid)
|
||||
{
|
||||
case OFTInteger:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsInteger (i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTReal:
|
||||
{
|
||||
boost::put(*feature,fld_name,(*feat)->GetFieldAsDouble (i));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTString:
|
||||
case OFTWideString: // deprecated !
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString (i));
|
||||
boost::put(*feature,fld_name,ustr);
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTIntegerList:
|
||||
case OFTRealList:
|
||||
case OFTStringList:
|
||||
case OFTWideStringList: // deprecated !
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unhandled type_oid=" << type_oid << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTBinary:
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unhandled type_oid=" << type_oid << endl;
|
||||
#endif
|
||||
//boost::put(*feature,name,feat->GetFieldAsBinary (i, size));
|
||||
break;
|
||||
}
|
||||
|
||||
case OFTDate:
|
||||
case OFTTime:
|
||||
case OFTDateTime: // unhandled !
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unhandled type_oid=" << type_oid << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default: // unknown
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << "unknown type_oid=" << type_oid << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_DEBUG
|
||||
clog << count_ << " features" << endl;
|
||||
#endif
|
||||
return feature_ptr();
|
||||
}
|
||||
|
||||
template class ogr_index_featureset<mapnik::filter_in_box>;
|
||||
template class ogr_index_featureset<mapnik::filter_at_point>;
|
||||
|
61
plugins/input/ogr/ogr_index_featureset.hpp
Normal file
61
plugins/input/ogr/ogr_index_featureset.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2007 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 OGR_INDEX_FEATURESET_HPP
|
||||
#define OGR_INDEX_FEATURESET_HPP
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "ogr_featureset.hpp"
|
||||
|
||||
template <typename filterT>
|
||||
class ogr_index_featureset : public mapnik::Featureset
|
||||
{
|
||||
OGRDataSource & dataset_;
|
||||
OGRLayer & layer_;
|
||||
OGRFeatureDefn * layerdef_;
|
||||
filterT filter_;
|
||||
std::vector<int> ids_;
|
||||
std::vector<int>::iterator itr_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
const char* fidcolumn_;
|
||||
bool multiple_geometries_;
|
||||
mutable int count_;
|
||||
|
||||
public:
|
||||
ogr_index_featureset(OGRDataSource & dataset,
|
||||
OGRLayer & layer,
|
||||
const filterT& filter,
|
||||
const std::string& index_file,
|
||||
const std::string& encoding,
|
||||
const bool multiple_geometries);
|
||||
virtual ~ogr_index_featureset();
|
||||
mapnik::feature_ptr next();
|
||||
private:
|
||||
//no copying
|
||||
ogr_index_featureset(const ogr_index_featureset&);
|
||||
ogr_index_featureset& operator=(const ogr_index_featureset&);
|
||||
};
|
||||
|
||||
#endif // OGR_FEATURESET_HPP
|
Loading…
Add table
Reference in a new issue