initial import

This commit is contained in:
Artem Pavlenko 2005-06-14 15:06:59 +00:00
parent 73c7e8e84f
commit a8ec856a15
151 changed files with 17139 additions and 0 deletions

3
AUTHORS Normal file
View file

@ -0,0 +1,3 @@
Artem Pavlenko <apavlenko@users.berlios.de>

340
COPYING Normal file
View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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
(at your option) 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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

4
INSTALL Normal file
View file

@ -0,0 +1,4 @@
Installation Instructions
*************************
TODO!

0
README Normal file
View file

81
SConstruct Normal file
View file

@ -0,0 +1,81 @@
#mapnik SConctruct
import os
#edit 'settings.py' to match your system settings
opts = Options('settings.py')
opts.Add('PREFIX', 'Set the install "prefix"', '/opt/mapnik')
opts.Add(PathOption('BOOST_ROOT','boost source root directory','/opt/boost'))
opts.Add(PathOption('AGG_ROOT','agg source root directory','/opt/agg23'))
opts.Add(PathOption('FREETYPE2_ROOT','freetype2 root directory','/opt/freetype2'))
opts.Add(PathOption('PYTHON_ROOT','python root directory','/opt/python'))
opts.Add('PYTHON_VERSION','python version','2.4')
opts.Add(ListOption('DATASOURCES','list of available datasources','postgis',['postgis']))
opts.Add('POSTGRESQL_ROOT','path to postgresql prefix','/usr/local')
platform = ARGUMENTS.get("OS",Platform())
build_dir = 'build'
build_prefix = build_dir+'/'+str(platform)
cxx = 'g++'
env = Environment(CXX=cxx,ENV=os.environ, options=opts)
cxx_debug='-Wall -ftemplate-depth-100 -O0 -fno-inline -g -pthread'
cxx_release='-Wall -ftemplate-depth-100 -O2 -finline-functions -Wno-inline -pthread -DNDEBUG'
release_env = env.Copy(CXXFLAGS = cxx_release)
debug_env = env.Copy(CXXFLAGS = cxx_debug)
if ARGUMENTS.get('debug',0):
env.Append(CXXFLAGS = cxx_debug)
build_prefix+='/debug'
else:
env.Append(CXXFLAGS = cxx_release)
build_prefix+='/release'
Help(opts.GenerateHelpText(env))
conf = Configure(env)
if not conf.CheckLibWithHeader('ltdl','ltdl.h','C'):
print 'Could not find libltdl/headers , exiting!'
Exit(1)
if not conf.CheckLib('z'):
print 'Could not find libz , exiting!'
Exit(1)
if not conf.CheckLibWithHeader('png','png.h','C'):
print 'Could not find libpng/headers, exiting!'
Exit(1)
if not conf.CheckLib('jpeg'):
print 'Could not find jpeg lib, exiting!'
Exit(1)
env = conf.Finish()
Export('env')
#build boost libs (filesystem, regex, python)
env.SConscript('boost/SConscript')
#build agg lib
env.SConscript('agg/SConscript')
#main lib
SConscript('src/SConscript')
#python ext
SConscript('python/SConscript')
#datasources
for datasource in Split(env['DATASOURCES']):
env.BuildDir('build/datasources/'+datasource,'src/datasources/'+datasource,duplicate=0)
SConscript('datasources/'+datasource+'/SConscript')

10
agg/SConscript Normal file
View file

@ -0,0 +1,10 @@
#
import glob
Import('env')
prefix = env['PREFIX']
agg_root = env['AGG_ROOT']
agg_headers = agg_root + '/include'
agg_src_dir = agg_root + '/src/'
agg_src = glob.glob(agg_src_dir + '*.cpp')
agg_lib = env.StaticLibrary('libagg',agg_src,CPPPATH=agg_headers)

21
boost/SConscript Normal file
View file

@ -0,0 +1,21 @@
##
import glob
Import('env')
prefix = env['PREFIX']
boost_root = env['BOOST_ROOT']
# boost filesystem
filesystem_src_dir = boost_root + '/libs/filesystem/src/'
boost_fs_src= glob.glob(filesystem_src_dir + '*.cpp')
lib_boost_filesystem = env.SharedLibrary('libboost-filesystem',boost_fs_src,CPPPATH=boost_root)
env.Install(prefix+'/lib',lib_boost_filesystem)
#boost regex
regex_src_dir = boost_root + '/libs/regex/src/'
boost_regex_src = glob.glob(regex_src_dir+ '*.cpp')
lib_boost_regex = env.SharedLibrary('libboost-regex',boost_regex_src,CPPPATH=boost_root)
env.Install(prefix+'/lib',lib_boost_regex)

View 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
;

View 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')

View 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

View 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

View 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() {}

View 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 &params);
~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

View 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();
}

View 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

View 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

View 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);
}

View 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

View 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>;

View 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

View 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_;
}

View 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
datasources/shape/Jamfile Normal file
View 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
;

View 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)

View 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;
}

View 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);
}

View 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
datasources/shape/shape.cpp Normal file
View 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 &params)
: 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_;
}

View 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 &params);
virtual ~shape_datasource();
private:
shape_datasource(const shape_datasource&);
shape_datasource& operator=(const shape_datasource&);
void init(shape_io& shape);
};
#endif //SHAPE_HH

View 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>;

View 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

View 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>;

View 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

View 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;
}

View 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

View 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();
}

View 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

View 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>;

View 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

218
include/attribute.hpp Normal file
View file

@ -0,0 +1,218 @@
/* 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: attribute.hpp 41 2005-04-13 20:21:56Z pavlenko $
#ifndef ATTRIBUTE_HPP
#define ATTRIBUTE_HPP
#include <typeinfo>
#include <sstream>
#include <map>
#include <boost/any.hpp>
namespace mapnik
{
template <typename T>
struct attribute_traits
{
static std::string to_string(const T& value)
{
std::stringstream ss;
ss << value;
return ss.str();
}
};
template <>
struct attribute_traits<std::string>
{
static std::string to_string(const std::string& value)
{
return value;
}
};
class attribute
{
public:
attribute()
: base_(0) {}
template <typename T>
attribute(const T& value)
: base_(new attribute_impl<T>(value))
{}
attribute(const attribute& rhs)
: base_(rhs.base_ ? rhs.base_->clone() : 0)
{}
~attribute()
{
delete base_;
}
template<typename T>
attribute& operator=(const T& rhs)
{
attribute(rhs).swap(*this);
return *this;
}
attribute& operator=(const attribute& rhs)
{
attribute(rhs).swap(*this);
return *this;
}
bool empty() const
{
return !base_;
}
const std::type_info & type() const
{
return base_ ? base_->type() : typeid(void);
}
const std::string to_string() const
{
return base_ ? base_->to_string() : "";
}
private:
attribute& swap(attribute& rhs)
{
std::swap(base_,rhs.base_);
return *this;
}
class attribute_base
{
public:
virtual ~attribute_base() {}
virtual attribute_base* clone() const=0;
virtual std::string to_string() const=0;
virtual const std::type_info& type() const=0;
};
template <typename T,typename ATraits=attribute_traits<T> >
class attribute_impl : public attribute_base
{
public:
typedef T value_type;
attribute_impl(const value_type& value)
: value_(value) {}
virtual std::string to_string() const
{
return ATraits::to_string(value_);
}
virtual attribute_base* clone() const
{
return new attribute_impl(value_);
}
virtual const std::type_info& type() const
{
return typeid(value_);
}
value_type value_;
};
private:
template<typename value_type>
friend value_type* attribute_cast(attribute*);
attribute_base* base_;
};
template<typename T>
struct bad_attribute_cast : public std::bad_cast
{
virtual const char* what() const throw()
{
return "attribute::failed conversion";
}
};
template <typename T>
bool is_type(const attribute& attr)
{
return attr.type()==typeid(T);
}
template <typename T>
T* attribute_cast(attribute* attr)
{
return attr && attr->type() == typeid(T)
? &static_cast<attribute::attribute_impl<T>*>(attr->base_)->value_
: 0;
}
template <typename T>
const T* attribute_cast(const attribute* attr)
{
return attribute_cast<T>(const_cast<attribute*>(attr));
}
template <typename T>
T attribute_cast(const attribute& attr)
{
using namespace boost;
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
const nonref * result=attribute_cast<nonref>(&attr);
if (!result)
{
throw bad_attribute_cast<T>();
}
return *result;
}
template <typename T>
T attribute_cast(attribute& attr)
{
using namespace boost;
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
nonref * result=attribute_cast<nonref>(&attr);
if (!result)
throw bad_attribute_cast<T>();
return *result;
}
template <typename T>
attribute attribute_from_string(const std::string& val)
{
std::istringstream is(val);
T t;
is >> t;
return attribute(t);
}
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const attribute& attr)
{
out << attr.to_string();
return out;
}
}
#endif //ATTRIBUTE_HPP

View file

@ -0,0 +1,62 @@
/* 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 ATTRIBUTE_COLLECTOR
#define ATTROBUTE_COLLECTOR
#include "filter.hpp"
#include "expression.hpp"
#include "feature_layer_desc.hpp"
#include <set>
namespace mapnik
{
template <typename FeatureT>
class attribute_collector : public filter_visitor<FeatureT>
{
public:
attribute_collector(std::set<std::string>& names)
: names_(names) {}
void visit(filter<FeatureT>& /*filter*/)
{
//not interested
}
void visit(expression<FeatureT>& exp)
{
property<FeatureT>* pf;
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
{
names_.insert(pf->name());
}
}
virtual ~attribute_collector() {}
private:
// no copying
attribute_collector(attribute_collector const&);
attribute_collector& operator=(attribute_collector const&);
private:
std::set<std::string>& names_;
};
}
#endif //ATTRIBUTE_COLLECTOR_HPP

View file

@ -0,0 +1,35 @@
/* 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 ATTRIBUTE_DESCRIPTOR
#define ATTRIBUTE_DESCRIPTOR
#include <string>
namespace mapnik
{
struct attribute_desc
{
std::string name;
eType type;
};
}
#endif

75
include/color.hpp Normal file
View file

@ -0,0 +1,75 @@
/* 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: color.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef COLOR_HPP
#define COLOR_HPP
namespace mapnik {
class Color
{
private:
int rgba_;
public:
Color()
:rgba_(0xffffffff) {}
Color(int red,int green,int blue)
: rgba_(0xff<<24 | (blue&0xff) << 16 | (green&0xff) << 8 | red&0xff) {}
explicit Color(int rgba)
: rgba_(rgba) {}
Color(const Color& rhs)
: rgba_(rhs.rgba_) {}
Color& operator=(const Color& rhs)
{
if (this==&rhs) return *this;
rgba_=rhs.rgba_;
return *this;
}
inline int blue() const
{
return (rgba_>>16)&0xff;
}
inline int green() const
{
return (rgba_>>8)&0xff;
}
inline int red() const
{
return rgba_&0xff;
}
inline int rgba() const
{
return rgba_;
}
static const Color White;
static const Color Black;
static const Color Gray;
static const Color Red;
static const Color Green;
static const Color Blue;
static const Color Yellow;
};
}
#endif //COLOR_HPP

91
include/colorcube.hpp Normal file
View 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$
#include "mapnik.hpp"
#include <iostream>
#ifndef COLORCUBE_HPP
#define COLORCUBE_HPP
namespace mapnik
{
template <int rLevel,int gLevel,int bLevel>
struct color_cube
{
const static unsigned maxcolors=rLevel * gLevel * bLevel + 32;
static unsigned cube[maxcolors];
static bool initialized;
static unsigned rDiv;
static unsigned gDiv;
static unsigned bDiv;
static unsigned color(unsigned red,unsigned green,unsigned blue)
{
if (!initialized)
init();
unsigned index=rgb_level_index(red/rDiv,green/gDiv,blue/bDiv);
return cube[index];
}
private:
static unsigned rgb_level_index(unsigned red,unsigned green,unsigned blue)
{
return (red * gLevel * bLevel + green * bLevel + blue);
}
static void init()
{
unsigned red,green,blue;
unsigned count=0;
for (int r=0;r<rLevel;++r)
{
for (int g=0;g<gLevel;++g)
{
for (int b=0;b<bLevel;++b)
{
red = std::min(255,r * (255 /(rLevel - 1)));
green = std::min(255,g * (255 /(gLevel - 1)));
blue = std::min(255,b * (255 /(bLevel - 1)));
cube[rgb_level_index(r,g,b)]= (red) | (green<<8) | (blue<<16);
//std::cout<<std::hex<<cube[rgb_level_index(r,g,b)]<<std::dec<<"\n";
++count;
}
}
}
std::cout<<"number of colours="<<count<<"\n";
}
};
//template<int rLevel,int gLevel,int bLevel>
//unsigned color_cube<rLevel,gLevel,bLevel>::cube[color_cube<rLevel,gLevel, bLevel>::maxcolors];
template<int rLevel,int gLevel,int bLevel>
unsigned color_cube<rLevel,gLevel,bLevel>::rDiv=52;
template<int rLevel,int gLevel,int bLevel>
unsigned color_cube<rLevel,gLevel,bLevel>::gDiv=52;
template<int rLevel,int gLevel,int bLevel>
unsigned color_cube<rLevel,gLevel,bLevel>::bDiv=52;
template<int rLevel,int gLevel,int bLevel>
bool color_cube<rLevel,gLevel,bLevel>::initialized=false;
}
#endif

150
include/comparison.hpp Normal file
View file

@ -0,0 +1,150 @@
/* 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 COMPARISON_HPP
#define COMPARISON_HPP
#include "filter.hpp"
#include "expression.hpp"
#include "attribute.hpp"
#include <iostream>
namespace mapnik
{
template <typename T>
struct greater_than
{
bool operator() (T const& left, T const& right) const
{
return left > right;
}
static std::string to_string()
{
return ">";
}
};
template <typename T>
struct greater_than_or_equal
{
bool operator() (T const& left, T const& right) const
{
return left >= right;
}
static std::string to_string()
{
return ">=";
}
};
template <typename T>
struct less_than
{
bool operator() (T const& left, T const& right) const
{
return left < right;
}
static std::string to_string()
{
return "<";
}
};
template <typename T>
struct less_than_or_equal
{
bool operator() (T const& left, T const& right) const
{
return left <= right;
}
static std::string to_string()
{
return "<=";
}
};
template <typename T>
struct equals
{
bool operator() (T const& left, T const& right) const
{
return left == right;
}
static std::string to_string()
{
return "=";
}
};
template <typename T>
struct not_equals
{
bool operator() (T const& left, T const& right) const
{
return left != right;
}
static std::string to_string()
{
return "<>";
}
};
template <typename FeatureT,typename Op>
struct compare_filter : public filter<FeatureT>
{
compare_filter(expression<FeatureT> const& left,
expression<FeatureT> const& right)
: filter<FeatureT>(),
left_(left.clone()), right_(right.clone()) {}
compare_filter(compare_filter const& other)
: filter<FeatureT>(),
left_(other.left_->clone()),right_(other.right_->clone()) {}
bool pass(const FeatureT& feature) const
{
return Op()(left_->get_value(feature),right_->get_value(feature));
}
void accept(filter_visitor<FeatureT>& v)
{
left_->accept(v);
right_->accept(v);
v.visit(*this);
}
std::string to_string() const
{
return "("+left_->to_string()+Op::to_string()+right_->to_string()+")";
}
filter<FeatureT>* clone() const
{
return new compare_filter<FeatureT,Op>(*this);
}
virtual ~compare_filter()
{
delete left_;
delete right_;
}
private:
expression<FeatureT>* left_;
expression<FeatureT>* right_;
};
}
#endif //COMPARISON_HPP

140
include/config.hpp Normal file
View file

@ -0,0 +1,140 @@
/* include/config.hpp. Generated by configure. */
/* include/config.hpp.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the `closedir' function returns void instead of `int'. */
/* #undef CLOSEDIR_VOID */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `floor' function. */
#define HAVE_FLOOR 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `jpeg' library (-ljpeg). */
#define HAVE_LIBJPEG 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define to 1 if you have the `png' library (-lpng). */
#define HAVE_LIBPNG 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `pow' function. */
#define HAVE_POW 1
/* Define to 1 if you have the `sqrt' function. */
#define HAVE_SQRT 1
/* Define to 1 if stdbool.h conforms to C99. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `_Bool'. */
#define HAVE__BOOL 1
/* Name of package */
#define PACKAGE "mapnik"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "mapnik"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "mapnik 0.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "mapnik"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Version number of package */
#define VERSION "0.1"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* datasource plugins dir */
#define _DATASOURCE_PLUGINS_DIR "/opt/mapnik/plugins"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to empty if the keyword `volatile' does not work. Warning: valid
code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

131
include/coord.hpp Normal file
View file

