diff --git a/Makefile b/Makefile index e5503fee9..d4bc48851 100755 --- a/Makefile +++ b/Makefile @@ -44,7 +44,6 @@ clean: @find ./ -name "*.so" -exec rm {} \; @find ./ -name "*.o" -exec rm {} \; @find ./ -name "*.a" -exec rm {} \; - @find ./ -name "*.pyc" -exec rm {} \; @if test -e "bindings/python/mapnik/paths.py"; then rm "bindings/python/mapnik/paths.py"; fi distclean: diff --git a/SConstruct b/SConstruct index ef07cb984..95af57863 100644 --- a/SConstruct +++ b/SConstruct @@ -66,6 +66,10 @@ BOOST_SEARCH_PREFIXES = ['/usr/local','/opt/local','/sw','/usr',] BOOST_MIN_VERSION = '1.47' #CAIRO_MIN_VERSION = '1.8.0' +HARFBUZZ_MIN_VERSION = (0, 9, 34) +HARFBUZZ_MIN_VERSION_STRING = "%s.%s.%s" % HARFBUZZ_MIN_VERSION + + DEFAULT_LINK_PRIORITY = ['internal','other','frameworks','user','system'] @@ -84,6 +88,7 @@ pretty_dep_names = { 'webp':'WEBP C library | configure with WEBP_LIBS & WEBP_INCLUDES', 'icuuc':'ICU C++ library | configure with ICU_LIBS & ICU_INCLUDES or use ICU_LIB_NAME to specify custom lib name | more info: http://site.icu-project.org/', 'harfbuzz':'HarfBuzz text shaping library | configure with HB_LIBS & HB_INCLUDES', + 'harfbuzz-min-version':'HarfBuzz >= %s (required for font-feature-settings support)' % HARFBUZZ_MIN_VERSION_STRING, 'z':'Z compression library | more info: http://www.zlib.net/', 'm':'Basic math library, part of C++ stlib', 'pkg-config':'pkg-config tool | more info: http://pkg-config.freedesktop.org', @@ -902,6 +907,35 @@ int main() color_print(1,'\nFound insufficient icu version... %s' % result) return False +def harfbuzz_version(context): + ret = context.TryRun(""" + +#include "harfbuzz/hb.h" +#include + +int main() +{ + std::cout << HB_VERSION_ATLEAST(%s, %s, %s) << ";" << HB_VERSION_STRING; + return 0; +} + +""" % HARFBUZZ_MIN_VERSION, '.cpp') + # hack to avoid printed output + context.Message('Checking for HarfBuzz version >= %s... ' % HARFBUZZ_MIN_VERSION_STRING) + context.did_show_result=1 + result = ret[1].strip() + if not result: + context.Result('error, could not get version from hb.h') + return False + + items = result.split(';') + if items[0] == '1': + color_print(4,'found: HarfBuzz %s' % items[1]) + return True + + color_print(1,'\nHarfbuzz >= %s required but found ... %s' % (HARFBUZZ_MIN_VERSION_STRING,items[1])) + return False + def boost_regex_has_icu(context): if env['RUNTIME_LINK'] == 'static': # re-order icu libs to ensure linux linker is happy @@ -1022,6 +1056,7 @@ conf_tests = { 'prioritize_paths' : prioritize_paths, 'get_pkg_lib' : get_pkg_lib, 'rollback_option' : rollback_option, 'icu_at_least_four_two' : icu_at_least_four_two, + 'harfbuzz_version' : harfbuzz_version, 'boost_regex_has_icu' : boost_regex_has_icu, 'sqlite_has_rtree' : sqlite_has_rtree, 'supports_cxx11' : supports_cxx11, @@ -1207,7 +1242,7 @@ if not preconfigured: ] if env.get('FREETYPE_LIBS') or env.get('FREETYPE_INCLUDES'): - REQUIRED_LIBSHEADERS.append(['freetype','ft2build.h',True,'C']) + REQUIRED_LIBSHEADERS.insert(0,['freetype','ft2build.h',True,'C']) if env.get('FREETYPE_INCLUDES'): inc_path = env['FREETYPE_INCLUDES'] env.AppendUnique(CPPPATH = os.path.realpath(inc_path)) @@ -1230,7 +1265,7 @@ if not preconfigured: # libxml2 should be optional but is currently not # https://github.com/mapnik/mapnik/issues/913 if env.get('XML2_LIBS') or env.get('XML2_INCLUDES'): - REQUIRED_LIBSHEADERS.append(['libxml2','libxml/parser.h',True,'C']) + REQUIRED_LIBSHEADERS.insert(0,['libxml2','libxml/parser.h',True,'C']) if env.get('XML2_INCLUDES'): inc_path = env['XML2_INCLUDES'] env.AppendUnique(CPPPATH = os.path.realpath(inc_path)) @@ -1312,12 +1347,15 @@ if not preconfigured: else: color_print(4, 'Could not find optional header or shared library for %s' % libname) env['SKIPPED_DEPS'].append(libname) - - if not env['HOST']: - if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']: - if not conf.icu_at_least_four_two(): - # expression_string.cpp and map.cpp use fromUTF* function only available in >= ICU 4.2 - env['MISSING_DEPS'].append(env['ICU_LIB_NAME']) + else: + if libname == env['ICU_LIB_NAME']: + if env['ICU_LIB_NAME'] not in env['MISSING_DEPS']: + if not conf.icu_at_least_four_two(): + # expression_string.cpp and map.cpp use fromUTF* function only available in >= ICU 4.2 + env['MISSING_DEPS'].append(env['ICU_LIB_NAME']) + elif libname == 'harfbuzz': + if not conf.harfbuzz_version(): + env['MISSING_DEPS'].append('harfbuzz-min-version') if env['BIGINT']: env.Append(CPPDEFINES = '-DBIGINT') diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index c317b75dc..532131d3c 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -32,6 +32,7 @@ #include #include #include +#include // boost #pragma GCC diagnostic push @@ -365,6 +366,13 @@ void ogr_datasource::init(mapnik::parameters const& params) } } } + mapnik::parameters & extra_params = desc_.get_extra_parameters(); + OGRSpatialReference * srs_ref = layer->GetSpatialRef(); + char * srs_output = NULL; + if (srs_ref && srs_ref->exportToProj4( &srs_output ) == OGRERR_NONE ) { + extra_params["proj4"] = mapnik::util::trim_copy(srs_output); + } + CPLFree(srs_output); } const char * ogr_datasource::name() diff --git a/src/box2d.cpp b/src/box2d.cpp index a812042f0..edea1b5a8 100644 --- a/src/box2d.cpp +++ b/src/box2d.cpp @@ -22,7 +22,6 @@ // mapnik #include -#include // stl #include diff --git a/tests/python_tests/ogr_test.py b/tests/python_tests/ogr_test.py index f463b22b5..6c577a514 100644 --- a/tests/python_tests/ogr_test.py +++ b/tests/python_tests/ogr_test.py @@ -14,14 +14,15 @@ if 'ogr' in mapnik.DatasourceCache.plugin_names(): # Shapefile initialization def test_shapefile_init(): - s = mapnik.Ogr(file='../../demo/data/boundaries.shp',layer_by_index=0) - - e = s.envelope() - + ds = mapnik.Ogr(file='../../demo/data/boundaries.shp',layer_by_index=0) + e = ds.envelope() assert_almost_equal(e.minx, -11121.6896651, places=7) assert_almost_equal(e.miny, -724724.216526, places=6) assert_almost_equal(e.maxx, 2463000.67866, places=5) assert_almost_equal(e.maxy, 1649661.267, places=3) + meta = ds.describe() + eq_(meta['geometry_type'],mapnik.DataGeometryType.Polygon) + eq_('+proj=lcc' in meta['proj4'],True) # Shapefile properties def test_shapefile_properties(): @@ -35,6 +36,8 @@ if 'ogr' in mapnik.DatasourceCache.plugin_names(): eq_(f['NAME_EN'], u'Quebec') eq_(f['Shape_Area'], 1512185733150.0) eq_(f['Shape_Leng'], 19218883.724300001) + meta = ds.describe() + eq_(meta['geometry_type'],mapnik.DataGeometryType.Polygon) # NOTE: encoding is latin1 but gdal >= 1.9 should now expose utf8 encoded features # See SHAPE_ENCODING for overriding: http://gdal.org/ogr/drv_shapefile.html # Failure for the NOM_FR field is expected for older gdal @@ -68,6 +71,9 @@ if 'ogr' in mapnik.DatasourceCache.plugin_names(): eq_(e.miny,-1) eq_(e.maxx,1) eq_(e.maxy,1) + meta = ds.describe() + eq_(meta['geometry_type'],mapnik.DataGeometryType.Polygon) + eq_('+proj=merc' in meta['proj4'],True) def test_ogr_reading_gpx_waypoint(): ds = mapnik.Ogr(file='../data/gpx/empty.gpx',layer='waypoints') @@ -76,6 +82,9 @@ if 'ogr' in mapnik.DatasourceCache.plugin_names(): eq_(e.miny,48) eq_(e.maxx,-122) eq_(e.maxy,48) + meta = ds.describe() + eq_(meta['geometry_type'],mapnik.DataGeometryType.Point) + eq_('+proj=longlat' in meta['proj4'],True) def test_ogr_empty_data_should_not_throw(): default_logging_severity = mapnik.logger.get_severity() @@ -89,6 +98,9 @@ if 'ogr' in mapnik.DatasourceCache.plugin_names(): eq_(e.maxx,0) eq_(e.maxy,0) mapnik.logger.set_severity(default_logging_severity) + meta = ds.describe() + eq_(meta['geometry_type'],mapnik.DataGeometryType.Point) + eq_('+proj=longlat' in meta['proj4'],True) # disabled because OGR prints an annoying error: ERROR 1: Invalid Point object. Missing 'coordinates' member. #def test_handling_of_null_features():