initial import
This commit is contained in:
commit
ebcdd3cf90
32 changed files with 3163 additions and 0 deletions
18
postgis/Jamfile
Normal file
18
postgis/Jamfile
Normal file
|
@ -0,0 +1,18 @@
|
|||
#postgis datasource plugin
|
||||
|
||||
project
|
||||
: usage-requirements
|
||||
<include>/opt/postgresql8/include
|
||||
;
|
||||
lib pq
|
||||
:
|
||||
: <file>/opt/postgresql8/lib/libpq.so
|
||||
;
|
||||
|
||||
lib postgis
|
||||
:
|
||||
postgis.cc
|
||||
postgisfs.cc
|
||||
pq
|
||||
;
|
||||
|
24
postgis/SConscript
Normal file
24
postgis/SConscript
Normal file
|
@ -0,0 +1,24 @@
|
|||
#mapnik
|
||||
|
||||
Import ('env')
|
||||
|
||||
prefix = env['PREFIX']
|
||||
boost_root = env['BOOST_ROOT']
|
||||
postgresql_root = env['POSTGRESQL_ROOT']
|
||||
agg_root = env['AGG_ROOT']
|
||||
agg_headers = agg_root + '/include'
|
||||
|
||||
postgresql_headers=postgresql_root+"/include"
|
||||
postgresql_libs=postgresql_root+"/lib"
|
||||
|
||||
postgis_src = Split(
|
||||
"""
|
||||
postgis.cpp
|
||||
postgisfs.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
headers = ['#include',boost_root,agg_headers,postgresql_headers]
|
||||
postgis_datasource = env.SharedLibrary('postgis',source=postgis_src,SHLIBPREFIX='',CPPPATH=headers,LIBS="pq",LIBPATH=postgresql_libs)
|
||||
env.Install(prefix + '/datasources',postgis_datasource)
|
||||
env.Alias("install",prefix + '/datasources')
|
85
postgis/connection.hpp
Normal file
85
postgis/connection.hpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: connection.hpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#ifndef CONNECTION_HPP
|
||||
#define CONNECTION_HPP
|
||||
|
||||
|
||||
#include "libpq-fe.h"
|
||||
#include "mapnik.hpp"
|
||||
#include "resultset.hpp"
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
class ResultSet;
|
||||
|
||||
class Connection
|
||||
{
|
||||
private:
|
||||
PGconn *conn_;
|
||||
public:
|
||||
Connection(const std::string& uri,const std::string& dbname,
|
||||
const std::string& username,const std::string& password)
|
||||
{
|
||||
std::string connStr="host="+uri+" dbname="+dbname+" user="+username+" password="+password;
|
||||
conn_=PQconnectdb(connStr.c_str());
|
||||
if (PQstatus(conn_) == CONNECTION_BAD)
|
||||
{
|
||||
std::cerr << "connection to "<< connStr << " failed\n"
|
||||
<< PQerrorMessage(conn_)<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout <<"connected ok "<<std::endl;
|
||||
}
|
||||
}
|
||||
bool execute(const std::string& sql) const
|
||||
{
|
||||
PGresult *result=PQexec(conn_,sql.c_str());
|
||||
bool ok=(result && PQresultStatus(result)==PGRES_COMMAND_OK);
|
||||
PQclear(result);
|
||||
return ok;
|
||||
}
|
||||
ref_ptr<ResultSet> executeQuery(const std::string& sql,int type=0) const
|
||||
{
|
||||
PGresult *result=0;
|
||||
if (type==1)
|
||||
{
|
||||
result=PQexecParams(conn_,sql.c_str(),0,0,0,0,0,1);
|
||||
return ref_ptr<ResultSet>(new ResultSet(result));
|
||||
}
|
||||
result=PQexec(conn_,sql.c_str());
|
||||
return ref_ptr<ResultSet>(new ResultSet(result));
|
||||
}
|
||||
bool isOK() const
|
||||
{
|
||||
return (PQstatus(conn_)!=CONNECTION_BAD);
|
||||
}
|
||||
void close()
|
||||
{
|
||||
PQfinish(conn_);
|
||||
}
|
||||
~Connection()
|
||||
{
|
||||
PQfinish(conn_);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //CONNECTION_HPP
|
111
postgis/connection_manager.hpp
Normal file
111
postgis/connection_manager.hpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: connection_manager.hpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#ifndef CONNECTION_MANAGER_HPP
|
||||
#define CONNECTION_MANAGER_HPP
|
||||
|
||||
#include <string>
|
||||
#include "pool.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "connection.hpp"
|
||||
|
||||
using namespace mapnik;
|
||||
using std::string;
|
||||
|
||||
template <typename T>
|
||||
class ConnectionCreator
|
||||
{
|
||||
string url_;
|
||||
string dbname_;
|
||||
string user_;
|
||||
string pass_;
|
||||
public:
|
||||
ConnectionCreator(const string& url,const string& dbname,
|
||||
const string& user,const string& pass)
|
||||
: url_(url),
|
||||
dbname_(dbname),
|
||||
user_(user),
|
||||
pass_(pass) {}
|
||||
|
||||
T* operator()() const
|
||||
{
|
||||
return new T(url_,dbname_,user_,pass_);
|
||||
}
|
||||
std::string id() const
|
||||
{
|
||||
return url_+":"+dbname_+":"+user_+":"+pass_;
|
||||
}
|
||||
};
|
||||
|
||||
class ConnectionManager : public singleton <ConnectionManager,CreateStatic>
|
||||
{
|
||||
|
||||
friend class CreateStatic<ConnectionManager>;
|
||||
typedef Pool<Connection,ConnectionCreator> PoolType;
|
||||
typedef std::map<std::string,ref_ptr<PoolType> > ContType;
|
||||
typedef ref_ptr<Connection> HolderType;
|
||||
ContType pools_;
|
||||
|
||||
public:
|
||||
|
||||
bool registerPool(const ConnectionCreator<Connection>& creator,int initialSize,int maxSize)
|
||||
{
|
||||
Lock lock(&mutex_);
|
||||
if (pools_.find(creator.id())==pools_.end())
|
||||
{
|
||||
return pools_.insert(std::make_pair(creator.id(),
|
||||
ref_ptr<PoolType>(new PoolType(creator,initialSize,maxSize)))).second;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
const ref_ptr<PoolType>& getPool(const std::string& key)
|
||||
{
|
||||
Lock lock(&mutex_);
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
if (itr!=pools_.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
static const ref_ptr<PoolType> emptyPool(0);
|
||||
return emptyPool;
|
||||
}
|
||||
|
||||
const HolderType& get(const std::string& key)
|
||||
{
|
||||
Lock lock(&mutex_);
|
||||
ContType::const_iterator itr=pools_.find(key);
|
||||
if (itr!=pools_.end())
|
||||
{
|
||||
ref_ptr<PoolType> pool=itr->second;
|
||||
return pool->borrowObject();
|
||||
}
|
||||
static const HolderType EmptyConn(0);
|
||||
return EmptyConn;
|
||||
}
|
||||
|
||||
private:
|
||||
ConnectionManager() {}
|
||||
ConnectionManager(const ConnectionManager&);
|
||||
ConnectionManager& operator=(const ConnectionManager);
|
||||
};
|
||||
|
||||
#endif //CONNECTION_MANAGER_HPP
|
214
postgis/postgis.cpp
Normal file
214
postgis/postgis.cpp
Normal file
|
@ -0,0 +1,214 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: postgis.cc 44 2005-04-22 18:53:54Z pavlenko $
|
||||
|
||||
#include "postgis.hpp"
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include "connection_manager.hpp"
|
||||
|
||||
DATASOURCE_PLUGIN(PostgisDatasource);
|
||||
|
||||
const std::string PostgisDatasource::GEOMETRY_COLUMNS="geometry_columns";
|
||||
const std::string PostgisDatasource::SPATIAL_REF_SYS="spatial_ref_system";
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using boost::lexical_cast;
|
||||
using boost::bad_lexical_cast;
|
||||
|
||||
PostgisDatasource::PostgisDatasource(const Parameters& params)
|
||||
: table_(params.get("table")),
|
||||
type_(datasource::Vector),
|
||||
desc_(params.get("name")),
|
||||
creator_(params.get("host"),
|
||||
params.get("dbname"),
|
||||
params.get("user"),
|
||||
params.get("password"))
|
||||
|
||||
{
|
||||
ConnectionManager *mgr=ConnectionManager::instance();
|
||||
mgr->registerPool(creator_,10,20);
|
||||
|
||||
ref_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
||||
if (pool)
|
||||
{
|
||||
const ref_ptr<Connection>& conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
PoolGuard<ref_ptr<Connection>,ref_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
|
||||
|
||||
std::string table_name=table_from_sql(table_);
|
||||
|
||||
std::ostringstream s;
|
||||
s << "select f_geometry_column,srid,type from ";
|
||||
s << GEOMETRY_COLUMNS <<" where f_table_name='"<<table_name<<"'";
|
||||
|
||||
ref_ptr<ResultSet> rs=conn->executeQuery(s.str());
|
||||
|
||||
if (rs->next())
|
||||
{
|
||||
try
|
||||
{
|
||||
srid_ = lexical_cast<int>(rs->getValue("srid"));
|
||||
desc_.set_srid(srid_);
|
||||
}
|
||||
catch (bad_lexical_cast &ex)
|
||||
{
|
||||
cerr << ex.what() << endl;
|
||||
}
|
||||
geometryColumn_=rs->getValue("f_geometry_column");
|
||||
std::string postgisType=rs->getValue("type");
|
||||
}
|
||||
rs->close();
|
||||
s.str("");
|
||||
s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)";
|
||||
s << " from (select estimated_extent('"<<table_name<<"','"<<geometryColumn_<<"') as ext) as tmp";
|
||||
|
||||
rs=conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
try
|
||||
{
|
||||
double lox=lexical_cast<double>(rs->getValue(0));
|
||||
double loy=lexical_cast<double>(rs->getValue(1));
|
||||
double hix=lexical_cast<double>(rs->getValue(2));
|
||||
double hiy=lexical_cast<double>(rs->getValue(3));
|
||||
extent_.init(lox,loy,hix,hiy);
|
||||
}
|
||||
catch (bad_lexical_cast &ex)
|
||||
{
|
||||
cerr << ex.what() << endl;
|
||||
}
|
||||
}
|
||||
rs->close();
|
||||
|
||||
// collect attribute desc
|
||||
s.str("");
|
||||
s << "select * from "<<table_<<" limit 1";
|
||||
rs=conn->executeQuery(s.str());
|
||||
if (rs->next())
|
||||
{
|
||||
int count = rs->getNumFields();
|
||||
for (int i=0;i<count;++i)
|
||||
{
|
||||
std::string fld_name=rs->getFieldName(i);
|
||||
int length = rs->getFieldLength(i);
|
||||
|
||||
int type_oid = rs->getTypeOID(i);
|
||||
switch (type_oid)
|
||||
{
|
||||
case 17285: // geometry
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,Geometry));
|
||||
break;
|
||||
case 21: // int2
|
||||
case 23: // int4
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,Integer,false,length));
|
||||
break;
|
||||
case 1043: // varchar
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,String));
|
||||
break;
|
||||
default: // shouldn't get here
|
||||
cout << "unknown type_oid="<<type_oid<<endl;
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,String));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string PostgisDatasource::name_="postgis";
|
||||
|
||||
std::string PostgisDatasource::name()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
int PostgisDatasource::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
layer_descriptor const& PostgisDatasource::get_descriptor() const
|
||||
{
|
||||
return desc_;
|
||||
}
|
||||
|
||||
std::string PostgisDatasource::table_from_sql(const std::string& sql)
|
||||
{
|
||||
std::string table_name(sql);
|
||||
transform(table_name.begin(),table_name.end(),table_name.begin(),tolower);
|
||||
std::string::size_type idx=table_name.rfind("from");
|
||||
if (idx!=std::string::npos)
|
||||
{
|
||||
idx=table_name.find_first_not_of(" ",idx+4);
|
||||
table_name=table_name.substr(idx);
|
||||
idx=table_name.find_first_of(" )");
|
||||
return table_name.substr(0,idx);
|
||||
}
|
||||
return table_name;
|
||||
}
|
||||
|
||||
featureset_ptr PostgisDatasource::features(const query& q) const
|
||||
{
|
||||
Featureset *fs=0;
|
||||
Envelope<double> const& box=q.get_bbox();
|
||||
ConnectionManager *mgr=ConnectionManager::instance();
|
||||
ref_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
|
||||
if (pool)
|
||||
{
|
||||
const ref_ptr<Connection>& conn = pool->borrowObject();
|
||||
if (conn && conn->isOK())
|
||||
{
|
||||
PoolGuard<ref_ptr<Connection>,ref_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
|
||||
std::ostringstream s;
|
||||
// can we rely on 'gid' name???
|
||||
s << "select gid,asbinary("<<geometryColumn_<<") as geom";
|
||||
std::set<std::string> const& props=q.property_names();
|
||||
std::set<std::string>::const_iterator pos=props.begin();
|
||||
while (pos!=props.end())
|
||||
{
|
||||
s <<",\""<<*pos<<"\"";
|
||||
++pos;
|
||||
}
|
||||
|
||||
s << " from " << table_<<" where "<<geometryColumn_<<" && setSRID('BOX3D(";
|
||||
s << box.minx() << " " << box.miny() << ",";
|
||||
s << box.maxx() << " " << box.maxy() << ")'::box3d,"<<srid_<<")";
|
||||
cout << s.str() << endl;
|
||||
ref_ptr<ResultSet> rs=conn->executeQuery(s.str(),1);
|
||||
fs=new PostgisFeatureset(rs,props.size());
|
||||
}
|
||||
}
|
||||
return featureset_ptr(fs);
|
||||
}
|
||||
|
||||
const Envelope<double>& PostgisDatasource::envelope() const
|
||||
{
|
||||
return extent_;
|
||||
}
|
||||
|
||||
PostgisDatasource::~PostgisDatasource() {}
|
79
postgis/postgis.hpp
Normal file
79
postgis/postgis.hpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: postgis.hpp 44 2005-04-22 18:53:54Z pavlenko $
|
||||
|
||||
#ifndef POSTGIS_HPP
|
||||
#define POSTGIS_HPP
|
||||
|
||||
|
||||
#include "mapnik.hpp"
|
||||
#include "connection_manager.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
class PostgisDatasource : public datasource
|
||||
{
|
||||
static const std::string GEOMETRY_COLUMNS;
|
||||
static const std::string SPATIAL_REF_SYS;
|
||||
const std::string uri_;
|
||||
const std::string username_;
|
||||
const std::string password_;
|
||||
const std::string table_;
|
||||
std::string geometryColumn_;
|
||||
int type_;
|
||||
int srid_;
|
||||
mapnik::Envelope<double> extent_;
|
||||
layer_descriptor desc_;
|
||||
ConnectionCreator<Connection> creator_;
|
||||
static std::string name_;
|
||||
public:
|
||||
static std::string name();
|
||||
int type() const;
|
||||
featureset_ptr features(const query& q) const;
|
||||
mapnik::Envelope<double> const& envelope() const;
|
||||
layer_descriptor const& get_descriptor() const;
|
||||
PostgisDatasource(const Parameters ¶ms);
|
||||
~PostgisDatasource();
|
||||
private:
|
||||
static std::string table_from_sql(const std::string& sql);
|
||||
PostgisDatasource(const PostgisDatasource&);
|
||||
PostgisDatasource& operator=(const PostgisDatasource&);
|
||||
};
|
||||
|
||||
class PostgisFeatureset : public Featureset
|
||||
{
|
||||
private:
|
||||
ref_ptr<ResultSet> rs_;
|
||||
unsigned num_attrs_;
|
||||
mutable int totalGeomSize_;
|
||||
mutable int count_;
|
||||
public:
|
||||
PostgisFeatureset(const ref_ptr<ResultSet>& rs,unsigned num_attrs);
|
||||
void dispose();
|
||||
Feature* next();
|
||||
~PostgisFeatureset();
|
||||
private:
|
||||
PostgisFeatureset(const PostgisFeatureset&);
|
||||
const PostgisFeatureset& operator=(const PostgisFeatureset&);
|
||||
};
|
||||
|
||||
#endif //POSTGIS_HPP
|
92
postgis/postgisfs.cpp
Normal file
92
postgis/postgisfs.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: postgisfs.cc 34 2005-04-04 13:27:23Z pavlenko $
|
||||
|
||||
|
||||
#include "postgis.hpp"
|
||||
|
||||
using boost::lexical_cast;
|
||||
using boost::bad_lexical_cast;
|
||||
using std::string;
|
||||
|
||||
PostgisFeatureset::PostgisFeatureset(const ref_ptr<ResultSet>& rs,
|
||||
unsigned num_attrs=0)
|
||||
: rs_(rs),
|
||||
num_attrs_(num_attrs),
|
||||
totalGeomSize_(0),
|
||||
count_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Feature* PostgisFeatureset::next()
|
||||
{
|
||||
Feature *feature=0;
|
||||
if (rs_->next())
|
||||
{
|
||||
const char* buf = rs_->getValue(0);
|
||||
int id = (buf[0]&255) << 24 | (buf[1]&255) << 16 | (buf[2] & 255) << 8 | buf[3] & 255;
|
||||
|
||||
int size=rs_->getFieldLength(1);
|
||||
const char *data=rs_->getValue(1);
|
||||
geometry_ptr geom=geometry_utils::from_wkb(data,size,-1);
|
||||
totalGeomSize_+=size;
|
||||
|
||||
if (geom)
|
||||
{
|
||||
feature=new Feature(id,geom);
|
||||
|
||||
unsigned start=2;
|
||||
for (unsigned pos=0;pos<num_attrs_;++pos)
|
||||
{
|
||||
const char* buf=rs_->getValue(start + pos);
|
||||
int field_size = rs_->getFieldLength(start + pos);
|
||||
int oid = rs_->getTypeOID(start + pos);
|
||||
if (oid==23)
|
||||
{
|
||||
int val = (buf[0]&255) << 24 | (buf[1]&255) << 16 | (buf[2] & 255) << 8 | buf[3] & 255;
|
||||
feature->add_property(val);
|
||||
}
|
||||
else if (oid==1043)
|
||||
{
|
||||
feature->add_property(string(buf));
|
||||
}
|
||||
else
|
||||
{
|
||||
feature->add_property(string("null"));
|
||||
}
|
||||
}
|
||||
++count_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rs_->close();
|
||||
std::cout << "totalGeomSize="<<totalGeomSize_<<" bytes"<<std::endl;
|
||||
std::cout << "count="<<count_<<std::endl;
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
||||
|
||||
PostgisFeatureset::~PostgisFeatureset()
|
||||
{
|
||||
rs_->close();
|
||||
}
|
71
postgis/property_index.hpp
Normal file
71
postgis/property_index.hpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
|
||||
#ifndef PROPERTY_VALIDATOR
|
||||
#define PROPERTY_VALIDATOR
|
||||
|
||||
#include "filter.hh"
|
||||
#include "expression.hh"
|
||||
#include <set>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename FeatureT>
|
||||
class property_validator : public filter_visitor<FeatureT>
|
||||
{
|
||||
public:
|
||||
property_validator(layer_descriptor& desc)
|
||||
desc_(desc) {}
|
||||
|
||||
void visit(filter<FeatureT>& /*filter*/)
|
||||
{
|
||||
//not interested
|
||||
}
|
||||
void visit(expression<FeatureT>& exp)
|
||||
{
|
||||
property<FeatureT>* pf;
|
||||
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
|
||||
{
|
||||
vector<attribute_descriptor> const& attr_desc = desc_.get_descriptors();
|
||||
for (size_t idx=0; idx < attr_desc.size();++idx)
|
||||
{
|
||||
if (attr_desc[idx] == pf->name())
|
||||
{
|
||||
pf->set_index(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::set<std::string> const& property_names() const
|
||||
{
|
||||
return names_;
|
||||
}
|
||||
|
||||
virtual ~property_validator() {}
|
||||
private:
|
||||
property_validator(property_validator const&);
|
||||
property_validator& operator=(property_validator const&);
|
||||
private:
|
||||
layer_descriptor& desc_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PROPERTY_HPP
|
138
postgis/resultset.hpp
Normal file
138
postgis/resultset.hpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: resultset.hpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
|
||||
#ifndef RESULTSET_HPP
|
||||
#define RESULTSET_HPP
|
||||
|
||||
#include "connection.hpp"
|
||||
|
||||
class ResultSet
|
||||
{
|
||||
private:
|
||||
PGresult* res_;
|
||||
int pos_;
|
||||
int numTuples_;
|
||||
int *refCount_;
|
||||
public:
|
||||
ResultSet(PGresult *res)
|
||||
:res_(res),pos_(-1),refCount_(new int(1))
|
||||
{
|
||||
numTuples_=PQntuples(res_);
|
||||
}
|
||||
|
||||
ResultSet(const ResultSet& rhs)
|
||||
:res_(rhs.res_),
|
||||
pos_(rhs.pos_),
|
||||
numTuples_(rhs.numTuples_),
|
||||
refCount_(rhs.refCount_)
|
||||
{
|
||||
(*refCount_)++;
|
||||
}
|
||||
|
||||
ResultSet& operator=(const ResultSet& rhs)
|
||||
{
|
||||
if (this==&rhs) return *this;
|
||||
if (--(refCount_)==0)
|
||||
{
|
||||
close();
|
||||
delete refCount_,refCount_=0;
|
||||
}
|
||||
res_=rhs.res_;
|
||||
pos_=rhs.pos_;
|
||||
numTuples_=rhs.numTuples_;
|
||||
refCount_=rhs.refCount_;
|
||||
(*refCount_)++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
PQclear(res_),res_=0;
|
||||
}
|
||||
|
||||
~ResultSet()
|
||||
{
|
||||
if (--(*refCount_)==0)
|
||||
{
|
||||
PQclear(res_);
|
||||
delete refCount_,refCount_=0;
|
||||
}
|
||||
}
|
||||
|
||||
int getNumFields() const
|
||||
{
|
||||
return PQnfields(res_);
|
||||
}
|
||||
|
||||
bool next()
|
||||
{
|
||||
return (++pos_<numTuples_);
|
||||
}
|
||||
|
||||
const char* getFieldName(int index) const
|
||||
{
|
||||
return PQfname(res_,index);
|
||||
}
|
||||
|
||||
int getFieldLength(int index) const
|
||||
{
|
||||
return PQgetlength(res_,pos_,index);
|
||||
}
|
||||
|
||||
int getFieldLength(const char* name) const
|
||||
{
|
||||
int col=PQfnumber(res_,name);
|
||||
if (col>=0)
|
||||
return PQgetlength(res_,pos_,col);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getTypeOID(int index) const
|
||||
{
|
||||
return PQftype(res_,index);
|
||||
}
|
||||
|
||||
int getTypeOID(const char* name) const
|
||||
{
|
||||
int col=PQfnumber(res_,name);
|
||||
if (col>=0)
|
||||
return PQftype(res_,col);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* getValue(int index) const
|
||||
{
|
||||
return PQgetvalue(res_,pos_,index);
|
||||
}
|
||||
|
||||
const char* getValue(const char* name) const
|
||||
{
|
||||
int col=PQfnumber(res_,name);
|
||||
if (col>=0)
|
||||
return getValue(col);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //RESULTSET_HPP
|
||||
|
||||
|
||||
|
91
raster/raster_datasource.cpp
Normal file
91
raster/raster_datasource.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: raster_datasource.cc 44 2005-04-22 18:53:54Z pavlenko $
|
||||
|
||||
#include "raster_datasource.hh"
|
||||
#include "image_reader.hh"
|
||||
#include "raster_featureset.hh"
|
||||
#include "raster_info.hh"
|
||||
|
||||
DATASOURCE_PLUGIN(raster_datasource);
|
||||
|
||||
raster_datasource::raster_datasource(const Parameters& params)
|
||||
: extent_()
|
||||
{
|
||||
filename_=params.get("file");
|
||||
format_=params.get("format");
|
||||
|
||||
double lox,loy,hix,hiy;
|
||||
fromString<double>(params.get("lox"),lox);
|
||||
fromString<double>(params.get("loy"),loy);
|
||||
fromString<double>(params.get("hix"),hix);
|
||||
fromString<double>(params.get("hiy"),hiy);
|
||||
|
||||
extent_=Envelope<double>(lox,loy,hix,hiy);
|
||||
}
|
||||
|
||||
|
||||
raster_datasource::~raster_datasource()
|
||||
{
|
||||
}
|
||||
|
||||
std::string raster_datasource::name_="raster";
|
||||
|
||||
int raster_datasource::type() const
|
||||
{
|
||||
return datasource::Raster;
|
||||
}
|
||||
|
||||
|
||||
std::string raster_datasource::name()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
bool raster_datasource::parseEnvelope(const std::string& str,Envelope<double>& envelope)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const mapnik::Envelope<double>& raster_datasource::envelope() const
|
||||
{
|
||||
return extent_;
|
||||
}
|
||||
|
||||
|
||||
featureset_ptr raster_datasource::featuresAll(const CoordTransform& t) const
|
||||
{
|
||||
return featureset_ptr(0);
|
||||
}
|
||||
|
||||
|
||||
featureset_ptr raster_datasource::featuresInBox(const CoordTransform& t,
|
||||
const mapnik::Envelope<double>& box) const
|
||||
{
|
||||
RasterInfo info(filename_,format_,extent_);
|
||||
single_file_policy policy(info); //todo: handle different policies!
|
||||
return featureset_ptr(new RasterFeatureset<single_file_policy>(policy,box,t));
|
||||
}
|
||||
|
||||
|
||||
featureset_ptr raster_datasource::featuresAtPoint(const CoordTransform& t,
|
||||
const coord2d& pt) const
|
||||
{
|
||||
return featureset_ptr(0);
|
||||
}
|
53
raster/raster_datasource.hpp
Normal file
53
raster/raster_datasource.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: raster_datasource.hh 44 2005-04-22 18:53:54Z pavlenko $
|
||||
|
||||
#ifndef RASTER_DATASOURCE_HH
|
||||
#define RASTER_DATASOURCE_HH
|
||||
|
||||
#include "mapnik.hh"
|
||||
#include "image_reader.hh"
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
class raster_datasource : public datasource
|
||||
{
|
||||
private:
|
||||
std::string filename_;
|
||||
std::string format_;
|
||||
mapnik::Envelope<double> extent_;
|
||||
static std::string name_;
|
||||
public:
|
||||
raster_datasource(const Parameters& params);
|
||||
virtual ~raster_datasource();
|
||||
int type() const;
|
||||
std::string name();
|
||||
featureset_ptr featuresAll(const CoordTransform& t) const;
|
||||
featureset_ptr featuresInBox(const CoordTransform& t,const mapnik::Envelope<double>& box) const;
|
||||
featureset_ptr featuresAtPoint(const CoordTransform& t,const coord2d& pt) const;
|
||||
const mapnik::Envelope<double>& envelope() const;
|
||||
private:
|
||||
//no copying
|
||||
raster_datasource(const raster_datasource&);
|
||||
raster_datasource& operator=(const raster_datasource&);
|
||||
//
|
||||
bool parseEnvelope(const std::string& str,Envelope<double>& envelope);
|
||||
};
|
||||
|
||||
#endif //RASTER_DATASOURCE_H
|
81
raster/raster_featureset.cpp
Normal file
81
raster/raster_featureset.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "raster_featureset.hh"
|
||||
#include "image_reader.hh"
|
||||
|
||||
template <typename LookupPolicy>
|
||||
RasterFeatureset<LookupPolicy>::RasterFeatureset(const LookupPolicy& policy,
|
||||
const Envelope<double>& box,
|
||||
const CoordTransform& t)
|
||||
: policy_(policy),
|
||||
id_(1),
|
||||
extent_(box),
|
||||
t_(t),
|
||||
curIter_(policy_.query(box)),
|
||||
endIter_(policy_.end())
|
||||
|
||||
{}
|
||||
|
||||
template <typename LookupPolicy>
|
||||
RasterFeatureset<LookupPolicy>::~RasterFeatureset() {}
|
||||
|
||||
template <typename LookupPolicy>
|
||||
Feature* RasterFeatureset<LookupPolicy>::next()
|
||||
{
|
||||
Feature* f=0;
|
||||
if (curIter_!=endIter_)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout<<"RasterFeatureset "<<curIter_->format()<<" "<<curIter_->file()<<std::endl;
|
||||
std::auto_ptr<ImageReader> reader(get_image_reader(curIter_->format(),curIter_->file()));
|
||||
std::cout<<reader.get()<<std::endl;
|
||||
if (reader.get())
|
||||
{
|
||||
int image_width=reader->width();
|
||||
int image_height=reader->height();
|
||||
if (image_width>0 && image_height>0)
|
||||
{
|
||||
CoordTransform t(image_width,image_height,curIter_->envelope());
|
||||
Envelope<double> intersect=extent_.intersect(curIter_->envelope());
|
||||
Envelope<double> ext=t.forward(intersect);
|
||||
|
||||
Envelope<double> image_ext=t_.forward(intersect);
|
||||
|
||||
ImageData32 image((int)ext.width(),(int)ext.height());
|
||||
reader->read((int)ext.minx(),(int)ext.miny(),image);
|
||||
ImageData32 target((int)(image_ext.width()+0.5),(int)(image_ext.height()+0.5));
|
||||
scale_image<ImageData32>(target,image);
|
||||
|
||||
f=new RasterFeature(++id_,RasterPtr(new raster((int)(image_ext.minx()+0.5),
|
||||
(int)(image_ext.miny()+0.5),target)));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
++curIter_;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
template class RasterFeatureset<single_file_policy>;
|
||||
//template RasterFeatureset<os_name_policy>;
|
115
raster/raster_featureset.hpp
Normal file
115
raster/raster_featureset.hpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef RASTER_FEATURESET_HH
|
||||
#define RASTER_FEATURESET_HH
|
||||
|
||||
#include "raster_datasource.hh"
|
||||
#include "raster_info.hh"
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
class single_file_policy
|
||||
{
|
||||
RasterInfo info_;
|
||||
public:
|
||||
class const_iterator
|
||||
{
|
||||
enum {start,end};
|
||||
bool status_;
|
||||
const single_file_policy* p_;
|
||||
public:
|
||||
explicit const_iterator(const single_file_policy* p)
|
||||
:status_(start),
|
||||
p_(p) {}
|
||||
|
||||
const_iterator()
|
||||
:status_(end){}
|
||||
|
||||
const_iterator(const const_iterator& other)
|
||||
:status_(other.status_),
|
||||
p_(other.p_) {}
|
||||
|
||||
const_iterator& operator++()
|
||||
{
|
||||
status_=end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const RasterInfo& operator*() const
|
||||
{
|
||||
return p_->info_;
|
||||
}
|
||||
|
||||
const RasterInfo* operator->() const
|
||||
{
|
||||
return &(p_->info_);
|
||||
}
|
||||
|
||||
bool operator!=(const const_iterator& itr)
|
||||
{
|
||||
return status_!=itr.status_;
|
||||
}
|
||||
};
|
||||
|
||||
explicit single_file_policy(const RasterInfo& info)
|
||||
:info_(info) {}
|
||||
|
||||
const_iterator begin()
|
||||
{
|
||||
return const_iterator(this);
|
||||
}
|
||||
|
||||
const_iterator query(const Envelope<double>& box)
|
||||
{
|
||||
if (box.intersects(info_.envelope()))
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
const_iterator end()
|
||||
{
|
||||
return const_iterator();
|
||||
}
|
||||
};
|
||||
|
||||
class os_name_policy
|
||||
{
|
||||
//TODO
|
||||
};
|
||||
|
||||
template <typename LookupPolicy>
|
||||
class RasterFeatureset : public Featureset
|
||||
{
|
||||
typedef typename LookupPolicy::const_iterator iterator_type;
|
||||
LookupPolicy policy_;
|
||||
size_t id_;
|
||||
Envelope<double> extent_;
|
||||
CoordTransform t_;
|
||||
iterator_type curIter_;
|
||||
iterator_type endIter_;
|
||||
public:
|
||||
RasterFeatureset(const LookupPolicy& policy,const Envelope<double>& box,const CoordTransform& t);
|
||||
virtual ~RasterFeatureset();
|
||||
Feature* next();
|
||||
};
|
||||
|
||||
#endif //RASTER_FEATURESET_HH
|
71
raster/raster_info.cpp
Normal file
71
raster/raster_info.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: raster_info.cc 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#include "raster_info.hh"
|
||||
|
||||
RasterInfo::RasterInfo(const std::string& file,const std::string& format,const mapnik::Envelope<double>& extent,int srid)
|
||||
:file_(file),
|
||||
format_(format),
|
||||
extent_(extent),
|
||||
srid_(srid) {}
|
||||
|
||||
RasterInfo::RasterInfo(const RasterInfo& rhs)
|
||||
:file_(rhs.file_),
|
||||
format_(rhs.format_),
|
||||
extent_(rhs.extent_),
|
||||
srid_(rhs.srid_) {}
|
||||
|
||||
void RasterInfo::swap(RasterInfo& other) throw()
|
||||
{
|
||||
file_=other.file_;
|
||||
format_=other.format_;
|
||||
extent_=other.extent_;
|
||||
srid_=other.srid_;
|
||||
}
|
||||
|
||||
|
||||
RasterInfo& RasterInfo::operator=(const RasterInfo& rhs)
|
||||
{
|
||||
RasterInfo tmp(rhs);
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const Envelope<double>& RasterInfo::envelope() const
|
||||
{
|
||||
return extent_;
|
||||
}
|
||||
|
||||
|
||||
const std::string& RasterInfo::file() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
|
||||
const std::string& RasterInfo::format() const
|
||||
{
|
||||
return format_;
|
||||
}
|
||||
|
||||
const int RasterInfo::srid() const
|
||||
{
|
||||
return srid_;
|
||||
}
|
46
raster/raster_info.hpp
Normal file
46
raster/raster_info.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: raster_info.hh 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#ifndef RASTER_INFO
|
||||
#define RASTER_INFO
|
||||
|
||||
#include "raster_datasource.hh"
|
||||
#include <string>
|
||||
|
||||
using mapnik::Envelope;
|
||||
|
||||
class RasterInfo
|
||||
{
|
||||
std::string file_;
|
||||
std::string format_;
|
||||
Envelope<double> extent_;
|
||||
int srid_;
|
||||
public:
|
||||
RasterInfo(const std::string& file,const std::string& format,const Envelope<double>& extent,int srid=-1);
|
||||
RasterInfo(const RasterInfo& rhs);
|
||||
RasterInfo& operator=(const RasterInfo& rhs);
|
||||
const Envelope<double>& envelope() const;
|
||||
const std::string& file() const;
|
||||
const std::string& format() const;
|
||||
const int srid() const;
|
||||
private:
|
||||
void swap(RasterInfo& other) throw();
|
||||
};
|
||||
#endif //RASTER_INFO
|
11
shape/Jamfile
Normal file
11
shape/Jamfile
Normal file
|
@ -0,0 +1,11 @@
|
|||
lib shape :
|
||||
dbffile.cc
|
||||
dbf_test.cc
|
||||
shape.cc
|
||||
shape_featureset.cc
|
||||
shapefile.cc
|
||||
shape_index_featureset.cc
|
||||
shape_io.cc
|
||||
shp_index.cc
|
||||
;
|
||||
|
26
shape/SConscript
Normal file
26
shape/SConscript
Normal file
|
@ -0,0 +1,26 @@
|
|||
#mapnik
|
||||
|
||||
Import ('env')
|
||||
|
||||
prefix = env['PREFIX']
|
||||
boost_root = env['BOOST_ROOT']
|
||||
agg_root = env['AGG_ROOT']
|
||||
agg_headers = agg_root + '/include'
|
||||
|
||||
shape_src = Split(
|
||||
"""
|
||||
dbffile.cc
|
||||
shape.cc
|
||||
shape_featureset.cc
|
||||
shapefile.cc
|
||||
shape_index_featureset.cc
|
||||
shape_io.cc
|
||||
shp_index.cc
|
||||
"""
|
||||
)
|
||||
|
||||
headers = ['#include',boost_root,agg_headers]
|
||||
|
||||
shape_datasource = env.SharedLibrary('shape',source=shape_src,SHLIBPREFIX='',CPPPATH=headers)
|
||||
env.Install('#stage/datasources',shape_datasource)
|
||||
#env.Default(shape_datasource)
|
60
shape/dbf_test.cpp
Normal file
60
shape/dbf_test.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "dbffile.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
if (argc!=2)
|
||||
{
|
||||
cout<<"usage: dbfdump <file_name>"<<endl;
|
||||
return 0;
|
||||
}
|
||||
cout << argv[1]<<endl;
|
||||
dbf_file dbf(argv[1]);
|
||||
|
||||
cout<<endl;
|
||||
for (int i=0;i<dbf.num_records();++i)
|
||||
{
|
||||
dbf.move_to(i+1);
|
||||
if (!(i%10))
|
||||
{
|
||||
for (int j=0;j<dbf.num_fields();++j)
|
||||
{
|
||||
int width=dbf.descriptor(j).length_;
|
||||
string name=dbf.descriptor(j).name_;
|
||||
char type=dbf.descriptor(j).type_;
|
||||
cout<<setw(width)<<name<<"("<<type<<")""|";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
for (int j=0;j<dbf.num_fields();++j)
|
||||
{
|
||||
int width=dbf.descriptor(j).length_;
|
||||
string val=dbf.string_value(j);
|
||||
cout <<setw(width)<<val<<"|";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
cout<<"done!"<<endl;
|
||||
return 0;
|
||||
}
|
216
shape/dbffile.cpp
Normal file
216
shape/dbffile.cpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "dbffile.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
dbf_file::dbf_file()
|
||||
: num_records_(0),
|
||||
num_fields_(0),
|
||||
record_length_(0),
|
||||
record_(0) {}
|
||||
|
||||
dbf_file::dbf_file(const char* file_name)
|
||||
:num_records_(0),
|
||||
num_fields_(0),
|
||||
record_length_(0),
|
||||
record_(0)
|
||||
{
|
||||
file_.open(file_name);
|
||||
if (file_.is_open())
|
||||
{
|
||||
read_header();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dbf_file::~dbf_file()
|
||||
{
|
||||
::operator delete(record_);
|
||||
file_.close();
|
||||
}
|
||||
|
||||
|
||||
bool dbf_file::open(const std::string& file_name)
|
||||
{
|
||||
file_.open(file_name.c_str());
|
||||
if (file_.is_open())
|
||||
read_header();
|
||||
return file_?true:false;
|
||||
}
|
||||
|
||||
|
||||
bool dbf_file::is_open()
|
||||
{
|
||||
return file_.is_open();
|
||||
}
|
||||
|
||||
|
||||
void dbf_file::close()
|
||||
{
|
||||
if (file_ && file_.is_open())
|
||||
file_.close();
|
||||
}
|
||||
|
||||
|
||||
int dbf_file::num_records() const
|
||||
{
|
||||
return num_records_;
|
||||
}
|
||||
|
||||
|
||||
int dbf_file::num_fields() const
|
||||
{
|
||||
return num_fields_;
|
||||
}
|
||||
|
||||
|
||||
void dbf_file::move_to(int index)
|
||||
{
|
||||
if (index>0 && index<=num_records_)
|
||||
{
|
||||
long pos=(num_fields_<<5)+34+(index-1)*(record_length_+1);
|
||||
file_.seekg(pos,std::ios::beg);
|
||||
file_.read(record_,record_length_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string dbf_file::string_value(int col) const
|
||||
{
|
||||
if (col>=0 && col<num_fields_)
|
||||
{
|
||||
return std::string(record_+fields_[col].offset_,fields_[col].length_);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
const field_descriptor& dbf_file::descriptor(int col) const
|
||||
{
|
||||
assert(col>=0 && col<num_fields_);
|
||||
return fields_[col];
|
||||
}
|
||||
|
||||
|
||||
void dbf_file::add_attribute(int col,Feature* f) const throw()
|
||||
{
|
||||
if (col>=0 && col<num_fields_)
|
||||
{
|
||||
std::string name=fields_[col].name_;
|
||||
std::string str=trim(std::string(record_+fields_[col].offset_,fields_[col].length_));
|
||||
|
||||
switch (fields_[col].type_)
|
||||
{
|
||||
case 'C':
|
||||
case 'D'://todo handle date?
|
||||
case 'M':
|
||||
case 'L':
|
||||
{
|
||||
f->add_property(name,str);
|
||||
break;
|
||||
}
|
||||
case 'N':
|
||||
case 'F':
|
||||
{
|
||||
if (str[0]=='*')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (fields_[col].dec_>0)
|
||||
{
|
||||
double d;
|
||||
fromString(str,d);
|
||||
|
||||
f->add_property(name,d);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
fromString(str,i);
|
||||
f->add_property(name,i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbf_file::read_header()
|
||||
{
|
||||
char c=file_.get();
|
||||
if (c=='\3' || c=='\131')
|
||||
{
|
||||
skip(3);
|
||||
num_records_=read_int();
|
||||
assert(num_records_>0);
|
||||
num_fields_=read_short();
|
||||
assert(num_fields_>0);
|
||||
num_fields_=(num_fields_-33)/32;
|
||||
skip(22);
|
||||
int offset=0;
|
||||
char name[11];
|
||||
memset(&name,0,11);
|
||||
fields_.reserve(num_fields_);
|
||||
for (int i=0;i<num_fields_;++i)
|
||||
{
|
||||
field_descriptor desc;
|
||||
desc.index_=i;
|
||||
file_.read(name,10);
|
||||
desc.name_=trim_left(name);
|
||||
skip(1);
|
||||
desc.type_=file_.get();
|
||||
skip(4);
|
||||
desc.length_=file_.get();
|
||||
desc.dec_=file_.get();
|
||||
skip(14);
|
||||
desc.offset_=offset;
|
||||
offset+=desc.length_;
|
||||
fields_.push_back(desc);
|
||||
}
|
||||
record_length_=offset;
|
||||
if (record_length_>0)
|
||||
{
|
||||
record_=static_cast<char*>(::operator new (sizeof(char)*record_length_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dbf_file::read_short()
|
||||
{
|
||||
char b[2];
|
||||
file_.read(b,2);
|
||||
return (b[0] & 0xff) | (b[1] & 0xff) << 8;
|
||||
}
|
||||
|
||||
|
||||
int dbf_file::read_int()
|
||||
{
|
||||
char b[4];
|
||||
file_.read(b,4);
|
||||
return (b[0] & 0xff) | (b[1] & 0xff) << 8 |
|
||||
(b[2] & 0xff) << 16 | (b[3] & 0xff) <<24;
|
||||
}
|
||||
|
||||
|
||||
void dbf_file::skip(int bytes)
|
||||
{
|
||||
file_.seekg(bytes,std::ios::cur);
|
||||
}
|
73
shape/dbffile.hpp
Normal file
73
shape/dbffile.hpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef DBFFILE_HH
|
||||
#define DBFFILE_HH
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
#include "mapnik.hh"
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
struct field_descriptor
|
||||
{
|
||||
int index_;
|
||||
std::string name_;
|
||||
char type_;
|
||||
int length_;
|
||||
int dec_;
|
||||
int offset_;
|
||||
};
|
||||
|
||||
class dbf_file
|
||||
{
|
||||
private:
|
||||
|
||||
int num_records_;
|
||||
int num_fields_;
|
||||
int record_length_;
|
||||
std::vector<field_descriptor> fields_;
|
||||
std::ifstream file_;
|
||||
char* record_;
|
||||
public:
|
||||
dbf_file();
|
||||
dbf_file(const char* file_name);
|
||||
dbf_file(const std::string& file_name);
|
||||
~dbf_file();
|
||||
bool open(const std::string& file_name);
|
||||
bool is_open();
|
||||
void close();
|
||||
int num_records() const;
|
||||
int num_fields() const;
|
||||
const field_descriptor& descriptor(int col) const;
|
||||
void move_to(int index);
|
||||
std::string string_value(int col) const;
|
||||
void add_attribute(int col,Feature* f) const throw();
|
||||
private:
|
||||
dbf_file(const dbf_file&);
|
||||
dbf_file& operator=(const dbf_file&);
|
||||
void read_header();
|
||||
int read_short();
|
||||
int read_int();
|
||||
void skip(int bytes);
|
||||
};
|
||||
#endif //DBFFILE_HH
|
113
shape/shape.cpp
Normal file
113
shape/shape.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "shape.hh"
|
||||
#include "shape_featureset.hh"
|
||||
#include "shape_index_featureset.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
DATASOURCE_PLUGIN(shape_datasource);
|
||||
|
||||
shape_datasource::shape_datasource(const Parameters ¶ms)
|
||||
: shape_name_(params.get("file")),
|
||||
type_(datasource::Vector),
|
||||
file_length_(0),
|
||||
indexed_(false)
|
||||
{
|
||||
try
|
||||
{
|
||||
shape_io shape(shape_name_);
|
||||
init(shape);
|
||||
}
|
||||
catch (datasource_exception& ex)
|
||||
{
|
||||
std::cerr<<ex.what()<<std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
shape_datasource::~shape_datasource()
|
||||
{
|
||||
}
|
||||
|
||||
std::string shape_datasource::name_="shape";
|
||||
|
||||
void shape_datasource::init(shape_io& shape)
|
||||
{
|
||||
//first read header from *.shp
|
||||
int file_code=shape.shp().read_xdr_integer();
|
||||
if (file_code!=9994)
|
||||
{
|
||||
//invalid
|
||||
throw datasource_exception("wrong file code");
|
||||
}
|
||||
shape.shp().skip(5*4);
|
||||
file_length_=shape.shp().read_xdr_integer();
|
||||
int version=shape.shp().read_ndr_integer();
|
||||
if (version!=1000)
|
||||
{
|
||||
//invalid version number
|
||||
throw datasource_exception("invalid version number");
|
||||
}
|
||||
int shape_type=shape.shp().read_ndr_integer();
|
||||
shape.shp().read_envelope(extent_);
|
||||
shape.shp().skip(4*8);
|
||||
|
||||
// check if we have an index file around
|
||||
std::string index_name(shape_name_+".index");
|
||||
std::ifstream file(index_name.c_str(),std::ios::in | std::ios::binary);
|
||||
if (file)
|
||||
{
|
||||
indexed_=true;
|
||||
file.close();
|
||||
}
|
||||
|
||||
std::cout<<extent_<<std::endl;
|
||||
std::cout<<"file_length="<<file_length_<<std::endl;
|
||||
std::cout<<"shape_type="<<shape_type<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
int shape_datasource::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
|
||||
std::string shape_datasource::name()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
featureset_ptr shape_datasource::features(const query& q) const
|
||||
{
|
||||
filter_in_box filter(q.get_bbox());
|
||||
if (indexed_)
|
||||
{
|
||||
return featureset_ptr(new shape_index_featureset<filter_in_box>(filter,shape_name_,q.property_names()));
|
||||
}
|
||||
return featureset_ptr(new shape_featureset<filter_in_box>(filter,shape_name_,q.property_names(),file_length_));
|
||||
}
|
||||
|
||||
const Envelope<double>& shape_datasource::envelope() const
|
||||
{
|
||||
return extent_;
|
||||
}
|
48
shape/shape.hpp
Normal file
48
shape/shape.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHAPE_HH
|
||||
#define SHAPE_HH
|
||||
|
||||
#include "mapnik.hh"
|
||||
#include "shape_io.hh"
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
class shape_datasource : public datasource
|
||||
{
|
||||
std::string shape_name_;
|
||||
int type_;
|
||||
long file_length_;
|
||||
mapnik::Envelope<double> extent_;
|
||||
bool indexed_;
|
||||
static std::string name_;
|
||||
public:
|
||||
int type() const;
|
||||
static std::string name();
|
||||
featureset_ptr features(const query& q) const;
|
||||
const Envelope<double>& envelope() const;
|
||||
shape_datasource(const Parameters ¶ms);
|
||||
virtual ~shape_datasource();
|
||||
private:
|
||||
shape_datasource(const shape_datasource&);
|
||||
shape_datasource& operator=(const shape_datasource&);
|
||||
void init(shape_io& shape);
|
||||
};
|
||||
|
||||
#endif //SHAPE_HH
|
180
shape/shape_featureset.cpp
Normal file
180
shape/shape_featureset.cpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "shape_featureset.hh"
|
||||
#include <iostream>
|
||||
|
||||
template <typename filterT>
|
||||
shape_featureset<filterT>::shape_featureset(const filterT& filter,
|
||||
const std::string& shape_file,
|
||||
const std::set<std::string>& attribute_names,
|
||||
long file_length )
|
||||
: filter_(filter),
|
||||
shape_type_(shape_io::shape_null),
|
||||
shape_(shape_file),
|
||||
query_ext_(),
|
||||
file_length_(file_length),
|
||||
count_(0)
|
||||
{
|
||||
shape_.shp().skip(100);
|
||||
//attributes
|
||||
typename std::set<std::string>::const_iterator pos=attribute_names.begin();
|
||||
while (pos!=attribute_names.end())
|
||||
{
|
||||
for (int i=0;i<shape_.dbf().num_fields();++i)
|
||||
{
|
||||
if (shape_.dbf().descriptor(i).name_ == *pos)
|
||||
{
|
||||
attr_ids_.push_back(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
Feature* shape_featureset<filterT>::next()
|
||||
{
|
||||
Feature* feature=0;
|
||||
std::streampos pos=shape_.shp().pos();
|
||||
|
||||
if (pos < std::streampos(file_length_ * 2))
|
||||
{
|
||||
shape_.move_to(pos);
|
||||
int type=shape_.type();
|
||||
int id=shape_.id_;
|
||||
if (type == shape_io::shape_point)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
feature=new Feature(id,point);
|
||||
++count_;
|
||||
}
|
||||
else if (type == shape_io::shape_pointm)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
shape_.shp().read_double();//m
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
feature=new Feature(id,point);
|
||||
++count_;
|
||||
}
|
||||
else if (type == shape_io::shape_pointz)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
shape_.shp().read_double();//z
|
||||
shape_.shp().read_double();//m
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
feature=new Feature(id,point);
|
||||
++count_;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!filter_.pass(shape_.current_extent()))
|
||||
{
|
||||
unsigned reclen=shape_.reclength_;
|
||||
shape_.move_to(long(shape_.shp().pos()) + 2 * reclen - 36);
|
||||
if ((long)shape_.shp().pos() >= file_length_ * 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
||||
case shape_io::shape_polyline:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polyline();
|
||||
feature=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polylinem:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polylinem();
|
||||
feature=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polylinez:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polylinez();
|
||||
feature=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygon:
|
||||
{
|
||||
geometry_ptr poly = shape_.read_polygon();
|
||||
feature=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygonm:
|
||||
{
|
||||
geometry_ptr poly = shape_.read_polygonm();
|
||||
feature=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygonz:
|
||||
{
|
||||
geometry_ptr poly = shape_.read_polygon();
|
||||
feature=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (attr_ids_.size())
|
||||
{
|
||||
shape_.dbf().move_to(shape_.id_);
|
||||
typename std::vector<int>::const_iterator pos=attr_ids_.begin();
|
||||
while (pos!=attr_ids_.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
shape_.dbf().add_attribute(*pos,feature);//TODO optimize!!!
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!feature)
|
||||
std::cout<<" total shapes read="<<count_<<"\n";
|
||||
return feature;
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
shape_featureset<filterT>::~shape_featureset() {}
|
||||
|
||||
template class shape_featureset<filter_in_box>;
|
48
shape/shape_featureset.hpp
Normal file
48
shape/shape_featureset.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHAPE_FS_HH
|
||||
#define SHAPE_FS_HH
|
||||
|
||||
#include "shape.hh"
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
template <typename filterT>
|
||||
class shape_featureset : public Featureset
|
||||
{
|
||||
filterT filter_;
|
||||
int shape_type_;
|
||||
shape_io shape_;
|
||||
Envelope<double> query_ext_;
|
||||
long file_length_;
|
||||
std::vector<int> attr_ids_;
|
||||
mutable Envelope<double> feature_ext_;
|
||||
mutable int total_geom_size;
|
||||
mutable int count_;
|
||||
public:
|
||||
shape_featureset(const filterT& filter, const std::string& shape_file,
|
||||
const std::set<std::string>& attribute_names,long file_length);
|
||||
virtual ~shape_featureset();
|
||||
Feature* next();
|
||||
private:
|
||||
shape_featureset(const shape_featureset&);
|
||||
const shape_featureset& operator=(const shape_featureset&);
|
||||
};
|
||||
|
||||
#endif //SHAPE_FS_HH
|
182
shape/shape_index_featureset.cpp
Normal file
182
shape/shape_index_featureset.cpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $
|
||||
|
||||
#include "shape_index_featureset.hh"
|
||||
|
||||
template <typename filterT>
|
||||
shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
|
||||
const std::string& shape_file,
|
||||
const std::set<std::string>& attribute_names)
|
||||
: filter_(filter),
|
||||
shape_type_(0),
|
||||
shape_(shape_file),
|
||||
count_(0)
|
||||
|
||||
{
|
||||
shape_.shp().skip(100);
|
||||
std::string indexname(shape_file + ".index");
|
||||
std::ifstream file(indexname.c_str(),std::ios::in|std::ios::binary);
|
||||
if (file)
|
||||
{
|
||||
shp_index<filterT>::query(filter,file,ids_);
|
||||
file.close();
|
||||
}
|
||||
std::cout<< "query size=" << ids_.size() << "\n";
|
||||
itr_ = ids_.begin();
|
||||
|
||||
// deal with attributes
|
||||
std::set<std::string>::const_iterator pos=attribute_names.begin();
|
||||
while (pos!=attribute_names.end())
|
||||
{
|
||||
for (int i=0;i<shape_.dbf().num_fields();++i)
|
||||
{
|
||||
if (shape_.dbf().descriptor(i).name_ == *pos)
|
||||
{
|
||||
attr_ids_.push_back(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename filterT>
|
||||
Feature* shape_index_featureset<filterT>::next()
|
||||
{
|
||||
Feature *f=0;
|
||||
if (itr_!=ids_.end())
|
||||
{
|
||||
int pos=*itr_++;
|
||||
shape_.move_to(pos);
|
||||
int type=shape_.type();
|
||||
if (type==shape_io::shape_point)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
f=new Feature(shape_.id_,point);
|
||||
++count_;
|
||||
}
|
||||
else if (type == shape_io::shape_pointm)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
shape_.shp().read_double();// m
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
f=new Feature(shape_.id_,point);
|
||||
++count_;
|
||||
}
|
||||
else if (type == shape_io::shape_pointz)
|
||||
{
|
||||
double x=shape_.shp().read_double();
|
||||
double y=shape_.shp().read_double();
|
||||
shape_.shp().read_double();// z
|
||||
shape_.shp().read_double();// m
|
||||
geometry_ptr point(new point_impl(-1));
|
||||
point->move_to(x,y);
|
||||
f=new Feature(shape_.id_,point);
|
||||
++count_;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(!filter_.pass(shape_.current_extent()) &&
|
||||
itr_!=ids_.end())
|
||||
{
|
||||
pos=*itr_++;
|
||||
shape_.move_to(pos);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case shape_io::shape_polyline:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polyline();
|
||||
f=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polylinem:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polylinem();
|
||||
f=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polylinez:
|
||||
{
|
||||
geometry_ptr line = shape_.read_polylinez();
|
||||
f=new Feature(shape_.id_,line);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygon:
|
||||
{
|
||||
|
||||
geometry_ptr poly = shape_.read_polygon();
|
||||
f=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygonm:
|
||||
{
|
||||
geometry_ptr poly = shape_.read_polygonm();
|
||||
f=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
case shape_io::shape_polygonz:
|
||||
{
|
||||
geometry_ptr poly = shape_.read_polygonz();
|
||||
f=new Feature(shape_.id_,poly);
|
||||
++count_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (attr_ids_.size())
|
||||
{
|
||||
shape_.dbf().move_to(shape_.id_);
|
||||
std::vector<int>::const_iterator pos=attr_ids_.begin();
|
||||
while (pos!=attr_ids_.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
shape_.dbf().add_attribute(*pos,f);//TODO optimize!!!
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr<<"exception caught\n";
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!f) std::cout<<count_<<" features\n";
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
shape_index_featureset<filterT>::~shape_index_featureset() {}
|
||||
|
||||
template class shape_index_featureset<filter_in_box>;
|
||||
|
49
shape/shape_index_featureset.hpp
Normal file
49
shape/shape_index_featureset.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHAPE_SQT_FS_HH
|
||||
#define SHAPE_SQT_FS_HH
|
||||
|
||||
#include "shape_featureset.hh"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
template <typename filterT>
|
||||
class shape_index_featureset : public Featureset
|
||||
{
|
||||
filterT filter_;
|
||||
int shape_type_;
|
||||
shape_io shape_;
|
||||
std::set<int> ids_;
|
||||
std::set<int>::iterator itr_;
|
||||
std::vector<int> attr_ids_;
|
||||
mutable Envelope<double> feature_ext_;
|
||||
mutable int total_geom_size;
|
||||
mutable int count_;
|
||||
|
||||
public:
|
||||
shape_index_featureset(const filterT& filter,const std::string& shape_file,
|
||||
const std::set<std::string>& attribute_names);
|
||||
virtual ~shape_index_featureset();
|
||||
Feature* next();
|
||||
private:
|
||||
//no copying
|
||||
shape_index_featureset(const shape_index_featureset&);
|
||||
shape_index_featureset& operator=(const shape_index_featureset&);
|
||||
};
|
||||
#endif //SHAPE_SQT_FS_HH
|
414
shape/shape_io.cpp
Normal file
414
shape/shape_io.cpp
Normal file
|
@ -0,0 +1,414 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: shape_io.cc 26 2005-03-29 19:18:59Z pavlenko $
|
||||
|
||||
#include "shape_io.hh"
|
||||
#include "shape.hh"
|
||||
|
||||
|
||||
const std::string shape_io::SHP = ".shp";
|
||||
const std::string shape_io::DBF = ".dbf";
|
||||
|
||||
shape_io::shape_io(const std::string& shape_name)
|
||||
: type_(shape_null),
|
||||
reclength_(0),
|
||||
id_(0)
|
||||
{
|
||||
bool ok = (shp_.open(shape_name + SHP) &&
|
||||
dbf_.open(shape_name + DBF));
|
||||
if (!ok)
|
||||
{
|
||||
throw datasource_exception("cannot read shape file");
|
||||
}
|
||||
}
|
||||
|
||||
shape_io::~shape_io()
|
||||
{
|
||||
shp_.close();
|
||||
dbf_.close();
|
||||
}
|
||||
|
||||
|
||||
void shape_io::move_to (int pos)
|
||||
{
|
||||
shp_.seek(pos);
|
||||
id_ = shp_.read_xdr_integer();
|
||||
reclength_ = shp_.read_xdr_integer();
|
||||
type_ = shp_.read_ndr_integer();
|
||||
|
||||
if (type_ != shape_point)
|
||||
{
|
||||
shp_.read_envelope(cur_extent_);
|
||||
}
|
||||
}
|
||||
|
||||
int shape_io::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
const Envelope<double>& shape_io::current_extent() const
|
||||
{
|
||||
return cur_extent_;
|
||||
}
|
||||
|
||||
shape_file& shape_io::shp()
|
||||
{
|
||||
return shp_;
|
||||
}
|
||||
|
||||
shape_file& shape_io::shx()
|
||||
{
|
||||
return shx_;
|
||||
}
|
||||
|
||||
|
||||
dbf_file& shape_io::dbf()
|
||||
{
|
||||
return dbf_;
|
||||
}
|
||||
|
||||
|
||||
geometry_ptr shape_io::read_polyline()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
shp_.read_record(record);
|
||||
int num_parts=record.read_ndr_integer();
|
||||
int num_points=record.read_ndr_integer();
|
||||
geometry_ptr line(new line_string_impl(-1));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
geometry_ptr shape_io::read_polylinem()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
shp_.read_record(record);
|
||||
int num_parts=record.read_ndr_integer();
|
||||
int num_points=record.read_ndr_integer();
|
||||
geometry_ptr line(new line_string_impl(-1));
|
||||
|
||||
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_ptr shape_io::read_polylinez()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
shp_.read_record(record);
|
||||
int num_parts=record.read_ndr_integer();
|
||||
int num_points=record.read_ndr_integer();
|
||||
geometry_ptr line(new line_string_impl(-1));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// z-range
|
||||
//double z0=record.read_double();
|
||||
//double z1=record.read_double();
|
||||
//for (int i=0;i<num_points;++i)
|
||||
// {
|
||||
// double z=record.read_double();
|
||||
// }
|
||||
|
||||
// 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_ptr shape_io::read_polygon()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
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_ptr poly(new polygon_impl(-1));
|
||||
|
||||
for (int i=0;i<num_parts;++i)
|
||||
{
|
||||
parts[i]=record.read_ndr_integer();
|
||||
}
|
||||
|
||||
for (int k=0;k<num_parts;k++)
|
||||
{
|
||||
int start=parts[k];
|
||||
int end;
|
||||
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++)
|
||||
{
|
||||
x=record.read_double();
|
||||
y=record.read_double();
|
||||
poly->line_to(x,y);
|
||||
}
|
||||
}
|
||||
return poly;
|
||||
}
|
||||
|
||||
geometry_ptr shape_io::read_polygonm()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
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_ptr poly(new polygon_impl(-1));
|
||||
|
||||
for (int i=0;i<num_parts;++i)
|
||||
{
|
||||
parts[i]=record.read_ndr_integer();
|
||||
}
|
||||
|
||||
for (int k=0;k<num_parts;k++)
|
||||
{
|
||||
int start=parts[k];
|
||||
int end;
|
||||
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++)
|
||||
{
|
||||
x=record.read_double();
|
||||
y=record.read_double();
|
||||
poly->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 poly;
|
||||
}
|
||||
|
||||
geometry_ptr shape_io::read_polygonz()
|
||||
{
|
||||
shape_record record(reclength_*2-36);
|
||||
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_ptr poly(new polygon_impl(-1));
|
||||
|
||||
for (int i=0;i<num_parts;++i)
|
||||
{
|
||||
parts[i]=record.read_ndr_integer();
|
||||
}
|
||||
|
||||
for (int k=0;k<num_parts;k++)
|
||||
{
|
||||
int start=parts[k];
|
||||
int end;
|
||||
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++)
|
||||
{
|
||||
x=record.read_double();
|
||||
y=record.read_double();
|
||||
poly->line_to(x,y);
|
||||
}
|
||||
}
|
||||
// z-range
|
||||
//double z0=record.read_double();
|
||||
//double z1=record.read_double();
|
||||
//for (int i=0;i<num_points;++i)
|
||||
//{
|
||||
// double z=record.read_double();
|
||||
//}
|
||||
|
||||
// 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 poly;
|
||||
}
|
82
shape/shape_io.hpp
Normal file
82
shape/shape_io.hpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHAPE_IO_HH
|
||||
#define SHAPE_IO_HH
|
||||
|
||||
#include "dbffile.hh"
|
||||
#include "shapefile.hh"
|
||||
#include "shp_index.hh"
|
||||
|
||||
using mapnik::geometry_ptr;
|
||||
|
||||
struct shape_io
|
||||
{
|
||||
static const std::string SHP;
|
||||
static const std::string SHX;
|
||||
static const std::string DBF;
|
||||
|
||||
shape_file shp_;
|
||||
shape_file shx_;
|
||||
dbf_file dbf_;
|
||||
unsigned type_;
|
||||
unsigned reclength_;
|
||||
unsigned id_;
|
||||
Envelope<double> cur_extent_;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
shape_null = 0,
|
||||
shape_point = 1,
|
||||
shape_polyline = 3,
|
||||
shape_polygon = 5,
|
||||
shape_multipoint = 8,
|
||||
shape_pointz = 11,
|
||||
shape_polylinez = 13,
|
||||
shape_polygonz = 15,
|
||||
shape_multipointz = 18,
|
||||
shape_pointm = 21,
|
||||
shape_polylinem = 23,
|
||||
shape_polygonm = 25,
|
||||
shape_multipointm = 28,
|
||||
shape_multipatch = 31
|
||||
};
|
||||
|
||||
shape_io(const std::string& shape_name);
|
||||
~shape_io();
|
||||
shape_file& shp();
|
||||
shape_file& shx();
|
||||
dbf_file& dbf();
|
||||
void move_to(int id);
|
||||
int type() const;
|
||||
const Envelope<double>& current_extent() const;
|
||||
|
||||
geometry_ptr read_polyline();
|
||||
geometry_ptr read_polylinem();
|
||||
geometry_ptr read_polylinez();
|
||||
geometry_ptr read_polygon();
|
||||
geometry_ptr read_polygonm();
|
||||
geometry_ptr read_polygonz();
|
||||
private:
|
||||
//void read_record(const shape_record& record);
|
||||
// no copying
|
||||
shape_io(const shape_io&);
|
||||
shape_io& operator=(const shape_io&);
|
||||
};
|
||||
#endif //SHAPE_IO_HH
|
58
shape/shapefile.cpp
Normal file
58
shape/shapefile.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "shapefile.hh"
|
||||
|
||||
shape_file::shape_file() {}
|
||||
|
||||
|
||||
shape_file::shape_file(const std::string& file_name)
|
||||
{
|
||||
//file_.rdbuf()->pubsetbuf(buff_,buffer_size);
|
||||
file_.open(file_name.c_str(),std::ios::in|std::ios::binary);
|
||||
}
|
||||
|
||||
shape_file::~shape_file()
|
||||
{
|
||||
if (file_ && file_.is_open())
|
||||
file_.close();
|
||||
}
|
||||
|
||||
|
||||
bool shape_file::open(const std::string& file_name)
|
||||
{
|
||||
//file_.rdbuf()->pubsetbuf(buff_,buffer_size);
|
||||
file_.open(file_name.c_str(),std::ios::in | std::ios::binary);
|
||||
return file_?true:false;
|
||||
}
|
||||
|
||||
|
||||
bool shape_file::is_open()
|
||||
{
|
||||
return file_.is_open();
|
||||
}
|
||||
|
||||
|
||||
void shape_file::close()
|
||||
{
|
||||
if (file_ && file_.is_open())
|
||||
file_.close();
|
||||
}
|
||||
|
||||
|
||||
|
195
shape/shapefile.hpp
Normal file
195
shape/shapefile.hpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: shapefile.hh 33 2005-04-04 13:01:03Z pavlenko $
|
||||
|
||||
#ifndef SHAPEFILE_HH
|
||||
#define SHAPEFILE_HH
|
||||
|
||||
#include "mapnik.hh"
|
||||
#include <fstream>
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
struct shape_record
|
||||
{
|
||||
char* data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
explicit shape_record(size_t size)
|
||||
: data(static_cast<char*>(::operator new(sizeof(char)*size))),
|
||||
size(size),
|
||||
pos(0) {}
|
||||
|
||||
char* rawdata()
|
||||
{
|
||||
return &data[0];
|
||||
}
|
||||
void skip(unsigned n)
|
||||
{
|
||||
pos+=n;
|
||||
}
|
||||
int read_ndr_integer()
|
||||
{
|
||||
int val=(data[pos] & 0xff) |
|
||||
(data[pos+1] & 0xff) << 8 |
|
||||
(data[pos+2] & 0xff) << 16 |
|
||||
(data[pos+3] & 0xff) << 24;
|
||||
pos+=4;
|
||||
return val;
|
||||
}
|
||||
|
||||
int read_xdr_integer()
|
||||
{
|
||||
int val=(data[pos] & 0xff) << 24 |
|
||||
(data[pos+1] & 0xff) << 16 |
|
||||
(data[pos+2] & 0xff) << 8 |
|
||||
(data[pos+3] & 0xff);
|
||||
pos+=4;
|
||||
return val;
|
||||
}
|
||||
|
||||
double read_double()
|
||||
{
|
||||
double val;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
std::memcpy(&val,&data[pos],8);
|
||||
#else
|
||||
long long bits = ((long long)data[pos] & 0xff) |
|
||||
((long long)data[pos+1] & 0xff) << 8 |
|
||||
((long long)data[pos+2] & 0xff) << 16 |
|
||||
((long long)data[pos+3] & 0xff) << 24 |
|
||||
((long long)data[pos+4] & 0xff) << 32 |
|
||||
((long long)data[pos+5] & 0xff) << 40 |
|
||||
((long long)data[pos+6] & 0xff) << 48 |
|
||||
((long long)data[pos+7] & 0xff) << 56 ;
|
||||
std::memcpy(&val,&bits,8);
|
||||
#endif
|
||||
pos+=8;
|
||||
return val;
|
||||
}
|
||||
long remains()
|
||||
{
|
||||
return (size-pos);
|
||||
}
|
||||
~shape_record()
|
||||
{
|
||||
::operator delete(data);
|
||||
}
|
||||
};
|
||||
|
||||
class shape_file
|
||||
{
|
||||
std::ifstream file_;
|
||||
//static const int buffer_size = 16;
|
||||
//char buff_[buffer_size];
|
||||
public:
|
||||
shape_file();
|
||||
shape_file(const std::string& file_name);
|
||||
~shape_file();
|
||||
bool open(const std::string& file_name);
|
||||
bool is_open();
|
||||
void close();
|
||||
|
||||
inline void shape_file::read_record(shape_record& rec)
|
||||
{
|
||||
file_.read(rec.rawdata(),rec.size);
|
||||
}
|
||||
|
||||
inline int read_xdr_integer()
|
||||
{
|
||||
char b[4];
|
||||
file_.read(b, 4);
|
||||
return b[3] & 0xffu | (b[2] & 0xffu) << 8 |
|
||||
(b[1] & 0xffu) << 16 | (b[0] & 0xffu) << 24;
|
||||
}
|
||||
|
||||
inline int read_ndr_integer()
|
||||
{
|
||||
char b[4];
|
||||
file_.read(b,4);
|
||||
return b[0]&0xffu | (b[1]&0xffu) << 8 |
|
||||
(b[2]&0xffu) << 16 | (b[3]&0xffu) << 24;
|
||||
}
|
||||
|
||||
inline double read_double()
|
||||
{
|
||||
double val;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
file_.read(reinterpret_cast<char*>(&val),8);
|
||||
#else
|
||||
char b[8];
|
||||
file_.read(b,8);
|
||||
long long bits = ((long long)b[0] & 0xff) |
|
||||
((long long)b[1] & 0xff) << 8 |
|
||||
((long long)b[2] & 0xff) << 16 |
|
||||
((long long)b[3] & 0xff) << 24 |
|
||||
((long long)b[4] & 0xff) << 32 |
|
||||
((long long)b[5] & 0xff) << 40 |
|
||||
((long long)b[6] & 0xff) << 48 |
|
||||
((long long)b[7] & 0xff) << 56 ;
|
||||
memcpy(&val,&bits,8);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
inline void read_envelope(Envelope<double>& envelope)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
file_.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
|
||||
#else
|
||||
double minx=read_double();
|
||||
double miny=read_double();
|
||||
double maxx=read_double();
|
||||
double maxy=read_double();
|
||||
envelope.init(minx,miny,maxx,maxy);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void skip(std::streampos bytes)
|
||||
{
|
||||
file_.seekg(bytes,std::ios::cur);
|
||||
}
|
||||
|
||||
inline void rewind()
|
||||
{
|
||||
seek(100);
|
||||
}
|
||||
|
||||
inline void seek(std::streampos pos)
|
||||
{
|
||||
file_.seekg(pos,std::ios::beg);
|
||||
}
|
||||
|
||||
|
||||
inline std::streampos pos()
|
||||
{
|
||||
return file_.tellg();
|
||||
}
|
||||
|
||||
|
||||
inline bool is_eof()
|
||||
{
|
||||
return file_.eof();
|
||||
}
|
||||
|
||||
private:
|
||||
shape_file(const shape_file&);
|
||||
shape_file& operator=(const shape_file&);
|
||||
};
|
||||
#endif //SHAPEFILE_HH
|
76
shape/shp_index.cpp
Normal file
76
shape/shp_index.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "shp_index.hh"
|
||||
|
||||
template <typename filterT>
|
||||
void shp_index<filterT>::query(const filterT& filter,std::ifstream& file,std::set<int>& pos)
|
||||
{
|
||||
file.seekg(16,std::ios::beg);
|
||||
query_node(filter,file,pos);
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
void shp_index<filterT>::query_node(const filterT& filter,std::ifstream& file,std::set<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.insert(id);
|
||||
}
|
||||
|
||||
int children=read_ndr_integer(file);
|
||||
|
||||
for (int j=0;j<children;++j)
|
||||
{
|
||||
query_node(filter,file,ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename filterT>
|
||||
int shp_index<filterT>::read_ndr_integer(std::ifstream& 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>
|
||||
void shp_index<filterT>::read_envelope(std::ifstream& file,Envelope<double>& envelope)
|
||||
{
|
||||
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
|
||||
}
|
||||
|
||||
template class shp_index<filter_in_box>;
|
||||
template class shp_index<filter_at_point>;
|
43
shape/shp_index.hpp
Normal file
43
shape/shp_index.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHP_INDEX_HH
|
||||
#define SHP_INDEX_HH
|
||||
|
||||
#include "mapnik.hh"
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
using namespace mapnik;
|
||||
|
||||
template <typename filterT>
|
||||
class shp_index
|
||||
{
|
||||
public:
|
||||
static void query(const filterT& filter,std::ifstream& file,std::set<int>& pos);
|
||||
private:
|
||||
shp_index();
|
||||
~shp_index();
|
||||
shp_index(const shp_index&);
|
||||
shp_index& operator=(const shp_index&);
|
||||
static int read_ndr_integer(std::ifstream& in);
|
||||
static void read_envelope(std::ifstream& in,Envelope<double> &envelope);
|
||||
static void query_node(const filterT& filter,std::ifstream& file,std::set<int>& pos);
|
||||
};
|
||||
|
||||
#endif //SHP_INDEX_HH
|
Loading…
Reference in a new issue