@ -0,0 +1,131 @@
/* 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.#include "memory.hpp"
*
* 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: coord.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef COORD_HPP
#define COORD_HPP
#include <iostream>
#include <sstream>
namespace mapnik
{
template <typename T,int dim>
struct coord {
typedef T type;
};
template <typename T>
struct coord<T,2>
{
typedef T type;
T x;
T y;
public:
coord()
: x(),y() {}
coord(T x,T y)
: x(x),y(y) {}
template <typename T2>
coord (const coord<T2,2>& rhs)
: x(type(rhs.x)),
y(type(rhs.y)) {}
template <typename T2>
coord<T,2>& operator=(const coord<T2,2>& rhs)
{
if ((void*)this==(void*)&rhs)
{
return *this;
}
x=type(rhs.x);
y=type(rhs.y);
return *this;
}
};
template <typename T>
struct coord<T,3>
{
typedef T type;
T x;
T y;
T z;
public:
coord()
: x(),y(),z() {}
coord(T x,T y,T z)
: x(x),y(y),z(z) {}
template <typename T2>
coord (const coord<T2,3>& rhs)
: x(type(rhs.x)),
y(type(rhs.y)),
z(type(rhs.z)) {}
template <typename T2>
coord<T,3>& operator=(const coord<T2,3>& rhs)
{
if ((void*)this==(void*)&rhs)
{
return *this;
}
x=type(rhs.x);
y=type(rhs.y);
z=type(rhs.z);
return *this;
}
};
typedef coord<double,2> coord2d;
typedef coord<int,2> coord2i;
template <typename charT,typename traits,typename T ,int dim>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const coord<T,dim>& c);
template <typename charT,typename traits,typename T>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const coord<T,2>& c)
{
std::basic_ostringstream<charT,traits> s;
s.copyfmt(out);
s.width(0);
s<<"coord2("<<c.x<<","<<c.y<<")";
out << s.str();
return out;
}
template <typename charT,typename traits,typename T>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const coord<T,3>& c)
{
std::basic_ostringstream<charT,traits> s;
s.copyfmt(out);
s.width(0);
s<<"coord3("<<c.x<<","<<c.y<<","<<c.z<<")";
out << s.str();
return out;
}
}
#endif // COORD_HPP

88
include/coord_array.hpp Normal file
View file

@ -0,0 +1,88 @@
/* 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.#include "memory.hpp"
*
* 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: coord_array.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef COORD_ARRAY_HPP
#define COORD_ARRAY_HPP
#include "coord.hpp"
#include <cassert>
namespace mapnik
{
template <typename T>
class coord_array
{
typedef T coord_type;
coord_type* pt_;
const unsigned size_;
public:
coord_array(unsigned size=0)
: pt_(static_cast<coord_type*>(size==0?0: ::operator new (sizeof(coord_type)*size))),
size_(size) {}
coord_array(const coord_array& rhs)
: pt_(static_cast<coord_type*>(rhs.size_==0?0: ::operator new (sizeof(coord_type)*rhs.size_))),
size_(rhs.size_) {
memcpy(pt_,rhs.pt_,sizeof(coord_type)*rhs.size_);
}
~coord_array()
{
::operator delete (pt_);
}
unsigned size() const
{
return size_;
}
void set(unsigned index,double x,double y)
{
assert(index<size_);
pt_[index].x=x;
pt_[index].y=y;
}
const coord_type& at(unsigned index) const
{
assert(index<size_);
return pt_[index];
}
const coord_type& operator[] (unsigned index) const
{
assert (index<size_);
return pt_[index];
}
coord_type& operator[] (unsigned index)
{
assert (index<size_);
return pt_[index];
}
private:
coord_array& operator=(const coord_array&);
};
}
#endif //COORD_ARRAY_HPP

122
include/ctrans.hpp Normal file
View file

@ -0,0 +1,122 @@
/* 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: ctrans.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef CTRANS_HPP
#define CTRANS_HPP
#include "envelope.hpp"
#include "coord_array.hpp"
namespace mapnik
{
typedef coord_array<coord2d> CoordinateArray;
class CoordTransform
{
private:
int width;
int height;
double scale_;
Envelope<double> extent;
coord2d center_;
public:
CoordTransform(int width,int height,const Envelope<double>& extent)
:width(width),height(height),extent(extent),center_(extent.center())
{
double sx=((double)width)/extent.width();
double sy=((double)height)/extent.height();
scale_=std::min(sx,sy);
}
inline double scale() const
{
return scale_;
}
double forward_x(double x) const
{
return (x-center_.x)*scale_+0.5*width;
}
double forward_y(double y) const
{
return -(y-center_.y)*scale_+0.5*height;
}
inline coord2d& forward(coord2d& c) const
{
c.x=(c.x-center_.x)*scale_+0.5*width;
c.y=-(c.y-center_.y)*scale_+0.5*height;
return c;
}
inline coord2d& backward(coord2d& c) const
{
c.x=(c.x-0.5*width)/scale_+center_.x;
c.y=-(c.y-0.5*height)/scale_+center_.y;
return c;
}
inline Envelope<double> forward(const Envelope<double>& e) const
{
double x0=(e.minx()-center_.x)*scale_+0.5*width;
double x1=(e.maxx()-center_.x)*scale_+0.5*width;
double y0=-(e.miny()-center_.y)*scale_+0.5*height;
double y1=-(e.maxy()-center_.y)*scale_+0.5*height;
return Envelope<double>(x0,y0,x1,y1);
}
inline Envelope<double> backward(const Envelope<double>& e) const
{
double x0=(e.minx()-0.5*width)/scale_+center_.x;
double x1=(e.maxx()-0.5*width)/scale_+center_.x;
double y0=-(e.miny()-0.5*height)/scale_+center_.y;
double y1=-(e.maxy()-0.5*height)/scale_+center_.y;
return Envelope<double>(x0,y0,x1,y1);
}
inline CoordinateArray& forward(CoordinateArray& coords) const
{
for (unsigned i=0;i<coords.size();++i)
{
coords[i].x=(coords[i].x-center_.x)*scale_+0.5*width;
coords[i].y=-(coords[i].y-center_.y)*scale_+0.5*height;
}
return coords;
}
inline CoordinateArray& backward(CoordinateArray& coords) const
{
for (unsigned i=0;i<coords.size();++i)
{
coords[i].x=(coords[i].x-0.5*width)/scale_+center_.x;
coords[i].y=-(coords[i].y-0.5*height)/scale_+center_.y;
}
return coords;
}
};
}
#endif //CTRANS_HPP

103
include/datasource.hpp Normal file
View file

@ -0,0 +1,103 @@
/* 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: datasource.hpp 43 2005-04-22 18:52:47Z pavlenko $
#ifndef DATASOURCE_HPP
#define DATASOURCE_HPP
#include <map>
#include <string>
#include "ptr.hpp"
#include "ctrans.hpp"
#include "params.hpp"
#include "feature.hpp"
#include "query.hpp"
#include "feature_layer_desc.hpp"
namespace mapnik
{
typedef ref_ptr<Feature> feature_ptr;
struct Featureset
{
virtual Feature* next()=0;
virtual ~Featureset() {};
};
typedef ref_ptr<Featureset> featureset_ptr;
class datasource_exception : public std::exception
{
private:
const std::string message_;
public:
datasource_exception(const std::string& message=std::string())
:message_(message) {}
~datasource_exception() throw() {}
virtual const char* what() const throw()
{
return message_.c_str();
}
};
class datasource
{
public:
enum {
Vector,
Raster
};
virtual int type() const=0;
virtual featureset_ptr features(const query& q) const=0;
virtual Envelope<double> const& envelope() const=0;
virtual layer_descriptor const& get_descriptor() const=0;
virtual ~datasource() {};
};
typedef std::string datasource_name();
typedef datasource* create_ds(const Parameters& params);
typedef void destroy_ds(datasource *ds);
template <typename DATASOURCE>
struct datasource_delete
{
static void destroy(DATASOURCE* ds)
{
destroy_ds(ds);
}
};
typedef ref_ptr<datasource,datasource_delete> datasource_p;
///////////////////////////////////////////
#define DATASOURCE_PLUGIN(classname) \
extern "C" std::string datasource_name() \
{ \
return classname::name();\
}\
extern "C" datasource* create(const Parameters &params) \
{ \
return new classname(params);\
}\
extern "C" void destroy(datasource *ds) \
{ \
delete ds;\
}\
///////////////////////////////////////////
}
#endif //DATASOURCE_HPP

View 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.
*/
//$Id: datasource_cache.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef DSFACTORY_HPP
#define DSFACTORY_HPP
#include "utils.hpp"
#include "ptr.hpp"
#include "params.hpp"
#include "plugin.hpp"
#include "datasource.hpp"
#include <map>
namespace mapnik
{
class datasource_cache : public singleton <datasource_cache,CreateStatic>
{
friend class CreateStatic<datasource_cache>;
private:
datasource_cache();
~datasource_cache();
datasource_cache(const datasource_cache&);
datasource_cache& operator=(const datasource_cache&);
static std::map<std::string,ref_ptr<PluginInfo> > plugins_;
static bool registered_;
static bool insert(const std::string& name,const lt_dlhandle module);
public:
static void register_datasources(const std::string& path);
static ref_ptr<datasource,datasource_delete> create(const Parameters& params);
};
}
#endif //DSFACTORY_HPP

80
include/envelope.hpp Normal file
View file

@ -0,0 +1,80 @@
/* 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: envelope.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef ENVELOPE_HPP
#define ENVELOPE_HPP
#include "coord.hpp"
namespace mapnik
{
template <class T> class Envelope
{
public:
typedef Envelope<T> EnvelopeType;
private:
T minx_;
T miny_;
T maxx_;
T maxy_;
public:
Envelope();
Envelope(T minx,T miny,T maxx,T maxy);
Envelope(const coord<T,2>& c0,const coord<T,2>& c1);
Envelope(const EnvelopeType& rhs);
T minx() const;
T miny() const;
T maxx() const;
T maxy() const;
T width() const;
T height() const;
void width(T w);
void height(T h);
coord<T,2> center() const;
void expand_to_include(T x,T y);
void expand_to_include(const coord<T,2>& c);
void expand_to_include(const EnvelopeType& other);
bool contains(const coord<T,2> &c) const;
bool contains(T x,T y) const;
bool contains(const EnvelopeType &other) const;
bool intersects(const coord<T,2> &c) const;
bool intersects(T x,T y) const;
bool intersects(const EnvelopeType &other) const;
EnvelopeType intersect(const EnvelopeType& other) const;
bool operator==(const EnvelopeType &other) const;
void re_center(T cx,T cy);
void init(T x0,T y0,T x1,T y1);
};
template <class charT,class traits,class T>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
const Envelope<T>& e)
{
std::basic_ostringstream<charT,traits> s;
s.copyfmt(out);
s.width(0);
s<<"Envelope("<<e.minx()<<","<<e.miny()<<","<<e.maxx()<<","<<e.maxy()<<")";
out << s.str();
return out;
}
}
#endif // ENVELOPE_HPP

136
include/expression.hpp Normal file
View file

@ -0,0 +1,136 @@
/* 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 EXPRESSION_HPP
#define EXPRESSION_HPP
#include "value.hpp"
#include "filter_visitor.hpp"
namespace mapnik
{
template <typename FeatureT> class filter_visitor;
template <typename FeatureT>
struct expression
{
virtual value get_value(FeatureT const& feature) const=0;
virtual void accept(filter_visitor<FeatureT>& v)=0;
virtual expression<FeatureT>* clone() const=0;
virtual std::string to_string() const=0;
virtual ~expression() {}
};
template <typename FeatureT>
class literal : public expression<FeatureT>
{
public:
literal(int val)
: expression<FeatureT>(),
value_(val) {}
literal(double val)
: expression<FeatureT>(),
value_(val) {}
literal(std::string const& val)
: expression<FeatureT>(),
value_(val) {}
literal(literal const& other)
: expression<FeatureT>(),
value_(other.value_) {}
value get_value(FeatureT const& /*feature*/) const
{
return value_;
}
void accept(filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
expression<FeatureT>* clone() const
{
return new literal(*this);
}
std::string to_string() const
{
return "'"+value_.to_string()+"'";
}
~literal() {}
private:
value value_;
};
template <typename FeatureT>
class property : public expression<FeatureT>
{
public:
property(std::string const& name)
: expression<FeatureT>(),
name_(name),
index_(0),
valid_(false) {}
property(property const& other)
: expression<FeatureT>(),
name_(other.name_),
index_(other.index_),
valid_(other.valid_) {}
value get_value(FeatureT const& feature) const
{
if (valid_)
{
return feature.get_property(index_);
}
else
{
return value("");
}
}
void accept(filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
expression<FeatureT>* clone() const
{
return new property(*this);
}
std::string const& name() const
{
return name_;
}
void set_index(size_t index)
{
index_=index;
valid_=true;
}
std::string to_string() const
{
return "["+name_+"]";
}
~property() {}
private:
std::string name_;
size_t index_;
bool valid_;
};
}
#endif //EXPRESSION_HPP

84
include/factory.hpp Normal file
View file

@ -0,0 +1,84 @@
/* 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: factory.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef FACTORY_HPP
#define FACTORY_HPP
#include <stdexcept>
#include <map>
#include "utils.hpp"
namespace mapnik
{
template <typename key_type,
typename product_type>
class default_factory_error
{
public:
struct factory_exception : public std::exception
{
const char* what() const throw()
{
return "uknown object type";
}
};
static product_type* on_unknown_type(const key_type&)
{
return 0;
}
};
template
<
typename product_type,
typename key_type,
typename product_creator=product_type* (*)(),
template <typename,typename> class factory_error_policy=default_factory_error
>
class factory : public singleton<factory <product_type,key_type,product_creator,factory_error_policy> >,
factory_error_policy <key_type,product_type>
{
private:
typedef std::map<key_type,product_creator> product_map;
product_map map_;
public:
bool register_product(const key_type& key,product_creator creator)
{
return map_.insert(typename product_map::value_type(key,creator)).second;
}
bool unregister_product(const key_type& key)
{
return map_.erase(key)==1;
}
product_type* create_object(const key_type& key,const std::string& file)
{
typename product_map::const_iterator pos=map_.find(key);
if (pos!=map_.end())
{
return (pos->second)(file);
}
return on_unknown_type(key);
}
};
}
#endif //FACTORY_HPP

129
include/feature.hpp Normal file
View file

@ -0,0 +1,129 @@
/* 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: feature.hpp 40 2005-04-13 20:20:46Z pavlenko $
#ifndef FEATURE_HPP
#define FEATURE_HPP
#include "geometry.hpp"
#include "raster.hpp"
#include "value.hpp"
#include <vector>
namespace mapnik
{
typedef ref_ptr<raster> raster_ptr;
typedef std::vector<value> properties;
template <typename T1,typename T2>
struct feature
{
public:
typedef T1 geometry_type;
typedef T2 raster_type;
private:
int id_;
geometry_type geom_;
raster_type raster_;
properties props_;
public:
explicit feature(int id)
: id_(id),
geom_(),
raster_() {}
feature(int id,const geometry_type& geom)
: id_(id),
geom_(geom),
raster_() {}
feature(const feature<T1,T2>& rhs)
: id_(rhs.id_),
geom_(rhs.geom_),
raster_(rhs.raster_) {}
feature<T1,T2>& operator=(const feature<T1,T2>& rhs)
{
feature<T1,T2> tmp;
swap(tmp);
return *this;
}
~feature() {}
int id() const
{
return id_;
}
void set_geometry(geometry_type& geom)
{
geom_=geom;
}
geometry_type& get_geometry()
{
return geom_;
}
const raster_type& get_raster() const
{
return raster_;
}
void add_property(int v)
{
return props_.push_back(value(v));
}
void add_property(double v)
{
return props_.push_back(value(v));
}
void add_property(std::string const& v)
{
return props_.push_back(value(v));
}
value get_property(size_t index) const
{
assert(index < props_.size());
return props_[index];
}
const properties& get_properties() const
{
return props_;
}
private:
void swap(const feature<T1,T2>& rhs) throw()
{
std::swap(id_,rhs.id_);
std::swap(geom_,rhs.geom_);
std::swap(raster_,rhs.raster_);
std::swap(props_,rhs.props_);
}
};
typedef feature<geometry_ptr,raster_ptr> Feature;
}
#endif //FEATURE_HPP

View file

@ -0,0 +1,249 @@
/* 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.#include "memory.hh"
*
* 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 FEATURE_LAYER_DESC_HPP
#define FEATURE_LAYER_DESC_HPP
//#include "array.hpp"
#include <string>
#include <vector>
#include <iostream>
namespace mapnik
{
using std::string;
using std::vector;
using std::cout;
using std::cerr;
using std::endl;
enum {
Integer=1,
Float =2,
Double =3,
String =4,
Geometry=5,
Object=6
};
class attribute_descriptor
{
public:
attribute_descriptor(string const& name,unsigned type,
bool primary_key=false,
int size=-1,
int precision=-1)
: name_(name),
type_(type),
primary_key_(primary_key),
size_(size),
precision_(precision) {}
attribute_descriptor(attribute_descriptor const& other)
: name_(other.name_),
type_(other.type_),
primary_key_(other.primary_key_),
size_(other.size_),
precision_(other.precision_) {}
attribute_descriptor& operator=(attribute_descriptor const& other)
{
if (this == &other)
return *this;
name_=other.name_;
type_=other.type_;
primary_key_=other.primary_key_;
size_=other.size_;
precision_=other.precision_;
return *this;
}
string const& get_name() const
{
return name_;
}
unsigned get_type() const
{
return type_;
}
bool is_primary_key() const
{
return primary_key_;
}
int get_size() const
{
return size_;
}
int get_precision() const
{
return precision_;
}
private:
string name_;
int type_;
bool primary_key_;
int size_;
int precision_;
};
template <typename charT,typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
attribute_descriptor const& ad)
{
out << "name=" << ad.get_name() << endl;
out << "type=" << ad.get_type() << endl;
out << "size=" << ad.get_size() << endl;
return out;
}
class layer_descriptor
{
public:
layer_descriptor(string const& name,int srid=-1)
: name_(name),
srid_(srid) {}
layer_descriptor(layer_descriptor const& other)
: name_(other.name_),
srid_(other.srid_),
desc_ar_(other.desc_ar_) {}
void set_name(string const& name)
{
name_=name;
}
string const& get_name() const
{
return name_;
}
void set_srid(int srid)
{
srid_=srid;
}
int get_srid() const
{
return srid_;
}
void add_descriptor(attribute_descriptor const& desc)
{
desc_ar_.push_back(desc);
}
vector<attribute_descriptor> const& get_descriptors() const
{
return desc_ar_;
}
vector<attribute_descriptor>& get_descriptors()
{
return desc_ar_;
}
private:
string name_;
int srid_;
vector<attribute_descriptor> desc_ar_;
};
template <typename charT,typename traits>
inline std::basic_ostream<charT,traits>&
operator << (std::basic_ostream<charT,traits>& out,
layer_descriptor const& ld)
{
out << "name=" << ld.get_name() << endl;
out << "srid=" << ld.get_srid() << endl;
vector<attribute_descriptor> const& desc_ar=ld.get_descriptors();
vector<attribute_descriptor>::const_iterator pos=desc_ar.begin();
while (pos != desc_ar.end())
{
out << *pos++ << endl;
}
return out;
}
/*
bool layer_descriptor_to_wkb(layer_descriptor const& desc,array<>& wkb)
{
//srid
int srid = desc.get_srid();
wkb.write(&srid,sizeof(int));
//attribute descriptors
vector<attribute_descriptor> const& desc_ar = desc.get_descriptors();
vector<attribute_descriptor>::const_iterator itr=desc_ar.begin();
size_t num_desc = desc_ar.size();
wkb.write(&num_desc,sizeof(int));
while (itr != desc_ar.end())
{
string name = itr->get_name();
wkb.write(name.c_str(),name.size()+1);
unsigned type = static_cast<int>(itr->get_type());
wkb.write(&type,sizeof(unsigned));
bool prim_key = itr->is_primary_key();
wkb.write(&prim_key,sizeof(bool));
int size = itr->get_size();
wkb.write(&size,sizeof(int));
++itr;
}
return true;
}
bool layer_descriptor_from_wkb(const char* wkb, layer_descriptor &desc)
{
unsigned pos=0;
int srid;
memcpy(&srid,wkb+pos,sizeof(int));
desc.set_srid(srid);
pos+=sizeof(int);
int num_desc;
memcpy(&num_desc,wkb+pos,sizeof(int));
pos+=sizeof(int);
for (int i=0;i<num_desc;++i)
{
string name = wkb+pos;
pos += name.size()+1;
//std::cout<<"name="<<name<<"\n";
int type;
memcpy(&type,wkb+pos,sizeof(int));
pos += sizeof(int);
attribute_descriptor ad(name,type);
desc.add_descriptor(ad);
//todo!!!
pos += 4+1;
}
return true;
}
*/
}
#endif //FEATURE_LAYER_DESC_HPP

View file

@ -0,0 +1,63 @@
/* 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 FEATURE_TYPE_STYLE
#define FEATURE_TYPE_STYLE
#include "rule.hpp"
#include "feature.hpp"
#include "ptr.hpp"
#include <vector>
namespace mapnik
{
typedef rule<Feature,filter> rule_type;
class feature_type_style
{
private:
std::vector<rule_type> rules_;
public:
feature_type_style() {}
feature_type_style(const feature_type_style& rhs)
: rules_(rhs.rules_) {}
feature_type_style& operator=(const feature_type_style& rhs)
{
if (this == &rhs) return *this;
rules_=rhs.rules_;
return *this;
}
void add_rule(const rule_type& rule)
{
rules_.push_back(rule);
}
const std::vector<rule_type>& rules() const
{
return rules_;
}
~feature_type_style() {}
};
}
#endif //FEATURE_TYPE_STYLE

32
include/fill.hpp Normal file
View file

@ -0,0 +1,32 @@
/* 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 FILL_HPP
#define FILL_HPP
namespace mapnik
{
class fill
{
};
}
#endif //FILL_HPP

65
include/filter.hpp Normal file
View file

@ -0,0 +1,65 @@
/* 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 FILTER_HPP
#define FILTER_HPP
#include "filter_visitor.hpp"
#include "feature.hpp"
namespace mapnik
{
typedef ref_ptr<filter<Feature> > filter_ptr;
template <typename FeatureT> class filter_visitor;
template <typename FeatureT>
struct filter
{
virtual bool pass(const FeatureT& feature) const=0;
virtual filter<FeatureT>* clone() const=0;
virtual void accept(filter_visitor<FeatureT>& v) = 0;
virtual std::string to_string() const=0;
virtual ~filter() {}
};
template <typename FeatureT>
struct null_filter : public filter<FeatureT>
{
bool pass (const FeatureT&) const
{
return true;
}
filter<FeatureT>* clone() const
{
return new null_filter<FeatureT>;
}
std::string to_string() const
{
return "true";
}
void accept(filter_visitor<FeatureT>&) {}
virtual ~null_filter() {}
};
}
#endif //FILTER_HPP

View file

@ -0,0 +1,61 @@
/* 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 FILTER_TO_STRING_HPP
#define FILTER_TO_STRING_HPP
#include "filter.hpp"
#include "expression.hpp"
#include <set>
namespace mapnik
{
template <typename FeatureT>
class filter_to_string : public filter_visitor<FeatureT>
{
private:
std::string text_;
public:
filter_to_string() {}
void visit(filter<FeatureT>& /*filter*/)
{
//not interested
}
void visit(expression<FeatureT>& exp)
{
property<FeatureT>* pf;
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
{
names_.insert(pf->name());
}
}
std::string const& text() const
{
return text_;
}
virtual ~filter_to_string() {}
private:
filter_to_string(filter_to_string const&);
filter_to_string& operator=(filter_to_string const&);
};
}
#endif //FILTER_TO_STRING

View file

@ -0,0 +1,52 @@
/* 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$
#include "filter_parser.hpp"
using std::string;
namespace mapnik
{
template<typename FeatureT>
class filter_factory
{
public:
filter_factory() {}
filter_ptr compile(string const& str) const
{
stack<ref_ptr<filter<FeatureT> > > filters;
stack<ref_ptr<expression<FeatureT> > > exps;
filter_grammar<FeatureT> grammar(filters,exps);
char const *text = str.c_str();
parse_info<> info = parse(text,text+strlen(text),grammar,space_p);
if (info.full && !filters.empty())
{
cout<<"success parsing filter expression:\n";
cout<<filters.top()->to_string()<<"\n";
return filters.top();
}
else
{
cout << "failed at :" << info.stop << "\n";
return filter_ptr(new null_filter<FeatureT>());
}
}
};
}

440
include/filter_parser.hpp Normal file
View file

@ -0,0 +1,440 @@
/* 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 FILTER_PARSER_HPP
#define FILTER_PARSER_HPP
#include <boost/spirit/core.hpp>
#include <boost/spirit/symbols.hpp>
#include <boost/spirit/utility/confix.hpp>
#include <boost/spirit/utility/escape_char.hpp>
#include <boost/spirit/utility/chset.hpp>
#include "value.hpp"
#include "comparison.hpp"
#include "expression.hpp"
#include "filter.hpp"
#include "regex_filter.hpp"
#include <stack>
#include <iostream>
using namespace boost::spirit;
using std::string;
using std::cout;
using std::cerr;
using std::stack;
namespace mapnik
{
template <typename FeatureT>
struct push_integer
{
push_integer(stack<ref_ptr<expression<FeatureT> > >& exprs)
: exprs_(exprs) {}
void operator() (int val) const
{
exprs_.push(ref_ptr<expression<FeatureT> >(new literal<FeatureT>(val)));
}
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT>
struct push_real
{
push_real(stack<ref_ptr<expression<FeatureT> > >& exprs)
: exprs_(exprs) {}
void operator() (double val) const
{
exprs_.push(ref_ptr<expression<FeatureT> >(new literal<FeatureT>(val)));
}
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT>
struct push_string
{
push_string(stack<ref_ptr<expression<FeatureT> > >& exprs)
: exprs_(exprs) {}
template <typename Iter>
void operator() (Iter start,Iter end) const
{
string str(start,end);
char quote='\\';
string::size_type idx;
idx = str.find(quote);
while (idx != string::npos)
{
str.erase(idx,1);
idx = str.find(quote);
}
cout << "string(\""<<str<<"\")\n";
exprs_.push(ref_ptr<expression<FeatureT> >(new literal<FeatureT>(str)));
}
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT>
struct push_property
{
push_property(stack<ref_ptr<expression<FeatureT> > >& exprs)
: exprs_(exprs) {}
template <typename Iter>
void operator() (Iter start,Iter end) const
{
string str(start,end);
exprs_.push(ref_ptr<expression<FeatureT> >(new property<FeatureT>(str)));
}
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT,typename Op>
struct compose_expression
{
compose_expression(stack<ref_ptr<expression<FeatureT> > >& exprs)
: exprs_(exprs) {}
template <typename Iter>
void operator() (Iter,Iter) const
{
if (exprs_.size()>=2)
{
ref_ptr<expression<FeatureT> > right = exprs_.top();
exprs_.pop();
ref_ptr<expression<FeatureT> > left = exprs_.top();
exprs_.pop();
if (left && right)
{
exprs_.push(ref_ptr<expression<FeatureT> >(new math_expr_b<FeatureT,Op>(*left,*right)));
}
}
}
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT>
struct compose_regex
{
compose_regex(stack<ref_ptr<filter<FeatureT> > >& filters,
stack<ref_ptr<expression<FeatureT> > >& exprs)
: filters_(filters),exprs_(exprs) {}
template <typename Iter>
void operator() (Iter start,Iter end) const
{
if (exprs_.size()>=1)
{
ref_ptr<expression<FeatureT> > exp = exprs_.top();
exprs_.pop();
if (exp)
{
std::string pattern(start,end);
try
{
filters_.push(ref_ptr<filter<FeatureT> >(new regex_filter<FeatureT>(*exp,pattern)));
}
catch (boost::regex_error& ex)
{
cerr<<ex.what()<<"\n";
}
}
}
}
stack<ref_ptr<filter<FeatureT> > >& filters_;
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT,typename Op>
struct compose_filter
{
compose_filter(stack<ref_ptr<filter<FeatureT> > >& filters,
stack<ref_ptr<expression<FeatureT> > >& exprs)
: filters_(filters),exprs_(exprs) {}
template <typename Iter>
void operator() (Iter,Iter) const
{
if (exprs_.size()>=2)
{
ref_ptr<expression<FeatureT> > right = exprs_.top();
exprs_.pop();
ref_ptr<expression<FeatureT> > left = exprs_.top();
exprs_.pop();
if (left && right)
{
filters_.push(ref_ptr<filter<FeatureT> >(new compare_filter<FeatureT,Op>(*left,*right)));
}
}
}
stack<ref_ptr<filter<FeatureT> > >& filters_;
stack<ref_ptr<expression<FeatureT> > >& exprs_;
};
template <typename FeatureT>
struct compose_and_filter
{
compose_and_filter(stack<ref_ptr<filter<FeatureT> > >& filters)
: filters_(filters) {}
template <typename Iter>
void operator() (Iter,Iter) const
{
if (filters_.size()>=2)
{
ref_ptr<filter<FeatureT> > right = filters_.top();
filters_.pop();
ref_ptr<filter<FeatureT> > left = filters_.top();
filters_.pop();
if (left && right)
{
filters_.push(ref_ptr<filter<FeatureT> >(new logical_and<FeatureT>(*left,*right)));
}
}
}
stack<ref_ptr<filter<FeatureT> > >& filters_;
};
template <typename FeatureT>
struct compose_or_filter
{
compose_or_filter(stack<ref_ptr<filter<FeatureT> > >& filters)
: filters_(filters) {}
template <typename Iter>
void operator() (Iter,Iter) const
{
if (filters_.size()>=2)
{
ref_ptr<filter<FeatureT> > right = filters_.top();
filters_.pop();
ref_ptr<filter<FeatureT> > left = filters_.top();
filters_.pop();
if (left && right)
{
filters_.push(ref_ptr<filter<FeatureT> >(new logical_or<FeatureT>(*left,*right)));
}
}
}
stack<ref_ptr<filter<FeatureT> > >& filters_;
};
template <typename FeatureT>
struct compose_not_filter
{
compose_not_filter(stack<ref_ptr<filter<FeatureT> > >& filters)
: filters_(filters) {}
template <typename Iter>
void operator() (Iter,Iter) const
{
if (filters_.size()>=1)
{
ref_ptr<filter<FeatureT> > filter_ = filters_.top();
filters_.pop();
if (filter_)
{
filters_.push(ref_ptr<filter<FeatureT> >(new logical_not<FeatureT>(*filter_)));
}
}
}
stack<ref_ptr<filter<FeatureT> > >& filters_;
};
template <typename FeatureT>
struct filter_grammar : public grammar<filter_grammar<FeatureT> >
{
filter_grammar(stack<ref_ptr<filter<FeatureT> > >& filters_,
stack<ref_ptr<expression<FeatureT> > >& exprs_)
: filters(filters_),exprs(exprs_) {}
template <typename ScannerT>
struct definition
{
definition(filter_grammar const& self)
{
typedef boost::spirit::chset<wchar_t> chset_t;
func1_op = "sqrt","sin","cos";
func2_op = "min","max";
spatial_op = "Equals","Disjoint","Touches","Within","Overlaps",
"Crosses","Intersects","Contains","DWithin","Beyond","BBOX";
chset_t BaseChar (L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E"
L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217"
L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE"
L"\x3D0-\x3D6\x3DA\x3DC\x3DE\x3E0\x3E2-\x3F3\x401-\x40C\x40E-\x44F"
L"\x451-\x45C\x45E-\x481\x490-\x4C4\x4C7-\x4C8\x4CB-\x4CC\x4D0-\x4EB"
L"\x4EE-\x4F5\x4F8-\x4F9\x531-\x556\x559\x561-\x586\x5D0-\x5EA"
L"\x5F0-\x5F2\x621-\x63A\x641-\x64A\x671-\x6B7\x6BA-\x6BE\x6C0-\x6CE"
L"\x6D0-\x6D3\x6D5\x6E5-\x6E6\x905-\x939\x93D\x958-\x961\x985-\x98C"
L"\x98F-\x990\x993-\x9A8\x9AA-\x9B0\x9B2\x9B6-\x9B9\x9DC-\x9DD"
L"\x9DF-\x9E1\x9F0-\x9F1\xA05-\xA0A\xA0F-\xA10\xA13-\xA28\xA2A-\xA30"
L"\xA32-\xA33\xA35-\xA36\xA38-\xA39\xA59-\xA5C\xA5E\xA72-\xA74"
L"\xA85-\xA8B\xA8D\xA8F-\xA91\xA93-\xAA8\xAAA-\xAB0\xAB2-\xAB3"
L"\xAB5-\xAB9\xABD\xAE0\xB05-\xB0C\xB0F-\xB10\xB13-\xB28\xB2A-\xB30"
L"\xB32-\xB33\xB36-\xB39\xB3D\xB5C-\xB5D\xB5F-\xB61\xB85-\xB8A"
L"\xB8E-\xB90\xB92-\xB95\xB99-\xB9A\xB9C\xB9E-\xB9F\xBA3-\xBA4"
L"\xBA8-\xBAA\xBAE-\xBB5\xBB7-\xBB9\xC05-\xC0C\xC0E-\xC10\xC12-\xC28"
L"\xC2A-\xC33\xC35-\xC39\xC60-\xC61\xC85-\xC8C\xC8E-\xC90\xC92-\xCA8"
L"\xCAA-\xCB3\xCB5-\xCB9\xCDE\xCE0-\xCE1\xD05-\xD0C\xD0E-\xD10"
L"\xD12-\xD28\xD2A-\xD39\xD60-\xD61\xE01-\xE2E\xE30\xE32-\xE33"
L"\xE40-\xE45\xE81-\xE82\xE84\xE87-\xE88\xE8A\xE8D\xE94-\xE97"
L"\xE99-\xE9F\xEA1-\xEA3\xEA5\xEA7\xEAA-\xEAB\xEAD-\xEAE\xEB0"
L"\xEB2-\xEB3\xEBD\xEC0-\xEC4\xF40-\xF47\xF49-\xF69\x10A0-\x10C5"
L"\x10D0-\x10F6\x1100\x1102-\x1103\x1105-\x1107\x1109\x110B-\x110C"
L"\x110E-\x1112\x113C\x113E\x1140\x114C\x114E\x1150\x1154-\x1155"
L"\x1159\x115F-\x1161\x1163\x1165\x1167\x1169\x116D-\x116E"
L"\x1172-\x1173\x1175\x119E\x11A8\x11AB\x11AE-\x11AF\x11B7-\x11B8"
L"\x11BA\x11BC-\x11C2\x11EB\x11F0\x11F9\x1E00-\x1E9B\x1EA0-\x1EF9"
L"\x1F00-\x1F15\x1F18-\x1F1D\x1F20-\x1F45\x1F48-\x1F4D\x1F50-\x1F57"
L"\x1F59\x1F5B\x1F5D\x1F5F-\x1F7D\x1F80-\x1FB4\x1FB6-\x1FBC\x1FBE"
L"\x1FC2-\x1FC4\x1FC6-\x1FCC\x1FD0-\x1FD3\x1FD6-\x1FDB\x1FE0-\x1FEC"
L"\x1FF2-\x1FF4\x1FF6-\x1FFC\x2126\x212A-\x212B\x212E\x2180-\x2182"
L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3");
chset_t Ideographic(L"\x4E00-\x9FA5\x3007\x3021-\x3029");
chset_t Letter = BaseChar | Ideographic;
chset_t CombiningChar(L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9"
L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670"
L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED"
L"\x0901-\x0903\x093C\x093E-\x094C\x094D\x0951-\x0954\x0962-\x0963"
L"\x0981-\x0983\x09BC\x09BE\x09BF\x09C0-\x09C4\x09C7-\x09C8"
L"\x09CB-\x09CD\x09D7\x09E2-\x09E3\x0A02\x0A3C\x0A3E\x0A3F"
L"\x0A40-\x0A42\x0A47-\x0A48\x0A4B-\x0A4D\x0A70-\x0A71\x0A81-\x0A83"
L"\x0ABC\x0ABE-\x0AC5\x0AC7-\x0AC9\x0ACB-\x0ACD\x0B01-\x0B03\x0B3C"
L"\x0B3E-\x0B43\x0B47-\x0B48\x0B4B-\x0B4D\x0B56-\x0B57\x0B82-\x0B83"
L"\x0BBE-\x0BC2\x0BC6-\x0BC8\x0BCA-\x0BCD\x0BD7\x0C01-\x0C03"
L"\x0C3E-\x0C44\x0C46-\x0C48\x0C4A-\x0C4D\x0C55-\x0C56\x0C82-\x0C83"
L"\x0CBE-\x0CC4\x0CC6-\x0CC8\x0CCA-\x0CCD\x0CD5-\x0CD6\x0D02-\x0D03"
L"\x0D3E-\x0D43\x0D46-\x0D48\x0D4A-\x0D4D\x0D57\x0E31\x0E34-\x0E3A"
L"\x0E47-\x0E4E\x0EB1\x0EB4-\x0EB9\x0EBB-\x0EBC\x0EC8-\x0ECD"
L"\x0F18-\x0F19\x0F35\x0F37\x0F39\x0F3E\x0F3F\x0F71-\x0F84"
L"\x0F86-\x0F8B\x0F90-\x0F95\x0F97\x0F99-\x0FAD\x0FB1-\x0FB7\x0FB9"
L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A");
chset_t Digit(L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF"
L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F"
L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29");
chset_t Extender(L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035"
L"\x309D-\x309E\x30FC-\x30FE");
chset_t NameChar =
Letter
| Digit
| L'.'
| L'-'
| L'_'
| L':'
| CombiningChar
| Extender;
number = strict_real_p [push_real<FeatureT>(self.exprs)]
| int_p [push_integer<FeatureT>(self.exprs)];
string_ = confix_p(L'\'',(*lex_escape_ch_p)
[push_string<FeatureT>(self.exprs)],
'\'');
property = L'[' >> ( (Letter | L'_' | L':')
>> *NameChar )[push_property<FeatureT>(self.exprs)] >> L']';
literal = number | string_ | property;
function = literal | ( func1_op >> L'('>> literal >> L')') |
(func2_op >> L'(' >> literal >> L','>> literal >> L')');
factor = function
| L'(' >> or_expr >> L')'
| ( L'-' >> factor)
;
term = factor
>> *((L'*' >> factor) [compose_expression<FeatureT,mapnik::mult<value> >(self.exprs)]
| (L'/' >> factor) [compose_expression<FeatureT,mapnik::div<value> >(self.exprs)]);
expression = term >> *((L'+' >> term) [compose_expression<FeatureT,mapnik::add<value> >(self.exprs)]
| (L'-' >> term) [compose_expression<FeatureT,mapnik::sub<value> >(self.exprs)]);
regex = str_p(L".match")>>L'('>>confix_p(L'\'',(*lex_escape_ch_p)
[compose_regex<FeatureT>(self.filters,self.exprs)],
L'\'') >>L')';
relation = expression
>> *((L">=" >> expression)
[compose_filter<FeatureT,greater_than_or_equal<value> >(self.filters,self.exprs)]
| (L'>' >> expression)
[compose_filter<FeatureT,mapnik::greater_than<value> >(self.filters,self.exprs)]
| (L'<' >> expression)
[compose_filter<FeatureT,mapnik::less_than<value> >(self.filters,self.exprs)]
| (L"<=" >> expression)
[compose_filter<FeatureT,less_than_or_equal<value> >(self.filters,self.exprs)]
| regex );
equation = relation >> *( ( L'=' >> relation)
[compose_filter<FeatureT,mapnik::equals<value> >(self.filters,self.exprs)]
| ( L"<>" >> relation)
[compose_filter<FeatureT,not_equals<value> >(self.filters,self.exprs)]);
not_expr = equation | *(str_p(L"not") >> equation)[compose_not_filter<FeatureT>(self.filters)];
and_expr = not_expr >> *(L"and" >> not_expr)[compose_and_filter<FeatureT>(self.filters)];
or_expr = and_expr >> *(L"or" >> and_expr)[compose_or_filter<FeatureT>(self.filters)];
filter_statement = or_expr;
}
boost::spirit::rule<ScannerT> const& start() const
{
return filter_statement;
}
boost::spirit::rule<ScannerT> factor;
boost::spirit::rule<ScannerT> term;
boost::spirit::rule<ScannerT> expression;
boost::spirit::rule<ScannerT> relation;
boost::spirit::rule<ScannerT> equation;
boost::spirit::rule<ScannerT> not_expr;
boost::spirit::rule<ScannerT> and_expr;
boost::spirit::rule<ScannerT> or_expr;
boost::spirit::rule<ScannerT> filter_statement;
boost::spirit::rule<ScannerT> literal;
boost::spirit::rule<ScannerT> number;
boost::spirit::rule<ScannerT> string_;
boost::spirit::rule<ScannerT> property;
boost::spirit::rule<ScannerT> function;
boost::spirit::rule<ScannerT> regex;
symbols<string> func1_op;
symbols<string> func2_op;
symbols<string> spatial_op;
};
stack<ref_ptr<filter<FeatureT> > >& filters;
stack<ref_ptr<expression<FeatureT> > >& exprs;
};
}
#endif //FILTER_PARSER_HPP

View file

@ -0,0 +1,261 @@
/* 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 FILTER_PARSER_AST_HPP
#define FILTER_PARSER_AST_HPP
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
#include <iostream>
using namespace std;
using namespace boost::spirit;
namespace mapnik
{
struct filter_grammar_ast : public grammar<filter_grammar_ast>
{
static const int integerID = 1;
static const int realID = 2;
static const int stringID = 3;
static const int propertyID = 4;
static const int factorID = 5;
static const int termID = 6;
static const int expressionID = 7;
static const int relationID = 8;
static const int equationID = 9;
static const int and_exprID = 10;
static const int or_exprID = 11;
template <typename ScannerT>
struct definition
{
definition(filter_grammar_ast const& /*self*/)
{
real = leaf_node_d[strict_real_p];
integer = leaf_node_d[int_p];
number = real | integer;
string_ = inner_node_d['\''>> leaf_node_d[( (alpha_p | '_') >>
* (alnum_p | '_' ))] >> '\''];
property = inner_node_d['[' >> leaf_node_d[ ( (alpha_p | '_') >> * (alnum_p | '_' )) ] >> ']'];
literal = number | string_ | property;
factor = literal
| (root_node_d[str_p("not")] >> literal)
| inner_node_d[ch_p('(') >> or_expr >> ch_p(')') ]
| (root_node_d[ch_p('-')] >> factor)
;
term = factor
>> *((root_node_d[ch_p('*')] >> factor) | (root_node_d[ch_p('/')] >> factor));
expression = term >> *((root_node_d[ch_p('+')] >> term) | (root_node_d[ch_p('-')] >> term));
relation = expression >> *((root_node_d[str_p(">=")] >> expression)
| (root_node_d[ch_p('>')] >> expression)
| (root_node_d[ch_p('<')] >> expression)
| (root_node_d[str_p("<=")] >> expression));
equation = relation >> *( (root_node_d[ch_p('=')] >> relation)
| (root_node_d[str_p("<>")] >> relation));
and_expr = equation >> *(root_node_d[str_p("and")] >> equation);
or_expr = and_expr >> *(root_node_d[str_p("or")] >> and_expr);
//spatial_op = str_p("Equals") | "Disjoint" | "Touches" | "Within"
// | "Overlaps" | "Crosses" | "Intersects" | "Contains" | "DWithin" | "Beyond" | "BBOX";
filter_statement = or_expr;
}
rule<ScannerT> const& start() const
{
return filter_statement;
}
rule<ScannerT,parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT,parser_context<>, parser_tag<termID> > term;
rule<ScannerT,parser_context<>, parser_tag<expressionID> > expression;
rule<ScannerT,parser_context<>, parser_tag<relationID> > relation;
rule<ScannerT,parser_context<>, parser_tag<equationID> > equation;
rule<ScannerT,parser_context<>, parser_tag<and_exprID> > and_expr;
rule<ScannerT,parser_context<>, parser_tag<or_exprID> > or_expr;
rule<ScannerT> filter_statement;
rule<ScannerT> literal,number;
rule<ScannerT,parser_context<>, parser_tag<integerID> > integer;
rule<ScannerT,parser_context<>, parser_tag<realID> > real;
rule<ScannerT,parser_context<>, parser_tag<stringID> > string_;
rule<ScannerT,parser_context<>, parser_tag<propertyID> > property;
//rule<ScannerT> spatial_op;
};
};
class node_data
{
public:
enum {
Unknown=0,
Integer=1,
Real =2,
String =3,
Property=4
};
node_data()
: type_(Unknown) {}
node_data(int type)
: type_(type) {}
node_data(node_data const& other)
: type_(other.type_) {}
node_data& operator=(node_data const& other)
{
if (this==&other)
return *this;
type_=other.type_;
return *this;
}
~node_data() {}
private:
int type_;
};
typedef char const* iterator_t;
typedef node_val_data_factory<node_data> factory_t;
typedef tree_match<iterator_t,factory_t>::tree_iterator iter_t;
void process_node(iter_t const&,string&);
void walk_ast_tree(tree_parse_info<iterator_t,factory_t> info,string& text)
{
process_node(info.trees.begin(),text);
}
void process_node(iter_t const& i,string& text)
{
//cout << "In eval_expression. i->value = " <<
// string(i->value.begin(), i->value.end()) <<
// " i->children.size() = " << i->children.size() << endl;
//std::cout<<typeid(*i).name()<<"\n";
if (i->value.id() == filter_grammar_ast::integerID)
{
assert(i->children.size()==0);
string integer(i->value.begin(), i->value.end());
text+= integer;
}
else if (i->value.id() == filter_grammar_ast::realID)
{
assert(i->children.size()==0);
string real(i->value.begin(), i->value.end());
text += real;
}
else if (i->value.id() == filter_grammar_ast::stringID)
{
assert(i->children.size()==0);
string str(i->value.begin(), i->value.end());
text += str;
}
else if (i->value.id() == filter_grammar_ast::propertyID)
{
assert(i->children.size()==0);
string property_name(i->value.begin(), i->value.end());
text += property_name;
}
else if (i->value.id() == filter_grammar_ast::expressionID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
else if (i->value.id() == filter_grammar_ast::termID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
else if (i->value.id() == filter_grammar_ast::relationID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
else if (i->value.id() == filter_grammar_ast::equationID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
else if (i->value.id() == filter_grammar_ast::and_exprID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
else if (i->value.id() == filter_grammar_ast::or_exprID)
{
assert(i->children.size() == 2);
assert(!i->children.begin()->value.is_root());
process_node(i->children.begin(),text);
text += string(i->value.begin(), i->value.end());
process_node(i->children.begin()+1,text);
text +="\n";
}
}
}
#endif //FILTER_PARSER_AST_HPP

View file

@ -0,0 +1,38 @@
/* 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 FILTER_VISITOR_HPP
#define FILTER_VISITOR_HPP
#include "filter.hpp"
#include "expression.hpp"
namespace mapnik
{
template <typename FeatureT> class filter;
template <typename FeatureT> class expression;
template <typename FeatureT>
struct filter_visitor
{
virtual void visit(filter<FeatureT>& filter)=0;
virtual void visit(expression<FeatureT>&)=0;
virtual ~filter_visitor() {}
};
}
#endif //FILTER_VISITOR_HPP

47
include/gamma.hpp Normal file
View file

@ -0,0 +1,47 @@
/* 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: gamma.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef GAMMA_HPP
#define GAMMA_HPP
namespace mapnik
{
struct gamma
{
unsigned char g2l[256];
unsigned char l2g[256];
gamma(double gamma=2.0)
{
int result;
for (int i=0;i< 256;i++)
{
result=(int)(pow(i/255.0,gamma) * 255.0 + 0.5);
g2l[i]=(unsigned short)result;
}
for (int i = 0; i < 256; i++)
{
result = (int)(pow(i/255.0, 1/gamma) * 255.0 + 0.5);
l2g[i] = (unsigned char)result;
}
}
};
}
#endif //GAMMA_HPP

227
include/geom_util.hpp Normal file
View file

@ -0,0 +1,227 @@
/* 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: geom_util.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef GEOM_UTIL_HPP
#define GEOM_UTIL_HPP
#include "geometry.hpp"
#include <cmath>
namespace mapnik
{
template <typename T>
bool clip_test(T p,T q,double& tmin,double& tmax)
{
double r;
bool result=true;
if (p<0.0)
{
r=q/p;
if (r>tmax) result=false;
else if (r>tmin) tmin=r;
}
else if (p>0.0)
{
r=q/p;
if (r<tmin) result=false;
else if (r<tmax) tmax=r;
} else if (q<0.0) result=false;
return result;
}
template <typename T,typename Image>
bool clip_line(T& x0,T& y0,T& x1,T& y1,const Image* image)
{
double tmin=0.0;
double tmax=1.0;
double dx=x1-x0;
if (clip_test<double>(-dx,x0,tmin,tmax))
{
if (clip_test<double>(dx,image->width()-x0,tmin,tmax))
{
double dy=y1-y0;
if (clip_test<double>(-dy,y0,tmin,tmax))
{
if (clip_test<double>(dy,image->height()-y0,tmin,tmax))
{
if (tmax<1.0)
{
x1=static_cast<T>(x0+tmax*dx);
y1=static_cast<T>(y0+tmax*dy);
}
if (tmin>0.0)
{
x0+=static_cast<T>(tmin*dx);
y0+=static_cast<T>(tmin*dy);
}
return true;
}
}
}
}
return false;
}
template <typename Iter>
inline bool point_inside_path(Iter start,Iter end,double x,double y)
{
bool inside=false;
double x0=start->x;
double y0=start->y;
double x1,y1;
while (++start!=end)
{
if (start->cmd == SEG_MOVETO)
{
x0=start->x;
y0=start->y;
continue;
}
x1=start->x;
y1=start->y;
if ((((y1 <= y) && (y < y0)) ||
((y0 <= y) && (y < y1))) &&
( x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
inside=!inside;
x0=x1;
y0=y1;
}
return inside;
}
#define TOL 0.00001
/*
(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
s = -----------------------------
L^2
*/
inline bool point_in_circle(double x,double y,double cx,double cy,double r)
{
double dx = x - cx;
double dy = y - cy;
double d2 = dx * dx + dy * dy;
return (d2 <= r * r);
}
inline bool point_on_segment(double x,double y,double x0,double y0,double x1,double y1)
{
double dx = x1 - x0;
double dy = y1 - y0;
if ( fabs(dx) > TOL || fabs(dy) > TOL )
{
double s = (y0 - y) * dx - (x0 - x) * dy;
return ( fabs (s) < TOL ) ;
}
return false;
}
inline bool point_on_segment2(double x,double y,double x0,double y0,double x1,double y1)
{
double d = sqrt ((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
double d0 = sqrt ((x0 - x) * (x0 - x) + (y0 - y) * (y0 - y));
double d1 = sqrt ((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y));
double d2 = d0 + d1;
return ( d2 - d < 0.01);
}
#undef TOL
inline bool point_on_path(double x,double y,const geometry<vertex2d>& geom)
{
bool on_path=false;
if (geom.num_points()>1)
{
geometry<vertex2d>::path_iterator<NO_SHIFT> itr=geom.begin<NO_SHIFT>();
geometry<vertex2d>::path_iterator<NO_SHIFT> end=geom.end<NO_SHIFT>();
double x0=itr->x;
double y0=itr->y;
while (++itr!=end)
{
if (itr->cmd == SEG_MOVETO)
{
x0=itr->x;
y0=itr->y;
continue;
}
double x1=itr->x;
double y1=itr->y;
on_path = point_on_segment(x,y,x0,y0,x1,y1);
if (on_path)
break;
x0=itr->x;
y0=itr->y;
}
}
return on_path;
}
inline bool point_on_points (double x,double y,const geometry_type& geom)
{
geometry<vertex2d>::path_iterator<NO_SHIFT> itr=geom.begin<NO_SHIFT>();
geometry<vertex2d>::path_iterator<NO_SHIFT> end=geom.end<NO_SHIFT>();
while (itr!=end)
{
double dx = x - itr->x;
double dy = y - itr->y;
double d = sqrt(dx*dx+dy*dy);
if (d < 0.02)
{
std::cout<<"d="<<d<<" x="<<x<<" y="<<y<<" itr->x="<<itr->x<<" itr->y="<<itr->y<<std::endl;
return true;
}
++itr;
}
return false;
}
struct filter_in_box
{
Envelope<double> box_;
explicit filter_in_box(const Envelope<double>& box)
: box_(box) {}
bool pass(const Envelope<double>& extent) const
{
return extent.intersects(box_);
}
};
struct filter_at_point
{
coord2d pt_;
explicit filter_at_point(const coord2d& pt)
: pt_(pt) {}
bool pass(const Envelope<double>& extent) const
{
return extent.contains(pt_);
}
};
}
#endif //GEOM_UTIL_HPP

256
include/geometry.hpp Normal file
View file

@ -0,0 +1,256 @@
/* 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: geometry.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef GEOMETRY_HPP
#define GEOMETRY_HPP
#include "vertex_vector.hpp"
#include "vertex_transform.hpp"
#include "ctrans.hpp"
#include "ptr.hpp"
namespace mapnik
{
enum {
Point = 1,
LineString = 2,
Polygon = 3,
};
template <typename T,template <typename> class Container=vertex_vector>
class geometry
{
public:
typedef T vertex_type;
typedef typename vertex_type::type value_type;
typedef Container<vertex_type> container_type;
private:
int srid_;
mutable unsigned itr_;
protected:
container_type cont_;
public:
geometry (int srid=-1)
: srid_(srid),
itr_(0),
cont_() {}
virtual int type() const=0;
virtual bool hit_test(value_type x,value_type y) const=0;
int srid() const
{
return srid_;
}
void move_to(value_type x,value_type y)
{
cont_.push_back(x,y,SEG_MOVETO);
}
void line_to(value_type x,value_type y)
{
cont_.push_back(x,y,SEG_LINETO);
}
template <typename Transform>
class path_iterator
{
typedef vertex<typename Transform::return_type,2> vertex_type;
const container_type* cont_;
unsigned pos_;
unsigned cmd_;
vertex_type vertex_;
private:
void advance ()
{
if (pos_ < cont_->size())
{
value_type x,y;
vertex_.cmd=cont_->get_vertex(pos_,&x,&y);
vertex_.x=Transform::apply(x);
vertex_.y=Transform::apply(y);
}
else
{
vertex_.cmd=SEG_END;
vertex_.x=0;
vertex_.y=0;
}
++pos_;
}
public:
path_iterator()
: cont_(0),
pos_(0),
cmd_(SEG_END),
vertex_(0,0,cmd_) {}
explicit path_iterator(const container_type& cont)
: cont_(&cont),
pos_(0),
cmd_(SEG_MOVETO),
vertex_(0,0,cmd_)
{
advance();
}
path_iterator& operator++()
{
advance();
return *this;
}
const vertex_type& operator*() const
{
return vertex_;
}
const vertex_type* operator->() const
{
return &vertex_;
}
bool operator !=(const path_iterator& itr)
{
return vertex_.cmd !=itr.vertex_.cmd;
}
};
template <typename Transform>
path_iterator<Transform> begin() const
{
return path_iterator<Transform>(cont_);
}
template <typename Transform>
path_iterator<Transform> end() const
{
return path_iterator<Transform>();
}
void transform(const mapnik::CoordTransform& t)
{
for (unsigned pos=0;pos<cont_.size();++pos)
{
cont_.transform_at(pos,t);
}
}
unsigned num_points() const
{
return cont_.size();
}
unsigned vertex(double* x, double* y)
{
return cont_.get_vertex(itr_++,x,y);
}
void rewind(unsigned )
{
itr_=0;
}
virtual ~geometry() {}
private:
geometry(const geometry&);
geometry& operator=(const geometry&);
};
template <typename T, template <typename> class Container=vertex_vector>
class point : public geometry<T,Container>
{
typedef typename geometry<T,Container>::value_type value_type;
using geometry<T,Container>::cont_;
public:
point(int srid)
: geometry<T,Container>(srid)
{}
int type() const
{
return Point;
}
bool hit_test(value_type x,value_type y) const
{
return point_on_points(x,y,*this);
}
};
template <typename T, template <typename> class Container=vertex_vector>
class polygon : public geometry<T,Container>
{
typedef geometry<T,Container> geometry_base;
typedef typename geometry_base::value_type value_type;
public:
polygon(int srid)
: geometry_base(srid)
{}
int type() const
{
return Polygon;
}
bool hit_test(value_type x,value_type y) const
{
typedef typename geometry_base::template path_iterator<NO_SHIFT> path_iterator;
path_iterator start = geometry_base::template begin<NO_SHIFT>();
path_iterator end = geometry_base::template end<NO_SHIFT>();
return point_inside_path(start,end,x,y);
}
};
template <typename T, template <typename> class Container=vertex_vector>
class line_string : public geometry<T,Container>
{
typedef typename geometry<T,Container>::value_type value_type;
public:
line_string(int srid)
: geometry<T,Container>(srid)
{}
int type() const
{
return LineString;
}
bool hit_test(value_type x,value_type y) const
{
return point_on_path(x,y,*this);
}
};
typedef point<vertex2d> point_impl;
typedef line_string<vertex2d> line_string_impl;
typedef polygon<vertex2d> polygon_impl;
typedef geometry<vertex2d> geometry_type;
typedef ref_ptr<geometry_type> geometry_ptr;
}
#endif //GEOMETRY_HPP

119
include/graphics.hpp Normal file
View file

@ -0,0 +1,119 @@
/* 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: graphics.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef GRAPHICS_HPP
#define GRAPHICS_HPP
#include <cmath>
#include <string>
#include <cassert>
#include "style.hpp"
#include "gamma.hpp"
#include "image_data.hpp"
namespace mapnik
{
class Image32
{
private:
unsigned width_;
unsigned height_;
Color background_;
ImageData32 data_;
static gamma gammaTable_;
public:
Image32(int width,int height);
Image32(const Image32& rhs);
~Image32();
static void setGamma(double gamma);
void setBackground(const Color& background);
const Color& getBackground() const;
void set_rectangle(unsigned x,unsigned y,const ImageData32& data);
const ImageData32& data() const;
inline ImageData32& data() {
return data_;
}
inline const unsigned char* raw_data() const
{
return data_.getBytes();
}
inline unsigned char* raw_data()
{
return data_.getBytes();
}
void saveToFile(const std::string& file,const std::string& format="auto");
private:
inline bool checkBounds(unsigned x,unsigned y) const
{
return ( x < width_ && y < height_);
}
public:
inline void setPixel(int x,int y,unsigned int rgba)
{
if (checkBounds(x,y))
{
data_(x,y)=rgba;
}
}
inline int blendColor(int c0,int c1,int t)
{
int bgRed=(c1>>16)&0xff;
int bgGreen=(c1>>8)&0xff;
int bgBlue=c1&0xff;
int red=(c0>>16)&0xff;
int green=(c0>>8)&0xff;
int blue=c0&0xff;
int alpha=t;
int r=gammaTable_.l2g[(gammaTable_.g2l[red]*alpha+gammaTable_.g2l[bgRed]*(255-alpha))>>8];
int g=gammaTable_.l2g[(gammaTable_.g2l[green]*alpha+gammaTable_.g2l[bgGreen]*(255-alpha))>>8];
int b=gammaTable_.l2g[(gammaTable_.g2l[blue]*alpha+gammaTable_.g2l[bgBlue]*(255-alpha))>>8];
return 0xff<<24 | r<<16 | g<<8 | b;
}
inline void blendPixel(int x,int y,unsigned int rgba,int t)
{
if (checkBounds(x,y))
{
int bg=data_(x,y);
int nc=blendColor(rgba,bg,t);
data_(x,y)=nc;
}
}
inline unsigned width() const
{
return width_;
}
inline unsigned height() const
{
return height_;
}
};
}
#endif //GRAPHICS_HPP

122
include/image_data.hpp Normal file
View file

@ -0,0 +1,122 @@
/* 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: image_data.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef IMAGE_DATA_HPP
#define IMAGE_DATA_HPP
namespace mapnik
{
template <class T> class ImageData
{
private:
const unsigned width_;
const unsigned height_;
T *pData_;
ImageData& operator=(const ImageData&);
public:
ImageData(unsigned width,unsigned height)
: width_(width),
height_(height),
pData_((width!=0 && height!=0)? static_cast<T*>(::operator new(sizeof(T)*width*height)):0)
{
if (pData_) memset(pData_,0,sizeof(T)*width_*height_);
}
ImageData(const ImageData<T>& rhs)
:width_(rhs.width_),
height_(rhs.height_),
pData_((rhs.width_!=0 && rhs.height_!=0)? new T[rhs.width_*rhs.height_]:0)
{
if (pData_) memcpy(pData_,rhs.pData_,sizeof(T)*rhs.width_* rhs.height_);
}
inline T& operator() (unsigned i,unsigned j)
{
assert(i<width_ && j<height_);
return pData_[j*width_+i];
}
inline const T& operator() (unsigned i,unsigned j) const
{
assert(i<width_ && j<height_);
return pData_[j*width_+i];
}
inline unsigned width() const
{
return width_;
}
inline unsigned height() const
{
return height_;
}
inline void set(const T& t)
{
for (unsigned i=0;i<width_;++i)
{
for (unsigned j=0;j<height_;++j)
{
(*this)(i,j)=t;
}
}
}
inline const T* getData() const
{
return pData_;
}
inline T* getData()
{
return pData_;
}
inline const unsigned char* getBytes() const
{
return (unsigned char*)pData_;
}
inline unsigned char* getBytes()
{
return (unsigned char*)pData_;
}
inline const T* getRow(unsigned row) const
{
return pData_+row*width_;
}
inline void setRow(unsigned row,const T* buf,unsigned size)
{
assert(row<height_);
assert(size<=(width_*sizeof(T)));
memcpy(pData_+row*width_,buf,size*sizeof(T));
}
inline void setRow(unsigned row,unsigned x0,unsigned x1,const T* buf)
{
memcpy(pData_+row*width_+x0,buf,(x1-x0)*sizeof(T));
}
inline ~ImageData()
{
::operator delete(pData_),pData_=0;
}
};
typedef ImageData<unsigned> ImageData32;
}
#endif //IMAGE_DATA_HPP

59
include/image_reader.hpp Normal file
View file

@ -0,0 +1,59 @@
/* 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: image_reader.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef IMAGE_READER_HPP
#define IMAGE_READER_HPP
#include "mapnik.hpp"
#include <stdexcept>
#include <string>
namespace mapnik
{
class ImageReaderException : public std::exception
{
private:
std::string message_;
public:
ImageReaderException(const std::string& message)
: message_(message) {}
~ImageReaderException() throw() {}
virtual const char* what() const throw()
{
return message_.c_str();
}
};
struct ImageReader
{
virtual unsigned width() const=0;
virtual unsigned height() const=0;
virtual void read(unsigned x,unsigned y,ImageData32& image)=0;
virtual ~ImageReader() {}
};
bool register_image_reader(const std::string& type,ImageReader* (*)(const std::string&));
ImageReader* get_image_reader(const std::string& type,const std::string& file);
}
#endif //IMAGE_READER_HPP

View file

@ -0,0 +1,78 @@
/* 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: image_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef IMAGE_SYMBOLIZER_HPP
#define IMAGE_SYMBOLIZER_HPP
#include "symbolizer.hpp"
#include "image_data.hpp"
namespace mapnik
{
struct image_symbolizer : public symbolizer
{
private:
ImageData32 symbol_;
public:
image_symbolizer(std::string const& file,
std::string const& type,
unsigned width,unsigned height)
: symbolizer(),
symbol_(width,height)
{
try
{
std::auto_ptr<ImageReader> reader(get_image_reader(type,file));
std::cout<<"image width="<<reader->width()<<std::endl;
std::cout<<"image height="<<reader->height()<<std::endl;
reader->read(0,0,symbol_);
}
catch (...)
{
std::cerr<<"exception caught..."<<std::endl;
}
}
virtual ~image_symbolizer() {}
void render(geometry_type& geom,Image32& image) const
{
int w=symbol_.width();
int h=symbol_.height();
geometry_type::path_iterator<SHIFT0> itr=geom.begin<SHIFT0>();
while (itr!=geom.end<SHIFT0>())
{
int x=itr->x;
int y=itr->y;
int px=int(x-0.5*w);
int py=int(y-0.5*h);
image.set_rectangle(px,py,symbol_);
++itr;
}
}
private:
image_symbolizer(const image_symbolizer&);
image_symbolizer& operator=(const image_symbolizer&);
};
}
#endif // IMAGE_SYMBOLIZER_HPP

208
include/image_util.hpp Normal file
View file

@ -0,0 +1,208 @@
/* 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: image_util.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef IMAGE_UTIL_HPP
#define IMAGE_UTIL_HPP
namespace mapnik
{
class ImageUtils
{
public:
static void save_to_file(const std::string& filename,const std::string& type,const Image32& image);
private:
static void save_as_png(const std::string& filename,const Image32& image);
static void save_as_jpeg(const std::string& filename,int quality, const Image32& image);
};
template <typename T>
double distance(T x0,T y0,T x1,T y1)
{
double dx = x1-x0;
double dy = y1-y0;
return sqrt(dx * dx + dy * dy);
}
template <typename Image>
inline void scale_down2(Image& target,const Image& source)
{
int source_width=source.width();
int source_height=source.height();
int target_width=target.width();
int target_height=target.height();
if (target_width<source_width/2 || target_height<source_height/2)
return;
int y1,x1;
for (int y=0;y<target_height;++y)
{
y1=2*y;
for(int x=0;x<target_width;++x)
{
x1=2*x;
//todo calculate average???
target(x,y)=source(x1,y1);
}
}
}
template <typename Image,int scale>
struct image_op
{
static void scale_up(Image& target,const Image& source)
{
if (scale<3) return;
int source_width=source.width();
int source_height=source.height();
int target_width=target.width();
int target_height=target.height();
if (target_width<scale*source_width || target_height<scale*source_height)
return;
for (int y=0;y<source_height;++y)
{
for(int x=0;x<source_width;++x)
{
unsigned p=source(x,y);
for (int i=0;i<scale;++i)
for (int j=0;j<scale;++j)
target(scale*x+i,scale*y+j)=p;
}
}
}
};
template <typename Image>
struct image_op<Image,2>
{
static void scale_up(Image& target,const Image& source)
{
int source_width=source.width();
int source_height=source.height();
int target_width=target.width();
int target_height=target.height();
if (target_width<2*source_width || target_height<2*source_height)
return;
for (int y=0;y<source_height;++y)
{
for(int x=0;x<source_width;++x)
{
target(2*x,2*y)=source(x,y);
target(2*x+1,2*y)=source(x,y);
target(2*x+1,2*y+1)=source(x,y);
target(2*x,2*y+1)=source(x,y);
}
}
}
};
namespace
{
template <typename Image>
inline void scale_up(Image& target,const Image& source,unsigned scale)
{
int source_width=source.width();
int source_height=source.height();
int target_width=target.width();
int target_height=target.height();
if (target_width<scale*source_width || target_height<scale*source_height)
return;
for (int y=0;y<source_height;++y)
{
for(int x=0;x<source_width;++x)
{
unsigned p=source(x,y);
for (int i=0;i<scale;++i)
for (int j=0;j<scale;++j)
target(scale*x+i,scale*y+j)=p;
}
}
}
}
template <typename Image>
void scale_image(Image& target,const Image& source,unsigned scale)
{
if (scale==2)
{
image_op<Image,2>::scale_up(target,source);
}
else
{
scale_up<Image>(target,source,scale);
}
}
template <typename Image>
inline void scale_image (Image& target,const Image& source)
{
int source_width=source.width();
int source_height=source.height();
int target_width=target.width();
int target_height=target.height();
if (source_width<1 || source_height<1 ||
target_width<1 || target_height<1) return;
int int_part_y=source_height/target_height;
int fract_part_y=source_height%target_height;
int err_y=0;
int int_part_x=source_width/target_width;
int fract_part_x=source_width%target_width;
int err_x=0;
int x=0,y=0,xs=0,ys=0;
int prev_y=-1;
for (y=0;y<target_height;++y)
{
if (ys==prev_y)
{
target.setRow(y,target.getRow(y-1),target_width);
}
else
{
xs=0;
for (x=0;x<target_width;++x)
{
target(x,y)=source(xs,ys);
xs+=int_part_x;
err_x+=fract_part_x;
if (err_x>=target_width)
{
err_x-=target_width;
++xs;
}
}
prev_y=ys;
}
ys+=int_part_y;
err_y+=fract_part_y;
if (err_y>=target_height)
{
err_y-=target_height;
++ys;
}
}
}
}
#endif //IMAGE_UTIL_HPP

View file

@ -0,0 +1,51 @@
/* 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 LABEL_PLACEMENT_HPP
#define LABEL_PLACEMENT_HPP
namespace mapnik
{
struct point_
{
double x;
double y;
point_()
: x(0),y(0) {}
point_(double x_,double y_)
: x(x_),y(y_) {}
};
class label_placement
{
private:
point_ anchor_;
point_ displacement_;
double rotation_;
public:
label_placement()
: anchor_(),
displacement_(),
rotation_(0.0) {}
};
}
#endif //LABEL_PLACEMENT_HPP

74
include/layer.hpp Normal file
View file

@ -0,0 +1,74 @@
/* 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: layer.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef LAYER_HPP
#define LAYER_HPP
#include <vector>
#include "feature.hpp"
#include "ptr.hpp"
#include "datasource.hpp"
namespace mapnik
{
class Layer
{
private:
Parameters params_;
std::string name_;
double minZoom_;
double maxZoom_;
bool active_;
bool selectable_;
datasource_p ds_;
std::vector<std::string> styles_;
std::string selection_style_;
mutable std::vector<ref_ptr<Feature> > selection_;
public:
explicit Layer(const Parameters& params);
Layer(const Layer& l);
Layer& operator=(const Layer& l);
Parameters const& params() const;
const std::string& name() const;
void add_style(std::string const& stylename);
std::vector<std::string> const& styles() const;
void selection_style(const std::string& name);
const std::string& selection_style() const;
void setMinZoom(double minZoom);
void setMaxZoom(double maxZoom);
double getMinZoom() const;
double getMaxZoom() const;
void setActive(bool active);
bool isActive() const;
void setSelectable(bool selectable);
bool isSelectable() const;
bool isVisible(double scale) const;
void add_to_selection(ref_ptr<Feature>& feature) const;
std::vector<ref_ptr<Feature> >& selection() const;
void clear_selection() const;
const datasource_p& datasource() const;
const Envelope<double>& envelope() const;
virtual ~Layer();
private:
void swap(const Layer& other);
};
}
#endif //LAYER_HPP

46
include/line_aa.hpp Normal file
View 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: line_aa.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef LINE_AA_HPP
#define LINE_AA_HPP
#include "geometry.hpp"
#include "graphics.hpp"
#include "style.hpp"
namespace mapnik
{
template <typename PixBuffer> class LineRasterizerAA
{
private:
PixBuffer* pixbuf_;
public:
LineRasterizerAA(PixBuffer& pixbuf)
:pixbuf_(&pixbuf) {}
template <typename Transform>
void render(const geometry_type& geom,const Color& c);
private:
LineRasterizerAA(const LineRasterizerAA&);
LineRasterizerAA& operator=(const LineRasterizerAA&);
void render_line(int x0,int y0,int x1,int y1,unsigned rgba);
};
}
#endif //LINE_AA_HPP

189
include/line_symbolizer.hpp Normal file
View file

@ -0,0 +1,189 @@
/* 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: line_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef LINE_SYMBOLIZER_HPP
#define LINE_SYMBOLIZER_HPP
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_stroke.h"
#include "agg_conv_curve.h"
#include "agg_conv_dash.h"
#include "agg_conv_contour.h"
#include "agg_conv_stroke.h"
#include "agg_vcgen_stroke.h"
#include "agg_conv_adaptor_vcgen.h"
#include "agg_conv_smooth_poly1.h"
#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_vcgen_markers_term.h"
#include "agg_scanline_p.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h"
#include "agg_path_storage.h"
#include "agg_renderer_outline_aa.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_outline.h"
#include "agg_renderer_outline_image.h"
#include "symbolizer.hpp"
#include "stroke.hpp"
#include "line_aa.hpp"
#include "scanline_aa.hpp"
namespace mapnik
{
struct line_symbolizer : public symbolizer
{
private:
stroke stroke_;
public:
line_symbolizer(stroke const& stroke)
: symbolizer(),
stroke_(stroke) {}
line_symbolizer(const Color& pen,float width=1.0)
: symbolizer(),
stroke_(pen,width) {}
void render(geometry_type& geom, Image32& image) const
{
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
agg::row_ptr_cache<agg::int8u> buf(image.raw_data(),image.width(),image.height(),
image.width()*4);
agg::pixfmt_rgba32 pixf(buf);
ren_base renb(pixf);
Color const& col = stroke_.get_color();
double r=col.red()/255.0;
double g=col.green()/255.0;
double b=col.blue()/255.0;
if (0) //stroke_.width() == 1.0)
{
typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
agg::line_profile_aa prof;
prof.width(stroke_.get_width());
renderer_oaa ren_oaa(renb, prof);
rasterizer_outline_aa ras_oaa(ren_oaa);
ren_oaa.color(agg::rgba(r, g, b, stroke_.get_opacity()));
ras_oaa.add_path(geom);
//LineRasterizerAA<Image32> rasterizer(image);
//rasterizer.render<SHIFT0>(geom,stroke_.get_color());
}
else
{
//typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
renderer ren(renb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
if (stroke_.has_dash())
{
agg::conv_dash<geometry<vertex2d,vertex_vector> > dash(geom);
dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin();
dash_array::const_iterator end = d.end();
while (itr != end)
{
dash.add_dash(itr->first, itr->second);
++itr;
}
agg::conv_stroke<agg::conv_dash<geometry<vertex2d,vertex_vector> > > stroke(dash);
line_join_e join=stroke_.get_line_join();
if ( join == MITER_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == MITER_REVERT_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == ROUND_JOIN)
stroke.generator().line_join(agg::round_join);
else
stroke.generator().line_join(agg::bevel_join);
line_cap_e cap=stroke_.get_line_cap();
if (cap == BUTT_CAP)
stroke.generator().line_cap(agg::butt_cap);
else if (cap == SQUARE_CAP)
stroke.generator().line_cap(agg::square_cap);
else
stroke.generator().line_cap(agg::round_cap);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width());
ras.clip_box(0,0,image.width(),image.height());
ras.add_path(stroke);
ren.color(agg::rgba(r, g, b, stroke_.get_opacity()));
agg::render_scanlines(ras, sl, ren);
}
else
{
agg::conv_stroke<geometry<vertex2d,vertex_vector> > stroke(geom);
line_join_e join=stroke_.get_line_join();
if ( join == MITER_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == MITER_REVERT_JOIN)
stroke.generator().line_join(agg::miter_join);
else if( join == ROUND_JOIN)
stroke.generator().line_join(agg::round_join);
else
stroke.generator().line_join(agg::bevel_join);
line_cap_e cap=stroke_.get_line_cap();
if (cap == BUTT_CAP)
stroke.generator().line_cap(agg::butt_cap);
else if (cap == SQUARE_CAP)
stroke.generator().line_cap(agg::square_cap);
else
stroke.generator().line_cap(agg::round_cap);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width());
ras.clip_box(0,0,image.width(),image.height());
ras.add_path(stroke);
ren.color(agg::rgba(r, g, b, stroke_.get_opacity()));
agg::render_scanlines(ras, sl, ren);
}
}
}
private:
line_symbolizer(const line_symbolizer&);
line_symbolizer& operator=(const line_symbolizer&);
};
}
#endif //LINE_SYMBOLIZER_HPP

View file

@ -0,0 +1,47 @@
/* 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 LOCAL_DATASOURCE_HPP
#define LOCAL_DATASOURCE_HPP
#include "mapnik.hpp"
#include <vector>
namespace mapnik
{
/*
class local_datasource : public datasource
{
public:
local_datasource(Parameters const& params);
int type() const;
static std::string name();
featureset_ptr features(query const& q) const;
const Envelope<double>& envelope() const;
virtual ~local_datasource();
private:
static std::string name_;
Envelope<double> extent_;
std::vector<Feature*>
};
*/
}
#endif //LOCAL_DATASOURCE_HPP

169
include/logical.hpp Normal file
View file

@ -0,0 +1,169 @@
/* 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 LOGICAL_HPP
#define LOGICAL_HPP
#include "filter.hpp"
namespace mapnik
{
template <typename FeatureT>
struct logical_and : public filter<FeatureT>
{
logical_and(filter<FeatureT> const& filter1,
filter<FeatureT> const& filter2)
: filter<FeatureT>(),
filter1_(filter1.clone()),
filter2_(filter2.clone()) {}
logical_and(logical_and const& other)
: filter<FeatureT>(),
filter1_(other.filter1_->clone()),
filter2_(other.filter2_->clone()) {}
bool pass(const FeatureT& feature) const
{
return (filter1_->pass(feature) &&
filter2_->pass(feature));
}
std::string to_string() const
{
return "("+filter1_->to_string()+" and "+filter2_->to_string()+")";
}
filter<FeatureT>* clone() const
{
return new logical_and(*this);
}
void accept(filter_visitor<FeatureT>& v)
{
filter1_->accept(v);
filter2_->accept(v);
v.visit(*this);
}
virtual ~logical_and()
{
delete filter1_;
delete filter2_;
}
private:
filter<FeatureT>* filter1_;
filter<FeatureT>* filter2_;
};
template <typename FeatureT>
struct logical_or : public filter<FeatureT>
{
logical_or(const filter<FeatureT>& filter1,const filter<FeatureT>& filter2)
: filter<FeatureT>(),
filter1_(filter1.clone()),
filter2_(filter2.clone()) {}
logical_or(logical_or const& other)
: filter<FeatureT>(),
filter1_(other.filter1_->clone()),
filter2_(other.filter2_->clone()) {}
bool pass(const FeatureT& feature) const
{
if (filter1_->pass(feature))
{
return true;
}
else
{
return filter2_->pass(feature);
}
}
filter<FeatureT>* clone() const
{
return new logical_or(*this);
}
void accept(filter_visitor<FeatureT>& v)
{
filter1_->accept(v);
filter2_->accept(v);
v.visit(*this);
}
std::string to_string() const
{
return "("+filter1_->to_string()+" or "+filter2_->to_string()+")";
}
virtual ~logical_or()
{
delete filter1_;
delete filter2_;
}
private:
filter<FeatureT>* filter1_;
filter<FeatureT>* filter2_;
};
template <typename FeatureT>
struct logical_not : public filter<FeatureT>
{
logical_not(filter<FeatureT> const& _filter)
: filter<FeatureT>(),
filter_(_filter.clone()) {}
logical_not(logical_not const& other)
: filter<FeatureT>(),
filter_(other.filter_->clone()) {}
int type() const
{
return filter<FeatureT>::LOGICAL_OPS;
}
bool pass(const FeatureT& feature) const
{
return !(filter_->pass(feature));
}
filter<FeatureT>* clone() const
{
return new logical_not(*this);
}
void accept(filter_visitor<FeatureT>& v)
{
filter_->accept(v);
v.visit(*this);
}
std::string to_string() const
{
return "not ("+filter_->to_string()+")";
}
~logical_not()
{
delete filter_;
}
private:
filter<FeatureT>* filter_;
};
}
#endif //LOGICAL_HPP

64
include/map.hpp Normal file
View file

@ -0,0 +1,64 @@
/* 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: map.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef MAP_HPP
#define MAP_HPP
namespace mapnik
{
class Layer;
class Map
{
private:
static const int MIN_MAPSIZE=16;
static const int MAX_MAPSIZE=1024;
int width_;
int height_;
int srid_;
Color background_;
std::vector<Layer> layers_;
Envelope<double> currentExtent_;
public:
Map(int width,int height,int srid=-1);
Map(const Map& rhs);
Map& operator=(const Map& rhs);
size_t layerCount() const;
void addLayer(const Layer& l);
const Layer& getLayer(size_t index) const;
void removeLayer(size_t index);
void removeLayer(const char* lName);
int getWidth() const;
int getHeight() const;
int srid() const;
void setBackground(const Color& c);
const Color& getBackground() const;
void zoom(double zoom);
void zoomToBox(const Envelope<double>& box);
void pan(int x,int y);
void pan_and_zoom(int x,int y,double zoom);
const Envelope<double>& getCurrentExtent() const;
double scale() const;
virtual ~Map();
private:
void fixAspectRatio();
};
}
#endif //MAP_HPP

76
include/mapnik.hpp Normal file
View 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.
*/
//$Id: mapnik.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef MAPNIK_HPP
#define MAPNIK_HPP
#include <map>
#include <vector>
#include <cassert>
#include "ptr.hpp"
#include "factory.hpp"
#include "filter.hpp"
#include "query.hpp"
#include "rule.hpp"
#include "spatial.hpp"
#include "logical.hpp"
#include "comparison.hpp"
#include "regex_filter.hpp"
#include "utils.hpp"
#include "style.hpp"
#include "symbolizer.hpp"
#include "style_cache.hpp"
#include "geometry.hpp"
#include "geom_util.hpp"
#include "raster.hpp"
#include "feature.hpp"
#include "attribute.hpp"
#include "attribute_collector.hpp"
#include "render.hpp"
#include "graphics.hpp"
#include "image_reader.hpp"
#include "line_symbolizer.hpp"
#include "polygon_symbolizer.hpp"
//#include "image_symbolizer.hpp"
#include "image_util.hpp"
#include "datasource.hpp"
#include "layer.hpp"
#include "datasource_cache.hpp"
#include "wkb.hpp"
#include "map.hpp"
#include "colorcube.hpp"
#include "feature_type_style.hpp"
#include "math_expr.hpp"
#include "value.hpp"
#include "expression.hpp"
#include "filter_visitor.hpp"
#include "filter_parser.hpp"
#include "filter_factory.hpp"
#include "text_symbolizer.hpp"
#include "label_placement.hpp"
#include "feature_layer_desc.hpp"
namespace mapnik
{
//typedef geometry_type geometry_type;
}
#endif //MAPNIK_HPP

126
include/math_expr.hpp Normal file
View file

@ -0,0 +1,126 @@
/* 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 MATH_EXPR_HPP
#define MATH_EXPR_HPP
#include "expression.hpp"
namespace mapnik
{
template <typename T>
struct add
{
T operator () (T const& left, T const& right)
{
return left + right;
}
static std::string to_string()
{
return "+";
}
};
template <typename T>
struct sub
{
T operator () (T const& left, T const& right)
{
return left - right;
}
static std::string to_string()
{
return "-";
}
};
template <typename T>
struct mult
{
T operator () (T const& left, T const& right)
{
return left * right;
}
static std::string to_string()
{
return "*";
}
};
template <typename T>
struct div
{
T operator () (T const& left, T const& right)
{
return left / right;
}
static std::string to_string()
{
return "/";
}
};
template <typename FeatureT,typename Op>
struct math_expr_b : public expression<FeatureT>
{
math_expr_b(expression<FeatureT> const& left,
expression<FeatureT> const& right)
: expression<FeatureT>(),
left_(left.clone()),
right_(right.clone()) {}
math_expr_b(math_expr_b const& other)
: expression<FeatureT>(),
left_(other.left_->clone()),
right_(other.right_->clone()) {}
value get_value(FeatureT const& feature) const
{
return Op ()(left_->get_value(feature),right_->get_value(feature));
}
void accept(filter_visitor<FeatureT>& v)
{
left_->accept(v);
right_->accept(v);
v.visit(*this);
}
expression<FeatureT>* clone() const
{
return new math_expr_b<FeatureT,Op>(*this);
}
std::string to_string() const
{
return "("+left_->to_string() + Op::to_string() + right_->to_string()+")";
}
~math_expr_b()
{
delete left_;
delete right_;
}
private:
expression<FeatureT>* left_;
expression<FeatureT>* right_;
};
};
#endif //

85
include/memory.hpp Normal file
View 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: memory.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef MEMORY_HPP
#define MEMORY_HPP
#include <iostream>
#include <cassert>
namespace mapnik
{
class MemoryUtils
{
public:
static size_t alignPointerSize(size_t ptrSize);
private:
MemoryUtils();
MemoryUtils(const MemoryUtils&);
MemoryUtils& operator=(const MemoryUtils&);
};
class MemoryManager
{
public:
virtual void* allocate(size_t size)=0;
virtual void deallocate(void* p)=0;
virtual ~MemoryManager();
protected:
MemoryManager(); // {}
private:
MemoryManager(const MemoryManager&);
MemoryManager& operator=(const MemoryManager&);
};
class Object
{
public:
void* operator new(size_t size);
void* operator new(size_t size, MemoryManager* manager);
void operator delete(void* p);
void operator delete(void* p, MemoryManager* manager);
protected:
virtual ~Object() {}
Object() {}
Object(const Object&) {}
protected:
Object& operator=(const Object&)
{
return *this;
}
};
template <typename Geometry>
class geometry_pool
{
public:
void* allocate()
{
return ::operator new(sizeof(Geometry));
}
void deallocate(void* p)
{
::operator delete(p);
}
};
}
#endif //MEMORY_HPP

47
include/params.hpp Normal file
View file

@ -0,0 +1,47 @@
/* 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: params.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef PARAMS_HPP
#define PARAMS_HPP
#include <map>
namespace mapnik
{
typedef std::pair<std::string,std::string> Parameter;
class Parameters
{
typedef std::map<std::string,std::string> ParamMap;
private:
ParamMap data_;
public:
typedef ParamMap::const_iterator const_iterator;
Parameters() {}
const std::string get(const std::string& name) const;
void add(const Parameter& param);
void add(const std::string& name,const std::string& value);
const_iterator begin() const;
const_iterator end() const;
virtual ~Parameters();
};
}
#endif //PARAMS_HPP

46
include/plugin.hpp Normal file
View 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: plugin.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef PLUGIN_HPP
#define PLUGIN_HPP
#include <ltdl.h>
#include <string>
namespace mapnik
{
class PluginInfo
{
private:
std::string name_;
lt_dlhandle module_;
public:
PluginInfo (const std::string& name,const lt_dlhandle module);
~PluginInfo();
const std::string& name() const;
lt_dlhandle handle() const;
private:
PluginInfo(const PluginInfo&);
PluginInfo& operator=(const PluginInfo&);
};
}
#endif //PLUGIN_HPP

View file

@ -0,0 +1,54 @@
/* 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: polygon_symbolizer.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef POLYGON_SYMBOLIZER_HPP
#define POLYGON_SYMBOLIZER_HPP
#include "symbolizer.hpp"
#include "scanline_aa.hpp"
#include "line_aa.hpp"
namespace mapnik
{
struct polygon_symbolizer : public symbolizer
{
private:
Color fill_;
public:
polygon_symbolizer(const Color& fill)
: symbolizer(),
fill_(fill) {}
virtual ~polygon_symbolizer() {}
void render(geometry_type& geom,Image32& image) const
{
ScanlineRasterizerAA<Image32> rasterizer(image);
rasterizer.render<SHIFT8>(geom,fill_);
}
private:
polygon_symbolizer(const polygon_symbolizer&);
polygon_symbolizer& operator=(const polygon_symbolizer&);
};
}
#endif // POLYGON_SYMBOLIZER_HPP

120
include/pool.hpp Normal file
View file

@ -0,0 +1,120 @@
/* 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: pool.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef POOL_HPP
#define POOL_HPP
#include <iostream>
#include <map>
#include <deque>
#include <ctime>
#include "ptr.hpp"
#include "utils.hpp"
namespace mapnik
{
template <typename T, typename PoolT>
class PoolGuard
{
private:
const T& obj_;
PoolT& pool_;
public:
explicit PoolGuard(const T& ptr,PoolT& pool)
: obj_(ptr),
pool_(pool) {}
~PoolGuard()
{
pool_->returnObject(obj_);
}
private:
PoolGuard();
PoolGuard(const PoolGuard&);
PoolGuard& operator=(const PoolGuard&);
};
template <typename T,template <typename> class Creator>
class Pool
{
typedef ref_ptr<T> HolderType;
typedef std::deque<HolderType> ContType;
Creator<T> creator_;
const int initialSize_;
const int maxSize_;
ContType usedPool_;
ContType unusedPool_;
Mutex mutex_;
public:
Pool(const Creator<T>& creator,int initialSize=5,int maxSize=20)
:creator_(creator),
initialSize_(initialSize),
maxSize_(maxSize)
{
for (int i=0;i<initialSize_;++i)
{
unusedPool_.push_back(HolderType(creator_()));
}
}
const HolderType& borrowObject()
{
Lock lock(&mutex_);
typename ContType::iterator itr=unusedPool_.begin();
if (itr!=unusedPool_.end())
{
std::cout<<"borrow "<<(*itr).get()<<"\n";
usedPool_.push_back(*itr);
itr=unusedPool_.erase(itr);
mutex_.unlock();
return usedPool_[usedPool_.size()-1];
}
static const HolderType defaultObj(0);
return defaultObj;
}
void returnObject(const HolderType& obj)
{
Lock lock(&mutex_);
typename ContType::iterator itr=usedPool_.begin();
while (itr != usedPool_.end())
{
if (obj.get()==(*itr).get())
{
std::cout<<"return "<<(*itr).get()<<"\n";
unusedPool_.push_back(*itr);
usedPool_.erase(itr);
return;
}
++itr;
}
}
private:
Pool(const Pool&);
Pool& operator=(const Pool&);
};
}
#endif //POOL_HPP

View file

@ -0,0 +1,68 @@
/* 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_INDEX_HPP
#define PROPERTY_INDEX_HPP
#include "filter.hpp"
#include "expression.hpp"
#include <set>
namespace mapnik
{
template <typename FeatureT>
class property_index : public filter_visitor<FeatureT>
{
public:
property_index(std::set<std::string> const& names)
: names_(names) {}
void visit(filter<FeatureT>& /*filter*/)
{
//not interested
}
void visit(expression<FeatureT>& exp)
{
property<FeatureT>* pf;
if ((pf = dynamic_cast<property<FeatureT>*>(&exp)))
{
std::set<std::string>::iterator pos;
pos = names_.find(pf->name());
if (pos != names_.end())
{
size_t idx = std::distance(names_.begin(),pos);
pf->set_index(idx);
}
}
}
virtual ~property_index() {}
private:
// no copying
property_index(property_index const&);
property_index& operator=(property_index const&);
private:
std::set<std::string> const& names_;
};
}
#endif //PROPERTY_INDEX_HPP

107
include/ptr.hpp Normal file
View file

@ -0,0 +1,107 @@
/* 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: ptr.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef PTR_HPP
#define PTR_HPP
namespace mapnik
{
template <typename T> struct DefaultDeletePolicy
{
static void destroy(T* p)
{
delete p;
}
};
template <typename T,
template <typename T> class DeallocPolicy=DefaultDeletePolicy>
class ref_ptr
{
private:
T* ptr_;
int* pCount_;
public:
T* operator->() {return ptr_;}
const T* operator->() const {return ptr_;}
T* get() {return ptr_;}
const T* get() const {return ptr_;}
const T& operator *() const {return *ptr_;}
T& operator *() {return *ptr_;}
explicit ref_ptr(T* ptr=0)
:ptr_(ptr),pCount_(new int(1)) {}
ref_ptr(const ref_ptr& rhs)
:ptr_(rhs.ptr_),pCount_(rhs.pCount_)
{
(*pCount_)++;
}
ref_ptr& operator=(const ref_ptr& rhs)
{
if (ptr_==rhs.ptr_) return *this;
if (--(*pCount_)==0)
{
DeallocPolicy<T>::destroy(ptr_);
delete pCount_;
}
ptr_=rhs.ptr_;
pCount_=rhs.pCount_;
(*pCount_)++;
return *this;
}
bool operator !() const
{
return ptr_==0;
}
operator bool () const
{
return ptr_!=0;
}
inline friend bool operator==(const ref_ptr& lhs,
const T* rhs)
{
return lhs.ptr_==rhs;
}
inline friend bool operator==(const T* lhs,
const ref_ptr& rhs)
{
return lhs==rhs.ptr_;
}
inline friend bool operator!=(const ref_ptr& lhs,
const T* rhs)
{
return lhs.ptr_!=rhs;
}
inline friend bool operator!=(const T* lhs,
const ref_ptr& rhs)
{
return lhs!=rhs.ptr_;
}
~ref_ptr()
{
if (--(*pCount_)==0)
{
DeallocPolicy<T>::destroy(ptr_);
delete pCount_;
}
}
};
}
#endif //PTR_HPP

107
include/query.hpp Normal file
View file

@ -0,0 +1,107 @@
/* 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 QUERY_HPP
#define QUERY_HPP
#include <set>
#include <limits>
#include "filter.hpp"
#include "envelope.hpp"
#include "feature.hpp"
namespace mapnik
{
class query
{
private:
Envelope<double> bbox_;
filter<Feature>* filter_;
std::set<std::string> names_;
public:
query()
: bbox_(std::numeric_limits<double>::min(),
std::numeric_limits<double>::min(),
std::numeric_limits<double>::max(),
std::numeric_limits<double>::max()),
filter_(new null_filter<Feature>)
{}
query(const Envelope<double>& bbox)
: bbox_(bbox),
filter_(new null_filter<Feature>)
{}
query(const Envelope<double>& bbox,const filter<Feature>& f)
: bbox_(bbox),
filter_(f.clone())
{}
query(const query& other)
: bbox_(other.bbox_),
filter_(other.filter_->clone())
{}
query& operator=(const query& other)
{
filter<Feature>* tmp=other.filter_->clone();
delete filter_;
filter_=tmp;
bbox_=other.bbox_;
names_=other.names_;
return *this;
}
const filter<Feature>* get_filter() const
{
return filter_;
}
const Envelope<double>& get_bbox() const
{
return bbox_;
}
void set_filter(const filter<Feature>& f)
{
filter<Feature>* tmp=f.clone();
delete filter_;
filter_=tmp;
}
void add_property_name(const std::string& name)
{
names_.insert(name);
}
const std::set<std::string>& property_names() const
{
return names_;
}
~query()
{
delete filter_;
}
};
}
#endif //QUERY_HPP

40
include/raster.hpp Normal file
View file

@ -0,0 +1,40 @@
/* 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.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef RASTER_HPP
#define RASTER_HPP
#include "graphics.hpp"
namespace mapnik
{
struct raster
{
int x_;
int y_;
ImageData32 data_;
raster(int x,int y,ImageData32& data)
: x_(x),
y_(y),
data_(data) {}
};
}
#endif //RASTER_HPP

79
include/regex_filter.hpp Normal file
View 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$
#ifndef REGEX_FILTER_HPP
#define REGEX_FILTER_HPP
#include "filter.hpp"
#include "expression.hpp"
#include <boost/regex.hpp>
namespace mapnik
{
template <typename FeatureT>
struct regex_filter : public filter<FeatureT>
{
regex_filter(expression<FeatureT> const& exp,
std::string const& pattern)
: filter<FeatureT>(),
exp_(exp.clone()),
pattern_(pattern) {}
regex_filter(regex_filter const& other)
: filter<FeatureT>(),
exp_(other.exp_->clone()),
pattern_(other.pattern_) {}
bool pass(FeatureT const& feature) const
{
std::string text=exp_->get_value(feature).to_string();
return boost::regex_match(text,pattern_);
}
void accept(filter_visitor<FeatureT>& v)
{
exp_->accept(v);
v.visit(*this);
}
filter<FeatureT>* clone() const
{
return new regex_filter(*this);
}
std::string to_string() const
{
return exp_->to_string()+".match("+pattern_.str()+")";
}
~regex_filter()
{
delete exp_;
}
private:
expression<FeatureT>* exp_;
boost::regex pattern_;
};
}
#endif //REGEX_FILTER_HPP

46
include/render.hpp Normal file
View 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: render.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef RENDER_HPP
#define RENDER_HPP
#include <stack>
#include "memory.hpp"
#include "ptr.hpp"
#include "style.hpp"
#include "envelope.hpp"
#include "graphics.hpp"
#include "datasource.hpp"
#include "layer.hpp"
#include "map.hpp"
namespace mapnik
{
template <typename Image> class Renderer
{
public:
static void render(const Map& map,Image& image);
private:
Renderer();
static void renderLayer(const Layer& l,const CoordTransform& t,const Envelope<double>& bbox,Image& image);
};
}
#endif //RENDER_HPP

217
include/rule.hpp Normal file
View file

@ -0,0 +1,217 @@
/* 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 RULE_HPP
#define RULE_HPP
#include "symbolizer.hpp"
#include "filter.hpp"
#include <ptr.hpp>
#include <string>
#include <vector>
namespace mapnik
{
typedef ref_ptr<symbolizer> symbolizer_ptr;
typedef std::vector<symbolizer_ptr> symbolizers;
template <typename FeatureT> class null_filter;
template <typename FeatureT,template <typename> class Filter>
class rule
{
typedef Filter<FeatureT> filter_type;
typedef ref_ptr<filter_type> filter_ptr;
private:
std::string name_;
std::string title_;
std::string abstract_;
double min_scale_;
double max_scale_;
symbolizers syms_;
filter_ptr filter_;
bool else_filter_;
public:
rule()
: name_(),
title_(),
abstract_(),
min_scale_(0),
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(new null_filter<FeatureT>),
else_filter_(false) {}
rule(const std::string& name,const std::string& title)
: name_(name),
title_(title),
abstract_(),
min_scale_(0),
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(new null_filter<FeatureT>),
else_filter_(false) {}
rule(const std::string& name,const std::string& title,
double min_scale_denominator,double max_scale_denominator)
: name_(name),
title_(title),
min_scale_(min_scale_denominator),
max_scale_(max_scale_denominator),
syms_(),
filter_(new null_filter<FeatureT>),
else_filter_(false) {}
rule(const rule& rhs)
: name_(rhs.name_),
title_(rhs.title_),
abstract_(rhs.abstract_),
min_scale_(rhs.min_scale_),
max_scale_(rhs.max_scale_),
syms_(rhs.syms_),
filter_(rhs.filter_),
else_filter_(rhs.else_filter_) {}
rule& operator=(rule const& rhs)
{
rule tmp(rhs);
swap(tmp);
return *this;
}
void set_max_scale(double scale)
{
max_scale_=scale;
}
double get_min_scale() const
{
return min_scale_;
}
double get_max_scale() const
{
return max_scale_;
}
void set_min_scale(double scale)
{
min_scale_=scale;
}
void set_name(std::string const& name)
{
name_=name;
}
const std::string& get_name() const
{
return name_;
}
const std::string& get_title() const
{
return title_;
}
void set_title(std::string const& title)
{
title_=title;
}
void set_abstract(const std::string& abstract)
{
abstract_=abstract;
}
const std::string& get_abstract() const
{
return abstract_;
}
void append(const symbolizer_ptr& symbol)
{
syms_.push_back(symbol);
}
void remove_at(size_t index)
{
if (index < syms_.size())
{
syms_.erase(syms_.begin()+index);
}
}
const symbolizers& get_symbolizers() const
{
return syms_;
}
symbolizers::const_iterator begin()
{
return syms_.begin();
}
symbolizers::const_iterator end()
{
return syms_.end();
}
void set_filter(const filter_ptr& filter)
{
filter_=filter;
}
const filter_ptr& get_filter() const
{
return filter_;
}
void set_else(bool else_filter)
{
else_filter_=else_filter;
}
bool has_else_filter() const
{
return else_filter_;
}
bool active(double scale) const
{
return ( scale > min_scale_ && scale < max_scale_ );
}
private:
void swap(rule& rhs) throw()
{
name_=rhs.name_;
title_=rhs.title_;
abstract_=rhs.abstract_;
min_scale_=rhs.min_scale_;
max_scale_=rhs.max_scale_;
syms_=rhs.syms_;
filter_=rhs.filter_;
else_filter_=rhs.else_filter_;
}
};
}
#endif //RULE_HPP

44
include/scanline.hpp Normal file
View file

@ -0,0 +1,44 @@
/* 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: scanline.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef SCANLINE_HPP
#define SCANLINE_HPP
#include "geometry.hpp"
namespace mapnik
{
template <typename PixBuffer> class ScanlineRasterizer
{
private:
PixBuffer* pixbuf_;
public:
ScanlineRasterizer(PixBuffer& pixbuf)
:pixbuf_(&pixbuf) {}
template <typename Transform>
void render(const geometry_type& geom,const Color& c);
private:
ScanlineRasterizer(const ScanlineRasterizer&);
ScanlineRasterizer& operator=(const ScanlineRasterizer&);
void render_hline(int x0,int x1,int y,unsigned int rgba);
};
}
#endif //SCANLINE_HPP

843
include/scanline_aa.hpp Normal file
View file

@ -0,0 +1,843 @@
/* 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.
*/
// Credits:
// I gratefully acknowledge the inspiring work of Maxim Shemanarev (McSeem),
// author of Anti-Grain Geometry (http://www.antigrain.com), and also the developers
// of the FreeType library (http://www.freetype.org). I have slightly modified the polygon
// rasterizing algorithm to work with my library, but render_line and
// render_hline remain intact.
//$Id: scanline_aa.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef SCANLINE_AA_HPP
#define SCANLINE_AA_HPP
#include "envelope.hpp"
#include "geometry.hpp"
#include "graphics.hpp"
#include "style.hpp"
namespace mapnik
{
enum path_commands_e
{
path_cmd_stop = 0, //----path_cmd_stop
path_cmd_move_to = 1, //----path_cmd_move_to
path_cmd_line_to = 2, //----path_cmd_line_to
path_cmd_curve3 = 3, //----path_cmd_curve3
path_cmd_curve4 = 4, //----path_cmd_curve4
path_cmd_end_poly = 6, //----path_cmd_end_poly
path_cmd_mask = 0x0F //----path_cmd_mask
};
//------------------------------------------------------------path_flags_e
enum path_flags_e
{
path_flags_none = 0, //----path_flags_none
path_flags_ccw = 0x10, //----path_flags_ccw
path_flags_cw = 0x20, //----path_flags_cw
path_flags_close = 0x40, //----path_flags_close
path_flags_mask = 0xF0 //----path_flags_mask
};
inline bool is_vertex(unsigned c)
{
return c >= path_cmd_move_to && c < path_cmd_end_poly;
}
inline bool is_move_to(unsigned c)
{
return c == path_cmd_move_to;
}
inline bool is_close(unsigned c)
{
return (c & ~(path_flags_cw | path_flags_ccw)) ==
(path_cmd_end_poly | path_flags_close);
}
inline unsigned clipping_flags(int x, int y, const Envelope<int>& clip_box)
{
return (x > clip_box.maxx()) |
((y > clip_box.maxy()) << 1) |
((x < clip_box.minx()) << 2) |
((y < clip_box.miny()) << 3);
}
template<class T>
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
const Envelope<T>& clip_box,
T* x, T* y)
{
const double nearzero = 1e-30;
double deltax = x2 - x1;
double deltay = y2 - y1;
double xin;
double xout;
double yin;
double yout;
double tinx;
double tiny;
double toutx;
double touty;
double tin1;
double tin2;
double tout1;
unsigned np = 0;
if(deltax == 0.0)
{
// bump off of the vertical
deltax = (x1 > clip_box.minx()) ? -nearzero : nearzero;
}
if(deltay == 0.0)
{
// bump off of the horizontal
deltay = (y1 > clip_box.miny()) ? -nearzero : nearzero;
}
if(deltax > 0.0)
{
// points to right
xin = clip_box.minx();
xout = clip_box.maxx();
}
else
{
xin = clip_box.maxx();
xout = clip_box.minx();
}
if(deltay > 0.0)
{
// points up
yin = clip_box.miny();
yout = clip_box.maxy();
}
else
{
yin = clip_box.maxy();
yout = clip_box.miny();
}
tinx = (xin - x1) / deltax;
tiny = (yin - y1) / deltay;
if (tinx < tiny)
{
// hits x first
tin1 = tinx;
tin2 = tiny;
}
else
{
// hits y first
tin1 = tiny;
tin2 = tinx;
}
if(tin1 <= 1.0)
{
if(0.0 < tin1)
{
*x++ = (T)xin;
*y++ = (T)yin;
++np;
}
if(tin2 <= 1.0)
{
toutx = (xout - x1) / deltax;
touty = (yout - y1) / deltay;
tout1 = (toutx < touty) ? toutx : touty;
if(tin2 > 0.0 || tout1 > 0.0)
{
if(tin2 <= tout1)
{
if(tin2 > 0.0)
{
if(tinx > tiny)
{
*x++ = (T)xin;
*y++ = (T)(y1 + tinx * deltay);
}
else
{
*x++ = (T)(x1 + tiny * deltax);
*y++ = (T)yin;
}
++np;
}
if(tout1 < 1.0)
{
if(toutx < touty)
{
*x++ = (T)xout;
*y++ = (T)(y1 + toutx * deltay);
}
else
{
*x++ = (T)(x1 + touty * deltax);
*y++ = (T)yout;
}
}
else
{
*x++ = x2;
*y++ = y2;
}
++np;
}
else
{
if(tinx > tiny)
{
*x++ = (T)xin;
*y++ = (T)yout;
}
else
{
*x++ = (T)xout;
*y++ = (T)yin;
}
++np;
}
}
}
}
return np;
}
enum
{
poly_base_shift = 8,
poly_base_size = 1 << poly_base_shift,
poly_base_mask = poly_base_size - 1
};
inline int poly_coord(double c)
{
return int(c * poly_base_size);
}
struct cell_aa
{
short x;
short y;
int packed_coord;
int cover;
int area;
void set(int x, int y, int c, int a);
void set_coord(int x, int y);
void set_cover(int c, int a);
void add_cover(int c, int a);
};
class outline_aa
{
enum {
cell_block_shift = 12,
cell_block_size = 1 << cell_block_shift,
cell_block_mask = cell_block_size - 1,
cell_block_pool = 256,
cell_block_limit = 1024
};
public:
~outline_aa();
outline_aa();
void reset();
void move_to(int x, int y);
void line_to(int x, int y);
int min_x() const { return m_min_x; }
int min_y() const { return m_min_y; }
int max_x() const { return m_max_x; }
int max_y() const { return m_max_y; }
const cell_aa* const* cells();
unsigned num_cells() { cells(); return m_num_cells; }
bool sorted() const { return m_sorted; }
private:
outline_aa(const outline_aa&);
const outline_aa& operator = (const outline_aa&);
void set_cur_cell(int x, int y);
void add_cur_cell();
void sort_cells();
void render_hline(int ey, int x1, int y1, int x2, int y2);
void render_line(int x1, int y1, int x2, int y2);
void allocate_block();
static void qsort_cells(cell_aa** start, unsigned num);
private:
unsigned m_num_blocks;
unsigned m_max_blocks;
unsigned m_cur_block;
unsigned m_num_cells;
cell_aa** m_cells;
cell_aa* m_cur_cell_ptr;
cell_aa** m_sorted_cells;
unsigned m_sorted_size;
cell_aa m_cur_cell;
int m_cur_x;
int m_cur_y;
int m_min_x;
int m_min_y;
int m_max_x;
int m_max_y;
bool m_sorted;
};
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
};
template <typename PixBuffer> class ScanlineRasterizerAA
{
enum status
{
status_initial,
status_line_to,
status_closed
};
struct iterator
{
const cell_aa* const* cells;
int cover;
int last_y;
};
enum
{
aa_shift = 8,
aa_num = 1 << aa_shift,
aa_mask = aa_num - 1,
aa_2num = aa_num * 2,
aa_2mask = aa_2num - 1
};
private:
PixBuffer* pixbuf_;
outline_aa m_outline;
int m_gamma[aa_num];
filling_rule_e m_filling_rule;
int m_clipped_start_x;
int m_clipped_start_y;
int m_start_x;
int m_start_y;
int m_prev_x;
int m_prev_y;
unsigned m_prev_flags;
unsigned m_status;
Envelope<int> m_clip_box;
bool m_clipping;
iterator m_iterator;
public:
ScanlineRasterizerAA(PixBuffer& pixbuf)
:pixbuf_(&pixbuf),
m_filling_rule(fill_non_zero),
m_clipped_start_x(0),
m_clipped_start_y(0),
m_start_x(0),
m_start_y(0),
m_prev_x(0),
m_prev_y(0),
m_prev_flags(0),
m_status(status_initial),
m_clipping(false)
{
for(int i = 0; i < aa_num; i++) m_gamma[i] = i;
}
template <typename Transform>
void render(const geometry_type& geom,const Color& c);
private:
ScanlineRasterizerAA(const ScanlineRasterizerAA&);
ScanlineRasterizerAA& operator=(const ScanlineRasterizerAA&);
void render_hline(int x0,int x1,int y,unsigned rgba);
void blend_hline(int x0,int x1,int y,const unsigned char* cover,
unsigned rgba);
int min_x() const { return m_outline.min_x(); }
int min_y() const { return m_outline.min_y(); }
int max_x() const { return m_outline.max_x(); }
int max_y() const { return m_outline.max_y(); }
void reset();
void filling_rule(filling_rule_e filling_rule);
void clip_box(double x1, double y1, double x2, double y2);
void reset_clipping();
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
for(i = 0; i < aa_num; i++)
{
m_gamma[i] = int(floor(gamma_function(double(i) / aa_mask) * aa_mask + 0.5));
}
}
unsigned apply_gamma(unsigned cover) const
{
return m_gamma[cover];
}
void add_vertex(double x, double y, unsigned cmd);
void move_to(int x, int y);
void line_to(int x, int y);
void close_polygon();
void move_to_no_clip(int x, int y);
void line_to_no_clip(int x, int y);
void close_polygon_no_clip();
void clip_segment(int x, int y);
unsigned calculate_alpha(int area) const
{
int cover = area >> (poly_base_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_2mask;
if(cover > aa_num)
{
cover = aa_2num - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return m_gamma[cover];
}
void sort()
{
m_outline.cells();
}
bool rewind_scanlines()
{
close_polygon();
m_iterator.cells = m_outline.cells();
if(m_outline.num_cells() == 0)
{
return false;
}
m_iterator.cover = 0;
m_iterator.last_y = (*m_iterator.cells)->y;
return true;
}
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
sl.reset_spans();
for(;;)
{
const cell_aa* cur_cell = *m_iterator.cells;
if(cur_cell == 0) return false;
++m_iterator.cells;
m_iterator.last_y = cur_cell->y;
for(;;)
{
int coord = cur_cell->packed_coord;
int area = cur_cell->area;
int last_x = cur_cell->x;
m_iterator.cover += cur_cell->cover;
//accumulate all cells with the same coordinates
for(; (cur_cell = *m_iterator.cells) != 0; ++m_iterator.cells)
{
if(cur_cell->packed_coord != coord) break;
area += cur_cell->area;
m_iterator.cover += cur_cell->cover;
}
int alpha;
if(cur_cell == 0 || cur_cell->y != m_iterator.last_y)
{
if(area)
{
alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
if(alpha)
{
sl.add_cell(last_x, alpha);
}
++last_x;
}
break;
}
++m_iterator.cells;
if(area)
{
alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
if(alpha)
{
sl.add_cell(last_x, alpha);
}
++last_x;
}
if(cur_cell->x > last_x)
{
alpha = calculate_alpha(m_iterator.cover << (poly_base_shift + 1));
if(alpha)
{
sl.add_span(last_x, cur_cell->x - last_x, alpha);
}
}
}
if(sl.num_spans())
{
sl.finalize(m_iterator.last_y);
break;
}
}
return true;
}
};
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::reset()
{
m_outline.reset();
m_status = status_initial;
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::clip_box(double x1, double y1, double x2, double y2)
{
//reset();
m_clip_box = Envelope<int>(poly_coord(x1), poly_coord(y1),
poly_coord(x2), poly_coord(y2));
//m_clip_box.normalize();
m_clipping = true;
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::move_to_no_clip(int x, int y)
{
if(m_status == status_line_to)
{
close_polygon_no_clip();
}
m_outline.move_to(x,y);
m_clipped_start_x = x;
m_clipped_start_y = y;
m_status = status_line_to;
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::line_to_no_clip(int x, int y)
{
if(m_status != status_initial)
{
m_outline.line_to(x , y);
m_status = status_line_to;
}
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::close_polygon_no_clip()
{
if(m_status == status_line_to)
{
m_outline.line_to(m_clipped_start_x, m_clipped_start_y);
m_status = status_closed;
}
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::clip_segment(int x, int y)
{
unsigned flags = clipping_flags(x, y, m_clip_box);
if(m_prev_flags == flags)
{
if(flags == 0)
{
if(m_status == status_initial)
{
move_to_no_clip(x, y);
}
else
{
line_to_no_clip(x, y);
}
}
}
else
{
int cx[4];
int cy[4];
unsigned n = clip_liang_barsky<int>(m_prev_x, m_prev_y,
x, y,
m_clip_box,
cx, cy);
const int* px = cx;
const int* py = cy;
while(n--)
{
if(m_status == status_initial)
{
move_to_no_clip(*px++, *py++);
}
else
{
line_to_no_clip(*px++, *py++);
}
}
}
m_prev_flags = flags;
m_prev_x = x;
m_prev_y = y;
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::add_vertex(double x, double y, unsigned cmd)
{
if(is_close(cmd))
{
close_polygon();
}
else
{
if(is_move_to(cmd))
{
move_to(poly_coord(x), poly_coord(y));
}
else
{
if(is_vertex(cmd))
{
line_to(poly_coord(x), poly_coord(y));
}
}
}
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::move_to(int x, int y)
{
if(m_clipping)
{
if(m_outline.sorted())
{
reset();
}
if(m_status == status_line_to)
{
close_polygon();
}
m_prev_x = m_start_x = x;
m_prev_y = m_start_y = y;
m_status = status_initial;
m_prev_flags = clipping_flags(x, y, m_clip_box);
if(m_prev_flags == 0)
{
move_to_no_clip(x, y);
}
}
else
{
move_to_no_clip(x, y);
}
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::line_to(int x, int y)
{
if(m_clipping)
{
clip_segment(x, y);
}
else
{
line_to_no_clip(x, y);
}
}
template<typename PixBuffer>
void ScanlineRasterizerAA<PixBuffer>::close_polygon()
{
if(m_clipping)
{
clip_segment(m_start_x, m_start_y);
}
close_polygon_no_clip();
}
template<class T> class scanline_u
{
public:
typedef T cover_type;
struct span
{
short x;
short len;
cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
~scanline_u();
scanline_u();
void reset(int min_x, int max_x);
void add_cell(int x, unsigned cover);
void add_cells(int x, unsigned len, const T* covers);
void add_span(int x, unsigned len, unsigned cover);
void finalize(int y) { m_y = y; }
void reset_spans();
int y() const { return m_y; }
unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
const_iterator begin() const { return m_spans + 1; }
iterator begin() { return m_spans + 1; }
private:
scanline_u<T>(const scanline_u<T>&);
const scanline_u<T>& operator = (const scanline_u<T>&);
private:
int m_min_x;
unsigned m_max_len;
int m_last_x;
int m_y;
cover_type* m_covers;
span* m_spans;
span* m_cur_span;
};
template<class T> scanline_u<T>::~scanline_u()
{
delete [] m_spans;
delete [] m_covers;
}
template<class T> scanline_u<T>::scanline_u() :
m_min_x(0),
m_max_len(0),
m_last_x(0x7FFFFFF0),
m_covers(0),
m_spans(0),
m_cur_span(0)
{
}
template<class T> void scanline_u<T>::reset(int min_x, int max_x)
{
unsigned max_len = max_x - min_x + 2;
if(max_len > m_max_len)
{
delete [] m_spans;
delete [] m_covers;
m_covers = new cover_type [max_len];
m_spans = new span [max_len];
m_max_len = max_len;
}
m_last_x = 0x7FFFFFF0;
m_min_x = min_x;
m_cur_span = m_spans;
}
template<class T> inline void scanline_u<T>::reset_spans()
{
m_last_x = 0x7FFFFFF0;
m_cur_span = m_spans;
}
template<class T> inline void scanline_u<T>::add_cell(int x, unsigned cover)
{
x -= m_min_x;
m_covers[x] = (unsigned char)cover;
if(x == m_last_x+1)
{
m_cur_span->len++;
}
else
{
m_cur_span++;
m_cur_span->x = (short)(x + m_min_x);
m_cur_span->len = 1;
m_cur_span->covers = m_covers + x;
}
m_last_x = x;
}
template<class T> void scanline_u<T>::add_cells(int x, unsigned len, const T* covers)
{
x -= m_min_x;
memcpy(m_covers + x, covers, len * sizeof(T));
if(x == m_last_x+1)
{
m_cur_span->len += (short)len;
}
else
{
m_cur_span++;
m_cur_span->x = (short)(x + m_min_x);
m_cur_span->len = (short)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
template<class T> void scanline_u<T>::add_span(int x, unsigned len, unsigned cover)
{
x -= m_min_x;
memset(m_covers + x, cover, len);
if(x == m_last_x+1)
{
m_cur_span->len += (short)len;
}
else
{
m_cur_span++;
m_cur_span->x = (short)(x + m_min_x);
m_cur_span->len = (short)len;
m_cur_span->covers = m_covers + x;
}
m_last_x = x + len - 1;
}
typedef scanline_u<unsigned char> scanline_u8;
typedef scanline_u<unsigned short> scanline_u16;
typedef scanline_u<unsigned int> scanline_u32;
}
#endif //SCANLINE_AA_HPP

151
include/spatial.hpp Normal file
View file

@ -0,0 +1,151 @@
/* 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 SPATIAL_HPP
#define SPATIAL_HPP
#include "filter.hpp"
#include "filter_visitor.hpp"
namespace mapnik
{
template <typename FeatureT>
struct equals_ : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct disjoint : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct touches : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct within : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct overlaps : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct crosses : public filter<FeatureT>
{
bool pass(const FeatureT& feature) const
{
return false;
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
};
template <typename FeatureT>
struct bbox : public filter<FeatureT>
{
private:
Envelope<double> box_;
public:
bbox(const Envelope<double>& box)
: box_(box) {}
bool pass(const FeatureT& feature) const
{
return box_.contains(feature.get_geometry()->bbox());
}
filter<FeatureT>* clone() const
{
return new bbox<FeatureT>(box_);
}
void accept(const filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
virtual ~bbox() {}
};
}
#endif //SPATIAL_HPP

166
include/stroke.hpp Normal file
View file

@ -0,0 +1,166 @@
/* 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 STROKE_HPP
#define STROKE_HPP
#include "color.hpp"
#include <vector>
namespace mapnik
{
using std::pair;
using std::vector;
typedef vector<pair<float,float> > dash_array;
enum line_cap_e
{
BUTT_CAP,
SQUARE_CAP,
ROUND_CAP
};
enum line_join_e
{
MITER_JOIN,
MITER_REVERT_JOIN,
ROUND_JOIN,
BEVEL_JOIN
};
class stroke
{
Color c_;
float width_;
float opacity_; // 0.0 - 1.0
line_cap_e line_cap_;
line_join_e line_join_;
dash_array dash_;
public:
stroke()
: c_(),
width_(1.0),
opacity_(1.0),
line_cap_(BUTT_CAP),
line_join_(MITER_JOIN),
dash_() {}
stroke(Color const& c, float width=1.0)
: c_(c),
width_(width),
opacity_(1.0),
line_cap_(BUTT_CAP),
line_join_(MITER_JOIN),
dash_() {}
stroke(stroke const& other)
: c_(other.c_),
width_(other.width_),
opacity_(other.opacity_),
line_cap_(other.line_cap_),
line_join_(other.line_join_),
dash_(other.dash_) {}
stroke& operator=(const stroke& rhs)
{
stroke tmp(rhs);
swap(tmp);
return *this;
}
void set_color(const Color& c)
{
c_=c;
}
Color const& get_color() const
{
return c_;
}
float get_width() const
{
return width_;
}
void set_width(float w)
{
width_=w;
}
void set_opacity(float opacity)
{
if (opacity > 1.0) opacity_=1.0;
else if (opacity < 0.0) opacity_=0.0;
else opacity_=opacity;
}
float get_opacity() const
{
return opacity_;
}
void set_line_cap(line_cap_e line_cap)
{
line_cap_=line_cap;
}
line_cap_e get_line_cap() const
{
return line_cap_;
}
void set_line_join(line_join_e line_join)
{
line_join_=line_join;
}
line_join_e get_line_join() const
{
return line_join_;
}
void add_dash(float dash,float gap)
{
dash_.push_back(std::make_pair(dash,gap));
}
bool has_dash() const
{
return dash_.size();
}
dash_array const& get_dash_array() const
{
return dash_;
}
private:
void swap(const stroke& other) throw()
{
c_=other.c_;
width_=other.width_;
opacity_=other.opacity_;
line_cap_=other.line_cap_;
line_join_=other.line_join_;
dash_ = other.dash_;
}
};
}
#endif //STROKE_HPP

80
include/style.hpp Normal file
View file

@ -0,0 +1,80 @@
/* 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: style.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef STYLE_HPP
#define STYLE_HPP
//#include "feature.hpp"
#include "color.hpp"
#include "ptr.hpp"
#include "symbolizer.hpp"
//#include "rule.hpp"
#include <vector>
#include <algorithm>
#include <functional>
namespace mapnik
{
class Style
{
private:
std::vector<ref_ptr<symbolizer> > symbols_;
static ref_ptr<symbolizer> zero_symbol_;
public:
typedef std::vector<ref_ptr<symbolizer> >::const_iterator Iterator;
Style() {}
Style(const ref_ptr<symbolizer>& symbol)
{
symbols_.push_back(symbol);
}
~Style() {}
Style(const Style& rhs)
: symbols_(rhs.symbols_) {}
Style& operator=(const Style& rhs)
{
if (this==&rhs) return *this;
symbols_=rhs.symbols_;
return *this;
}
void add(const ref_ptr<symbolizer>& symbol)
{
symbols_.push_back(symbol);
}
Iterator begin() const
{
return symbols_.begin();
}
Iterator end() const
{
return symbols_.end();
}
};
}
#endif //STYLE_HPP

64
include/style_cache.hpp Normal file
View file

@ -0,0 +1,64 @@
/* 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: style_cache.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef STYLE_CACHE_HPP
#define STYLE_CACHE_HPP
#include "utils.hpp"
#include "ptr.hpp"
#include "style.hpp"
#include <map>
#include "feature_type_style.hpp"
namespace mapnik {
class style_cache : public singleton <style_cache,CreateStatic>
{
friend class CreateStatic<style_cache>;
private:
static std::map<std::string,Style > styles_;
style_cache();
~style_cache();
style_cache(const style_cache&);
style_cache& operator=(const style_cache&);
public:
static bool insert(const std::string& name,const Style& style);
static void remove(const std::string& name);
static const Style& find(const std::string& name);
};
class named_style_cache : public singleton <named_style_cache,CreateStatic>
{
friend class CreateStatic<named_style_cache>;
private:
static std::map<std::string,feature_type_style> styles_;
named_style_cache();
~named_style_cache();
named_style_cache(const named_style_cache&);
named_style_cache& operator=(const named_style_cache&);
public:
static bool insert(const std::string& name,const feature_type_style& style);
static void remove(const std::string& name);
static feature_type_style find(const std::string& name);
};
}
#endif //STYLE_CACHE_HPP

34
include/style_factory.hpp Normal file
View file

@ -0,0 +1,34 @@
/* 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: style_factory.hpp 39 2005-04-10 20:39:53Z pavlenko $
#ifndef STYLE_FACTORY_HPP
#define STYLE_FACTORY_HPP
#include "style.hpp"
namespace mapnik {
class style_factory
{
};
}
#endif //STYLE_FACTORY_HPP

Some files were not shown because too many files have changed in this diff Show more