Compare commits
76 commits
Author | SHA1 | Date | |
---|---|---|---|
|
025b04fe2b | ||
|
4acda0a752 | ||
|
7cf334852d | ||
|
e61644b930 | ||
|
fd27717253 | ||
|
1aa28fb966 | ||
|
ca43cc3f40 | ||
|
170e23440f | ||
|
ed734df467 | ||
|
3b831a485d | ||
|
adb2ec7414 | ||
|
7e36b13dce | ||
|
daeecb39e0 | ||
|
fa23cda22f | ||
|
cc3cd5f63f | ||
|
9b251e16f7 | ||
|
8dea5a5fe2 | ||
|
718d3a4e66 | ||
|
49483fa2dd | ||
|
d139e491c2 | ||
|
f878989b2e | ||
|
6a6a48bc6c | ||
|
7a7ab494f4 | ||
|
dc813167c7 | ||
|
ff271853ce | ||
|
57a3836c50 | ||
|
3b44a88c44 | ||
|
47e5b3c95e | ||
|
51bf0ef2a5 | ||
|
c8848c8a9b | ||
|
2b5ad5bd7e | ||
|
92dd30556a | ||
|
7fe677dd41 | ||
|
19b51fd43b | ||
|
c1ed1da9e2 | ||
|
0370913bfc | ||
|
56d8f7a3f9 | ||
|
57347e9106 | ||
|
5cd3cb2efd | ||
|
862bd54799 | ||
|
1f49c52be4 | ||
|
bd8446d875 | ||
|
af6cd78ab9 | ||
|
b93c760b33 | ||
|
c9a610df92 | ||
|
50abe356d8 | ||
|
0be7d66549 | ||
|
19f43c9d2f | ||
|
49f0df0f7f | ||
|
896bcbd211 | ||
|
a6891f2459 | ||
|
e66d724841 | ||
|
cacc90962c | ||
|
91ad01b11b | ||
|
8229b22ed7 | ||
|
1912362b46 | ||
|
9ddef6463f | ||
|
e7f62675a9 | ||
|
34ddc65e30 | ||
|
7a10befa11 | ||
|
4292cf1687 | ||
|
b0c6378eb8 | ||
|
21af038fd3 | ||
|
3a086b8dfc | ||
|
150c9f819a | ||
|
90fccfe710 | ||
|
ee8a150e38 | ||
|
53e171c1f1 | ||
|
01d6567007 | ||
|
496b393623 | ||
|
babe1b6fd0 | ||
|
58c29c052b | ||
|
c4edd2bd59 | ||
|
5c76218070 | ||
|
7eef4af143 | ||
|
86a1d9626b |
115 changed files with 1818 additions and 2769 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,7 +4,10 @@
|
|||
*.so
|
||||
*.a
|
||||
*.dylib
|
||||
*.cpp~
|
||||
*.hpp~
|
||||
plugins/input/*.input
|
||||
plugins/input/templates/hello.input
|
||||
demo/c++/rundemo
|
||||
bindings/python/mapnik/paths.py
|
||||
config.cache
|
||||
|
|
68
CHANGELOG
68
CHANGELOG
|
@ -10,12 +10,76 @@ Developers: Please commit along with changes.
|
|||
|
||||
For a complete change history, see the SVN log.
|
||||
|
||||
Future
|
||||
|
||||
Mapnik 2.1.0
|
||||
- Fixed linking to recent boost versions
|
||||
|
||||
- Added support for literal types in PostGIS Plugin (#1464)
|
||||
|
||||
Mapnik 2.0.2
|
||||
------------
|
||||
|
||||
Released Aug 3, 2012
|
||||
|
||||
(Packaged from adb2ec741)
|
||||
|
||||
- Fixed handling of empty WKB geometries (#1334)
|
||||
|
||||
- Fixed naming of `stroke-dashoffset` in save_map (cc3cd5f63f28)
|
||||
|
||||
- Fixed support for boost 1.50 (8dea5a5fe239233)
|
||||
|
||||
- Fixed TextSymbolizer placement in Cairo backend so it respects avoid-edges and minimum-padding across all renderers (#1242)
|
||||
|
||||
- Fixed ShieldSymbolizer placement so it respects avoid-edges and minimum-padding across all renderers (#1242)
|
||||
|
||||
- Rolled back change made in 2.0.1 to marker width/height meaning that Mapnik > 2.0.2 will stick to assuming width/heigh are radii for back compatibility with 2.0.0. The reverted change is seen below as "Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentionally radii)". Issue tracking this is #1163
|
||||
|
||||
- XML: Fixed to avoid throwing if a `<Parameters>` element is encountered (which is supported in >= 2.1.x)
|
||||
|
||||
- Support for PostGIS 2.0 in the pgsql2sqlite command (e69c44e/47e5b3c)
|
||||
|
||||
- Fixed reference counting of Py_None when returning null attributes from Postgres during UTFGrid encoding, which could cause a Fatal Python error: deallocating None (#1221)
|
||||
|
||||
- Fixed possible breakage registering plugins via python if a custom PREFIX or DESTDIR was used (e.g. macports/homebrew) (#1171)
|
||||
|
||||
- Fixed memory leak in the case of proj >= 4.8 and a projection initialization error (#1173)
|
||||
|
||||
|
||||
Mapnik 2.0.1
|
||||
------------
|
||||
|
||||
(Packaged from 5cd3cb2efdaf7e9990a57e8e00b652a81aaa39ae)
|
||||
|
||||
- Support for PostGIS 2.0 (#956,#1083)
|
||||
|
||||
- Switched back to "libmapnik" and "import mapnik" rather than "mapnik2" (mapnik2 will still work from python) (#941)
|
||||
|
||||
- Restored Python 2.5 compatibility (#904)
|
||||
|
||||
- Fixed `mapnik-config --version` (#903)
|
||||
|
||||
- Cairo: Add full rendering support for markers to match AGG renderer functionality (#1071)
|
||||
|
||||
- Fix Markers rendering so that ellipse height/width units are pixels (previously were unintentionally radii) (#1134)
|
||||
|
||||
- Added 'ignore-placement` attribute to markers-symbolizer (#1135)
|
||||
|
||||
- Removed svn_revision info from mapnik-config and python bindings as git is now used
|
||||
|
||||
- Removed OGCServer from core - now at https://github.com/mapnik/OGCServer (e7f6267)
|
||||
|
||||
- Fixed SQLite open stability across platforms/versions (#854)
|
||||
|
||||
- Workaround for boost interprocess compile error with recent gcc versions (#950,#1001,#1082)
|
||||
|
||||
- Fix possible memory corruption when using hextree mode for png color reduction (#1087)
|
||||
|
||||
- Fixed bug in shield line placement when dx/dy are used to shift the label relative to the placement point (Matt Amos) (#908)
|
||||
|
||||
- Fix to avoid modifying a feature if an attribute is requested that does not exist (0f5ab18ed)
|
||||
|
||||
- Fixed ability to save to jpeg format from python (7387afd9) (#896)
|
||||
|
||||
|
||||
Mapnik 2.0.0
|
||||
|
@ -225,8 +289,6 @@ Mapnik 0.7.0 Release
|
|||
|
||||
- Python: Fixed potential crash if pycairo support is enabled but python-cairo module is missing (#392)
|
||||
|
||||
- Python: Added 'mapnik.mapnik_svn_revision()' function to svn revision of Mapnik was compiled at.
|
||||
|
||||
- Python: Added 'mapnik.has_pycairo()' function to test for pycairo support (r1278) (#284)
|
||||
|
||||
- Python: Added 'mapnik.register_plugins()' and 'mapnik.register_fonts()' functions (r1256)
|
||||
|
|
100
SConstruct
100
SConstruct
|
@ -16,7 +16,6 @@
|
|||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
|
||||
import os
|
||||
|
@ -53,17 +52,17 @@ DEFAULT_LINK_PRIORITY = ['internal','other','frameworks','user','system']
|
|||
|
||||
|
||||
pretty_dep_names = {
|
||||
'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: http://trac.mapnik.org/wiki/OCCI',
|
||||
'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: http://trac.mapnik.org/wiki/GDAL',
|
||||
'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: http://trac.mapnik.org/wiki/OGR',
|
||||
'geos_c':'GEOS Simple Geometry Specification C Library | configured with GEOS_LIB & GEOS_INCLUDE | more info: http://trac.mapnik.org/wiki/GEOS',
|
||||
'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/OCCI',
|
||||
'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/GDAL',
|
||||
'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/OGR',
|
||||
'geos_c':'GEOS Simple Geometry Specification C Library | configured with GEOS_LIB & GEOS_INCLUDE | more info: https://github.com/mapnik/mapnik/wiki/GEOS',
|
||||
'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
|
||||
'cairomm':'Cairomm C++ bindings to Cairo library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
|
||||
'cairomm-version':'Cairomm version is too old (so cairo renderer will not be built), you need at least %s' % CAIROMM_MIN_VERSION,
|
||||
'pycairo':'Python bindings to Cairo library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option',
|
||||
'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/',
|
||||
'pg':'Postgres C Library requiered for PostGIS plugin | configure with pg_config program | more info: http://trac.mapnik.org/wiki/PostGIS',
|
||||
'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: http://trac.mapnik.org/wiki/SQLite',
|
||||
'pg':'Postgres C Library requiered for PostGIS plugin | configure with pg_config program | more info: https://github.com/mapnik/mapnik/wiki/PostGIS',
|
||||
'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite',
|
||||
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
|
||||
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
|
||||
'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES',
|
||||
|
@ -77,8 +76,8 @@ pretty_dep_names = {
|
|||
'gdal-config':'gdal-config program | try setting GDAL_CONFIG SCons option',
|
||||
'geos-config':'geos-config program | try setting GEOS_CONFIG SCons option',
|
||||
'freetype-config':'freetype-config program | try setting FREETYPE_CONFIG SCons option',
|
||||
'osm':'more info: http://trac.mapnik.org/wiki/OsmPlugin',
|
||||
'curl':'libcurl is required for the "osm" plugin - more info: http://trac.mapnik.org/wiki/OsmPlugin',
|
||||
'osm':'more info: https://github.com/mapnik/mapnik/wiki/OsmPlugin',
|
||||
'curl':'libcurl is required for the "osm" plugin - more info: https://github.com/mapnik/mapnik/wiki/OsmPlugin',
|
||||
'boost_regex_icu':'libboost_regex built with optional ICU unicode support is needed for unicode regex support in mapnik.',
|
||||
'sqlite_rtree':'The SQLite plugin requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)',
|
||||
'pgsql2sqlite_rtree':'The pgsql2sqlite program requires libsqlite3 built with RTREE support (-DSQLITE_ENABLE_RTREE=1)'
|
||||
|
@ -102,7 +101,6 @@ PLUGINS = { # plugins with external dependencies
|
|||
|
||||
# plugins without external dependencies requiring CheckLibWithHeader...
|
||||
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||
'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||
'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||
'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||
}
|
||||
|
@ -278,7 +276,7 @@ def pretty_dep(dep):
|
|||
if pretty:
|
||||
return '%s (%s)' % (dep,pretty)
|
||||
elif 'boost' in dep:
|
||||
return '%s (%s)' % (dep,'more info see: http://trac.mapnik.org/wiki/MapnikInstallation & http://www.boost.org')
|
||||
return '%s (%s)' % (dep,'more info see: https://github.com/mapnik/mapnik/wiki/MapnikInstallation & http://www.boost.org')
|
||||
return dep
|
||||
|
||||
|
||||
|
@ -329,7 +327,7 @@ opts.AddVariables(
|
|||
('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False),
|
||||
('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False),
|
||||
('BOOST_VERSION','Specify boost version, e.g., 1_35.','',False),
|
||||
('BOOST_PYTHON_LIB','Specify library name or full path to boost_python lib (e.g. "boost_python-py26" or "/usr/lib/libboost_python.dylib")',''),
|
||||
('BOOST_PYTHON_LIB','Specify library name to specific Boost Python lib (e.g. "boost_python-py26")',''),
|
||||
|
||||
# Variables for required dependencies
|
||||
('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'),
|
||||
|
@ -375,7 +373,7 @@ opts.AddVariables(
|
|||
# Other variables
|
||||
BoolVariable('SHAPE_MEMORY_MAPPED_FILE', 'Utilize memory-mapped files in Shapefile Plugin (higher memory usage, better performance)', 'True'),
|
||||
('SYSTEM_FONTS','Provide location for python bindings to register fonts (if given aborts installation of bundled DejaVu fonts)',''),
|
||||
('LIB_DIR_NAME','Name to use for the subfolder beside libmapnik where fonts and plugins are installed','mapnik2'),
|
||||
('LIB_DIR_NAME','Name to use for the subfolder beside libmapnik where fonts and plugins are installed','mapnik'),
|
||||
PathVariable('PYTHON','Full path to Python executable used to build bindings', sys.executable),
|
||||
BoolVariable('FRAMEWORK_PYTHON', 'Link against Framework Python on Mac OS X', 'True'),
|
||||
BoolVariable('PYTHON_DYNAMIC_LOOKUP', 'On OSX, do not directly link python lib, but rather dynamically lookup symbols', 'True'),
|
||||
|
@ -426,7 +424,6 @@ pickle_store = [# Scons internal variables
|
|||
'PYTHON_SYS_PREFIX',
|
||||
'COLOR_PRINT',
|
||||
'HAS_BOOST_SYSTEM',
|
||||
'SVN_REVISION',
|
||||
'HAS_CAIRO',
|
||||
'HAS_PYCAIRO',
|
||||
'HAS_LIBXML2',
|
||||
|
@ -451,6 +448,7 @@ pickle_store = [# Scons internal variables
|
|||
'CAIROMM_LIBPATHS',
|
||||
'CAIROMM_LINKFLAGS',
|
||||
'CAIROMM_CPPPATHS',
|
||||
'BOOST_LIB_VERSION_FROM_HEADER'
|
||||
]
|
||||
|
||||
# Add all other user configurable options to pickle pickle_store
|
||||
|
@ -525,11 +523,6 @@ if sys.platform == "win32":
|
|||
|
||||
color_print(4,'\nWelcome to Mapnik...\n')
|
||||
|
||||
color_print(1,'*'*45)
|
||||
color_print(1,'You are compiling Mapnik trunk (aka Mapnik2)')
|
||||
color_print(1,'See important details at:\nhttp://trac.mapnik.org/wiki/Mapnik2')
|
||||
color_print(1,('*'*45)+'\n')
|
||||
|
||||
|
||||
#### Custom Configure Checks ###
|
||||
|
||||
|
@ -799,7 +792,7 @@ def GetMapnikLibVersion(context):
|
|||
|
||||
int main()
|
||||
{
|
||||
std::cout << MAPNIK_VERSION << std::endl;
|
||||
std::cout << MAPNIK_VERSION_STRING << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -809,11 +802,7 @@ int main()
|
|||
context.Result(ret[0])
|
||||
if not ret[1]:
|
||||
return []
|
||||
version = int(ret[1].strip())
|
||||
patch_level = version % 100
|
||||
minor_version = version / 100 % 1000
|
||||
major_version = version / 100000
|
||||
return [major_version,minor_version,patch_level]
|
||||
return ret[1].strip()
|
||||
|
||||
def icu_at_least_four_two(context):
|
||||
ret = context.TryRun("""
|
||||
|
@ -845,6 +834,9 @@ int main()
|
|||
return False
|
||||
|
||||
def boost_regex_has_icu(context):
|
||||
if env['RUNTIME_LINK'] == 'static':
|
||||
context.env.Append(LIBS='icui18n')
|
||||
context.env.Append(LIBS='icudata')
|
||||
ret = context.TryRun("""
|
||||
|
||||
#include <boost/regex/icu.hpp>
|
||||
|
@ -969,7 +961,6 @@ if not preconfigured:
|
|||
env['CAIROMM_CPPPATHS'] = []
|
||||
env['HAS_PYCAIRO'] = False
|
||||
env['HAS_LIBXML2'] = False
|
||||
env['SVN_REVISION'] = None
|
||||
env['LIBMAPNIK_LIBS'] = []
|
||||
env['LIBMAPNIK_CPPATHS'] = []
|
||||
env['LIBMAPNIK_CXXFLAGS'] = []
|
||||
|
@ -1010,9 +1001,9 @@ if not preconfigured:
|
|||
env['MAPNIK_FONTS_DEST'] = os.path.join(env['MAPNIK_LIB_DIR_DEST'],'fonts')
|
||||
|
||||
if env['LINKING'] == 'static':
|
||||
env['MAPNIK_LIB_NAME'] = '${LIBPREFIX}mapnik2${LIBSUFFIX}'
|
||||
env['MAPNIK_LIB_NAME'] = '${LIBPREFIX}mapnik${LIBSUFFIX}'
|
||||
else:
|
||||
env['MAPNIK_LIB_NAME'] = '${SHLIBPREFIX}mapnik2${SHLIBSUFFIX}'
|
||||
env['MAPNIK_LIB_NAME'] = '${SHLIBPREFIX}mapnik${SHLIBSUFFIX}'
|
||||
|
||||
if env['PKG_CONFIG_PATH']:
|
||||
env['ENV']['PKG_CONFIG_PATH'] = os.path.realpath(env['PKG_CONFIG_PATH'])
|
||||
|
@ -1111,14 +1102,14 @@ if not preconfigured:
|
|||
if env['PRIORITIZE_LINKING']:
|
||||
conf.prioritize_paths(silent=False)
|
||||
|
||||
for libinfo in LIBSHEADERS:
|
||||
if not conf.CheckLibWithHeader(libinfo[0], libinfo[1], libinfo[3]):
|
||||
if libinfo[2]:
|
||||
color_print(1,'Could not find required header or shared library for %s' % libinfo[0])
|
||||
env['MISSING_DEPS'].append(libinfo[0])
|
||||
for libname, headers, required, lang in LIBSHEADERS:
|
||||
if not conf.CheckLibWithHeader(libname, headers, lang):
|
||||
if required:
|
||||
color_print(1, 'Could not find required header or shared library for %s' % libname)
|
||||
env['MISSING_DEPS'].append(libname)
|
||||
else:
|
||||
color_print(4,'Could not find optional header or shared library for %s' % libinfo[0])
|
||||
env['SKIPPED_DEPS'].append(libinfo[0])
|
||||
color_print(4, 'Could not find optional header or shared library for %s' % libname)
|
||||
env['SKIPPED_DEPS'].append(libname)
|
||||
|
||||
if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']:
|
||||
if not conf.icu_at_least_four_two():
|
||||
|
@ -1134,9 +1125,9 @@ if not preconfigured:
|
|||
|
||||
# boost system is used in boost 1.35 and greater
|
||||
env['HAS_BOOST_SYSTEM'] = False
|
||||
boost_lib_version_from_header = conf.GetBoostLibVersion()
|
||||
if boost_lib_version_from_header:
|
||||
boost_version_from_header = int(boost_lib_version_from_header.split('_')[1])
|
||||
env['BOOST_LIB_VERSION_FROM_HEADER'] = conf.GetBoostLibVersion()
|
||||
if env['BOOST_LIB_VERSION_FROM_HEADER']:
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header >= 35:
|
||||
env['HAS_BOOST_SYSTEM'] = True
|
||||
|
||||
|
@ -1169,7 +1160,7 @@ if not preconfigured:
|
|||
if not env['BOOST_VERSION']:
|
||||
env['MISSING_DEPS'].append('boost version >=%s' % BOOST_MIN_VERSION)
|
||||
else:
|
||||
color_print(4,'Found boost lib version... %s' % boost_lib_version_from_header )
|
||||
color_print(4,'Found boost lib version... %s' % env['BOOST_LIB_VERSION_FROM_HEADER'] )
|
||||
|
||||
for count, libinfo in enumerate(BOOST_LIBSHEADERS):
|
||||
if not conf.CheckLibWithHeader('boost_%s%s' % (libinfo[0],env['BOOST_APPEND']), libinfo[1], 'C++'):
|
||||
|
@ -1353,7 +1344,7 @@ if not preconfigured:
|
|||
color_print(4," $ sudo python scons/scons.py install")
|
||||
color_print(4,"\nTo view available path variables:\n $ python scons/scons.py --help or -h")
|
||||
color_print(4,'\nTo view overall SCons help options:\n $ python scons/scons.py --help-options or -H\n')
|
||||
color_print(4,'More info: http://trac.mapnik.org/wiki/MapnikInstallation')
|
||||
color_print(4,'More info: https://github.com/mapnik/mapnik/wiki/MapnikInstallation')
|
||||
if not HELP_REQUESTED:
|
||||
Exit(1)
|
||||
else:
|
||||
|
@ -1379,14 +1370,13 @@ if not preconfigured:
|
|||
# fetch the mapnik version header in order to set the
|
||||
# ABI version used to build libmapnik.so on linux in src/build.py
|
||||
abi = conf.GetMapnikLibVersion()
|
||||
abi_fallback = [2,0,0]
|
||||
abi_fallback = "2.0.3"
|
||||
if not abi:
|
||||
color_print(1,'Problem encountered parsing mapnik version, falling back to %s' % abi_fallback)
|
||||
env['ABI_VERSION'] = abi_fallback
|
||||
else:
|
||||
env['ABI_VERSION'] = abi
|
||||
env['MAPNIK_VERSION_STRING'] = '.'.join(['%d' % i for i in env['ABI_VERSION']])
|
||||
abi = abi_fallback
|
||||
|
||||
env['ABI_VERSION'] = abi.replace('-pre','').split('.')
|
||||
env['MAPNIK_VERSION_STRING'] = abi
|
||||
|
||||
# Common C++ flags.
|
||||
if env['THREADING'] == 'multi':
|
||||
|
@ -1394,13 +1384,6 @@ if not preconfigured:
|
|||
else :
|
||||
common_cxx_flags = '-D%s ' % env['PLATFORM'].upper()
|
||||
|
||||
svn_version = call('svnversion')
|
||||
if not svn_version == 'exported':
|
||||
pattern = r'(\d+)(.*)'
|
||||
try:
|
||||
env['SVN_REVISION'] = re.match(pattern,svn_version).groups()[0]
|
||||
except: pass
|
||||
|
||||
# Mac OSX (Darwin) special settings
|
||||
if env['PLATFORM'] == 'Darwin':
|
||||
pthread = ''
|
||||
|
@ -1500,7 +1483,7 @@ if not preconfigured:
|
|||
if not conf.CheckHeader(header='Python.h',language='C'):
|
||||
color_print(1,'Could not find required header files for the Python language (version %s)' % env['PYTHON_VERSION'])
|
||||
env.Replace(**backup)
|
||||
env['MISSING_DEPS'].append('python %s development headers' % env['PYTHON_VERSION'])
|
||||
Exit(1)
|
||||
else:
|
||||
env.Replace(**backup)
|
||||
|
||||
|
@ -1508,6 +1491,15 @@ if not preconfigured:
|
|||
color_print(1,"Python version 2.2 or greater required")
|
||||
Exit(1)
|
||||
|
||||
if env['BOOST_PYTHON_LIB']:
|
||||
env.Append(LIBS='python%s' % env['PYTHON_VERSION'])
|
||||
if not conf.CheckLibWithHeader(libs=[env['BOOST_PYTHON_LIB']], header='boost/python/detail/config.hpp', language='C++'):
|
||||
color_print(1, 'Could not find library %s for boost python' % env['BOOST_PYTHON_LIB'])
|
||||
env.Replace(**backup)
|
||||
Exit(1)
|
||||
else:
|
||||
env.Replace(**backup)
|
||||
|
||||
color_print(4,'Bindings Python version... %s' % env['PYTHON_VERSION'])
|
||||
color_print(4,'Python %s prefix... %s' % (env['PYTHON_VERSION'], env['PYTHON_SYS_PREFIX']))
|
||||
color_print(4,'Python bindings will install in... %s' % os.path.normpath(env['PYTHON_INSTALL_LOCATION']))
|
||||
|
@ -1673,7 +1665,7 @@ if not HELP_REQUESTED:
|
|||
# Install the python speed testing scripts if python bindings will be available
|
||||
SConscript('utils/performance/build.py')
|
||||
|
||||
# Install the mapnik2 upgrade script
|
||||
# Install the mapnik upgrade script
|
||||
SConscript('utils/upgrade_map_xml/build.py')
|
||||
|
||||
# Configure fonts and if requested install the bundled DejaVu fonts
|
||||
|
|
|
@ -40,28 +40,28 @@ def is_py3():
|
|||
|
||||
|
||||
prefix = env['PREFIX']
|
||||
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
|
||||
target_path = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik')
|
||||
target_path_deprecated = os.path.normpath(env['PYTHON_INSTALL_LOCATION'] + os.path.sep + 'mapnik2')
|
||||
|
||||
libraries = ['mapnik2','png']
|
||||
libraries = ['mapnik']
|
||||
|
||||
if env['JPEG']:
|
||||
libraries.append('jpeg')
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
if env['BOOST_PYTHON_LIB']:
|
||||
if os.path.sep in env['BOOST_PYTHON_LIB']:
|
||||
pylib_dir = os.path.dirname(env['BOOST_PYTHON_LIB'])
|
||||
env.Prepend(LIBPATH = pylib_dir)
|
||||
pylib_name = os.path.splitext(os.path.basename(env['BOOST_PYTHON_LIB']))[0].replace('lib','',1)
|
||||
libraries.append(pylib_name)
|
||||
else:
|
||||
libraries.append(env['BOOST_PYTHON_LIB'].replace('lib','',1))
|
||||
libraries.append(env['BOOST_PYTHON_LIB'])
|
||||
else:
|
||||
if is_py3():
|
||||
libraries.append('boost_python3%s' % env['BOOST_APPEND'])
|
||||
else:
|
||||
libraries.append('boost_python%s' % env['BOOST_APPEND'])
|
||||
|
||||
# TODO - do solaris/fedora need direct linking too?
|
||||
if env['PLATFORM'] == 'Darwin':
|
||||
if not env['PYTHON_DYNAMIC_LOOKUP']:
|
||||
libraries.append('png')
|
||||
if env['JPEG']:
|
||||
libraries.append('jpeg')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
|
||||
if env['THREADING'] == 'multi':
|
||||
|
@ -111,6 +111,7 @@ if env['PLATFORM'] == 'Darwin':
|
|||
else:
|
||||
# TODO - do we need to pass -L/?
|
||||
python_link_flag = '-lpython%s' % env['PYTHON_VERSION']
|
||||
|
||||
elif env['PLATFORM'] == 'SunOS':
|
||||
# make sure to explicitly link mapnik.so against
|
||||
# libmapnik in its installed location
|
||||
|
@ -127,21 +128,24 @@ else:
|
|||
paths = '''
|
||||
"""Configuration paths of Mapnik fonts and input plugins (auto-generated by SCons)."""
|
||||
|
||||
import os
|
||||
from os.path import normpath,join,dirname
|
||||
|
||||
mapniklibpath = '%s'
|
||||
mapniklibpath = normpath(join(dirname(__file__),mapniklibpath))
|
||||
'''
|
||||
|
||||
paths += "inputpluginspath = os.path.normpath(mapniklibpath + '/input')\n"
|
||||
paths += "inputpluginspath = join(mapniklibpath,'input')\n"
|
||||
|
||||
if env['SYSTEM_FONTS']:
|
||||
paths += "fontscollectionpath = os.path.normpath('%s')" % env['SYSTEM_FONTS']
|
||||
paths += "fontscollectionpath = normpath('%s')\n" % env['SYSTEM_FONTS']
|
||||
else:
|
||||
paths += "fontscollectionpath = os.path.normpath(mapniklibpath + '/fonts')"
|
||||
paths += "fontscollectionpath = join(mapniklibpath,'fonts')\n"
|
||||
|
||||
paths += "__all__ = [mapniklibpath,inputpluginspath,fontscollectionpath]\n"
|
||||
|
||||
if not os.path.exists('mapnik'):
|
||||
os.mkdir('mapnik')
|
||||
|
||||
file('mapnik/paths.py','w').write(paths % (env['MAPNIK_LIB_DIR']))
|
||||
|
||||
# force open perms temporarily so that `sudo scons install`
|
||||
|
@ -157,6 +161,9 @@ if 'install' in COMMAND_LINE_TARGETS:
|
|||
init_files.remove('mapnik/paths.py')
|
||||
init_module = env.Install(target_path, init_files)
|
||||
env.Alias(target='install', source=init_module)
|
||||
# install mapnik2 module which redirects to mapnik and issues DeprecatedWarning
|
||||
init_mapnik2 = env.Install(target_path_deprecated, 'mapnik2/__init__.py')
|
||||
env.Alias(target='install', source=init_mapnik2)
|
||||
|
||||
# fix perms and install the custom generated 'paths.py'
|
||||
if 'install' in COMMAND_LINE_TARGETS:
|
||||
|
@ -170,17 +177,10 @@ if 'install' in COMMAND_LINE_TARGETS:
|
|||
Chmod("$TARGET", 0644),
|
||||
])
|
||||
|
||||
# install the ogcserver module code
|
||||
if 'install' in COMMAND_LINE_TARGETS:
|
||||
ogcserver_files = glob.glob('mapnik/ogcserver/*.py')
|
||||
ogcserver_module = env.Install(target_path + '/ogcserver', ogcserver_files)
|
||||
env.Alias(target='install', source=ogcserver_module)
|
||||
|
||||
|
||||
# install the shared object beside the module directory
|
||||
sources = glob.glob('*.cpp')
|
||||
|
||||
|
||||
py_env = env.Clone()
|
||||
py_env.Append(CPPPATH = env['PYTHON_INCLUDES'])
|
||||
|
||||
|
@ -194,13 +194,8 @@ if env['HAS_PYCAIRO']:
|
|||
py_env.ParseConfig('pkg-config --cflags pycairo')
|
||||
py_env.Append(CXXFLAGS = '-DHAVE_PYCAIRO')
|
||||
|
||||
if env['SVN_REVISION']:
|
||||
sources.remove('mapnik_python.cpp')
|
||||
env2 = py_env.Clone()
|
||||
env2.Append(CXXFLAGS='-DSVN_REVISION=%s' % env['SVN_REVISION'])
|
||||
sources.insert(0,env2.SharedObject('mapnik_python.cpp'))
|
||||
|
||||
_mapnik = py_env.LoadableModule('mapnik/_mapnik2', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)
|
||||
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
|
||||
_mapnik = py_env.LoadableModule('mapnik/_mapnik', sources, LIBS=libraries, LDMODULEPREFIX='', LDMODULESUFFIX='.so',LINKFLAGS=linkflags)
|
||||
|
||||
Depends(_mapnik, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
|
@ -219,4 +214,5 @@ if 'uninstall' not in COMMAND_LINE_TARGETS:
|
|||
|
||||
|
||||
env['create_uninstall_target'](env, target_path)
|
||||
env['create_uninstall_target'](env, target_path_deprecated)
|
||||
|
|
@ -43,7 +43,7 @@ import os
|
|||
import sys
|
||||
import warnings
|
||||
|
||||
from _mapnik2 import *
|
||||
from _mapnik import *
|
||||
from paths import inputpluginspath, fontscollectionpath
|
||||
|
||||
import printing
|
||||
|
@ -67,13 +67,13 @@ class _MapnikMetaclass(BoostPythonMetaclass):
|
|||
_injector = _MapnikMetaclass('_injector', (object, ), {})
|
||||
|
||||
def Filter(*args,**kwargs):
|
||||
warnings.warn("'Filter' is deprecated and will be removed in Mapnik 2.0.1, use 'Expression' instead",
|
||||
warnings.warn("'Filter' is deprecated and will be removed in Mapnik 3.x, use 'Expression' instead",
|
||||
DeprecationWarning, 2)
|
||||
return Expression(*args, **kwargs)
|
||||
|
||||
class Envelope(Box2d):
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("'Envelope' is deprecated and will be removed in Mapnik 2.0.1, use 'Box2d' instead",
|
||||
warnings.warn("'Envelope' is deprecated and will be removed in Mapnik 3.x, use 'Box2d' instead",
|
||||
DeprecationWarning, 2)
|
||||
Box2d.__init__(self, *args, **kwargs)
|
||||
|
||||
|
@ -605,13 +605,6 @@ def Geos(**keywords):
|
|||
keywords['type'] = 'geos'
|
||||
return CreateDatasource(keywords)
|
||||
|
||||
def mapnik_version_string(version=mapnik_version()):
|
||||
"""Return the Mapnik version as a string."""
|
||||
patch_level = version % 100
|
||||
minor_version = version / 100 % 1000
|
||||
major_version = version / 100000
|
||||
return '%s.%s.%s' % ( major_version, minor_version,patch_level)
|
||||
|
||||
def mapnik_version_from_string(version_string):
|
||||
"""Return the Mapnik version from a string."""
|
||||
n = version_string.split('.')
|
||||
|
@ -631,105 +624,3 @@ def register_fonts(path=fontscollectionpath,valid_extensions=['.ttf','.otf','.tt
|
|||
# auto-register known plugins and fonts
|
||||
register_plugins()
|
||||
register_fonts()
|
||||
|
||||
# Explicitly export API members to avoid namespace pollution
|
||||
# and ensure correct documentation processing
|
||||
__all__ = [
|
||||
# classes
|
||||
'Color',
|
||||
'Coord',
|
||||
'Palette',
|
||||
#'ColorBand',
|
||||
'CompositeOp',
|
||||
'DatasourceCache',
|
||||
'MemoryDatasource',
|
||||
'Box2d',
|
||||
'Feature',
|
||||
'Featureset',
|
||||
'FontEngine',
|
||||
'Geometry2d',
|
||||
'GlyphSymbolizer',
|
||||
'Image',
|
||||
'ImageView',
|
||||
'Grid',
|
||||
'GridView',
|
||||
'Layer',
|
||||
'Layers',
|
||||
'LinePatternSymbolizer',
|
||||
'LineSymbolizer',
|
||||
'Map',
|
||||
'MarkersSymbolizer',
|
||||
'Names',
|
||||
'Path',
|
||||
'Parameter',
|
||||
'Parameters',
|
||||
'PointDatasource',
|
||||
'PointSymbolizer',
|
||||
'PolygonPatternSymbolizer',
|
||||
'PolygonSymbolizer',
|
||||
'ProjTransform',
|
||||
'Projection',
|
||||
'Query',
|
||||
'RasterSymbolizer',
|
||||
'RasterColorizer',
|
||||
'Rule', 'Rules',
|
||||
'ShieldSymbolizer',
|
||||
'Singleton',
|
||||
'Stroke',
|
||||
'Style',
|
||||
'Symbolizer',
|
||||
'Symbolizers',
|
||||
'TextSymbolizer',
|
||||
'ViewTransform',
|
||||
# enums
|
||||
'aspect_fix_mode',
|
||||
'point_placement',
|
||||
'label_placement',
|
||||
'line_cap',
|
||||
'line_join',
|
||||
'text_transform',
|
||||
'vertical_alignment',
|
||||
'horizontal_alignment',
|
||||
'justify_alignment',
|
||||
'pattern_alignment',
|
||||
'filter_mode',
|
||||
# functions
|
||||
# datasources
|
||||
'Datasource',
|
||||
'CreateDatasource',
|
||||
'Shapefile',
|
||||
'PostGIS',
|
||||
'Raster',
|
||||
'Gdal',
|
||||
'Occi',
|
||||
'Ogr',
|
||||
'SQLite',
|
||||
'Osm',
|
||||
'Kismet',
|
||||
'Describe',
|
||||
# version and environment
|
||||
'mapnik_version_string',
|
||||
'mapnik_version',
|
||||
'mapnik_svn_revision',
|
||||
'has_cairo',
|
||||
'has_pycairo',
|
||||
# factory methods
|
||||
'Expression',
|
||||
'PathExpression',
|
||||
# load/save/render
|
||||
'load_map',
|
||||
'load_map_from_string',
|
||||
'save_map',
|
||||
'save_map_to_string',
|
||||
'render',
|
||||
'render_grid',
|
||||
'render_tile_to_file',
|
||||
'render_to_file',
|
||||
# other
|
||||
'register_plugins',
|
||||
'register_fonts',
|
||||
'scale_denominator',
|
||||
# deprecated
|
||||
'Filter',
|
||||
'Envelope',
|
||||
]
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""Interface for registering map styles and layers for availability in WMS Requests."""
|
||||
|
||||
from common import Version, copy_style, copy_layer
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from wms111 import ServiceHandler as ServiceHandler111
|
||||
from wms130 import ServiceHandler as ServiceHandler130
|
||||
from mapnik2 import Style, Map, load_map
|
||||
import re
|
||||
import sys
|
||||
|
||||
def ServiceHandlerFactory(conf, mapfactory, onlineresource, version):
|
||||
|
||||
if not version:
|
||||
version = Version('1.3.0')
|
||||
else:
|
||||
version = Version(version)
|
||||
if version >= '1.3.0':
|
||||
return ServiceHandler130(conf, mapfactory, onlineresource)
|
||||
else:
|
||||
return ServiceHandler111(conf, mapfactory, onlineresource)
|
||||
|
||||
class BaseWMSFactory:
|
||||
def __init__(self):
|
||||
self.layers = {}
|
||||
self.ordered_layers = []
|
||||
self.styles = {}
|
||||
self.aggregatestyles = {}
|
||||
|
||||
def loadXML(self, xmlfile, strict=False):
|
||||
tmp_map = Map(0,0)
|
||||
load_map (tmp_map, xmlfile, strict)
|
||||
for lyr in tmp_map.layers:
|
||||
style_count = len(lyr.styles)
|
||||
if style_count == 0:
|
||||
raise ServerConfigurationError("Cannot register Layer '%s' without a style" % lyr.name)
|
||||
elif style_count == 1:
|
||||
style_obj = tmp_map.find_style(lyr.styles[0])
|
||||
style_obj = copy_style(style_obj)
|
||||
style_name = lyr.styles[0]
|
||||
if style_name not in self.aggregatestyles.keys() and style_name not in self.styles.keys():
|
||||
self.register_style(style_name, style_obj)
|
||||
self.register_layer(copy_layer(lyr), style_name, extrastyles=(style_name,))
|
||||
elif style_count > 1:
|
||||
for style_name in lyr.styles:
|
||||
style_obj = tmp_map.find_style(style_name)
|
||||
style_obj = copy_style(style_obj)
|
||||
if style_name not in self.aggregatestyles.keys() and style_name not in self.styles.keys():
|
||||
self.register_style(style_name, style_obj)
|
||||
aggregates = tuple([sty for sty in lyr.styles])
|
||||
aggregates_name = '%s_aggregates' % lyr.name
|
||||
self.register_aggregate_style(aggregates_name,aggregates)
|
||||
self.register_layer(copy_layer(lyr), aggregates_name, extrastyles=aggregates)
|
||||
|
||||
def register_layer(self, layer, defaultstyle, extrastyles=()):
|
||||
layername = layer.name
|
||||
if not layername:
|
||||
raise ServerConfigurationError('Attempted to register an unnamed layer.')
|
||||
if not re.match('^\+init=epsg:\d+$', layer.srs) and not re.match('^\+proj=.*$', layer.srs):
|
||||
raise ServerConfigurationError('Attempted to register a layer without an epsg projection defined.')
|
||||
if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys():
|
||||
raise ServerConfigurationError('Attempted to register a layer with an non-existent default style.')
|
||||
layer.wmsdefaultstyle = defaultstyle
|
||||
if isinstance(extrastyles, tuple):
|
||||
for stylename in extrastyles:
|
||||
if type(stylename) == type(''):
|
||||
if stylename not in self.styles.keys() + self.aggregatestyles.keys():
|
||||
raise ServerConfigurationError('Attempted to register a layer with an non-existent extra style.')
|
||||
else:
|
||||
ServerConfigurationError('Attempted to register a layer with an invalid extra style name.')
|
||||
layer.wmsextrastyles = extrastyles
|
||||
else:
|
||||
raise ServerConfigurationError('Layer "%s" was passed an invalid list of extra styles. List must be a tuple of strings.' % layername)
|
||||
self.ordered_layers.append(layer)
|
||||
self.layers[layername] = layer
|
||||
|
||||
def register_style(self, name, style):
|
||||
if not name:
|
||||
raise ServerConfigurationError('Attempted to register a style without providing a name.')
|
||||
if name in self.aggregatestyles.keys() or name in self.styles.keys():
|
||||
raise ServerConfigurationError("Attempted to register a style with a name already in use: '%s'" % name)
|
||||
if not isinstance(style, Style):
|
||||
raise ServerConfigurationError('Bad style object passed to register_style() for style "%s".' % name)
|
||||
self.styles[name] = style
|
||||
|
||||
def register_aggregate_style(self, name, stylenames):
|
||||
if not name:
|
||||
raise ServerConfigurationError('Attempted to register an aggregate style without providing a name.')
|
||||
if name in self.aggregatestyles.keys() or name in self.styles.keys():
|
||||
raise ServerConfigurationError('Attempted to register an aggregate style with a name already in use.')
|
||||
self.aggregatestyles[name] = []
|
||||
for stylename in stylenames:
|
||||
if stylename not in self.styles.keys():
|
||||
raise ServerConfigurationError('Attempted to register an aggregate style containing a style that does not exist.')
|
||||
self.aggregatestyles[name].append(stylename)
|
||||
|
||||
def finalize(self):
|
||||
if len(self.layers) == 0:
|
||||
raise ServerConfigurationError('No layers defined!')
|
||||
if len(self.styles) == 0:
|
||||
raise ServerConfigurationError('No styles defined!')
|
||||
for layer in self.layers.values():
|
||||
for style in list(layer.styles) + list(layer.wmsextrastyles):
|
||||
if style not in self.styles.keys() + self.aggregatestyles.keys():
|
||||
raise ServerConfigurationError('Layer "%s" refers to undefined style "%s".' % (layer.name, style))
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""Mapnik OGC WMS Server."""
|
||||
|
||||
import os
|
||||
import warnings
|
||||
|
||||
warnings.warn("ogcserver module development has moved to https://github.com/mapnik/OGCServer.\n This code will function fine with this version, but will be removed in Mapnik 2.1.0. Disable this warning by editing this file: %s" % os.path.realpath(__file__), DeprecationWarning, 2)
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""CGI/FastCGI handler for Mapnik OGC WMS Server.
|
||||
|
||||
Requires 'jon' module.
|
||||
|
||||
"""
|
||||
|
||||
from os import environ
|
||||
from tempfile import gettempdir
|
||||
environ['PYTHON_EGG_CACHE'] = gettempdir()
|
||||
|
||||
import sys
|
||||
from jon import cgi
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from wms111 import ExceptionHandler as ExceptionHandler111
|
||||
from wms130 import ExceptionHandler as ExceptionHandler130
|
||||
from configparser import SafeConfigParser
|
||||
from common import Version
|
||||
|
||||
class Handler(cgi.DebugHandler):
|
||||
|
||||
def __init__(self):
|
||||
conf = SafeConfigParser()
|
||||
conf.readfp(open(self.configpath))
|
||||
self.conf = conf
|
||||
if not conf.has_option_with_value('server', 'module'):
|
||||
raise ServerConfigurationError('The factory module is not defined in the configuration file.')
|
||||
try:
|
||||
mapfactorymodule = __import__(conf.get('server', 'module'))
|
||||
except ImportError:
|
||||
raise ServerConfigurationError('The factory module could not be loaded.')
|
||||
if hasattr(mapfactorymodule, 'WMSFactory'):
|
||||
self.mapfactory = getattr(mapfactorymodule, 'WMSFactory')()
|
||||
else:
|
||||
raise ServerConfigurationError('The factory module does not have a WMSFactory class.')
|
||||
if conf.has_option('server', 'debug'):
|
||||
self.debug = int(conf.get('server', 'debug'))
|
||||
else:
|
||||
self.debug = 0
|
||||
|
||||
def process(self, req):
|
||||
reqparams = lowerparams(req.params)
|
||||
onlineresource = 'http://%s:%s%s?' % (req.environ['SERVER_NAME'], req.environ['SERVER_PORT'], req.environ['SCRIPT_NAME'])
|
||||
if not reqparams.has_key('request'):
|
||||
raise OGCException('Missing request parameter.')
|
||||
request = reqparams['request']
|
||||
del reqparams['request']
|
||||
if request == 'GetCapabilities' and not reqparams.has_key('service'):
|
||||
raise OGCException('Missing service parameter.')
|
||||
if request in ['GetMap', 'GetFeatureInfo']:
|
||||
service = 'WMS'
|
||||
else:
|
||||
service = reqparams['service']
|
||||
if reqparams.has_key('service'):
|
||||
del reqparams['service']
|
||||
try:
|
||||
mapnikmodule = __import__('mapnik2.ogcserver.' + service)
|
||||
except:
|
||||
raise OGCException('Unsupported service "%s".' % service)
|
||||
ServiceHandlerFactory = getattr(mapnikmodule.ogcserver, service).ServiceHandlerFactory
|
||||
servicehandler = ServiceHandlerFactory(self.conf, self.mapfactory, onlineresource, reqparams.get('version', None))
|
||||
if reqparams.has_key('version'):
|
||||
del reqparams['version']
|
||||
if request not in servicehandler.SERVICE_PARAMS.keys():
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
ogcparams = servicehandler.processParameters(request, reqparams)
|
||||
try:
|
||||
requesthandler = getattr(servicehandler, request)
|
||||
except:
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
response = requesthandler(ogcparams)
|
||||
req.set_header('Content-Type', response.content_type)
|
||||
req.set_header('Content-Length', str(len(response.content)))
|
||||
req.write(response.content)
|
||||
|
||||
def traceback(self, req):
|
||||
reqparams = lowerparams(req.params)
|
||||
version = reqparams.get('version', None)
|
||||
if not version:
|
||||
version = Version('1.3.0')
|
||||
else:
|
||||
version = Version(version)
|
||||
if version >= '1.3.0':
|
||||
eh = ExceptionHandler130(self.debug)
|
||||
else:
|
||||
eh = ExceptionHandler111(self.debug)
|
||||
response = eh.getresponse(reqparams)
|
||||
req.set_header('Content-Type', response.content_type)
|
||||
req.set_header('Content-Length', str(len(response.content)))
|
||||
req.write(response.content)
|
||||
|
||||
def lowerparams(params):
|
||||
reqparams = {}
|
||||
for key, value in params.items():
|
||||
reqparams[key.lower()] = value
|
||||
return reqparams
|
|
@ -1,539 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""Core OGCServer classes and functions."""
|
||||
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from mapnik2 import Map, Color, Box2d, render, Image, Layer, Style, Projection as MapnikProjection, Coord
|
||||
from PIL.Image import new
|
||||
from PIL.ImageDraw import Draw
|
||||
from StringIO import StringIO
|
||||
from copy import deepcopy
|
||||
from traceback import format_exception, format_exception_only
|
||||
from sys import exc_info
|
||||
import re
|
||||
import sys
|
||||
|
||||
try:
|
||||
from lxml import etree as ElementTree
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
except ImportError:
|
||||
import elementtree.ElementTree as ElementTree
|
||||
|
||||
# from elementtree import ElementTree
|
||||
# ElementTree._namespace_map.update({'http://www.opengis.net/wms': 'wms',
|
||||
# 'http://www.opengis.net/ogc': 'ogc',
|
||||
# 'http://www.w3.org/1999/xlink': 'xlink',
|
||||
# 'http://www.w3.org/2001/XMLSchema-instance': 'xsi'
|
||||
# })
|
||||
|
||||
PIL_TYPE_MAPPING = {'image/jpeg': 'jpeg', 'image/png': 'png'}
|
||||
|
||||
class ParameterDefinition:
|
||||
|
||||
def __init__(self, mandatory, cast, default=None, allowedvalues=None, fallback=False):
|
||||
""" An OGC request parameter definition. Used to describe a
|
||||
parameter's characteristics.
|
||||
|
||||
@param mandatory: Is this parameter required by the request?
|
||||
@type mandatory: Boolean.
|
||||
|
||||
@param default: Default value to use if one is not provided
|
||||
and the parameter is optional.
|
||||
@type default: None or any valid value.
|
||||
|
||||
@param allowedvalues: A list of allowed values for the parameter.
|
||||
If a value is provided that is not in this
|
||||
list, an error is raised.
|
||||
@type allowedvalues: A python tuple of values.
|
||||
|
||||
@param fallback: Whether the value of the parameter should fall
|
||||
back to the default should an illegal value be
|
||||
provided.
|
||||
@type fallback: Boolean.
|
||||
|
||||
@return: A L{ParameterDefinition} instance.
|
||||
"""
|
||||
if mandatory not in [True, False]:
|
||||
raise ServerConfigurationError("Bad value for 'mandatory' parameter, must be True or False.")
|
||||
self.mandatory = mandatory
|
||||
if not callable(cast):
|
||||
raise ServerConfigurationError('Cast parameter definition must be callable.')
|
||||
self.cast = cast
|
||||
self.default = default
|
||||
if allowedvalues and type(allowedvalues) != type(()):
|
||||
raise ServerConfigurationError("Bad value for 'allowedvalues' parameter, must be a tuple.")
|
||||
self.allowedvalues = allowedvalues
|
||||
if fallback not in [True, False]:
|
||||
raise ServerConfigurationError("Bad value for 'fallback' parameter, must be True or False.")
|
||||
self.fallback = fallback
|
||||
|
||||
class BaseServiceHandler:
|
||||
|
||||
CONF_CONTACT_PERSON_PRIMARY = [
|
||||
['contactperson', 'ContactPerson', str],
|
||||
['contactorganization', 'ContactOrganization', str]
|
||||
]
|
||||
|
||||
CONF_CONTACT_ADDRESS = [
|
||||
['addresstype', 'AddressType', str],
|
||||
['address', 'Address', str],
|
||||
['city', 'City', str],
|
||||
['stateorprovince', 'StateOrProvince', str],
|
||||
['postcode', 'PostCode', str],
|
||||
['country', 'Country', str]
|
||||
]
|
||||
|
||||
CONF_CONTACT = [
|
||||
['contactposition', 'ContactPosition', str],
|
||||
['contactvoicetelephone', 'ContactVoiceTelephone', str],
|
||||
['contactelectronicmailaddress', 'ContactElectronicMailAddress', str]
|
||||
]
|
||||
|
||||
def processParameters(self, requestname, params):
|
||||
finalparams = {}
|
||||
for paramname, paramdef in self.SERVICE_PARAMS[requestname].items():
|
||||
if paramname not in params.keys() and paramdef.mandatory:
|
||||
raise OGCException('Mandatory parameter "%s" missing from request.' % paramname)
|
||||
elif paramname in params.keys():
|
||||
try:
|
||||
params[paramname] = paramdef.cast(params[paramname])
|
||||
except OGCException:
|
||||
raise
|
||||
except:
|
||||
raise OGCException('Invalid value "%s" for parameter "%s".' % (params[paramname], paramname))
|
||||
if paramdef.allowedvalues and params[paramname] not in paramdef.allowedvalues:
|
||||
if not paramdef.fallback:
|
||||
raise OGCException('Parameter "%s" has an illegal value.' % paramname)
|
||||
else:
|
||||
finalparams[paramname] = paramdef.default
|
||||
else:
|
||||
finalparams[paramname] = params[paramname]
|
||||
elif not paramdef.mandatory and paramdef.default:
|
||||
finalparams[paramname] = paramdef.default
|
||||
return finalparams
|
||||
|
||||
def processServiceCapabilities(self, capetree):
|
||||
if len(self.conf.items('service')) > 0:
|
||||
servicee = capetree.find('{http://www.opengis.net/wms}Service')
|
||||
for item in self.CONF_SERVICE:
|
||||
if self.conf.has_option_with_value('service', item[0]):
|
||||
value = self.conf.get('service', item[0]).strip()
|
||||
try:
|
||||
item[2](value)
|
||||
except:
|
||||
raise ServerConfigurationError('Configuration parameter [%s]->%s has an invalid value: %s.' % ('service', item[0], value))
|
||||
if item[0] == 'onlineresource':
|
||||
element = ElementTree.Element('%s' % item[1])
|
||||
servicee.append(element)
|
||||
element.set('{http://www.w3.org/1999/xlink}href', value)
|
||||
element.set('{http://www.w3.org/1999/xlink}type', 'simple')
|
||||
elif item[0] == 'keywordlist':
|
||||
element = ElementTree.Element('%s' % item[1])
|
||||
servicee.append(element)
|
||||
keywords = value.split(',')
|
||||
keywords = map(str.strip, keywords)
|
||||
for keyword in keywords:
|
||||
kelement = ElementTree.Element('Keyword')
|
||||
kelement.text = keyword
|
||||
element.append(kelement)
|
||||
else:
|
||||
element = ElementTree.Element('%s' % item[1])
|
||||
element.text = value
|
||||
servicee.append(element)
|
||||
if len(self.conf.items_with_value('contact')) > 0:
|
||||
element = ElementTree.Element('ContactInformation')
|
||||
servicee.append(element)
|
||||
for item in self.CONF_CONTACT:
|
||||
if self.conf.has_option_with_value('contact', item[0]):
|
||||
value = self.conf.get('contact', item[0]).strip()
|
||||
try:
|
||||
item[2](value)
|
||||
except:
|
||||
raise ServerConfigurationError('Configuration parameter [%s]->%s has an invalid value: %s.' % ('service', item[0], value))
|
||||
celement = ElementTree.Element('%s' % item[1])
|
||||
celement.text = value
|
||||
element.append(celement)
|
||||
for item in self.CONF_CONTACT_PERSON_PRIMARY + self.CONF_CONTACT_ADDRESS:
|
||||
if item in self.CONF_CONTACT_PERSON_PRIMARY:
|
||||
tagname = 'ContactPersonPrimary'
|
||||
else:
|
||||
tagname = 'ContactAddress'
|
||||
if self.conf.has_option_with_value('contact', item[0]):
|
||||
if element.find(tagname) == None:
|
||||
subelement = ElementTree.Element(tagname)
|
||||
element.append(subelement)
|
||||
value = self.conf.get('contact', item[0]).strip()
|
||||
try:
|
||||
item[2](value)
|
||||
except:
|
||||
raise ServerConfigurationError('Configuration parameter [%s]->%s has an invalid value: %s.' % ('service', item[0], value))
|
||||
celement = ElementTree.Element('%s' % item[1])
|
||||
celement.text = value
|
||||
subelement.append(celement)
|
||||
|
||||
class Response:
|
||||
|
||||
def __init__(self, content_type, content):
|
||||
self.content_type = content_type
|
||||
self.content = content
|
||||
|
||||
class Version:
|
||||
|
||||
def __init__(self, version):
|
||||
version = version.split('.')
|
||||
if len(version) != 3:
|
||||
raise OGCException('Badly formatted version number.')
|
||||
try:
|
||||
version = map(int, version)
|
||||
except:
|
||||
raise OGCException('Badly formatted version number.')
|
||||
self.version = version
|
||||
|
||||
def __repr__(self):
|
||||
return '%s.%s.%s' % (self.version[0], self.version[1], self.version[2])
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, str):
|
||||
other = Version(other)
|
||||
if self.version[0] < other.version[0]:
|
||||
return -1
|
||||
elif self.version[0] > other.version[0]:
|
||||
return 1
|
||||
else:
|
||||
if self.version[1] < other.version[1]:
|
||||
return -1
|
||||
elif self.version[1] > other.version[1]:
|
||||
return 1
|
||||
else:
|
||||
if self.version[2] < other.version[2]:
|
||||
return -1
|
||||
elif self.version[2] > other.version[2]:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
class ListFactory:
|
||||
|
||||
def __init__(self, cast):
|
||||
self.cast = cast
|
||||
|
||||
def __call__(self, string):
|
||||
seq = string.split(',')
|
||||
return map(self.cast, seq)
|
||||
|
||||
def ColorFactory(colorstring):
|
||||
if re.match('^0x[a-fA-F0-9]{6}$', colorstring):
|
||||
return Color(eval('0x' + colorstring[2:4]), eval('0x' + colorstring[4:6]), eval('0x' + colorstring[6:8]))
|
||||
else:
|
||||
raise OGCException('Invalid color value. Must be of format "0xFFFFFF".')
|
||||
|
||||
class CRS:
|
||||
|
||||
def __init__(self, namespace, code):
|
||||
self.namespace = namespace.lower()
|
||||
self.code = int(code)
|
||||
self.proj = None
|
||||
|
||||
def __repr__(self):
|
||||
return '%s:%s' % (self.namespace, self.code)
|
||||
|
||||
def __eq__(self, other):
|
||||
if str(other) == str(self):
|
||||
return True
|
||||
return False
|
||||
|
||||
def inverse(self, x, y):
|
||||
if not self.proj:
|
||||
self.proj = Projection('+init=%s:%s' % (self.namespace, self.code))
|
||||
return self.proj.inverse(Coord(x, y))
|
||||
|
||||
def forward(self, x, y):
|
||||
if not self.proj:
|
||||
self.proj = Projection('+init=%s:%s' % (self.namespace, self.code))
|
||||
return self.proj.forward(Coord(x, y))
|
||||
|
||||
class CRSFactory:
|
||||
|
||||
def __init__(self, allowednamespaces):
|
||||
self.allowednamespaces = allowednamespaces
|
||||
|
||||
def __call__(self, crsstring):
|
||||
if not re.match('^[A-Z]{3,5}:\d+$', crsstring):
|
||||
raise OGCException('Invalid format for the CRS parameter: %s' % crsstring, 'InvalidCRS')
|
||||
crsparts = crsstring.split(':')
|
||||
if crsparts[0] in self.allowednamespaces:
|
||||
return CRS(crsparts[0], crsparts[1])
|
||||
else:
|
||||
raise OGCException('Invalid CRS Namespace: %s' % crsparts[0], 'InvalidCRS')
|
||||
|
||||
def copy_layer(obj):
|
||||
lyr = Layer(obj.name)
|
||||
lyr.abstract = obj.abstract
|
||||
lyr.active = obj.active
|
||||
lyr.clear_label_cache = obj.clear_label_cache
|
||||
lyr.datasource = obj.datasource
|
||||
#lyr.maxzoom = obj.maxzoom
|
||||
#lyr.minzoom = obj.minzoom
|
||||
lyr.queryable = obj.queryable
|
||||
lyr.srs = obj.srs
|
||||
lyr.title = obj.title
|
||||
if hasattr(obj,'wmsdefaultstyle'):
|
||||
lyr.wmsdefaultstyle = obj.wmsdefaultstyle
|
||||
if hasattr(obj,'wmsextrastyles'):
|
||||
lyr.wmsextrastyles = obj.wmsextrastyles
|
||||
return lyr
|
||||
|
||||
def copy_style(obj):
|
||||
sty = Style()
|
||||
for rule in obj.rules:
|
||||
sty.rules.append(rule)
|
||||
return sty
|
||||
|
||||
class WMSBaseServiceHandler(BaseServiceHandler):
|
||||
|
||||
def GetMap(self, params):
|
||||
m = self._buildMap(params)
|
||||
im = Image(params['width'], params['height'])
|
||||
render(m, im)
|
||||
return Response(params['format'], im.tostring(PIL_TYPE_MAPPING[params['format']]))
|
||||
|
||||
def GetFeatureInfo(self, params, querymethodname='query_point'):
|
||||
m = self._buildMap(params)
|
||||
if params['info_format'] == 'text/plain':
|
||||
writer = TextFeatureInfo()
|
||||
elif params['info_format'] == 'text/xml':
|
||||
writer = XMLFeatureInfo()
|
||||
if params['query_layers'] and params['query_layers'][0] == '__all__':
|
||||
for layerindex, layer in enumerate(m.layers):
|
||||
featureset = getattr(m, querymethodname)(layerindex, params['i'], params['j'])
|
||||
features = featureset.features
|
||||
if features:
|
||||
writer.addlayer(layer.name)
|
||||
for feat in features:
|
||||
writer.addfeature()
|
||||
for prop in feat.properties:
|
||||
writer.addattribute(prop[0], prop[1])
|
||||
else:
|
||||
for layerindex, layername in enumerate(params['query_layers']):
|
||||
if layername in params['layers']:
|
||||
if m.layers[layerindex].queryable:
|
||||
featureset = getattr(m, querymethodname)(layerindex, params['i'], params['j'])
|
||||
features = featureset.features
|
||||
if features:
|
||||
writer.addlayer(m.layers[layerindex].name)
|
||||
for feat in features:
|
||||
writer.addfeature()
|
||||
for prop in feat.properties:
|
||||
writer.addattribute(prop[0], prop[1])
|
||||
else:
|
||||
raise OGCException('Requested query layer "%s" is not marked queryable.' % layername, 'LayerNotQueryable')
|
||||
else:
|
||||
raise OGCException('Requested query layer "%s" not in the LAYERS parameter.' % layername)
|
||||
return Response(params['info_format'], str(writer))
|
||||
|
||||
def _buildMap(self, params):
|
||||
if str(params['crs']) not in self.allowedepsgcodes:
|
||||
raise OGCException('Unsupported CRS "%s" requested.' % str(params['crs']).upper(), 'InvalidCRS')
|
||||
if params['bbox'][0] >= params['bbox'][2]:
|
||||
raise OGCException("BBOX values don't make sense. minx is greater than maxx.")
|
||||
if params['bbox'][1] >= params['bbox'][3]:
|
||||
raise OGCException("BBOX values don't make sense. miny is greater than maxy.")
|
||||
if params.has_key('styles') and len(params['styles']) != len(params['layers']):
|
||||
raise OGCException('STYLES length does not match LAYERS length.')
|
||||
m = Map(params['width'], params['height'], '+init=%s' % params['crs'])
|
||||
if params.has_key('transparent') and params['transparent'] == 'FALSE':
|
||||
if params['bgcolor']:
|
||||
m.background = params['bgcolor']
|
||||
else:
|
||||
m.background = Color(0, 0, 0, 0)
|
||||
maplayers = self.mapfactory.layers
|
||||
orderedmaplayers = self.mapfactory.ordered_layers
|
||||
mapstyles = self.mapfactory.styles
|
||||
mapaggregatestyles = self.mapfactory.aggregatestyles
|
||||
# a non WMS spec way of requesting all layers
|
||||
if params['layers'] and params['layers'][0] == '__all__':
|
||||
for layername in orderedmaplayers:
|
||||
layer = copy_layer(layername)
|
||||
reqstyle = layer.wmsdefaultstyle
|
||||
if reqstyle in mapaggregatestyles.keys():
|
||||
for stylename in mapaggregatestyles[reqstyle]:
|
||||
layer.styles.append(stylename)
|
||||
else:
|
||||
layer.styles.append(reqstyle)
|
||||
for stylename in layer.styles:
|
||||
if stylename in mapstyles.keys():
|
||||
m.append_style(stylename, mapstyles[stylename])
|
||||
m.layers.append(layer)
|
||||
else:
|
||||
for layerindex, layername in enumerate(params['layers']):
|
||||
try:
|
||||
layer = copy_layer(maplayers[layername])
|
||||
except KeyError:
|
||||
raise OGCException('Layer "%s" not defined.' % layername, 'LayerNotDefined')
|
||||
try:
|
||||
reqstyle = params['styles'][layerindex]
|
||||
except IndexError:
|
||||
reqstyle = ''
|
||||
if reqstyle and reqstyle not in layer.wmsextrastyles:
|
||||
raise OGCException('Invalid style "%s" requested for layer "%s".' % (reqstyle, layername), 'StyleNotDefined')
|
||||
if not reqstyle:
|
||||
reqstyle = layer.wmsdefaultstyle
|
||||
if reqstyle in mapaggregatestyles.keys():
|
||||
for stylename in mapaggregatestyles[reqstyle]:
|
||||
layer.styles.append(stylename)
|
||||
else:
|
||||
layer.styles.append(reqstyle)
|
||||
for stylename in layer.styles:
|
||||
if stylename in mapstyles.keys():
|
||||
m.append_style(stylename, mapstyles[stylename])
|
||||
else:
|
||||
raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
|
||||
m.layers.append(layer)
|
||||
m.zoom_to_box(Box2d(params['bbox'][0], params['bbox'][1], params['bbox'][2], params['bbox'][3]))
|
||||
return m
|
||||
|
||||
class BaseExceptionHandler:
|
||||
|
||||
def __init__(self, debug):
|
||||
self.debug = debug
|
||||
|
||||
def getresponse(self, params):
|
||||
code = ''
|
||||
message = '\n'
|
||||
if not params:
|
||||
message = '''
|
||||
<h2>Welcome to the Mapnik OGCServer.</h2>
|
||||
<h3>Ready to accept map requests...</h5>
|
||||
<h4>For more info see: <a href="http://trac.mapnik.org/wiki/OgcServer">trac.mapnik.org</a></h4>
|
||||
'''
|
||||
return self.htmlhandler('', message)
|
||||
excinfo = exc_info()
|
||||
if self.debug:
|
||||
messagelist = format_exception(excinfo[0], excinfo[1], excinfo[2])
|
||||
else:
|
||||
messagelist = format_exception_only(excinfo[0], excinfo[1])
|
||||
message += ''.join(messagelist)
|
||||
if isinstance(excinfo[1], OGCException) and len(excinfo[1].args) > 1:
|
||||
code = excinfo[1].args[1]
|
||||
exceptions = params.get('exceptions', None)
|
||||
if self.debug:
|
||||
return self.htmlhandler(code, message)
|
||||
if not exceptions or not self.handlers.has_key(exceptions):
|
||||
exceptions = self.defaulthandler
|
||||
return self.handlers[exceptions](self, code, message, params)
|
||||
|
||||
def htmlhandler(self,code,message):
|
||||
if code:
|
||||
resp_text = '<h2>OGCServer Error:</h2><pre>%s</pre>\n<h3>Traceback:</h3><pre>%s</pre>\n' % (message, code)
|
||||
else:
|
||||
resp_text = message
|
||||
return Response('text/html', resp_text)
|
||||
|
||||
def xmlhandler(self, code, message, params):
|
||||
ogcexcetree = deepcopy(self.xmltemplate)
|
||||
e = ogcexcetree.find(self.xpath)
|
||||
e.text = message
|
||||
if code:
|
||||
e.set('code', code)
|
||||
return Response(self.xmlmimetype, ElementTree.tostring(ogcexcetree))
|
||||
|
||||
def inimagehandler(self, code, message, params):
|
||||
im = new('RGBA', (int(params['width']), int(params['height'])))
|
||||
im.putalpha(new('1', (int(params['width']), int(params['height']))))
|
||||
draw = Draw(im)
|
||||
for count, line in enumerate(message.strip().split('\n')):
|
||||
draw.text((12,15*(count+1)), line, fill='#000000')
|
||||
fh = StringIO()
|
||||
im.save(fh, PIL_TYPE_MAPPING[params['format']])
|
||||
fh.seek(0)
|
||||
return Response(params['format'], fh.read())
|
||||
|
||||
def blankhandler(self, code, message, params):
|
||||
bgcolor = params.get('bgcolor', '#FFFFFF')
|
||||
bgcolor = bgcolor.replace('0x', '#')
|
||||
transparent = params.get('transparent', 'FALSE')
|
||||
if transparent == 'TRUE':
|
||||
im = new('RGBA', (int(params['width']), int(params['height'])))
|
||||
im.putalpha(new('1', (int(params['width']), int(params['height']))))
|
||||
else:
|
||||
im = new('RGBA', (int(params['width']), int(params['height'])), bgcolor)
|
||||
fh = StringIO()
|
||||
im.save(fh, PIL_TYPE_MAPPING[params['format']])
|
||||
fh.seek(0)
|
||||
return Response(params['format'], fh.read())
|
||||
|
||||
class Projection(MapnikProjection):
|
||||
|
||||
def epsgstring(self):
|
||||
return self.params().split('=')[1].upper()
|
||||
|
||||
class TextFeatureInfo:
|
||||
|
||||
def __init__(self):
|
||||
self.buffer = ''
|
||||
|
||||
def addlayer(self, name):
|
||||
self.buffer += '\n[%s]\n' % name
|
||||
|
||||
def addfeature(self):
|
||||
pass#self.buffer += '\n'
|
||||
|
||||
def addattribute(self, name, value):
|
||||
self.buffer += '%s=%s\n' % (name, str(value))
|
||||
|
||||
def __str__(self):
|
||||
return self.buffer
|
||||
|
||||
class XMLFeatureInfo:
|
||||
|
||||
basexml = """<?xml version="1.0"?>
|
||||
<resultset>
|
||||
</resultset>
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.rootelement = ElementTree.fromstring(self.basexml)
|
||||
|
||||
def addlayer(self, name):
|
||||
layer = ElementTree.Element('layer')
|
||||
layer.set('name', name)
|
||||
self.rootelement.append(layer)
|
||||
self.currentlayer = layer
|
||||
|
||||
def addfeature(self):
|
||||
feature = ElementTree.Element('feature')
|
||||
self.currentlayer.append(feature)
|
||||
self.currentfeature = feature
|
||||
|
||||
def addattribute(self, name, value):
|
||||
attribute = ElementTree.Element('attribute')
|
||||
attname = ElementTree.Element('name')
|
||||
attname.text = name
|
||||
attvalue = ElementTree.Element('value')
|
||||
attvalue.text = unicode(value)
|
||||
attribute.append(attname)
|
||||
attribute.append(attvalue)
|
||||
self.currentfeature.append(attribute)
|
||||
|
||||
def __str__(self):
|
||||
return '<?xml version="1.0"?>\n' + ElementTree.tostring(self.rootelement)
|
|
@ -1,44 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
""" Change SafeConfigParser behavior to treat options without values as
|
||||
non-existent.
|
||||
"""
|
||||
|
||||
from ConfigParser import SafeConfigParser as OrigSafeConfigParser
|
||||
|
||||
class SafeConfigParser(OrigSafeConfigParser):
|
||||
|
||||
def items_with_value(self, section):
|
||||
finallist = []
|
||||
items = self.items(section)
|
||||
for item in items:
|
||||
if item[1] != '':
|
||||
finallist.append(item)
|
||||
return finallist
|
||||
|
||||
def has_option_with_value(self, section, option):
|
||||
if self.has_option(section, option):
|
||||
if self.get(section, option) == '':
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
return True
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""Custom OGCServer Exceptions"""
|
||||
|
||||
class OGCException(Exception):
|
||||
pass
|
||||
|
||||
class ServerConfigurationError(Exception):
|
||||
pass
|
|
@ -1,133 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id: modserver.py 283 2006-07-22 18:54:53Z jdoyon $
|
||||
|
||||
"""Mod_python handler for Mapnik OGC WMS Server."""
|
||||
|
||||
import sys
|
||||
from mod_python import apache, util
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from wms111 import ExceptionHandler as ExceptionHandler111
|
||||
from wms130 import ExceptionHandler as ExceptionHandler130
|
||||
from configparser import SafeConfigParser
|
||||
from common import Version
|
||||
|
||||
|
||||
class ModHandler(object):
|
||||
def __init__(self, configpath):
|
||||
conf = SafeConfigParser()
|
||||
conf.readfp(open(configpath))
|
||||
self.conf = conf
|
||||
if not conf.has_option_with_value('server', 'module'):
|
||||
raise ServerConfigurationError('The factory module is not defined in the configuration file.')
|
||||
try:
|
||||
mapfactorymodule = __import__(conf.get('server', 'module'))
|
||||
except ImportError:
|
||||
raise ServerConfigurationError('The factory module could not be loaded.')
|
||||
if hasattr(mapfactorymodule, 'WMSFactory'):
|
||||
self.mapfactory = getattr(mapfactorymodule, 'WMSFactory')()
|
||||
else:
|
||||
raise ServerConfigurationError('The factory module does not have a WMSFactory class.')
|
||||
if conf.has_option('server', 'debug'):
|
||||
self.debug = int(conf.get('server', 'debug'))
|
||||
else:
|
||||
self.debug = 0
|
||||
if self.conf.has_option_with_value('server', 'maxage'):
|
||||
self.max_age = 'max-age=%d' % self.conf.get('server', 'maxage')
|
||||
else:
|
||||
self.max_age = None
|
||||
|
||||
def __call__(self, apacheReq):
|
||||
try:
|
||||
reqparams = util.FieldStorage(apacheReq,keep_blank_values=1)
|
||||
if not reqparams:
|
||||
eh = ExceptionHandler130(self.debug)
|
||||
response = eh.getresponse(reqparams)
|
||||
apacheReq.content_type = response.content_type
|
||||
else:
|
||||
reqparams = lowerparams(reqparams)
|
||||
port = apacheReq.connection.local_addr[1]
|
||||
onlineresource = 'http://%s:%s%s?' % (apacheReq.hostname, port, apacheReq.subprocess_env['SCRIPT_NAME'])
|
||||
if not reqparams.has_key('request'):
|
||||
raise OGCException('Missing Request parameter.')
|
||||
request = reqparams['request']
|
||||
del reqparams['request']
|
||||
if request == 'GetCapabilities' and not reqparams.has_key('service'):
|
||||
raise OGCException('Missing service parameter.')
|
||||
if request in ['GetMap', 'GetFeatureInfo']:
|
||||
service = 'WMS'
|
||||
else:
|
||||
service = reqparams['service']
|
||||
if reqparams.has_key('service'):
|
||||
del reqparams['service']
|
||||
try:
|
||||
mapnikmodule = __import__('mapnik2.ogcserver.' + service)
|
||||
except:
|
||||
raise OGCException('Unsupported service "%s".' % service)
|
||||
ServiceHandlerFactory = getattr(mapnikmodule.ogcserver, service).ServiceHandlerFactory
|
||||
servicehandler = ServiceHandlerFactory(self.conf, self.mapfactory, onlineresource, reqparams.get('version', None))
|
||||
if reqparams.has_key('version'):
|
||||
del reqparams['version']
|
||||
if request not in servicehandler.SERVICE_PARAMS.keys():
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
|
||||
# Get parameters and pass to WMSFactory in custom "setup" method
|
||||
ogcparams = servicehandler.processParameters(request, reqparams)
|
||||
try:
|
||||
requesthandler = getattr(servicehandler, request)
|
||||
except:
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
|
||||
response = requesthandler(ogcparams)
|
||||
apacheReq.content_type = response.content_type
|
||||
apacheReq.status = apache.HTTP_OK
|
||||
except Exception, E:
|
||||
return self.traceback(apacheReq,E)
|
||||
|
||||
if self.max_age:
|
||||
apacheReq.headers_out.add('Cache-Control', max_age)
|
||||
apacheReq.headers_out.add('Content-Length', str(len(response.content)))
|
||||
apacheReq.send_http_header()
|
||||
apacheReq.write(response.content)
|
||||
return apache.OK
|
||||
|
||||
def traceback(self, apacheReq,E):
|
||||
reqparams = lowerparams(util.FieldStorage(apacheReq))
|
||||
version = reqparams.get('version', None)
|
||||
if not version:
|
||||
version = Version('1.3.0')
|
||||
else:
|
||||
version = Version(version)
|
||||
if version >= '1.3.0':
|
||||
eh = ExceptionHandler130(self.debug)
|
||||
else:
|
||||
eh = ExceptionHandler111(self.debug)
|
||||
response = eh.getresponse(reqparams)
|
||||
apacheReq.content_type = response.content_type
|
||||
apacheReq.headers_out.add('Content-Length', str(len(response.content)))
|
||||
apacheReq.send_http_header()
|
||||
apacheReq.write(response.content)
|
||||
return apache.OK
|
||||
|
||||
def lowerparams(params):
|
||||
reqparams = {}
|
||||
for key, value in params.items():
|
||||
reqparams[key.lower()] = value
|
||||
return reqparams
|
|
@ -1,238 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""WMS 1.1.1 compliant GetCapabilities, GetMap, GetFeatureInfo, and Exceptions interface."""
|
||||
|
||||
from common import ParameterDefinition, Response, Version, ListFactory, \
|
||||
ColorFactory, CRSFactory, WMSBaseServiceHandler, CRS, \
|
||||
BaseExceptionHandler, Projection
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from mapnik2 import Coord
|
||||
|
||||
try:
|
||||
from lxml import etree as ElementTree
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
except ImportError:
|
||||
import elementtree.ElementTree as ElementTree
|
||||
|
||||
class ServiceHandler(WMSBaseServiceHandler):
|
||||
|
||||
SERVICE_PARAMS = {
|
||||
'GetCapabilities': {
|
||||
'updatesequence': ParameterDefinition(False, str)
|
||||
},
|
||||
'GetMap': {
|
||||
'layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'styles': ParameterDefinition(True, ListFactory(str)),
|
||||
'srs': ParameterDefinition(True, CRSFactory(['EPSG'])),
|
||||
'bbox': ParameterDefinition(True, ListFactory(float)),
|
||||
'width': ParameterDefinition(True, int),
|
||||
'height': ParameterDefinition(True, int),
|
||||
'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')),
|
||||
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
|
||||
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
|
||||
'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank','text/html'))
|
||||
},
|
||||
'GetFeatureInfo': {
|
||||
'layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'styles': ParameterDefinition(False, ListFactory(str)),
|
||||
'srs': ParameterDefinition(True, CRSFactory(['EPSG'])),
|
||||
'bbox': ParameterDefinition(True, ListFactory(float)),
|
||||
'width': ParameterDefinition(True, int),
|
||||
'height': ParameterDefinition(True, int),
|
||||
'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')),
|
||||
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
|
||||
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
|
||||
'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank','text/html')),
|
||||
'query_layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')),
|
||||
'feature_count': ParameterDefinition(False, int, 1),
|
||||
'x': ParameterDefinition(True, int),
|
||||
'y': ParameterDefinition(True, int)
|
||||
}
|
||||
}
|
||||
|
||||
CONF_SERVICE = [
|
||||
['title', 'Title', str],
|
||||
['abstract', 'Abstract', str],
|
||||
['onlineresource', 'OnlineResource', str],
|
||||
['fees', 'Fees', str],
|
||||
['accessconstraints', 'AccessConstraints', str],
|
||||
['keywordlist', 'KeywordList', str]
|
||||
]
|
||||
|
||||
capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE WMT_MS_Capabilities SYSTEM "http://www.digitalearth.gov/wmt/xml/capabilities_1_1_1.dtd">
|
||||
<WMT_MS_Capabilities version="1.1.1" updateSequence="0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.opengis.net/wms">
|
||||
<Service>
|
||||
<Name>WMS</Name>
|
||||
</Service>
|
||||
<Capability>
|
||||
<Request>
|
||||
<GetCapabilities>
|
||||
<Format>application/vnd.ogc.wms_xml</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetCapabilities>
|
||||
<GetMap>
|
||||
<Format>image/png</Format>
|
||||
<Format>image/jpeg</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetMap>
|
||||
<GetFeatureInfo>
|
||||
<Format>text/plain</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetFeatureInfo>
|
||||
</Request>
|
||||
<Exception>
|
||||
<Format>application/vnd.ogc.se_xml</Format>
|
||||
<Format>application/vnd.ogc.se_inimage</Format>
|
||||
<Format>application/vnd.ogc.se_blank</Format>
|
||||
</Exception>
|
||||
<Layer>
|
||||
<Title>A Mapnik WMS Server</Title>
|
||||
<Abstract>A Mapnik WMS Server</Abstract>
|
||||
</Layer>
|
||||
</Capability>
|
||||
</WMT_MS_Capabilities>
|
||||
"""
|
||||
|
||||
def __init__(self, conf, mapfactory, opsonlineresource):
|
||||
self.conf = conf
|
||||
self.mapfactory = mapfactory
|
||||
self.opsonlineresource = opsonlineresource
|
||||
if self.conf.has_option('service', 'allowedepsgcodes'):
|
||||
self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(','))
|
||||
else:
|
||||
raise ServerConfigurationError('Allowed EPSG codes not properly configured.')
|
||||
self.capabilities = None
|
||||
|
||||
def GetCapabilities(self, params):
|
||||
if not self.capabilities:
|
||||
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
|
||||
|
||||
elements = capetree.findall('Capability//OnlineResource')
|
||||
for element in elements:
|
||||
element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource)
|
||||
|
||||
self.processServiceCapabilities(capetree)
|
||||
|
||||
rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer')
|
||||
|
||||
for epsgcode in self.allowedepsgcodes:
|
||||
rootlayercrs = ElementTree.Element('SRS')
|
||||
rootlayercrs.text = epsgcode.upper()
|
||||
rootlayerelem.append(rootlayercrs)
|
||||
|
||||
for layer in self.mapfactory.ordered_layers:
|
||||
layerproj = Projection(layer.srs)
|
||||
layername = ElementTree.Element('Name')
|
||||
layername.text = layer.name
|
||||
env = layer.envelope()
|
||||
llp = layerproj.inverse(Coord(env.minx, env.miny))
|
||||
urp = layerproj.inverse(Coord(env.maxx, env.maxy))
|
||||
latlonbb = ElementTree.Element('LatLonBoundingBox')
|
||||
latlonbb.set('minx', str(llp.x))
|
||||
latlonbb.set('miny', str(llp.y))
|
||||
latlonbb.set('maxx', str(urp.x))
|
||||
latlonbb.set('maxy', str(urp.y))
|
||||
layerbbox = ElementTree.Element('BoundingBox')
|
||||
layerbbox.set('SRS', layerproj.epsgstring())
|
||||
layerbbox.set('minx', str(env.minx))
|
||||
layerbbox.set('miny', str(env.miny))
|
||||
layerbbox.set('maxx', str(env.maxx))
|
||||
layerbbox.set('maxy', str(env.maxy))
|
||||
layere = ElementTree.Element('Layer')
|
||||
layere.append(layername)
|
||||
if layer.title:
|
||||
layertitle = ElementTree.Element('Title')
|
||||
layertitle.text = layer.title
|
||||
layere.append(layertitle)
|
||||
if layer.abstract:
|
||||
layerabstract = ElementTree.Element('Abstract')
|
||||
layerabstract.text = layer.abstract
|
||||
layere.append(layerabstract)
|
||||
if layer.queryable:
|
||||
layere.set('queryable', '1')
|
||||
layere.append(latlonbb)
|
||||
layere.append(layerbbox)
|
||||
if len(layer.wmsextrastyles) > 0:
|
||||
for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles):
|
||||
style = ElementTree.Element('Style')
|
||||
stylename = ElementTree.Element('Name')
|
||||
stylename.text = extrastyle
|
||||
styletitle = ElementTree.Element('Title')
|
||||
styletitle.text = extrastyle
|
||||
style.append(stylename)
|
||||
style.append(styletitle)
|
||||
layere.append(style)
|
||||
rootlayerelem.append(layere)
|
||||
self.capabilities = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + ElementTree.tostring(capetree)
|
||||
response = Response('application/vnd.ogc.wms_xml', self.capabilities)
|
||||
return response
|
||||
|
||||
def GetMap(self, params):
|
||||
params['crs'] = params['srs']
|
||||
return WMSBaseServiceHandler.GetMap(self, params)
|
||||
|
||||
def GetFeatureInfo(self, params):
|
||||
params['crs'] = params['srs']
|
||||
params['i'] = params['x']
|
||||
params['j'] = params['y']
|
||||
return WMSBaseServiceHandler.GetFeatureInfo(self, params, 'query_map_point')
|
||||
|
||||
class ExceptionHandler(BaseExceptionHandler):
|
||||
|
||||
xmlmimetype = "application/vnd.ogc.se_xml"
|
||||
|
||||
xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE ServiceExceptionReport SYSTEM "http://www.digitalearth.gov/wmt/xml/exception_1_1_1.dtd">
|
||||
<ServiceExceptionReport version="1.1.1">
|
||||
<ServiceException />
|
||||
</ServiceExceptionReport>
|
||||
""")
|
||||
|
||||
xpath = 'ServiceException'
|
||||
|
||||
handlers = {'application/vnd.ogc.se_xml': BaseExceptionHandler.xmlhandler,
|
||||
'application/vnd.ogc.se_inimage': BaseExceptionHandler.inimagehandler,
|
||||
'application/vnd.ogc.se_blank': BaseExceptionHandler.blankhandler,
|
||||
'text/html': BaseExceptionHandler.htmlhandler}
|
||||
|
||||
defaulthandler = 'application/vnd.ogc.se_xml'
|
|
@ -1,264 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""WMS 1.3.0 compliant GetCapabilities, GetMap, GetFeatureInfo, and Exceptions interface."""
|
||||
|
||||
from common import ParameterDefinition, Response, Version, ListFactory, \
|
||||
ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \
|
||||
BaseExceptionHandler, Projection, Box2d
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from mapnik2 import Coord
|
||||
|
||||
try:
|
||||
from lxml import etree as ElementTree
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
except ImportError:
|
||||
import elementtree.ElementTree as ElementTree
|
||||
|
||||
class ServiceHandler(WMSBaseServiceHandler):
|
||||
|
||||
SERVICE_PARAMS = {
|
||||
'GetCapabilities': {
|
||||
'format': ParameterDefinition(False, str, 'text/xml', ('text/xml',), True),
|
||||
'updatesequence': ParameterDefinition(False, str)
|
||||
},
|
||||
'GetMap': {
|
||||
'layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'styles': ParameterDefinition(True, ListFactory(str)),
|
||||
'crs': ParameterDefinition(True, CRSFactory(['EPSG'])),
|
||||
'bbox': ParameterDefinition(True, ListFactory(float)),
|
||||
'width': ParameterDefinition(True, int),
|
||||
'height': ParameterDefinition(True, int),
|
||||
'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')),
|
||||
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
|
||||
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
|
||||
'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK','HTML')),
|
||||
},
|
||||
'GetFeatureInfo': {
|
||||
'layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'styles': ParameterDefinition(False, ListFactory(str)),
|
||||
'crs': ParameterDefinition(True, CRSFactory(['EPSG'])),
|
||||
'bbox': ParameterDefinition(True, ListFactory(float)),
|
||||
'width': ParameterDefinition(True, int),
|
||||
'height': ParameterDefinition(True, int),
|
||||
'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')),
|
||||
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
|
||||
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
|
||||
'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK','HTML')),
|
||||
'query_layers': ParameterDefinition(True, ListFactory(str)),
|
||||
'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')),
|
||||
'feature_count': ParameterDefinition(False, int, 1),
|
||||
'i': ParameterDefinition(True, float),
|
||||
'j': ParameterDefinition(True, float)
|
||||
}
|
||||
}
|
||||
|
||||
CONF_SERVICE = [
|
||||
['title', 'Title', str],
|
||||
['abstract', 'Abstract', str],
|
||||
['onlineresource', 'OnlineResource', str],
|
||||
['fees', 'Fees', str],
|
||||
['accessconstraints', 'AccessConstraints', str],
|
||||
['layerlimit', 'LayerLimit', int],
|
||||
['maxwidth', 'MaxWidth', int],
|
||||
['maxheight', 'MaxHeight', int],
|
||||
['keywordlist', 'KeywordList', str]
|
||||
]
|
||||
|
||||
capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd">
|
||||
<Service>
|
||||
<Name>WMS</Name>
|
||||
</Service>
|
||||
<Capability>
|
||||
<Request>
|
||||
<GetCapabilities>
|
||||
<Format>text/xml</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetCapabilities>
|
||||
<GetMap>
|
||||
<Format>image/png</Format>
|
||||
<Format>image/jpeg</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetMap>
|
||||
<GetFeatureInfo>
|
||||
<Format>text/plain</Format>
|
||||
<DCPType>
|
||||
<HTTP>
|
||||
<Get>
|
||||
<OnlineResource xlink:type="simple"/>
|
||||
</Get>
|
||||
</HTTP>
|
||||
</DCPType>
|
||||
</GetFeatureInfo>
|
||||
</Request>
|
||||
<Exception>
|
||||
<Format>XML</Format>
|
||||
<Format>INIMAGE</Format>
|
||||
<Format>BLANK</Format>
|
||||
</Exception>
|
||||
<Layer>
|
||||
<Title>A Mapnik WMS Server</Title>
|
||||
<Abstract>A Mapnik WMS Server</Abstract>
|
||||
</Layer>
|
||||
</Capability>
|
||||
</WMS_Capabilities>
|
||||
"""
|
||||
|
||||
def __init__(self, conf, mapfactory, opsonlineresource):
|
||||
self.conf = conf
|
||||
self.mapfactory = mapfactory
|
||||
self.opsonlineresource = opsonlineresource
|
||||
if self.conf.has_option('service', 'allowedepsgcodes'):
|
||||
self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(','))
|
||||
else:
|
||||
raise ServerConfigurationError('Allowed EPSG codes not properly configured.')
|
||||
self.capabilities = None
|
||||
|
||||
def GetCapabilities(self, params):
|
||||
if not self.capabilities:
|
||||
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
|
||||
|
||||
elements = capetree.findall('{http://www.opengis.net/wms}Capability//{http://www.opengis.net/wms}OnlineResource')
|
||||
for element in elements:
|
||||
element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource)
|
||||
|
||||
self.processServiceCapabilities(capetree)
|
||||
|
||||
rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer')
|
||||
|
||||
for epsgcode in self.allowedepsgcodes:
|
||||
rootlayercrs = ElementTree.Element('CRS')
|
||||
rootlayercrs.text = epsgcode.upper()
|
||||
rootlayerelem.append(rootlayercrs)
|
||||
|
||||
for layer in self.mapfactory.ordered_layers:
|
||||
layerproj = Projection(layer.srs)
|
||||
layername = ElementTree.Element('Name')
|
||||
layername.text = layer.name
|
||||
env = layer.envelope()
|
||||
layerexgbb = ElementTree.Element('EX_GeographicBoundingBox')
|
||||
ll = layerproj.inverse(Coord(env.minx, env.miny))
|
||||
ur = layerproj.inverse(Coord(env.maxx, env.maxy))
|
||||
exgbb_wbl = ElementTree.Element('westBoundLongitude')
|
||||
exgbb_wbl.text = str(ll.x)
|
||||
layerexgbb.append(exgbb_wbl)
|
||||
exgbb_ebl = ElementTree.Element('eastBoundLongitude')
|
||||
exgbb_ebl.text = str(ur.x)
|
||||
layerexgbb.append(exgbb_ebl)
|
||||
exgbb_sbl = ElementTree.Element('southBoundLatitude')
|
||||
exgbb_sbl.text = str(ll.y)
|
||||
layerexgbb.append(exgbb_sbl)
|
||||
exgbb_nbl = ElementTree.Element('northBoundLatitude')
|
||||
exgbb_nbl.text = str(ur.y)
|
||||
layerexgbb.append(exgbb_nbl)
|
||||
layerbbox = ElementTree.Element('BoundingBox')
|
||||
layerbbox.set('CRS', layerproj.epsgstring())
|
||||
layerbbox.set('minx', str(env.minx))
|
||||
layerbbox.set('miny', str(env.miny))
|
||||
layerbbox.set('maxx', str(env.maxx))
|
||||
layerbbox.set('maxy', str(env.maxy))
|
||||
layere = ElementTree.Element('Layer')
|
||||
layere.append(layername)
|
||||
if layer.title:
|
||||
layertitle = ElementTree.Element('Title')
|
||||
layertitle.text = layer.title
|
||||
layere.append(layertitle)
|
||||
if layer.abstract:
|
||||
layerabstract = ElementTree.Element('Abstract')
|
||||
layerabstract.text = layer.abstract
|
||||
layere.append(layerabstract)
|
||||
if layer.queryable:
|
||||
layere.set('queryable', '1')
|
||||
layere.append(layerexgbb)
|
||||
layere.append(layerbbox)
|
||||
if len(layer.wmsextrastyles) > 0:
|
||||
for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles):
|
||||
style = ElementTree.Element('Style')
|
||||
stylename = ElementTree.Element('Name')
|
||||
stylename.text = extrastyle
|
||||
styletitle = ElementTree.Element('Title')
|
||||
styletitle.text = extrastyle
|
||||
style.append(stylename)
|
||||
style.append(styletitle)
|
||||
layere.append(style)
|
||||
rootlayerelem.append(layere)
|
||||
self.capabilities = '<?xml version="1.0" encoding="UTF-8"?>' + ElementTree.tostring(capetree)
|
||||
response = Response('text/xml', self.capabilities)
|
||||
return response
|
||||
|
||||
def GetMap(self, params):
|
||||
if params['width'] > int(self.conf.get('service', 'maxwidth')) or params['height'] > int(self.conf.get('service', 'maxheight')):
|
||||
raise OGCException('Requested map size exceeds limits set by this server.')
|
||||
return WMSBaseServiceHandler.GetMap(self, params)
|
||||
|
||||
def _buildMap(self, params):
|
||||
""" Override _buildMap method to handle reverse axis ordering in WMS 1.3.0.
|
||||
|
||||
More info: http://mapserver.org/development/rfc/ms-rfc-30.html
|
||||
|
||||
'when using epsg code >=4000 and <5000 will be assumed to have a reversed axes.'
|
||||
|
||||
"""
|
||||
# Call superclass method
|
||||
m = WMSBaseServiceHandler._buildMap(self, params)
|
||||
# for range of epsg codes reverse axis
|
||||
if params['crs'].code >= 4000 and params['crs'].code < 5000:
|
||||
m.zoom_to_box(Box2d(params['bbox'][1], params['bbox'][0], params['bbox'][3], params['bbox'][2]))
|
||||
return m
|
||||
|
||||
class ExceptionHandler(BaseExceptionHandler):
|
||||
|
||||
xmlmimetype = "text/xml"
|
||||
|
||||
xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8"?>
|
||||
<ServiceExceptionReport version="1.3.0"
|
||||
xmlns="http://www.opengis.net/ogc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
|
||||
<ServiceException/>
|
||||
</ServiceExceptionReport>
|
||||
""")
|
||||
|
||||
xpath = '{http://www.opengis.net/ogc}ServiceException'
|
||||
|
||||
handlers = {'XML': BaseExceptionHandler.xmlhandler,
|
||||
'INIMAGE': BaseExceptionHandler.inimagehandler,
|
||||
'BLANK': BaseExceptionHandler.blankhandler,
|
||||
'HTML': BaseExceptionHandler.htmlhandler}
|
||||
|
||||
defaulthandler = 'XML'
|
|
@ -1,106 +0,0 @@
|
|||
#
|
||||
# This file is part of Mapnik (c++ mapping toolkit)
|
||||
#
|
||||
# Copyright (C) 2006 Jean-Francois Doyon
|
||||
#
|
||||
# Mapnik is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
"""WSGI application wrapper for Mapnik OGC WMS Server."""
|
||||
|
||||
from exceptions import OGCException, ServerConfigurationError
|
||||
from configparser import SafeConfigParser
|
||||
from cgi import parse_qs
|
||||
from wms111 import ExceptionHandler as ExceptionHandler111
|
||||
from wms130 import ExceptionHandler as ExceptionHandler130
|
||||
from common import Version
|
||||
|
||||
class WSGIApp:
|
||||
|
||||
def __init__(self, configpath):
|
||||
conf = SafeConfigParser()
|
||||
conf.readfp(open(configpath))
|
||||
self.conf = conf
|
||||
if not conf.has_option_with_value('server', 'module'):
|
||||
raise ServerConfigurationError('The factory module is not defined in the configuration file.')
|
||||
try:
|
||||
mapfactorymodule = __import__(conf.get('server', 'module'))
|
||||
except ImportError:
|
||||
raise ServerConfigurationError('The factory module could not be loaded.')
|
||||
if hasattr(mapfactorymodule, 'WMSFactory'):
|
||||
self.mapfactory = getattr(mapfactorymodule, 'WMSFactory')()
|
||||
else:
|
||||
raise ServerConfigurationError('The factory module does not have a WMSFactory class.')
|
||||
if conf.has_option('server', 'debug'):
|
||||
self.debug = int(conf.get('server', 'debug'))
|
||||
else:
|
||||
self.debug = 0
|
||||
if self.conf.has_option_with_value('server', 'maxage'):
|
||||
self.max_age = 'max-age=%d' % self.conf.get('server', 'maxage')
|
||||
else:
|
||||
self.max_age = None
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
reqparams = {}
|
||||
for key, value in parse_qs(environ['QUERY_STRING'], True).items():
|
||||
reqparams[key.lower()] = value[0]
|
||||
onlineresource = 'http://%s:%s%s?' % (environ['SERVER_NAME'], environ['SERVER_PORT'], environ['PATH_INFO'])
|
||||
try:
|
||||
if not reqparams.has_key('request'):
|
||||
raise OGCException('Missing request parameter.')
|
||||
request = reqparams['request']
|
||||
del reqparams['request']
|
||||
if request == 'GetCapabilities' and not reqparams.has_key('service'):
|
||||
raise OGCException('Missing service parameter.')
|
||||
if request in ['GetMap', 'GetFeatureInfo']:
|
||||
service = 'WMS'
|
||||
else:
|
||||
service = reqparams['service']
|
||||
if reqparams.has_key('service'):
|
||||
del reqparams['service']
|
||||
try:
|
||||
mapnikmodule = __import__('mapnik2.ogcserver.' + service)
|
||||
except:
|
||||
raise OGCException('Unsupported service "%s".' % service)
|
||||
ServiceHandlerFactory = getattr(mapnikmodule.ogcserver, service).ServiceHandlerFactory
|
||||
servicehandler = ServiceHandlerFactory(self.conf, self.mapfactory, onlineresource, reqparams.get('version', None))
|
||||
if reqparams.has_key('version'):
|
||||
del reqparams['version']
|
||||
if request not in servicehandler.SERVICE_PARAMS.keys():
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
ogcparams = servicehandler.processParameters(request, reqparams)
|
||||
try:
|
||||
requesthandler = getattr(servicehandler, request)
|
||||
except:
|
||||
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
|
||||
response = requesthandler(ogcparams)
|
||||
except:
|
||||
version = reqparams.get('version', None)
|
||||
if not version:
|
||||
version = Version('1.3.0')
|
||||
else:
|
||||
version = Version(version)
|
||||
if version >= '1.3.0':
|
||||
eh = ExceptionHandler130(self.debug)
|
||||
else:
|
||||
eh = ExceptionHandler111(self.debug)
|
||||
response = eh.getresponse(reqparams)
|
||||
response_headers = [('Content-Type', response.content_type),('Content-Length', str(len(response.content)))]
|
||||
if self.max_age:
|
||||
response_headers.append(('Cache-Control', max_age))
|
||||
start_response('200 OK', response_headers)
|
||||
yield response.content
|
||||
|
|
@ -4,17 +4,18 @@
|
|||
|
||||
basic usage is along the lines of
|
||||
|
||||
import mapnik2
|
||||
import mapnik
|
||||
|
||||
page = mapnik2.printing.PDFPrinter()
|
||||
m = mapnik2.Map(100,100)
|
||||
mapnik2.load_map(m, "my_xml_map_description", True)
|
||||
page = mapnik.printing.PDFPrinter()
|
||||
m = mapnik.Map(100,100)
|
||||
mapnik.load_map(m, "my_xml_map_description", True)
|
||||
m.zoom_all()
|
||||
page.render_map(m,"my_output_file.pdf")
|
||||
|
||||
see the documentation of mapnik2.printing.PDFPrinter() for options
|
||||
see the documentation of mapnik.printing.PDFPrinter() for options
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from . import render, Map, Box2d, MemoryDatasource, Layer, Feature, Projection, ProjTransform, Coord, Style, Rule, Geometry2d
|
||||
import math
|
||||
|
|
27
bindings/python/mapnik2/__init__.py
Normal file
27
bindings/python/mapnik2/__init__.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# This file is part of Mapnik (C++/Python mapping toolkit)
|
||||
# Copyright (C) 2011 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.
|
||||
#
|
||||
|
||||
# mapnik2 module (Deprecated)
|
||||
|
||||
import warnings
|
||||
from mapnik import *
|
||||
warnings.simplefilter("default")
|
||||
msg=""" mapnik2 module has been deprecated,
|
||||
please use 'import mapnik' """
|
||||
warnings.warn(msg, DeprecationWarning)
|
|
@ -75,11 +75,11 @@ void export_featureset()
|
|||
"\n"
|
||||
"Usage:\n"
|
||||
">>> m.query_map_point(0, 10, 10)\n"
|
||||
"<mapnik2._mapnik2.Featureset object at 0x1004d2938>\n"
|
||||
"<mapnik._mapnik.Featureset object at 0x1004d2938>\n"
|
||||
">>> fs = m.query_map_point(0, 10, 10)\n"
|
||||
">>> for f in fs.features:\n"
|
||||
">>> print f\n"
|
||||
"<mapnik2.Feature object at 0x105e64140>\n"
|
||||
"<mapnik.Feature object at 0x105e64140>\n"
|
||||
)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite
|
|||
static boost::python::tuple
|
||||
getstate(markers_symbolizer const& p)
|
||||
{
|
||||
return boost::python::make_tuple(p.get_allow_overlap());//,p.get_opacity());
|
||||
return boost::python::make_tuple(p.get_allow_overlap(),
|
||||
p.get_ignore_placement());//,p.get_opacity());
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -77,8 +78,7 @@ struct markers_symbolizer_pickle_suite : boost::python::pickle_suite
|
|||
}
|
||||
|
||||
p.set_allow_overlap(extract<bool>(state[0]));
|
||||
//p.set_opacity(extract<float>(state[1]));
|
||||
|
||||
p.set_ignore_placement(extract<bool>(state[1]));
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -108,8 +108,19 @@ void export_markers_symbolizer()
|
|||
&markers_symbolizer::get_opacity,
|
||||
&markers_symbolizer::set_opacity,
|
||||
"Set/get the text opacity")
|
||||
.add_property("ignore_placement",
|
||||
&markers_symbolizer::get_ignore_placement,
|
||||
&markers_symbolizer::set_ignore_placement)
|
||||
.add_property("transform",
|
||||
&mapnik::get_svg_transform<markers_symbolizer>,
|
||||
&mapnik::set_svg_transform<markers_symbolizer>)
|
||||
.add_property("width",
|
||||
&markers_symbolizer::get_width,
|
||||
&markers_symbolizer::set_width,
|
||||
"Set/get the marker width")
|
||||
.add_property("height",
|
||||
&markers_symbolizer::get_height,
|
||||
&markers_symbolizer::set_height,
|
||||
"Set/get the marker height")
|
||||
;
|
||||
}
|
||||
|
|
|
@ -319,13 +319,9 @@ unsigned mapnik_version()
|
|||
return MAPNIK_VERSION;
|
||||
}
|
||||
|
||||
unsigned mapnik_svn_revision()
|
||||
std::string mapnik_version_string()
|
||||
{
|
||||
#if defined(SVN_REVISION)
|
||||
return SVN_REVISION;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
return MAPNIK_VERSION_STRING;
|
||||
}
|
||||
|
||||
// indicator for jpeg read/write support within libmapnik
|
||||
|
@ -375,7 +371,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3)
|
|||
BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2)
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5)
|
||||
|
||||
BOOST_PYTHON_MODULE(_mapnik2)
|
||||
BOOST_PYTHON_MODULE(_mapnik)
|
||||
{
|
||||
|
||||
using namespace boost::python;
|
||||
|
@ -606,7 +602,7 @@ BOOST_PYTHON_MODULE(_mapnik2)
|
|||
|
||||
def("save_map_to_string", &save_map_to_string, save_map_to_string_overloads());
|
||||
def("mapnik_version", &mapnik_version,"Get the Mapnik version number");
|
||||
def("mapnik_svn_revision", &mapnik_svn_revision,"Get the Mapnik svn revision");
|
||||
def("mapnik_version_string", &mapnik_version_string,"Get the Mapnik version string");
|
||||
def("has_jpeg", &has_jpeg, "Get jpeg read/write support status");
|
||||
def("has_cairo", &has_cairo, "Get cairo library status");
|
||||
def("has_pycairo", &has_pycairo, "Get pycairo module status");
|
||||
|
|
|
@ -110,7 +110,7 @@ void export_raster_colorizer()
|
|||
"\n"
|
||||
"Usage:\n"
|
||||
">>> default_color = mapnik.Color(\"#0044cc\")\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik2.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer.add_stop(100)\n"
|
||||
)
|
||||
.def("add_stop", add_stop3,
|
||||
|
@ -119,7 +119,7 @@ void export_raster_colorizer()
|
|||
"\n"
|
||||
"Usage:\n"
|
||||
">>> default_color = mapnik.Color(\"#0044cc\")\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik2.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer.add_stop(100, mapnik.Color(\"#123456\"))\n"
|
||||
)
|
||||
.def("add_stop", add_stop4,
|
||||
|
@ -128,8 +128,8 @@ void export_raster_colorizer()
|
|||
"\n"
|
||||
"Usage:\n"
|
||||
">>> default_color = mapnik.Color(\"#0044cc\")\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik2.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer.add_stop(100, mapnik2.COLORIZER_EXACT)\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer.add_stop(100, mapnik.COLORIZER_EXACT)\n"
|
||||
)
|
||||
.def("add_stop", add_stop5,
|
||||
(arg("value")),
|
||||
|
@ -137,7 +137,7 @@ void export_raster_colorizer()
|
|||
"\n"
|
||||
"Usage:\n"
|
||||
">>> default_color = mapnik.Color(\"#0044cc\")\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik2.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_LINEAR, default_color)\n"
|
||||
">>> colorizer.add_stop(100, mapnik.COLORIZER_DISCRETE, mapnik.Color(\"#112233\"))\n"
|
||||
)
|
||||
.def("get_color", &raster_colorizer::get_color,
|
||||
|
@ -146,8 +146,8 @@ void export_raster_colorizer()
|
|||
"Usage:\n"
|
||||
">>> colorizer = mapnik.RasterColorizer()\n"
|
||||
">>> color = mapnik.Color(\"#0044cc\")\n"
|
||||
">>> colorizer.add_stop(0, mapnik2.COLORIZER_DISCRETE, mapnik.Color(\"#000000\"))\n"
|
||||
">>> colorizer.add_stop(100, mapnik2.COLORIZER_DISCRETE, mapnik.Color(\"#0E0A06\"))\n"
|
||||
">>> colorizer.add_stop(0, mapnik.COLORIZER_DISCRETE, mapnik.Color(\"#000000\"))\n"
|
||||
">>> colorizer.add_stop(100, mapnik.COLORIZER_DISCRETE, mapnik.Color(\"#0E0A06\"))\n"
|
||||
">>> colorizer.get_color(50)\n"
|
||||
"Color('#070503')\n"
|
||||
)
|
||||
|
|
|
@ -95,8 +95,8 @@ void export_style()
|
|||
"Usage:\n"
|
||||
">>> for r in m.find_style('style 1').rules:\n"
|
||||
">>> print r\n"
|
||||
"<mapnik2._mapnik2.Rule object at 0x100549910>\n"
|
||||
"<mapnik2._mapnik2.Rule object at 0x100549980>\n"
|
||||
"<mapnik._mapnik.Rule object at 0x100549910>\n"
|
||||
"<mapnik._mapnik.Rule object at 0x100549980>\n"
|
||||
)
|
||||
.add_property("filter_mode",
|
||||
&feature_type_style::get_filter_mode,
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace boost { namespace python {
|
|||
|
||||
PyObject * operator() (mapnik::value_null const& /*s*/) const
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ if env['HAS_CAIRO']:
|
|||
|
||||
libraries = copy(env['LIBMAPNIK_LIBS'])
|
||||
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
|
||||
libraries.extend([boost_program_options,'mapnik2'])
|
||||
libraries.extend([boost_program_options,'mapnik'])
|
||||
|
||||
rundemo = demo_env.Program('rundemo', source, LIBS=libraries, LINKFLAGS=env["CUSTOM_LDFLAGS"])
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ int main ( int argc , char** argv)
|
|||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cout << "usage: ./rundemo <mapnik_install_dir>\nUsually /usr/local/lib/mapnik2\n";
|
||||
std::cout << "usage: ./rundemo <mapnik_install_dir>\nUsually /usr/local/lib/mapnik\n";
|
||||
std::cout << "Warning: ./rundemo looks for data in ../data/,\nTherefore must be run from within the demo/c++ folder.\n";
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
import sys
|
||||
|
||||
try:
|
||||
import mapnik2
|
||||
import mapnik
|
||||
except:
|
||||
print '\n\nThe mapnik library and python bindings must have been compiled and \
|
||||
installed successfully before running this script.\n\n'
|
||||
|
@ -41,11 +41,11 @@ except ImportError:
|
|||
# Instanciate a map, giving it a width and height. Remember: the word "map" is
|
||||
# reserved in Python! :)
|
||||
|
||||
m = mapnik2.Map(800,600,"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs")
|
||||
m = mapnik.Map(800,600,"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs")
|
||||
|
||||
# Set its background colour. More on colours later ...
|
||||
|
||||
m.background = mapnik2.Color('white')
|
||||
m.background = mapnik.Color('white')
|
||||
|
||||
# Now we can start adding layers, in stacking order (i.e. bottom layer first)
|
||||
|
||||
|
@ -66,9 +66,9 @@ m.background = mapnik2.Color('white')
|
|||
# password='mypassword'
|
||||
# table= TODO
|
||||
|
||||
provpoly_lyr = mapnik2.Layer('Provinces')
|
||||
provpoly_lyr = mapnik.Layer('Provinces')
|
||||
provpoly_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
provpoly_lyr.datasource = mapnik2.Shapefile(file='../data/boundaries', encoding='latin1')
|
||||
provpoly_lyr.datasource = mapnik.Shapefile(file='../data/boundaries', encoding='latin1')
|
||||
|
||||
# We then define a style for the layer. A layer can have one or many styles.
|
||||
# Styles are named, so they can be shared across different layers.
|
||||
|
@ -78,18 +78,18 @@ provpoly_lyr.datasource = mapnik2.Shapefile(file='../data/boundaries', encoding=
|
|||
# multiple styles in one layer is the same has having multiple layers.
|
||||
# The paradigm is useful mostly as a convenience.
|
||||
|
||||
provpoly_style = mapnik2.Style()
|
||||
provpoly_style = mapnik.Style()
|
||||
|
||||
# A Style needs one or more rules. A rule will normally consist of a filter
|
||||
# for feature selection, and one or more symbolizers.
|
||||
|
||||
provpoly_rule_on = mapnik2.Rule()
|
||||
provpoly_rule_on = mapnik.Rule()
|
||||
|
||||
# A Expression() allows the selection of features to which the symbology will
|
||||
# be applied. More on Mapnik expressions can be found in Tutorial #2.
|
||||
# A given feature can only match one filter per rule per style.
|
||||
|
||||
provpoly_rule_on.filter = mapnik2.Expression("[NAME_EN] = 'Ontario'")
|
||||
provpoly_rule_on.filter = mapnik.Expression("[NAME_EN] = 'Ontario'")
|
||||
|
||||
# Here a symbolizer is defined. Available are:
|
||||
# - LineSymbolizer(Color(),<width>)
|
||||
|
@ -103,12 +103,12 @@ provpoly_rule_on.filter = mapnik2.Expression("[NAME_EN] = 'Ontario'")
|
|||
# - Color(<string>) where <string> will be something like '#00FF00'
|
||||
# or '#0f0' or 'green'
|
||||
|
||||
provpoly_rule_on.symbols.append(mapnik2.PolygonSymbolizer(mapnik2.Color(250, 190, 183)))
|
||||
provpoly_rule_on.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(250, 190, 183)))
|
||||
provpoly_style.rules.append(provpoly_rule_on)
|
||||
|
||||
provpoly_rule_qc = mapnik2.Rule()
|
||||
provpoly_rule_qc.filter = mapnik2.Expression("[NOM_FR] = 'Québec'")
|
||||
provpoly_rule_qc.symbols.append(mapnik2.PolygonSymbolizer(mapnik2.Color(217, 235, 203)))
|
||||
provpoly_rule_qc = mapnik.Rule()
|
||||
provpoly_rule_qc.filter = mapnik.Expression("[NOM_FR] = 'Québec'")
|
||||
provpoly_rule_qc.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(217, 235, 203)))
|
||||
provpoly_style.rules.append(provpoly_rule_qc)
|
||||
|
||||
# Add the style to the map, giving it a name. This is the name that will be
|
||||
|
@ -131,14 +131,14 @@ m.layers.append(provpoly_lyr)
|
|||
|
||||
# A simple example ...
|
||||
|
||||
qcdrain_lyr = mapnik2.Layer('Quebec Hydrography')
|
||||
qcdrain_lyr = mapnik.Layer('Quebec Hydrography')
|
||||
qcdrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
qcdrain_lyr.datasource = mapnik2.Shapefile(file='../data/qcdrainage')
|
||||
qcdrain_lyr.datasource = mapnik.Shapefile(file='../data/qcdrainage')
|
||||
|
||||
qcdrain_style = mapnik2.Style()
|
||||
qcdrain_rule = mapnik2.Rule()
|
||||
qcdrain_rule.filter = mapnik2.Expression('[HYC] = 8')
|
||||
qcdrain_rule.symbols.append(mapnik2.PolygonSymbolizer(mapnik2.Color(153, 204, 255)))
|
||||
qcdrain_style = mapnik.Style()
|
||||
qcdrain_rule = mapnik.Rule()
|
||||
qcdrain_rule.filter = mapnik.Expression('[HYC] = 8')
|
||||
qcdrain_rule.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color(153, 204, 255)))
|
||||
qcdrain_style.rules.append(qcdrain_rule)
|
||||
|
||||
m.append_style('drainage', qcdrain_style)
|
||||
|
@ -149,31 +149,31 @@ m.layers.append(qcdrain_lyr)
|
|||
# attributes, and same desired style), so we're going to
|
||||
# re-use the style defined in the above layer for the next one.
|
||||
|
||||
ondrain_lyr = mapnik2.Layer('Ontario Hydrography')
|
||||
ondrain_lyr = mapnik.Layer('Ontario Hydrography')
|
||||
ondrain_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
ondrain_lyr.datasource = mapnik2.Shapefile(file='../data/ontdrainage')
|
||||
ondrain_lyr.datasource = mapnik.Shapefile(file='../data/ontdrainage')
|
||||
|
||||
ondrain_lyr.styles.append('drainage')
|
||||
m.layers.append(ondrain_lyr)
|
||||
|
||||
# Provincial boundaries
|
||||
|
||||
provlines_lyr = mapnik2.Layer('Provincial borders')
|
||||
provlines_lyr = mapnik.Layer('Provincial borders')
|
||||
provlines_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
provlines_lyr.datasource = mapnik2.Shapefile(file='../data/boundaries_l')
|
||||
provlines_lyr.datasource = mapnik.Shapefile(file='../data/boundaries_l')
|
||||
|
||||
# Here we define a "dash dot dot dash" pattern for the provincial boundaries.
|
||||
|
||||
provlines_stk = mapnik2.Stroke()
|
||||
provlines_stk = mapnik.Stroke()
|
||||
provlines_stk.add_dash(8, 4)
|
||||
provlines_stk.add_dash(2, 2)
|
||||
provlines_stk.add_dash(2, 2)
|
||||
provlines_stk.color = mapnik2.Color('black')
|
||||
provlines_stk.color = mapnik.Color('black')
|
||||
provlines_stk.width = 1.0
|
||||
|
||||
provlines_style = mapnik2.Style()
|
||||
provlines_rule = mapnik2.Rule()
|
||||
provlines_rule.symbols.append(mapnik2.LineSymbolizer(provlines_stk))
|
||||
provlines_style = mapnik.Style()
|
||||
provlines_rule = mapnik.Rule()
|
||||
provlines_rule.symbols.append(mapnik.LineSymbolizer(provlines_stk))
|
||||
provlines_style.rules.append(provlines_rule)
|
||||
|
||||
m.append_style('provlines', provlines_style)
|
||||
|
@ -182,22 +182,22 @@ m.layers.append(provlines_lyr)
|
|||
|
||||
# Roads 3 and 4 (The "grey" roads)
|
||||
|
||||
roads34_lyr = mapnik2.Layer('Roads')
|
||||
roads34_lyr = mapnik.Layer('Roads')
|
||||
roads34_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
# create roads datasource (we're going to re-use it later)
|
||||
|
||||
roads34_lyr.datasource = mapnik2.Shapefile(file='../data/roads')
|
||||
roads34_lyr.datasource = mapnik.Shapefile(file='../data/roads')
|
||||
|
||||
roads34_style = mapnik2.Style()
|
||||
roads34_rule = mapnik2.Rule()
|
||||
roads34_rule.filter = mapnik2.Expression('([CLASS] = 3) or ([CLASS] = 4)')
|
||||
roads34_style = mapnik.Style()
|
||||
roads34_rule = mapnik.Rule()
|
||||
roads34_rule.filter = mapnik.Expression('([CLASS] = 3) or ([CLASS] = 4)')
|
||||
|
||||
# With lines of a certain width, you can control how the ends
|
||||
# are closed off using line_cap as below.
|
||||
|
||||
roads34_rule_stk = mapnik2.Stroke()
|
||||
roads34_rule_stk.color = mapnik2.Color(171,158,137)
|
||||
roads34_rule_stk.line_cap = mapnik2.line_cap.ROUND_CAP
|
||||
roads34_rule_stk = mapnik.Stroke()
|
||||
roads34_rule_stk.color = mapnik.Color(171,158,137)
|
||||
roads34_rule_stk.line_cap = mapnik.line_cap.ROUND_CAP
|
||||
|
||||
# Available options are:
|
||||
# line_cap: BUTT_CAP, SQUARE_CAP, ROUND_CAP
|
||||
|
@ -207,7 +207,7 @@ roads34_rule_stk.line_cap = mapnik2.line_cap.ROUND_CAP
|
|||
# can be set to a numerical value.
|
||||
|
||||
roads34_rule_stk.width = 2.0
|
||||
roads34_rule.symbols.append(mapnik2.LineSymbolizer(roads34_rule_stk))
|
||||
roads34_rule.symbols.append(mapnik.LineSymbolizer(roads34_rule_stk))
|
||||
roads34_style.rules.append(roads34_rule)
|
||||
|
||||
m.append_style('smallroads', roads34_style)
|
||||
|
@ -216,31 +216,31 @@ m.layers.append(roads34_lyr)
|
|||
|
||||
# Roads 2 (The thin yellow ones)
|
||||
|
||||
roads2_lyr = mapnik2.Layer('Roads')
|
||||
roads2_lyr = mapnik.Layer('Roads')
|
||||
roads2_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
# Just get a copy from roads34_lyr
|
||||
roads2_lyr.datasource = roads34_lyr.datasource
|
||||
|
||||
roads2_style_1 = mapnik2.Style()
|
||||
roads2_rule_1 = mapnik2.Rule()
|
||||
roads2_rule_1.filter = mapnik2.Expression('[CLASS] = 2')
|
||||
roads2_rule_stk_1 = mapnik2.Stroke()
|
||||
roads2_rule_stk_1.color = mapnik2.Color(171,158,137)
|
||||
roads2_rule_stk_1.line_cap = mapnik2.line_cap.ROUND_CAP
|
||||
roads2_style_1 = mapnik.Style()
|
||||
roads2_rule_1 = mapnik.Rule()
|
||||
roads2_rule_1.filter = mapnik.Expression('[CLASS] = 2')
|
||||
roads2_rule_stk_1 = mapnik.Stroke()
|
||||
roads2_rule_stk_1.color = mapnik.Color(171,158,137)
|
||||
roads2_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
||||
roads2_rule_stk_1.width = 4.0
|
||||
roads2_rule_1.symbols.append(mapnik2.LineSymbolizer(roads2_rule_stk_1))
|
||||
roads2_rule_1.symbols.append(mapnik.LineSymbolizer(roads2_rule_stk_1))
|
||||
roads2_style_1.rules.append(roads2_rule_1)
|
||||
|
||||
m.append_style('road-border', roads2_style_1)
|
||||
|
||||
roads2_style_2 = mapnik2.Style()
|
||||
roads2_rule_2 = mapnik2.Rule()
|
||||
roads2_rule_2.filter = mapnik2.Expression('[CLASS] = 2')
|
||||
roads2_rule_stk_2 = mapnik2.Stroke()
|
||||
roads2_rule_stk_2.color = mapnik2.Color(255,250,115)
|
||||
roads2_rule_stk_2.line_cap = mapnik2.line_cap.ROUND_CAP
|
||||
roads2_style_2 = mapnik.Style()
|
||||
roads2_rule_2 = mapnik.Rule()
|
||||
roads2_rule_2.filter = mapnik.Expression('[CLASS] = 2')
|
||||
roads2_rule_stk_2 = mapnik.Stroke()
|
||||
roads2_rule_stk_2.color = mapnik.Color(255,250,115)
|
||||
roads2_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
||||
roads2_rule_stk_2.width = 2.0
|
||||
roads2_rule_2.symbols.append(mapnik2.LineSymbolizer(roads2_rule_stk_2))
|
||||
roads2_rule_2.symbols.append(mapnik.LineSymbolizer(roads2_rule_stk_2))
|
||||
roads2_style_2.rules.append(roads2_rule_2)
|
||||
|
||||
m.append_style('road-fill', roads2_style_2)
|
||||
|
@ -252,29 +252,29 @@ m.layers.append(roads2_lyr)
|
|||
|
||||
# Roads 1 (The big orange ones, the highways)
|
||||
|
||||
roads1_lyr = mapnik2.Layer('Roads')
|
||||
roads1_lyr = mapnik.Layer('Roads')
|
||||
roads1_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
roads1_lyr.datasource = roads34_lyr.datasource
|
||||
|
||||
roads1_style_1 = mapnik2.Style()
|
||||
roads1_rule_1 = mapnik2.Rule()
|
||||
roads1_rule_1.filter = mapnik2.Expression('[CLASS] = 1')
|
||||
roads1_rule_stk_1 = mapnik2.Stroke()
|
||||
roads1_rule_stk_1.color = mapnik2.Color(188,149,28)
|
||||
roads1_rule_stk_1.line_cap = mapnik2.line_cap.ROUND_CAP
|
||||
roads1_style_1 = mapnik.Style()
|
||||
roads1_rule_1 = mapnik.Rule()
|
||||
roads1_rule_1.filter = mapnik.Expression('[CLASS] = 1')
|
||||
roads1_rule_stk_1 = mapnik.Stroke()
|
||||
roads1_rule_stk_1.color = mapnik.Color(188,149,28)
|
||||
roads1_rule_stk_1.line_cap = mapnik.line_cap.ROUND_CAP
|
||||
roads1_rule_stk_1.width = 7.0
|
||||
roads1_rule_1.symbols.append(mapnik2.LineSymbolizer(roads1_rule_stk_1))
|
||||
roads1_rule_1.symbols.append(mapnik.LineSymbolizer(roads1_rule_stk_1))
|
||||
roads1_style_1.rules.append(roads1_rule_1)
|
||||
m.append_style('highway-border', roads1_style_1)
|
||||
|
||||
roads1_style_2 = mapnik2.Style()
|
||||
roads1_rule_2 = mapnik2.Rule()
|
||||
roads1_rule_2.filter = mapnik2.Expression('[CLASS] = 1')
|
||||
roads1_rule_stk_2 = mapnik2.Stroke()
|
||||
roads1_rule_stk_2.color = mapnik2.Color(242,191,36)
|
||||
roads1_rule_stk_2.line_cap = mapnik2.line_cap.ROUND_CAP
|
||||
roads1_style_2 = mapnik.Style()
|
||||
roads1_rule_2 = mapnik.Rule()
|
||||
roads1_rule_2.filter = mapnik.Expression('[CLASS] = 1')
|
||||
roads1_rule_stk_2 = mapnik.Stroke()
|
||||
roads1_rule_stk_2.color = mapnik.Color(242,191,36)
|
||||
roads1_rule_stk_2.line_cap = mapnik.line_cap.ROUND_CAP
|
||||
roads1_rule_stk_2.width = 5.0
|
||||
roads1_rule_2.symbols.append(mapnik2.LineSymbolizer(roads1_rule_stk_2))
|
||||
roads1_rule_2.symbols.append(mapnik.LineSymbolizer(roads1_rule_stk_2))
|
||||
roads1_style_2.rules.append(roads1_rule_2)
|
||||
|
||||
m.append_style('highway-fill', roads1_style_2)
|
||||
|
@ -286,25 +286,25 @@ m.layers.append(roads1_lyr)
|
|||
|
||||
# Populated Places
|
||||
|
||||
popplaces_lyr = mapnik2.Layer('Populated Places')
|
||||
popplaces_lyr = mapnik.Layer('Populated Places')
|
||||
popplaces_lyr.srs = "+proj=lcc +ellps=GRS80 +lat_0=49 +lon_0=-95 +lat+1=49 +lat_2=77 +datum=NAD83 +units=m +no_defs"
|
||||
popplaces_lyr.datasource = mapnik2.Shapefile(file='../data/popplaces',encoding='latin1')
|
||||
popplaces_lyr.datasource = mapnik.Shapefile(file='../data/popplaces',encoding='latin1')
|
||||
|
||||
popplaces_style = mapnik2.Style()
|
||||
popplaces_rule = mapnik2.Rule()
|
||||
popplaces_style = mapnik.Style()
|
||||
popplaces_rule = mapnik.Rule()
|
||||
|
||||
# And here we have a TextSymbolizer, used for labeling.
|
||||
# The first parameter is the name of the attribute to use as the source of the
|
||||
# text to label with. Then there is font size in points (I think?), and colour.
|
||||
|
||||
popplaces_text_symbolizer = mapnik2.TextSymbolizer(mapnik2.Expression("[GEONAME]"),
|
||||
popplaces_text_symbolizer = mapnik.TextSymbolizer(mapnik.Expression("[GEONAME]"),
|
||||
'DejaVu Sans Book',
|
||||
10, mapnik2.Color('black'))
|
||||
10, mapnik.Color('black'))
|
||||
|
||||
# We set a "halo" around the text, which looks like an outline if thin enough,
|
||||
# or an outright background if large enough.
|
||||
popplaces_text_symbolizer.label_placement= mapnik2.label_placement.POINT_PLACEMENT
|
||||
popplaces_text_symbolizer.halo_fill = mapnik2.Color('white')
|
||||
popplaces_text_symbolizer.label_placement= mapnik.label_placement.POINT_PLACEMENT
|
||||
popplaces_text_symbolizer.halo_fill = mapnik.Color('white')
|
||||
popplaces_text_symbolizer.halo_radius = 1
|
||||
popplaces_text_symbolizer.avoid_edges = True
|
||||
#popplaces_text_symbolizer.minimum_padding = 30
|
||||
|
@ -320,11 +320,11 @@ m.layers.append(popplaces_lyr)
|
|||
# Draw map
|
||||
|
||||
# Set the initial extent of the map in 'master' spherical Mercator projection
|
||||
m.zoom_to_box(mapnik2.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855))
|
||||
m.zoom_to_box(mapnik.Box2d(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855))
|
||||
|
||||
# Render two maps, two PNGs, one JPEG.
|
||||
im = mapnik2.Image(m.width,m.height)
|
||||
mapnik2.render(m, im)
|
||||
im = mapnik.Image(m.width,m.height)
|
||||
mapnik.render(m, im)
|
||||
|
||||
# Save image to files
|
||||
images_ = []
|
||||
|
@ -348,37 +348,37 @@ im.save('demo_low.jpg', 'jpeg50')
|
|||
images_.append('demo_low.jpg')
|
||||
|
||||
# Render cairo examples
|
||||
if HAS_PYCAIRO_MODULE and mapnik2.has_pycairo():
|
||||
if HAS_PYCAIRO_MODULE and mapnik.has_pycairo():
|
||||
|
||||
svg_surface = cairo.SVGSurface('demo.svg', m.width,m.height)
|
||||
mapnik2.render(m, svg_surface)
|
||||
mapnik.render(m, svg_surface)
|
||||
svg_surface.finish()
|
||||
images_.append('demo.svg')
|
||||
|
||||
pdf_surface = cairo.PDFSurface('demo.pdf', m.width,m.height)
|
||||
mapnik2.render(m, pdf_surface)
|
||||
mapnik.render(m, pdf_surface)
|
||||
images_.append('demo.pdf')
|
||||
pdf_surface.finish()
|
||||
|
||||
postscript_surface = cairo.PSSurface('demo.ps', m.width,m.height)
|
||||
mapnik2.render(m, postscript_surface)
|
||||
mapnik.render(m, postscript_surface)
|
||||
images_.append('demo.ps')
|
||||
postscript_surface.finish()
|
||||
|
||||
else:
|
||||
print '\n\nPycairo not available...',
|
||||
if mapnik2.has_cairo():
|
||||
if mapnik.has_cairo():
|
||||
print ' will render Cairo formats using alternative method'
|
||||
|
||||
mapnik2.render_to_file(m,'demo.pdf')
|
||||
mapnik.render_to_file(m,'demo.pdf')
|
||||
images_.append('demo.pdf')
|
||||
mapnik2.render_to_file(m,'demo.ps')
|
||||
mapnik.render_to_file(m,'demo.ps')
|
||||
images_.append('demo.ps')
|
||||
mapnik2.render_to_file(m,'demo.svg')
|
||||
mapnik.render_to_file(m,'demo.svg')
|
||||
images_.append('demo.svg')
|
||||
mapnik2.render_to_file(m,'demo_cairo_rgb.png','RGB24')
|
||||
mapnik.render_to_file(m,'demo_cairo_rgb.png','RGB24')
|
||||
images_.append('demo_cairo_rgb.png')
|
||||
mapnik2.render_to_file(m,'demo_cairo_argb.png','ARGB32')
|
||||
mapnik.render_to_file(m,'demo_cairo_argb.png','ARGB32')
|
||||
images_.append('demo_cairo_argb.png')
|
||||
|
||||
print "\n\n", len(images_), "maps have been rendered in the current directory:"
|
||||
|
@ -388,4 +388,4 @@ for im_ in images_:
|
|||
|
||||
print "\n\nHave a look!\n\n"
|
||||
|
||||
mapnik2.save_map(m,"map.xml")
|
||||
mapnik.save_map(m,"map.xml")
|
||||
|
|
|
@ -23,7 +23,7 @@ Import ('env')
|
|||
import os
|
||||
import platform
|
||||
|
||||
lib_dir = os.path.normpath(env['DESTDIR'] + '/' + env['PREFIX'] + '/' + env['LIBDIR_SCHEMA'] + '/mapnik2')
|
||||
lib_dir = os.path.normpath(env['DESTDIR'] + '/' + env['PREFIX'] + '/' + env['LIBDIR_SCHEMA'] + '/mapnik')
|
||||
|
||||
fonts = 1
|
||||
ini_template = '''
|
||||
|
|
|
@ -43,7 +43,7 @@ int main( int argc, char **argv )
|
|||
|
||||
// register input plug-ins
|
||||
QString plugins_dir = settings.value("mapnik/plugins_dir",
|
||||
QVariant("/usr/local/lib/mapnik2/input/")).toString();
|
||||
QVariant("/usr/local/lib/mapnik/input/")).toString();
|
||||
datasource_cache::instance()->register_datasources(plugins_dir.toStdString());
|
||||
// register fonts
|
||||
int count = settings.beginReadArray("mapnik/fonts");
|
||||
|
|
|
@ -11,7 +11,7 @@ INCLUDEPATH += /usr/X11/include/freetype2
|
|||
INCLUDEPATH += .
|
||||
|
||||
QMAKE_CXXFLAGS +=' -DDARWIN -Wno-missing-field-initializers -ansi'
|
||||
unix:LIBS = -L/usr/local/lib -L/usr/X11/lib -lmapnik2 -lfreetype
|
||||
unix:LIBS = -L/usr/local/lib -L/usr/X11/lib -lmapnik -lfreetype
|
||||
unix:LIBS += -lboost_system -licuuc -lboost_filesystem -lboost_regex
|
||||
|
||||
# Input
|
||||
|
|
|
@ -25,10 +25,15 @@
|
|||
#ifndef MAPNIK_ATTRIBUTE_HPP
|
||||
#define MAPNIK_ATTRIBUTE_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/value.hpp>
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
static mapnik::value _null_value;
|
||||
|
||||
struct attribute
|
||||
{
|
||||
std::string name_;
|
||||
|
@ -36,9 +41,15 @@ struct attribute
|
|||
: name_(name) {}
|
||||
|
||||
template <typename V ,typename F>
|
||||
V value(F const& f) const
|
||||
V const& value(F const& f) const
|
||||
{
|
||||
return f[name_];
|
||||
typedef typename F::const_iterator const_iterator;
|
||||
const_iterator itr = f.find(name_);
|
||||
if (itr != f.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
return _null_value;
|
||||
}
|
||||
std::string const& name() const { return name_;}
|
||||
};
|
||||
|
|
|
@ -131,10 +131,12 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void render_marker(const int x, const int y, marker &marker, const agg::trans_affine & mtx, double opacity=1.0);
|
||||
void render_marker(const int x, const int y, marker &marker, const agg::trans_affine & mtx, double opacity=1.0, bool recenter=true);
|
||||
|
||||
Map const& m_;
|
||||
Cairo::RefPtr<Cairo::Context> context_;
|
||||
unsigned width_;
|
||||
unsigned height_;
|
||||
CoordTransform t_;
|
||||
boost::shared_ptr<freetype_engine> font_engine_;
|
||||
face_manager<freetype_engine> font_manager_;
|
||||
|
|
1
include/mapnik/expression.hpp
Normal file
1
include/mapnik/expression.hpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include <mapnik/filter_factory.hpp>
|
|
@ -66,6 +66,7 @@ private:
|
|||
std::map<std::string,value> props_;
|
||||
public:
|
||||
typedef std::map<std::string,value>::iterator iterator;
|
||||
typedef std::map<std::string,value>::const_iterator const_iterator;
|
||||
explicit feature(int id)
|
||||
: properties(props_),
|
||||
id_(id),
|
||||
|
@ -157,6 +158,21 @@ public:
|
|||
return props_.end();
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return props_.begin();
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return props_.end();
|
||||
}
|
||||
|
||||
const_iterator find(std::string const& key) const
|
||||
{
|
||||
return props_.find(key);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -77,7 +77,9 @@ public:
|
|||
key_(key),
|
||||
data_(width,height),
|
||||
resolution_(resolution),
|
||||
id_name_("__id__") {
|
||||
painted_(false),
|
||||
id_name_("__id__")
|
||||
{
|
||||
// this only works if each datasource's
|
||||
// feature count starts at 1
|
||||
f_keys_[0] = "";
|
||||
|
@ -89,6 +91,7 @@ public:
|
|||
key_(rhs.key_),
|
||||
data_(rhs.data_),
|
||||
resolution_(rhs.resolution_),
|
||||
painted_(rhs.painted_),
|
||||
id_name_("__id__") {
|
||||
f_keys_[0] = "";
|
||||
}
|
||||
|
|
|
@ -434,7 +434,7 @@ private:
|
|||
}
|
||||
tries=0;
|
||||
// ignore leaves and also nodes with small mean error and not excessive number of pixels
|
||||
if ((cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(long(cur_node->pixel_count)) > 15
|
||||
if (cur_node->pixel_count > 0 && (cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(long(cur_node->pixel_count)) > 15
|
||||
&& cur_node->children_count > 0)
|
||||
{
|
||||
colors_--;
|
||||
|
|
|
@ -110,41 +110,81 @@ public:
|
|||
* @param maxZoom The minimum zoom level to set
|
||||
*/
|
||||
void setMinZoom(double minZoom);
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
void set_min_zoom(double minZoom)
|
||||
{
|
||||
setMinZoom(minZoom);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @param maxZoom The maximum zoom level to set
|
||||
*/
|
||||
void setMaxZoom(double maxZoom);
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
void set_max_zoom(double maxZoom)
|
||||
{
|
||||
setMinZoom(maxZoom);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return the minimum zoom level of the layer.
|
||||
*/
|
||||
double getMinZoom() const;
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
double min_zoom() const
|
||||
{
|
||||
return getMinZoom();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return the maximum zoom level of the layer.
|
||||
*/
|
||||
double getMaxZoom() const;
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
double max_zoom() const
|
||||
{
|
||||
return getMaxZoom();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set whether this layer is active and will be rendered.
|
||||
*/
|
||||
void setActive(bool active);
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
void set_active(bool active)
|
||||
{
|
||||
setActive(active);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return whether this layer is active and will be rendered.
|
||||
*/
|
||||
bool isActive() const;
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
bool active() const
|
||||
{
|
||||
return isActive();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set whether this layer is queryable.
|
||||
*/
|
||||
void setQueryable(bool queryable);
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
void set_queryable(bool queryable)
|
||||
{
|
||||
setQueryable(queryable);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @return whether this layer is queryable or not.
|
||||
*/
|
||||
bool isQueryable() const;
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
bool queryable() const
|
||||
{
|
||||
return isQueryable();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the visability for a specific scale.
|
||||
|
@ -159,6 +199,11 @@ public:
|
|||
* scale < maxzoom + 1e-6
|
||||
*/
|
||||
bool isVisible(double scale) const;
|
||||
// forward compatibility with mapnik 2.1.x
|
||||
bool visible(double scale) const
|
||||
{
|
||||
return isVisible(scale);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @param clear_cache Set whether this layer's labels are cached.
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
explicit markers_symbolizer();
|
||||
markers_symbolizer(path_expression_ptr filename);
|
||||
markers_symbolizer(markers_symbolizer const& rhs);
|
||||
void set_ignore_placement(bool ignore_placement);
|
||||
bool get_ignore_placement() const;
|
||||
void set_allow_overlap(bool overlap);
|
||||
bool get_allow_overlap() const;
|
||||
void set_spacing(double spacing);
|
||||
|
@ -79,6 +81,7 @@ public:
|
|||
|
||||
private:
|
||||
bool allow_overlap_;
|
||||
bool ignore_placement_;
|
||||
color fill_;
|
||||
double spacing_;
|
||||
double max_error_;
|
||||
|
|
|
@ -47,11 +47,22 @@ struct placement;
|
|||
class metawriter_property_map
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, UnicodeString> property_map;
|
||||
typedef property_map::const_iterator const_iterator;
|
||||
|
||||
metawriter_property_map() {}
|
||||
UnicodeString const& operator[](std::string const& key) const;
|
||||
UnicodeString& operator[](std::string const& key) {return m_[key];}
|
||||
std::map<std::string, UnicodeString>::const_iterator find(std::string const& key) const
|
||||
{
|
||||
return m_.find(key);
|
||||
}
|
||||
std::map<std::string, UnicodeString>::const_iterator end() const
|
||||
{
|
||||
return m_.end();
|
||||
}
|
||||
private:
|
||||
std::map<std::string, UnicodeString> m_;
|
||||
property_map m_;
|
||||
UnicodeString not_found_;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,29 @@
|
|||
#ifndef MAPNIK_VERSION_HPP
|
||||
#define MAPNIK_VERSION_HPP
|
||||
|
||||
#define MAPNIK_VERSION 200000
|
||||
#define MAPNIK_VERSION_IS_RELEASE 0
|
||||
|
||||
#define MAPNIK_MAJOR_VERSION 2
|
||||
#define MAPNIK_MINOR_VERSION 0
|
||||
#define MAPNIK_PATCH_VERSION 3
|
||||
|
||||
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
|
||||
|
||||
#ifndef MAPNIK_STRINGIFY
|
||||
#define MAPNIK_STRINGIFY(n) MAPNIK_STRINGIFY_HELPER(n)
|
||||
#define MAPNIK_STRINGIFY_HELPER(n) #n
|
||||
#endif
|
||||
|
||||
#if MAPNIK_VERSION_IS_RELEASE
|
||||
# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \
|
||||
MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \
|
||||
MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION)
|
||||
|
||||
#else
|
||||
# define MAPNIK_VERSION_STRING MAPNIK_STRINGIFY(MAPNIK_MAJOR_VERSION) "." \
|
||||
MAPNIK_STRINGIFY(MAPNIK_MINOR_VERSION) "." \
|
||||
MAPNIK_STRINGIFY(MAPNIK_PATCH_VERSION) "-pre"
|
||||
#endif
|
||||
|
||||
#endif // MAPNIK_VERSION_HPP
|
||||
|
||||
|
|
|
@ -36,16 +36,19 @@ gdal_src = Split(
|
|||
plugin_env['LIBS'] = [env['PLUGINS']['gdal']['lib']]
|
||||
|
||||
# Link Library to Dependencies
|
||||
plugin_env['LIBS'].append('mapnik2')
|
||||
plugin_env['LIBS'].append('mapnik')
|
||||
plugin_env['LIBS'].append(env['ICU_LIB_NAME'])
|
||||
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
plugin_env['LIBS'].append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
if env['RUNTIME_LINK'] == 'static':
|
||||
cmd = 'gdal-config --dep-libs'
|
||||
plugin_env.ParseConfig(cmd)
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../gdal', source=gdal_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -36,14 +36,15 @@ geos_src = Split(
|
|||
libraries = [env['PLUGINS']['geos']['lib']]
|
||||
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../geos', source=geos_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
// geos
|
||||
#include <geos_c.h>
|
||||
#include <cstdlib>
|
||||
|
||||
class geos_feature_ptr
|
||||
{
|
||||
|
@ -77,7 +78,10 @@ public:
|
|||
~geos_wkb_ptr ()
|
||||
{
|
||||
if (data_ != NULL)
|
||||
GEOSFree(data_);
|
||||
{
|
||||
// We use std::free here instead of GEOSFree(data_) to support geos 3.1.0
|
||||
std::free(data_);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
|
|
|
@ -34,13 +34,16 @@ kismet_src = Split(
|
|||
|
||||
libraries = []
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
|
||||
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../kismet', source=kismet_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -36,12 +36,14 @@ occi_src = Split(
|
|||
)
|
||||
|
||||
libraries = [ 'occi', 'ociei' ]
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../occi', source=occi_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -38,8 +38,9 @@ ogr_src = Split(
|
|||
plugin_env['LIBS'] = [env['PLUGINS']['ogr']['lib']]
|
||||
|
||||
# Link Library to Dependencies
|
||||
plugin_env['LIBS'].append('mapnik2')
|
||||
plugin_env['LIBS'].append('mapnik')
|
||||
plugin_env['LIBS'].append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
plugin_env['LIBS'].append('boost_system%s' % env['BOOST_APPEND'])
|
||||
plugin_env['LIBS'].append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
|
@ -47,9 +48,16 @@ if env['RUNTIME_LINK'] == 'static':
|
|||
cmd = 'gdal-config --dep-libs'
|
||||
plugin_env.ParseConfig(cmd)
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1082
|
||||
plugin_env.Append(CXXFLAGS = '-fpermissive')
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../ogr', source=ogr_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -169,11 +169,12 @@ void ogr_datasource::bind() const
|
|||
|
||||
if (!layer_)
|
||||
{
|
||||
std::string s("OGR Plugin: ");
|
||||
if (layer_by_name) s += "cannot find layer by name '" + *layer_by_name;
|
||||
else if (layer_by_index) s += "cannot find layer by index number '" + *layer_by_index;
|
||||
s += "' in dataset '" + dataset_name_ + "'";
|
||||
throw datasource_exception(s);
|
||||
std::ostringstream s;
|
||||
s << "OGR Plugin: ";
|
||||
if (layer_by_name) s << "cannot find layer by name '" << *layer_by_name;
|
||||
else if (layer_by_index) s << "cannot find layer by index number '" << *layer_by_index;
|
||||
s << "' in dataset '" << dataset_name_ << "'";
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
|
||||
// initialize envelope
|
||||
|
|
|
@ -38,12 +38,14 @@ osm_src = Split(
|
|||
|
||||
libraries = [ 'xml2' ]
|
||||
libraries.append('curl')
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../osm', source=osm_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -32,17 +32,28 @@ postgis_src = Split(
|
|||
"""
|
||||
)
|
||||
|
||||
libraries = ['pq']
|
||||
# clear out and rebuild libs
|
||||
plugin_env['LIBS'] = ['pq']
|
||||
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
plugin_env['LIBS'].append('mapnik')
|
||||
plugin_env['LIBS'].append(env['ICU_LIB_NAME'])
|
||||
if env['THREADING'] == 'multi':
|
||||
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
|
||||
plugin_env['LIBS'].append('boost_thread%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../postgis', source=postgis_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
plugin_env['LIBS'].append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
if env['RUNTIME_LINK'] == 'static':
|
||||
#cmd = 'pg_config --libs'
|
||||
#plugin_env.ParseConfig(cmd)
|
||||
# pg_config does not seem to report correct deps of libpq
|
||||
# so resort to hardcoding for now
|
||||
plugin_env['LIBS'].extend(['ldap','pam','ssl','crypto','krb5'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../postgis', source=postgis_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -83,8 +83,6 @@ postgis_datasource::postgis_datasource(parameters const& params, bool bind)
|
|||
persist_connection_(*params_.get<mapnik::boolean>("persist_connection",true)),
|
||||
extent_from_subquery_(*params_.get<mapnik::boolean>("extent_from_subquery",false)),
|
||||
// params below are for testing purposes only (will likely be removed at any time)
|
||||
force2d_(*params_.get<mapnik::boolean>("force_2d",false)),
|
||||
st_(*params_.get<mapnik::boolean>("st_prefix",false)),
|
||||
intersect_min_scale_(*params_.get<int>("intersect_min_scale",0)),
|
||||
intersect_max_scale_(*params_.get<int>("intersect_max_scale",0))
|
||||
//show_queries_(*params_.get<mapnik::boolean>("show_queries",false))
|
||||
|
@ -302,6 +300,7 @@ void postgis_datasource::bind() const
|
|||
case 1042: // bpchar
|
||||
case 1043: // varchar
|
||||
case 25: // text
|
||||
case 705: // literal
|
||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
|
||||
break;
|
||||
default: // should not get here
|
||||
|
@ -358,7 +357,7 @@ std::string postgis_datasource::sql_bbox(box2d<double> const& env) const
|
|||
{
|
||||
std::ostringstream b;
|
||||
if (srid_ > 0)
|
||||
b << "SetSRID(";
|
||||
b << "ST_SetSRID(";
|
||||
b << "'BOX3D(";
|
||||
b << std::setprecision(16);
|
||||
b << env.minx() << " " << env.miny() << ",";
|
||||
|
@ -495,13 +494,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
}
|
||||
|
||||
std::ostringstream s;
|
||||
s << "SELECT ";
|
||||
if (st_)
|
||||
s << "ST_";
|
||||
if (force2d_)
|
||||
s << "AsBinary(ST_Force_2D(\"" << geometryColumn_ << "\")) AS geom";
|
||||
else
|
||||
s << "AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
|
||||
if (!key_field_.empty())
|
||||
mapnik::quote_attr(s,key_field_);
|
||||
|
@ -571,13 +564,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
|||
}
|
||||
|
||||
|
||||
s << "SELECT ";
|
||||
if (st_)
|
||||
s << "ST_";
|
||||
if (force2d_)
|
||||
s << "AsBinary(ST_Force_2D(\"" << geometryColumn_ << "\")) AS geom";
|
||||
else
|
||||
s << "AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
|
||||
if (!key_field_.empty())
|
||||
mapnik::quote_attr(s,key_field_);
|
||||
|
|
|
@ -75,8 +75,6 @@ class postgis_datasource : public datasource
|
|||
bool persist_connection_;
|
||||
bool extent_from_subquery_;
|
||||
// params below are for testing purposes only (will likely be removed at any time)
|
||||
bool force2d_;
|
||||
bool st_;
|
||||
int intersect_min_scale_;
|
||||
int intersect_max_scale_;
|
||||
//bool show_queries_;
|
||||
|
|
|
@ -152,7 +152,7 @@ feature_ptr postgis_featureset::next()
|
|||
float8net(val,buf);
|
||||
boost::put(*feature,name,val);
|
||||
}
|
||||
else if (oid==25 || oid==1043) // text or varchar
|
||||
else if (oid==25 || oid==1043 || oid==705 ) // text or varchar or literal
|
||||
{
|
||||
UnicodeString ustr = tr_->transcode(buf);
|
||||
boost::put(*feature,name,ustr);
|
||||
|
|
|
@ -35,14 +35,15 @@ raster_src = Split(
|
|||
|
||||
libraries = []
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../raster', source=raster_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -35,14 +35,15 @@ rasterlite_src = Split(
|
|||
libraries = [env['PLUGINS']['rasterlite']['lib']]
|
||||
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../rasterlite', source=rasterlite_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -39,17 +39,25 @@ shape_src = Split(
|
|||
libraries = []
|
||||
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
if env['SHAPE_MEMORY_MAPPED_FILE']:
|
||||
plugin_env.Append(CXXFLAGS = '-DSHAPE_MEMORY_MAPPED_FILE')
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1082
|
||||
plugin_env.Append(CXXFLAGS = '-fpermissive')
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../shape', SHLIBSUFFIX='.input', source=shape_src, SHLIBPREFIX='', LIBS = libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -35,14 +35,16 @@ sqlite_src = Split(
|
|||
libraries = [ 'sqlite3' ]
|
||||
|
||||
# Link Library to Dependencies
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
if env['HAS_BOOST_SYSTEM']:
|
||||
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||
|
||||
libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../sqlite', source=sqlite_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik2 ensure it is built first
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -142,27 +142,26 @@ public:
|
|||
sqlite_connection (const std::string& file)
|
||||
: db_(0)
|
||||
{
|
||||
// sqlite3_open_v2 is available earlier but
|
||||
// shared cache not available until >= 3.6.18
|
||||
#if SQLITE_VERSION_NUMBER >= 3005000
|
||||
int mode = SQLITE_OPEN_READWRITE;
|
||||
#if SQLITE_VERSION_NUMBER >= 3006018
|
||||
int rc = sqlite3_enable_shared_cache(1);
|
||||
// shared cache flag not available until >= 3.6.18
|
||||
mode |= SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE;
|
||||
#endif
|
||||
const int rc = sqlite3_open_v2 (file.c_str(), &db_, mode, 0);
|
||||
#else
|
||||
#warning "Mapnik's sqlite plugin is compiling against a version of sqlite older than 3.5.x which may make rendering slow..."
|
||||
const int rc = sqlite3_open (file.c_str(), &db_);
|
||||
#endif
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
throw mapnik::datasource_exception (sqlite3_errmsg (db_));
|
||||
std::ostringstream s;
|
||||
s << "Sqlite Plugin: " << sqlite3_errmsg (db_);
|
||||
|
||||
throw mapnik::datasource_exception (s.str());
|
||||
}
|
||||
|
||||
int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE;
|
||||
if (sqlite3_open_v2 (file.c_str(), &db_, mode, NULL))
|
||||
#else
|
||||
#warning "Mapnik's sqlite plugin is compiling against a version of sqlite older than 3.6.18 which may make rendering slow..."
|
||||
if (sqlite3_open (file.c_str(), &db_))
|
||||
#endif
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "Sqlite Plugin: ";
|
||||
throw mapnik::datasource_exception (sqlite3_errmsg (db_));
|
||||
}
|
||||
//sqlite3_enable_load_extension(db_, 1);
|
||||
sqlite3_busy_timeout(db_,5000);
|
||||
}
|
||||
|
||||
~sqlite_connection ()
|
||||
|
|
|
@ -31,7 +31,7 @@ the middle of any map tile and display a "hello world!" label if used like:
|
|||
|
||||
Or used in python like:
|
||||
|
||||
from mapnik2 import *
|
||||
from mapnik import *
|
||||
m = Map(600,400)
|
||||
m.background = Color('white')
|
||||
s = Style()
|
||||
|
|
|
@ -22,7 +22,7 @@ Import ('env')
|
|||
# main SConstruct file where configuration happens
|
||||
|
||||
# plugins can go anywhere, and be registered in custom locations by Mapnik
|
||||
# but the standard location is '/usr/local/lib/mapnik2/input'
|
||||
# but the standard location is '/usr/local/lib/mapnik/input'
|
||||
install_dest = env['MAPNIK_INPUT_PLUGINS_DEST']
|
||||
|
||||
# clone the environment here
|
||||
|
@ -42,7 +42,7 @@ plugin_sources = Split(
|
|||
# directly link to
|
||||
libraries = [ '' ] # eg 'libfoo'
|
||||
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
# link libicuuc, but ICU_LIB_NAME is used custom builds of icu can
|
||||
# have different library names like osx which offers /usr/lib/libicucore.dylib
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
|
|
|
@ -142,6 +142,8 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
unsigned s_a=col.alpha();
|
||||
double w = sym.get_width();
|
||||
double h = sym.get_height();
|
||||
double rx = w;
|
||||
double ry = h;
|
||||
|
||||
arrow arrow_;
|
||||
box2d<double> extent;
|
||||
|
@ -196,7 +198,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(label_ext))
|
||||
{
|
||||
agg::ellipse c(x, y, w, h);
|
||||
agg::ellipse c(x, y, rx, ry);
|
||||
marker.concat_path(c);
|
||||
ras_ptr->add_path(marker);
|
||||
ren.color(agg::rgba8(r, g, b, int(a*sym.get_opacity())));
|
||||
|
@ -215,6 +217,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
|
||||
agg::render_scanlines(*ras_ptr, sl_line, ren);
|
||||
}
|
||||
if (!sym.get_ignore_placement())
|
||||
detector_.insert(label_ext);
|
||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
}
|
||||
|
@ -239,7 +242,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|||
if (marker_type == ELLIPSE)
|
||||
{
|
||||
// todo proper bbox - this is buggy
|
||||
agg::ellipse c(x_t, y_t, w, h);
|
||||
agg::ellipse c(x_t, y_t, rx, ry);
|
||||
marker.concat_path(c);
|
||||
agg::trans_affine matrix;
|
||||
matrix *= agg::trans_affine_translation(-x_t,-y_t);
|
||||
|
|
|
@ -135,7 +135,8 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||
ren.set_opacity(sym.get_text_opacity());
|
||||
|
||||
placement_finder<label_collision_detector4> finder(detector_);
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
|
||||
string_info info(text);
|
||||
|
||||
|
@ -214,7 +215,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
{
|
||||
render_marker(px,py,**marker,tr,sym.get_opacity());
|
||||
|
||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
||||
ren.prepare_glyphs(&text_placement.placements[0]);
|
||||
ren.render(x,y);
|
||||
detector_.insert(label_ext);
|
||||
finder.update_detector(text_placement);
|
||||
|
@ -253,7 +254,7 @@ void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|||
|
||||
render_marker(px,py,**marker,tr,sym.get_opacity());
|
||||
|
||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||
ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||
ren.render(x,y);
|
||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
}
|
||||
|
|
37
src/build.py
37
src/build.py
|
@ -55,7 +55,10 @@ filesystem = 'boost_filesystem%s' % env['BOOST_APPEND']
|
|||
regex = 'boost_regex%s' % env['BOOST_APPEND']
|
||||
|
||||
# clear out and re-set libs for this env
|
||||
lib_env['LIBS'] = ['freetype','ltdl','png','tiff','z','jpeg','proj',env['ICU_LIB_NAME'],filesystem,regex]
|
||||
lib_env['LIBS'] = ['freetype','ltdl','png','tiff','z','proj',env['ICU_LIB_NAME'],filesystem,regex]
|
||||
|
||||
if env['JPEG']:
|
||||
lib_env['LIBS'].append('jpeg')
|
||||
|
||||
if len(env['EXTRA_FREETYPE_LIBS']):
|
||||
lib_env['LIBS'].extend(copy(env['EXTRA_FREETYPE_LIBS']))
|
||||
|
@ -77,11 +80,15 @@ if not env['RUNTIME_LINK'] == 'static':
|
|||
else:
|
||||
lib_env['LIBS'].append([lib for lib in env['LIBS'] if lib.startswith('agg')])
|
||||
|
||||
if env['RUNTIME_LINK'] == 'static':
|
||||
if 'icuuc' in env['ICU_LIB_NAME']:
|
||||
lib_env['LIBS'].append('icudata')
|
||||
lib_env['LIBS'].append('icui18n')
|
||||
|
||||
if env['PLATFORM'] == 'Darwin':
|
||||
mapnik_libname = 'libmapnik2.dylib'
|
||||
mapnik_libname = 'libmapnik.dylib'
|
||||
else:
|
||||
mapnik_libname = 'libmapnik2.so.' + ("%d.%d" % (ABI_VERSION[0],ABI_VERSION[1]))
|
||||
mapnik_libname = 'libmapnik.so.' + ("%d.%d" % (int(ABI_VERSION[0]),int(ABI_VERSION[1])))
|
||||
|
||||
if env['PLATFORM'] == 'Darwin':
|
||||
if env['FULL_LIB_PATH']:
|
||||
|
@ -89,7 +96,7 @@ if env['PLATFORM'] == 'Darwin':
|
|||
else:
|
||||
lib_path = mapnik_libname
|
||||
mapnik_lib_link_flag += ' -Wl,-install_name,%s' % lib_path
|
||||
_d = {'version':env['MAPNIK_VERSION_STRING']}
|
||||
_d = {'version':env['MAPNIK_VERSION_STRING'].replace('-pre','')}
|
||||
mapnik_lib_link_flag += ' -current_version %(version)s -compatibility_version %(version)s' % _d
|
||||
elif env['PLATFORM'] == 'SunOS':
|
||||
if env['CXX'].startswith('CC'):
|
||||
|
@ -204,6 +211,20 @@ if env['LIBTOOL_SUPPORTS_ADVISE']:
|
|||
else:
|
||||
source.insert(0,'datasource_cache.cpp')
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1001
|
||||
env4 = lib_env.Clone()
|
||||
env4.Append(CXXFLAGS = '-fpermissive')
|
||||
cpp ='mapped_memory_cache.cpp'
|
||||
source.remove(cpp)
|
||||
if env['LINKING'] == 'static':
|
||||
source.insert(0,env4.StaticObject(cpp))
|
||||
else:
|
||||
source.insert(0,env4.SharedObject(cpp))
|
||||
|
||||
if env['JPEG']:
|
||||
source += Split(
|
||||
"""
|
||||
|
@ -293,9 +314,9 @@ else:
|
|||
linkflags = mapnik_lib_link_flag
|
||||
|
||||
if env['LINKING'] == 'static':
|
||||
mapnik = lib_env.StaticLibrary('mapnik2', source, LINKFLAGS=linkflags)
|
||||
mapnik = lib_env.StaticLibrary('mapnik', source, LINKFLAGS=linkflags)
|
||||
else:
|
||||
mapnik = lib_env.SharedLibrary('mapnik2', source, LINKFLAGS=linkflags)
|
||||
mapnik = lib_env.SharedLibrary('mapnik', source, LINKFLAGS=linkflags)
|
||||
|
||||
# cache library values for other builds to use
|
||||
env['LIBMAPNIK_LIBS'] = copy(lib_env['LIBS'])
|
||||
|
@ -313,7 +334,7 @@ if env['PLATFORM'] != 'Darwin':
|
|||
|
||||
major, minor, micro = ABI_VERSION
|
||||
|
||||
soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), major, minor, micro)
|
||||
soFile = "%s.%d.%d.%d" % (os.path.basename(str(mapnik[0])), int(major), int(minor), int(micro))
|
||||
target = os.path.join(env['MAPNIK_LIB_BASE_DEST'], soFile)
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
|
@ -324,7 +345,7 @@ if env['PLATFORM'] != 'Darwin':
|
|||
|
||||
|
||||
# Install symlinks
|
||||
target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),major, minor))
|
||||
target1 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], "%s.%d.%d" % (os.path.basename(str(mapnik[0])),int(major), int(minor)))
|
||||
target2 = os.path.join(env['MAPNIK_LIB_BASE_DEST'], os.path.basename(str(mapnik[0])))
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
if 'install' in COMMAND_LINE_TARGETS:
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include <mapnik/warp.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
|
||||
#include "agg_path_storage.h" // for markers_symbolizer
|
||||
#include "agg_ellipse.h" // for markers_symbolizer
|
||||
|
||||
// cairo
|
||||
#include <cairomm/context.h>
|
||||
#include <cairomm/surface.h>
|
||||
|
@ -657,6 +660,8 @@ private:
|
|||
cairo_renderer_base::cairo_renderer_base(Map const& m, Cairo::RefPtr<Cairo::Context> const& context, unsigned offset_x, unsigned offset_y)
|
||||
: m_(m),
|
||||
context_(context),
|
||||
width_(m.width()),
|
||||
height_(m.height()),
|
||||
t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
|
||||
font_engine_(new freetype_engine()),
|
||||
font_manager_(*font_engine_),
|
||||
|
@ -908,7 +913,7 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
|
|||
}
|
||||
}
|
||||
|
||||
void cairo_renderer_base::render_marker(const int x, const int y, marker &marker, const agg::trans_affine & tr, double opacity)
|
||||
void cairo_renderer_base::render_marker(const int x, const int y, marker &marker, const agg::trans_affine & tr, double opacity, bool recenter)
|
||||
|
||||
{
|
||||
cairo_context context(context_);
|
||||
|
@ -917,15 +922,21 @@ void cairo_renderer_base::render_marker(const int x, const int y, marker &marker
|
|||
box2d<double> bbox;
|
||||
bbox = (*marker.get_vector_data())->bounding_box();
|
||||
|
||||
agg::trans_affine mtx = tr;
|
||||
|
||||
if (recenter)
|
||||
{
|
||||
coord<double,2> c = bbox.center();
|
||||
// center the svg marker on '0,0'
|
||||
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
|
||||
mtx = agg::trans_affine_translation(-c.x,-c.y);
|
||||
// apply symbol transformation to get to map space
|
||||
mtx *= tr;
|
||||
// render the marker at the center of the marker box
|
||||
mtx.translate(x+0.5 * marker.width(), y+0.5 * marker.height());
|
||||
}
|
||||
|
||||
typedef coord_transform2<CoordTransform,geometry_type> path_type;
|
||||
agg::trans_affine transform;
|
||||
mapnik::path_ptr vmarker = *marker.get_vector_data();
|
||||
|
||||
agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes();
|
||||
|
@ -937,10 +948,10 @@ void cairo_renderer_base::render_marker(const int x, const int y, marker &marker
|
|||
|
||||
context.save();
|
||||
|
||||
agg::trans_affine transform = attr.transform;
|
||||
transform = attr.transform;
|
||||
transform *= mtx;
|
||||
|
||||
if (transform.is_valid() && !transform.is_identity())
|
||||
if (/*transform.is_valid() &&*/ !transform.is_identity())
|
||||
{
|
||||
double m[6];
|
||||
transform.store_to(m);
|
||||
|
@ -1136,7 +1147,8 @@ void cairo_renderer_base::process(shield_symbolizer const& sym,
|
|||
cairo_context context(context_);
|
||||
string_info info(text);
|
||||
|
||||
placement_finder<label_collision_detector4> finder(detector_);
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
|
||||
faces->set_pixel_sizes(placement_options->text_size);
|
||||
faces->get_string_info(info);
|
||||
|
@ -1423,33 +1435,235 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
|
|||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef coord_transform2<CoordTransform,geometry_type> path_type;
|
||||
arrow arrow_;
|
||||
cairo_context context(context_);
|
||||
|
||||
color const& fill_ = sym.get_fill();
|
||||
context.set_color(fill_.red(), fill_.green(), fill_.blue(), fill_.alpha());
|
||||
double scale_factor_(1);
|
||||
|
||||
typedef coord_transform2<CoordTransform,mapnik::geometry_type> path_type;
|
||||
|
||||
agg::trans_affine tr;
|
||||
boost::array<double,6> const& m = sym.get_transform();
|
||||
tr.load_from(&m[0]);
|
||||
// TODO - use this?
|
||||
//tr = agg::trans_affine_scaling(scale_factor_) * tr;
|
||||
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
||||
marker_placement_e placement_method = sym.get_marker_placement();
|
||||
marker_type_e marker_type = sym.get_marker_type();
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
if (!(*mark)->is_vector()) {
|
||||
std::clog << "### Warning only svg markers are supported in the markers_symbolizer\n";
|
||||
return;
|
||||
}
|
||||
boost::optional<path_ptr> marker = (*mark)->get_vector_data();
|
||||
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||
double x1 = bbox.minx();
|
||||
double y1 = bbox.miny();
|
||||
double x2 = bbox.maxx();
|
||||
double y2 = bbox.maxy();
|
||||
double w = (*mark)->width();
|
||||
double h = (*mark)->height();
|
||||
|
||||
agg::trans_affine recenter = agg::trans_affine_translation(-0.5*(x1+x2),-0.5*(y1+y2));
|
||||
tr.transform(&x1,&y1);
|
||||
tr.transform(&x2,&y2);
|
||||
box2d<double> extent(x1,y1,x2,y2);
|
||||
using namespace mapnik::svg;
|
||||
|
||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
||||
{
|
||||
geometry_type const& geom = feature.get_geometry(i);
|
||||
// TODO - merge this code with point_symbolizer rendering
|
||||
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z=0;
|
||||
geom.label_interior_position(&x, &y);
|
||||
prj_trans.backward(x,y,z);
|
||||
t_.forward(&x,&y);
|
||||
extent.re_center(x,y);
|
||||
|
||||
if (geom.num_points() > 1)
|
||||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(extent))
|
||||
{
|
||||
render_marker(x - 0.5 * w, y - 0.5 * h,**mark, tr, sym.get_opacity());
|
||||
|
||||
// TODO - impl this for markers?
|
||||
//if (!sym.get_ignore_placement())
|
||||
// detector_.insert(label_ext);
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
if (writer.first) writer.first->add_box(extent, feature, t_, writer.second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
path_type path(t_,geom,prj_trans);
|
||||
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, arrow_.extent(), detector_, sym.get_spacing(), sym.get_max_error(), sym.get_allow_overlap());
|
||||
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
||||
sym.get_spacing() * scale_factor_,
|
||||
sym.get_max_error(),
|
||||
sym.get_allow_overlap());
|
||||
double x, y, angle;
|
||||
while (placement.get_point(&x, &y, &angle)) {
|
||||
Cairo::Matrix matrix = Cairo::rotation_matrix(angle) * Cairo::translation_matrix(x,y) ;
|
||||
context.set_matrix(matrix);
|
||||
context.add_path(arrow_);
|
||||
|
||||
while (placement.get_point(&x, &y, &angle))
|
||||
{
|
||||
agg::trans_affine matrix = recenter * tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x, y);
|
||||
render_marker(x - 0.5 * w, y - 0.5 * h, **mark, matrix, sym.get_opacity(),false);
|
||||
|
||||
if (writer.first)
|
||||
//writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
std::clog << "### Warning metawriter not yet supported for LINE placement\n";
|
||||
}
|
||||
}
|
||||
context.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
color const& fill_ = sym.get_fill();
|
||||
stroke const& stroke_ = sym.get_stroke();
|
||||
color const& col = stroke_.get_color();
|
||||
double strk_width = stroke_.get_width();
|
||||
double w = sym.get_width();
|
||||
double h = sym.get_height();
|
||||
double rx = w;
|
||||
double ry = h;
|
||||
|
||||
arrow arrow_;
|
||||
box2d<double> extent;
|
||||
|
||||
double dx = w + (2*strk_width);
|
||||
double dy = h + (2*strk_width);
|
||||
|
||||
if (marker_type == ARROW)
|
||||
{
|
||||
extent = arrow_.extent();
|
||||
double x1 = extent.minx();
|
||||
double y1 = extent.miny();
|
||||
double x2 = extent.maxx();
|
||||
double y2 = extent.maxy();
|
||||
tr.transform(&x1,&y1);
|
||||
tr.transform(&x2,&y2);
|
||||
extent.init(x1,y1,x2,y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
double x1 = -1 *(dx);
|
||||
double y1 = -1 *(dy);
|
||||
double x2 = dx;
|
||||
double y2 = dy;
|
||||
tr.transform(&x1,&y1);
|
||||
tr.transform(&x2,&y2);
|
||||
extent.init(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
double x;
|
||||
double y;
|
||||
double z=0;
|
||||
|
||||
agg::path_storage marker;
|
||||
|
||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
||||
{
|
||||
geometry_type const& geom = feature.get_geometry(i);
|
||||
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
|
||||
{
|
||||
geom.label_position(&x,&y);
|
||||
prj_trans.backward(x,y,z);
|
||||
t_.forward(&x,&y);
|
||||
int px = int(floor(x - 0.5 * dx));
|
||||
int py = int(floor(y - 0.5 * dy));
|
||||
box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
|
||||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(label_ext))
|
||||
{
|
||||
agg::ellipse c(x, y, rx, ry);
|
||||
marker.concat_path(c);
|
||||
context.set_color(fill_,sym.get_opacity());
|
||||
context.add_agg_path(marker);
|
||||
context.fill();
|
||||
|
||||
if (strk_width)
|
||||
{
|
||||
//context.restore();
|
||||
context.set_color(col,stroke_.get_opacity());
|
||||
context.set_line_width(stroke_.get_width());
|
||||
if (stroke_.has_dash())
|
||||
{
|
||||
context.set_dash(stroke_.get_dash_array());
|
||||
}
|
||||
context.add_agg_path(marker);
|
||||
context.stroke();
|
||||
}
|
||||
if (!sym.get_ignore_placement())
|
||||
detector_.insert(label_ext);
|
||||
if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (marker_type == ARROW)
|
||||
marker.concat_path(arrow_);
|
||||
|
||||
path_type path(t_,geom,prj_trans);
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_,
|
||||
sym.get_spacing() * scale_factor_,
|
||||
sym.get_max_error(),
|
||||
sym.get_allow_overlap());
|
||||
double x_t, y_t, angle;
|
||||
|
||||
while (placement.get_point(&x_t, &y_t, &angle))
|
||||
{
|
||||
agg::trans_affine matrix;
|
||||
|
||||
if (marker_type == ELLIPSE)
|
||||
{
|
||||
agg::ellipse c(x_t, y_t, rx, ry);
|
||||
marker.concat_path(c);
|
||||
agg::trans_affine matrix;
|
||||
matrix *= agg::trans_affine_translation(-x_t,-y_t);
|
||||
matrix *= agg::trans_affine_rotation(angle);
|
||||
matrix *= agg::trans_affine_translation(x_t,y_t);
|
||||
marker.transform(matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix = tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x_t, y_t);
|
||||
}
|
||||
|
||||
// TODO
|
||||
if (writer.first)
|
||||
//writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||
std::clog << "### Warning metawriter not yet supported for LINE placement\n";
|
||||
|
||||
agg::conv_transform<agg::path_storage, agg::trans_affine> trans(marker, matrix);
|
||||
context.set_color(fill_,sym.get_opacity());
|
||||
context.add_agg_path(trans);
|
||||
context.fill();
|
||||
|
||||
if (strk_width)
|
||||
{
|
||||
context.set_color(col,stroke_.get_opacity());
|
||||
context.set_line_width(stroke_.get_width());
|
||||
if (stroke_.has_dash())
|
||||
{
|
||||
context.set_dash(stroke_.get_dash_array());
|
||||
}
|
||||
context.add_agg_path(trans);
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cairo_renderer_base::process(glyph_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
|
@ -1566,7 +1780,8 @@ void cairo_renderer_base::process(text_symbolizer const& sym,
|
|||
faces->set_pixel_sizes(placement_options->text_size);
|
||||
faces->get_string_info(info);
|
||||
|
||||
placement_finder<label_collision_detector4> finder(detector_);
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
|
||||
metawriter_with_properties writer = sym.get_metawriter();
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
// cairo
|
||||
#ifdef HAVE_CAIRO
|
||||
|
@ -117,9 +118,23 @@ void image_32::set_grayscale_to_alpha()
|
|||
}
|
||||
}
|
||||
|
||||
void image_32::set_color_to_alpha(const color& /*c*/)
|
||||
void image_32::set_color_to_alpha(const color& c)
|
||||
{
|
||||
// TODO - function to set all pixels to a % alpha based on distance to a given color
|
||||
for (unsigned y = 0; y < height_; ++y)
|
||||
{
|
||||
unsigned int* row_from = data_.getRow(y);
|
||||
for (unsigned x = 0; x < width_; ++x)
|
||||
{
|
||||
unsigned rgba = row_from[x];
|
||||
unsigned r = rgba & 0xff;
|
||||
unsigned g = (rgba >> 8 ) & 0xff;
|
||||
unsigned b = (rgba >> 16) & 0xff;
|
||||
if (r == c.red() && g == c.green() && b == c.blue())
|
||||
{
|
||||
row_from[x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image_32::set_alpha(float opacity)
|
||||
|
|
|
@ -146,6 +146,9 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
|
|||
h = sym.get_height()/res;
|
||||
}
|
||||
|
||||
double rx = w;
|
||||
double ry = h;
|
||||
|
||||
arrow arrow_;
|
||||
box2d<double> extent;
|
||||
|
||||
|
@ -193,7 +196,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
|
|||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(label_ext))
|
||||
{
|
||||
agg::ellipse c(x, y, w, h);
|
||||
agg::ellipse c(x, y, rx, ry);
|
||||
agg::path_storage marker;
|
||||
marker.concat_path(c);
|
||||
ras_ptr->add_path(marker);
|
||||
|
@ -230,7 +233,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
|
|||
if (marker_type == ELLIPSE)
|
||||
{
|
||||
// todo proper bbox - this is buggy
|
||||
agg::ellipse c(x_t, y_t, w, h);
|
||||
agg::ellipse c(x_t, y_t, rx, ry);
|
||||
marker.concat_path(c);
|
||||
agg::trans_affine matrix;
|
||||
matrix *= agg::trans_affine_translation(-x_t,-y_t);
|
||||
|
|
|
@ -116,7 +116,8 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
|
|||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||
ren.set_opacity(sym.get_text_opacity());
|
||||
|
||||
placement_finder<label_collision_detector4> finder(detector_);
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
|
||||
string_info info(text);
|
||||
|
||||
|
@ -196,7 +197,7 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
|
|||
{
|
||||
render_marker(feature,pixmap_.get_resolution(),px,py,**marker,tr,sym.get_opacity());
|
||||
|
||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
||||
ren.prepare_glyphs(&text_placement.placements[0]);
|
||||
ren.render_id(feature.id(),x,y,2);
|
||||
detector_.insert(label_ext);
|
||||
finder.update_detector(text_placement);
|
||||
|
@ -226,7 +227,7 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
|
|||
|
||||
render_marker(feature,pixmap_.get_resolution(),px,py,**marker,tr,sym.get_opacity());
|
||||
|
||||
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||
ren.prepare_glyphs(&text_placement.placements[ii]);
|
||||
ren.render_id(feature.id(),x,y,2);
|
||||
}
|
||||
finder.update_detector(text_placement);
|
||||
|
|
|
@ -83,7 +83,6 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
|
|||
ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
|
||||
ren.set_opacity(sym.get_text_opacity());
|
||||
|
||||
// /pixmap_.get_resolution() ?
|
||||
box2d<double> dims(0,0,width_,height_);
|
||||
placement_finder<label_collision_detector4> finder(detector_,dims);
|
||||
|
||||
|
|
67
src/json/feature_collection_parser.cpp
Normal file
67
src/json/feature_collection_parser.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// TODO https://github.com/mapnik/mapnik/issues/1658
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION >= 105200
|
||||
#define BOOST_SPIRIT_USE_PHOENIX_V3
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/json/feature_collection_parser.hpp>
|
||||
#include <mapnik/json/feature_collection_grammar.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/include/support_multi_pass.hpp>
|
||||
|
||||
namespace mapnik { namespace json {
|
||||
|
||||
#if BOOST_VERSION >= 104700
|
||||
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::feature_collection_parser(mapnik::context_ptr const& ctx, mapnik::transcoder const& tr)
|
||||
: grammar_(new feature_collection_grammar<iterator_type,feature_type>(ctx,tr)) {}
|
||||
|
||||
template <typename Iterator>
|
||||
feature_collection_parser<Iterator>::~feature_collection_parser() {}
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
bool feature_collection_parser<Iterator>::parse(iterator_type first, iterator_type last, std::vector<mapnik::feature_ptr> & features)
|
||||
{
|
||||
#if BOOST_VERSION >= 104700
|
||||
using namespace boost::spirit;
|
||||
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
||||
#else
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
throw std::runtime_error("mapnik::feature_collection_parser::parse() requires at least boost 1.47 while your build was compiled against boost " + s.str());
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
template class feature_collection_parser<std::string::const_iterator> ;
|
||||
template class feature_collection_parser<boost::spirit::multi_pass<std::istreambuf_iterator<char> > >;
|
||||
|
||||
}}
|
||||
|
|
@ -389,6 +389,10 @@ void map_parser::parse_map_include( Map & map, ptree const & include )
|
|||
}
|
||||
datasource_templates_[name] = params;
|
||||
}
|
||||
else if (v.first == "Parameters")
|
||||
{
|
||||
// do not throw in order to support Mapnik 2.1.x stylesheets
|
||||
}
|
||||
else if (v.first != "<xmlcomment>" &&
|
||||
v.first != "<xmlattr>")
|
||||
{
|
||||
|
@ -975,6 +979,7 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym )
|
|||
//s << "file,opacity,spacing,max-error,allow-overlap,placement,";
|
||||
s << "file,base,transform,fill,opacity,"
|
||||
<< "spacing,max-error,allow-overlap,"
|
||||
<< "ignore-placement,"
|
||||
<< "width,height,placement,marker-type,"
|
||||
<< "stroke,stroke-width,stroke-opacity,stroke-linejoin,"
|
||||
<< "stroke-linecap,stroke-dashoffset,stroke-dasharray,"
|
||||
|
@ -1047,7 +1052,9 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym )
|
|||
optional<double> max_error = get_opt_attr<double>(sym, "max-error");
|
||||
if (max_error) symbol.set_max_error(*max_error);
|
||||
optional<boolean> allow_overlap = get_opt_attr<boolean>(sym, "allow-overlap");
|
||||
optional<boolean> ignore_placement = get_opt_attr<boolean>(sym, "ignore-placement");
|
||||
if (allow_overlap) symbol.set_allow_overlap(*allow_overlap);
|
||||
if (ignore_placement) symbol.set_ignore_placement(*ignore_placement);
|
||||
|
||||
optional<double> w = get_opt_attr<double>(sym, "width");
|
||||
optional<double> h = get_opt_attr<double>(sym, "height");
|
||||
|
|
|
@ -47,6 +47,7 @@ markers_symbolizer::markers_symbolizer()
|
|||
: symbolizer_with_image(path_expression_ptr(new path_expression)),
|
||||
symbolizer_base(),
|
||||
allow_overlap_(false),
|
||||
ignore_placement_(false),
|
||||
fill_(color(0,0,255)),
|
||||
spacing_(100.0),
|
||||
max_error_(0.2),
|
||||
|
@ -60,6 +61,7 @@ markers_symbolizer::markers_symbolizer(path_expression_ptr filename)
|
|||
: symbolizer_with_image(filename),
|
||||
symbolizer_base(),
|
||||
allow_overlap_(false),
|
||||
ignore_placement_(false),
|
||||
fill_(color(0,0,255)),
|
||||
spacing_(100.0),
|
||||
max_error_(0.2),
|
||||
|
@ -73,6 +75,7 @@ markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs)
|
|||
: symbolizer_with_image(rhs),
|
||||
symbolizer_base(rhs),
|
||||
allow_overlap_(rhs.allow_overlap_),
|
||||
ignore_placement_(rhs.ignore_placement_),
|
||||
fill_(rhs.fill_),
|
||||
spacing_(rhs.spacing_),
|
||||
max_error_(rhs.max_error_),
|
||||
|
@ -82,6 +85,16 @@ markers_symbolizer::markers_symbolizer(markers_symbolizer const& rhs)
|
|||
marker_p_(rhs.marker_p_),
|
||||
marker_type_(rhs.marker_type_) {}
|
||||
|
||||
void markers_symbolizer::set_ignore_placement(bool ignore_placement)
|
||||
{
|
||||
ignore_placement_ = ignore_placement;
|
||||
}
|
||||
|
||||
bool markers_symbolizer::get_ignore_placement() const
|
||||
{
|
||||
return ignore_placement_;
|
||||
}
|
||||
|
||||
void markers_symbolizer::set_allow_overlap(bool overlap)
|
||||
{
|
||||
allow_overlap_ = overlap;
|
||||
|
|
|
@ -35,10 +35,11 @@ bool rgba::mean_sort_cmp::operator() (const rgba& x, const rgba& y) const
|
|||
int t2 = (int)y.a + y.r + y.g + y.b;
|
||||
if (t1 != t2) return t1 < t2;
|
||||
|
||||
return (((int)x.a - y.a) >> 24) +
|
||||
(((int)x.r - y.r) >> 16) +
|
||||
(((int)x.g - y.g) >> 8) +
|
||||
(((int)x.b - y.b));
|
||||
// https://github.com/mapnik/mapnik/issues/1087
|
||||
if (x.a != y.a) return x.a < y.a;
|
||||
if (x.r != y.r) return x.r < y.r;
|
||||
if (x.g != y.g) return x.g < y.g;
|
||||
return x.b < y.b;
|
||||
}
|
||||
|
||||
std::size_t rgba::hash_func::operator()(rgba const& p) const
|
||||
|
|
|
@ -137,10 +137,15 @@ void projection::init()
|
|||
#if PJ_VERSION >= 480
|
||||
proj_ctx_ = pj_ctx_alloc();
|
||||
proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str());
|
||||
if (!proj_)
|
||||
{
|
||||
if (proj_ctx_) pj_ctx_free(proj_ctx_);
|
||||
throw proj_init_error(params_);
|
||||
}
|
||||
#else
|
||||
proj_ = pj_init_plus(params_.c_str());
|
||||
#endif
|
||||
if (!proj_) throw proj_init_error(params_);
|
||||
#endif
|
||||
is_geographic_ = pj_is_latlong(proj_) ? true : false;
|
||||
}
|
||||
|
||||
|
|
|
@ -261,6 +261,10 @@ public:
|
|||
{
|
||||
set_attr( sym_node, "allow-overlap", sym.get_allow_overlap() );
|
||||
}
|
||||
if (sym.get_ignore_placement() != dfl.get_ignore_placement() || explicit_defaults_)
|
||||
{
|
||||
set_attr( sym_node, "ignore-placement", sym.get_ignore_placement() );
|
||||
}
|
||||
if (sym.get_spacing() != dfl.get_spacing() || explicit_defaults_)
|
||||
{
|
||||
set_attr( sym_node, "spacing", sym.get_spacing() );
|
||||
|
@ -609,7 +613,7 @@ private:
|
|||
}
|
||||
if ( strk.dash_offset() != dfl.dash_offset() || explicit_defaults_ )
|
||||
{
|
||||
set_attr( node, "stroke-dash-offset", strk.dash_offset());
|
||||
set_attr( node, "stroke-dashoffset", strk.dash_offset());
|
||||
}
|
||||
if ( ! strk.get_dash_array().empty() )
|
||||
{
|
||||
|
|
|
@ -403,7 +403,7 @@ void svg_parser::parse_path(xmlTextReaderPtr reader)
|
|||
|
||||
if (!mapnik::svg::parse_path((const char*) value, path_))
|
||||
{
|
||||
std::runtime_error("can't parse PATH\n");
|
||||
throw std::runtime_error("can't parse PATH\n");
|
||||
}
|
||||
path_.end_path();
|
||||
}
|
||||
|
|
23
src/wkb.cpp
23
src/wkb.cpp
|
@ -238,8 +238,10 @@ private:
|
|||
|
||||
void read_linestring(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type * line = new geometry_type(LineString);
|
||||
int num_points=read_integer();
|
||||
if (num_points > 0)
|
||||
{
|
||||
geometry_type * line = new geometry_type(LineString);
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
line->set_capacity(num_points);
|
||||
|
@ -250,6 +252,7 @@ private:
|
|||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
|
@ -263,8 +266,10 @@ private:
|
|||
|
||||
void read_multilinestring_2(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type * line = new geometry_type(MultiLineString);
|
||||
int num_lines=read_integer();
|
||||
if (num_lines > 0)
|
||||
{
|
||||
geometry_type * line = new geometry_type(MultiLineString);
|
||||
unsigned capacity = 0;
|
||||
for (int i=0;i<num_lines;++i)
|
||||
{
|
||||
|
@ -282,11 +287,14 @@ private:
|
|||
}
|
||||
paths.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
void read_polygon(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type * poly = new geometry_type(Polygon);
|
||||
int num_rings=read_integer();
|
||||
if (num_rings > 0)
|
||||
{
|
||||
geometry_type * poly = new geometry_type(Polygon);
|
||||
unsigned capacity = 0;
|
||||
for (int i=0;i<num_rings;++i)
|
||||
{
|
||||
|
@ -303,6 +311,7 @@ private:
|
|||
}
|
||||
paths.push_back(poly);
|
||||
}
|
||||
}
|
||||
|
||||
void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
|
@ -316,8 +325,10 @@ private:
|
|||
|
||||
void read_multipolygon_2(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
geometry_type * poly = new geometry_type(MultiPolygon);
|
||||
int num_polys=read_integer();
|
||||
if (num_polys > 0)
|
||||
{
|
||||
geometry_type * poly = new geometry_type(MultiPolygon);
|
||||
unsigned capacity = 0;
|
||||
for (int i=0;i<num_polys;++i)
|
||||
{
|
||||
|
@ -326,6 +337,8 @@ private:
|
|||
for (int r=0;r<num_rings;++r)
|
||||
{
|
||||
int num_points=read_integer();
|
||||
if (num_points > 0)
|
||||
{
|
||||
capacity += num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
|
@ -338,8 +351,10 @@ private:
|
|||
poly->line_to(ar[0].x,ar[0].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
paths.push_back(poly);
|
||||
}
|
||||
}
|
||||
|
||||
void read_collection(boost::ptr_vector<geometry_type> & paths)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ test_env = env.Clone()
|
|||
headers = env['CPPPATH']
|
||||
|
||||
libraries = copy(env['LIBMAPNIK_LIBS'])
|
||||
libraries.append('mapnik2')
|
||||
libraries.append('mapnik')
|
||||
|
||||
for cpp_test in glob.glob('*_test.cpp'):
|
||||
test_program = test_env.Program(cpp_test.replace('.cpp',''), [cpp_test], CPPPATH=headers, LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
|
|
@ -9,7 +9,7 @@ filesystem = 'boost_filesystem%s' % env['BOOST_APPEND']
|
|||
system = 'boost_system%s' % env['BOOST_APPEND']
|
||||
regex = 'boost_regex%s' % env['BOOST_APPEND']
|
||||
|
||||
libraries = [filesystem, 'mapnik2']
|
||||
libraries = [filesystem, 'mapnik']
|
||||
|
||||
if env['PLATFORM'] == 'Darwin':
|
||||
libraries.append(env['ICU_LIB_NAME'])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import mapnik2
|
||||
import mapnik
|
||||
from nose.tools import *
|
||||
from utilities import execution_path,Todo
|
||||
|
||||
|
@ -11,13 +11,13 @@ def setup():
|
|||
os.chdir(execution_path('.'))
|
||||
|
||||
def _pycairo_surface(type,sym):
|
||||
if mapnik2.has_pycairo():
|
||||
if mapnik.has_pycairo():
|
||||
import cairo
|
||||
test_cairo_file = 'test.%s' % type
|
||||
m = mapnik2.Map(256,256)
|
||||
mapnik2.load_map(m,'../data/good_maps/%s_symbolizer.xml' % sym)
|
||||
m = mapnik.Map(256,256)
|
||||
mapnik.load_map(m,'../data/good_maps/%s_symbolizer.xml' % sym)
|
||||
surface = getattr(cairo,'%sSurface' % type.upper())(test_cairo_file, m.width,m.height)
|
||||
mapnik2.render(m, surface)
|
||||
mapnik.render(m, surface)
|
||||
surface.finish()
|
||||
|
||||
if os.path.exists(test_cairo_file):
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -11,36 +11,36 @@ def setup():
|
|||
os.chdir(execution_path('.'))
|
||||
|
||||
def test_field_listing():
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Shapefile(file='../data/shp/poly.shp')
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||
fields = lyr.datasource.fields()
|
||||
eq_(fields, ['AREA', 'EAS_ID', 'PRFEDEA'])
|
||||
|
||||
def test_total_feature_count_shp():
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Shapefile(file='../data/shp/poly.shp')
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||
features = lyr.datasource.all_features()
|
||||
num_feats = len(features)
|
||||
eq_(num_feats, 10)
|
||||
|
||||
def test_total_feature_count_json():
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Ogr(file='../data/json/points.json',layer_by_index=0)
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Ogr(file='../data/json/points.json',layer_by_index=0)
|
||||
features = lyr.datasource.all_features()
|
||||
num_feats = len(features)
|
||||
eq_(num_feats, 5)
|
||||
|
||||
def test_reading_json_from_string():
|
||||
json = open('../data/json/points.json','r').read()
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Ogr(file=json,layer_by_index=0)
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Ogr(file=json,layer_by_index=0)
|
||||
features = lyr.datasource.all_features()
|
||||
num_feats = len(features)
|
||||
eq_(num_feats, 5)
|
||||
|
||||
def test_feature_envelope():
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Shapefile(file='../data/shp/poly.shp')
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||
features = lyr.datasource.all_features()
|
||||
for feat in features:
|
||||
env = feat.envelope()
|
||||
|
@ -50,8 +50,8 @@ def test_feature_envelope():
|
|||
eq_(intersects, True)
|
||||
|
||||
def test_feature_attributes():
|
||||
lyr = mapnik2.Layer('test')
|
||||
lyr.datasource = mapnik2.Shapefile(file='../data/shp/poly.shp')
|
||||
lyr = mapnik.Layer('test')
|
||||
lyr.datasource = mapnik.Shapefile(file='../data/shp/poly.shp')
|
||||
features = lyr.datasource.all_features()
|
||||
feat = features[0]
|
||||
attrs = {'PRFEDEA': u'35043411', 'EAS_ID': 168, 'AREA': 215229.266}
|
||||
|
@ -67,8 +67,8 @@ def test_hit_grid():
|
|||
""" encode a list of strings with run-length compression """
|
||||
return ["%d:%s" % (len(list(group)), name) for name, group in groupby(l)]
|
||||
|
||||
m = mapnik2.Map(256,256);
|
||||
mapnik2.load_map(m,'../data/good_maps/agg_poly_gamma_map.xml');
|
||||
m = mapnik.Map(256,256);
|
||||
mapnik.load_map(m,'../data/good_maps/agg_poly_gamma_map.xml');
|
||||
m.zoom_all()
|
||||
join_field = 'NAME'
|
||||
fg = [] # feature grid
|
||||
|
|
|
@ -4,7 +4,7 @@ from nose.tools import *
|
|||
|
||||
from utilities import execution_path, Todo
|
||||
|
||||
import os, sys, glob, mapnik2
|
||||
import os, sys, glob, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -12,8 +12,8 @@ def setup():
|
|||
os.chdir(execution_path('.'))
|
||||
|
||||
def compare_shape_between_mapnik_and_ogr(shapefile,query=None):
|
||||
ds1 = mapnik2.Ogr(file=shapefile,layer_by_index=0)
|
||||
ds2 = mapnik2.Shapefile(file=shapefile)
|
||||
ds1 = mapnik.Ogr(file=shapefile,layer_by_index=0)
|
||||
ds2 = mapnik.Shapefile(file=shapefile)
|
||||
if query:
|
||||
fs1 = ds1.features(query)
|
||||
fs2 = ds2.features(query)
|
||||
|
@ -44,8 +44,8 @@ def test_shapefile_polygon_featureset_id():
|
|||
|
||||
def test_shapefile_polygon_feature_query_id():
|
||||
bbox = (15523428.2632, 4110477.6323, -11218494.8310, 7495720.7404)
|
||||
query = mapnik2.Query(mapnik2.Box2d(*bbox))
|
||||
ds = mapnik2.Ogr(file='../data/shp/world_merc.shp',layer_by_index=0)
|
||||
query = mapnik.Query(mapnik.Box2d(*bbox))
|
||||
ds = mapnik.Ogr(file='../data/shp/world_merc.shp',layer_by_index=0)
|
||||
for fld in ds.fields():
|
||||
query.add_property_name(fld)
|
||||
compare_shape_between_mapnik_and_ogr('../data/shp/world_merc.shp',query)
|
||||
|
@ -55,11 +55,11 @@ def test_feature_hit_count():
|
|||
# results in different results between shp and ogr!
|
||||
#bbox = (-14284551.8434, 2074195.1992, -7474929.8687, 8140237.7628)
|
||||
bbox = (1113194.91,4512803.085,2226389.82,6739192.905)
|
||||
query = mapnik2.Query(mapnik2.Box2d(*bbox))
|
||||
ds1 = mapnik2.Ogr(file='../data/shp/world_merc.shp',layer_by_index=0)
|
||||
query = mapnik.Query(mapnik.Box2d(*bbox))
|
||||
ds1 = mapnik.Ogr(file='../data/shp/world_merc.shp',layer_by_index=0)
|
||||
for fld in ds1.fields():
|
||||
query.add_property_name(fld)
|
||||
ds2 = mapnik2.Shapefile(file='../data/shp/world_merc.shp')
|
||||
ds2 = mapnik.Shapefile(file='../data/shp/world_merc.shp')
|
||||
count1 = len(ds1.features(query).features)
|
||||
count2 = len(ds2.features(query).features)
|
||||
eq_(count1,count2,"Feature count differs between OGR driver (%s features) and Shapefile Driver (%s features) when querying the same bbox" % (count1,count2))
|
||||
|
|
|
@ -6,7 +6,7 @@ from utilities import Todo
|
|||
|
||||
class FeatureTest(unittest.TestCase):
|
||||
def makeOne(self, *args, **kw):
|
||||
from mapnik2 import Feature
|
||||
from mapnik import Feature
|
||||
return Feature(*args, **kw)
|
||||
|
||||
def test_default_constructor(self):
|
||||
|
@ -14,7 +14,7 @@ class FeatureTest(unittest.TestCase):
|
|||
self.failUnless(f is not None)
|
||||
|
||||
def test_python_extended_constructor(self):
|
||||
from mapnik2 import Box2d
|
||||
from mapnik import Box2d
|
||||
f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar")
|
||||
self.failUnlessEqual(f['foo'], 'bar')
|
||||
self.failUnlessEqual(f.envelope(),Box2d(10.0,10.0,45.0,45.0))
|
||||
|
@ -37,7 +37,7 @@ class FeatureTest(unittest.TestCase):
|
|||
test_val(v)
|
||||
|
||||
def test_add_wkt_geometry(self):
|
||||
from mapnik2 import Box2d
|
||||
from mapnik import Box2d
|
||||
def add_geom_wkt(wkt):
|
||||
f = self.makeOne(1)
|
||||
self.failUnlessEqual(len(f.geometries()), 0)
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
from nose.tools import *
|
||||
from utilities import Todo
|
||||
|
||||
import mapnik2
|
||||
import mapnik
|
||||
|
||||
if hasattr(mapnik2,'Expression'):
|
||||
mapnik2.Filter = mapnik2.Expression
|
||||
if hasattr(mapnik,'Expression'):
|
||||
mapnik.Filter = mapnik.Expression
|
||||
|
||||
map_ = '''<Map>
|
||||
<Style name="s">
|
||||
|
@ -52,25 +52,25 @@ map_ = '''<Map>
|
|||
</Map>'''
|
||||
|
||||
def test_filter_init():
|
||||
m = mapnik2.Map(1,1)
|
||||
mapnik2.load_map_from_string(m,map_)
|
||||
m = mapnik.Map(1,1)
|
||||
mapnik.load_map_from_string(m,map_)
|
||||
filters = []
|
||||
filters.append(mapnik2.Filter("([region]>=0) and ([region]<=50)"))
|
||||
filters.append(mapnik2.Filter("(([region]>=0) and ([region]<=50))"))
|
||||
filters.append(mapnik2.Filter("((([region]>=0) and ([region]<=50)))"))
|
||||
filters.append(mapnik2.Filter('((([region]>=0) and ([region]<=50)))'))
|
||||
filters.append(mapnik2.Filter('''((([region]>=0) and ([region]<=50)))'''))
|
||||
filters.append(mapnik2.Filter('''
|
||||
filters.append(mapnik.Filter("([region]>=0) and ([region]<=50)"))
|
||||
filters.append(mapnik.Filter("(([region]>=0) and ([region]<=50))"))
|
||||
filters.append(mapnik.Filter("((([region]>=0) and ([region]<=50)))"))
|
||||
filters.append(mapnik.Filter('((([region]>=0) and ([region]<=50)))'))
|
||||
filters.append(mapnik.Filter('''((([region]>=0) and ([region]<=50)))'''))
|
||||
filters.append(mapnik.Filter('''
|
||||
((([region]>=0)
|
||||
and
|
||||
([region]<=50)))
|
||||
'''))
|
||||
filters.append(mapnik2.Filter('''
|
||||
filters.append(mapnik.Filter('''
|
||||
([region]>=0)
|
||||
and
|
||||
([region]<=50)
|
||||
'''))
|
||||
filters.append(mapnik2.Filter('''
|
||||
filters.append(mapnik.Filter('''
|
||||
([region]
|
||||
>=
|
||||
0)
|
||||
|
@ -91,31 +91,31 @@ def test_filter_init():
|
|||
|
||||
s = m.find_style('s2')
|
||||
|
||||
eq_(s.filter_mode,mapnik2.filter_mode.FIRST)
|
||||
eq_(s.filter_mode,mapnik.filter_mode.FIRST)
|
||||
|
||||
|
||||
def test_regex_match():
|
||||
f = mapnik2.Feature(0)
|
||||
f = mapnik.Feature(0)
|
||||
f["name"] = 'test'
|
||||
expr = mapnik2.Expression("[name].match('test')")
|
||||
expr = mapnik.Expression("[name].match('test')")
|
||||
eq_(expr.evaluate(f),True) # 1 == True
|
||||
|
||||
def test_unicode_regex_match():
|
||||
f = mapnik2.Feature(0)
|
||||
f = mapnik.Feature(0)
|
||||
f["name"] = 'Québec'
|
||||
expr = mapnik2.Expression("[name].match('Québec')")
|
||||
expr = mapnik.Expression("[name].match('Québec')")
|
||||
eq_(expr.evaluate(f),True) # 1 == True
|
||||
|
||||
def test_regex_replace():
|
||||
f = mapnik2.Feature(0)
|
||||
f = mapnik.Feature(0)
|
||||
f["name"] = 'test'
|
||||
expr = mapnik2.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
expr = mapnik.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
eq_(expr.evaluate(f),'t e s t')
|
||||
|
||||
def test_unicode_regex_replace():
|
||||
f = mapnik2.Feature(0)
|
||||
f = mapnik.Feature(0)
|
||||
f["name"] = 'Québec'
|
||||
expr = mapnik2.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
expr = mapnik.Expression("[name].replace('(\B)|( )','$1 ')")
|
||||
eq_(expr.evaluate(f), u'Q u é b e c')
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import mapnik2, pickle
|
||||
import mapnik, pickle
|
||||
|
||||
# Tests that exercise fonts.
|
||||
|
||||
|
@ -10,7 +10,7 @@ import mapnik2, pickle
|
|||
# Todo: Add logic to use this TextSymbolizer in a rendering
|
||||
#@raises(UserWarning)
|
||||
#def test_invalid_font():
|
||||
# ts = mapnik2.TextSymbolizer('Name', 'Invalid Font Name', int(8), mapnik2.Color('black'))
|
||||
# ts = mapnik.TextSymbolizer('Name', 'Invalid Font Name', int(8), mapnik.Color('black'))
|
||||
|
||||
if __name__ == "__main__":
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
||||
|
|
|
@ -5,53 +5,53 @@ from nose.tools import *
|
|||
|
||||
from utilities import execution_path, save_data, contains_word
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
|
||||
def test_renders_with_agg():
|
||||
sym = mapnik2.GlyphSymbolizer("DejaVu Sans Condensed",
|
||||
mapnik2.Expression("'í'"))
|
||||
sym = mapnik.GlyphSymbolizer("DejaVu Sans Condensed",
|
||||
mapnik.Expression("'í'"))
|
||||
sym.allow_overlap = True
|
||||
sym.angle = mapnik2.Expression("[azimuth]+90") #+90 so the top of the glyph points upwards
|
||||
sym.size = mapnik2.Expression("[value]")
|
||||
sym.color = mapnik2.Expression("'#ff0000'")
|
||||
sym.angle = mapnik.Expression("[azimuth]+90") #+90 so the top of the glyph points upwards
|
||||
sym.size = mapnik.Expression("[value]")
|
||||
sym.color = mapnik.Expression("'#ff0000'")
|
||||
|
||||
_map = create_map_and_append_symbolyzer(sym)
|
||||
im = mapnik2.Image(_map.width,_map.height)
|
||||
mapnik2.render(_map, im)
|
||||
im = mapnik.Image(_map.width,_map.height)
|
||||
mapnik.render(_map, im)
|
||||
save_data('agg_glyph_symbolizer.png', im.tostring('png'))
|
||||
assert contains_word('\xff\x00\x00\xff', im.tostring())
|
||||
|
||||
def test_renders_with_cairo():
|
||||
if not mapnik2.has_pycairo():
|
||||
if not mapnik.has_pycairo():
|
||||
return
|
||||
sym = mapnik2.GlyphSymbolizer("DejaVu Sans Condensed",
|
||||
mapnik2.Expression("'í'"))
|
||||
sym = mapnik.GlyphSymbolizer("DejaVu Sans Condensed",
|
||||
mapnik.Expression("'í'"))
|
||||
sym.allow_overlap = True
|
||||
sym.angle = mapnik2.Expression("[azimuth]+90") #+90 so the top of the glyph points upwards
|
||||
sym.size = mapnik2.Expression("[value]")
|
||||
sym.color = mapnik2.Expression("'#ff0000'")
|
||||
sym.angle = mapnik.Expression("[azimuth]+90") #+90 so the top of the glyph points upwards
|
||||
sym.size = mapnik.Expression("[value]")
|
||||
sym.color = mapnik.Expression("'#ff0000'")
|
||||
_map = create_map_and_append_symbolyzer(sym)
|
||||
|
||||
from cStringIO import StringIO
|
||||
import cairo
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 256, 256)
|
||||
mapnik2.render(_map, surface)
|
||||
im = mapnik2.Image.from_cairo(surface)
|
||||
mapnik.render(_map, surface)
|
||||
im = mapnik.Image.from_cairo(surface)
|
||||
save_data('cairo_glyph_symbolizer.png', im.tostring('png'))
|
||||
assert contains_word('\xff\x00\x00\xff', im.tostring())
|
||||
|
||||
def test_load_save_load_map():
|
||||
map = mapnik2.Map(256,256)
|
||||
map = mapnik.Map(256,256)
|
||||
in_map = "../data/good_maps/glyph_symbolizer.xml"
|
||||
mapnik2.load_map(map, in_map)
|
||||
mapnik.load_map(map, in_map)
|
||||
style = map.find_style('arrows')
|
||||
sym = style.rules[0].symbols[0]
|
||||
assert isinstance(sym, mapnik2.GlyphSymbolizer)
|
||||
assert sym.angle_mode == mapnik2.angle_mode.AZIMUTH
|
||||
assert isinstance(sym, mapnik.GlyphSymbolizer)
|
||||
assert sym.angle_mode == mapnik.angle_mode.AZIMUTH
|
||||
|
||||
out_map = mapnik2.save_map_to_string(map).decode('utf8')
|
||||
map = mapnik2.Map(256,256)
|
||||
mapnik2.load_map_from_string(map, out_map.encode('utf8'))
|
||||
out_map = mapnik.save_map_to_string(map).decode('utf8')
|
||||
map = mapnik.Map(256,256)
|
||||
mapnik.load_map_from_string(map, out_map.encode('utf8'))
|
||||
assert 'GlyphSymbolizer' in out_map
|
||||
# make sure non-ascii characters are well supported since most interesting
|
||||
# glyphs for symbology are usually in that range
|
||||
|
@ -68,21 +68,21 @@ def setup():
|
|||
|
||||
def create_map_and_append_symbolyzer(sym):
|
||||
srs = '+init=epsg:32630'
|
||||
lyr = mapnik2.Layer('arrows')
|
||||
lyr.datasource = mapnik2.Shapefile(
|
||||
lyr = mapnik.Layer('arrows')
|
||||
lyr.datasource = mapnik.Shapefile(
|
||||
file = '../data/shp/arrows.shp',
|
||||
)
|
||||
lyr.srs = srs
|
||||
_map = mapnik2.Map(256,256, srs)
|
||||
style = mapnik2.Style()
|
||||
rule = mapnik2.Rule()
|
||||
_map = mapnik.Map(256,256, srs)
|
||||
style = mapnik.Style()
|
||||
rule = mapnik.Rule()
|
||||
rule.symbols.append(sym)
|
||||
|
||||
# put a test symbolizer to see what is the azimuth being read
|
||||
ts = mapnik2.TextSymbolizer(mapnik2.Expression('[azimuth]'),
|
||||
ts = mapnik.TextSymbolizer(mapnik.Expression('[azimuth]'),
|
||||
"DejaVu Sans Book",
|
||||
10,
|
||||
mapnik2.Color("black"))
|
||||
mapnik.Color("black"))
|
||||
ts.allow_overlap = True
|
||||
rule.symbols.append(ts)
|
||||
|
||||
|
@ -90,7 +90,7 @@ def create_map_and_append_symbolyzer(sym):
|
|||
_map.append_style('foo', style)
|
||||
lyr.styles.append('foo')
|
||||
_map.layers.append(lyr)
|
||||
_map.zoom_to_box(mapnik2.Box2d(0,0,8,8))
|
||||
_map.zoom_to_box(mapnik.Box2d(0,0,8,8))
|
||||
return _map
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -5,7 +5,7 @@ from nose.tools import *
|
|||
from utilities import execution_path
|
||||
from utilities import Todo
|
||||
|
||||
import mapnik2
|
||||
import mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -14,7 +14,7 @@ def setup():
|
|||
|
||||
def test_introspect_symbolizers():
|
||||
# create a symbolizer
|
||||
p = mapnik2.PointSymbolizer(mapnik2.PathExpression("../data/images/dummy.png"))
|
||||
p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/dummy.png"))
|
||||
p.allow_overlap = True
|
||||
p.opacity = 0.5
|
||||
|
||||
|
@ -29,11 +29,11 @@ def test_introspect_symbolizers():
|
|||
eq_(p.filename,'../data/images/dummy.png')
|
||||
|
||||
# contruct objects to hold it
|
||||
r = mapnik2.Rule()
|
||||
r = mapnik.Rule()
|
||||
r.symbols.append(p)
|
||||
s = mapnik2.Style()
|
||||
s = mapnik.Style()
|
||||
s.rules.append(r)
|
||||
m = mapnik2.Map(0,0)
|
||||
m = mapnik.Map(0,0)
|
||||
m.append_style('s',s)
|
||||
|
||||
# try to figure out what is
|
||||
|
@ -51,7 +51,7 @@ def test_introspect_symbolizers():
|
|||
sym = syms[0]
|
||||
# this is hackish at best
|
||||
p2 = sym.symbol()
|
||||
assert isinstance(p2,mapnik2.PointSymbolizer)
|
||||
assert isinstance(p2,mapnik.PointSymbolizer)
|
||||
|
||||
eq_(p2.allow_overlap, True)
|
||||
eq_(p2.opacity, 0.5)
|
||||
|
@ -60,7 +60,7 @@ def test_introspect_symbolizers():
|
|||
## but we need to be able to do:
|
||||
p2 = syms[0] # get the actual symbolizer, not the variant object
|
||||
# this will throw for now...
|
||||
assert isinstance(p2,mapnik2.PointSymbolizer)
|
||||
assert isinstance(p2,mapnik.PointSymbolizer)
|
||||
|
||||
eq_(p2.allow_overlap, True)
|
||||
eq_(p2.opacity, 0.5)
|
||||
|
|
|
@ -5,7 +5,7 @@ from nose.tools import *
|
|||
import os
|
||||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
import mapnik2
|
||||
import mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -30,9 +30,9 @@ def test_adding_datasource_to_layer():
|
|||
|
||||
</Map>
|
||||
'''
|
||||
m = mapnik2.Map(256, 256)
|
||||
m = mapnik.Map(256, 256)
|
||||
|
||||
mapnik2.load_map_from_string(m, map_string)
|
||||
mapnik.load_map_from_string(m, map_string)
|
||||
|
||||
# validate it loaded fine
|
||||
eq_(m.layers[0].styles[0],'world_borders_style')
|
||||
|
@ -53,7 +53,7 @@ def test_adding_datasource_to_layer():
|
|||
eq_(lyr.srs,'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
|
||||
|
||||
# now add a datasource one...
|
||||
ds = mapnik2.Shapefile(file='../data/shp/world_merc.shp')
|
||||
ds = mapnik.Shapefile(file='../data/shp/world_merc.shp')
|
||||
m.layers[0].datasource = ds
|
||||
|
||||
# now ensure it is attached
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
|
||||
import os, sys, glob, mapnik2
|
||||
import os, sys, glob, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -13,15 +13,15 @@ def setup():
|
|||
# We expect these files to not raise any
|
||||
# exceptions at all
|
||||
def assert_loads_successfully(file):
|
||||
m = mapnik2.Map(512, 512)
|
||||
m = mapnik.Map(512, 512)
|
||||
|
||||
strict = True
|
||||
mapnik2.load_map(m, file, strict)
|
||||
mapnik.load_map(m, file, strict)
|
||||
|
||||
# libxml2 is not smart about paths, and clips the last directory off
|
||||
# of a path if it does not end in a trailing slash
|
||||
base_path = os.path.dirname(file) + '/'
|
||||
mapnik2.load_map_from_string(m,open(file,'rb').read(),strict,base_path)
|
||||
mapnik.load_map_from_string(m,open(file,'rb').read(),strict,base_path)
|
||||
|
||||
|
||||
# We expect these files to raise a RuntimeError
|
||||
|
@ -29,10 +29,10 @@ def assert_loads_successfully(file):
|
|||
# of exception)
|
||||
@raises(RuntimeError)
|
||||
def assert_raises_runtime_error(file):
|
||||
m = mapnik2.Map(512, 512)
|
||||
m = mapnik.Map(512, 512)
|
||||
|
||||
strict = True
|
||||
mapnik2.load_map(m, file, strict)
|
||||
mapnik.load_map(m, file, strict)
|
||||
|
||||
def test_broken_files():
|
||||
broken_files = glob.glob("../data/broken_maps/*.xml")
|
||||
|
|
|
@ -4,7 +4,7 @@ from nose.tools import *
|
|||
from subprocess import call
|
||||
import os
|
||||
|
||||
#import os, sys, glob, mapnik2
|
||||
#import os, sys, glob, mapnik
|
||||
|
||||
#def test():
|
||||
# # mapnik-config program
|
||||
|
|
|
@ -8,11 +8,11 @@ class MemoryDatasource(unittest.TestCase):
|
|||
ids = itertools.count(0)
|
||||
|
||||
def makeOne(self, *args, **kw):
|
||||
from mapnik2 import MemoryDatasource
|
||||
from mapnik import MemoryDatasource
|
||||
return MemoryDatasource(*args, **kw)
|
||||
|
||||
def makeFeature(self, wkt, **properties):
|
||||
from mapnik2 import Feature
|
||||
from mapnik import Feature
|
||||
f = Feature(self.ids.next())
|
||||
f.add_geometries_from_wkt(wkt)
|
||||
for k,v in properties.iteritems():
|
||||
|
@ -29,7 +29,7 @@ class MemoryDatasource(unittest.TestCase):
|
|||
md.add_feature(self.makeFeature('Point(2 3)', foo='bar'))
|
||||
self.failUnlessEqual(md.num_features(), 1)
|
||||
|
||||
from mapnik2 import Coord
|
||||
from mapnik import Coord
|
||||
retrieved = md.features_at_point(Coord(2,3)).features
|
||||
self.failUnlessEqual(len(retrieved), 1)
|
||||
f = retrieved[0]
|
||||
|
|
|
@ -6,7 +6,7 @@ from nose.tools import *
|
|||
from utilities import execution_path
|
||||
from utilities import Todo
|
||||
|
||||
import mapnik2, pickle
|
||||
import mapnik, pickle
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -17,44 +17,44 @@ def setup():
|
|||
|
||||
# LineSymbolizer initialization
|
||||
def test_line_symbolizer_init():
|
||||
s = mapnik2.LineSymbolizer()
|
||||
eq_(s.rasterizer, mapnik2.line_rasterizer.FULL)
|
||||
s = mapnik.LineSymbolizer()
|
||||
eq_(s.rasterizer, mapnik.line_rasterizer.FULL)
|
||||
|
||||
# ShieldSymbolizer initialization
|
||||
def test_shieldsymbolizer_init():
|
||||
s = mapnik2.ShieldSymbolizer(mapnik2.Expression('[Field Name]'), 'DejaVu Sans Bold', 6, mapnik2.Color('#000000'), mapnik2.PathExpression('../data/images/dummy.png'))
|
||||
s = mapnik.ShieldSymbolizer(mapnik.Expression('[Field Name]'), 'DejaVu Sans Bold', 6, mapnik.Color('#000000'), mapnik.PathExpression('../data/images/dummy.png'))
|
||||
eq_(s.anchor, (0.0,0.5,))
|
||||
eq_(s.displacement, (0.0,0.0))
|
||||
eq_(s.allow_overlap, False)
|
||||
eq_(s.avoid_edges, False)
|
||||
eq_(s.character_spacing,0)
|
||||
eq_(str(s.name), str(mapnik2.Expression('[Field Name]')))
|
||||
eq_(str(s.name), str(mapnik.Expression('[Field Name]')))
|
||||
eq_(s.face_name, 'DejaVu Sans Bold')
|
||||
eq_(s.allow_overlap, False)
|
||||
eq_(s.fill, mapnik2.Color('#000000'))
|
||||
eq_(s.fill, mapnik.Color('#000000'))
|
||||
eq_(s.force_odd_labels, False)
|
||||
eq_(s.halo_fill, mapnik2.Color('rgb(255,255,255)'))
|
||||
eq_(s.halo_fill, mapnik.Color('rgb(255,255,255)'))
|
||||
eq_(s.halo_radius, 0)
|
||||
eq_(s.label_placement, mapnik2.label_placement.POINT_PLACEMENT)
|
||||
eq_(s.label_placement, mapnik.label_placement.POINT_PLACEMENT)
|
||||
eq_(s.minimum_distance, 0.0)
|
||||
eq_(s.text_ratio, 0)
|
||||
eq_(s.text_size, 6)
|
||||
eq_(s.wrap_width, 0)
|
||||
eq_(s.vertical_alignment, mapnik2.vertical_alignment.MIDDLE)
|
||||
eq_(s.vertical_alignment, mapnik.vertical_alignment.MIDDLE)
|
||||
eq_(s.label_spacing, 0)
|
||||
eq_(s.label_position_tolerance, 0)
|
||||
# 22.5 * M_PI/180.0 initialized by default
|
||||
assert_almost_equal(s.max_char_angle_delta, 0.39269908169872414)
|
||||
|
||||
eq_(s.wrap_character, ' ')
|
||||
eq_(s.text_transform, mapnik2.text_transform.NONE)
|
||||
eq_(s.text_transform, mapnik.text_transform.NONE)
|
||||
eq_(s.line_spacing, 0)
|
||||
eq_(s.character_spacing, 0)
|
||||
|
||||
# r1341
|
||||
eq_(s.wrap_before, False)
|
||||
eq_(s.horizontal_alignment, mapnik2.horizontal_alignment.MIDDLE)
|
||||
eq_(s.justify_alignment, mapnik2.justify_alignment.MIDDLE)
|
||||
eq_(s.horizontal_alignment, mapnik.horizontal_alignment.MIDDLE)
|
||||
eq_(s.justify_alignment, mapnik.justify_alignment.MIDDLE)
|
||||
eq_(s.opacity, 1.0)
|
||||
|
||||
# r2300
|
||||
|
@ -70,7 +70,7 @@ def test_shieldsymbolizer_init():
|
|||
|
||||
eq_(s.transform, 'matrix(1, 0, 0, 1, 0, 0)')
|
||||
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik2.org/ticket/348")
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik.org/ticket/348")
|
||||
eq_(s.fontset, '')
|
||||
|
||||
|
||||
|
@ -79,53 +79,53 @@ def test_shieldsymbolizer_init():
|
|||
# so it does not make sense to throw...
|
||||
#@raises(RuntimeError)
|
||||
#def test_shieldsymbolizer_missing_image():
|
||||
# s = mapnik2.ShieldSymbolizer(mapnik2.Expression('[Field Name]'), 'DejaVu Sans Bold', 6, mapnik2.Color('#000000'), mapnik2.PathExpression('../#data/images/broken.png'))
|
||||
# s = mapnik.ShieldSymbolizer(mapnik.Expression('[Field Name]'), 'DejaVu Sans Bold', 6, mapnik.Color('#000000'), mapnik.PathExpression('../#data/images/broken.png'))
|
||||
|
||||
def test_polygonsymbolizer_init():
|
||||
p = mapnik2.PolygonSymbolizer()
|
||||
p = mapnik.PolygonSymbolizer()
|
||||
|
||||
eq_(p.fill, mapnik2.Color('gray'))
|
||||
eq_(p.fill, mapnik.Color('gray'))
|
||||
eq_(p.fill_opacity, 1)
|
||||
eq_(p.placement, mapnik2.point_placement.CENTROID)
|
||||
eq_(p.placement, mapnik.point_placement.CENTROID)
|
||||
|
||||
p = mapnik2.PolygonSymbolizer(mapnik2.Color('blue'))
|
||||
p.placement = mapnik2.point_placement.INTERIOR
|
||||
p = mapnik.PolygonSymbolizer(mapnik.Color('blue'))
|
||||
p.placement = mapnik.point_placement.INTERIOR
|
||||
|
||||
eq_(p.fill, mapnik2.Color('blue'))
|
||||
eq_(p.fill, mapnik.Color('blue'))
|
||||
eq_(p.fill_opacity, 1)
|
||||
eq_(p.placement, mapnik2.point_placement.INTERIOR)
|
||||
eq_(p.placement, mapnik.point_placement.INTERIOR)
|
||||
|
||||
# PointSymbolizer initialization
|
||||
def test_pointsymbolizer_init():
|
||||
p = mapnik2.PointSymbolizer()
|
||||
p = mapnik.PointSymbolizer()
|
||||
eq_(p.allow_overlap, False)
|
||||
eq_(p.opacity,1)
|
||||
eq_(p.filename,'')
|
||||
eq_(p.ignore_placement,False)
|
||||
eq_(p.placement, mapnik2.point_placement.CENTROID)
|
||||
eq_(p.placement, mapnik.point_placement.CENTROID)
|
||||
|
||||
p = mapnik2.PointSymbolizer(mapnik2.PathExpression("../data/images/dummy.png"))
|
||||
p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/dummy.png"))
|
||||
p.allow_overlap = True
|
||||
p.opacity = 0.5
|
||||
p.ignore_placement = True
|
||||
p.placement = mapnik2.point_placement.INTERIOR
|
||||
p.placement = mapnik.point_placement.INTERIOR
|
||||
eq_(p.allow_overlap, True)
|
||||
eq_(p.opacity, 0.5)
|
||||
eq_(p.filename,'../data/images/dummy.png')
|
||||
eq_(p.ignore_placement,True)
|
||||
eq_(p.placement, mapnik2.point_placement.INTERIOR)
|
||||
eq_(p.placement, mapnik.point_placement.INTERIOR)
|
||||
|
||||
# PointSymbolizer missing image file
|
||||
# images paths are now PathExpressions are evaluated at runtime
|
||||
# so it does not make sense to throw...
|
||||
#@raises(RuntimeError)
|
||||
#def test_pointsymbolizer_missing_image():
|
||||
# p = mapnik2.PointSymbolizer(mapnik2.PathExpression("../data/images/broken.png"))
|
||||
# p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/broken.png"))
|
||||
|
||||
# PointSymbolizer pickling
|
||||
def test_pointsymbolizer_pickle():
|
||||
raise Todo("point_symbolizer pickling currently disabled")
|
||||
p = mapnik2.PointSymbolizer(mapnik2.PathExpression("../data/images/dummy.png"))
|
||||
p = mapnik.PointSymbolizer(mapnik.PathExpression("../data/images/dummy.png"))
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# image type, width, and height only used in contructor...
|
||||
eq_(p.filename, p2.filename)
|
||||
|
@ -136,19 +136,19 @@ def test_pointsymbolizer_pickle():
|
|||
|
||||
# PolygonSymbolizer initialization
|
||||
def test_polygonsymbolizer_init():
|
||||
p = mapnik2.PolygonSymbolizer()
|
||||
p = mapnik.PolygonSymbolizer()
|
||||
|
||||
eq_(p.fill, mapnik2.Color('gray'))
|
||||
eq_(p.fill, mapnik.Color('gray'))
|
||||
eq_(p.fill_opacity, 1)
|
||||
|
||||
p = mapnik2.PolygonSymbolizer(mapnik2.Color('blue'))
|
||||
p = mapnik.PolygonSymbolizer(mapnik.Color('blue'))
|
||||
|
||||
eq_(p.fill, mapnik2.Color('blue'))
|
||||
eq_(p.fill, mapnik.Color('blue'))
|
||||
eq_(p.fill_opacity, 1)
|
||||
|
||||
# PolygonSymbolizer pickling
|
||||
def test_polygonsymbolizer_pickle():
|
||||
p = mapnik2.PolygonSymbolizer(mapnik2.Color('black'))
|
||||
p = mapnik.PolygonSymbolizer(mapnik.Color('black'))
|
||||
p.fill_opacity = .5
|
||||
# does not work for some reason...
|
||||
#eq_(pickle.loads(pickle.dumps(p)), p)
|
||||
|
@ -159,28 +159,28 @@ def test_polygonsymbolizer_pickle():
|
|||
|
||||
# Stroke initialization
|
||||
def test_stroke_init():
|
||||
s = mapnik2.Stroke()
|
||||
s = mapnik.Stroke()
|
||||
|
||||
eq_(s.width, 1)
|
||||
eq_(s.opacity, 1)
|
||||
eq_(s.color, mapnik2.Color('black'))
|
||||
eq_(s.line_cap, mapnik2.line_cap.BUTT_CAP)
|
||||
eq_(s.line_join, mapnik2.line_join.MITER_JOIN)
|
||||
eq_(s.color, mapnik.Color('black'))
|
||||
eq_(s.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(s.line_join, mapnik.line_join.MITER_JOIN)
|
||||
eq_(s.gamma,1.0)
|
||||
|
||||
s = mapnik2.Stroke(mapnik2.Color('blue'), 5.0)
|
||||
s = mapnik.Stroke(mapnik.Color('blue'), 5.0)
|
||||
s.gamma = .5
|
||||
|
||||
eq_(s.width, 5)
|
||||
eq_(s.opacity, 1)
|
||||
eq_(s.color, mapnik2.Color('blue'))
|
||||
eq_(s.color, mapnik.Color('blue'))
|
||||
eq_(s.gamma, .5)
|
||||
eq_(s.line_cap, mapnik2.line_cap.BUTT_CAP)
|
||||
eq_(s.line_join, mapnik2.line_join.MITER_JOIN)
|
||||
eq_(s.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(s.line_join, mapnik.line_join.MITER_JOIN)
|
||||
|
||||
# Stroke dashes
|
||||
def test_stroke_dash_arrays():
|
||||
s = mapnik2.Stroke()
|
||||
s = mapnik.Stroke()
|
||||
s.add_dash(1,2)
|
||||
s.add_dash(3,4)
|
||||
s.add_dash(5,6)
|
||||
|
@ -189,10 +189,10 @@ def test_stroke_dash_arrays():
|
|||
|
||||
# Stroke pickling
|
||||
def test_stroke_pickle():
|
||||
s = mapnik2.Stroke(mapnik2.Color('black'),4.5)
|
||||
s = mapnik.Stroke(mapnik.Color('black'),4.5)
|
||||
|
||||
eq_(s.width, 4.5)
|
||||
eq_(s.color, mapnik2.Color('black'))
|
||||
eq_(s.color, mapnik.Color('black'))
|
||||
|
||||
s.add_dash(1,2)
|
||||
s.add_dash(3,4)
|
||||
|
@ -209,34 +209,34 @@ def test_stroke_pickle():
|
|||
|
||||
# LineSymbolizer initialization
|
||||
def test_linesymbolizer_init():
|
||||
l = mapnik2.LineSymbolizer()
|
||||
l = mapnik.LineSymbolizer()
|
||||
|
||||
eq_(l.stroke.width, 1)
|
||||
eq_(l.stroke.opacity, 1)
|
||||
eq_(l.stroke.color, mapnik2.Color('black'))
|
||||
eq_(l.stroke.line_cap, mapnik2.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik2.line_join.MITER_JOIN)
|
||||
eq_(l.stroke.color, mapnik.Color('black'))
|
||||
eq_(l.stroke.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik.line_join.MITER_JOIN)
|
||||
|
||||
l = mapnik2.LineSymbolizer(mapnik2.Color('blue'), 5.0)
|
||||
l = mapnik.LineSymbolizer(mapnik.Color('blue'), 5.0)
|
||||
|
||||
eq_(l.stroke.width, 5)
|
||||
eq_(l.stroke.opacity, 1)
|
||||
eq_(l.stroke.color, mapnik2.Color('blue'))
|
||||
eq_(l.stroke.line_cap, mapnik2.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik2.line_join.MITER_JOIN)
|
||||
eq_(l.stroke.color, mapnik.Color('blue'))
|
||||
eq_(l.stroke.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik.line_join.MITER_JOIN)
|
||||
|
||||
s = mapnik2.Stroke(mapnik2.Color('blue'), 5.0)
|
||||
l = mapnik2.LineSymbolizer(s)
|
||||
s = mapnik.Stroke(mapnik.Color('blue'), 5.0)
|
||||
l = mapnik.LineSymbolizer(s)
|
||||
|
||||
eq_(l.stroke.width, 5)
|
||||
eq_(l.stroke.opacity, 1)
|
||||
eq_(l.stroke.color, mapnik2.Color('blue'))
|
||||
eq_(l.stroke.line_cap, mapnik2.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik2.line_join.MITER_JOIN)
|
||||
eq_(l.stroke.color, mapnik.Color('blue'))
|
||||
eq_(l.stroke.line_cap, mapnik.line_cap.BUTT_CAP)
|
||||
eq_(l.stroke.line_join, mapnik.line_join.MITER_JOIN)
|
||||
|
||||
# LineSymbolizer pickling
|
||||
def test_linesymbolizer_pickle():
|
||||
p = mapnik2.LineSymbolizer()
|
||||
p = mapnik.LineSymbolizer()
|
||||
p2 = pickle.loads(pickle.dumps(p,pickle.HIGHEST_PROTOCOL))
|
||||
# line and stroke eq fails, so we compare attributes for now..
|
||||
s,s2 = p.stroke, p2.stroke
|
||||
|
@ -249,7 +249,7 @@ def test_linesymbolizer_pickle():
|
|||
|
||||
# Shapefile initialization
|
||||
def test_shapefile_init():
|
||||
s = mapnik2.Shapefile(file='../../demo/data/boundaries')
|
||||
s = mapnik.Shapefile(file='../../demo/data/boundaries')
|
||||
|
||||
e = s.envelope()
|
||||
|
||||
|
@ -260,7 +260,7 @@ def test_shapefile_init():
|
|||
|
||||
# Shapefile properties
|
||||
def test_shapefile_properties():
|
||||
s = mapnik2.Shapefile(file='../../demo/data/boundaries', encoding='latin1')
|
||||
s = mapnik.Shapefile(file='../../demo/data/boundaries', encoding='latin1')
|
||||
f = s.features_at_point(s.envelope().center()).features[0]
|
||||
|
||||
eq_(f['CGNS_FID'], u'6f733341ba2011d892e2080020a0f4c9')
|
||||
|
@ -279,22 +279,22 @@ def test_shapefile_properties():
|
|||
|
||||
# TextSymbolizer initialization
|
||||
def test_textsymbolizer_init():
|
||||
ts = mapnik2.TextSymbolizer(mapnik2.Expression('[Field_Name]'), 'Font Name', 8, mapnik2.Color('black'))
|
||||
ts = mapnik.TextSymbolizer(mapnik.Expression('[Field_Name]'), 'Font Name', 8, mapnik.Color('black'))
|
||||
|
||||
eq_(str(ts.name), str(mapnik2.Expression('[Field_Name]')))
|
||||
eq_(str(ts.name), str(mapnik.Expression('[Field_Name]')))
|
||||
eq_(ts.face_name, 'Font Name')
|
||||
eq_(ts.text_size, 8)
|
||||
eq_(ts.fill, mapnik2.Color('black'))
|
||||
eq_(ts.label_placement, mapnik2.label_placement.POINT_PLACEMENT)
|
||||
eq_(ts.fill, mapnik.Color('black'))
|
||||
eq_(ts.label_placement, mapnik.label_placement.POINT_PLACEMENT)
|
||||
|
||||
# TextSymbolizer pickling
|
||||
def test_textsymbolizer_pickle():
|
||||
ts = mapnik2.TextSymbolizer(mapnik2.Expression('[Field_Name]'), 'Font Name', 8, mapnik2.Color('black'))
|
||||
ts = mapnik.TextSymbolizer(mapnik.Expression('[Field_Name]'), 'Font Name', 8, mapnik.Color('black'))
|
||||
|
||||
eq_(str(ts.name), str(mapnik2.Expression('[Field_Name]')))
|
||||
eq_(str(ts.name), str(mapnik.Expression('[Field_Name]')))
|
||||
eq_(ts.face_name, 'Font Name')
|
||||
eq_(ts.text_size, 8)
|
||||
eq_(ts.fill, mapnik2.Color('black'))
|
||||
eq_(ts.fill, mapnik.Color('black'))
|
||||
|
||||
raise Todo("text_symbolizer pickling currently disabled")
|
||||
|
||||
|
@ -333,15 +333,15 @@ def test_textsymbolizer_pickle():
|
|||
# r2300
|
||||
eq_(s.minimum_padding, 0.0)
|
||||
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik2.org/ticket/348")
|
||||
raise Todo("FontSet pickling support needed: http://trac.mapnik.org/ticket/348")
|
||||
eq_(ts.fontset, ts2.fontset)
|
||||
|
||||
|
||||
# Map initialization
|
||||
def test_layer_init():
|
||||
l = mapnik2.Layer('test')
|
||||
l = mapnik.Layer('test')
|
||||
eq_(l.name,'test')
|
||||
eq_(l.envelope(),mapnik2.Box2d())
|
||||
eq_(l.envelope(),mapnik.Box2d())
|
||||
eq_(l.clear_label_cache,False)
|
||||
eq_(l.cache_features,False)
|
||||
eq_(l.visible(1),True)
|
||||
|
@ -354,14 +354,14 @@ def test_layer_init():
|
|||
|
||||
# Map initialization
|
||||
def test_map_init():
|
||||
m = mapnik2.Map(256, 256)
|
||||
m = mapnik.Map(256, 256)
|
||||
|
||||
eq_(m.width, 256)
|
||||
eq_(m.height, 256)
|
||||
eq_(m.srs, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
|
||||
eq_(m.base, '')
|
||||
|
||||
m = mapnik2.Map(256, 256, '+proj=latlong')
|
||||
m = mapnik.Map(256, 256, '+proj=latlong')
|
||||
eq_(m.srs, '+proj=latlong')
|
||||
|
||||
# Map initialization from string
|
||||
|
@ -387,19 +387,19 @@ def test_map_init_from_string():
|
|||
</Layer>
|
||||
</Map>'''
|
||||
|
||||
m = mapnik2.Map(600, 300)
|
||||
m = mapnik.Map(600, 300)
|
||||
eq_(m.base, '')
|
||||
mapnik2.load_map_from_string(m, map_string)
|
||||
mapnik.load_map_from_string(m, map_string)
|
||||
eq_(m.base, './')
|
||||
mapnik2.load_map_from_string(m, map_string, False, "") # this "" will have no effect
|
||||
mapnik.load_map_from_string(m, map_string, False, "") # this "" will have no effect
|
||||
eq_(m.base, './')
|
||||
try:
|
||||
mapnik2.load_map_from_string(m, map_string, False, "/tmp")
|
||||
mapnik.load_map_from_string(m, map_string, False, "/tmp")
|
||||
except RuntimeError:
|
||||
pass # runtime error expected because shapefile path should be wrong and datasource will throw
|
||||
eq_(m.base, '/tmp') # /tmp will be set despite the exception because load_map mostly worked
|
||||
m.base = 'foo'
|
||||
mapnik2.load_map_from_string(m, map_string, True, ".")
|
||||
mapnik.load_map_from_string(m, map_string, True, ".")
|
||||
eq_(m.base, '.')
|
||||
raise(Todo("Need to write more map property tests in 'object_test.py'..."))
|
||||
|
||||
|
@ -408,11 +408,11 @@ def test_map_pickle():
|
|||
# Fails due to scale() not matching, possibly other things
|
||||
raise(Todo("Map does not support pickling yet (Tickets #345)."))
|
||||
|
||||
m = mapnik2.Map(256, 256)
|
||||
m = mapnik.Map(256, 256)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
m = mapnik2.Map(256, 256, '+proj=latlong')
|
||||
m = mapnik.Map(256, 256, '+proj=latlong')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(m)), m)
|
||||
|
||||
|
@ -420,14 +420,14 @@ def test_map_pickle():
|
|||
|
||||
@raises(Exception) # Boost.Python.ArgumentError
|
||||
def test_color_init_errors():
|
||||
c = mapnik2.Color()
|
||||
c = mapnik.Color()
|
||||
|
||||
@raises(RuntimeError)
|
||||
def test_color_init_errors():
|
||||
c = mapnik2.Color('foo') # mapnik config
|
||||
c = mapnik.Color('foo') # mapnik config
|
||||
|
||||
def test_color_init():
|
||||
c = mapnik2.Color('blue')
|
||||
c = mapnik.Color('blue')
|
||||
|
||||
eq_(c.a, 255)
|
||||
eq_(c.r, 0)
|
||||
|
@ -436,7 +436,7 @@ def test_color_init():
|
|||
|
||||
eq_(c.to_hex_string(), '#0000ff')
|
||||
|
||||
c = mapnik2.Color('#f2eff9')
|
||||
c = mapnik.Color('#f2eff9')
|
||||
|
||||
eq_(c.a, 255)
|
||||
eq_(c.r, 242)
|
||||
|
@ -445,7 +445,7 @@ def test_color_init():
|
|||
|
||||
eq_(c.to_hex_string(), '#f2eff9')
|
||||
|
||||
c = mapnik2.Color('rgb(50%,50%,50%)')
|
||||
c = mapnik.Color('rgb(50%,50%,50%)')
|
||||
|
||||
eq_(c.a, 255)
|
||||
eq_(c.r, 128)
|
||||
|
@ -454,7 +454,7 @@ def test_color_init():
|
|||
|
||||
eq_(c.to_hex_string(), '#808080')
|
||||
|
||||
c = mapnik2.Color(0, 64, 128)
|
||||
c = mapnik.Color(0, 64, 128)
|
||||
|
||||
eq_(c.a, 255)
|
||||
eq_(c.r, 0)
|
||||
|
@ -463,7 +463,7 @@ def test_color_init():
|
|||
|
||||
eq_(c.to_hex_string(), '#004080')
|
||||
|
||||
c = mapnik2.Color(0, 64, 128, 192)
|
||||
c = mapnik.Color(0, 64, 128, 192)
|
||||
|
||||
eq_(c.a, 192)
|
||||
eq_(c.r, 0)
|
||||
|
@ -475,9 +475,9 @@ def test_color_init():
|
|||
# Color equality
|
||||
def test_color_equality():
|
||||
|
||||
c1 = mapnik2.Color('blue')
|
||||
c2 = mapnik2.Color(0,0,255)
|
||||
c3 = mapnik2.Color('black')
|
||||
c1 = mapnik.Color('blue')
|
||||
c2 = mapnik.Color(0,0,255)
|
||||
c3 = mapnik.Color('black')
|
||||
|
||||
|
||||
c3.r = 0
|
||||
|
@ -488,9 +488,9 @@ def test_color_equality():
|
|||
eq_(c1, c2)
|
||||
eq_(c1, c3)
|
||||
|
||||
c1 = mapnik2.Color(0, 64, 128)
|
||||
c2 = mapnik2.Color(0, 64, 128)
|
||||
c3 = mapnik2.Color(0, 0, 0)
|
||||
c1 = mapnik.Color(0, 64, 128)
|
||||
c2 = mapnik.Color(0, 64, 128)
|
||||
c3 = mapnik.Color(0, 0, 0)
|
||||
|
||||
c3.r = 0
|
||||
c3.g = 64
|
||||
|
@ -499,9 +499,9 @@ def test_color_equality():
|
|||
eq_(c1, c2)
|
||||
eq_(c1, c3)
|
||||
|
||||
c1 = mapnik2.Color(0, 64, 128, 192)
|
||||
c2 = mapnik2.Color(0, 64, 128, 192)
|
||||
c3 = mapnik2.Color(0, 0, 0, 255)
|
||||
c1 = mapnik.Color(0, 64, 128, 192)
|
||||
c2 = mapnik.Color(0, 64, 128, 192)
|
||||
c3 = mapnik.Color(0, 0, 0, 255)
|
||||
|
||||
c3.r = 0
|
||||
c3.g = 64
|
||||
|
@ -511,35 +511,35 @@ def test_color_equality():
|
|||
eq_(c1, c2)
|
||||
eq_(c1, c3)
|
||||
|
||||
c1 = mapnik2.Color('rgb(50%,50%,50%)')
|
||||
c2 = mapnik2.Color(128, 128, 128, 255)
|
||||
c3 = mapnik2.Color('#808080')
|
||||
c4 = mapnik2.Color('gray')
|
||||
c1 = mapnik.Color('rgb(50%,50%,50%)')
|
||||
c2 = mapnik.Color(128, 128, 128, 255)
|
||||
c3 = mapnik.Color('#808080')
|
||||
c4 = mapnik.Color('gray')
|
||||
|
||||
eq_(c1, c2)
|
||||
eq_(c1, c3)
|
||||
eq_(c1, c4)
|
||||
|
||||
c1 = mapnik2.Color('hsl(0, 100%, 50%)') # red
|
||||
c2 = mapnik2.Color('hsl(120, 100%, 50%)') # lime
|
||||
c3 = mapnik2.Color('hsla(240, 100%, 50%, 0.5)') # semi-transparent solid blue
|
||||
c1 = mapnik.Color('hsl(0, 100%, 50%)') # red
|
||||
c2 = mapnik.Color('hsl(120, 100%, 50%)') # lime
|
||||
c3 = mapnik.Color('hsla(240, 100%, 50%, 0.5)') # semi-transparent solid blue
|
||||
|
||||
eq_(c1, mapnik2.Color('red'))
|
||||
eq_(c2, mapnik2.Color('lime'))
|
||||
eq_(c3, mapnik2.Color(0,0,255,128))
|
||||
eq_(c1, mapnik.Color('red'))
|
||||
eq_(c2, mapnik.Color('lime'))
|
||||
eq_(c3, mapnik.Color(0,0,255,128))
|
||||
|
||||
|
||||
# Color pickling
|
||||
def test_color_pickle():
|
||||
c = mapnik2.Color('blue')
|
||||
c = mapnik.Color('blue')
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik2.Color(0, 64, 128)
|
||||
c = mapnik.Color(0, 64, 128)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
c = mapnik2.Color(0, 64, 128, 192)
|
||||
c = mapnik.Color(0, 64, 128, 192)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(c)), c)
|
||||
|
||||
|
@ -548,7 +548,7 @@ def test_rule_init():
|
|||
min_scale = 5
|
||||
max_scale = 10
|
||||
|
||||
r = mapnik2.Rule()
|
||||
r = mapnik.Rule()
|
||||
|
||||
eq_(r.name, '')
|
||||
eq_(r.title, '')
|
||||
|
@ -557,19 +557,19 @@ def test_rule_init():
|
|||
eq_(r.has_else(), False)
|
||||
eq_(r.has_also(), False)
|
||||
|
||||
r = mapnik2.Rule()
|
||||
r = mapnik.Rule()
|
||||
|
||||
r.set_else(True)
|
||||
eq_(r.has_else(), True)
|
||||
eq_(r.has_also(), False)
|
||||
|
||||
r = mapnik2.Rule()
|
||||
r = mapnik.Rule()
|
||||
|
||||
r.set_also(True)
|
||||
eq_(r.has_else(), False)
|
||||
eq_(r.has_also(), True)
|
||||
|
||||
r = mapnik2.Rule("Name")
|
||||
r = mapnik.Rule("Name")
|
||||
|
||||
eq_(r.name, 'Name')
|
||||
eq_(r.title, '')
|
||||
|
@ -578,7 +578,7 @@ def test_rule_init():
|
|||
eq_(r.has_else(), False)
|
||||
eq_(r.has_also(), False)
|
||||
|
||||
r = mapnik2.Rule("Name", "Title")
|
||||
r = mapnik.Rule("Name", "Title")
|
||||
|
||||
eq_(r.name, 'Name')
|
||||
eq_(r.title, 'Title')
|
||||
|
@ -587,7 +587,7 @@ def test_rule_init():
|
|||
eq_(r.has_else(), False)
|
||||
eq_(r.has_also(), False)
|
||||
|
||||
r = mapnik2.Rule("Name", "Title", min_scale)
|
||||
r = mapnik.Rule("Name", "Title", min_scale)
|
||||
|
||||
eq_(r.name, 'Name')
|
||||
eq_(r.title, 'Title')
|
||||
|
@ -596,7 +596,7 @@ def test_rule_init():
|
|||
eq_(r.has_else(), False)
|
||||
eq_(r.has_also(), False)
|
||||
|
||||
r = mapnik2.Rule("Name", "Title", min_scale, max_scale)
|
||||
r = mapnik.Rule("Name", "Title", min_scale, max_scale)
|
||||
|
||||
eq_(r.name, 'Name')
|
||||
eq_(r.title, 'Title')
|
||||
|
@ -607,14 +607,14 @@ def test_rule_init():
|
|||
|
||||
# Coordinate initialization
|
||||
def test_coord_init():
|
||||
c = mapnik2.Coord(100, 100)
|
||||
c = mapnik.Coord(100, 100)
|
||||
|
||||
eq_(c.x, 100)
|
||||
eq_(c.y, 100)
|
||||
|
||||
# Coordinate multiplication
|
||||
def test_coord_multiplication():
|
||||
c = mapnik2.Coord(100, 100)
|
||||
c = mapnik.Coord(100, 100)
|
||||
c *= 2
|
||||
|
||||
eq_(c.x, 200)
|
||||
|
@ -622,7 +622,7 @@ def test_coord_multiplication():
|
|||
|
||||
# Box2d initialization
|
||||
def test_envelope_init():
|
||||
e = mapnik2.Box2d(100, 100, 200, 200)
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
|
||||
assert_true(e.contains(100, 100))
|
||||
assert_true(e.contains(100, 200))
|
||||
|
@ -661,9 +661,9 @@ def test_envelope_init():
|
|||
|
||||
# Box2d static initialization
|
||||
def test_envelope_static_init():
|
||||
e = mapnik2.Box2d.from_string('100 100 200 200')
|
||||
e2 = mapnik2.Box2d.from_string('100,100,200,200')
|
||||
e3 = mapnik2.Box2d.from_string('100 , 100 , 200 , 200')
|
||||
e = mapnik.Box2d.from_string('100 100 200 200')
|
||||
e2 = mapnik.Box2d.from_string('100,100,200,200')
|
||||
e3 = mapnik.Box2d.from_string('100 , 100 , 200 , 200')
|
||||
eq_(e,e2)
|
||||
eq_(e,e3)
|
||||
|
||||
|
@ -704,13 +704,13 @@ def test_envelope_static_init():
|
|||
|
||||
# Box2d pickling
|
||||
def test_envelope_pickle():
|
||||
e = mapnik2.Box2d(100, 100, 200, 200)
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
|
||||
eq_(pickle.loads(pickle.dumps(e)), e)
|
||||
|
||||
# Box2d multiplication
|
||||
def test_envelope_multiplication():
|
||||
e = mapnik2.Box2d(100, 100, 200, 200)
|
||||
e = mapnik.Box2d(100, 100, 200, 200)
|
||||
e *= 2
|
||||
|
||||
assert_true(e.contains(50, 50))
|
||||
|
@ -741,20 +741,20 @@ def test_envelope_multiplication():
|
|||
|
||||
# Box2d clipping
|
||||
def test_envelope_pickle():
|
||||
e1 = mapnik2.Box2d(-180,-90,180,90)
|
||||
e2 = mapnik2.Box2d(-120,40,-110,48)
|
||||
e1 = mapnik.Box2d(-180,-90,180,90)
|
||||
e2 = mapnik.Box2d(-120,40,-110,48)
|
||||
e1.clip(e2)
|
||||
eq_(e1,e2)
|
||||
|
||||
# madagascar in merc
|
||||
e1 = mapnik2.Box2d(4772116.5490, -2744395.0631, 5765186.4203, -1609458.0673)
|
||||
e2 = mapnik2.Box2d(5124338.3753, -2240522.1727, 5207501.8621, -2130452.8520)
|
||||
e1 = mapnik.Box2d(4772116.5490, -2744395.0631, 5765186.4203, -1609458.0673)
|
||||
e2 = mapnik.Box2d(5124338.3753, -2240522.1727, 5207501.8621, -2130452.8520)
|
||||
e1.clip(e2)
|
||||
eq_(e1,e2)
|
||||
|
||||
# nz in lon/lat
|
||||
e1 = mapnik2.Box2d(163.8062, -47.1897, 179.3628, -33.9069)
|
||||
e2 = mapnik2.Box2d(173.7378, -39.6395, 174.4849, -38.9252)
|
||||
e1 = mapnik.Box2d(163.8062, -47.1897, 179.3628, -33.9069)
|
||||
e2 = mapnik.Box2d(173.7378, -39.6395, 174.4849, -38.9252)
|
||||
e1.clip(e2)
|
||||
eq_(e1,e2)
|
||||
|
||||
|
|
271
tests/python_tests/postgis_test.py
Normal file
271
tests/python_tests/postgis_test.py
Normal file
|
@ -0,0 +1,271 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from nose.tools import *
|
||||
import atexit
|
||||
import time
|
||||
from utilities import execution_path
|
||||
from subprocess import Popen, PIPE
|
||||
import os, mapnik
|
||||
|
||||
MAPNIK_TEST_DBNAME = 'mapnik-tmp-postgis-test-db'
|
||||
POSTGIS_TEMPLATE_DBNAME = 'template_postgis'
|
||||
SHAPEFILE = os.path.join(execution_path('.'),'../data/shp/world_merc.shp')
|
||||
SQL_DUMPS = os.path.join(execution_path('.'),'../data/sql')
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
# from another directory we need to chdir()
|
||||
os.chdir(execution_path('.'))
|
||||
|
||||
def call(cmd,silent=False):
|
||||
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||
if not stderr:
|
||||
return stdin.strip()
|
||||
elif not silent and not 'NOTICE' in stderr:
|
||||
raise RuntimeError(stderr.strip())
|
||||
|
||||
def psql_can_connect():
|
||||
"""Test ability to connect to a postgis template db with no options.
|
||||
|
||||
Basically, to run these tests your user must have full read
|
||||
access over unix sockets without supplying a password. This
|
||||
keeps these tests simple and focused on postgis not on postgres
|
||||
auth issues.
|
||||
"""
|
||||
try:
|
||||
call('psql %s -c "select postgis_version()"' % POSTGIS_TEMPLATE_DBNAME)
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests (connection)'
|
||||
return False
|
||||
|
||||
def shp2pgsql_on_path():
|
||||
"""Test for presence of shp2pgsql on the user path.
|
||||
|
||||
We require this program to load test data into a temporarily database.
|
||||
"""
|
||||
try:
|
||||
call('shp2pgsql')
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests (shp2pgsql)'
|
||||
return False
|
||||
|
||||
def createdb_and_dropdb_on_path():
|
||||
"""Test for presence of dropdb/createdb on user path.
|
||||
|
||||
We require these programs to setup and teardown the testing db.
|
||||
"""
|
||||
try:
|
||||
call('createdb --help')
|
||||
call('dropdb --help')
|
||||
return True
|
||||
except RuntimeError, e:
|
||||
print 'Notice: skipping postgis tests (createdb/dropdb)'
|
||||
return False
|
||||
|
||||
insert_table_1 = """
|
||||
CREATE TABLE test(gid serial PRIMARY KEY, geom geometry);
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POINT(-2 2)'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTIPOINT(2 1,1 2)'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;LINESTRING(0 0,1 1,1 2)'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTILINESTRING((1 0,0 1,3 2),(3 2,5 4))'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;MULTIPOLYGON(((1 1,3 1,3 3,1 3,1 1),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))'));
|
||||
INSERT INTO test(geom) values (GeomFromEWKT('SRID=4326;GEOMETRYCOLLECTION(POLYGON((1 1, 2 1, 2 2, 1 2,1 1)),POINT(2 3),LINESTRING(2 3,3 4))'));
|
||||
"""
|
||||
|
||||
insert_table_2 = """
|
||||
CREATE TABLE test2(manual_id int4 PRIMARY KEY, geom geometry);
|
||||
INSERT INTO test2(manual_id, geom) values (0, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test2(manual_id, geom) values (1, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test2(manual_id, geom) values (1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test2(manual_id, geom) values (-1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test2(manual_id, geom) values (2147483647, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test2(manual_id, geom) values (-2147483648, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
"""
|
||||
|
||||
insert_table_3 = """
|
||||
CREATE TABLE test3(non_id bigint, manual_id int4, geom geometry);
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, 0, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, 1, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, 1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, -1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, 2147483647, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test3(non_id, manual_id, geom) values (9223372036854775807, -2147483648, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
"""
|
||||
|
||||
insert_table_4 = """
|
||||
CREATE TABLE test4(non_id int4, manual_id int8 PRIMARY KEY, geom geometry);
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, 0, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, 1, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, 1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, -1000, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, 2147483647, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test4(non_id, manual_id, geom) values (0, -2147483648, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
"""
|
||||
|
||||
insert_table_5 = """
|
||||
CREATE TABLE test5(non_id int4, manual_id numeric PRIMARY KEY, geom geometry);
|
||||
INSERT INTO test5(non_id, manual_id, geom) values (0, -1, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
INSERT INTO test5(non_id, manual_id, geom) values (0, 1, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
"""
|
||||
|
||||
insert_table_6 = '''
|
||||
CREATE TABLE "tableWithMixedCase"(gid serial PRIMARY KEY, geom geometry);
|
||||
INSERT INTO "tableWithMixedCase"(geom) values (ST_MakePoint(0,0));
|
||||
INSERT INTO "tableWithMixedCase"(geom) values (ST_MakePoint(0,1));
|
||||
INSERT INTO "tableWithMixedCase"(geom) values (ST_MakePoint(1,0));
|
||||
INSERT INTO "tableWithMixedCase"(geom) values (ST_MakePoint(1,1));
|
||||
'''
|
||||
|
||||
insert_table_7 = '''
|
||||
CREATE TABLE test6(first_id int4, second_id int4,PRIMARY KEY (first_id,second_id), geom geometry);
|
||||
INSERT INTO test6(first_id, second_id, geom) values (0, 0, GeomFromEWKT('SRID=4326;POINT(0 0)'));
|
||||
'''
|
||||
|
||||
insert_table_8 = '''
|
||||
CREATE TABLE test7(gid serial PRIMARY KEY, geom geometry);
|
||||
INSERT INTO test7(gid, geom) values (1, GeomFromEWKT('SRID=4326;GEOMETRYCOLLECTION(MULTILINESTRING((10 10,20 20,10 40),(40 40,30 30,40 20,30 10)),LINESTRING EMPTY)'));
|
||||
'''
|
||||
|
||||
def postgis_setup():
|
||||
call('dropdb %s' % MAPNIK_TEST_DBNAME,silent=True)
|
||||
call('createdb -T %s %s' % (POSTGIS_TEMPLATE_DBNAME,MAPNIK_TEST_DBNAME),silent=False)
|
||||
call('shp2pgsql -s 3857 -g geom -W LATIN1 %s world_merc | psql -q %s' % (SHAPEFILE,MAPNIK_TEST_DBNAME), silent=True)
|
||||
call('''psql -q %s -c "CREATE TABLE \"empty\" (key serial);SELECT AddGeometryColumn('','empty','geom','-1','GEOMETRY',4);"''' % MAPNIK_TEST_DBNAME,silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_1),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_2),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_3),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_4),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_5),silent=False)
|
||||
call("""psql -q %s -c '%s'""" % (MAPNIK_TEST_DBNAME,insert_table_6),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_7),silent=False)
|
||||
call('''psql -q %s -c "%s"''' % (MAPNIK_TEST_DBNAME,insert_table_8),silent=False)
|
||||
|
||||
def postgis_takedown():
|
||||
pass
|
||||
# fails as the db is in use: https://github.com/mapnik/mapnik/issues/960
|
||||
#call('dropdb %s' % MAPNIK_TEST_DBNAME)
|
||||
|
||||
if 'postgis' in mapnik.DatasourceCache.instance().plugin_names() \
|
||||
and createdb_and_dropdb_on_path() \
|
||||
and psql_can_connect() \
|
||||
and shp2pgsql_on_path():
|
||||
|
||||
# initialize test database
|
||||
postgis_setup()
|
||||
|
||||
def test_feature():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='world_merc')
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
eq_(feature['gid'],1)
|
||||
eq_(feature['fips'],u'AC')
|
||||
eq_(feature['iso2'],u'AG')
|
||||
eq_(feature['iso3'],u'ATG')
|
||||
eq_(feature['un'],28)
|
||||
eq_(feature['name'],u'Antigua and Barbuda')
|
||||
eq_(feature['area'],44)
|
||||
eq_(feature['pop2005'],83039)
|
||||
eq_(feature['region'],19)
|
||||
eq_(feature['subregion'],29)
|
||||
eq_(feature['lon'],-61.783)
|
||||
eq_(feature['lat'],17.078)
|
||||
|
||||
def test_subquery():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select * from world_merc) as w')
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
eq_(feature['gid'],1)
|
||||
eq_(feature['fips'],u'AC')
|
||||
eq_(feature['iso2'],u'AG')
|
||||
eq_(feature['iso3'],u'ATG')
|
||||
eq_(feature['un'],28)
|
||||
eq_(feature['name'],u'Antigua and Barbuda')
|
||||
eq_(feature['area'],44)
|
||||
eq_(feature['pop2005'],83039)
|
||||
eq_(feature['region'],19)
|
||||
eq_(feature['subregion'],29)
|
||||
eq_(feature['lon'],-61.783)
|
||||
eq_(feature['lat'],17.078)
|
||||
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='(select gid,geom,fips as _fips from world_merc) as w')
|
||||
fs = ds.featureset()
|
||||
feature = fs.next()
|
||||
eq_(feature['gid'],1)
|
||||
eq_(feature['_fips'],u'AC')
|
||||
eq_(len(feature),2)
|
||||
|
||||
def test_geometry_detection():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test',
|
||||
geometry_field='geom')
|
||||
|
||||
def test_disabled_auto_detection_and_subquery():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='''(select geom, 'a'::varchar as name from test2) as t''',
|
||||
geometry_field='geom')
|
||||
fs = ds.featureset()
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),1)
|
||||
eq_(feat['name'],'a')
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),2)
|
||||
eq_(feat['name'],'a')
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),3)
|
||||
eq_(feat['name'],'a')
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),4)
|
||||
eq_(feat['name'],'a')
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),5)
|
||||
eq_(feat['name'],'a')
|
||||
feat = fs.next()
|
||||
eq_(feat.id(),6)
|
||||
eq_(feat['name'],'a')
|
||||
|
||||
|
||||
def test_manually_specified_feature_id_field():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test4',
|
||||
geometry_field='geom',
|
||||
key_field='manual_id')
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next()['manual_id'],0)
|
||||
eq_(fs.next()['manual_id'],1)
|
||||
eq_(fs.next()['manual_id'],1000)
|
||||
eq_(fs.next()['manual_id'],-1000)
|
||||
eq_(fs.next()['manual_id'],2147483647)
|
||||
eq_(fs.next()['manual_id'],-2147483648)
|
||||
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next().id(),0)
|
||||
eq_(fs.next().id(),1)
|
||||
eq_(fs.next().id(),1000)
|
||||
eq_(fs.next().id(),-1000)
|
||||
eq_(fs.next().id(),2147483647)
|
||||
eq_(fs.next().id(),-2147483648)
|
||||
|
||||
def test_numeric_type_feature_id_field():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test5',
|
||||
geometry_field='geom')
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next()['manual_id'],-1)
|
||||
eq_(fs.next()['manual_id'],1)
|
||||
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next().id(),1)
|
||||
eq_(fs.next().id(),2)
|
||||
|
||||
def test_empty_geom():
|
||||
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='test7',
|
||||
geometry_field='geom')
|
||||
fs = ds.featureset()
|
||||
eq_(fs.next()['gid'],1)
|
||||
|
||||
atexit.register(postgis_takedown)
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
#test_auto_detection_and_subquery()
|
||||
[eval(run)() for run in dir() if 'test_' in run]
|
|
@ -2,22 +2,22 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import mapnik2, pickle
|
||||
import mapnik, pickle
|
||||
|
||||
# Tests that exercise map projections.
|
||||
|
||||
def test_normalizing_definition():
|
||||
p = mapnik2.Projection('+init=epsg:4326')
|
||||
p = mapnik.Projection('+init=epsg:4326')
|
||||
expanded = p.expanded()
|
||||
eq_('+proj=longlat' in expanded,True)
|
||||
|
||||
|
||||
# Trac Ticket #128
|
||||
def test_wgs84_inverse_forward():
|
||||
p = mapnik2.Projection('+init=epsg:4326')
|
||||
p = mapnik.Projection('+init=epsg:4326')
|
||||
|
||||
c = mapnik2.Coord(3.01331418311, 43.3333092669)
|
||||
e = mapnik2.Box2d(-122.54345245, 45.12312553, 68.2335581353, 48.231231233)
|
||||
c = mapnik.Coord(3.01331418311, 43.3333092669)
|
||||
e = mapnik.Box2d(-122.54345245, 45.12312553, 68.2335581353, 48.231231233)
|
||||
|
||||
# It appears that the y component changes very slightly, is this OK?
|
||||
# so we test for 'almost equal float values'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#coding=utf8
|
||||
import os
|
||||
import mapnik2
|
||||
import mapnik
|
||||
from utilities import execution_path
|
||||
from nose.tools import *
|
||||
|
||||
|
@ -14,56 +14,56 @@ def test_gen_map():
|
|||
mapxmloutputfile = 'raster_colorizer_test_save.xml'
|
||||
outputfile = 'raster_colorizer_test.png'
|
||||
|
||||
m = mapnik2.Map(800, 600)
|
||||
mapnik2.load_map(m, mapxmlfile)
|
||||
mapnik2.save_map(m, mapxmloutputfile)
|
||||
m = mapnik.Map(800, 600)
|
||||
mapnik.load_map(m, mapxmlfile)
|
||||
mapnik.save_map(m, mapxmloutputfile)
|
||||
m.zoom_all()
|
||||
mapnik2.render_to_file(m, outputfile)
|
||||
mapnik.render_to_file(m, outputfile)
|
||||
|
||||
#test discrete colorizer mode
|
||||
def test_get_color_discrete():
|
||||
#setup
|
||||
colorizer = mapnik2.RasterColorizer();
|
||||
colorizer.default_color = mapnik2.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik2.COLORIZER_DISCRETE;
|
||||
colorizer = mapnik.RasterColorizer();
|
||||
colorizer.default_color = mapnik.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik.COLORIZER_DISCRETE;
|
||||
|
||||
colorizer.add_stop(10, mapnik2.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik2.Color(200,200,200,200));
|
||||
colorizer.add_stop(10, mapnik.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik.Color(200,200,200,200));
|
||||
|
||||
|
||||
|
||||
#should be default colour
|
||||
eq_(colorizer.get_color(-50), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(0), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(-50), mapnik.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(0), mapnik.Color(0,0,0,0));
|
||||
|
||||
#now in stop 1
|
||||
eq_(colorizer.get_color(10), mapnik2.Color(100,100,100,100));
|
||||
eq_(colorizer.get_color(19), mapnik2.Color(100,100,100,100));
|
||||
eq_(colorizer.get_color(10), mapnik.Color(100,100,100,100));
|
||||
eq_(colorizer.get_color(19), mapnik.Color(100,100,100,100));
|
||||
|
||||
#now in stop 2
|
||||
eq_(colorizer.get_color(20), mapnik2.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(1000), mapnik2.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(20), mapnik.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(1000), mapnik.Color(200,200,200,200));
|
||||
|
||||
#test exact colorizer mode
|
||||
def test_get_color_exact():
|
||||
#setup
|
||||
colorizer = mapnik2.RasterColorizer();
|
||||
colorizer.default_color = mapnik2.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik2.COLORIZER_EXACT;
|
||||
colorizer = mapnik.RasterColorizer();
|
||||
colorizer.default_color = mapnik.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik.COLORIZER_EXACT;
|
||||
|
||||
colorizer.add_stop(10, mapnik2.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik2.Color(200,200,200,200));
|
||||
colorizer.add_stop(10, mapnik.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik.Color(200,200,200,200));
|
||||
|
||||
#should be default colour
|
||||
eq_(colorizer.get_color(-50), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(11), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(20.001), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(-50), mapnik.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(11), mapnik.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(20.001), mapnik.Color(0,0,0,0));
|
||||
|
||||
#should be stop 1
|
||||
eq_(colorizer.get_color(10), mapnik2.Color(100,100,100,100));
|
||||
eq_(colorizer.get_color(10), mapnik.Color(100,100,100,100));
|
||||
|
||||
#should be stop 2
|
||||
eq_(colorizer.get_color(20), mapnik2.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(20), mapnik.Color(200,200,200,200));
|
||||
|
||||
|
||||
|
||||
|
@ -71,32 +71,32 @@ def test_get_color_exact():
|
|||
#test linear colorizer mode
|
||||
def test_get_color_linear():
|
||||
#setup
|
||||
colorizer = mapnik2.RasterColorizer();
|
||||
colorizer.default_color = mapnik2.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik2.COLORIZER_LINEAR;
|
||||
colorizer = mapnik.RasterColorizer();
|
||||
colorizer.default_color = mapnik.Color(0,0,0,0);
|
||||
colorizer.default_mode = mapnik.COLORIZER_LINEAR;
|
||||
|
||||
colorizer.add_stop(10, mapnik2.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik2.Color(200,200,200,200));
|
||||
colorizer.add_stop(10, mapnik.Color(100,100,100,100));
|
||||
colorizer.add_stop(20, mapnik.Color(200,200,200,200));
|
||||
|
||||
#should be default colour
|
||||
eq_(colorizer.get_color(-50), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(9.9), mapnik2.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(-50), mapnik.Color(0,0,0,0));
|
||||
eq_(colorizer.get_color(9.9), mapnik.Color(0,0,0,0));
|
||||
|
||||
#should be stop 1
|
||||
eq_(colorizer.get_color(10), mapnik2.Color(100,100,100,100));
|
||||
eq_(colorizer.get_color(10), mapnik.Color(100,100,100,100));
|
||||
|
||||
#should be stop 2
|
||||
eq_(colorizer.get_color(20), mapnik2.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(20), mapnik.Color(200,200,200,200));
|
||||
|
||||
#half way between stops 1 and 2
|
||||
eq_(colorizer.get_color(15), mapnik2.Color(150,150,150,150));
|
||||
eq_(colorizer.get_color(15), mapnik.Color(150,150,150,150));
|
||||
|
||||
#after stop 2
|
||||
eq_(colorizer.get_color(100), mapnik2.Color(200,200,200,200));
|
||||
eq_(colorizer.get_color(100), mapnik.Color(200,200,200,200));
|
||||
|
||||
|
||||
def test_stop_label():
|
||||
stop = mapnik2.ColorizerStop(1, mapnik2.COLORIZER_LINEAR, mapnik2.Color('red'))
|
||||
stop = mapnik.ColorizerStop(1, mapnik.COLORIZER_LINEAR, mapnik.Color('red'))
|
||||
assert not stop.label
|
||||
label = u"32º C".encode('utf8')
|
||||
stop.label = label
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from nose.tools import *
|
||||
from utilities import execution_path, save_data, contains_word
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -13,19 +13,19 @@ def setup():
|
|||
|
||||
def test_dataraster_coloring():
|
||||
srs = '+init=epsg:32630'
|
||||
lyr = mapnik2.Layer('dataraster')
|
||||
lyr.datasource = mapnik2.Gdal(
|
||||
lyr = mapnik.Layer('dataraster')
|
||||
lyr.datasource = mapnik.Gdal(
|
||||
file = '../data/raster/dataraster.tif',
|
||||
band = 1,
|
||||
)
|
||||
lyr.srs = srs
|
||||
_map = mapnik2.Map(256,256, srs)
|
||||
style = mapnik2.Style()
|
||||
rule = mapnik2.Rule()
|
||||
sym = mapnik2.RasterSymbolizer()
|
||||
_map = mapnik.Map(256,256, srs)
|
||||
style = mapnik.Style()
|
||||
rule = mapnik.Rule()
|
||||
sym = mapnik.RasterSymbolizer()
|
||||
# Assigning a colorizer to the RasterSymbolizer tells the later
|
||||
# that it should use it to colorize the raw data raster
|
||||
sym.colorizer = mapnik2.RasterColorizer(mapnik2.COLORIZER_DISCRETE, mapnik2.Color("transparent"))
|
||||
sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color("transparent"))
|
||||
|
||||
for value, color in [
|
||||
( 0, "#0044cc"),
|
||||
|
@ -40,7 +40,7 @@ def test_dataraster_coloring():
|
|||
( 90, "#660066"),
|
||||
( 200, "transparent"),
|
||||
]:
|
||||
sym.colorizer.add_stop(value, mapnik2.Color(color))
|
||||
sym.colorizer.add_stop(value, mapnik.Color(color))
|
||||
rule.symbols.append(sym)
|
||||
style.rules.append(rule)
|
||||
_map.append_style('foo', style)
|
||||
|
@ -48,8 +48,8 @@ def test_dataraster_coloring():
|
|||
_map.layers.append(lyr)
|
||||
_map.zoom_to_box(lyr.envelope())
|
||||
|
||||
im = mapnik2.Image(_map.width,_map.height)
|
||||
mapnik2.render(_map, im)
|
||||
im = mapnik.Image(_map.width,_map.height)
|
||||
mapnik.render(_map, im)
|
||||
# save a png somewhere so we can see it
|
||||
save_data('test_dataraster_coloring.png', im.tostring('png'))
|
||||
imdata = im.tostring()
|
||||
|
@ -58,13 +58,13 @@ def test_dataraster_coloring():
|
|||
|
||||
def test_dataraster_query_point():
|
||||
srs = '+init=epsg:32630'
|
||||
lyr = mapnik2.Layer('dataraster')
|
||||
lyr.datasource = mapnik2.Gdal(
|
||||
lyr = mapnik.Layer('dataraster')
|
||||
lyr.datasource = mapnik.Gdal(
|
||||
file = '../data/raster/dataraster.tif',
|
||||
band = 1,
|
||||
)
|
||||
lyr.srs = srs
|
||||
_map = mapnik2.Map(256,256, srs)
|
||||
_map = mapnik.Map(256,256, srs)
|
||||
_map.layers.append(lyr)
|
||||
|
||||
# point inside raster extent with valid data
|
||||
|
@ -86,11 +86,11 @@ def test_dataraster_query_point():
|
|||
assert len(features) == 0
|
||||
|
||||
def test_load_save_map():
|
||||
map = mapnik2.Map(256,256)
|
||||
map = mapnik.Map(256,256)
|
||||
in_map = "../data/good_maps/raster_symbolizer.xml"
|
||||
mapnik2.load_map(map, in_map)
|
||||
mapnik.load_map(map, in_map)
|
||||
|
||||
out_map = mapnik2.save_map_to_string(map)
|
||||
out_map = mapnik.save_map_to_string(map)
|
||||
assert 'RasterSymbolizer' in out_map
|
||||
assert 'RasterColorizer' in out_map
|
||||
assert 'stop' in out_map
|
||||
|
@ -99,13 +99,13 @@ def test_raster_with_alpha_blends_correctly_with_background():
|
|||
WIDTH = 500
|
||||
HEIGHT = 500
|
||||
|
||||
map = mapnik2.Map(WIDTH, HEIGHT)
|
||||
WHITE = mapnik2.Color(255, 255, 255)
|
||||
map = mapnik.Map(WIDTH, HEIGHT)
|
||||
WHITE = mapnik.Color(255, 255, 255)
|
||||
map.background = WHITE
|
||||
|
||||
style = mapnik2.Style()
|
||||
rule = mapnik2.Rule()
|
||||
symbolizer = mapnik2.RasterSymbolizer()
|
||||
style = mapnik.Style()
|
||||
rule = mapnik.Rule()
|
||||
symbolizer = mapnik.RasterSymbolizer()
|
||||
#XXX: This fixes it, see http://trac.mapnik.org/ticket/759#comment:3
|
||||
# (and remove comment when this test passes)
|
||||
#symbolizer.scaling="bilinear_old"
|
||||
|
@ -115,17 +115,17 @@ def test_raster_with_alpha_blends_correctly_with_background():
|
|||
|
||||
map.append_style('raster_style', style)
|
||||
|
||||
map_layer = mapnik2.Layer('test_layer')
|
||||
map_layer = mapnik.Layer('test_layer')
|
||||
filepath = '../data/raster/white-alpha.png'
|
||||
map_layer.datasource = mapnik2.Gdal(file=filepath)
|
||||
map_layer.datasource = mapnik.Gdal(file=filepath)
|
||||
map_layer.styles.append('raster_style')
|
||||
map.layers.append(map_layer)
|
||||
|
||||
map.zoom_all()
|
||||
|
||||
mim = mapnik2.Image(WIDTH, HEIGHT)
|
||||
mim = mapnik.Image(WIDTH, HEIGHT)
|
||||
|
||||
mapnik2.render(map, mim)
|
||||
mapnik.render(map, mim)
|
||||
save_data('test_raster_with_alpha_blends_correctly_with_background.png',
|
||||
mim.tostring('png'))
|
||||
imdata = mim.tostring()
|
||||
|
@ -135,27 +135,27 @@ def test_raster_with_alpha_blends_correctly_with_background():
|
|||
def test_raster_warping():
|
||||
lyrSrs = "+init=epsg:32630"
|
||||
mapSrs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
|
||||
lyr = mapnik2.Layer('dataraster', lyrSrs)
|
||||
lyr.datasource = mapnik2.Gdal(
|
||||
lyr = mapnik.Layer('dataraster', lyrSrs)
|
||||
lyr.datasource = mapnik.Gdal(
|
||||
file = '../data/raster/dataraster.tif',
|
||||
band = 1,
|
||||
)
|
||||
sym = mapnik2.RasterSymbolizer()
|
||||
sym.colorizer = mapnik2.RasterColorizer(mapnik2.COLORIZER_DISCRETE, mapnik2.Color(255,255,0))
|
||||
rule = mapnik2.Rule()
|
||||
sym = mapnik.RasterSymbolizer()
|
||||
sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255,255,0))
|
||||
rule = mapnik.Rule()
|
||||
rule.symbols.append(sym)
|
||||
style = mapnik2.Style()
|
||||
style = mapnik.Style()
|
||||
style.rules.append(rule)
|
||||
_map = mapnik2.Map(256,256, mapSrs)
|
||||
_map = mapnik.Map(256,256, mapSrs)
|
||||
_map.append_style('foo', style)
|
||||
lyr.styles.append('foo')
|
||||
_map.layers.append(lyr)
|
||||
prj_trans = mapnik2.ProjTransform(mapnik2.Projection(mapSrs),
|
||||
mapnik2.Projection(lyrSrs))
|
||||
prj_trans = mapnik.ProjTransform(mapnik.Projection(mapSrs),
|
||||
mapnik.Projection(lyrSrs))
|
||||
_map.zoom_to_box(prj_trans.backward(lyr.envelope()))
|
||||
|
||||
im = mapnik2.Image(_map.width,_map.height)
|
||||
mapnik2.render(_map, im)
|
||||
im = mapnik.Image(_map.width,_map.height)
|
||||
mapnik.render(_map, im)
|
||||
# save a png somewhere so we can see it
|
||||
save_data('test_raster_warping.png', im.tostring('png'))
|
||||
imdata = im.tostring()
|
||||
|
@ -164,26 +164,26 @@ def test_raster_warping():
|
|||
def test_raster_warping_does_not_overclip_source():
|
||||
lyrSrs = "+init=epsg:32630"
|
||||
mapSrs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
|
||||
lyr = mapnik2.Layer('dataraster', lyrSrs)
|
||||
lyr.datasource = mapnik2.Gdal(
|
||||
lyr = mapnik.Layer('dataraster', lyrSrs)
|
||||
lyr.datasource = mapnik.Gdal(
|
||||
file = '../data/raster/dataraster.tif',
|
||||
band = 1,
|
||||
)
|
||||
sym = mapnik2.RasterSymbolizer()
|
||||
sym.colorizer = mapnik2.RasterColorizer(mapnik2.COLORIZER_DISCRETE, mapnik2.Color(255,255,0))
|
||||
rule = mapnik2.Rule()
|
||||
sym = mapnik.RasterSymbolizer()
|
||||
sym.colorizer = mapnik.RasterColorizer(mapnik.COLORIZER_DISCRETE, mapnik.Color(255,255,0))
|
||||
rule = mapnik.Rule()
|
||||
rule.symbols.append(sym)
|
||||
style = mapnik2.Style()
|
||||
style = mapnik.Style()
|
||||
style.rules.append(rule)
|
||||
_map = mapnik2.Map(256,256, mapSrs)
|
||||
_map.background=mapnik2.Color('white')
|
||||
_map = mapnik.Map(256,256, mapSrs)
|
||||
_map.background=mapnik.Color('white')
|
||||
_map.append_style('foo', style)
|
||||
lyr.styles.append('foo')
|
||||
_map.layers.append(lyr)
|
||||
_map.zoom_to_box(mapnik2.Box2d(3,42,4,43))
|
||||
_map.zoom_to_box(mapnik.Box2d(3,42,4,43))
|
||||
|
||||
im = mapnik2.Image(_map.width,_map.height)
|
||||
mapnik2.render(_map, im)
|
||||
im = mapnik.Image(_map.width,_map.height)
|
||||
mapnik.render(_map, im)
|
||||
# save a png somewhere so we can see it
|
||||
save_data('test_raster_warping_does_not_overclip_source.png',
|
||||
im.tostring('png'))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
from utilities import Todo
|
||||
import json
|
||||
|
||||
|
@ -35,31 +35,33 @@ def resolve(grid,x,y):
|
|||
|
||||
|
||||
def create_grid_map(width,height):
|
||||
places_ds = mapnik2.PointDatasource()
|
||||
places_ds = mapnik.PointDatasource()
|
||||
places_ds.add_point(143.10,-38.60,'Name','South East')
|
||||
places_ds.add_point(142.48,-38.60,'Name','South West')
|
||||
places_ds.add_point(142.48,-38.38,'Name','North West')
|
||||
places_ds.add_point(143.10,-38.38,'Name','North East')
|
||||
s = mapnik2.Style()
|
||||
r = mapnik2.Rule()
|
||||
#symb = mapnik2.PointSymbolizer()
|
||||
symb = mapnik2.MarkersSymbolizer()
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
#symb = mapnik.PointSymbolizer()
|
||||
symb = mapnik.MarkersSymbolizer()
|
||||
symb.width = 5
|
||||
symb.height = 5
|
||||
symb.allow_overlap = True
|
||||
r.symbols.append(symb)
|
||||
label = mapnik2.TextSymbolizer(mapnik2.Expression('[Name]'),
|
||||
label = mapnik.TextSymbolizer(mapnik.Expression('[Name]'),
|
||||
'DejaVu Sans Book',
|
||||
10,
|
||||
mapnik2.Color('black')
|
||||
mapnik.Color('black')
|
||||
)
|
||||
label.allow_overlap = True
|
||||
label.displacement = (0,-10)
|
||||
#r.symbols.append(label)
|
||||
|
||||
s.rules.append(r)
|
||||
lyr = mapnik2.Layer('Places')
|
||||
lyr = mapnik.Layer('Places')
|
||||
lyr.datasource = places_ds
|
||||
lyr.styles.append('places_labels')
|
||||
m = mapnik2.Map(width,height)
|
||||
m = mapnik.Map(width,height)
|
||||
m.append_style('places_labels',s)
|
||||
m.layers.append(lyr)
|
||||
return m
|
||||
|
@ -68,10 +70,10 @@ def test_render_grid():
|
|||
""" test old method """
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height)
|
||||
ul_lonlat = mapnik2.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik2.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik2.Box2d(ul_lonlat,lr_lonlat))
|
||||
grid = mapnik2.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
grid = mapnik.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
eq_(grid,grid_correct)
|
||||
eq_(resolve(grid,0,0),None)
|
||||
|
||||
|
@ -104,18 +106,18 @@ def test_render_grid2():
|
|||
""" test old against new"""
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height)
|
||||
ul_lonlat = mapnik2.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik2.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik2.Box2d(ul_lonlat,lr_lonlat))
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
|
||||
# new method
|
||||
grid = mapnik2.Grid(m.width,m.height,key='Name')
|
||||
mapnik2.render_layer(m,grid,layer=0,fields=['Name'])
|
||||
grid = mapnik.Grid(m.width,m.height,key='Name')
|
||||
mapnik.render_layer(m,grid,layer=0,fields=['Name'])
|
||||
utf1 = grid.encode('utf',resolution=4)
|
||||
eq_(utf1,grid_correct_new)
|
||||
|
||||
# old method - to be removed
|
||||
utf2 = mapnik2.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
utf2 = mapnik.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
eq_(utf2,grid_correct)
|
||||
|
||||
# for complex polygons these will not be true
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from nose.tools import *
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
from nose.tools import *
|
||||
|
||||
from utilities import execution_path
|
||||
|
@ -16,19 +16,19 @@ def setup():
|
|||
|
||||
|
||||
def test_simplest_render():
|
||||
m = mapnik2.Map(256, 256)
|
||||
i = mapnik2.Image(m.width, m.height)
|
||||
m = mapnik.Map(256, 256)
|
||||
i = mapnik.Image(m.width, m.height)
|
||||
|
||||
mapnik2.render(m, i)
|
||||
mapnik.render(m, i)
|
||||
|
||||
s = i.tostring()
|
||||
|
||||
eq_(s, 256 * 256 * '\x00\x00\x00\x00')
|
||||
|
||||
def test_render_image_to_string():
|
||||
i = mapnik2.Image(256, 256)
|
||||
i = mapnik.Image(256, 256)
|
||||
|
||||
i.background = mapnik2.Color('black')
|
||||
i.background = mapnik.Color('black')
|
||||
|
||||
s = i.tostring()
|
||||
|
||||
|
@ -38,24 +38,24 @@ def test_render_image_to_string():
|
|||
|
||||
def test_setting_alpha():
|
||||
w,h = 256,256
|
||||
im1 = mapnik2.Image(w,h)
|
||||
im1 = mapnik.Image(w,h)
|
||||
# white, half transparent
|
||||
im1.background = mapnik2.Color('rgba(255,255,255,.5)')
|
||||
im1.background = mapnik.Color('rgba(255,255,255,.5)')
|
||||
|
||||
# pure white
|
||||
im2 = mapnik2.Image(w,h)
|
||||
im2.background = mapnik2.Color('rgba(255,255,255,1)')
|
||||
im2 = mapnik.Image(w,h)
|
||||
im2.background = mapnik.Color('rgba(255,255,255,1)')
|
||||
im2.set_alpha(.5)
|
||||
|
||||
eq_(len(im1.tostring()), len(im2.tostring()))
|
||||
|
||||
|
||||
def test_render_image_to_file():
|
||||
i = mapnik2.Image(256, 256)
|
||||
i = mapnik.Image(256, 256)
|
||||
|
||||
i.background = mapnik2.Color('black')
|
||||
i.background = mapnik.Color('black')
|
||||
|
||||
if mapnik2.has_jpeg():
|
||||
if mapnik.has_jpeg():
|
||||
i.save('test.jpg')
|
||||
i.save('test.png', 'png')
|
||||
|
||||
|
@ -71,17 +71,17 @@ def test_render_image_to_file():
|
|||
|
||||
def get_paired_images(w,h,mapfile):
|
||||
tmp_map = 'tmp_map.xml'
|
||||
m = mapnik2.Map(w,h)
|
||||
mapnik2.load_map(m,mapfile)
|
||||
i = mapnik2.Image(w,h)
|
||||
m = mapnik.Map(w,h)
|
||||
mapnik.load_map(m,mapfile)
|
||||
i = mapnik.Image(w,h)
|
||||
m.zoom_all()
|
||||
mapnik2.render(m,i)
|
||||
mapnik2.save_map(m,tmp_map)
|
||||
m2 = mapnik2.Map(w,h)
|
||||
mapnik2.load_map(m2,tmp_map)
|
||||
i2 = mapnik2.Image(w,h)
|
||||
mapnik.render(m,i)
|
||||
mapnik.save_map(m,tmp_map)
|
||||
m2 = mapnik.Map(w,h)
|
||||
mapnik.load_map(m2,tmp_map)
|
||||
i2 = mapnik.Image(w,h)
|
||||
m2.zoom_all()
|
||||
mapnik2.render(m2,i2)
|
||||
mapnik.render(m2,i2)
|
||||
os.remove(tmp_map)
|
||||
return i,i2
|
||||
|
||||
|
@ -118,37 +118,39 @@ def resolve(grid,x,y):
|
|||
|
||||
|
||||
def test_render_grid():
|
||||
places_ds = mapnik2.PointDatasource()
|
||||
places_ds = mapnik.PointDatasource()
|
||||
places_ds.add_point(143.10,-38.60,'Name','South East')
|
||||
places_ds.add_point(142.48,-38.60,'Name','South West')
|
||||
places_ds.add_point(142.48,-38.38,'Name','North West')
|
||||
places_ds.add_point(143.10,-38.38,'Name','North East')
|
||||
s = mapnik2.Style()
|
||||
r = mapnik2.Rule()
|
||||
#symb = mapnik2.PointSymbolizer()
|
||||
symb = mapnik2.MarkersSymbolizer()
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
#symb = mapnik.PointSymbolizer()
|
||||
symb = mapnik.MarkersSymbolizer()
|
||||
symb.width = 5
|
||||
symb.height = 5
|
||||
symb.allow_overlap = True
|
||||
r.symbols.append(symb)
|
||||
label = mapnik2.TextSymbolizer(mapnik2.Expression('[Name]'),
|
||||
label = mapnik.TextSymbolizer(mapnik.Expression('[Name]'),
|
||||
'DejaVu Sans Book',
|
||||
10,
|
||||
mapnik2.Color('black')
|
||||
mapnik.Color('black')
|
||||
)
|
||||
label.allow_overlap = True
|
||||
label.displacement = (0,-10)
|
||||
#r.symbols.append(label)
|
||||
|
||||
s.rules.append(r)
|
||||
lyr = mapnik2.Layer('Places')
|
||||
lyr = mapnik.Layer('Places')
|
||||
lyr.datasource = places_ds
|
||||
lyr.styles.append('places_labels')
|
||||
m = mapnik2.Map(256,256)
|
||||
m = mapnik.Map(256,256)
|
||||
m.append_style('places_labels',s)
|
||||
m.layers.append(lyr)
|
||||
ul_lonlat = mapnik2.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik2.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik2.Box2d(ul_lonlat,lr_lonlat))
|
||||
grid = mapnik2.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
grid = mapnik.render_grid(m,0,key='Name',resolution=4,fields=['Name'])
|
||||
eq_(grid,grid_correct)
|
||||
eq_(resolve(grid,0,0),None)
|
||||
|
||||
|
@ -179,25 +181,25 @@ def test_render_grid():
|
|||
|
||||
def test_render_points():
|
||||
|
||||
if not mapnik2.has_cairo(): return
|
||||
if not mapnik.has_cairo(): return
|
||||
|
||||
# create and populate point datasource (WGS84 lat-lon coordinates)
|
||||
places_ds = mapnik2.PointDatasource()
|
||||
places_ds = mapnik.PointDatasource()
|
||||
places_ds.add_point(142.48,-38.38,'Name','Westernmost Point') # westernmost
|
||||
places_ds.add_point(143.10,-38.60,'Name','Southernmost Point') # southernmost
|
||||
# create layer/rule/style
|
||||
s = mapnik2.Style()
|
||||
r = mapnik2.Rule()
|
||||
symb = mapnik2.PointSymbolizer()
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
symb = mapnik.PointSymbolizer()
|
||||
symb.allow_overlap = True
|
||||
r.symbols.append(symb)
|
||||
s.rules.append(r)
|
||||
lyr = mapnik2.Layer('Places','+proj=latlon +datum=WGS84')
|
||||
lyr = mapnik.Layer('Places','+proj=latlon +datum=WGS84')
|
||||
lyr.datasource = places_ds
|
||||
lyr.styles.append('places_labels')
|
||||
# latlon bounding box corners
|
||||
ul_lonlat = mapnik2.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik2.Coord(143.40,-38.80)
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
# render for different projections
|
||||
projs = {
|
||||
'latlon': '+proj=latlon +datum=WGS84',
|
||||
|
@ -206,14 +208,14 @@ def test_render_points():
|
|||
'utm': '+proj=utm +zone=54 +datum=WGS84'
|
||||
}
|
||||
for projdescr in projs.iterkeys():
|
||||
m = mapnik2.Map(1000, 500, projs[projdescr])
|
||||
m = mapnik.Map(1000, 500, projs[projdescr])
|
||||
m.append_style('places_labels',s)
|
||||
m.layers.append(lyr)
|
||||
p = mapnik2.Projection(projs[projdescr])
|
||||
m.zoom_to_box(p.forward(mapnik2.Box2d(ul_lonlat,lr_lonlat)))
|
||||
p = mapnik.Projection(projs[projdescr])
|
||||
m.zoom_to_box(p.forward(mapnik.Box2d(ul_lonlat,lr_lonlat)))
|
||||
# Render to SVG so that it can be checked how many points are there with string comparison
|
||||
svg_file = '/tmp/%s.svg'
|
||||
mapnik2.render_to_file(m, svg_file)
|
||||
mapnik.render_to_file(m, svg_file)
|
||||
num_points_present = len(places_ds.all_features())
|
||||
svg = open(svg_file,'r').read()
|
||||
num_points_rendered = svg.count('<image ')
|
||||
|
|
|
@ -5,7 +5,7 @@ from utilities import Todo
|
|||
from utilities import execution_path
|
||||
import tempfile
|
||||
|
||||
import os, sys, glob, mapnik2
|
||||
import os, sys, glob, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -18,13 +18,13 @@ def test():
|
|||
# 2. Save map as XML
|
||||
# 3. Load map to a second object
|
||||
# 4. Compare both map objects
|
||||
map = mapnik2.Map(256, 256)
|
||||
map = mapnik.Map(256, 256)
|
||||
|
||||
raise Todo("map comparison is currently broken due to lacking relative paths support (#324,#340")
|
||||
|
||||
def compare_map(in_map):
|
||||
|
||||
mapnik2.load_map(map, in_map)
|
||||
mapnik.load_map(map, in_map)
|
||||
|
||||
(handle, test_map) = tempfile.mkstemp(suffix='.xml', prefix='mapnik-temp-map1-')
|
||||
os.close(handle)
|
||||
|
@ -35,11 +35,11 @@ def test():
|
|||
if os.path.exists(test_map):
|
||||
os.remove(test_map)
|
||||
|
||||
mapnik2.save_map(map, test_map)
|
||||
new_map = mapnik2.Map(256, 256)
|
||||
mapnik.save_map(map, test_map)
|
||||
new_map = mapnik.Map(256, 256)
|
||||
|
||||
mapnik2.load_map(new_map, test_map)
|
||||
open(test_map2,'w').write(mapnik2.save_map_to_string(new_map))
|
||||
mapnik.load_map(new_map, test_map)
|
||||
open(test_map2,'w').write(mapnik.save_map_to_string(new_map))
|
||||
|
||||
diff = ' diff %s %s' % (os.path.abspath(test_map),os.path.abspath(test_map2))
|
||||
try:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
from timeit import Timer, time
|
||||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
|
@ -59,7 +59,7 @@ def do_encoding():
|
|||
|
||||
def blank():
|
||||
eval('image.tostring("%s")' % c)
|
||||
blank_im = mapnik2.Image(512,512)
|
||||
blank_im = mapnik.Image(512,512)
|
||||
|
||||
for c in combinations:
|
||||
t = Timer(blank)
|
||||
|
@ -67,8 +67,8 @@ def do_encoding():
|
|||
|
||||
def solid():
|
||||
eval('image.tostring("%s")' % c)
|
||||
solid_im = mapnik2.Image(512,512)
|
||||
solid_im.background = mapnik2.Color("#f2efe9")
|
||||
solid_im = mapnik.Image(512,512)
|
||||
solid_im.background = mapnik.Color("#f2efe9")
|
||||
|
||||
for c in combinations:
|
||||
t = Timer(solid)
|
||||
|
@ -77,7 +77,7 @@ def do_encoding():
|
|||
def many_colors():
|
||||
eval('image.tostring("%s")' % c)
|
||||
# lots of colors: http://tile.osm.org/13/4194/2747.png
|
||||
many_colors_im = mapnik2.Image.open('../data/images/13_4194_2747.png')
|
||||
many_colors_im = mapnik.Image.open('../data/images/13_4194_2747.png')
|
||||
|
||||
for c in combinations:
|
||||
t = Timer(many_colors)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from nose.tools import *
|
||||
from utilities import execution_path
|
||||
|
||||
import os, mapnik2
|
||||
import os, mapnik
|
||||
|
||||
def setup():
|
||||
# All of the paths used are relative, if we run the tests
|
||||
|
@ -17,13 +17,13 @@ def setup():
|
|||
def test_attachdb_with_relative_file():
|
||||
# The point table and index is in the qgis_spatiallite.sqlite
|
||||
# database. If either is not found, then this fails
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
ds = mapnik.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='point',
|
||||
attachdb='scratch@qgis_spatiallite.sqlite'
|
||||
)
|
||||
|
||||
def test_attachdb_with_multiple_files():
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
ds = mapnik.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='attachedtest',
|
||||
attachdb='scratch1@:memory:,scratch2@:memory:',
|
||||
initdb='create table scratch1.attachedtest (the_geom);\n' +
|
||||
|
@ -34,13 +34,13 @@ def test_attachdb_with_multiple_files():
|
|||
def test_attachdb_with_absolute_file():
|
||||
# The point table and index is in the qgis_spatiallite.sqlite
|
||||
# database. If either is not found, then this fails
|
||||
ds = mapnik2.SQLite(file=os.getcwd() + '/../data/sqlite/world.sqlite',
|
||||
ds = mapnik.SQLite(file=os.getcwd() + '/../data/sqlite/world.sqlite',
|
||||
table='point',
|
||||
attachdb='scratch@qgis_spatiallite.sqlite'
|
||||
)
|
||||
|
||||
def test_attachdb_with_index():
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
ds = mapnik.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='attachedtest',
|
||||
attachdb='scratch@:memory:',
|
||||
initdb='create table scratch.attachedtest (the_geom);\n' +
|
||||
|
@ -49,7 +49,7 @@ def test_attachdb_with_index():
|
|||
)
|
||||
|
||||
def test_attachdb_with_explicit_index():
|
||||
ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite',
|
||||
ds = mapnik.SQLite(file='../data/sqlite/world.sqlite',
|
||||
table='attachedtest',
|
||||
index_table='myindex',
|
||||
attachdb='scratch@:memory:',
|
||||
|
|
|
@ -42,14 +42,14 @@ def main():
|
|||
# Allow python to find libraries for testing on the buildbot
|
||||
sys.path.insert(0, os.path.join(prefix, "lib/python%s/site-packages" % sys.version[:3]))
|
||||
|
||||
import mapnik2
|
||||
import mapnik
|
||||
|
||||
if not quiet:
|
||||
print("- mapnik2 path: %s" % mapnik2.__file__)
|
||||
if hasattr(mapnik2,'_mapnik2'):
|
||||
print("- _mapnik2.so path: %s" % mapnik2._mapnik2.__file__)
|
||||
print("- Input plugins path: %s" % mapnik2.inputpluginspath)
|
||||
print("- Font path: %s" % mapnik2.fontscollectionpath)
|
||||
print("- mapnik path: %s" % mapnik.__file__)
|
||||
if hasattr(mapnik,'_mapnik'):
|
||||
print("- _mapnik.so path: %s" % mapnik._mapnik.__file__)
|
||||
print("- Input plugins path: %s" % mapnik.inputpluginspath)
|
||||
print("- Font path: %s" % mapnik.fontscollectionpath)
|
||||
print('')
|
||||
print("- Running nosetests:")
|
||||
print('')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
API_DOCS_DIR="../api_docs/python"
|
||||
API_DOCS_DIR="mapnik-python-`mapnik-config --version`"
|
||||
|
||||
if [ ! -d $API_DOCS_DIR ]
|
||||
then
|
||||
|
@ -11,9 +11,9 @@ fi
|
|||
epydoc --no-private \
|
||||
--no-frames \
|
||||
--no-sourcecode \
|
||||
--name mapnik2 \
|
||||
--name mapnik \
|
||||
--url http://mapnik.org \
|
||||
--css mapnik_epydoc.css mapnik2 \
|
||||
--css mapnik_epydoc.css mapnik \
|
||||
-o $API_DOCS_DIR
|
||||
|
||||
exit $?
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue