[magics] 01/01: Metview 2.28.0
Alastair McKinstry
mckinstry at moszumanska.debian.org
Thu Mar 17 19:33:18 UTC 2016
This is an automated email from the git hooks/post-receive script.
mckinstry pushed a commit to tag upstream/2.28.2
in repository magics.
commit 340e9e6b833b643d31cfb4bbfc866c602eb5fdfd
Author: Alastair McKinstry <mckinstry at debian.org>
Date: Thu Mar 17 10:06:52 2016 +0000
Metview 2.28.0
---
CMakeLists.txt | 14 +-
VERSION.cmake | 4 +-
apps/metgram/metgram.py | 130 --
bin/CMakeLists.txt | 3 -
bin/ecbuild | 62 +-
cmake/CMakeLists.txt | 5 -
cmake/FindADSM.cmake | 2 +-
cmake/FindAEC.cmake | 2 +-
cmake/FindAIO.cmake | 2 +-
cmake/FindArmadillo.cmake | 2 +-
cmake/FindCMath.cmake | 2 +-
cmake/FindDl.cmake | 2 +-
cmake/FindEMOS.cmake | 2 +-
cmake/FindFDB.cmake | 2 +-
cmake/FindHPSS.cmake | 2 +-
cmake/FindLEX.cmake | 2 +-
cmake/FindLegacyFDB.cmake | 2 +-
cmake/FindLibGFortran.cmake | 16 +-
cmake/FindLibIFort.cmake | 2 +-
cmake/FindMKL.cmake | 2 +-
cmake/FindNDBM.cmake | 2 +-
cmake/FindNetCDF.cmake | 46 +-
cmake/FindNetCDF3.cmake | 2 +-
cmake/FindODB.cmake | 2 +-
cmake/FindOpenCL.cmake | 2 +-
cmake/FindOpenJPEG.cmake | 2 +-
cmake/FindPGIFortran.cmake | 2 +-
cmake/FindPango.cmake | 16 +-
cmake/FindPangoCairo.cmake | 14 +-
cmake/FindProj4.cmake | 10 +-
cmake/FindREADLINE.cmake | 6 +-
cmake/FindRPCGEN.cmake | 2 +-
cmake/FindRealtime.cmake | 2 +-
cmake/FindSZip.cmake | 2 +-
cmake/FindTrilinos.cmake | 2 +-
cmake/FindViennaCL.cmake | 2 +-
cmake/FindXLFortranLibs.cmake | 2 +-
cmake/FindYACC.cmake | 2 +-
cmake/Findgrib_api.cmake | 44 +-
cmake/Findodb_api.cmake | 2 +-
cmake/Findspot.cmake | 2 +-
cmake/VERSION.cmake | 6 +-
cmake/compiler_flags/Clang_C.cmake | 13 +
cmake/compiler_flags/Clang_CXX.cmake | 13 +
cmake/compiler_flags/Cray_C.cmake | 14 +
cmake/compiler_flags/Cray_CXX.cmake | 14 +
cmake/compiler_flags/Cray_Fortran.cmake | 15 +
cmake/compiler_flags/GNU_C.cmake | 18 +
cmake/compiler_flags/GNU_CXX.cmake | 18 +
cmake/compiler_flags/GNU_Fortran.cmake | 21 +
cmake/compiler_flags/Intel_C.cmake | 13 +
cmake/compiler_flags/Intel_CXX.cmake | 13 +
cmake/compiler_flags/Intel_Fortran.cmake | 14 +
cmake/compiler_flags/PGI_C.cmake | 11 +
cmake/compiler_flags/PGI_CXX.cmake | 11 +
cmake/compiler_flags/PGI_Fortran.cmake | 11 +
cmake/contrib/FindFFTW.cmake | 193 ++-
cmake/contrib/FindNetCDF4.cmake | 14 +-
cmake/contrib/GetGitRevisionDescription.cmake.in | 6 +-
.../contrib/GreatCMakeCookOff/tests/CMakeLists.txt | 12 -
.../GreatCMakeCookOff/tests/cpp11/CMakeLists.txt | 3 -
cmake/ecbuild-config-version.cmake | 12 +
cmake/ecbuild-config.cmake | 97 ++
cmake/ecbuild_add_c_flags.cmake | 59 +-
cmake/ecbuild_add_cxx11_flags.cmake | 2 +-
cmake/ecbuild_add_cxx_flags.cmake | 59 +-
cmake/ecbuild_add_executable.cmake | 167 ++-
cmake/ecbuild_add_extra_search_paths.cmake | 12 +-
cmake/ecbuild_add_fortran_flags.cmake | 61 +-
cmake/ecbuild_add_library.cmake | 148 +-
cmake/ecbuild_add_option.cmake | 61 +-
cmake/ecbuild_add_persistent.cmake | 14 +-
cmake/ecbuild_add_resources.cmake | 2 +-
cmake/ecbuild_add_test.cmake | 34 +-
cmake/ecbuild_append_to_rpath.cmake | 2 +-
cmake/ecbuild_bundle.cmake | 38 +-
cmake/ecbuild_cache.cmake | 2 +-
cmake/ecbuild_check_c_source_return.cmake | 2 +-
cmake/ecbuild_check_compiler.cmake | 9 +-
cmake/ecbuild_check_cxx11.cmake | 2 +-
cmake/ecbuild_check_cxx_source_return.cmake | 42 +-
cmake/ecbuild_check_fortran_source_return.cmake | 2 +-
cmake/ecbuild_check_functions.cmake | 16 +-
cmake/ecbuild_check_os.cmake | 58 +-
cmake/ecbuild_compiler_flags.cmake | 97 ++
cmake/ecbuild_config.h.in | 2 +-
cmake/ecbuild_debug_var.cmake | 47 -
cmake/ecbuild_declare_project.cmake | 24 +-
cmake/ecbuild_define_build_types.cmake | 80 +-
cmake/ecbuild_define_libs_and_execs_target.cmake | 29 +
...get.cmake => ecbuild_define_links_target.cmake} | 10 +-
cmake/ecbuild_define_options.cmake | 12 +-
cmake/ecbuild_define_paths.cmake | 2 +-
cmake/ecbuild_dont_pack.cmake | 2 +-
cmake/ecbuild_download_resource.cmake | 2 +-
cmake/ecbuild_echo_targets.cmake | 8 +-
cmake/ecbuild_enable_fortran.cmake | 11 +-
cmake/ecbuild_features.cmake | 53 +-
cmake/ecbuild_find_fortranlibs.cmake | 2 +-
cmake/ecbuild_find_lexyacc.cmake | 20 +-
cmake/ecbuild_find_mpi.cmake | 2 +-
cmake/ecbuild_find_omp.cmake | 9 +-
cmake/ecbuild_find_package.cmake | 8 +-
cmake/ecbuild_find_perl.cmake | 2 +-
cmake/ecbuild_find_python.cmake | 134 +-
cmake/ecbuild_generate_config_headers.cmake | 2 +-
cmake/ecbuild_generate_fortran_interfaces.cmake | 115 ++
cmake/ecbuild_generate_rpc.cmake | 2 +-
cmake/ecbuild_generate_yy.cmake | 30 +-
cmake/ecbuild_get_cxx11_flags.cmake | 2 +-
cmake/ecbuild_get_date.cmake | 2 +-
cmake/ecbuild_get_resources.cmake | 16 +-
cmake/ecbuild_get_test_data.cmake | 29 +-
cmake/ecbuild_git.cmake | 10 +-
cmake/ecbuild_install_project.cmake | 81 +-
cmake/ecbuild_list_add_pattern.cmake | 102 ++
cmake/ecbuild_list_exclude_pattern.cmake | 88 ++
cmake/ecbuild_list_extra_search_paths.cmake | 12 +-
cmake/ecbuild_list_macros.cmake | 40 +-
cmake/ecbuild_log.cmake | 92 +-
cmake/ecbuild_pkgconfig.cmake | 2 +-
cmake/ecbuild_policies.cmake | 10 +-
cmake/ecbuild_print_summary.cmake | 8 +-
cmake/ecbuild_project_files.cmake | 10 +-
cmake/ecbuild_remove_fortran_flags.cmake | 61 +
cmake/ecbuild_requires_macro_version.cmake | 2 +-
cmake/ecbuild_separate_sources.cmake | 10 +-
cmake/ecbuild_setup_test_framework.cmake | 6 +-
cmake/ecbuild_source_flags.cmake | 30 +
cmake/ecbuild_system.cmake | 66 +-
cmake/ecbuild_use_package.cmake | 25 +-
cmake/ecbuild_version.h.in | 2 +-
cmake/ecbuild_warn_unused_files.cmake | 2 +-
cmake/gen_source_flags.py | 84 ++
cmake/include/ecbuild/boost_test_framework.h | 2 +-
cmake/project-config.cmake.in | 49 +-
cmake/sg.pl | 2 +-
magics-import.cmake.in | 2 +
python/Magics/Magics_interface.cc | 12 +-
python/Magics/macro.py | 2 +
share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake | 56 +-
share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake | 50 +-
share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake | 44 +-
.../magics/10m/10m_admin_0_boundary_lines_land.dbf | Bin 12752 -> 0 bytes
.../magics/10m/10m_admin_0_boundary_lines_land.shp | Bin 1195564 -> 0 bytes
.../magics/10m/10m_admin_0_boundary_lines_land.shx | Bin 2836 -> 0 bytes
.../10m/10m_admin_1_states_provinces_shp.dbf | Bin 4553698 -> 0 bytes
.../10m/10m_admin_1_states_provinces_shp.shp | Bin 15598952 -> 0 bytes
.../10m/10m_admin_1_states_provinces_shp.shx | Bin 15644 -> 0 bytes
share/magics/10m/10m_lakes.dbf | Bin 540735 -> 0 bytes
share/magics/10m/10m_lakes.prj | 1 -
share/magics/10m/10m_lakes.shp | Bin 1253556 -> 0 bytes
share/magics/10m/10m_lakes.shx | Bin 3452 -> 0 bytes
share/magics/10m/10m_land.prj | 1 -
share/magics/10m/10m_land.shp | Bin 6248904 -> 0 bytes
share/magics/10m/10m_land.shx | Bin 16228 -> 0 bytes
share/magics/10m/10m_populated_places_simple.dbf | Bin 32124176 -> 0 bytes
share/magics/10m/10m_populated_places_simple.shp | Bin 204752 -> 0 bytes
share/magics/10m/10m_rivers_lake_centerlines.dbf | Bin 163625 -> 0 bytes
share/magics/10m/10m_rivers_lake_centerlines.prj | 1 -
share/magics/10m/10m_rivers_lake_centerlines.shp | Bin 1950380 -> 0 bytes
share/magics/10m/10m_rivers_lake_centerlines.shx | Bin 3900 -> 0 bytes
.../ne_10m_admin_0_boundary_lines_land.VERSION.txt | 1 +
.../10m/ne_10m_admin_0_boundary_lines_land.dbf | Bin 0 -> 260057 bytes
....prj => ne_10m_admin_0_boundary_lines_land.prj} | 0
.../10m/ne_10m_admin_0_boundary_lines_land.shp | Bin 0 -> 1299780 bytes
.../10m/ne_10m_admin_0_boundary_lines_land.shx | Bin 0 -> 3788 bytes
.../ne_10m_admin_1_states_provinces.VERSION.txt | 1 +
.../magics/10m/ne_10m_admin_1_states_provinces.dbf | Bin 0 -> 15267317 bytes
.../ne_10m_admin_1_states_provinces.prj} | 0
.../ne_10m_admin_1_states_provinces.shp} | Bin 19936848 -> 21612568 bytes
.../magics/10m/ne_10m_admin_1_states_provinces.shx | Bin 0 -> 37276 bytes
share/magics/10m/ne_10m_land.VERSION.txt | 1 +
share/magics/10m/ne_10m_land.dbf | Bin 0 -> 702401 bytes
.../{10m_full/10m_land.prj => 10m/ne_10m_land.prj} | 0
share/magics/10m/ne_10m_land.qpj | 1 +
share/magics/10m/ne_10m_land.shp | Bin 0 -> 10064204 bytes
share/magics/10m/ne_10m_land.shx | Bin 0 -> 63940 bytes
share/magics/10m/ne_10m_ocean.VERSION.txt | 1 +
.../10m_lakes.dbf => 10m/ne_10m_ocean.dbf} | Bin 1724955 -> 1516917 bytes
.../ne_10m_ocean.prj} | 0
share/magics/10m/ne_10m_ocean.qpj | 1 +
share/magics/10m/ne_10m_ocean.shp | Bin 0 -> 9460720 bytes
share/magics/10m/ne_10m_ocean.shx | Bin 0 -> 10884 bytes
share/magics/10m/ne_10m_ocean_orig.VERSION.txt | 1 +
.../10m/ne_10m_populated_places_simple.VERSION.txt | 1 +
.../magics/10m/ne_10m_populated_places_simple.dbf | Bin 0 -> 13136853 bytes
..._shp.prj => ne_10m_populated_places_simple.prj} | 0
.../magics/10m/ne_10m_populated_places_simple.shp | Bin 0 -> 205116 bytes
...mple.shx => ne_10m_populated_places_simple.shx} | Bin 58572 -> 58676 bytes
.../10m/ne_10m_rivers_lake_centerlines.VERSION.txt | 1 +
...land.dbf => ne_10m_rivers_lake_centerlines.dbf} | Bin 1064577 -> 1265238 bytes
..._shp.prj => ne_10m_rivers_lake_centerlines.prj} | 0
.../magics/10m/ne_10m_rivers_lake_centerlines.shp | Bin 0 -> 4186892 bytes
.../magics/10m/ne_10m_rivers_lake_centerlines.shx | Bin 0 -> 11732 bytes
.../10m_full/10m_admin_0_boundary_lines_land.dbf | Bin 12752 -> 0 bytes
.../10m_full/10m_admin_0_boundary_lines_land.shp | Bin 1195564 -> 0 bytes
.../10m_full/10m_admin_0_boundary_lines_land.shx | Bin 2836 -> 0 bytes
.../10m_full/10m_admin_1_states_provinces_shp.dbf | Bin 8354045 -> 0 bytes
.../10m_full/10m_admin_1_states_provinces_shp.shx | Bin 28620 -> 0 bytes
share/magics/10m_full/10m_lakes.prj | 1 -
share/magics/10m_full/10m_lakes.shp | Bin 2252300 -> 0 bytes
share/magics/10m_full/10m_lakes.shx | Bin 10796 -> 0 bytes
share/magics/10m_full/10m_land.dbf | Bin 293905 -> 0 bytes
share/magics/10m_full/10m_land.shp | Bin 6945784 -> 0 bytes
share/magics/10m_full/10m_land.shx | Bin 31436 -> 0 bytes
.../10m_full/10m_rivers_lake_centerlines.dbf | Bin 481138 -> 0 bytes
.../10m_full/10m_rivers_lake_centerlines.shp | Bin 4130540 -> 0 bytes
.../10m_full/10m_rivers_lake_centerlines.shx | Bin 11284 -> 0 bytes
.../110m/110m_admin_0_boundary_lines_land.dbf | Bin 9168 -> 0 bytes
.../110m/110m_admin_0_boundary_lines_land.prj | 1 -
.../110m/110m_admin_0_boundary_lines_land.shx | Bin 1364 -> 0 bytes
.../110m/110m_admin_1_states_provinces_shp.prj | 1 -
share/magics/110m/110m_lakes.prj | 1 -
share/magics/110m/110m_lakes.shp | Bin 9324 -> 0 bytes
share/magics/110m/110m_lakes.shx | Bin 300 -> 0 bytes
share/magics/110m/110m_land.dbf | Bin 3400 -> 0 bytes
share/magics/110m/110m_land.prj | 1 -
share/magics/110m/110m_land.sbx | Bin 268 -> 0 bytes
share/magics/110m/110m_land.shp.xml | 3 -
...ne_110m_admin_0_boundary_lines_land.VERSION.txt | 1 +
.../110m/ne_110m_admin_0_boundary_lines_land.dbf | Bin 0 -> 29946 bytes
.../ne_110m_admin_0_boundary_lines_land.prj} | 0
...shp => ne_110m_admin_0_boundary_lines_land.shp} | Bin 53188 -> 55692 bytes
.../110m/ne_110m_admin_0_boundary_lines_land.shx | Bin 0 -> 1580 bytes
.../ne_110m_admin_1_states_provinces.VERSION.txt | 1 +
...hp.dbf => ne_110m_admin_1_states_provinces.dbf} | Bin 102605 -> 110913 bytes
.../ne_110m_admin_1_states_provinces.prj} | 0
.../110m/ne_110m_admin_1_states_provinces.sbn | Bin 0 -> 596 bytes
.../110m/ne_110m_admin_1_states_provinces.sbx | Bin 0 -> 148 bytes
...hp.shp => ne_110m_admin_1_states_provinces.shp} | Bin 39132 -> 39132 bytes
...hp.shx => ne_110m_admin_1_states_provinces.shx} | Bin 508 -> 508 bytes
share/magics/110m/ne_110m_land.VERSION.txt | 1 +
share/magics/110m/ne_110m_land.dbf | Bin 0 -> 2637 bytes
.../ne_110m_land.prj} | 0
share/magics/110m/ne_110m_land.qpj | 1 +
.../110m/{110m_land.shp => ne_110m_land.shp} | Bin 89504 -> 97152 bytes
.../110m/{110m_land.shx => ne_110m_land.shx} | Bin 1116 -> 1116 bytes
share/magics/110m/ne_110m_ocean.VERSION.txt | 1 +
.../110m/{110m_lakes.dbf => ne_110m_ocean.dbf} | Bin 19711 -> 17402 bytes
.../10m_land.prj => 110m/ne_110m_ocean.prj} | 0
share/magics/110m/ne_110m_ocean.qpj | 1 +
share/magics/110m/ne_110m_ocean.shp | Bin 0 -> 94028 bytes
share/magics/110m/ne_110m_ocean.shx | Bin 0 -> 316 bytes
.../ne_110m_rivers_lake_centerlines.VERSION.txt | 1 +
...nes.dbf => ne_110m_rivers_lake_centerlines.dbf} | Bin 7876 -> 7875 bytes
.../ne_110m_rivers_lake_centerlines.prj} | 0
...nes.shp => ne_110m_rivers_lake_centerlines.shp} | Bin 19268 -> 19268 bytes
...nes.shx => ne_110m_rivers_lake_centerlines.shx} | Bin 212 -> 212 bytes
.../magics/50m/50m_admin_0_boundary_lines_land.shx | Bin 2924 -> 0 bytes
.../50m/50m_admin_1_states_provinces_shp.dbf | Bin 36546 -> 0 bytes
.../50m/50m_admin_1_states_provinces_shp.prj | 1 -
.../50m/50m_admin_1_states_provinces_shp.shp | Bin 409604 -> 0 bytes
.../50m/50m_admin_1_states_provinces_shp.shx | Bin 612 -> 0 bytes
share/magics/50m/50m_lakes.prj | 1 -
share/magics/50m/50m_lakes.shp | Bin 330436 -> 0 bytes
share/magics/50m/50m_lakes.shx | Bin 3268 -> 0 bytes
share/magics/50m/50m_land.dbf | Bin 782582 -> 0 bytes
share/magics/50m/50m_land.prj | 1 -
share/magics/50m/50m_land.shp | Bin 1050812 -> 0 bytes
share/magics/50m/50m_land.shx | Bin 11460 -> 0 bytes
share/magics/50m/50m_rivers_lake_centerlines.dbf | Bin 154476 -> 0 bytes
share/magics/50m/50m_rivers_lake_centerlines.prj | 1 -
share/magics/50m/50m_rivers_lake_centerlines.shp | Bin 433660 -> 0 bytes
.../magics/50m/50m_rivers_lake_centerlines.shp.xml | 3 -
share/magics/50m/50m_rivers_lake_centerlines.shx | Bin 3764 -> 0 bytes
.../ne_50m_admin_0_boundary_lines_land.VERSION.txt | 1 +
....dbf => ne_50m_admin_0_boundary_lines_land.dbf} | Bin 102853 -> 107049 bytes
.../ne_50m_admin_0_boundary_lines_land.prj} | 0
....shp => ne_50m_admin_0_boundary_lines_land.shp} | Bin 334300 -> 336788 bytes
.../50m/ne_50m_admin_0_boundary_lines_land.shx | Bin 0 -> 2980 bytes
..._admin_1_states_provinces_lines_shp.VERSION.txt | 1 +
.../ne_50m_admin_1_states_provinces_lines_shp.dbf | Bin 0 -> 8852 bytes
.../ne_50m_admin_1_states_provinces_lines_shp.prj | 1 +
.../ne_50m_admin_1_states_provinces_lines_shp.shp | Bin 0 -> 73788 bytes
.../ne_50m_admin_1_states_provinces_lines_shp.shx | Bin 0 -> 1244 bytes
share/magics/50m/ne_50m_land.VERSION.txt | 1 +
share/magics/50m/ne_50m_land.dbf | Bin 0 -> 61157 bytes
.../{10m_full/10m_land.prj => 50m/ne_50m_land.prj} | 0
share/magics/50m/ne_50m_land.qpj | 1 +
share/magics/50m/ne_50m_land.shp | Bin 0 -> 1336536 bytes
share/magics/50m/ne_50m_land.shx | Bin 0 -> 11460 bytes
share/magics/50m/ne_50m_ocean.VERSION.txt | 1 +
.../magics/50m/{50m_lakes.dbf => ne_50m_ocean.dbf} | Bin 410449 -> 297489 bytes
.../10m_land.prj => 50m/ne_50m_ocean.prj} | 0
share/magics/50m/ne_50m_ocean.qpj | 1 +
share/magics/50m/ne_50m_ocean.shp | Bin 0 -> 1306048 bytes
share/magics/50m/ne_50m_ocean.shx | Bin 0 -> 3300 bytes
share/magics/50m/ne_50m_ocean_orig.VERSION.txt | 1 +
.../50m/ne_50m_rivers_lake_centerlines.VERSION.txt | 1 +
.../magics/50m/ne_50m_rivers_lake_centerlines.dbf | Bin 0 -> 200262 bytes
.../ne_50m_rivers_lake_centerlines.prj} | 0
.../magics/50m/ne_50m_rivers_lake_centerlines.shp | Bin 0 -> 437660 bytes
.../magics/50m/ne_50m_rivers_lake_centerlines.shx | Bin 0 -> 3780 bytes
share/magics/contour_ids.json | 186 ++-
share/magics/contours.json | 1318 ++++++++++++++++-
share/magics/default.json | 113 +-
share/magics/ecmwf_logo_2014.svg | 10 +
share/magics/epsg.json | 428 +++---
share/magics/layer_contours.json | 606 +++++++-
share/magics/layer_ids.json | 109 +-
share/magics/layers.json | 1275 ++++++++++++++++-
share/magics/level.json | 203 ++-
share/magics/marsClass.json | 94 +-
share/magics/marsStream.json | 140 +-
share/magics/marsType.json | 145 +-
share/magics/number.json | 132 +-
share/magics/paramId.json | 348 ++++-
share/magics/shortName.json | 347 ++++-
share/magics/stepRange.json | 136 +-
share/magics/symbols.svg | 2 +-
share/magics/typeOfLevel.json | 126 +-
share/magics/units.json | 178 ++-
src/CMakeLists.txt | 7 +-
src/basic/CMakeLists.txt | 2 +-
src/basic/FortranMagics.cc | 28 +-
src/basic/FortranMagics.h | 4 +
src/basic/ViewNode.cc | 3 +-
src/basic/XmlMagics.cc | 7 +-
.../extensions/gis/io/shapelib/shape_creator.hpp | 1 +
src/common/CMakeLists.txt | 2 +-
src/common/Colour.cc | 1 +
src/common/GeoRectangularProjection.cc | 44 +-
src/common/LogoPlotting.cc | 16 +-
src/common/MagicsCalls.cc | 59 +-
src/common/PolarStereographicProjection.cc | 64 +-
src/common/Polyline.cc | 20 +-
src/common/Proj4Projection.cc | 117 +-
src/common/magics_api.h | 4 +-
src/decoders/CMakeLists.txt | 3 +-
src/decoders/EpsBufr.cc | 55 +-
src/decoders/GribDecoder.cc | 193 +--
src/decoders/GribRegularInterpretor.cc | 78 +-
src/decoders/InputMatrixInterpretor.cc | 4 +-
src/decoders/ShapeDecoder.cc | 149 +-
src/decoders/dbfopen.c | 1480 +++++++++++++++-----
src/decoders/safileio.c | 286 ++++
src/decoders/shapefil.h | 315 ++++-
src/decoders/shpopen.c | 1013 ++++++++++----
src/drivers/BaseDriver.cc | 2 +-
src/drivers/BaseDriverSymbols.h | 2 +-
src/drivers/CMakeLists.txt | 11 +-
src/drivers/CairoDriver.cc | 19 +-
src/drivers/KMLDriver.cc | 8 +-
src/drivers/PostScriptDriver.cc | 5 +-
src/drivers/QtDriver.cc | 2 +-
src/drivers/SVGDriver.cc | 77 +-
src/drivers/libimagequant/CHANGELOG | 130 ++
src/drivers/libimagequant/COPYRIGHT | 2 +-
src/drivers/libimagequant/MANUAL.md | 55 +-
src/drivers/libimagequant/Makefile | 2 -
src/drivers/libimagequant/blur.c | 7 +
src/drivers/libimagequant/configure | 39 +-
src/drivers/libimagequant/libimagequant.c | 358 +++--
src/drivers/libimagequant/libimagequant.h | 85 +-
src/drivers/libimagequant/mediancut.c | 72 +-
src/drivers/libimagequant/mediancut.h | 2 +-
src/drivers/libimagequant/mempool.c | 5 +
src/drivers/libimagequant/nearest.c | 316 ++---
src/drivers/libimagequant/nearest.h | 2 +-
src/drivers/libimagequant/pam.c | 19 +-
src/drivers/libimagequant/pam.h | 21 +-
src/drivers/libimagequant/rwpng.c | 49 +-
src/drivers/libimagequant/rwpng.h | 7 +-
src/drivers/libimagequant/viter.c | 13 +-
src/drivers/libimagequant/viter.h | 2 +-
src/eckit_readers/MvPrepBufrPrep.cc | 2 +-
src/params/BaseDriver.xml | 23 +-
src/params/EpsGraph.xml | 12 +-
src/params/MarkerShadingTechnique.xml | 2 +-
src/params/PageID.xml | 52 +-
src/params/TextVisitor.xml | 4 +-
src/terralib/kernel/TeCentroid.cpp | 2 +-
src/terralib/kernel/TeDatabase.cpp | 9 +-
src/terralib/kernel/TeDecoderDatabase.cpp | 4 +-
src/terralib/kernel/TeDecoderDatabase.h | 2 +-
src/terralib/kernel/TeDecoderMemoryMap.cpp | 2 +-
src/terralib/kernel/TeProjection.cpp | 1 +
src/terralib/kernel/TeProxMatrixImplementation.cpp | 14 +-
src/terralib/kernel/TeRaster.cpp | 4 +-
src/terralib/kernel/TeStdFile.h | 2 +-
src/terralib/kernel/TeTin.cpp | 2 +-
src/terralib/kernel/TeUtils.cpp | 4 +-
src/terralib/kernel/yyTemporal.cpp | 4 +-
src/visualisers/Boundaries.cc | 8 +-
src/visualisers/CMakeLists.txt | 2 +-
src/visualisers/Cities.cc | 4 +-
src/visualisers/CoastPlotting.cc | 206 +--
src/visualisers/CoastPlotting.h | 24 +-
src/visualisers/EpsGraph.cc | 137 +-
src/visualisers/EpsGraph.h | 2 +-
src/visualisers/MetgramStyle.cc | 8 +-
src/visualisers/ObsItemFamily.cc | 47 +-
src/visualisers/Streamlines.cc | 6 +-
src/web/WrepJSon.cc | 28 +-
src/web/WrepJSon.h | 2 +
utils/GRA01130000012300001 | Bin 0 -> 19200 bytes
utils/bufrgram.py | 324 +++++
utils/epsgrams.py | 424 ++++++
utils/plumes.py | 676 +++++++++
400 files changed, 13217 insertions(+), 3508 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f40659d..5bce9a5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,7 +20,7 @@
# Missing dependencies:
# * ghostscript ( is it really needed? -- to confirm )
-cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR )
+cmake_minimum_required( VERSION 2.8.11 FATAL_ERROR )
project( magics CXX )
@@ -126,7 +126,7 @@ set( MAGICS_SITE "ecmwf" )
set( MAGICS_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} )
# Regression definitions
-set( MAGICS_REFERENCE_VERSIONS "2.26.0" )
+set( MAGICS_REFERENCE_VERSIONS "2.26.2" )
set( MAGICS_HTML_ROOT "${CMAKE_BINARY_DIR}/regression/html")
file(MAKE_DIRECTORY ${MAGICS_HTML_ROOT} )
@@ -201,7 +201,7 @@ find_package( EXPAT REQUIRED )
###############################################################################
# contents
-set( MAGICS_TPLS grib_api spot EXPAT NetCDF PangoCairo PNG Proj4 libemos )
+set( MAGICS_TPLS grib_api spot EXPAT NetCDF PNG Proj4 libemos )
set( MAGICS_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/src
@@ -221,8 +221,12 @@ set( MAGICS_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/src/terralib/kernel
${CMAKE_CURRENT_SOURCE_DIR}/src/terralib/utils
${CMAKE_CURRENT_SOURCE_DIR}/src/libMagWrapper
- ${Boost_INCLUDE_DIRS}
- ${PANGOCAIRO_INCLUDE_DIRS} )
+ ${Boost_INCLUDE_DIRS} )
+
+if( HAVE_CAIRO )
+ list( APPEND MAGICS_TPLS PangoCairo )
+ list( APPEND MAGICS_INCLUDE_DIRS ${PANGOCAIRO_INCLUDE_DIRS} )
+endif()
if( HAVE_ODB )
list( APPEND MAGICS_TPLS odb_api )
diff --git a/VERSION.cmake b/VERSION.cmake
index 17915ac..fb3f9a7 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -1,6 +1,6 @@
-set ( metabuilder_version 2.26.2 )
-set ( _version 2.26.2 )
+set ( metabuilder_version 2.28.0 )
+set ( _version 2.28.0 )
if ( MAGICS_BUILD )
set( ${PROJECT_NAME}_VERSION_STR "${_version}-${MAGICS_BUILD}" )
else ()
diff --git a/apps/metgram/metgram.py b/apps/metgram/metgram.py
deleted file mode 100755
index c758e60..0000000
--- a/apps/metgram/metgram.py
+++ /dev/null
@@ -1,130 +0,0 @@
-
-import xml.sax
-import requests
-import json
-import sys, getopt
-
-epsgrams = {
- "15_days" : "classical_15d",
- "15_days_with_clim" : "classical_15d_with_climate",
- "10_days" : "classical_10d",
- "10_days_wave": "classical_wave",
- "10_days_plumes" : "classical_plume",
-
-}
-
-class MetgramHandler( xml.sax.ContentHandler ):
- def __init__(self):
- self.CurrentData = ""
- self.type = ""
- self.date = ""
- self.expver = ""
- self.stations = []
-
-
- # Call when an element starts
- def startElement(self, tag, attributes):
- self.CurrentData = tag
- if tag == "eps":
- self.type = attributes["template"]
- self.date = attributes.get("date", "")
- self.time = attributes.get("time", "")
- if ( self.time != "") :
- self.time = self.time[:2]
- self.expver = attributes.get("expver", "0001")
- self.stations = []
- if self.date == "latest":
- self.date = ""
- else:
- self.date = "%s%s" % (self.date, self.time)
-
-
- if tag == "station":
-
- request = {
- "station_name" : attributes["name"],
- "lat" : attributes["latitude"],
- "lon" : attributes["longitude"],
- "token" : "metview",
- "expver" : self.expver,
- "epsgram" : epsgrams[self.type]
- }
- if attributes.has_key("height") :
- request["altitude"] = attributes["height"],
-
- if self.date != "" :
- request["time"] = self.date
-
- if attributes.has_key("pngfile") :
- request["format"] = "png"
- output = attributes["pngfile"]
- if attributes.has_key("psfile") :
- request["format"] = "ps"
- output = attributes["psfile"]
- if attributes.has_key("pdffile") :
- request["format"] = "pdf"
- output = attributes["pdffile"]
- self.stations.append({"request" : request,
- "output": output}
- )
-
-
-
- # Call when an elements ends
- def endElement(self, tag):
- if tag == "eps":
-
-
- self.execute()
-
-
-
- # Call when a character is read
- def characters(self, content):
- pass
-
- def execute(self):
- url = "https://apps.ecmwf.int/plots/product-download/web/classical_meteogram"
- for station in self.stations :
- request = station["request"]
- request["token"] = "metview"
- request["email"] = "Web.Administrator at ecmwf.int"
- request = requests.get(url, params = request,
- proxies = { "http": "http://proxy.ecmwf.int:3333/" })
- print request.url
- if request.status_code == 200 :
- out = open(station["output"], "w")
- out.write(request.content)
- out.close()
- print "Result saved in %s" % (station["output"], )
- else :
- print "No Result -->Error %d" % (request.status_code)
- self.stations = []
-
-
-def main(argv):
- try:
- opts, args = getopt.getopt(argv,"hi:",["input="])
- except getopt.GetoptError:
- print 'metgram.py -i <inputfile> '
- sys.exit(2)
- for opt, arg in opts:
- if opt == '-h':
- print 'metgram.py -i <inputfile> '
- sys.exit()
- elif opt in ("-i", "--input"):
- input = arg
-
- # create an XMLReader
- parser = xml.sax.make_parser()
- # turn off namepsaces
- parser.setFeature(xml.sax.handler.feature_namespaces, 0)
-
- # override the default ContextHandler
- Handler = MetgramHandler()
- parser.setContentHandler( Handler )
-
- parser.parse(input)
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt
deleted file mode 100644
index 24a12cf..0000000
--- a/bin/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-if( ENABLE_INSTALL )
- install( PROGRAMS ecbuild DESTINATION ${INSTALL_BIN_DIR} )
-endif()
diff --git a/bin/ecbuild b/bin/ecbuild
index 8a271dc..d1ffff4 100755
--- a/bin/ecbuild
+++ b/bin/ecbuild
@@ -3,7 +3,7 @@
set -eua
CMAKE_MIN_REQUIRED=2.8.10
-CMAKE_BUILD_VERSION=3.2.3
+CMAKE_BUILD_VERSION=3.4.1
usage()
{
@@ -70,13 +70,13 @@ Available values for "option":
Build static libraries.
Equivalent to "-DBUILD_SHARED_LIBS=OFF"
- --dynamic
+ --dynamic, --shared
Build dynamic libraries (usually the default).
Equivalent to "-DBUILD_SHARED_LIBS=ON"
- --shared (same option as --dynamic)
- Build dynamic libraries (usually the default).
- Equivalent to "-DBUILD_SHARED_LIBS=ON"
+ --config=<config>
+ Configuration file using CMake syntax that gets included
+ Equivalent to cmake argument "-DECBUILD_CONFIG=<config-file>"
--toolchain=<toolchain>
Use a platform specific toolchain, containing settings such
@@ -151,27 +151,30 @@ EOF
exit $1
}
-
-INSTALL_DIR="$( dirname $( readlink -e "${BASH_SOURCE[0]}" ) )"
+INSTALL_DIR="$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )"
ECBUILD_MODULE_PATH=""
# If there is a directory share/ecbuild/cmake relative to the parent directory
# (as in an install tree), add it to CMAKE_MODULE_PATH
if [ -d $INSTALL_DIR/../share/ecbuild/cmake ]; then
- ECBUILD_MODULE_PATH="$( readlink -e $INSTALL_DIR/../share/ecbuild/cmake )"
-fi
+ ECBUILD_MODULE_PATH="$( cd "$INSTALL_DIR/../share/ecbuild/cmake" && pwd -P )"
# If there is a cmake subdirectory relative to the script directory (as in a
# tarball), add it to CMAKE_MODULE_PATH
-if [ -d $INSTALL_DIR/../cmake ]; then
- ECBUILD_MODULE_PATH="$( readlink -e $INSTALL_DIR/../cmake );$ECBUILD_MODULE_PATH"
+elif [ -d $INSTALL_DIR/../cmake ]; then
+ ECBUILD_MODULE_PATH="$( cd "$INSTALL_DIR/../cmake" && pwd -P )"
fi
-if [ -n "$ECBUILD_MODULE_PATH" ]; then
- ADD_ECBUILD_OPTIONS="-DCMAKE_MODULE_PATH=$ECBUILD_MODULE_PATH"
+
+# Fail if we couldn't find ecBuild modules
+if [ ! -f "$ECBUILD_MODULE_PATH/VERSION.cmake" ]; then
+ echo "FATAL: ecBuild modules could not be found in either $INSTALL_DIR/../share/ecbuild/cmake or $INSTALL_DIR/../cmake" >&2
+ exit 1
fi
+ADD_ECBUILD_OPTIONS="-DCMAKE_MODULE_PATH=$ECBUILD_MODULE_PATH"
+
if [ -d $INSTALL_DIR/../share/ecbuild/toolchains ]; then
- ECBUILD_TOOLCHAIN_DIR="$( readlink -e $INSTALL_DIR/../share/ecbuild/toolchains )"
+ ECBUILD_TOOLCHAIN_DIR="$( cd "$INSTALL_DIR/../share/ecbuild/toolchains" && pwd -P )"
elif [ -d $INSTALL_DIR/share/ecbuild/toolchains ]; then
- ECBUILD_TOOLCHAIN_DIR="$( readlink -e $INSTALL_DIR/share/ecbuild/toolchains )"
+ ECBUILD_TOOLCHAIN_DIR="$( cd "$INSTALL_DIR/share/ecbuild/toolchains" && pwd -P )"
fi
version()
@@ -185,7 +188,7 @@ version()
log()
{
- log_level=$(sed 's/.*/\U&/' <<< "$1")
+ log_level=$(tr "[a-z]" "[A-Z]" <<< "$1")
ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DECBUILD_LOG_LEVEL=${log_level}"
}
@@ -207,12 +210,26 @@ toolchains()
prefix()
{
- ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DCMAKE_INSTALL_PREFIX=$(readlink -m ${1/#\~\//$HOME\/})"
+ ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DCMAKE_INSTALL_PREFIX=${1/#\~\//$HOME/}"
+}
+
+config()
+{
+ arg=${1/#\~\//$HOME/}
+ if [ -f $arg ]; then
+ config_file=$arg
+ config_file="$( cd $( dirname "${config_file}" ) && pwd -P )/$( basename ${config_file} )"
+ else
+ echo "Error:"
+ echo " Config file [$arg] is not found or is not a file."
+ exit 1
+ fi
+ ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DECBUILD_CONFIG=${config_file}"
}
toolchain()
{
- arg=$1
+ arg=${1/#\~\//$HOME/}
if [ -f $arg ]; then
toolchain_file=$arg
else
@@ -226,7 +243,6 @@ toolchain()
echo " found in [$ECBUILD_TOOLCHAIN_DIR]"
exit 1
else
- toolchain_file=$( readlink -e "$toolchain_file" )
ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${toolchain_file}"
fi
}
@@ -235,7 +251,8 @@ cache()
{
arg=$1
if [ -f $arg ]; then
- cache_file=$( readlink -e "$arg" )
+ cache_file=$arg
+ cache_file="$( cd $( dirname "${cache_file}" ) && pwd -P )/$( basename ${cache_file} )"
else
echo "Error:"
echo " Cache file [$arg] is not found or is not a file."
@@ -291,7 +308,7 @@ while test $# -gt 0; do
cmakebin="$val"
;;
--prefix)
- prefix $val
+ prefix "$val"
;;
--build)
ADD_ECBUILD_OPTIONS="$ADD_ECBUILD_OPTIONS -DCMAKE_BUILD_TYPE=$val"
@@ -311,6 +328,9 @@ while test $# -gt 0; do
--toolchain)
toolchain $val
;;
+ --config)
+ config $val
+ ;;
--cache)
cache $val
;;
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
deleted file mode 100644
index d42a153..0000000
--- a/cmake/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-file( GLOB_RECURSE ecbuild_support_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*" )
-
-ecbuild_add_resources( TARGET ${PROJECT_NAME}_ecbuild_support_files
- SOURCES_PACK
- ${ecbuild_support_files} )
diff --git a/cmake/FindADSM.cmake b/cmake/FindADSM.cmake
index 76140b6..b46e798 100644
--- a/cmake/FindADSM.cmake
+++ b/cmake/FindADSM.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindAEC.cmake b/cmake/FindAEC.cmake
index 28d086d..767544f 100644
--- a/cmake/FindAEC.cmake
+++ b/cmake/FindAEC.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindAIO.cmake b/cmake/FindAIO.cmake
index 61fdcc0..76e357a 100644
--- a/cmake/FindAIO.cmake
+++ b/cmake/FindAIO.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindArmadillo.cmake b/cmake/FindArmadillo.cmake
index 4183306..5fdf2a6 100644
--- a/cmake/FindArmadillo.cmake
+++ b/cmake/FindArmadillo.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindCMath.cmake b/cmake/FindCMath.cmake
index 7cf6f58..0c18b52 100644
--- a/cmake/FindCMath.cmake
+++ b/cmake/FindCMath.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindDl.cmake b/cmake/FindDl.cmake
index 305fff0..3fb3cc8 100644
--- a/cmake/FindDl.cmake
+++ b/cmake/FindDl.cmake
@@ -1,4 +1,4 @@
-# © Copyright 1996-2014 ECMWF.
+# © Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindEMOS.cmake b/cmake/FindEMOS.cmake
index 56ee334..c549fc2 100644
--- a/cmake/FindEMOS.cmake
+++ b/cmake/FindEMOS.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindFDB.cmake b/cmake/FindFDB.cmake
index 6624544..4bcbdf3 100644
--- a/cmake/FindFDB.cmake
+++ b/cmake/FindFDB.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindHPSS.cmake b/cmake/FindHPSS.cmake
index 50f95cc..b2b662b 100644
--- a/cmake/FindHPSS.cmake
+++ b/cmake/FindHPSS.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindLEX.cmake b/cmake/FindLEX.cmake
index 34ea36c..221868f 100644
--- a/cmake/FindLEX.cmake
+++ b/cmake/FindLEX.cmake
@@ -44,7 +44,7 @@
# This file is based on the FindFLEX CMake macro, and adapted by ECMWF
#=============================================================================
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindLegacyFDB.cmake b/cmake/FindLegacyFDB.cmake
index 0136299..f92be59 100644
--- a/cmake/FindLegacyFDB.cmake
+++ b/cmake/FindLegacyFDB.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindLibGFortran.cmake b/cmake/FindLibGFortran.cmake
index bf9e168..f1150e8 100644
--- a/cmake/FindLibGFortran.cmake
+++ b/cmake/FindLibGFortran.cmake
@@ -1,8 +1,8 @@
-# © Copyright 1996-2014 ECMWF.
-#
+# © Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -23,16 +23,16 @@ if( GFORTRAN_EXECUTABLE )
ERROR_VARIABLE _GFORTRAN_ERROR_VALUE
OUTPUT_STRIP_TRAILING_WHITESPACE)
-# debug_var(_GFORTRAN_SEARCH_SUCCESS)
-# debug_var(_GFORTRAN_VALUES_OUTPUT)
-# debug_var(_GFORTRAN_ERROR_VALUE)
+# ecbuild_debug_var(_GFORTRAN_SEARCH_SUCCESS)
+# ecbuild_debug_var(_GFORTRAN_VALUES_OUTPUT)
+# ecbuild_debug_var(_GFORTRAN_ERROR_VALUE)
if(_GFORTRAN_SEARCH_SUCCESS MATCHES 0)
string(REGEX REPLACE ".*libraries: =(.*)" "\\1" _result ${_GFORTRAN_VALUES_OUTPUT})
string(REGEX REPLACE ":" ";" _gfortran_hints ${_result} )
endif()
- debug_var( _gfortran_hints )
+ ecbuild_debug_var( _gfortran_hints )
endif()
diff --git a/cmake/FindLibIFort.cmake b/cmake/FindLibIFort.cmake
index e1d82ee..8e12ad8 100644
--- a/cmake/FindLibIFort.cmake
+++ b/cmake/FindLibIFort.cmake
@@ -1,4 +1,4 @@
-# © Copyright 1996-2015 ECMWF.
+# © Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindMKL.cmake b/cmake/FindMKL.cmake
index fe182a4..1123234 100644
--- a/cmake/FindMKL.cmake
+++ b/cmake/FindMKL.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindNDBM.cmake b/cmake/FindNDBM.cmake
index 21cf1cf..869223f 100644
--- a/cmake/FindNDBM.cmake
+++ b/cmake/FindNDBM.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake
index b214d27..9084549 100644
--- a/cmake/FindNetCDF.cmake
+++ b/cmake/FindNetCDF.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -76,7 +76,7 @@ if( PREFER_NETCDF4 )
## hdf5
- # Note: Only the HDF5 C-library is required for NetCDF
+ # Note: Only the HDF5 C-library is required for NetCDF
# ( even for Fortan and CXX bindings)
find_package( HDF5 COMPONENTS C QUIET )
@@ -87,24 +87,24 @@ if( PREFER_NETCDF4 )
# Find NetCDF4
# message( "NETCDF CMAKE_PREFIX_PATH = [${CMAKE_PREFIX_PATH}]")
- # debug_var( NETCDF_ROOT )
- # debug_var( NETCDF_FIND_COMPONENTS )
- # debug_var( NETCDF_FIND_QUIETLY )
- # debug_var( NETCDF_FIND_REQUIRED )
+ # ecbuild_debug_var( NETCDF_ROOT )
+ # ecbuild_debug_var( NETCDF_FIND_COMPONENTS )
+ # ecbuild_debug_var( NETCDF_FIND_QUIETLY )
+ # ecbuild_debug_var( NETCDF_FIND_REQUIRED )
find_package( NetCDF4 COMPONENTS ${NETCDF_FIND_COMPONENTS} )
- # debug_var( NETCDF4_FOUND )
- # debug_var( NETCDF_FOUND )
- # debug_var( NETCDF_LIBRARIES )
- # debug_var( NETCDF_INCLUDE_DIRS )
+ # ecbuild_debug_var( NETCDF4_FOUND )
+ # ecbuild_debug_var( NETCDF_FOUND )
+ # ecbuild_debug_var( NETCDF_LIBRARIES )
+ # ecbuild_debug_var( NETCDF_INCLUDE_DIRS )
list( APPEND NETCDF_Fortran_LIBRARIES ${NETCDF_FORTRAN_LIBRARIES} ${NETCDF_F90_LIBRARIES} )
if( NETCDF_Fortran_LIBRARIES )
list( REMOVE_DUPLICATES NETCDF_Fortran_LIBRARIES )
endif()
- # debug_var( NETCDF_Fortran_LIBRARIES )
- # debug_var( NETCDF_C_LIBRARIES )
- # debug_var( NETCDF_CXX_LIBRARIES )
+ # ecbuild_debug_var( NETCDF_Fortran_LIBRARIES )
+ # ecbuild_debug_var( NETCDF_C_LIBRARIES )
+ # ecbuild_debug_var( NETCDF_CXX_LIBRARIES )
set_package_properties( NetCDF4 PROPERTIES TYPE RECOMMENDED PURPOSE "support for NetCDF4 file format" )
@@ -115,13 +115,13 @@ if( PREFER_NETCDF4 )
list( APPEND NETCDF_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS} )
endif()
- #debug_var( NETCDF_FOUND )
- #debug_var( NETCDF_LIBRARIES )
- #debug_var( NETCDF_INCLUDE_DIRS )
- #debug_var( HDF5_FOUND )
- #debug_var( HDF5_INCLUDE_DIRS )
- #debug_var( HDF5_HL_LIBRARIES )
- #debug_var( HDF5_LIBRARIES )
+ #ecbuild_debug_var( NETCDF_FOUND )
+ #ecbuild_debug_var( NETCDF_LIBRARIES )
+ #ecbuild_debug_var( NETCDF_INCLUDE_DIRS )
+ #ecbuild_debug_var( HDF5_FOUND )
+ #ecbuild_debug_var( HDF5_INCLUDE_DIRS )
+ #ecbuild_debug_var( HDF5_HL_LIBRARIES )
+ #ecbuild_debug_var( HDF5_LIBRARIES )
endif()
@@ -131,9 +131,9 @@ if( PREFER_NETCDF3 )
ecbuild_debug( "FindNetCDF: looking for NetCDF3" )
- # debug_var( NetCDF_FIND_COMPONENTS )
- # debug_var( NetCDF_FIND_QUIETLY )
- # debug_var( NetCDF_FIND_REQUIRED )
+ # ecbuild_debug_var( NetCDF_FIND_COMPONENTS )
+ # ecbuild_debug_var( NetCDF_FIND_QUIETLY )
+ # ecbuild_debug_var( NetCDF_FIND_REQUIRED )
list(FIND NetCDF_FIND_COMPONENTS "CXX" _index)
if(${_index} GREATER -1)
diff --git a/cmake/FindNetCDF3.cmake b/cmake/FindNetCDF3.cmake
index 20a5396..1fe9a74 100644
--- a/cmake/FindNetCDF3.cmake
+++ b/cmake/FindNetCDF3.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindODB.cmake b/cmake/FindODB.cmake
index bfa6905..1beb5c8 100644
--- a/cmake/FindODB.cmake
+++ b/cmake/FindODB.cmake
@@ -1,4 +1,4 @@
-# © Copyright 1996-2014 ECMWF.
+# © Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindOpenCL.cmake b/cmake/FindOpenCL.cmake
index e4e9556..4995d92 100644
--- a/cmake/FindOpenCL.cmake
+++ b/cmake/FindOpenCL.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindOpenJPEG.cmake b/cmake/FindOpenJPEG.cmake
index d692f35..805f091 100644
--- a/cmake/FindOpenJPEG.cmake
+++ b/cmake/FindOpenJPEG.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindPGIFortran.cmake b/cmake/FindPGIFortran.cmake
index ae2221b..58956fe 100644
--- a/cmake/FindPGIFortran.cmake
+++ b/cmake/FindPGIFortran.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindPango.cmake b/cmake/FindPango.cmake
index 0105d7f..fc1f879 100644
--- a/cmake/FindPango.cmake
+++ b/cmake/FindPango.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -17,10 +17,10 @@ find_package(PkgConfig)
pkg_check_modules(PC_LIBPANGO QUIET pango)
-debug_var( PC_LIBPANGO_FOUND )
-debug_var( PC_LIBPANGO_VERSION )
-debug_var( PC_LIBPANGO_LIBRARIES )
-debug_var( PC_LIBPANGO_INCLUDE_DIRS )
+ecbuild_debug_var( PC_LIBPANGO_FOUND )
+ecbuild_debug_var( PC_LIBPANGO_VERSION )
+ecbuild_debug_var( PC_LIBPANGO_LIBRARIES )
+ecbuild_debug_var( PC_LIBPANGO_INCLUDE_DIRS )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args( pango DEFAULT_MSG PC_LIBPANGO_LIBRARIES PC_LIBPANGO_INCLUDE_DIRS )
diff --git a/cmake/FindPangoCairo.cmake b/cmake/FindPangoCairo.cmake
index 611e269..a852e65 100644
--- a/cmake/FindPangoCairo.cmake
+++ b/cmake/FindPangoCairo.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -18,12 +18,12 @@ find_package(PkgConfig)
pkg_check_modules(PC_LIBPANGOCAIRO QUIET pangocairo)
-#debug_var( PC_LIBPANGOCAIRO_FOUND )
-#debug_var( PC_LIBPANGOCAIRO_VERSION )
-#debug_var( PC_LIBPANGOCAIRO_LIBRARIES )
-#debug_var( PC_LIBPANGOCAIRO_LDFLAGS )
-#debug_var( PC_LIBPANGOCAIRO_LDFLAGS_OTHER )
-#debug_var( PC_LIBPANGOCAIRO_INCLUDE_DIRS )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_FOUND )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_VERSION )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_LIBRARIES )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_LDFLAGS )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_LDFLAGS_OTHER )
+#ecbuild_debug_var( PC_LIBPANGOCAIRO_INCLUDE_DIRS )
if(PC_LIBPANGOCAIRO_FOUND)
diff --git a/cmake/FindProj4.cmake b/cmake/FindProj4.cmake
index 6774b6e..64eab79 100644
--- a/cmake/FindProj4.cmake
+++ b/cmake/FindProj4.cmake
@@ -38,9 +38,9 @@ if( NOT PROJ4_PATH )
endif()
-# debug_var( PKG_CONFIG_FOUND )
-# debug_var( PKPROJ4_FOUND )
-# debug_var( PROJ4_MIN_VERSION )
+# ecbuild_debug_var( PKG_CONFIG_FOUND )
+# ecbuild_debug_var( PKPROJ4_FOUND )
+# ecbuild_debug_var( PROJ4_MIN_VERSION )
endif()
@@ -55,8 +55,8 @@ find_path(PROJ4_INCLUDE_DIR NAMES proj_api.h PATHS PATH_SUFFIXES proj4 )
find_library( PROJ4_LIBRARY NAMES proj PATHS PATH_SUFFIXES proj4 )
-# debug_var( PROJ4_INCLUDE_DIR )
-# debug_var( PROJ4_LIBRARY )
+# ecbuild_debug_var( PROJ4_INCLUDE_DIR )
+# ecbuild_debug_var( PROJ4_LIBRARY )
# handle the QUIETLY and REQUIRED arguments and set GRIBAPI_FOUND
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindREADLINE.cmake b/cmake/FindREADLINE.cmake
index 9477026..2ba08b4 100644
--- a/cmake/FindREADLINE.cmake
+++ b/cmake/FindREADLINE.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -47,8 +47,8 @@ cmake_push_check_state()
cmake_pop_check_state()
-# debug_var( readline_version )
-# debug_var( __readline_version_out )
+# ecbuild_debug_var( readline_version )
+# ecbuild_debug_var( __readline_version_out )
set( __readline_fail 0 )
if( __readline_version_out )
diff --git a/cmake/FindRPCGEN.cmake b/cmake/FindRPCGEN.cmake
index 98c4a98..fd42e9f 100644
--- a/cmake/FindRPCGEN.cmake
+++ b/cmake/FindRPCGEN.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindRealtime.cmake b/cmake/FindRealtime.cmake
index b46b9b7..8fd65b1 100644
--- a/cmake/FindRealtime.cmake
+++ b/cmake/FindRealtime.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindSZip.cmake b/cmake/FindSZip.cmake
index d7d6026..925348c 100644
--- a/cmake/FindSZip.cmake
+++ b/cmake/FindSZip.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindTrilinos.cmake b/cmake/FindTrilinos.cmake
index 9cc6132..0d99b54 100644
--- a/cmake/FindTrilinos.cmake
+++ b/cmake/FindTrilinos.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindViennaCL.cmake b/cmake/FindViennaCL.cmake
index a1b1eb9..af7469d 100644
--- a/cmake/FindViennaCL.cmake
+++ b/cmake/FindViennaCL.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindXLFortranLibs.cmake b/cmake/FindXLFortranLibs.cmake
index 7be0070..ff93481 100644
--- a/cmake/FindXLFortranLibs.cmake
+++ b/cmake/FindXLFortranLibs.cmake
@@ -1,4 +1,4 @@
-# © Copyright 1996-2014 ECMWF.
+# © Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/FindYACC.cmake b/cmake/FindYACC.cmake
index dbdb191..7b15bfe 100644
--- a/cmake/FindYACC.cmake
+++ b/cmake/FindYACC.cmake
@@ -41,7 +41,7 @@
# This file is based on the FindFLEX CMake macro, and adapted by ECMWF
#=============================================================================
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/Findgrib_api.cmake b/cmake/Findgrib_api.cmake
index 32a01e9..ab6fc0b 100644
--- a/cmake/Findgrib_api.cmake
+++ b/cmake/Findgrib_api.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -20,16 +20,16 @@ option( GRIB_API_JPG "use jpg with grib_api" ON )
if( NOT grib_api_FOUND AND NOT NO_GRIB_API_BINARIES )
if( GRIB_API_JPG ) # jpeg support
-
+
find_package( JPEG QUIET ) # grib_api might be a static .a library in which
-
+
if( NOT "$ENV{JASPER_PATH}" STREQUAL "" )
list( APPEND CMAKE_PREFIX_PATH "$ENV{JASPER_PATH}" )
endif()
find_package( Jasper QUIET ) # case we don't know if which jpeg library was used
-
- find_package( OpenJPEG QUIET ) # so we try to find all jpeg libs and link to them
-
+
+ find_package( OpenJPEG QUIET ) # so we try to find all jpeg libs and link to them
+
if(JPEG_FOUND)
list( APPEND _grib_api_jpg_incs ${JPEG_INCLUDE_DIR} )
list( APPEND _grib_api_jpg_libs ${JPEG_LIBRARIES} )
@@ -44,18 +44,18 @@ if( NOT grib_api_FOUND AND NOT NO_GRIB_API_BINARIES )
endif()
endif()
-
+
if( GRIB_API_PNG ) # png support
-
+
find_package(PNG)
-
+
if( DEFINED PNG_PNG_INCLUDE_DIR AND NOT DEFINED PNG_INCLUDE_DIRS )
set( PNG_INCLUDE_DIRS ${PNG_PNG_INCLUDE_DIR} CACHE INTERNAL "PNG include dirs" )
endif()
if( DEFINED PNG_LIBRARY AND NOT DEFINED PNG_LIBRARIES )
set( PNG_LIBRARIES ${PNG_LIBRARY} CACHE INTERNAL "PNG libraries" )
endif()
-
+
if(PNG_FOUND)
list( APPEND _grib_api_png_defs ${PNG_DEFINITIONS} )
list( APPEND _grib_api_png_incs ${PNG_INCLUDE_DIRS} )
@@ -85,22 +85,22 @@ if( NOT grib_api_FOUND AND NOT NO_GRIB_API_BINARIES )
find_library(GRIB_API_LIB_F77 NAMES grib_api_f77 PATHS ${GRIB_API_PATH} ${GRIB_API_PATH}/lib PATH_SUFFIXES grib_api NO_DEFAULT_PATH)
find_program(GRIB_API_INFO NAMES grib_info PATHS ${GRIB_API_PATH} ${GRIB_API_PATH}/bin PATH_SUFFIXES grib_api NO_DEFAULT_PATH)
endif()
-
+
find_path(GRIB_API_INCLUDE_DIR NAMES grib_api.h PATHS PATH_SUFFIXES grib_api )
find_library( GRIB_API_LIBRARY NAMES grib_api PATHS PATH_SUFFIXES grib_api )
find_library( GRIB_API_LIB_F90 NAMES grib_api_f90 PATHS PATH_SUFFIXES grib_api )
find_library( GRIB_API_LIB_F77 NAMES grib_api_f77 PATHS PATH_SUFFIXES grib_api )
find_program(GRIB_API_INFO NAMES grib_info PATHS PATH_SUFFIXES grib_api )
-
+
list( APPEND GRIB_API_LIBRARIES ${GRIB_API_LIBRARY} ${GRIB_API_LIB_F90} ${GRIB_API_LIB_F77} )
set( GRIB_API_INCLUDE_DIRS ${GRIB_API_INCLUDE_DIR} )
if( GRIB_API_INFO )
-
+
execute_process( COMMAND ${GRIB_API_INFO} -v OUTPUT_VARIABLE _grib_info_out ERROR_VARIABLE _grib_info_err OUTPUT_STRIP_TRAILING_WHITESPACE )
-
- # debug_var( _grib_info_out )
-
+
+ # ecbuild_debug_var( _grib_info_out )
+
string( REPLACE "." " " _version_list ${_grib_info_out} ) # dots to spaces
separate_arguments( _version_list )
@@ -108,22 +108,22 @@ if( NOT grib_api_FOUND AND NOT NO_GRIB_API_BINARIES )
list( GET _version_list 1 GRIB_API_MINOR_VERSION )
list( GET _version_list 2 GRIB_API_PATCH_VERSION )
- set( GRIB_API_VERSION "${GRIB_API_MAJOR_VERSION}.${GRIB_API_MINOR_VERSION}.${GRIB_API_PATCH_VERSION}" )
+ set( GRIB_API_VERSION "${GRIB_API_MAJOR_VERSION}.${GRIB_API_MINOR_VERSION}.${GRIB_API_PATCH_VERSION}" )
set( GRIB_API_VERSION_STR "${_grib_info_out}" )
- set( grib_api_VERSION "${GRIB_API_VERSION}" )
+ set( grib_api_VERSION "${GRIB_API_VERSION}" )
set( grib_api_VERSION_STR "${GRIB_API_VERSION_STR}" )
endif()
-
+
include(FindPackageHandleStandardArgs)
-
+
# handle the QUIETLY and REQUIRED arguments and set GRIB_API_FOUND to TRUE
find_package_handle_standard_args( grib_api DEFAULT_MSG
GRIB_API_LIBRARY GRIB_API_INCLUDE_DIR GRIB_API_INFO )
-
+
mark_as_advanced( GRIB_API_INCLUDE_DIR GRIB_API_LIBRARY GRIB_API_INFO )
-
+
list( APPEND GRIB_API_DEFINITIONS ${_grib_api_jpg_defs} ${_grib_api_png_defs} )
list( APPEND GRIB_API_INCLUDE_DIRS ${_grib_api_jpg_incs} ${_grib_api_png_incs} )
list( APPEND GRIB_API_LIBRARIES ${_grib_api_jpg_libs} ${_grib_api_png_libs} )
diff --git a/cmake/Findodb_api.cmake b/cmake/Findodb_api.cmake
index 5cd2a10..0058fbe 100644
--- a/cmake/Findodb_api.cmake
+++ b/cmake/Findodb_api.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/Findspot.cmake b/cmake/Findspot.cmake
index 1edb2cd..52e0fb5 100644
--- a/cmake/Findspot.cmake
+++ b/cmake/Findspot.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2012 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/VERSION.cmake b/cmake/VERSION.cmake
index a07bd4a..e7ac9ad 100644
--- a/cmake/VERSION.cmake
+++ b/cmake/VERSION.cmake
@@ -1,7 +1,7 @@
-set( ECBUILD_MAJOR_VERSION "1" )
-set( ECBUILD_MINOR_VERSION "9" )
+set( ECBUILD_MAJOR_VERSION "2" )
+set( ECBUILD_MINOR_VERSION "0" )
set( ECBUILD_PATCH_VERSION "0" )
-set( ECBUILD_VERSION_STR "1.9.0" )
+set( ECBUILD_VERSION_STR "2.0.0" )
set( ECBUILD_MACRO_VERSION "${ECBUILD_MAJOR_VERSION}.${ECBUILD_MINOR_VERSION}" )
diff --git a/cmake/compiler_flags/Clang_C.cmake b/cmake/compiler_flags/Clang_C.cmake
new file mode 100644
index 0000000..bc73c69
--- /dev/null
+++ b/cmake/compiler_flags/Clang_C.cmake
@@ -0,0 +1,13 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "C compiler flags for Release builds" FORCE )
+set( CMAKE_C_FLAGS_BIT "-O2 -DNDEBUG" CACHE STRING "C compiler flags for Bit-reproducible builds" FORCE )
+set( CMAKE_C_FLAGS_DEBUG "-O0 -g -ftrapv" CACHE STRING "C compiler flags for Debug builds" FORCE )
+set( CMAKE_C_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "C compiler flags for Production builds." FORCE )
+set( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "C compiler flags for RelWithDebInfo builds." FORCE )
diff --git a/cmake/compiler_flags/Clang_CXX.cmake b/cmake/compiler_flags/Clang_CXX.cmake
new file mode 100644
index 0000000..53f0f21
--- /dev/null
+++ b/cmake/compiler_flags/Clang_CXX.cmake
@@ -0,0 +1,13 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "C++ compiler flags for Release builds" FORCE )
+set( CMAKE_CXX_FLAGS_BIT "-O2 -DNDEBUG" CACHE STRING "C++ compiler flags for Bit-reproducible builds" FORCE )
+set( CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ftrapv" CACHE STRING "C++ compiler flags for Debug builds" FORCE )
+set( CMAKE_CXX_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "C++ compiler flags for Production builds." FORCE )
+set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "C++ compiler flags for RelWithDebInfo builds." FORCE )
diff --git a/cmake/compiler_flags/Cray_C.cmake b/cmake/compiler_flags/Cray_C.cmake
new file mode 100644
index 0000000..76779f9
--- /dev/null
+++ b/cmake/compiler_flags/Cray_C.cmake
@@ -0,0 +1,14 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_C_FLAGS_ALL "-hlist=amid" CACHE STRING "Common flags for all build-types" FORCE )
+set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" CACHE STRING "Release C flags" FORCE )
+set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG" CACHE STRING "Release-with-debug-info C flags" FORCE )
+set( CMAKE_C_FLAGS_PRODUCTION "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -G2" CACHE STRING "Production C flags" FORCE )
+set( CMAKE_C_FLAGS_BIT "${CMAKE_C_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible C flags" FORCE )
+set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_ALL} -O0 -G0" CACHE STRING "Debug Cflags" FORCE )
diff --git a/cmake/compiler_flags/Cray_CXX.cmake b/cmake/compiler_flags/Cray_CXX.cmake
new file mode 100644
index 0000000..d599bff
--- /dev/null
+++ b/cmake/compiler_flags/Cray_CXX.cmake
@@ -0,0 +1,14 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_CXX_FLAGS_ALL "-hlist=amid" CACHE STRING "Common flags for all build-types" FORCE )
+set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" CACHE STRING "Release C++ flags" FORCE )
+set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG" CACHE STRING "Release-with-debug-info C++ flags" FORCE )
+set( CMAKE_CXX_FLAGS_PRODUCTION "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -G2" CACHE STRING "Production C++ flags" FORCE )
+set( CMAKE_CXX_FLAGS_BIT "${CMAKE_CXX_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible C++ flags" FORCE )
+set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_ALL} -O0 -G0" CACHE STRING "Debug CXX flags" FORCE )
diff --git a/cmake/compiler_flags/Cray_Fortran.cmake b/cmake/compiler_flags/Cray_Fortran.cmake
new file mode 100644
index 0000000..b2c23de
--- /dev/null
+++ b/cmake/compiler_flags/Cray_Fortran.cmake
@@ -0,0 +1,15 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+# -emf activates .mods and uses lower case
+set( CMAKE_Fortran_FLAGS_ALL "-emf" CACHE STRING "Common flags for all build-types" FORCE )
+set( CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_ALL} -O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" CACHE STRING "Release Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_RELWITHDEBINFO "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -Gfast -DNDEBUG" CACHE STRING "Release-with-debug-info Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_PRODUCTION "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -G2" CACHE STRING "Production Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_BIT "${CMAKE_Fortran_FLAGS_ALL} -O2 -hfp1 -G2 -hflex_mp=conservative -hadd_paren -DNDEBUG" CACHE STRING "Bit-reproducible Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_ALL} -O0 -G0" CACHE STRING "Debug Fortran flags" FORCE )
diff --git a/cmake/compiler_flags/GNU_C.cmake b/cmake/compiler_flags/GNU_C.cmake
new file mode 100644
index 0000000..955f527
--- /dev/null
+++ b/cmake/compiler_flags/GNU_C.cmake
@@ -0,0 +1,18 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "C compiler flags for Release builds" FORCE )
+set( CMAKE_C_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG" CACHE STRING "C compiler flags for Bit-reproducible builds" FORCE )
+set( CMAKE_C_FLAGS_DEBUG "-O0 -g" CACHE STRING "C compiler flags for Debug builds" FORCE )
+set( CMAKE_C_FLAGS_PRODUCTION "-O2 -g" CACHE STRING "C compiler flags for Production builds." FORCE )
+set( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "C compiler flags for RelWithDebInfo builds." FORCE )
+
+# NOTE: gcc does not guarrante that -O3 performs better than -O2
+# -- it can perform worse due to assembly code bloating.
+# Moreover for gcc 4.1.2 we found that -O3 remove the parser code generated from Lex/Yacc
+# and therefore in production mode we downgrade to -O2 if the compiler is GCC (for all versions).
diff --git a/cmake/compiler_flags/GNU_CXX.cmake b/cmake/compiler_flags/GNU_CXX.cmake
new file mode 100644
index 0000000..0ab8c3a
--- /dev/null
+++ b/cmake/compiler_flags/GNU_CXX.cmake
@@ -0,0 +1,18 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "C++ compiler flags for Release builds" FORCE )
+set( CMAKE_CXX_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG" CACHE STRING "C++ compiler flags for Bit-reproducible builds" FORCE )
+set( CMAKE_CXX_FLAGS_DEBUG "-O0 -g" CACHE STRING "C++ compiler flags for Debug builds" FORCE )
+set( CMAKE_CXX_FLAGS_PRODUCTION "-O2 -g" CACHE STRING "C++ compiler flags for Production builds." FORCE )
+set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "C++ compiler flags for RelWithDebInfo builds." FORCE )
+
+# NOTE: gcc does not guarrante that -O3 performs better than -O2
+# -- it can perform worse due to assembly code bloating.
+# Moreover for gcc 4.1.2 we found that -O3 remove the parser code generated from Lex/Yacc
+# and therefore in production mode we downgrade to -O2 if the compiler is GCC (for all versions).
diff --git a/cmake/compiler_flags/GNU_Fortran.cmake b/cmake/compiler_flags/GNU_Fortran.cmake
new file mode 100644
index 0000000..a12abec
--- /dev/null
+++ b/cmake/compiler_flags/GNU_Fortran.cmake
@@ -0,0 +1,21 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_Fortran_FLAGS_RELEASE "-O3 -funroll-all-loops -finline-functions" CACHE STRING "Fortran compiler flags for Release builds" FORCE )
+set( CMAKE_Fortran_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG -fno-range-check -fconvert=big-endian" CACHE STRING "Fortran compiler flags for Bit-reproducible builds" FORCE )
+set( CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -fcheck=bounds -fbacktrace -finit-real=snan" CACHE STRING "Fortran compiler flags for Debug builds" FORCE )
+set( CMAKE_Fortran_FLAGS_PRODUCTION "-O2 -g" CACHE STRING "Fortran compiler flags for Production builds." FORCE )
+set( CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Fortran compiler flags for RelWithDebInfo builds." FORCE )
+
+####################################################################
+
+# Meaning of flags
+# ----------------
+# -fstack-arrays : Allocate automatic arrays on the stack (needs large stacksize!!!)
+# -funroll-all-loops : Unroll all loops
+# -fcheck=bounds : Bounds checking
diff --git a/cmake/compiler_flags/Intel_C.cmake b/cmake/compiler_flags/Intel_C.cmake
new file mode 100644
index 0000000..dbea59f
--- /dev/null
+++ b/cmake/compiler_flags/Intel_C.cmake
@@ -0,0 +1,13 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "Release C compiler flags" FORCE )
+set( CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Release-with-debug-info C compiler flags" FORCE )
+set( CMAKE_C_FLAGS_BIT "-O2 -DNDEBUG" CACHE STRING "Bit-reproducible C compiler flags" FORCE )
+set( CMAKE_C_FLAGS_DEBUG "-O0 -g -traceback" CACHE STRING "Debug C compiler flags" FORCE )
+set( CMAKE_C_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "Production C compiler flags" FORCE )
diff --git a/cmake/compiler_flags/Intel_CXX.cmake b/cmake/compiler_flags/Intel_CXX.cmake
new file mode 100644
index 0000000..5b8dc78
--- /dev/null
+++ b/cmake/compiler_flags/Intel_CXX.cmake
@@ -0,0 +1,13 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "Release C++ compiler flags" FORCE )
+set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Release-with-debug-info C++ compiler flags" FORCE )
+set( CMAKE_CXX_FLAGS_BIT "-O2 -DNDEBUG" CACHE STRING "Bit-reproducible C++ compiler flags" FORCE )
+set( CMAKE_CXX_FLAGS_DEBUG "-O0 -g -traceback" CACHE STRING "Debug C++ compiler flags" FORCE )
+set( CMAKE_CXX_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "Production C++ compiler flags" FORCE )
diff --git a/cmake/compiler_flags/Intel_Fortran.cmake b/cmake/compiler_flags/Intel_Fortran.cmake
new file mode 100644
index 0000000..86b69dc
--- /dev/null
+++ b/cmake/compiler_flags/Intel_Fortran.cmake
@@ -0,0 +1,14 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( CMAKE_Fortran_FLAGS_RELEASE "-O3 -unroll -inline -heap-arrays" CACHE STRING "Release Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Release-with-debug-info Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_BIT "-O2 -unroll -inline -heap-arrays" CACHE STRING "Bit-reproducible Fortran flags" FORCE )
+# -check all implies -check bounds
+set( CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -traceback -heap-arrays -check all" CACHE STRING "Debug Fortran flags" FORCE )
+set( CMAKE_Fortran_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "Production Fortran compiler flags" FORCE )
diff --git a/cmake/compiler_flags/PGI_C.cmake b/cmake/compiler_flags/PGI_C.cmake
new file mode 100644
index 0000000..6784a14
--- /dev/null
+++ b/cmake/compiler_flags/PGI_C.cmake
@@ -0,0 +1,11 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+set( CMAKE_C_FLAGS_RELEASE "-fast -O3 -DNDEBUG" CACHE STRING "Release C compiler flags" FORCE )
+
+set( CMAKE_C_LINK_FLAGS "" CACHE STRING "" )
diff --git a/cmake/compiler_flags/PGI_CXX.cmake b/cmake/compiler_flags/PGI_CXX.cmake
new file mode 100644
index 0000000..877ef3f
--- /dev/null
+++ b/cmake/compiler_flags/PGI_CXX.cmake
@@ -0,0 +1,11 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+set( CMAKE_CXX_FLAGS_RELEASE "-fast -O3 -DNDEBUG" CACHE STRING "Release C++ compiler flags" FORCE )
+
+set( CMAKE_CXX_LINK_FLAGS "" CACHE STRING "" )
diff --git a/cmake/compiler_flags/PGI_Fortran.cmake b/cmake/compiler_flags/PGI_Fortran.cmake
new file mode 100644
index 0000000..a268cc9
--- /dev/null
+++ b/cmake/compiler_flags/PGI_Fortran.cmake
@@ -0,0 +1,11 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+set( CMAKE_Fortran_FLAGS_RELEASE "-fast -O3" CACHE STRING "Release Fortran compiler flags" FORCE )
+
+set( CMAKE_Fortran_LINK_FLAGS "" CACHE STRING "" )
diff --git a/cmake/contrib/FindFFTW.cmake b/cmake/contrib/FindFFTW.cmake
index d76767b..5ef46df 100644
--- a/cmake/contrib/FindFFTW.cmake
+++ b/cmake/contrib/FindFFTW.cmake
@@ -1,22 +1,60 @@
-# - Find the FFTW library
-#
-# Usage:
-# find_package(FFTW [REQUIRED] [QUIET] )
-#
-# It sets the following variables:
-# FFTW_FOUND ... true if fftw is found on the system
-# FFTW_LIBRARIES ... full path to fftw library
-# FFTW_INCLUDES ... fftw include directory
-#
-# The following variables will be checked by the function
-# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found
-# FFTW_ROOT ... if set, the libraries are exclusively searched
-# under this path
-# FFTW_DIR ... equivalent to FFTW_ROOT
-# FFTW_PATH ... equivalent to FFTW_ROOT
-# FFTW_LIBRARY ... fftw library to use
-# FFTW_INCLUDE_DIR ... fftw include directory
+# (C) Copyright 1996-2016 ECMWF.
#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# FindFFTW
+# ========
+#
+# Find the FFTW library. ::
+#
+# find_package(FFTW [REQUIRED] [QUIET]
+# [COMPONENTS [single] [double] [long_double] [quad]])
+#
+# By default, search for the double precision library ``fftw3``
+#
+# Components
+# ----------
+#
+# If a different version or multiple versions of the library are required,
+# these need to be specified as ``COMPONENTS``. Note that double must be given
+# explicitly if any ``COMPONENTS`` are specified.
+#
+# The libraries corresponding to each of the ``COMPONENTS`` are:
+#
+# :single: ``fftw3f``
+# :double: ``fftw3``
+# :long_double: ``fftw3l``
+# :quad: ``fftw3q``
+#
+# Output variables
+# ----------------
+#
+# The following CMake variables are set on completion:
+#
+# :FFTW_FOUND: true if FFTW is found on the system
+# :FFTW_LIBRARIES: full paths to requested FFTW libraries
+# :FFTW_INCLUDES: FFTW include directory
+#
+# Input variables
+# ---------------
+#
+# The following CMake variables are checked by the function:
+#
+# :FFTW_USE_STATIC_LIBS: if true, only static libraries are found
+# :FFTW_ROOT: if set, this path is exclusively searched
+# :FFTW_DIR: equivalent to FFTW_ROOT
+# :FFTW_PATH: equivalent to FFTW_ROOT
+# :FFTW_LIBRARY: FFTW library to use
+# :FFTW_INCLUDE_DIR: FFTW include directory
+#
+##############################################################################
#============================================#
# #
@@ -72,76 +110,103 @@ else()
set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX} )
endif()
+if( FFTW_FIND_COMPONENTS )
+ ecbuild_debug( "FindFFTW: looking for components: ${FFTW_FIND_COMPONENTS}" )
+ foreach( _component ${FFTW_FIND_COMPONENTS} )
+ if( _component MATCHES "single" )
+ ecbuild_debug( "FindFFTW: looking for single precision (fftw3f)" )
+ set( _require_sp TRUE )
+ elseif( _component MATCHES "double" )
+ ecbuild_debug( "FindFFTW: looking for double precision (fftw3)" )
+ set( _require_dp TRUE )
+ elseif( _component MATCHES "long_double" )
+ ecbuild_debug( "FindFFTW: looking for long double precision (fftw3l)" )
+ set( _require_lp TRUE )
+ elseif( _component MATCHES "quad" )
+ ecbuild_debug( "FindFFTW: looking for quad precision (fftw3q)" )
+ set( _require_qp TRUE )
+ else()
+ endif()
+ endforeach()
+else()
+ ecbuild_debug( "FindFFTW: no components specified, looking for double precision (fftw3)" )
+ set( _require_dp TRUE )
+endif()
+
if( FFTW_ROOT )
+ set( _default_paths NO_DEFAULT_PATH )
+ set( _lib_paths ${FFTW_ROOT} )
+ set( _include_paths ${FFTW_ROOT} )
+else()
+ set( _lib_paths ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} )
+ set( _include_paths ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} )
+endif()
+
+#find libs
- #find libs
+if( _require_dp )
find_library(
FFTW_LIB
NAMES "fftw3"
- PATHS ${FFTW_ROOT}
+ PATHS ${_lib_paths}
PATH_SUFFIXES "lib" "lib64"
- NO_DEFAULT_PATH
+ ${_default_paths}
)
+ if( NOT FFTW_LIB )
+ ecbuild_warn("FindFFTW: double precision required, but fftw3 was not found")
+ endif()
+endif()
+if( _require_sp )
find_library(
FFTWF_LIB
NAMES "fftw3f"
- PATHS ${FFTW_ROOT}
+ PATHS ${_lib_paths}
PATH_SUFFIXES "lib" "lib64"
- NO_DEFAULT_PATH
+ ${_default_paths}
)
+ if( NOT FFTWF_LIB )
+ ecbuild_warn("FindFFTW: single precision required, but fftw3f was not found")
+ endif()
+endif()
+if( _require_lp )
find_library(
FFTWL_LIB
NAMES "fftw3l"
- PATHS ${FFTW_ROOT}
+ PATHS ${_lib_paths}
PATH_SUFFIXES "lib" "lib64"
- NO_DEFAULT_PATH
+ ${_default_paths}
)
+ if( NOT FFTWL_LIB )
+ ecbuild_warn("FindFFTW: long double precision required, but fftw3l was not found")
+ endif()
+endif()
- #find includes
- find_path(
- FFTW_INCLUDES
- NAMES "fftw3.h"
- PATHS ${FFTW_ROOT}
- PATH_SUFFIXES "include"
- NO_DEFAULT_PATH
- )
-
-else()
-
- find_library(
- FFTW_LIB
- NAMES "fftw3"
- PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
- )
-
- find_library(
- FFTWF_LIB
- NAMES "fftw3f"
- PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
- )
-
-
+if( _require_qp )
find_library(
- FFTWL_LIB
- NAMES "fftw3l"
- PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}
- )
-
- find_path(
- FFTW_INCLUDES
- NAMES "fftw3.h"
- PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR}
+ FFTWQ_LIB
+ NAMES "fftw3q"
+ PATHS ${_lib_paths}
+ PATH_SUFFIXES "lib" "lib64"
+ ${_default_paths}
)
+ if( NOT FFTWQ_LIB )
+ ecbuild_warn("FindFFTW: quad precision required, but fftw3q was not found")
+ endif()
+endif()
-endif( FFTW_ROOT )
+#find includes
-set(FFTW_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB})
+find_path(
+ FFTW_INCLUDES
+ NAMES "fftw3.h"
+ PATHS ${_include_paths}
+ PATH_SUFFIXES "include"
+ ${_default_paths}
+)
-if(FFTWL_LIB)
- set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTWL_LIB})
-endif()
+set(FFTW_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB} ${FFTWL_LIB} ${FFTWQ_LIB})
set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} )
@@ -149,4 +214,4 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFTW DEFAULT_MSG
FFTW_INCLUDES FFTW_LIBRARIES)
-mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB)
\ No newline at end of file
+mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB)
diff --git a/cmake/contrib/FindNetCDF4.cmake b/cmake/contrib/FindNetCDF4.cmake
index 89b0337..2afff21 100644
--- a/cmake/contrib/FindNetCDF4.cmake
+++ b/cmake/contrib/FindNetCDF4.cmake
@@ -158,7 +158,7 @@ else()
foreach( LANGUAGE ${NETCDF_LANGUAGE_BINDINGS} )
ecbuild_debug("FindNetCDF4: looking for ${LANGUAGE} language bindings")
set( NETCDF_${LANGUAGE}_FOUND 1 ) # disable this in following if necessary
-
+
# find the NETCDF includes
foreach( INC ${NETCDF_${LANGUAGE}_INCLUDE_NAMES} )
find_path( NETCDF_${INC}_INCLUDE_DIR ${INC}
@@ -170,7 +170,7 @@ else()
Include
)
mark_as_advanced( NETCDF_${INC}_INCLUDE_DIR )
- # debug_var( NETCDF_${INC}_INCLUDE_DIR)
+ # ecbuild_debug_var( NETCDF_${INC}_INCLUDE_DIR)
if (NETCDF_${INC}_INCLUDE_DIR)
list( APPEND NETCDF_INCLUDE_DIRS ${NETCDF_${INC}_INCLUDE_DIR} )
else()
@@ -249,19 +249,19 @@ else()
# Append the libraries for this language binding to the list of all
# required libraries.
-
+
if( NETCDF_${LANGUAGE}_FOUND )
ecbuild_debug( "FindNetCDF4: ${LANGUAGE} language bindings found" )
if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
- list( APPEND NETCDF_${LANGUAGE}_LIBRARIES
+ list( APPEND NETCDF_${LANGUAGE}_LIBRARIES
debug ${NETCDF_${LANGUAGE}_LIBRARIES_DEBUG}
optimized ${NETCDF_${LANGUAGE}_LIBRARIES_RELEASE} )
else()
- list( APPEND NETCDF_${LANGUAGE}_LIBRARIES
- ${NETCDF_${LANGUAGE}_LIBRARIES_RELEASE} )
+ list( APPEND NETCDF_${LANGUAGE}_LIBRARIES
+ ${NETCDF_${LANGUAGE}_LIBRARIES_RELEASE} )
endif()
endif()
- # debug_var( NETCDF_${LANGUAGE}_LIBRARIES )
+ # ecbuild_debug_var( NETCDF_${LANGUAGE}_LIBRARIES )
list( APPEND NETCDF_FOUND_REQUIRED_VARS NETCDF_${LANGUAGE}_FOUND )
endforeach()
diff --git a/cmake/contrib/GetGitRevisionDescription.cmake.in b/cmake/contrib/GetGitRevisionDescription.cmake.in
index 7a3e42f..9fd3e64 100644
--- a/cmake/contrib/GetGitRevisionDescription.cmake.in
+++ b/cmake/contrib/GetGitRevisionDescription.cmake.in
@@ -33,6 +33,10 @@ else()
endif()
if(NOT HEAD_HASH)
+ if(EXISTS "@GIT_DATA@/head-ref")
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
-endif()
\ No newline at end of file
+ else()
+ set(HEAD_HASH "unknown")
+ endif()
+endif()
diff --git a/cmake/contrib/GreatCMakeCookOff/tests/CMakeLists.txt b/cmake/contrib/GreatCMakeCookOff/tests/CMakeLists.txt
deleted file mode 100644
index f2eb4d0..0000000
--- a/cmake/contrib/GreatCMakeCookOff/tests/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
-project(COOKOFF_TEST)
-
-enable_testing()
-
-include(${PROJECT_SOURCE_DIR}/../TestCMake.cmake)
-
-cmake_test(checkisnan SOURCE)
-cmake_test(checkcpp11flags)
-cmake_test(addgtest NOEXEC SOURCE --test-command ${CMAKE_MAKE_PROGRAM} test)
-
-add_subdirectory(cpp11)
diff --git a/cmake/contrib/GreatCMakeCookOff/tests/cpp11/CMakeLists.txt b/cmake/contrib/GreatCMakeCookOff/tests/cpp11/CMakeLists.txt
deleted file mode 100644
index 45d20a5..0000000
--- a/cmake/contrib/GreatCMakeCookOff/tests/cpp11/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_test(allfeatures)
-cmake_test(parse_input_features)
-cmake_test(check_features)
diff --git a/cmake/ecbuild-config-version.cmake b/cmake/ecbuild-config-version.cmake
new file mode 100644
index 0000000..df30489
--- /dev/null
+++ b/cmake/ecbuild-config-version.cmake
@@ -0,0 +1,12 @@
+set(PACKAGE_VERSION "2.0.0")
+
+# check whether the requested PACKAGE_FIND_VERSION is compatible
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/cmake/ecbuild-config.cmake b/cmake/ecbuild-config.cmake
new file mode 100644
index 0000000..c446743
--- /dev/null
+++ b/cmake/ecbuild-config.cmake
@@ -0,0 +1,97 @@
+# Config file for the ecbuild package
+# Defines the following variables:
+#
+# ECBUILD_INCLUDE_DIRS - include directories
+# ECBUILD_DEFINITIONS - preprocessor definitions
+# ECBUILD_LIBRARIES - libraries to link against
+# ECBUILD_FEATURES - list of enabled features
+# ECBUILD_VERSION - version of the package
+# ECBUILD_GIT_SHA1 - Git revision of the package
+# ECBUILD_GIT_SHA1_SHORT - short Git revision of the package
+#
+# Also defines ecbuild third-party library dependencies:
+# ECBUILD_TPLS - package names of third-party library dependencies
+# ECBUILD_TPL_INCLUDE_DIRS - include directories
+# ECBUILD_TPL_DEFINITIONS - preprocessor definitions
+# ECBUILD_TPL_LIBRARIES - libraries to link against
+
+### compute paths
+
+get_filename_component(ECBUILD_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+set( ECBUILD_SELF_INCLUDE_DIRS "${ECBUILD_CMAKE_DIR}/../../../include" )
+set( ECBUILD_SELF_DEFINITIONS "" )
+set( ECBUILD_SELF_LIBRARIES "" )
+
+set( ECBUILD_TPLS "" )
+set( ECBUILD_TPL_INCLUDE_DIRS "" )
+set( ECBUILD_TPL_DEFINITIONS "" )
+set( ECBUILD_TPL_LIBRARIES "" )
+
+set( ECBUILD_VERSION "2.0.0" )
+set( ECBUILD_GIT_SHA1 "0ef4781340b9bc18fb771255dad92be78e049a51" )
+set( ECBUILD_GIT_SHA1_SHORT "0ef4781" )
+
+### export include paths as absolute paths
+
+set( ECBUILD_INCLUDE_DIRS "" )
+foreach( path ${ECBUILD_SELF_INCLUDE_DIRS} )
+ get_filename_component( abspath ${path} ABSOLUTE )
+ list( APPEND ECBUILD_INCLUDE_DIRS ${abspath} )
+endforeach()
+list( APPEND ECBUILD_INCLUDE_DIRS ${ECBUILD_TPL_INCLUDE_DIRS} )
+
+### export definitions
+
+set( ECBUILD_DEFINITIONS ${ECBUILD_SELF_DEFINITIONS} ${ECBUILD_TPL_DEFINITIONS} )
+
+### export list of all libraries
+
+set( ECBUILD_LIBRARIES ${ECBUILD_SELF_LIBRARIES} ${ECBUILD_TPL_LIBRARIES} )
+
+### export the features provided by the package
+
+set( ECBUILD_FEATURES "TESTS;INSTALL" )
+foreach( _f ${ECBUILD_FEATURES} )
+ set( ECBUILD_HAVE_${_f} 1 )
+endforeach()
+
+# Has this configuration been exported from a build tree?
+set( ECBUILD_IS_BUILD_DIR_EXPORT OFF )
+
+if( EXISTS ${ECBUILD_CMAKE_DIR}/ecbuild-import.cmake )
+ set( ECBUILD_IMPORT_FILE "${ECBUILD_CMAKE_DIR}/ecbuild-import.cmake" )
+ include( ${ECBUILD_IMPORT_FILE} )
+endif()
+
+# here goes the imports of the TPL's
+
+include( ${CMAKE_CURRENT_LIST_FILE}.tpls OPTIONAL )
+
+# insert definitions for IMPORTED targets
+
+if( NOT ecbuild_BINARY_DIR )
+
+ if( ECBUILD_IS_BUILD_DIR_EXPORT )
+ include( "/tmp/metabuilds/ecflow-metab_5062/opensuse131/ecbuild/builds/ecbuild-targets.cmake" OPTIONAL )
+ else()
+ include( "${ECBUILD_CMAKE_DIR}/ecbuild-targets.cmake" )
+ endif()
+
+endif()
+
+# publish this file as imported
+
+set( ECBUILD_IMPORT_FILE ${CMAKE_CURRENT_LIST_FILE} )
+mark_as_advanced( ECBUILD_IMPORT_FILE )
+
+# set ecbuild_BASE_DIR for final installations or build directories
+
+if( NOT ecbuild )
+ if( ECBUILD_IS_BUILD_DIR_EXPORT )
+ set( ecbuild_BASE_DIR /tmp/metabuilds/ecflow-metab_5062/opensuse131/ecbuild/builds )
+ else()
+ get_filename_component( abspath ${CMAKE_CURRENT_LIST_DIR}/../../.. ABSOLUTE )
+ set( ecbuild_BASE_DIR ${abspath} )
+ endif()
+endif()
diff --git a/cmake/ecbuild_add_c_flags.cmake b/cmake/ecbuild_add_c_flags.cmake
index 012c2d6..bef45f3 100644
--- a/cmake/ecbuild_add_c_flags.cmake
+++ b/cmake/ecbuild_add_c_flags.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -40,40 +40,53 @@ macro( ecbuild_add_c_flags m_c_flags )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
- if( NOT DEFINED N_CFLAG )
- set( N_CFLAG 0 )
+ set( _try_add_flag TRUE )
+ if( _PAR_BUILD )
+ string( TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_CAPS )
+ string( TOUPPER ${_PAR_BUILD} _PAR_BUILD_CAPS )
+ if( NOT CMAKE_BUILD_TYPE_CAPS MATCHES "${_PAR_BUILD_CAPS}" )
+ set( _try_add_flag FALSE )
+ endif()
endif()
+ if( _try_add_flag )
+ if( NOT DEFINED N_CFLAG )
+ set( N_CFLAG 0 )
+ endif()
- math( EXPR N_CFLAG '${N_CFLAG}+1' )
+ math( EXPR N_CFLAG '${N_CFLAG}+1' )
- if( NOT ECBUILD_TRUST_FLAGS )
- if( DEFINED _PAR_NAME )
- check_c_compiler_flag( ${_flags} ${_PAR_NAME} )
- set( _flag_ok ${${_PAR_NAME}} )
+ if( NOT ECBUILD_TRUST_FLAGS )
+ if( DEFINED _PAR_NAME )
+ check_c_compiler_flag( ${_flags} ${_PAR_NAME} )
+ set( _flag_ok ${${_PAR_NAME}} )
+ else()
+ check_c_compiler_flag( ${_flags} C_FLAG_TEST_${N_CFLAG} )
+ set( _flag_ok ${C_FLAG_TEST_${N_CFLAG}} )
+ endif()
else()
- check_c_compiler_flag( ${_flags} C_FLAG_TEST_${N_CFLAG} )
- set( _flag_ok ${C_FLAG_TEST_${N_CFLAG}} )
+ set( _flag_ok 1 )
endif()
- else()
- set( _flag_ok 1 )
- endif()
- if( _flag_ok )
- if( _PAR_BUILD )
- set( CMAKE_C_FLAGS_${_PAR_BUILD} "${CMAKE_C_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ if( _flag_ok )
+ if( _PAR_BUILD )
+ set( CMAKE_C_FLAGS_${_PAR_BUILD} "${CMAKE_C_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ ecbuild_debug( "C FLAG [${_flags}] added for build type ${_PAR_BUILD}" )
+ else()
+ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" )
+ ecbuild_debug( "C FLAG [${_flags}] added" )
+ endif()
else()
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" )
- ecbuild_debug( "C FLAG [${_flags}] added" )
+ message( WARNING "Unrecognised C flag [${_flags}] -- skipping" )
endif()
- else()
- message( WARNING "Unrecognised C flag [${_flags}] -- skipping" )
endif()
+ unset( _flags )
+ unset( _flag_ok )
+ unset( _try_add_flag )
endif()
- unset( _flags )
- unset( _flag_ok )
+
endmacro()
macro( cmake_add_c_flags m_c_flags )
- message( DEPRECATION " cmake_add_c_flags is deprecated, use ecbuild_add_c_flags instead." )
+ ecbuild_deprecate( " cmake_add_c_flags is deprecated, use ecbuild_add_c_flags instead." )
ecbuild_add_c_flags( ${m_c_flags} )
endmacro()
diff --git a/cmake/ecbuild_add_cxx11_flags.cmake b/cmake/ecbuild_add_cxx11_flags.cmake
index 7687bd9..df8cde5 100644
--- a/cmake/ecbuild_add_cxx11_flags.cmake
+++ b/cmake/ecbuild_add_cxx11_flags.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_add_cxx_flags.cmake b/cmake/ecbuild_add_cxx_flags.cmake
index 82644a5..9e59305 100644
--- a/cmake/ecbuild_add_cxx_flags.cmake
+++ b/cmake/ecbuild_add_cxx_flags.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -39,41 +39,54 @@ macro( ecbuild_add_cxx_flags m_cxx_flags )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
- if( NOT DEFINED N_CXXFLAG )
- set( N_CXXFLAG 0 )
+ set( _try_add_flag TRUE )
+ if( _PAR_BUILD )
+ string( TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_CAPS )
+ string( TOUPPER ${_PAR_BUILD} _PAR_BUILD_CAPS )
+ if( NOT CMAKE_BUILD_TYPE_CAPS MATCHES "${_PAR_BUILD_CAPS}" )
+ set( _try_add_flag FALSE )
+ endif()
endif()
+ if( _try_add_flag )
+
+ if( NOT DEFINED N_CXXFLAG )
+ set( N_CXXFLAG 0 )
+ endif()
- math( EXPR N_CXXFLAG '${N_CXXFLAG}+1' )
+ math( EXPR N_CXXFLAG '${N_CXXFLAG}+1' )
- if( NOT ECBUILD_TRUST_FLAGS )
- if( DEFINED _PAR_NAME )
- check_cxx_compiler_flag( ${_flags} ${_PAR_NAME} )
- set( _flag_ok ${${_PAR_NAME}} )
+ if( NOT ECBUILD_TRUST_FLAGS )
+ if( DEFINED _PAR_NAME )
+ check_cxx_compiler_flag( ${_flags} ${_PAR_NAME} )
+ set( _flag_ok ${${_PAR_NAME}} )
+ else()
+ check_cxx_compiler_flag( ${_flags} CXX_FLAG_TEST_${N_CXXFLAG} )
+ set( _flag_ok CXX_FLAG_TEST_${N_CXXFLAG} )
+ endif()
else()
- check_cxx_compiler_flag( ${_flags} CXX_FLAG_TEST_${N_CXXFLAG} )
- set( _flag_ok CXX_FLAG_TEST_${N_CXXFLAG} )
+ set( _flag_ok 1 )
endif()
- else()
- set( _flag_ok 1 )
- endif()
- if( _flag_ok )
- if( _PAR_BUILD )
- set( CMAKE_CXX_FLAGS_${_PAR_BUILD} "${CMAKE_CXX_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ if( _flag_ok )
+ if( _PAR_BUILD )
+ set( CMAKE_CXX_FLAGS_${_PAR_BUILD} "${CMAKE_CXX_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ ecbuild_debug( "C++ FLAG [${_flags}] added for build type ${_PAR_BUILD}" )
+ else()
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" )
+ ecbuild_debug( "C++ FLAG [${_flags}] added" )
+ endif()
else()
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" )
- ecbuild_debug( "C++ FLAG [${_flags}] added" )
+ message( STATUS "Unrecognised CXX flag [${_flags}] -- skipping" )
endif()
- else()
- message( STATUS "Unrecognised CXX flag [${_flags}] -- skipping" )
endif()
+ unset( _flags )
+ unset( _flag_ok )
+ unset( _try_add_flag )
endif()
- unset( _flags )
- unset( _flag_ok )
endmacro()
macro( cmake_add_cxx_flags m_cxx_flags )
- message( DEPRECATION " cmake_add_cxx_flags is deprecated, use ecbuild_add_cxx_flags instead." )
+ ecbuild_deprecate( " cmake_add_cxx_flags is deprecated, use ecbuild_add_cxx_flags instead." )
ecbuild_add_cxx_flags( ${m_cxx_flags} )
endmacro()
diff --git a/cmake/ecbuild_add_executable.cmake b/cmake/ecbuild_add_executable.cmake
index d1355c3..d2e3f4c 100644
--- a/cmake/ecbuild_add_executable.cmake
+++ b/cmake/ecbuild_add_executable.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -16,6 +16,9 @@
#
# ecbuild_add_executable( TARGET <name>
# SOURCES <source1> [<source2> ...]
+# [ SOURCES_GLOB <glob1> [<glob2> ...] ]
+# [ SOURCES_EXCLUDE_REGEX <regex1> [<regex2> ...] ]
+# [ OBJECTS <obj1> [<obj2> ...] ]
# [ TEMPLATES <template1> [<template2> ...] ]
# [ LIBS <library1> [<library2> ...] ]
# [ INCLUDES <path1> [<path2> ...] ]
@@ -41,6 +44,16 @@
# SOURCES : required
# list of source files
#
+# SOURCES_GLOB : optional
+# search pattern to find source files to compile (note: not recommend according to CMake guidelines)
+# it is usually better to explicitly list the source files in the CMakeList.txt
+#
+# SOURCES_EXCLUDE_REGEX : optional
+# search pattern to exclude source files from compilation, applies o the results of SOURCES_GLOB
+#
+# OBJECTS : optional
+# list of object libraries to add to this target
+#
# TEMPLATES : optional
# list of files specified as SOURCES which are not to be compiled separately
# (these are commonly template implementation files included in a header)
@@ -64,11 +77,12 @@
# list of targets to be built before this target
#
# CONDITION : optional
-# list of conditions, all of which must evaluate to true for this target to be built
+# conditional expression which must evaluate to true for this target to be
+# built (must be valid in a CMake ``if`` statement)
#
# NOINSTALL : optional
# do not install the executable
-#
+#
# VERSION : optional, AUTO_VERSION or LIBS_VERSION is used if not specified
# version to use as executable version
#
@@ -84,7 +98,6 @@
# FFLAGS : optional
# list of Fortran compiler flags to use for all Fortran source files
#
-#
# LINKER_LANGUAGE : optional
# sets the LINKER_LANGUAGE property on the target
#
@@ -97,7 +110,7 @@ macro( ecbuild_add_executable )
set( options NOINSTALL AUTO_VERSION )
set( single_value_args TARGET COMPONENT LINKER_LANGUAGE VERSION OUTPUT_NAME )
- set( multi_value_args SOURCES TEMPLATES LIBS INCLUDES DEPENDS PERSISTENT DEFINITIONS CFLAGS CXXFLAGS FFLAGS GENERATED CONDITION )
+ set( multi_value_args SOURCES SOURCES_GLOB SOURCES_EXCLUDE_REGEX OBJECTS TEMPLATES LIBS INCLUDES DEPENDS PERSISTENT DEFINITIONS CFLAGS CXXFLAGS FFLAGS GENERATED CONDITION )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
@@ -109,8 +122,8 @@ macro( ecbuild_add_executable )
message(FATAL_ERROR "The call to ecbuild_add_executable() doesn't specify the TARGET.")
endif()
- if( NOT _PAR_SOURCES )
- message(FATAL_ERROR "The call to ecbuild_add_executable() doesn't specify the SOURCES.")
+ if( NOT _PAR_SOURCES AND NOT _PAR_OBJECTS AND NOT _PAR_SOURCES_GLOB )
+ message(FATAL_ERROR "The call to ecbuild_add_executable() specifies neither SOURCES nor OBJECTS nor SOURCES_GLOB.")
endif()
### conditional build
@@ -129,19 +142,6 @@ macro( ecbuild_add_executable )
if( _${_PAR_TARGET}_condition )
- # add include dirs if defined
- if( DEFINED _PAR_INCLUDES )
- list(REMOVE_DUPLICATES _PAR_INCLUDES )
- foreach( path ${_PAR_INCLUDES} ) # skip NOTFOUND
- if( path )
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): add ${path} to include_directories")
- include_directories( ${path} )
- else()
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): ${path} not found - not adding to include_directories")
- endif()
- endforeach()
- endif()
-
# add persistent layer files
if( DEFINED _PAR_PERSISTENT )
if( DEFINED PERSISTENT_NAMESPACE )
@@ -158,8 +158,44 @@ macro( ecbuild_add_executable )
add_custom_target( ${_PAR_TARGET}_templates SOURCES ${_PAR_TEMPLATES} )
endif()
- # add the executable target
- add_executable( ${_PAR_TARGET} ${_PAR_SOURCES} )
+ # glob sources
+ unset( _glob_srcs )
+ foreach( pattern ${_PAR_SOURCES_GLOB} )
+ ecbuild_list_add_pattern( LIST _glob_srcs GLOB "${pattern}" )
+ endforeach()
+
+ foreach( pattern ${_PAR_SOURCES_EXCLUDE_REGEX} )
+ ecbuild_list_exclude_pattern( LIST _glob_srcs REGEX "${pattern}" )
+ endforeach()
+
+ # insert already compiled objects (from OBJECT libraries)
+ unset( _all_objects )
+ foreach( _obj ${_PAR_OBJECTS} )
+ list( APPEND _all_objects $<TARGET_OBJECTS:${_obj}> )
+ endforeach()
+
+ list( APPEND _PAR_SOURCES ${_glob_srcs} )
+
+ if( ECBUILD_LIST_SOURCES )
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): sources ${_PAR_SOURCES}")
+ endif()
+
+ add_executable( ${_PAR_TARGET} ${_PAR_SOURCES} ${_all_objects} )
+
+ # ecbuild_echo_target( ${_PAR_TARGET} )
+
+ # add include dirs if defined
+ if( DEFINED _PAR_INCLUDES )
+ list(REMOVE_DUPLICATES _PAR_INCLUDES )
+ foreach( path ${_PAR_INCLUDES} ) # skip NOTFOUND
+ if( path )
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): add ${path} to include_directories")
+ target_include_directories( ${_PAR_TARGET} PRIVATE ${path} )
+ else()
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): ${path} not found - not adding to include_directories")
+ endif()
+ endforeach()
+ endif()
# set OUTPUT_NAME
@@ -190,24 +226,71 @@ macro( ecbuild_add_executable )
endif()
# filter sources
+
ecbuild_separate_sources( TARGET ${_PAR_TARGET} SOURCES ${_PAR_SOURCES} )
+ # ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
+
# add local flags
- if( DEFINED _PAR_CFLAGS )
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_c_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
- endif()
- if( DEFINED _PAR_CXXFLAGS )
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
+
+ if( ${_PAR_TARGET}_c_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_C_SOURCE_FLAGS
+ ${_PAR_TARGET}_c
+ "${_PAR_CFLAGS}"
+ "${${_PAR_TARGET}_c_srcs}" )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file C flags from ${${_PAR_TARGET}_C_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_C_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_CFLAGS )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_c_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
+
+ endif()
endif()
- if( DEFINED _PAR_FFLAGS )
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_f_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
+
+ if( ${_PAR_TARGET}_cxx_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_CXX_SOURCE_FLAGS
+ ${_PAR_TARGET}_cxx
+ "${_PAR_CXXFLAGS}"
+ "${${_PAR_TARGET}_cxx_srcs}" )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file CXX flags from ${${_PAR_TARGET}_CXX_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_CXX_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_CXXFLAGS )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
+
+ endif()
endif()
- if( DEFINED _PAR_GENERATED )
- ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): mark as generated ${_PAR_GENERATED}")
- set_source_files_properties( ${_PAR_GENERATED} PROPERTIES GENERATED 1 )
+
+ if( ${_PAR_TARGET}_f_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_Fortran_SOURCE_FLAGS
+ ${_PAR_TARGET}_f
+ "${_PAR_FFLAGS}"
+ "${${_PAR_TARGET}_f_srcs}" )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): setting source file Fortran flags from ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_FFLAGS )
+
+ ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_f_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
+
+ endif()
endif()
# define VERSION if requested
@@ -221,11 +304,6 @@ macro( ecbuild_add_executable )
endif()
endif()
- # debug_var( ${_PAR_TARGET}_h_srcs )
- # debug_var( ${_PAR_TARGET}_c_srcs )
- # debug_var( ${_PAR_TARGET}_cxx_srcs )
- # debug_var( ${_PAR_TARGET}_f_srcs )
-
# installation
if( NOT _PAR_NOINSTALL )
@@ -239,7 +317,7 @@ macro( ecbuild_add_executable )
# endif()
install( TARGETS ${_PAR_TARGET}
- EXPORT ${CMAKE_PROJECT_NAME}-targets
+ EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${INSTALL_BIN_DIR}
LIBRARY DESTINATION ${INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${INSTALL_LIB_DIR} )
@@ -272,6 +350,13 @@ macro( ecbuild_add_executable )
if( DEFINED _PAR_LINKER_LANGUAGE )
ecbuild_debug("ecbuild_add_executable(${_PAR_TARGET}): using linker language ${_PAR_LINKER_LANGUAGE}")
set_property( TARGET ${_PAR_TARGET} PROPERTY LINKER_LANGUAGE ${_PAR_LINKER_LANGUAGE} )
+ if( ECBUILD_${_PAR_LINKER_LANGUAGE}_IMPLICIT_LINK_LIBRARIES )
+ target_link_libraries( ${_PAR_TARGET} ${ECBUILD_${_PAR_LINKER_LANGUAGE}_IMPLICIT_LINK_LIBRARIES} )
+ endif()
+ endif()
+
+ if( ECBUILD_IMPLICIT_LINK_LIBRARIES )
+ target_link_libraries( ${_PAR_TARGET} ${ECBUILD_IMPLICIT_LINK_LIBRARIES} )
endif()
# make sure target is removed before - some problems with AIX
diff --git a/cmake/ecbuild_add_extra_search_paths.cmake b/cmake/ecbuild_add_extra_search_paths.cmake
index c8a7a77..94ac85b 100644
--- a/cmake/ecbuild_add_extra_search_paths.cmake
+++ b/cmake/ecbuild_add_extra_search_paths.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -15,10 +15,10 @@
function( ecbuild_add_extra_search_paths pkg )
- message( DEPRECATION " ecbuild_add_extra_search_paths modifies CMAKE_PREFIX_PATH,"
- " which can affect future package discovery if not undone by the caller."
- " The current CMAKE_PREFIX_PATH is being backed up as _CMAKE_PREFIX_PATH"
- " so it can later be restored." )
+ ecbuild_deprecate( " ecbuild_add_extra_search_paths modifies CMAKE_PREFIX_PATH,"
+ " which can affect future package discovery if not undone by the caller."
+ " The current CMAKE_PREFIX_PATH is being backed up as _CMAKE_PREFIX_PATH"
+ " so it can later be restored." )
# Back up current CMAKE_PREFIX_PATH so the caller can reset it
set( _CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE )
@@ -28,6 +28,6 @@ function( ecbuild_add_extra_search_paths pkg )
ecbuild_list_extra_search_paths( ${pkg} CMAKE_PREFIX_PATH )
set( CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE )
- # debug_var( CMAKE_PREFIX_PATH )
+ # ecbuild_debug_var( CMAKE_PREFIX_PATH )
endfunction()
diff --git a/cmake/ecbuild_add_fortran_flags.cmake b/cmake/ecbuild_add_fortran_flags.cmake
index 827c39e..cf61a0a 100644
--- a/cmake/ecbuild_add_fortran_flags.cmake
+++ b/cmake/ecbuild_add_fortran_flags.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -44,42 +44,55 @@ macro( ecbuild_add_fortran_flags m_fortran_flags )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
- if( NOT DEFINED N_FortranFLAG )
- set( N_FortranFLAG 0 )
+ set( _try_add_flag TRUE )
+ if( _PAR_BUILD )
+ string( TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_CAPS )
+ string( TOUPPER ${_PAR_BUILD} _PAR_BUILD_CAPS )
+ if( NOT CMAKE_BUILD_TYPE_CAPS MATCHES "${_PAR_BUILD_CAPS}" )
+ set( _try_add_flag FALSE )
+ endif()
endif()
- math( EXPR N_FortranFLAG '${N_FortranFLAG}+1' )
+ if( _try_add_flag )
+ if( NOT DEFINED N_FortranFLAG )
+ set( N_FortranFLAG 0 )
+ endif()
+
+ math( EXPR N_FortranFLAG '${N_FortranFLAG}+1' )
- if( NOT ECBUILD_TRUST_FLAGS )
- if( DEFINED _PAR_NAME )
- check_fortran_compiler_flag( ${_flags} ${_PAR_NAME} )
- set( _flag_ok ${${_PAR_NAME}} )
+ if( NOT ECBUILD_TRUST_FLAGS )
+ if( DEFINED _PAR_NAME )
+ check_fortran_compiler_flag( ${_flags} ${_PAR_NAME} )
+ set( _flag_ok ${${_PAR_NAME}} )
+ else()
+ check_fortran_compiler_flag( ${_flags} Fortran_FLAG_TEST_${N_FortranFLAG} )
+ set( _flag_ok ${Fortran_FLAG_TEST_${N_FortranFLAG}} )
+ endif()
else()
- check_fortran_compiler_flag( ${_flags} Fortran_FLAG_TEST_${N_FortranFLAG} )
- set( _flag_ok ${Fortran_FLAG_TEST_${N_FortranFLAG}} )
+ set( _flag_ok 1 )
endif()
- else()
- set( _flag_ok 1 )
- endif()
- if( _flag_ok )
- if( _PAR_BUILD )
- set( CMAKE_Fortran_FLAGS_${_PAR_BUILD} "${CMAKE_Fortran_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ if( _flag_ok )
+ if( _PAR_BUILD )
+ set( CMAKE_Fortran_FLAGS_${_PAR_BUILD} "${CMAKE_Fortran_FLAGS_${_PAR_BUILD}} ${_flags}" )
+ ecbuild_debug( "Fortran FLAG [${_flags}] added for build type ${_PAR_BUILD}" )
+ else()
+ set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${_flags}" )
+ ecbuild_debug( "Fortran FLAG [${_flags}] added" )
+ endif()
else()
- set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${_flags}" )
- ecbuild_debug( "Fortran FLAG [${_flags}] added" )
+ message( STATUS "Unrecognised Fortran flag [${_flags}] -- skipping" )
endif()
- else()
- message( STATUS "Unrecognised Fortran flag [${_flags}] -- skipping" )
endif()
- endif()
- unset( _flags )
- unset( _flag_ok )
+ unset( _flags )
+ unset( _flag_ok )
+ unset( _try_add_flag )
+ endif()
endmacro()
macro( cmake_add_fortran_flags m_fortran_flags )
- message( DEPRECATION " cmake_add_fortran_flags is deprecated, use ecbuild_add_fortran_flags instead." )
+ ecbuild_deprecate( " cmake_add_fortran_flags is deprecated, use ecbuild_add_fortran_flags instead." )
ecbuild_add_fortran_flags( ${m_fortran_flags} )
endmacro()
diff --git a/cmake/ecbuild_add_library.cmake b/cmake/ecbuild_add_library.cmake
index 49f9425..bcd9a98 100644
--- a/cmake/ecbuild_add_library.cmake
+++ b/cmake/ecbuild_add_library.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -16,7 +16,10 @@
#
# ecbuild_add_library( TARGET <name>
# SOURCES <source1> [<source2> ...]
-# [ TYPE SHARED|STATIC|MODULE ]
+# [ SOURCES_GLOB <glob1> [<glob2> ...] ]
+# [ SOURCES_EXCLUDE_REGEX <regex1> [<regex2> ...] ]
+# [ TYPE SHARED|STATIC|MODULE|OBJECT ]
+# [ OBJECTS <obj1> [<obj2> ...] ]
# [ TEMPLATES <template1> [<template2> ...] ]
# [ LIBS <library1> [<library2> ...] ]
# [ INCLUDES <path1> [<path2> ...] ]
@@ -55,6 +58,17 @@
# :STATIC: archives of object files for use when linking other targets.
# :MODULE: plugins that are not linked into other targets but may be loaded
# dynamically at runtime using dlopen-like functionality
+# :OBJECT: files are just compiled into objects
+#
+# SOURCES_GLOB : optional
+# search pattern to find source files to compile (note: not recommend according to CMake guidelines)
+# it is usually better to explicitly list the source files in the CMakeList.txt
+#
+# SOURCES_EXCLUDE_REGEX : optional
+# search pattern to exclude source files from compilation, applies o the results of SOURCES_GLOB
+#
+# OBJECTS : optional
+# list of object libraries to add to this target
#
# TEMPLATES : optional
# list of files specified as SOURCES which are not to be compiled separately
@@ -87,7 +101,8 @@
# list of targets to be built before this target
#
# CONDITION : optional
-# list of conditions, all of which must evaluate to true for this target to be built
+# conditional expression which must evaluate to true for this target to be
+# built (must be valid in a CMake ``if`` statement)
#
# NOINSTALL : optional
# do not install the library
@@ -134,7 +149,7 @@ function( ecbuild_add_library_impl )
set( options NOINSTALL AUTO_VERSION )
set( single_value_args TARGET TYPE COMPONENT INSTALL_HEADERS INSTALL_HEADERS_REGEX LINKER_LANGUAGE HEADER_DESTINATION VERSION OUTPUT_NAME )
- set( multi_value_args SOURCES TEMPLATES LIBS INCLUDES PRIVATE_INCLUDES PUBLIC_INCLUDES DEPENDS PERSISTENT DEFINITIONS INSTALL_HEADERS_LIST CFLAGS CXXFLAGS FFLAGS GENERATED CONDITION )
+ set( multi_value_args SOURCES SOURCES_GLOB SOURCES_EXCLUDE_REGEX OBJECTS TEMPLATES LIBS INCLUDES PRIVATE_INCLUDES PUBLIC_INCLUDES DEPENDS PERSISTENT DEFINITIONS INSTALL_HEADERS_LIST CFLAGS CXXFLAGS FFLAGS GENERATED CONDITION )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
@@ -146,8 +161,8 @@ function( ecbuild_add_library_impl )
message(FATAL_ERROR "The call to ecbuild_add_library() doesn't specify the TARGET.")
endif()
- if( NOT _PAR_SOURCES )
- message(FATAL_ERROR "The call to ecbuild_add_library() doesn't specify the SOURCES.")
+ if( NOT _PAR_SOURCES AND NOT _PAR_OBJECTS AND NOT _PAR_SOURCES_GLOB )
+ message(FATAL_ERROR "The call to ecbuild_add_library() specifies neither SOURCES nor OBJECTS nor SOURCES_GLOB")
endif()
### conditional build
@@ -171,8 +186,9 @@ function( ecbuild_add_library_impl )
# checks that is either SHARED or STATIC or MODULE
if( NOT _PAR_TYPE MATCHES "STATIC" AND
NOT _PAR_TYPE MATCHES "SHARED" AND
+ NOT _PAR_TYPE MATCHES "OBJECT" AND
NOT _PAR_TYPE MATCHES "MODULE" )
- message( FATAL_ERROR "library type must be one of [ STATIC | SHARED | MODULE ]" )
+ message( FATAL_ERROR "library type must be one of [ STATIC | SHARED | MODULE | OBJECT ]" )
endif()
ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): library type is ${_PAR_TYPE}")
endif()
@@ -194,7 +210,31 @@ function( ecbuild_add_library_impl )
add_custom_target( ${_PAR_TARGET}_templates SOURCES ${_PAR_TEMPLATES} )
endif()
- add_library( ${_PAR_TARGET} ${_PAR_TYPE} ${_PAR_SOURCES} )
+ # glob sources
+ unset( _glob_srcs )
+ foreach( pattern ${_PAR_SOURCES_GLOB} )
+ ecbuild_list_add_pattern( LIST _glob_srcs GLOB "${pattern}" )
+ endforeach()
+
+ foreach( pattern ${_PAR_SOURCES_EXCLUDE_REGEX} )
+ ecbuild_list_exclude_pattern( LIST _glob_srcs REGEX "${pattern}" )
+ endforeach()
+
+ # insert already compiled objects (from OBJECT libraries)
+ unset( _all_objects )
+ foreach( _obj ${_PAR_OBJECTS} )
+ list( APPEND _all_objects $<TARGET_OBJECTS:${_obj}> )
+ endforeach()
+
+ list( APPEND _PAR_SOURCES ${_glob_srcs} )
+
+ if( ECBUILD_LIST_SOURCES )
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): sources ${_PAR_SOURCES}")
+ endif()
+
+ add_library( ${_PAR_TARGET} ${_PAR_TYPE} ${_PAR_SOURCES} ${_all_objects} )
+
+ # ecbuild_echo_target( ${_PAR_TARGET} )
# set OUTPUT_NAME
@@ -305,27 +345,74 @@ function( ecbuild_add_library_impl )
# filter sources
- ecbuild_separate_sources( TARGET ${_PAR_TARGET} SOURCES ${_PAR_SOURCES} )
+ if( _PAR_SOURCES )
+ ecbuild_separate_sources( TARGET ${_PAR_TARGET} SOURCES ${_PAR_SOURCES} )
+ endif()
- # debug_var( ${_PAR_TARGET}_h_srcs )
- # debug_var( ${_PAR_TARGET}_c_srcs )
- # debug_var( ${_PAR_TARGET}_cxx_srcs )
- # debug_var( ${_PAR_TARGET}_f_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
+ # ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
# add local flags
- if( DEFINED _PAR_CFLAGS )
- ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_c_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
+ if( ${_PAR_TARGET}_c_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_C_SOURCE_FLAGS
+ ${_PAR_TARGET}_c
+ "${_PAR_CFLAGS}"
+ "${${_PAR_TARGET}_c_srcs}" )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file C flags from ${${_PAR_TARGET}_C_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_C_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_CFLAGS )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_c_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CFLAGS}" )
+
+ endif()
endif()
- if( DEFINED _PAR_CXXFLAGS )
- ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
+
+ if( ${_PAR_TARGET}_cxx_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_CXX_SOURCE_FLAGS
+ ${_PAR_TARGET}_cxx
+ "${_PAR_CXXFLAGS}"
+ "${${_PAR_TARGET}_cxx_srcs}" )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file CXX flags from ${${_PAR_TARGET}_CXX_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_CXX_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_CXXFLAGS )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use C++ flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_cxx_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_CXXFLAGS}" )
+
+ endif()
endif()
- if( DEFINED _PAR_FFLAGS )
- ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
- set_source_files_properties( ${${_PAR_TARGET}_f_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
+
+ if( ${_PAR_TARGET}_f_srcs )
+
+ if( ECBUILD_SOURCE_FLAGS )
+ ecbuild_source_flags( ${_PAR_TARGET}_Fortran_SOURCE_FLAGS
+ ${_PAR_TARGET}_f
+ "${_PAR_FFLAGS}"
+ "${${_PAR_TARGET}_f_srcs}" )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): setting source file Fortran flags from ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS}")
+ include( ${${_PAR_TARGET}_Fortran_SOURCE_FLAGS} )
+
+ elseif( DEFINED _PAR_FFLAGS )
+
+ ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): use Fortran flags ${_PAR_CFLAGS}")
+ set_source_files_properties( ${${_PAR_TARGET}_f_srcs} PROPERTIES COMPILE_FLAGS "${_PAR_FFLAGS}" )
+
+ endif()
endif()
+
if( DEFINED _PAR_GENERATED )
ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): mark as generated ${_PAR_GENERATED}")
set_source_files_properties( ${_PAR_GENERATED} PROPERTIES GENERATED 1 )
@@ -335,11 +422,18 @@ function( ecbuild_add_library_impl )
if( DEFINED _PAR_LINKER_LANGUAGE )
ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): using linker language ${_PAR_LINKER_LANGUAGE}")
set_property( TARGET ${_PAR_TARGET} PROPERTY LINKER_LANGUAGE ${_PAR_LINKER_LANGUAGE} )
+ if( ECBUILD_${_PAR_LINKER_LANGUAGE}_IMPLICIT_LINK_LIBRARIES )
+ target_link_libraries( ${_PAR_TARGET} ${ECBUILD_${_PAR_LINKER_LANGUAGE}_IMPLICIT_LINK_LIBRARIES} )
+ endif()
endif()
- # installation
+ if( ECBUILD_IMPLICIT_LINK_LIBRARIES )
+ target_link_libraries( ${_PAR_TARGET} ${ECBUILD_IMPLICIT_LINK_LIBRARIES} )
+ endif()
- if( NOT _PAR_NOINSTALL )
+ # installation (except for OBJECT libraries)
+
+ if( NOT _PAR_NOINSTALL AND NOT _PAR_TYPE MATCHES "OBJECT" )
ecbuild_debug("ecbuild_add_library(${_PAR_TARGET}): installing to ${INSTALL_LIB_DIR}")
# and associate with defined component
@@ -350,7 +444,7 @@ function( ecbuild_add_library_impl )
# endif()
install( TARGETS ${_PAR_TARGET}
- EXPORT ${CMAKE_PROJECT_NAME}-targets
+ EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${INSTALL_BIN_DIR}
LIBRARY DESTINATION ${INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${INSTALL_LIB_DIR} )
@@ -420,7 +514,9 @@ function( ecbuild_add_library_impl )
endif()
# make sure target is removed before - some problems with AIX
- add_custom_command( TARGET ${_PAR_TARGET} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E remove $<TARGET_FILE:${_PAR_TARGET}> )
+ if( NOT _PAR_TYPE MATCHES "OBJECT" )
+ add_custom_command( TARGET ${_PAR_TARGET} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E remove $<TARGET_FILE:${_PAR_TARGET}> )
+ endif()
# for the links target
if( NOT _PAR_NOINSTALL )
diff --git a/cmake/ecbuild_add_option.cmake b/cmake/ecbuild_add_option.cmake
index ce8c541..e0e6040 100644
--- a/cmake/ecbuild_add_option.cmake
+++ b/cmake/ecbuild_add_option.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -17,6 +17,7 @@
# ecbuild_add_option( FEATURE <name>
# [ DEFAULT ON|OFF ]
# [ DESCRIPTION <description> ]
+# [ PURPOSE <purpose> ]
# [ REQUIRED_PACKAGES <package1> [<package2> ...] ]
# [ CONDITION <condition1> [<condition2> ...] ]
# [ ADVANCED ] )
@@ -33,22 +34,34 @@
# DESCRIPTION : optional
# string describing the feature (shown in summary and stored in the cache)
#
+# TYPE : optional, one of RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED
+# type of dependency of the project on this package (defaults to OPTIONAL)
+#
+# PURPOSE : optional
+# string describing which functionality this package enables in the project
+#
# REQUIRED_PACKAGES : optional
# list of packages required to be found for this feature to be enabled
#
-# The package specification can be either ::
+# The package specification can have one of two forms. Either ::
#
-# <package> [ <version> ... ]
+# "<package> [ <version> ... ]"
#
-# to search for a given package with option minimum required version or ::
+# to search for a given package using the CMake ``find_package`` mechanism.
+# The entire specification must be enclosed in quotes and is passed on
+# verbatim. Any options of ``find_package`` are supported.
#
-# PROJECT <name> [ VERSION <version> ... ]
+# The other specification must start with ``PROJECT`` like this ::
#
-# to search for an ecBuild project with optional minimum required version.
+# "PROJECT <name> [ VERSION <version> ... ]"
+#
+# and is used to search for an ecBuild project via ``ecbuild_use_package``.
+# The entire specification must be enclosed in quotes and is passed on
+# verbatim. Any options of ``ecbuild_use_package`` are supported.
#
# CONDITION : optional
-# list of conditions, all of which must evaluate to true for this option to
-# be enabled
+# conditional expression which must evaluate to true for this option to be
+# enabled (must be valid in a CMake ``if`` statement)
#
# ADVANCED : optional
# mark the feature as advanced
@@ -58,7 +71,7 @@
#
# Features with ``DEFAULT OFF`` need to be explcitly enabled by the user with
# ``-DENABLE_<FEATURE>=ON``. If a feature is enabled, all ``REQUIRED_PACKAGES``
-# are found and every ``CONDITION`` is met, ecBuild sets the variable
+# are found and ``CONDITION`` is met, ecBuild sets the variable
# ``HAVE_<FEATURE>`` to ``ON``. This is the variable to use to check for the
# availability of the feature.
#
@@ -72,7 +85,7 @@
macro( ecbuild_add_option )
set( options ADVANCED )
- set( single_value_args FEATURE DEFAULT DESCRIPTION )
+ set( single_value_args FEATURE DEFAULT DESCRIPTION TYPE PURPOSE )
set( multi_value_args REQUIRED_PACKAGES CONDITION )
cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
@@ -98,6 +111,10 @@ macro( ecbuild_add_option )
endif()
ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): defaults to ${_p_DEFAULT}")
+ if( NOT _p_TYPE )
+ set( _p_TYPE OPTIONAL )
+ endif()
+
# check CONDITION parameter
if( DEFINED _p_CONDITION )
set(_feature_condition_file "${CMAKE_CURRENT_BINARY_DIR}/set_${_p_FEATURE}_condition.cmake")
@@ -135,7 +152,12 @@ macro( ecbuild_add_option )
# define the option -- for cmake GUI
option( ENABLE_${_p_FEATURE} "${_p_DESCRIPTION}" ${_p_DEFAULT} )
- ecbuild_set_feature( ${_p_FEATURE} ENABLED ${_p_DEFAULT} PURPOSE "${_p_DESCRIPTION}" )
+ ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): defining option ENABLE_${_p_FEATURE} '${_p_DESCRIPTION}' ${_p_DEFAULT}")
+ ecbuild_set_feature( ${_p_FEATURE} ENABLED ${_p_DEFAULT} )
+ set_package_properties( ${_p_FEATURE} PROPERTIES
+ DESCRIPTION "${_p_DESCRIPTION}"
+ TYPE ${_p_TYPE}
+ PURPOSE "${_p_PURPOSE}" )
ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): ENABLE_${_p_FEATURE} = ${ENABLE_${_p_FEATURE}}")
set( _do_search ${ENABLE_${_p_FEATURE}} )
@@ -167,9 +189,9 @@ macro( ecbuild_add_option )
set( pkgproject 0 )
endif()
- # debug_var( pkg )
- # debug_var( pkglist )
- # debug_var( pkgname )
+ # ecbuild_debug_var( pkg )
+ # ecbuild_debug_var( pkglist )
+ # ecbuild_debug_var( pkgname )
string( TOUPPER ${pkgname} pkgUPPER )
string( TOLOWER ${pkgname} pkgLOWER )
@@ -206,6 +228,11 @@ macro( ecbuild_add_option )
list( REMOVE_ITEM _find_args ${pkgname} )
ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for Python")
ecbuild_find_python( ${_find_args} )
+ elseif( pkgname STREQUAL "LEXYACC" )
+ set( _find_args ${pkglist} )
+ list( REMOVE_ITEM _find_args ${pkgname} )
+ ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for lex-yacc")
+ ecbuild_find_lexyacc( ${_find_args} )
else()
ecbuild_debug("ecbuild_add_option(${_p_FEATURE}): searching for package ${pkgname}")
find_package( ${pkglist} )
@@ -223,9 +250,9 @@ macro( ecbuild_add_option )
endif()
- # debug_var( ${pkgname}_FOUND )
- # debug_var( ${pkgLOWER}_FOUND )
- # debug_var( ${pkgUPPER}_FOUND )
+ # ecbuild_debug_var( ${pkgname}_FOUND )
+ # ecbuild_debug_var( ${pkgLOWER}_FOUND )
+ # ecbuild_debug_var( ${pkgUPPER}_FOUND )
# we have feature if all required packages were FOUND
diff --git a/cmake/ecbuild_add_persistent.cmake b/cmake/ecbuild_add_persistent.cmake
index 42788c7..e27eb89 100644
--- a/cmake/ecbuild_add_persistent.cmake
+++ b/cmake/ecbuild_add_persistent.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -34,7 +34,7 @@
# C++ namespace to place the persistent class information in
#
##############################################################################
-
+
# define the script to build the persistent class information
set( sg_perl "${CMAKE_CURRENT_LIST_DIR}/sg.pl" CACHE INTERNAL "perl script to generate persistent objects" )
@@ -44,7 +44,7 @@ macro( ecbuild_add_persistent )
set( options )
set( single_value_args SRC_LIST NAMESPACE )
- set( multi_value_args FILES )
+ set( multi_value_args FILES )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
@@ -71,7 +71,7 @@ macro( ecbuild_add_persistent )
set( file ${_file_dir}/${_file_we} )
endif()
- # debug_var(file)
+ # ecbuild_debug_var(file)
add_custom_command( OUTPUT ${file}.b
COMMAND ${PERL_EXECUTABLE} ${sg_perl} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.h
diff --git a/cmake/ecbuild_add_resources.cmake b/cmake/ecbuild_add_resources.cmake
index 83f3c7e..d09581c 100644
--- a/cmake/ecbuild_add_resources.cmake
+++ b/cmake/ecbuild_add_resources.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_add_test.cmake b/cmake/ecbuild_add_test.cmake
index f651de9..6d208b0 100644
--- a/cmake/ecbuild_add_test.cmake
+++ b/cmake/ecbuild_add_test.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -16,6 +16,7 @@
#
# ecbuild_add_test( [ TARGET <name> ]
# [ SOURCES <source1> [<source2> ...] ]
+# [ OBJECTS <obj1> [<obj2> ...] ]
# [ COMMAND <executable> ]
# [ TYPE EXE|SCRIPT|PYTHON ]
# [ ARGS <argument1> [<argument2> ...] ]
@@ -48,6 +49,9 @@
# SOURCES : required if TARGET is provided
# list of source files to be compiled
#
+# OBJECTS : optional
+# list of object libraries to add to this target
+#
# COMMAND : either TARGET or COMMAND must be provided, unless TYPE is PYTHON
# command or script to execute (no executable is built)
#
@@ -100,7 +104,8 @@
# list of tests to be run before this one
#
# CONDITION : optional
-# list of conditions, all of which must evaluate to true for this target to be built
+# conditional expression which must evaluate to true for this target to be
+# built (must be valid in a CMake ``if`` statement)
#
# ENVIRONMENT : optional
# list of environment variables to set in the test environment
@@ -126,7 +131,7 @@ macro( ecbuild_add_test )
set( options BOOST )
set( single_value_args TARGET ENABLED COMMAND TYPE LINKER_LANGUAGE MPI WORKING_DIRECTORY )
- set( multi_value_args SOURCES LIBS INCLUDES TEST_DEPENDS DEPENDS ARGS
+ set( multi_value_args SOURCES OBJECTS LIBS INCLUDES TEST_DEPENDS DEPENDS ARGS
PERSISTENT DEFINITIONS RESOURCES TEST_DATA CFLAGS
CXXFLAGS FFLAGS GENERATED CONDITION ENVIRONMENT )
@@ -140,13 +145,14 @@ macro( ecbuild_add_test )
# Check for MPI
if(_PAR_MPI)
- if( (_PAR_MPI GREATER 1) AND ( (NOT HAVE_MPI) OR (NOT MPIEXEC) ) )
+ if( (_PAR_MPI GREATER 1) AND ( (NOT MPI_FOUND) OR (NOT MPIEXEC) ) )
ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): ${_PAR_MPI} MPI ranks requested but MPI not available - disabling test")
set( _PAR_ENABLED 0 )
- endif()
- if( (_PAR_MPI EQUAL 1) AND (NOT HAVE_MPI) )
+ elseif( (_PAR_MPI EQUAL 1) AND (NOT MPI_FOUND) )
ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): 1 MPI rank requested but MPI not available - disabling MPI")
set( _PAR_MPI 0 )
+ else()
+ ecbuild_debug("ecbuild_add_test(${_PAR_TARGET}): Running using ${_PAR_MPI} MPI rank(s)")
endif()
endif()
@@ -265,9 +271,13 @@ macro( ecbuild_add_test )
endif()
endif()
- # add the test target
+ # insert already compiled objects (from OBJECT libraries)
+ unset( _all_objects )
+ foreach( _obj ${_PAR_OBJECTS} )
+ list( APPEND _all_objects $<TARGET_OBJECTS:${_obj}> )
+ endforeach()
- add_executable( ${_PAR_TARGET} ${_PAR_SOURCES} )
+ add_executable( ${_PAR_TARGET} ${_PAR_SOURCES} ${_all_objects} )
# add extra dependencies
if( DEFINED _PAR_DEPENDS)
@@ -353,9 +363,6 @@ macro( ecbuild_add_test )
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E remove ${EXE_FILENAME} )
- set_property( TARGET ${_PAR_TARGET} PROPERTY SKIP_BUILD_RPATH FALSE )
- set_property( TARGET ${_PAR_TARGET} PROPERTY BUILD_WITH_INSTALL_RPATH FALSE )
-
endif() # _PAR_SOURCES
if( DEFINED _PAR_COMMAND AND NOT _PAR_TARGET ) # in the absence of target, we use the command as a name
@@ -375,7 +382,10 @@ macro( ecbuild_add_test )
# define the arguments
set( TEST_ARGS "" )
- if( DEFINED _PAR_ARGS )
+ # Boost Unit Test >= 1.60 requires arguments to be passed to the application to be separated by --
+ if( DEFINED _PAR_ARGS AND _PAR_BOOST )
+ list( APPEND TEST_ARGS "--" ${_PAR_ARGS} )
+ elseif( DEFINED _PAR_ARGS )
list( APPEND TEST_ARGS ${_PAR_ARGS} )
endif()
diff --git a/cmake/ecbuild_append_to_rpath.cmake b/cmake/ecbuild_append_to_rpath.cmake
index db1efb4..4f10368 100644
--- a/cmake/ecbuild_append_to_rpath.cmake
+++ b/cmake/ecbuild_append_to_rpath.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_bundle.cmake b/cmake/ecbuild_bundle.cmake
index 2d9b779..7a0eff4 100644
--- a/cmake/ecbuild_bundle.cmake
+++ b/cmake/ecbuild_bundle.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -61,7 +61,7 @@ endmacro()
# Declare a subproject to be built as part of this bundle. ::
#
# ecbuild_bundle( PROJECT <name>
-# STASH <repository> | GIT <giturl>
+# STASH <repository> | GIT <giturl> | SOURCE <path>
# [ BRANCH <gitbranch> | TAG <gittag> ]
# [ UPDATE | NOREMOTE ] )
# [ MANUAL ] )
@@ -72,12 +72,15 @@ endmacro()
# PROJECT : required
# project name for the Git repository to be managed
#
-# STASH : cannot be combined with GIT, either is required
+# STASH : cannot be combined with GIT or SOURCE
# Stash repository in the form <project>/<repository>
#
-# URL : cannot be combined with STASH, either is required
+# GIT : cannot be combined with STASH or SOURCE
# Git URL of the remote repository to clone (see ``git help clone``)
#
+# SOURCE : cannot be combined with STASH or GIT
+# Path to an existing local repository, which will be symlinked
+#
# BRANCH : optional, cannot be combined with TAG
# Git branch to check out
#
@@ -104,6 +107,10 @@ endmacro()
# The first time a bundle is built, the sources of all subprojects are cloned
# into directories named according to project in the *source* tree of the
# bundle (which means these directories should be added to ``.gitignore``).
+# If the ``SOURCE`` option is used it must point to an existing local
+# repository on disk and no new repository is cloned. Be aware that using the
+# ``BRANCH`` or ``TAG`` option leads to the corresponding version being checked
+# out in that repository!
#
# Subprojects are configured and built in order. Due to being added as a
# subproject, the usual project discovery mechanism (i.e. locating and
@@ -119,23 +126,32 @@ endmacro()
macro( ecbuild_bundle )
set( options )
- set( single_value_args PROJECT STASH GIT )
+ set( single_value_args PROJECT STASH GIT SOURCE )
set( multi_value_args )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
string(TOUPPER "${_PAR_PROJECT}" PNAME)
if( BUNDLE_SKIP_${PNAME} )
- message( STATUS "Skipping bundle project ${PNAME}" )
+ message( STATUS "Skipping bundle project ${PNAME}" )
else()
- if( _PAR_STASH )
- ecmwf_stash( PROJECT ${_PAR_PROJECT} DIR ${PROJECT_SOURCE_DIR}/${_PAR_PROJECT} STASH ${_PAR_STASH} ${_PAR_UNPARSED_ARGUMENTS} )
- elseif( _PAR_GIT )
- ecbuild_git( PROJECT ${_PAR_PROJECT} DIR ${PROJECT_SOURCE_DIR}/${_PAR_PROJECT} URL ${_PAR_GIT} ${_PAR_UNPARSED_ARGUMENTS} )
+ if( _PAR_STASH )
+ ecmwf_stash( PROJECT ${_PAR_PROJECT} DIR ${PROJECT_SOURCE_DIR}/${_PAR_PROJECT} STASH ${_PAR_STASH} ${_PAR_UNPARSED_ARGUMENTS} )
+ elseif( _PAR_GIT )
+ ecbuild_git( PROJECT ${_PAR_PROJECT} DIR ${PROJECT_SOURCE_DIR}/${_PAR_PROJECT} URL ${_PAR_GIT} ${_PAR_UNPARSED_ARGUMENTS} )
+ elseif( _PAR_SOURCE )
+ if( DEFINED ${PNAME}_SOURCE )
+ ecbuild_critical( "ecbuild_bundle called with SOURCE for project ${_PAR_PROJECT} but ${PNAME}_SOURCE is defined" )
endif()
+ execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ${_PAR_SOURCE} ${PROJECT_SOURCE_DIR}/${_PAR_PROJECT} )
+ endif()
+
+ if( NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_PAR_PROJECT} OR NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_PAR_PROJECT}/CMakeLists.txt )
+ ecbuild_critical("Source directory '${CMAKE_CURRENT_SOURCE_DIR}/${_PAR_PROJECT}' for subproject '${_PAR_PROJECT}' does not exist or does not contain a CMakeLists.txt file.")
+ endif()
- ecbuild_use_package( PROJECT ${_PAR_PROJECT} )
+ ecbuild_use_package( PROJECT ${_PAR_PROJECT} )
endif()
endmacro()
diff --git a/cmake/ecbuild_cache.cmake b/cmake/ecbuild_cache.cmake
index 2752392..e257b36 100644
--- a/cmake/ecbuild_cache.cmake
+++ b/cmake/ecbuild_cache.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_check_c_source_return.cmake b/cmake/ecbuild_check_c_source_return.cmake
index 4e670dc..7e704cb 100644
--- a/cmake/ecbuild_check_c_source_return.cmake
+++ b/cmake/ecbuild_check_c_source_return.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_check_compiler.cmake b/cmake/ecbuild_check_compiler.cmake
index 4333abd..437b81e 100644
--- a/cmake/ecbuild_check_compiler.cmake
+++ b/cmake/ecbuild_check_compiler.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -10,7 +10,8 @@
# enable C to use in system introspection
if( NOT CMAKE_C_COMPILER_LOADED AND ENABLE_OS_TESTS )
- enable_language( C )
+ enable_language( C )
+ ecbuild_compiler_flags( C )
endif()
############################################################################################
@@ -122,6 +123,10 @@ if( CMAKE_COMPILER_IS_GNUCXX )
endif()
+if( ENABLE_WARNINGS AND CMAKE_Fortran_COMPILER_ID MATCHES "Intel" )
+ ecbuild_add_fortran_flags("-warn all")
+endif()
+
############################################################################################
# compiler dependent fixes
diff --git a/cmake/ecbuild_check_cxx11.cmake b/cmake/ecbuild_check_cxx11.cmake
index 51c5dc6..dd78649 100644
--- a/cmake/ecbuild_check_cxx11.cmake
+++ b/cmake/ecbuild_check_cxx11.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_check_cxx_source_return.cmake b/cmake/ecbuild_check_cxx_source_return.cmake
index df6839c..402850e 100644
--- a/cmake/ecbuild_check_cxx_source_return.cmake
+++ b/cmake/ecbuild_check_cxx_source_return.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -93,9 +93,9 @@ macro( ecbuild_check_cxx_source_return SOURCE )
if( __add_incs )
set(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES "-DINCLUDE_DIRECTORIES:STRING=${__add_incs}")
endif()
-
+
# write the source file
-
+
file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_${_p_VAR}.cxx" "${SOURCE}\n" )
message( STATUS "${_msg}" )
@@ -107,11 +107,11 @@ macro( ecbuild_check_cxx_source_return SOURCE )
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
"${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
- COMPILE_OUTPUT_VARIABLE compile_OUTPUT
+ COMPILE_OUTPUT_VARIABLE compile_OUTPUT
RUN_OUTPUT_VARIABLE run_OUTPUT )
-
- # debug_var( ${_p_VAR}_COMPILED )
- # debug_var( ${_p_VAR}_EXITCODE )
+
+ # ecbuild_debug_var( ${_p_VAR}_COMPILED )
+ # ecbuild_debug_var( ${_p_VAR}_EXITCODE )
# if it did not compile make the return value fail code of 1
@@ -125,21 +125,21 @@ macro( ecbuild_check_cxx_source_return SOURCE )
# if the return value was 0 then it worked
if( ${_p_VAR}_COMPILED AND "${${_p_VAR}_EXITCODE}" EQUAL 0 )
-
+
message(STATUS "${_msg} Success")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C++ SOURCE FILE Test ${_p_VAR} succeded with the following compile output:\n"
- "${compile_OUTPUT}\n"
+ "${compile_OUTPUT}\n"
"Performing C++ SOURCE FILE Run ${_p_VAR} succeded with the following run output:\n"
- "${run_OUTPUT}\n"
+ "${run_OUTPUT}\n"
"Return value: ${${_p_VAR}}\n"
"Source file was:\n${SOURCE}\n")
set( ${_p_VAR} 1 CACHE INTERNAL "Test ${_p_VAR}")
set( ${_p_OUTPUT} "${run_OUTPUT}" CACHE INTERNAL "Test ${_p_VAR} output")
-
+
else()
-
+
if(CMAKE_CROSSCOMPILING AND "${${_p_VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
set(${_p_VAR} "${${_p_VAR}_EXITCODE}")
set(${OUTPUT} "")
@@ -147,17 +147,17 @@ macro( ecbuild_check_cxx_source_return SOURCE )
set(${_p_VAR} "" CACHE INTERNAL "Test ${_p_VAR}")
set(${_p_OUTPUT} "" CACHE INTERNAL "Test ${_p_VAR} output")
endif()
-
+
message(STATUS "Test ${_p_VAR} - Failed")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C++ SOURCE FILE Test ${_p_VAR} failed with the following compile output:\n"
- "${compile_OUTPUT}\n"
+ "${compile_OUTPUT}\n"
"Performing C++ SOURCE FILE Run ${_p_VAR} failed with the following run output:\n"
- "${run_OUTPUT}\n"
+ "${run_OUTPUT}\n"
"Return value: ${${_p_VAR}_EXITCODE}\n"
"Source file was:\n${SOURCE}\n")
endif()
-
+
endif()
endmacro()
diff --git a/cmake/ecbuild_check_fortran_source_return.cmake b/cmake/ecbuild_check_fortran_source_return.cmake
index 689749b..7477e88 100644
--- a/cmake/ecbuild_check_fortran_source_return.cmake
+++ b/cmake/ecbuild_check_fortran_source_return.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_check_functions.cmake b/cmake/ecbuild_check_functions.cmake
index 0369797..7b850e9 100644
--- a/cmake/ecbuild_check_functions.cmake
+++ b/cmake/ecbuild_check_functions.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -73,10 +73,10 @@ if( ENABLE_OS_FUNCTIONS_TEST )
ecbuild_cache_check_c_source_compiles( "#define _LARGEFILE64_SOURCE\n#include <sys/stat.h>\nint main(){ struct stat64 s; fstat64(1,&s); return 0; }" EC_HAVE_FSTAT64 )
# test fseeko64
ecbuild_cache_check_c_source_compiles( "#define _LARGEFILE64_SOURCE\n#include <stdio.h>\n#include <sys/types.h>\nint main(){FILE* file;off64_t l=0;fseeko64(file,l,SEEK_CUR);return 0;}\n" EC_HAVE_FSEEKO64 )
-
+
# test for ftello64
ecbuild_cache_check_c_source_compiles( "#define _LARGEFILE64_SOURCE\n#include <stdio.h>\n#include <sys/types.h>\nint main(){FILE* file;off64_t l = ftello64(file);return 0;}\n" EC_HAVE_FTELLO64 )
-
+
# test for lseek64
ecbuild_cache_check_c_source_compiles( "#define _LARGEFILE64_SOURCE\n#include <sys/types.h>\n#include <unistd.h>\nint main(){off64_t h = lseek64(0,0,SEEK_SET);return 0;}\n" EC_HAVE_LSEEK64 )
# test for open64
@@ -114,7 +114,7 @@ if( ENABLE_OS_FUNCTIONS_TEST )
# test for getpwuid_r
ecbuild_cache_check_c_source_compiles( "#include <unistd.h>\n#include <sys/types.h>\n#include <pwd.h>\nint main(){ char buf[4096]; struct passwd pwbuf; struct passwd *pwbufp = 0; getpwuid_r(getuid(), &pwbuf, buf, sizeof(buf), &pwbufp); }\n" EC_HAVE_GETPWUID_R )
# test for getpwnam_r
- ecbuild_cache_check_c_source_compiles( "#include <sys/types.h>\n#include <pwd.h>\nint main(){ struct passwd p; char line[1024]; int n = getpwnam_r(\"user\",&p,line,sizeof(line),0); }\n" EC_HAVE_GETPWNAM_R )
+ ecbuild_cache_check_c_source_compiles( "#include <sys/types.h>\n#include <pwd.h>\nint main(){ struct passwd p; char line[1024]; int n = getpwnam_r(\"user\",&p,line,sizeof(line),0); }\n" EC_HAVE_GETPWNAM_R )
# test for readdir_r
ecbuild_cache_check_c_source_compiles( "#include <dirent.h>\nint main(){ DIR *dirp; struct dirent *entry; struct dirent **result; int i = readdir_r(dirp, entry, result); }\n" EC_HAVE_READDIR_R )
# test for gethostbyname_r
@@ -164,8 +164,8 @@ if( ENABLE_OS_FUNCTIONS_TEST )
endif()
ecbuild_cache_var( EC_HAVE_PROCFS )
-# debug_var(EC_HAVE_PROCFS)
-# debug_var(EC_HAVE_PROCFS_OUTPUT)
+# ecbuild_debug_var(EC_HAVE_PROCFS)
+# ecbuild_debug_var(EC_HAVE_PROCFS_OUTPUT)
endif()
diff --git a/cmake/ecbuild_check_os.cmake b/cmake/ecbuild_check_os.cmake
index c9fd199..5fc3c2e 100644
--- a/cmake/ecbuild_check_os.cmake
+++ b/cmake/ecbuild_check_os.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -9,23 +9,34 @@
############################################################################################
# check size of pointer
+# Re-check size of void pointer since for some compiler combinations this is not properly set
ecbuild_cache_check_type_size( "void*" CMAKE_SIZEOF_VOID_P )
+if( NOT CMAKE_C_COMPILER_LOADED AND ENABLE_OS_TESTS )
+
+ enable_language( C )
+ ecbuild_compiler_flags( C )
+
+endif()
+
math( EXPR EC_OS_BITS "${CMAKE_SIZEOF_VOID_P} * 8" )
# we only support 32 and 64 bit operating systems
if( NOT EC_OS_BITS EQUAL "32" AND NOT EC_OS_BITS EQUAL "64" )
- message( FATAL_ERROR "operating system ${CMAKE_SYSTEM} ${EC_OS_BITS} bits -- ecbuild only supports 32 or 64 bit OS's" )
+ message( FATAL_ERROR "operating system ${CMAKE_SYSTEM} ${EC_OS_BITS} bits -- ecbuild only supports 32 or 64 bit OS's" )
endif()
-ecbuild_cache_var( EC_OS_BITS )
############################################################################################
# For 64 bit architectures enable PIC (position-independent code)
-if( ${EC_OS_BITS} EQUAL 64 )
- set( CMAKE_POSITION_INDEPENDENT_CODE ON )
+# Allow overriding the position independent code setting (ECBUILD-220)
+if( DEFINED ECBUILD_POSITION_INDEPENDENT_CODE )
+ set( CMAKE_POSITION_INDEPENDENT_CODE ${ECBUILD_POSITION_INDEPENDENT_CODE} )
+elseif( ${EC_OS_BITS} EQUAL 64 )
+ set( CMAKE_POSITION_INDEPENDENT_CODE ON )
endif()
+
############################################################################################
# check architecture
@@ -101,14 +112,19 @@ endif()
if( ENABLE_OS_ENDINESS_TEST )
if( NOT DEFINED EC_BIG_ENDIAN AND NOT DEFINED EC_LITTLE_ENDIAN )
+
test_big_endian( _BIG_ENDIAN )
if( _BIG_ENDIAN )
- set( EC_BIG_ENDIAN 1 )
+ set( EC_BIG_ENDIAN 1 )
+ set( EC_LITTLE_ENDIAN 0 )
else()
- set( EC_LITTLE_ENDIAN 1 )
+ set( EC_BIG_ENDIAN 0 )
+ set( EC_LITTLE_ENDIAN 1 )
endif()
+
endif()
+
ecbuild_cache_var( EC_BIG_ENDIAN )
ecbuild_cache_var( EC_LITTLE_ENDIAN )
@@ -142,9 +158,15 @@ if( ENABLE_OS_ENDINESS_TEST )
if( "${IEEE_BE}" STREQUAL "" )
set( IEEE_BE 0 CACHE INTERNAL "Test IEEE_BE")
endif()
+
endif()
+
ecbuild_cache_var( IEEE_BE )
+ if( EC_BIG_ENDIAN AND NOT IEEE_BE )
+ ecbuild_critical("Failed to sanity check on endiness: OS should be Big-Endian but compiled code runs differently -- to ignore this pass -DIEEE_BE=0 to CMake/ecBuild")
+ endif()
+
if( NOT DEFINED IEEE_LE )
check_c_source_runs(
"int compare(unsigned char* a,unsigned char* b) {
@@ -172,12 +194,17 @@ if( ENABLE_OS_ENDINESS_TEST )
return 0;
}" IEEE_LE )
- if( "${IEEE_BE}" STREQUAL "" )
+ if( "${IEEE_LE}" STREQUAL "" )
set( IEEE_LE 0 CACHE INTERNAL "Test IEEE_LE")
endif()
endif()
+
ecbuild_cache_var( IEEE_LE )
+ if( EC_LITTLE_ENDIAN AND NOT IEEE_LE )
+ ecbuild_critical("Failed to sanity check on endiness: OS should be Little-Endian but compiled code runs differently -- to ignore this pass -DIEEE_LE=0 to CMake/ecBuild")
+ endif()
+
endif()
############################################################################################
@@ -187,17 +214,22 @@ if( ENABLE_PROFILING )
if( CMAKE_C_COMPILER_ID MATCHES "GNU" )
- set( _flags "-pg;-fprofile-arcs;-ftest-coverage" )
- ecbuild_add_c_flags( "${_flags}" )
- ecbuild_add_cxx_flags( "${_flags}" )
- ecbuild_add_fortran_flags( "${_flags}" )
+ set( _flags "-pg --coverage" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_flags}" )
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_flags}" )
set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${_flags}" )
+ set( _trust_flags ${ECBUILD_TRUST_FLAGS} )
+ set( ECBUILD_TRUST_FLAGS ON )
+ ecbuild_add_c_flags( "${_flags}" )
+ ecbuild_add_cxx_flags( "${_flags}" )
+ ecbuild_add_fortran_flags( "${_flags}" )
+ set( ECBUILD_TRUST_FLAGS ${_trust_flags} )
+ unset( _trust_flags )
+
unset( _flags )
-
+
else()
message( WARNING "Profiling enabled but ecbuild doesn't know how to enable for this particular compiler ${CMAKE_C_COMPILER_ID}")
endif()
diff --git a/cmake/ecbuild_compiler_flags.cmake b/cmake/ecbuild_compiler_flags.cmake
new file mode 100644
index 0000000..b97eb2c
--- /dev/null
+++ b/cmake/ecbuild_compiler_flags.cmake
@@ -0,0 +1,97 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_compiler_flags
+# ======================
+#
+# Set default compiler flags for a given language. ::
+#
+# ecbuild_compiler_flags( <lang> )
+#
+# The procedure is as follows:
+#
+# 1. ecBuild does *not* set ``CMAKE_<lang>_FLAGS`` i.e. the user can set these
+# via -D or the CMake cache and these will be the "base" flags.
+#
+# 2. ecBuild *overwrites* ``CMAKE_<lang>_FLAGS_<btype>`` in the CMake cache
+# for all build types with compiler specific defaults for the currently
+# loaded compiler i.e. any value set by the user via -D or the CMake cache
+# *has no effect*.
+#
+# 3. Any value the user provides via ``ECBUILD_<lang>_FLAGS`` or
+# ``ECBUILD_<lang>_FLAGS_<btype>`` *overrides* the corresponding
+# ``CMAKE_<lang>_FLAGS`` or ``CMAKE_<lang>_FLAGS_<btype>`` *without being
+# written to the CMake cache*.
+#
+##############################################################################
+
+macro( ecbuild_compiler_flags _lang )
+
+ if( CMAKE_${_lang}_COMPILER_LOADED )
+
+ ecbuild_debug( "try include ${ECBUILD_MACROS_DIR}/compiler_flags/${CMAKE_${_lang}_COMPILER_ID}_${_lang}.cmake ")
+
+ include( ${ECBUILD_MACROS_DIR}/compiler_flags/${CMAKE_${_lang}_COMPILER_ID}_${_lang}.cmake OPTIONAL )
+
+ ecbuild_debug_var( CMAKE_${_lang}_FLAGS )
+
+ foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
+ ecbuild_debug_var( CMAKE_${_lang}_FLAGS_${_btype} )
+ endforeach()
+
+ endif()
+
+ foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
+ if( DEFINED ECBUILD_${_lang}_FLAGS_${_btype} )
+ set( CMAKE_${_lang}_FLAGS_${_btype} ${ECBUILD_${_lang}_FLAGS_${_btype}} )
+ endif()
+ mark_as_advanced( CMAKE_${_lang}_FLAGS_${_btype} )
+ endforeach()
+
+ if( DEFINED ECBUILD_${_lang}_FLAGS )
+ set( CMAKE_${_lang}_FLAGS "${ECBUILD_${_lang}_FLAGS}" )
+ endif()
+
+ mark_as_advanced( CMAKE_${_lang}_FLAGS )
+
+ if( DEFINED ECBUILD_${_lang}_LINK_FLAGS )
+ set( CMAKE_${_lang}_LINK_FLAGS "${ECBUILD_${_lang}_LINK_FLAGS}" )
+ endif()
+
+ mark_as_advanced( CMAKE_${_lang}_LINK_FLAGS )
+
+endmacro()
+
+#-----------------------------------------------------------------------------------------------------------------------
+
+### OVERRIDE Compiler FLAGS (we override because CMake forcely defines them) -- see ecbuild_compiler_flags() macro
+
+foreach( _lang C CXX Fortran )
+ if( CMAKE_${_lang}_COMPILER_LOADED )
+ ecbuild_compiler_flags( ${_lang} )
+ endif()
+endforeach()
+
+### OVERRIDE Linker FLAGS per object type (we override because CMake forcely defines them)
+
+foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
+
+ foreach( _obj EXE SHARED MODULE )
+ if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} )
+ set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} )
+ endif()
+ endforeach()
+
+endforeach()
+
+#-----------------------------------------------------------------------------------------------------------------------
+
+mark_as_advanced( CMAKE_C_FLAGS_BIT )
diff --git a/cmake/ecbuild_config.h.in b/cmake/ecbuild_config.h.in
index 68d31f8..eef9b85 100644
--- a/cmake/ecbuild_config.h.in
+++ b/cmake/ecbuild_config.h.in
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 1996-2014 ECMWF.
+ * (C) Copyright 1996-2016 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_debug_var.cmake b/cmake/ecbuild_debug_var.cmake
deleted file mode 100644
index 7084c7c..0000000
--- a/cmake/ecbuild_debug_var.cmake
+++ /dev/null
@@ -1,47 +0,0 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
-# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
-# granted to it by virtue of its status as an intergovernmental organisation nor
-# does it submit to any jurisdiction.
-
-##############################################################################
-# macro for exporting a variable to parent scope
-
-macro( set_parent_scope VAR )
-
- set( ${VAR} ${${VAR}} PARENT_SCOPE )
-
-endmacro( set_parent_scope )
-
-##############################################################################
-# macro for debugging a cmake variable
-
-macro( debug_var VAR )
-
- message( STATUS "${VAR} [${${VAR}}]" )
-
-endmacro( debug_var )
-
-##############################################################################
-# macro for debugging a cmake list
-
-macro( debug_list VAR )
-
- message( STATUS "${VAR}:" )
- foreach( _elem ${${VAR}} )
- message( STATUS " ${_elem}" )
- endforeach()
-
-endmacro( debug_list )
-
-##############################################################################
-# macro for debugging a environment variable within cmake
-
-macro( debug_env_var VAR )
-
- message( STATUS "ENV ${VAR} [$ENV{${VAR}}]" )
-
-endmacro( debug_env_var )
-
diff --git a/cmake/ecbuild_declare_project.cmake b/cmake/ecbuild_declare_project.cmake
index bc99de4..c59079e 100644
--- a/cmake/ecbuild_declare_project.cmake
+++ b/cmake/ecbuild_declare_project.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -69,8 +69,8 @@ macro( ecbuild_declare_project )
get_git_head_revision( GIT_REFSPEC ${PNAME}_GIT_SHA1 )
if( ${PNAME}_GIT_SHA1 )
string( SUBSTRING "${${PNAME}_GIT_SHA1}" 0 7 ${PNAME}_GIT_SHA1_SHORT )
- # debug_var( ${PNAME}_GIT_SHA1 )
- # debug_var( ${PNAME}_GIT_SHA1_SHORT )
+ # ecbuild_debug_var( ${PNAME}_GIT_SHA1 )
+ # ecbuild_debug_var( ${PNAME}_GIT_SHA1_SHORT )
else()
message( STATUS "Could not get git-sha1 for project ${PNAME}")
endif()
@@ -101,11 +101,11 @@ macro( ecbuild_declare_project )
set( ${PNAME}_VERSION_STR "${${PROJECT_NAME}_VERSION_STR}"
CACHE INTERNAL "package ${PNAME} version string" ) # ignore caps
- # debug_var( ${PNAME}_VERSION )
- # debug_var( ${PNAME}_VERSION_STR )
- # debug_var( ${PNAME}_MAJOR_VERSION )
- # debug_var( ${PNAME}_MINOR_VERSION )
- # debug_var( ${PNAME}_PATCH_VERSION )
+ # ecbuild_debug_var( ${PNAME}_VERSION )
+ # ecbuild_debug_var( ${PNAME}_VERSION_STR )
+ # ecbuild_debug_var( ${PNAME}_MAJOR_VERSION )
+ # ecbuild_debug_var( ${PNAME}_MINOR_VERSION )
+ # ecbuild_debug_var( ${PNAME}_PATCH_VERSION )
# install dirs for this project
@@ -151,7 +151,7 @@ macro( ecbuild_declare_project )
CACHE INTERNAL "${PNAME} ${p} full install path" )
endif()
- # debug_var( ${PNAME}_FULL_INSTALL_${p}_DIR )
+ # ecbuild_debug_var( ${PNAME}_FULL_INSTALL_${p}_DIR )
endforeach()
@@ -162,7 +162,7 @@ macro( ecbuild_declare_project )
if( ENABLE_RELATIVE_RPATHS )
file( RELATIVE_PATH relative_rpath ${${PNAME}_FULL_INSTALL_BIN_DIR} ${${PNAME}_FULL_INSTALL_LIB_DIR} )
- # debug_var( relative_rpath )
+ # ecbuild_debug_var( relative_rpath )
ecbuild_append_to_rpath( ${relative_rpath} )
@@ -171,14 +171,14 @@ macro( ecbuild_declare_project )
if( IS_ABSOLUTE ${INSTALL_LIB_DIR} )
ecbuild_append_to_rpath( "${INSTALL_LIB_DIR}" )
else()
- ecbuild_append_to_rpath( "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}" )
+ ecbuild_append_to_rpath( "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB_DIR}" )
endif()
endif()
endif()
- # debug_var( CMAKE_INSTALL_RPATH )
+ # ecbuild_debug_var( CMAKE_INSTALL_RPATH )
# print project header
diff --git a/cmake/ecbuild_define_build_types.cmake b/cmake/ecbuild_define_build_types.cmake
index f239f01..4958458 100644
--- a/cmake/ecbuild_define_build_types.cmake
+++ b/cmake/ecbuild_define_build_types.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -7,55 +7,6 @@
# does it submit to any jurisdiction.
############################################################################################
-# define a Production build type
-
-# NOTE: gcc does not guarrante that -O3 performs better than -O2
-# -- it can perform worse due to assembly code bloating.
-# Moreover for gcc 4.1.2 we found that -O3 remove the parser code generated from Lex/Yacc
-# and therefore in production mode we downgrade to -O2 if the compiler is GCC (for all versions).
-
-
-if(CMAKE_COMPILER_IS_GNUCXX)
- set( CMAKE_CXX_FLAGS_PRODUCTION "-O2 -g" CACHE STRING "Flags used by the C++ compiler during Production builds." FORCE )
-else()
- set( CMAKE_CXX_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "Flags used by the C++ compiler during Production builds." FORCE )
-endif()
-
-if(CMAKE_COMPILER_IS_GNUCC)
- set( CMAKE_C_FLAGS_PRODUCTION "-O2 -g" CACHE STRING "Flags used by the C compiler during Production builds." FORCE )
-else()
- set( CMAKE_C_FLAGS_PRODUCTION "-O3 -g" CACHE STRING "Flags used by the C compiler during Production builds." FORCE )
-endif()
-
-set( CMAKE_EXE_LINKER_FLAGS_PRODUCTION "" CACHE STRING "Flags used for linking binaries during Production builds." FORCE )
-set( CMAKE_SHARED_LINKER_FLAGS_PRODUCTION "" CACHE STRING "Flags used by the shared libraries linker during Production builds." FORCE )
-set( CMAKE_MODULE_LINKER_FLAGS_PRODUCTION "" CACHE STRING "Flags used by the static libraries linker during Production builds." FORCE )
-
-mark_as_advanced(
- CMAKE_CXX_FLAGS_PRODUCTION
- CMAKE_C_FLAGS_PRODUCTION
- CMAKE_EXE_LINKER_FLAGS_PRODUCTION
- CMAKE_SHARED_LINKER_FLAGS_PRODUCTION
- CMAKE_MODULE_LINKER_FLAGS_PRODUCTION )
-
-############################################################################################
-# fixes for specific compilers
-
-### remove -Mipa=fast from PGI compilers in RELEASE mode
-
-if( CMAKE_C_COMPILER_ID STREQUAL "PGI" )
- set(CMAKE_C_FLAGS_RELEASE "-fast -O3")
-endif()
-
-if( CMAKE_CXX_COMPILER_ID STREQUAL "PGI" )
- set(CMAKE_CXX_FLAGS_RELEASE "-fast -O3")
-endif()
-
-if( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
- set(CMAKE_Fortran_FLAGS_RELEASE "-fast -O3")
-endif()
-
-############################################################################################
# define default build type
set( _BUILD_TYPE_MSG "Build type options are: [ None | Debug | Bit | Production | Release | RelWithDebInfo ]" )
@@ -106,32 +57,3 @@ if( NOT CMAKE_BUILD_TYPE MATCHES "None" AND
NOT CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo" )
message( FATAL_ERROR "CMAKE_BUILD_TYPE is not recognized. ${_BUILD_TYPE_MSG}" )
endif()
-
-############################################################################################
-# overrides of the flags per build type
-
-foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
-
- # OVERRIDE Compiler FLAGS per language (we override because CMake forcely defines them)
- foreach( _lang C CXX Fortran )
- if( ECBUILD_${_lang}_FLAGS_${_btype} )
- set( CMAKE_${_lang}_FLAGS_${_btype} ${ECBUILD_${_lang}_FLAGS_${_btype}} )
- endif()
- endforeach()
-
- # OVERRIDE Linker FLAGS per object type (we override because CMake forcely defines them)
- foreach( _obj EXE SHARED MODULE )
- if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} )
- set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} )
- endif()
- endforeach()
-
-endforeach()
-
-# APPEND Linker FLAGS per language (we append because CMake typically leaves them empty)
-
-foreach( _lang C CXX Fortran )
- if( ECBUILD_${_lang}_LINK_FLAGS )
- set( CMAKE_${_lang}_LINK_FLAGS "${CMAKE_${_lang}_LINK_FLAGS} ${ECBUILD_${_lang}_LINK_FLAGS}" )
- endif()
-endforeach()
\ No newline at end of file
diff --git a/cmake/ecbuild_define_libs_and_execs_target.cmake b/cmake/ecbuild_define_libs_and_execs_target.cmake
new file mode 100644
index 0000000..812f42c
--- /dev/null
+++ b/cmake/ecbuild_define_libs_and_execs_target.cmake
@@ -0,0 +1,29 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+set( EC_ALL_EXES "" CACHE INTERNAL "" )
+set( EC_ALL_LIBS "" CACHE INTERNAL "" )
+
+############################################################################################
+# define libs and execs targets
+
+macro( ecbuild_define_libs_and_execs_targets )
+
+ add_custom_target( libs )
+
+ if( EC_ALL_LIBS )
+ add_dependencies( libs ${EC_ALL_LIBS} )
+ endif()
+
+ add_custom_target( execs )
+
+ if( EC_ALL_EXECS )
+ add_dependencies( execs ${EC_ALL_EXES} )
+ endif()
+
+endmacro(ecbuild_define_libs_and_execs_targets)
diff --git a/cmake/ecbuild_links_target.cmake b/cmake/ecbuild_define_links_target.cmake
similarity index 92%
rename from cmake/ecbuild_links_target.cmake
rename to cmake/ecbuild_define_links_target.cmake
index 5dfacdc..b5f53fe 100644
--- a/cmake/ecbuild_links_target.cmake
+++ b/cmake/ecbuild_define_links_target.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -63,11 +63,11 @@ macro( ecbuild_define_links_target )
add_custom_target( links DEPENDS ${ec_link_libs} ${ec_link_exes} )
- # debug_var( EC_ALL_EXES )
- # debug_var( ec_link_exes )
+ # ecbuild_debug_var( EC_ALL_EXES )
+ # ecbuild_debug_var( ec_link_exes )
- # debug_var( EC_ALL_LIBS )
- # debug_var( ec_link_libs )
+ # ecbuild_debug_var( EC_ALL_LIBS )
+ # ecbuild_debug_var( ec_link_libs )
endif()
diff --git a/cmake/ecbuild_define_options.cmake b/cmake/ecbuild_define_options.cmake
index 49cbed8..af40ae1 100644
--- a/cmake/ecbuild_define_options.cmake
+++ b/cmake/ecbuild_define_options.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -46,3 +46,7 @@ option( ECBUILD_USE_INCLUDE_DIRECTORIES "Forces to use global include_directorie
mark_as_advanced( ECBUILD_USE_INCLUDE_DIRECTORIES )
set( CMAKE_NO_SYSTEM_FROM_IMPORTED ON )
+
+# hide some CMake options from CMake UI
+
+mark_as_advanced( CMAKE_OSX_ARCHITECTURES CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT )
\ No newline at end of file
diff --git a/cmake/ecbuild_define_paths.cmake b/cmake/ecbuild_define_paths.cmake
index 57a3f1a..856903d 100644
--- a/cmake/ecbuild_define_paths.cmake
+++ b/cmake/ecbuild_define_paths.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2012 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_dont_pack.cmake b/cmake/ecbuild_dont_pack.cmake
index 099ee1d..987aca7 100644
--- a/cmake/ecbuild_dont_pack.cmake
+++ b/cmake/ecbuild_dont_pack.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_download_resource.cmake b/cmake/ecbuild_download_resource.cmake
index d313704..3a9abdb 100644
--- a/cmake/ecbuild_download_resource.cmake
+++ b/cmake/ecbuild_download_resource.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_echo_targets.cmake b/cmake/ecbuild_echo_targets.cmake
index ddaa2e4..58407f7 100644
--- a/cmake/ecbuild_echo_targets.cmake
+++ b/cmake/ecbuild_echo_targets.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -32,13 +32,13 @@ function(ecbuild_echo_target_property tgt prop)
get_property(s TARGET ${tgt} PROPERTY ${prop} SET)
# only produce output for values that are set
- #if(s)
+ if(s)
message("tgt='${tgt}' prop='${prop}'")
message(" value='${v}'")
message(" defined='${d}'")
message(" set='${s}'")
message("")
- #endif()
+ endif()
cmake_policy(POP)
@@ -207,7 +207,7 @@ XCODE_ATTRIBUTE_WHATEVER
message("======================== ${tgt} ========================")
foreach(p ${props})
- ecbuild_echo_target_property("${t}" "${p}")
+ ecbuild_echo_target_property("${tgt}" "${p}")
endforeach()
message("")
endfunction()
diff --git a/cmake/ecbuild_enable_fortran.cmake b/cmake/ecbuild_enable_fortran.cmake
index 5560148..9d65a59 100644
--- a/cmake/ecbuild_enable_fortran.cmake
+++ b/cmake/ecbuild_enable_fortran.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -39,7 +39,14 @@ macro( ecbuild_enable_fortran )
message(FATAL_ERROR "Unknown keywords given to ecbuild_enable_fortran(): \"${_PAR_UNPARSED_ARGUMENTS}\"")
endif()
- enable_language( Fortran )
+ if( NOT CMAKE_Fortran_COMPILER_LOADED )
+ enable_language( Fortran )
+ ecbuild_compiler_flags( Fortran )
+ if( ENABLE_WARNINGS AND CMAKE_Fortran_COMPILER_ID MATCHES "Intel" )
+ set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all" )
+ ecbuild_debug( "Fortran FLAG [-warn all] added" )
+ endif()
+ endif()
if( DEFINED _PAR_REQUIRED )
if( CMAKE_Fortran_COMPILER_FORCED )
diff --git a/cmake/ecbuild_features.cmake b/cmake/ecbuild_features.cmake
index 5d619a5..0490783 100644
--- a/cmake/ecbuild_features.cmake
+++ b/cmake/ecbuild_features.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -10,10 +10,6 @@
include( FeatureSummary )
-function( debug_var _var )
- message( "${_var} = ${${_var}}" )
-endfunction()
-
# Write list of enabled features to CMake variable ${OUT}
macro( ecbuild_enabled_features OUT )
get_property( ${OUT} GLOBAL PROPERTY ENABLED_FEATURES )
@@ -26,17 +22,17 @@ endmacro()
# Enable the feature ${_name} (add to enabled features, remove from disabled)
function( ecbuild_enable_feature _name )
-
+
get_property( _enabled_features GLOBAL PROPERTY ENABLED_FEATURES )
get_property( _disabled_features GLOBAL PROPERTY DISABLED_FEATURES )
-
+
if( _disabled_features )
list( REMOVE_ITEM _disabled_features ${_name} )
endif()
list( APPEND _enabled_features ${_name} )
list( REMOVE_DUPLICATES _enabled_features )
-
+
set_property(GLOBAL PROPERTY ENABLED_FEATURES "${_enabled_features}" )
set_property(GLOBAL PROPERTY DISABLED_FEATURES "${_disabled_features}" )
@@ -47,53 +43,42 @@ function( ecbuild_disable_feature _name )
get_property( _enabled_features GLOBAL PROPERTY ENABLED_FEATURES )
get_property( _disabled_features GLOBAL PROPERTY DISABLED_FEATURES )
-
+
if( _enabled_features )
list( REMOVE_ITEM _enabled_features ${_name} )
endif()
list( APPEND _disabled_features ${_name} )
list( REMOVE_DUPLICATES _disabled_features )
-
+
set_property(GLOBAL PROPERTY ENABLED_FEATURES "${_enabled_features}" )
set_property(GLOBAL PROPERTY DISABLED_FEATURES "${_disabled_features}" )
-
-endfunction()
-# Set description of feature ${_name} to ${_desc}
-function( ecbuild_set_feature_description _name _desc)
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
-endfunction()
-
-# Set purpose of feature ${_name} to ${_desc}
-function( ecbuild_set_feature_purpose _name _purpose )
- get_property( _purpose_list GLOBAL PROPERTY _CMAKE_${_name}_PURPOSE )
- list( APPEND _purpose_list ${_purpose} )
- list( REMOVE_DUPLICATES _purpose_list )
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_PURPOSE "${_purpose_list}" )
endfunction()
# en/disable feature ${_name} and set its description and purpose
function( ecbuild_set_feature _name )
set(options ) # none
- set(oneValueArgs ENABLED DESCRIPTION PURPOSE )
+ set(oneValueArgs ENABLED )
set(multiValueArgs ) # none
- CMAKE_PARSE_ARGUMENTS( _PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
-
- get_property( _feature_desc GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION )
+ cmake_parse_arguments( _PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+ get_property( _feature_desc GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION )
get_property( _enabled_features GLOBAL PROPERTY ENABLED_FEATURES )
get_property( _disabled_features GLOBAL PROPERTY DISABLED_FEATURES )
-
+
if( DEFINED _PAR_ENABLED )
if( _PAR_ENABLED )
+ ecbuild_debug( "ecbuild_set_feature(${_name}): enabling feature" )
ecbuild_enable_feature( ${_name} )
else()
+ ecbuild_debug( "ecbuild_set_feature(${_name}): disabling feature" )
ecbuild_disable_feature( ${_name} )
endif()
endif()
-
+
ecbuild_enabled_features( _enabled_features )
list (FIND _enabled_features "${_name}" _index)
if (${_index} GREATER -1)
@@ -105,17 +90,9 @@ function( ecbuild_set_feature _name )
if (${_index} GREATER -1)
set( _feature_found 1 )
endif()
-
+
if( NOT _feature_found )
message( WARNING "Feature ${_name} has not yet been enabled or disabled" )
endif()
-
- if( _PAR_DESCRIPTION )
- ecbuild_set_feature_description( ${_name} ${_PAR_DESCRIPTION} )
- endif()
-
- if( _PAR_PURPOSE )
- ecbuild_set_feature_purpose( ${_name} ${_PAR_PURPOSE} )
- endif()
endfunction()
diff --git a/cmake/ecbuild_find_fortranlibs.cmake b/cmake/ecbuild_find_fortranlibs.cmake
index 850c4a3..c7ccc64 100644
--- a/cmake/ecbuild_find_fortranlibs.cmake
+++ b/cmake/ecbuild_find_fortranlibs.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_find_lexyacc.cmake b/cmake/ecbuild_find_lexyacc.cmake
index b74c3e1..628488f 100644
--- a/cmake/ecbuild_find_lexyacc.cmake
+++ b/cmake/ecbuild_find_lexyacc.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -34,6 +34,7 @@
#
# The following CMake variables are set if lex and yacc were found:
#
+# :LEXYACC_FOUND: Found suitable combination of bison, lex, yacc, flex
# :LEX_FOUND: lex was found
# :YACC_FOUND: yacc was found
# :LEX_EXECUTABLE: path to the lex executable
@@ -59,25 +60,32 @@ macro( ecbuild_find_lexyacc )
endif()
+ set( LEXYACC_FOUND 1 )
+
if( NOT YACC_FOUND AND NOT BISON_FOUND ) # neither bison nor yacc were found
- message( FATAL_ERROR "neither bison or yacc were found - at least one is required (together with its lexical analyser" )
+ ecbuild_debug( "Neither bison or yacc were found - at least one is required (together with its lexical analyser" )
+ set( LEXYACC_FOUND 0 )
endif()
if( NOT YACC_FOUND ) # check for both bison & flex together
if( BISON_FOUND AND NOT FLEX_FOUND )
- message( FATAL_ERROR "both bison and flex are required - flex not found" )
+ set( LEXYACC_FOUND 0 )
+ ecbuild_debug( "Both bison and flex are required - flex not found" )
endif()
if( FLEX_FOUND AND NOT BISON_FOUND )
- message( FATAL_ERROR "both bison and flex are required - bison not found" )
+ set( LEXYACC_FOUND 0 )
+ ecbuild_debug( "Both bison and flex are required - bison not found" )
endif()
endif()
if( NOT BISON_FOUND ) # check for both yacc & lex together
if( YACC_FOUND AND NOT LEX_FOUND )
- message( FATAL_ERROR "both yacc and lex are required - lex not found" )
+ set( LEXYACC_FOUND 0 )
+ ecbuild_debug( "Both yacc and lex are required - lex not found" )
endif()
if( LEX_FOUND AND NOT YACC_FOUND )
- message( FATAL_ERROR "both yacc and lex are required - yacc not found" )
+ set( LEXYACC_FOUND 0 )
+ ecbuild_debug( "Both yacc and lex are required - yacc not found" )
endif()
endif()
diff --git a/cmake/ecbuild_find_mpi.cmake b/cmake/ecbuild_find_mpi.cmake
index d3f6c8e..5610c77 100644
--- a/cmake/ecbuild_find_mpi.cmake
+++ b/cmake/ecbuild_find_mpi.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_find_omp.cmake b/cmake/ecbuild_find_omp.cmake
index 2de9d74..5458d3e 100644
--- a/cmake/ecbuild_find_omp.cmake
+++ b/cmake/ecbuild_find_omp.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -206,17 +206,24 @@ endmacro( ecbuild_find_omp )
macro( ecbuild_enable_omp )
+ ecbuild_debug("ecbuild_enable_omp: Trying to enable OpenMP")
ecbuild_find_omp( COMPONENTS C CXX Fortran )
+ ecbuild_debug_var("OMP_C_FOUND")
if( OMP_C_FOUND )
+ ecbuild_debug("Adding ${OMP_C_FLAGS} to CMAKE_C_FLAGS")
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OMP_C_FLAGS}" )
endif()
+ ecbuild_debug_var("OMP_CXX_FOUND")
if( OMP_CXX_FOUND )
+ ecbuild_debug("Adding ${OMP_CXX_FLAGS} to CMAKE_CXX_FLAGS")
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OMP_CXX_FLAGS}" )
endif()
+ ecbuild_debug_var("OMP_Fortran_FOUND")
if( OMP_Fortran_FOUND )
+ ecbuild_debug("Adding ${OMP_Fortran_FLAGS} to CMAKE_Fortran_FLAGS")
set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OMP_Fortran_FLAGS}" )
endif()
diff --git a/cmake/ecbuild_find_package.cmake b/cmake/ecbuild_find_package.cmake
index 4d1b108..33d136a 100644
--- a/cmake/ecbuild_find_package.cmake
+++ b/cmake/ecbuild_find_package.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -103,7 +103,7 @@ macro( ecbuild_find_package )
message(FATAL_ERROR "Call to ecbuild_find_package() requests EXACT but doesn't specify VERSION.")
endif()
- # debug_var( _PAR_NAME )
+ # ecbuild_debug_var( _PAR_NAME )
string( TOUPPER ${_PAR_NAME} pkgUPPER )
string( TOLOWER ${_PAR_NAME} pkgLOWER )
@@ -157,9 +157,9 @@ macro( ecbuild_find_package )
set( ${_PAR_NAME}_DIR "$ENV{${_PAR_NAME}_DIR}" )
endif()
- # Find packages quietly unless in DEVELOPER_MODE, LOG_LEVEL is DEBUG or the package is REQUIRED
+ # Find packages quietly unless in DEVELOPER_MODE or LOG_LEVEL is DEBUG
- if( NOT ( DEVELOPER_MODE OR _PAR_REQUIRED ) AND ( ECBUILD_LOG_LEVEL GREATER ${ECBUILD_DEBUG} ) )
+ if( NOT DEVELOPER_MODE AND ( ECBUILD_LOG_LEVEL GREATER ${ECBUILD_DEBUG} ) )
set( _find_quiet QUIET )
endif()
diff --git a/cmake/ecbuild_find_perl.cmake b/cmake/ecbuild_find_perl.cmake
index f4c933a..11e6f1d 100644
--- a/cmake/ecbuild_find_perl.cmake
+++ b/cmake/ecbuild_find_perl.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_find_python.cmake b/cmake/ecbuild_find_python.cmake
index 3209826..2a8b457 100644
--- a/cmake/ecbuild_find_python.cmake
+++ b/cmake/ecbuild_find_python.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -14,7 +14,7 @@
#
# Find Python interpreter, its version and the Python libraries. ::
#
-# ecbuild_find_python( [ VERSION <version> ] [ REQUIRED ] )
+# ecbuild_find_python( [ VERSION <version> ] [ REQUIRED ] [ NO_LIBS ] )
#
# Options
# -------
@@ -25,14 +25,18 @@
# REQUIRED : optional
# fail if Python was not found
#
+# NO_LIBS : optional
+# only search for the Python interpreter, not the libraries
+#
# Output variables
# ----------------
#
-# The following CMake variables are set if perl was found:
+# The following CMake variables are set if python was found:
#
# :PYTHONINTERP_FOUND: Python interpreter was found
# :PYTHONLIBS_FOUND: Python libraries were found
# :PYTHON_FOUND: Python was found (both interpreter and libraries)
+# :PYTHON_EXECUTABLE: Python executable
# :PYTHON_VERSION_MAJOR: major version number
# :PYTHON_VERSION_MINOR: minor version number
# :PYTHON_VERSION_PATCH: patch version number
@@ -45,11 +49,11 @@
set( __test_python ${CMAKE_CURRENT_LIST_DIR}/pymain.c )
-macro( ecbuild_find_python )
+function( ecbuild_find_python )
# parse parameters
- set( options REQUIRED )
+ set( options REQUIRED NO_LIBS )
set( single_value_args VERSION )
set( multi_value_args )
@@ -64,7 +68,7 @@ macro( ecbuild_find_python )
find_package( PythonInterp )
if( NOT PYTHONINTERP_FOUND AND _p_REQUIRED )
- message( FATAL_ERROR "Failed to find any Python interpreter (REQUIRED)" )
+ ecbuild_error( "Failed to find any Python interpreter (REQUIRED)" )
endif()
# find python version
@@ -74,10 +78,10 @@ macro( ecbuild_find_python )
# endif()
# endif()
- # message( STATUS "Python version ${PYTHON_VERSION_STRING}" )
- # debug_var(PYTHON_VERSION_MAJOR)
- # debug_var(PYTHON_VERSION_MINOR)
- # debug_var(PYTHON_VERSION_PATCH)
+ # ecbuild_debug( "Python version ${PYTHON_VERSION_STRING}" )
+ # ecbuild_debug_var(PYTHON_VERSION_MAJOR)
+ # ecbuild_debug_var(PYTHON_VERSION_MINOR)
+ # ecbuild_debug_var(PYTHON_VERSION_PATCH)
if( PYTHONINTERP_FOUND AND DEFINED _p_VERSION )
if( _p_VERSION VERSION_GREATER "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}" )
@@ -94,65 +98,77 @@ macro( ecbuild_find_python )
if( PYTHONINTERP_FOUND )
ecbuild_debug( "ecbuild_find_python: Found Python interpreter version ${PYTHON_VERSION_STRING} at ${PYTHON_EXECUTABLE}" )
+ # find where python site-packages are ...
+
+ if( PYTHON_EXECUTABLE )
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ ecbuild_debug( "ecbuild_find_python: PYTHON_SITE_PACKAGES=${PYTHON_SITE_PACKAGES}" )
+
+ endif()
+ if( PYTHONINTERP_FOUND AND NOT _p_NO_LIBS )
# find python config
if( PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE}-config )
- set(PYTHON_CONFIG ${PYTHON_EXECUTABLE}-config CACHE PATH "" FORCE)
+ set(PYTHON_CONFIG_EXECUTABLE ${PYTHON_EXECUTABLE}-config CACHE PATH "" FORCE)
else()
- find_program( PYTHON_CONFIG NAMES python-config python-config${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} )
+ find_program( PYTHON_CONFIG_EXECUTABLE NAMES python-config python-config${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} )
endif()
+ ecbuild_debug_var( PYTHON_CONFIG_EXECUTABLE )
+
# find python libs
- # The OpenBSD python packages have python-config's
+ # The OpenBSD python packages have python-config's
# that don't reliably report linking flags that will work.
-
- if( PYTHON_CONFIG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" )
- ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using ${PYTHON_CONFIG}" )
-
- execute_process(COMMAND "${PYTHON_CONFIG}" --ldflags
+
+ if( PYTHON_CONFIG_EXECUTABLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" )
+ ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using ${PYTHON_CONFIG_EXECUTABLE}" )
+
+ execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --ldflags
OUTPUT_VARIABLE PYTHON_LIBRARIES
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
- execute_process(COMMAND "${PYTHON_CONFIG}" --includes
- OUTPUT_VARIABLE PYTHON_INCLUDE_DIR
+ execute_process(COMMAND "${PYTHON_CONFIG_EXECUTABLE}" --includes
+ OUTPUT_VARIABLE PYTHON_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
- string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
- string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
-
- separate_arguments(PYTHON_INCLUDE_DIR)
+ string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
+ string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
+
+ separate_arguments(PYTHON_INCLUDE_DIRS)
else() # revert to finding pythonlibs the standard way (cmake macro)
ecbuild_debug( "ecbuild_find_python: Searching for Python include directories and libraries using find_package(PythonLibs)" )
-
+
find_package(PythonLibs)
- if( PYTHON_INCLUDE_PATH AND NOT PYTHON_INCLUDE_DIR )
- set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}")
+ if( PYTHON_INCLUDE_PATH AND NOT PYTHON_INCLUDE_DIRS )
+ set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_PATH}")
endif()
endif()
# Remove duplicate include directories
- list(REMOVE_DUPLICATES PYTHON_INCLUDE_DIR)
+ list(REMOVE_DUPLICATES PYTHON_INCLUDE_DIRS)
- # Test if we can link against the Python libraries and include Python.h
- try_compile( PYTHON_LIBS_WORKING ${CMAKE_CURRENT_BINARY_DIR}
- ${__test_python}
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${PYTHON_INCLUDE_DIR}"
- LINK_LIBRARIES ${PYTHON_LIBRARIES} )
- # set output variables
+ if( PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS )
+ # Test if we can link against the Python libraries and include Python.h
+ try_compile( PYTHON_LIBS_WORKING ${CMAKE_CURRENT_BINARY_DIR}
+ ${__test_python}
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${PYTHON_INCLUDE_DIRS}"
+ LINK_LIBRARIES ${PYTHON_LIBRARIES} )
- find_package_handle_standard_args( PythonLibs DEFAULT_MSG
- PYTHON_INCLUDE_DIR PYTHON_LIBRARIES PYTHON_LIBS_WORKING )
- ecbuild_debug( "ecbuild_find_python: PYTHON_INCLUDE_DIR=${PYTHON_INCLUDE_DIR}" )
- ecbuild_debug( "ecbuild_find_python: PYTHON_LIBRARIES=${PYTHON_LIBRARIES}" )
+ # set output variables
- set( PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR} )
- set( PYTHON_INCLUDE_PATH ${PYTHON_INCLUDE_DIR} )
+ find_package_handle_standard_args( PythonLibs DEFAULT_MSG
+ PYTHON_INCLUDE_DIRS PYTHON_LIBRARIES PYTHON_LIBS_WORKING )
+ ecbuild_debug( "ecbuild_find_python: PYTHON_INCLUDE_DIRS=${PYTHON_INCLUDE_DIRS}" )
+ ecbuild_debug( "ecbuild_find_python: PYTHON_LIBRARIES=${PYTHON_LIBRARIES}" )
+
+ endif()
# Also set PYTHON_FOUND and Python_FOUND for compatibility with ecbuild_add_option
if( PYTHONLIBS_FOUND )
@@ -160,18 +176,30 @@ macro( ecbuild_find_python )
set( Python_FOUND 1 )
endif()
- # find where python site-packages are ...
-
- execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
- ecbuild_debug( "ecbuild_find_python: PYTHON_SITE_PACKAGES=${PYTHON_SITE_PACKAGES}" )
-
endif()
-# debug_var( PYTHONINTERP_FOUND )
-# debug_var( PYTHON_EXECUTABLE )
-# debug_var( PYTHONLIBS_FOUND )
-# debug_var( PYTHON_INCLUDE_DIRS )
-# debug_var( PYTHON_LIBRARIES )
-# debug_var( PYTHON_SITE_PACKAGES )
-
-endmacro( ecbuild_find_python )
+ ecbuild_debug_var( PYTHONINTERP_FOUND )
+ ecbuild_debug_var( PYTHON_FOUND )
+ ecbuild_debug_var( PYTHON_EXECUTABLE )
+ ecbuild_debug_var( PYTHON_CONFIG_EXECUTABLE )
+ ecbuild_debug_var( PYTHON_VERSION_MAJOR )
+ ecbuild_debug_var( PYTHON_VERSION_MINOR )
+ ecbuild_debug_var( PYTHON_VERSION_PATCH )
+ ecbuild_debug_var( PYTHON_VERSION_STRING )
+ ecbuild_debug_var( PYTHON_INCLUDE_DIRS )
+ ecbuild_debug_var( PYTHON_LIBRARIES )
+ ecbuild_debug_var( PYTHON_SITE_PACKAGES )
+
+ set( PYTHONINTERP_FOUND ${PYTHONINTERP_FOUND} PARENT_SCOPE )
+ set( PYTHONLIBS_FOUND ${PYTHONLIBS_FOUND} PARENT_SCOPE )
+ set( PYTHON_FOUND ${PYTHON_FOUND} PARENT_SCOPE )
+ set( PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} PARENT_SCOPE )
+ set( PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} PARENT_SCOPE )
+ set( PYTHON_VERSION_MINOR ${PYTHON_VERSION_MINOR} PARENT_SCOPE )
+ set( PYTHON_VERSION_PATCH ${PYTHON_VERSION_PATCH} PARENT_SCOPE )
+ set( PYTHON_VERSION_STRING ${PYTHON_VERSION_STRING} PARENT_SCOPE )
+ set( PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} PARENT_SCOPE )
+ set( PYTHON_LIBRARIES ${PYTHON_LIBRARIES} PARENT_SCOPE )
+ set( PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES} PARENT_SCOPE )
+
+endfunction( ecbuild_find_python )
diff --git a/cmake/ecbuild_generate_config_headers.cmake b/cmake/ecbuild_generate_config_headers.cmake
index 53be8f3..930fa3a 100644
--- a/cmake/ecbuild_generate_config_headers.cmake
+++ b/cmake/ecbuild_generate_config_headers.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_generate_fortran_interfaces.cmake b/cmake/ecbuild_generate_fortran_interfaces.cmake
new file mode 100644
index 0000000..9c2045b
--- /dev/null
+++ b/cmake/ecbuild_generate_fortran_interfaces.cmake
@@ -0,0 +1,115 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_generate_fortran_interfaces
+# ===================================
+#
+# Generates interfaces form the Fortran source files. ::
+#
+# ecbuild_generate_fortran_interfaces()
+#
+# Options
+# -------
+#
+# TARGET : required
+# target name
+#
+##############################################################################
+
+function( ecbuild_generate_fortran_interfaces )
+
+ find_program( FCM_EXECUTABLE fcm REQUIRED DOC "Fortran interface generator" )
+
+ if( NOT FCM_EXECUTABLE )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: fcm executable not found." )
+ endif()
+
+ set( FCM_CONFIG_FILE "${PROJECT_SOURCE_DIR}/cmake/fcm-make-interfaces.cfg")
+
+ if( NOT EXISTS ${FCM_CONFIG_FILE} )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: needs fcm configuration in ${FCM_CONFIG_FILE}" )
+ endif()
+
+ set( options )
+ set( single_value_args TARGET DESTINATION PARALLEL INCLUDE_DIRS GENERATED SOURCE_DIR )
+ set( multi_value_args DIRECTORIES )
+
+ cmake_parse_arguments( P "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
+
+ if( NOT DEFINED P_TARGET )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: TARGET argument missing" )
+ endif()
+
+ if( NOT DEFINED P_DESTINATION )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: DESTINATION argument missing" )
+ endif()
+
+ if( NOT DEFINED P_DIRECTORIES )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: DIRECTORIES argument missing" )
+ endif()
+
+ if( NOT DEFINED P_PARALLEL OR (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") )
+ set( P_PARALLEL 1 )
+ endif()
+
+ if( NOT DEFINED P_SOURCE_DIR )
+ message( FATAL_ERROR "ecbuild_generate_fortran_interfaces: SOURCE_DIR argument missing")
+ endif()
+
+ foreach( _srcdir ${P_DIRECTORIES} )
+ if( _srcdir MATCHES "/$" )
+ ecbuild_critical("ecbuild_generate_fortran_interfaces: directory ${_srcdir} must not end with /")
+ endif()
+ ecbuild_list_add_pattern( LIST fortran_files SOURCE_DIR ${P_SOURCE_DIR} GLOB ${_srcdir}/*.F* )
+ endforeach()
+
+ string( REPLACE ";" " " _srcdirs "${P_DIRECTORIES}" )
+
+ set( _cnt 0 )
+ foreach( file ${_fortran_files} )
+ if( ${${SRC}/file} IS_NEWER_THAN ${${SRC}/file} )
+ set( run_fcm 1 )
+ endif()
+ endforeach()
+
+ foreach( fortran_file ${fortran_files} )
+ #list( APPEND fullpath_fortran_files ${CMAKE_CURRENT_SOURCE_DIR}/${fortran_file} )
+ get_filename_component(base ${fortran_file} NAME_WE)
+ set( interface_file "${CMAKE_CURRENT_BINARY_DIR}/interfaces/include/${base}.intfb.h" )
+ list( APPEND interface_files ${interface_file} )
+ set_source_files_properties( ${interface_file} PROPERTIES GENERATED TRUE )
+ math(EXPR _cnt "${_cnt}+1")
+ endforeach()
+
+ ecbuild_info("Target ${P_TARGET} will generate ${_cnt} interface files using FCM")
+
+ if( DEFINED P_GENERATED )
+ set( ${P_GENERATED} ${interface_files} PARENT_SCOPE )
+ endif()
+
+ set( include_dir ${CMAKE_CURRENT_BINARY_DIR}/${P_DESTINATION}/interfaces/include )
+ set( ${P_INCLUDE_DIRS} ${include_dir} PARENT_SCOPE )
+
+ execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${include_dir}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )
+
+ add_custom_command(
+ OUTPUT "${P_DESTINATION}/${P_TARGET}.timestamp"
+ COMMAND ${FCM_EXECUTABLE} make -j ${P_PARALLEL} --config-file=${FCM_CONFIG_FILE} interfaces.ns-incl=${_srcdirs} interfaces.source=${P_SOURCE_DIR}
+ COMMAND touch "${P_TARGET}.timestamp"
+ DEPENDS ${fortran_files}
+ COMMENT "Generating ${_cnt} interface files for target ${P_TARGET}"
+ WORKING_DIRECTORY ${P_DESTINATION} VERBATIM )
+
+ add_custom_target( ${P_TARGET} DEPENDS ${P_DESTINATION}/${P_TARGET}.timestamp )
+
+
+endfunction( ecbuild_generate_fortran_interfaces )
diff --git a/cmake/ecbuild_generate_rpc.cmake b/cmake/ecbuild_generate_rpc.cmake
index 19fd3eb..a2e3dd2 100644
--- a/cmake/ecbuild_generate_rpc.cmake
+++ b/cmake/ecbuild_generate_rpc.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_generate_yy.cmake b/cmake/ecbuild_generate_yy.cmake
index e686434..aba5620 100644
--- a/cmake/ecbuild_generate_yy.cmake
+++ b/cmake/ecbuild_generate_yy.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -19,6 +19,7 @@
# LEX <file>
# DEPENDANT <file1> [ <file2> ... ]
# [ SOURCE_DIR <dir> ]
+# [ OUTPUT_DIRECTORY <dir> ]
# [ YACC_TARGET <file> ]
# [ LEX_TARGET <file> ]
# [ YACC_FLAGS <flags> ]
@@ -45,6 +46,9 @@
# SOURCE_DIR : optional, defaults to CMAKE_CURRENT_SOURCE_DIR
# directory where yacc and lex source files are located
#
+# OUTPUT_DIRECTORY : optional, defaults to CMAKE_CURRENT_BINARY_DIR
+# output directory for yacc and lex target files
+#
# YACC_TARGET : optional, defaults to YACC
# base name of the generated yacc target file (without .c extension)
#
@@ -72,7 +76,7 @@ macro( ecbuild_generate_yy )
ecbuild_find_perl( REQUIRED )
set( options )
- set( single_value_args YYPREFIX YACC LEX SOURCE_DIR YACC_TARGET LEX_TARGET LEX_FLAGS YACC_FLAGS FLEX_FLAGS BISON_FLAGS )
+ set( single_value_args YYPREFIX YACC LEX SOURCE_DIR OUTPUT_DIRECTORY YACC_TARGET LEX_TARGET LEX_FLAGS YACC_FLAGS FLEX_FLAGS BISON_FLAGS )
set( multi_value_args DEPENDANT )
cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
@@ -125,19 +129,23 @@ macro( ecbuild_generate_yy )
set ( _PAR_LEX_TARGET ${_PAR_LEX} )
endif()
- set( ${BASE}yy_tmp_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_YACC_TARGET}.tmp.c )
- set( ${BASE}yh_tmp_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_YACC_TARGET}.tmp.h )
- set( ${BASE}yl_tmp_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_LEX_TARGET}.tmp.c )
-
- set( ${BASE}yy_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_YACC_TARGET}.c )
- set( ${BASE}yh_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_YACC_TARGET}.h )
- set( ${BASE}yl_target ${CMAKE_CURRENT_BINARY_DIR}/${_PAR_LEX_TARGET}.c )
-
if( NOT _PAR_SOURCE_DIR )
set( _PAR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
endif()
- add_custom_target( ${_PAR_YYPREFIX}_${DEPENDANT} SOURCES ${_PAR_SOURCE_DIR}/${_PAR_YACC}.y ${_PAR_SOURCE_DIR}/${_PAR_LEX}.l )
+ if( NOT _PAR_OUTPUT_DIRECTORY )
+ set( _PAR_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )
+ else()
+ file( MAKE_DIRECTORY ${_PAR_OUTPUT_DIRECTORY} )
+ endif()
+
+ set( ${BASE}yy_tmp_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_YACC_TARGET}.tmp.c )
+ set( ${BASE}yh_tmp_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_YACC_TARGET}.tmp.h )
+ set( ${BASE}yl_tmp_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_LEX_TARGET}.tmp.c )
+
+ set( ${BASE}yy_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_YACC_TARGET}.c )
+ set( ${BASE}yh_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_YACC_TARGET}.h )
+ set( ${BASE}yl_target ${_PAR_OUTPUT_DIRECTORY}/${_PAR_LEX_TARGET}.c )
if( BISON_FOUND )
bison_target( ${BASE}_parser ${_PAR_SOURCE_DIR}/${_PAR_YACC}.y ${${BASE}yy_tmp_target} COMPILE_FLAGS "${_PAR_BISON_FLAGS}" )
diff --git a/cmake/ecbuild_get_cxx11_flags.cmake b/cmake/ecbuild_get_cxx11_flags.cmake
index 5bfed07..bd7d0e8 100644
--- a/cmake/ecbuild_get_cxx11_flags.cmake
+++ b/cmake/ecbuild_get_cxx11_flags.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_get_date.cmake b/cmake/ecbuild_get_date.cmake
index 8c24623..7a35a0c 100644
--- a/cmake/ecbuild_get_date.cmake
+++ b/cmake/ecbuild_get_date.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_get_resources.cmake b/cmake/ecbuild_get_resources.cmake
index bf48ecf..4dc4957 100644
--- a/cmake/ecbuild_get_resources.cmake
+++ b/cmake/ecbuild_get_resources.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -29,7 +29,7 @@ macro( ecbuild_get_resources )
if( NOT _PAR_TO_DIR )
set( _PAR_TO_DIR ${CMAKE_CURRENT_BINARY_DIR} )
endif()
-
+
list( LENGTH _PAR_LIST _rsize )
math( EXPR _max "${_rsize}-1" )
foreach( i RANGE 0 ${_max} 2 )
@@ -39,14 +39,14 @@ macro( ecbuild_get_resources )
list( GET _PAR_LIST ${i} r )
list( GET _PAR_LIST ${in} rh )
-# debug_var( r )
-# debug_var( rh )
+# ecbuild_debug_var( r )
+# ecbuild_debug_var( rh )
get_filename_component( rf ${r} NAME )
file( DOWNLOAD ${r} ${_PAR_TO_DIR}/${rf} EXPECTED_HASH SHA1=${rh} )
endforeach()
-
+
endmacro()
diff --git a/cmake/ecbuild_get_test_data.cmake b/cmake/ecbuild_get_test_data.cmake
index ee585ca..9c1e18b 100644
--- a/cmake/ecbuild_get_test_data.cmake
+++ b/cmake/ecbuild_get_test_data.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -151,10 +151,10 @@ function( ecbuild_get_test_data )
set( _p_DIRNAME ${PROJECT_NAME}/${currdir} )
endif()
-# debug_var( _p_TARGET )
-# debug_var( _p_NAME )
-# debug_var( _p_URL )
-# debug_var( _p_DIRNAME )
+# ecbuild_debug_var( _p_TARGET )
+# ecbuild_debug_var( _p_NAME )
+# ecbuild_debug_var( _p_URL )
+# ecbuild_debug_var( _p_DIRNAME )
# download the data
@@ -326,9 +326,9 @@ function( ecbuild_get_test_multidata )
message(FATAL_ERROR "ecbuild_get_test_data() expects a TARGET")
endif()
-# debug_var( _p_TARGET )
-# debug_var( _p_NAME )
-# debug_var( _p_DIRNAME )
+# ecbuild_debug_var( _p_TARGET )
+# ecbuild_debug_var( _p_NAME )
+# ecbuild_debug_var( _p_DIRNAME )
if( _p_EXTRACT )
set( _extract EXTRACT )
@@ -358,12 +358,11 @@ endfunction()\n\n" )
get_filename_component( _dir ${_f} PATH )
list( APPEND _path_comps ${_p_DIRNAME} ${_dir} )
-
join( _path_comps "/" _dirname )
-
if( _dirname )
set( _dirname DIRNAME ${_dirname} )
endif()
+ unset( _path_comps )
string( REPLACE "." "_" _name "${_file}" )
string( REGEX MATCH ":.*" _md5 "${_d}" )
@@ -373,11 +372,11 @@ endfunction()\n\n" )
set( _md5 MD5 ${_md5} )
endif()
- #debug_var(_f)
- #debug_var(_file)
- #debug_var(_dirname)
- #debug_var(_name)
- #debug_var(_md5)
+ #ecbuild_debug_var(_f)
+ #ecbuild_debug_var(_file)
+ #ecbuild_debug_var(_dirname)
+ #ecbuild_debug_var(_name)
+ #ecbuild_debug_var(_md5)
ecbuild_get_test_data(
TARGET __get_data_${_p_TARGET}_${_name}
diff --git a/cmake/ecbuild_git.cmake b/cmake/ecbuild_git.cmake
index 42124db..b20e895 100644
--- a/cmake/ecbuild_git.cmake
+++ b/cmake/ecbuild_git.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -8,6 +8,8 @@
set( ECBUILD_GIT ON CACHE BOOL "Turn on/off ecbuild_git() function" )
+mark_as_advanced(ECBUILD_GIT)
+
if( ECBUILD_GIT )
find_package(Git)
@@ -106,7 +108,7 @@ macro( ecbuild_git )
RESULT_VARIABLE nok ERROR_VARIABLE error
WORKING_DIRECTORY "${PARENT_DIR}")
if(nok)
- message(FATAL_ERROR "${_PAR_DIR} git clone failed: ${error}\n")
+ message(FATAL_ERROR "${_PAR_DIR} git clone failed:\n ${GIT_EXECUTABLE} clone ${_PAR_URL} ${clone_args} ${_PAR_DIR} -q\n ${error}\n")
endif()
message( STATUS "${_PAR_DIR} retrieved.")
set( _needs_switch 1 )
@@ -133,7 +135,6 @@ macro( ecbuild_git )
message(STATUS "git rev-parse --abbrev-ref HEAD on ${_PAR_DIR} failed:\n ${error}")
endif()
- #message(STATUS "git describe --exact-match --abbrev=0 @ ${ABS_PAR_DIR}")
execute_process( COMMAND ${GIT_EXECUTABLE} describe --exact-match --abbrev=0
OUTPUT_VARIABLE _current_tag RESULT_VARIABLE nok ERROR_VARIABLE error
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE
@@ -148,7 +149,6 @@ macro( ecbuild_git )
endif()
if( NOT _current_tag ) # try nother method
- #message(STATUS "git name-rev --tags --name-only @ ${ABS_PAR_DIR}")
execute_process( COMMAND ${GIT_EXECUTABLE} name-rev --tags --name-only ${_sha1}
OUTPUT_VARIABLE _current_tag RESULT_VARIABLE nok ERROR_VARIABLE error
OUTPUT_STRIP_TRAILING_WHITESPACE
@@ -231,7 +231,7 @@ macro( ecbuild_git )
RESULT_VARIABLE nok ERROR_VARIABLE error
WORKING_DIRECTORY "${ABS_PAR_DIR}")
if(nok)
- message(FATAL_ERROR "git checkout ${_gitref} on ${_PAR_DIR} failed:\n ${error}")
+ message(FATAL_ERROR "git checkout ${_gitref} on ${_PAR_DIR} failed:\n ${GIT_EXECUTABLE} checkout -q ${_gitref}\n ${error}")
endif()
if( DEFINED _PAR_BRANCH AND _PAR_UPDATE ) #############################################################################
diff --git a/cmake/ecbuild_install_project.cmake b/cmake/ecbuild_install_project.cmake
index a7d84a4..8c21d7a 100644
--- a/cmake/ecbuild_install_project.cmake
+++ b/cmake/ecbuild_install_project.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -33,7 +33,7 @@
# the project with cpack and exports the configuration and targets for other
# projects to use.
#
-# In a top-level project, the following files are generated:
+# Unless ECBUILD_SKIP_<PNAME>_EXPORT is set, the following files are generated:
#
# :<project>-config.cmake: default project configuration
# :<project>-config-version.cmake: project version number
@@ -49,7 +49,7 @@
# and ``<project>-config-version.cmake``.
#
# In DEVELOPER_MODE, the build tree location is also added to the CMake user
-# package registry.
+# package registry for top level projects.
#
# If the project is added as a subdirectory, the following CMake variables
# are set in the parent scope:
@@ -70,7 +70,6 @@
#
##############################################################################
-
macro( ecbuild_install_project )
set( options )
@@ -87,6 +86,17 @@ macro( ecbuild_install_project )
message(FATAL_ERROR "The call to ecbuild_install_project() doesn't specify the NAME.")
endif()
+ ### EXTRA TARGETS #####################################################
+
+ # added here to avoid adding another macro call at the end of each project,
+
+ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
+
+ ecbuild_define_libs_and_execs_targets()
+ ecbuild_define_links_target()
+
+ endif()
+
### PACKAGING ########################################################
set( PNAME ${PROJECT_NAME_CAPS} )
@@ -160,6 +170,8 @@ macro( ecbuild_install_project )
PATHS ${ECBUILD_MACROS_DIR}/../toolchains
${ECBUILD_MACROS_DIR}/../share/ecbuild/toolchains )
+ mark_as_advanced( ECBUILD_TOOLCHAIN_DIR )
+
if( ECBUILD_TOOLCHAIN_DIR )
list( APPEND CPACK_SOURCE_INSTALLED_DIRECTORIES "${ECBUILD_TOOLCHAIN_DIR}" "share/ecbuild/toolchains/" )
endif()
@@ -169,6 +181,8 @@ macro( ecbuild_install_project )
PATHS ${ECBUILD_MACROS_DIR}/../bin
${ECBUILD_MACROS_DIR}/../../../bin )
+ mark_as_advanced( ECBUILD_SCRIPT )
+
if( ECBUILD_SCRIPT )
get_filename_component( ECBUILD_BIN_DIR ${ECBUILD_SCRIPT} PATH )
list( APPEND CPACK_SOURCE_INSTALLED_DIRECTORIES "${ECBUILD_BIN_DIR}" "bin/" )
@@ -219,16 +233,9 @@ macro( ecbuild_install_project )
endif()
endforeach()
- # TOP-LEVEL PROJECT EXPORT
-
- if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
-
- # exports the package for use from the build-tree but only in DEVELOPER_MODE
- # inserts <package> into the CMake user package registry
-
- if( DEVELOPER_MODE )
- export( PACKAGE ${PROJECT_NAME} )
- endif()
+ # Generate the project .cmake config files
+ # All variables here must be (sub)project specific in order to work within bundles
+ if ( NOT ECBUILD_SKIP_${PNAME}_EXPORT )
set( _template_config "${ECBUILD_MACROS_DIR}/project-config.cmake.in" )
if( EXISTS ${LNAME}-config.cmake.in )
@@ -242,7 +249,9 @@ macro( ecbuild_install_project )
# project-config-version.cmake -- format ([0-9]+).([0-9]+).([0-9]+)
- set( PACKAGE_VERSION "${${PNAME}_VERSION}" )
+ set( PACKAGE_VERSION "${${PNAME}_VERSION}" )
+ set( PACKAGE_GIT_SHA1 "${${PNAME}_GIT_SHA1}" )
+ set( PACKAGE_GIT_SHA1_SHORT "${${PNAME}_GIT_SHA1_SHORT}" )
configure_file( "${_template_config_version}" "${PROJECT_BINARY_DIR}/${LNAME}-config-version.cmake" @ONLY )
@@ -297,6 +306,7 @@ macro( ecbuild_install_project )
# If <project>-import.cmake.in exist in source tree, configure it to
# the build tree and install the configured version
if( EXISTS "${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}.in" )
+ ecbuild_debug( "Found ${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}.in - configuring to ${PROJECT_BINARY_DIR}/${CONF_IMPORT_FILE}" )
configure_file( "${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}.in"
"${PROJECT_BINARY_DIR}/${CONF_IMPORT_FILE}" @ONLY )
install( FILES "${PROJECT_BINARY_DIR}/${CONF_IMPORT_FILE}"
@@ -304,10 +314,13 @@ macro( ecbuild_install_project )
# Otherwise, if <project>-import.cmake exist in source tree, copy it to
# the build tree and install it
elseif( EXISTS "${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}" )
+ ecbuild_debug( "Found ${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE} - copying to ${PROJECT_BINARY_DIR}/${CONF_IMPORT_FILE}" )
configure_file( "${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}"
"${PROJECT_BINARY_DIR}/${CONF_IMPORT_FILE}" COPYONLY )
install( FILES "${PROJECT_SOURCE_DIR}/${CONF_IMPORT_FILE}"
DESTINATION "${INSTALL_CMAKE_DIR}" )
+ else()
+ ecbuild_debug( "No ${CONF_IMPORT_FILE} found in ${PROJECT_SOURCE_DIR}" )
endif()
set( _lname_config "${PROJECT_BINARY_DIR}/${LNAME}-config.cmake")
@@ -318,13 +331,28 @@ macro( ecbuild_install_project )
file( REMOVE ${_lname_config}.tpls.in )
foreach( _tpl ${${PNAME}_TPLS} )
+
string( TOUPPER ${_tpl} TPL )
- if( ${TPL}_IMPORT_FILE )
+
+ if( ${TPL}_IMPORT_FILE ) # ecBuild packages should trigger this if they export themselves
+
+ ecbuild_debug( "Adding TPL ${TPL} import file to ${_lname_config}.tpls.in" )
set( __import_file "${${TPL}_IMPORT_FILE}" )
file( APPEND "${_lname_config}.tpls.in" "if( NOT ${TPL}_IMPORT_FILE )\n" )
file( APPEND "${_lname_config}.tpls.in" " include( \"${__import_file}\" OPTIONAL )\n" )
file( APPEND "${_lname_config}.tpls.in" "endif()\n" )
+
+ elseif( ${TPL}_CONFIG ) # cmake built packages (e.g. CGAL) may have exported their targets
+
+ ecbuild_debug( "Adding TPL ${TPL} import file to ${_lname_config}.tpls.in" )
+ set( __import_file "${${TPL}_CONFIG}" )
+ file( APPEND "${_lname_config}.tpls.in" "if( NOT ${TPL}_CONFIG )\n" )
+ file( APPEND "${_lname_config}.tpls.in" " include( \"${__import_file}\" OPTIONAL )\n" )
+ file( APPEND "${_lname_config}.tpls.in" " set( ${TPL}_CONFIG \"${__import_file}\" )\n" )
+ file( APPEND "${_lname_config}.tpls.in" "endif()\n" )
+
endif()
+
endforeach()
if( EXISTS "${_lname_config}.tpls.in" )
@@ -361,14 +389,30 @@ macro( ecbuild_install_project )
# install the export
if( ${PROJECT_NAME}_ALL_EXES OR ${PROJECT_NAME}_ALL_LIBS )
- install( EXPORT ${CMAKE_PROJECT_NAME}-targets DESTINATION "${INSTALL_CMAKE_DIR}" )
+ install( EXPORT ${PROJECT_NAME}-targets
+ DESTINATION "${INSTALL_CMAKE_DIR}" )
+ endif()
+
+ endif() # if ( NOT ECBUILD_SKIP_${PNAME}_EXPORT )
+
+ # exports the package for use from the build-tree but only in DEVELOPER_MODE
+ # inserts <package> into the CMake user package registry
+
+ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
+
+ if( DEVELOPER_MODE )
+ export( PACKAGE ${PROJECT_NAME} )
endif()
else()
+ # export variables for upper projects
+
set( ${PNAME}_FOUND TRUE PARENT_SCOPE )
set( ${PROJECT_NAME}_FOUND TRUE PARENT_SCOPE )
set( ${PNAME}_VERSION ${${PNAME}_VERSION} PARENT_SCOPE )
+ set( ${PNAME}_GIT_SHA1 ${${PNAME}_GIT_SHA1} PARENT_SCOPE )
+ set( ${PNAME}_GIT_SHA1_SHORT ${${PNAME}_GIT_SHA1_SHORT} PARENT_SCOPE )
set( ${PROJECT_NAME}_VERSION ${${PNAME}_VERSION} PARENT_SCOPE )
set( ${PNAME}_INCLUDE_DIRS ${${PNAME}_INCLUDE_DIRS} PARENT_SCOPE )
set( ${PNAME}_LIBRARIES ${${PNAME}_LIBRARIES} PARENT_SCOPE )
@@ -382,6 +426,7 @@ macro( ecbuild_install_project )
foreach( _f ${${PNAME}_FEATURES} )
set( ${PNAME}_HAVE_${_f} ${${PNAME}_HAVE_${_f}} PARENT_SCOPE )
endforeach()
- endif()
+
+ endif()
endmacro( ecbuild_install_project )
diff --git a/cmake/ecbuild_list_add_pattern.cmake b/cmake/ecbuild_list_add_pattern.cmake
new file mode 100644
index 0000000..0f68217
--- /dev/null
+++ b/cmake/ecbuild_list_add_pattern.cmake
@@ -0,0 +1,102 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_list_add_pattern
+# ========================
+#
+# Exclude items from a list that match a list of patterns. ::
+#
+# ecbuild_list_add_pattern( LIST <input_list>
+# GLOB <pattern1> [ <pattern2> ... ]
+# [ SOURCE_DIR <source_dir> ]
+# [ QUIET ] )
+#
+# Options
+# -------
+#
+# LIST : required
+# list variable to be appended to
+#
+# GLOB : required
+# Regex pattern of exclusion
+#
+# SOURCE_DIR : optional
+# Directory from where to start search
+#
+# QUIET : optional
+# Don't warn if patterns don't match
+#
+##############################################################################
+
+function( ecbuild_list_add_pattern )
+
+ set( options QUIET )
+ set( single_value_args LIST SOURCE_DIR )
+ set( multi_value_args GLOB )
+
+ cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
+
+ if(_p_UNPARSED_ARGUMENTS)
+ ecbuild_critical("Unknown keywords given to ecbuild_list_add_pattern(): \"${_p_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if( NOT _p_LIST )
+ ecbuild_critical("The call to ecbuild_list_add_pattern() doesn't specify the LIST.")
+ endif()
+
+ if( NOT _p_GLOB )
+ ecbuild_critical("The call to ecbuild_list_add_pattern() doesn't specify the GLOB.")
+ endif()
+
+ #####
+
+ set( input_list ${${_p_LIST}} )
+ unset( matched_files )
+
+ foreach( pattern ${_p_GLOB} )
+
+ if( IS_ABSOLUTE ${pattern} )
+ ecbuild_debug( "ecbuild_list_add_pattern: Adding ${pattern}" )
+ file( GLOB_RECURSE matched_files ${pattern} )
+ else()
+
+ if(_p_SOURCE_DIR)
+ if( IS_ABSOLUTE ${_p_SOURCE_DIR} )
+ ecbuild_debug( "ecbuild_list_add_pattern: Adding ${_p_SOURCE_DIR}/${pattern}" )
+ file( GLOB_RECURSE matched_files ${_p_SOURCE_DIR}/${pattern} )
+ else()
+ ecbuild_debug( "ecbuild_list_add_pattern: Adding ${_p_SOURCE_DIR}/${pattern}" )
+ file( GLOB_RECURSE matched_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${_p_SOURCE_DIR}/${pattern} )
+ endif()
+ else()
+ ecbuild_debug( "ecbuild_list_add_pattern: Adding ${pattern} ")
+ file( GLOB_RECURSE matched_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${pattern} )
+ endif()
+
+ endif()
+
+ if(matched_files)
+ ecbuild_debug( "ecbuild_list_add_pattern: Found ${matched_files}" )
+ list( APPEND input_list ${matched_files} )
+ list( REMOVE_DUPLICATES input_list )
+ set( ${_p_LIST} ${input_list} PARENT_SCOPE )
+ else()
+ if(NOT _p_QUIET)
+ ecbuild_warn( "ecbuild_list_add_pattern: no matches found for patterns ${pattern}" )
+ else()
+ ecbuild_debug( "ecbuild_list_add_pattern:no matches found for patterns ${pattern}" )
+ endif()
+ endif()
+
+ endforeach()
+
+
+endfunction(ecbuild_list_add_pattern)
diff --git a/cmake/ecbuild_list_exclude_pattern.cmake b/cmake/ecbuild_list_exclude_pattern.cmake
new file mode 100644
index 0000000..ab9c2d9
--- /dev/null
+++ b/cmake/ecbuild_list_exclude_pattern.cmake
@@ -0,0 +1,88 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation nor
+# does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_list_exclude_pattern
+# ============================
+#
+# Exclude items from a list that match a list of patterns. ::
+#
+# ecbuild_list_exclude_pattern( LIST <input_list>
+# REGEX <regex1> [ <regex2> ... ]
+# [ QUIET ] )
+#
+# Options
+# -------
+#
+# LIST : required
+# list variable to be cleaned
+#
+# REGEX : required
+# Regex pattern of exclusions
+#
+# QUIET : optional
+# Don't warn if patterns don't match
+#
+##############################################################################
+
+function( ecbuild_list_exclude_pattern )
+
+ set( options QUIET )
+ set( single_value_args LIST )
+ set( multi_value_args REGEX )
+
+ cmake_parse_arguments( _p "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
+
+ if(_p_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to ecbuild_list_exclude_pattern(): \"${_p_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if( NOT _p_LIST )
+ message(FATAL_ERROR "The call to ecbuild_list_exclude_pattern() doesn't specify the LIST.")
+ endif()
+
+ if( NOT _p_REGEX )
+ message(FATAL_ERROR "The call to ecbuild_list_exclude_pattern() doesn't specify the REGEX.")
+ endif()
+
+ #####
+
+ set( result "" )
+ set( matches_found 0 )
+
+ # ecbuild_debug_var(_p_REGEX)
+
+ foreach( item ${${_p_LIST}} )
+
+ set( _keep 1 )
+
+ foreach( pattern ${_p_REGEX} )
+ if( ${item} MATCHES ${pattern} )
+ set( _keep 0 )
+ set( matches_found 1 )
+ endif()
+ endforeach()
+ if( _keep )
+ list( APPEND result ${item} )
+# else()
+# ecbuild_warn( "removing ${item}" )
+ endif()
+
+ endforeach()
+
+ if( matches_found )
+ set( ${_p_LIST} ${result} PARENT_SCOPE )
+ else()
+ if( NOT _p_QUIET )
+ ecbuild_warn( "ecbuild_list_exclude_pattern: no matches found for patterns ${_p_REGEX} in ${_p_LIST}" )
+ endif()
+ endif()
+
+endfunction(ecbuild_list_exclude_pattern)
diff --git a/cmake/ecbuild_list_extra_search_paths.cmake b/cmake/ecbuild_list_extra_search_paths.cmake
index 719b1e7..b81f062 100644
--- a/cmake/ecbuild_list_extra_search_paths.cmake
+++ b/cmake/ecbuild_list_extra_search_paths.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -14,11 +14,11 @@
function( ecbuild_list_extra_search_paths pkg var )
- message( DEPRECATION " ecbuild_list_extra_search_paths should no longer be"
- " used and is going to be removed in a future version of ecBuild." )
+ ecbuild_deprecate( " ecbuild_list_extra_search_paths should no longer be"
+ " used and is going to be removed in a future version of ecBuild." )
- # debug_var( pkg )
- # debug_var( var )
+ # ecbuild_debug_var( pkg )
+ # ecbuild_debug_var( var )
string( TOUPPER ${pkg} _PKG )
@@ -75,7 +75,7 @@ function( ecbuild_list_extra_search_paths pkg var )
ecbuild_debug("ecbuild_list_extra_search_paths(${pkg}): setting ${var} to ${${var}}")
set( ${var} ${${var}} PARENT_SCOPE )
-# debug_var( ${var} )
+# ecbuild_debug_var( ${var} )
endfunction()
diff --git a/cmake/ecbuild_list_macros.cmake b/cmake/ecbuild_list_macros.cmake
index fcfc815..176a161 100644
--- a/cmake/ecbuild_list_macros.cmake
+++ b/cmake/ecbuild_list_macros.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -56,35 +56,3 @@ function( MAP_GET _map _key _var )
set( ${_var} "${_${_map}_${_key}}" PARENT_SCOPE )
endfunction(MAP_GET)
-##############################################################################
-# function to remove items from a list that match a list of patterns
-#
-# examples:
-#
-# ecbuild_list_remove_pattern( mylist "foo;bar" VAR )
-#
-
-function(ecbuild_list_remove_pattern _list _patterns _var)
-
-#debug_var( _list )
-#debug_var( _patterns )
-#debug_var( _var )
-
- foreach( _elem ${_list} )
- set( _keep TRUE)
- foreach( _pat ${_patterns} )
- if( ${_elem} MATCHES ${_pat} )
- set( _keep FALSE)
- endif()
- endforeach()
- if( _keep )
- list( APPEND _result ${_elem} )
- endif()
-
- endforeach()
-
-#debug_var( _result )
-
- set( ${_var} "${_result}" PARENT_SCOPE )
-
-endfunction(ecbuild_list_remove_pattern)
diff --git a/cmake/ecbuild_log.cmake b/cmake/ecbuild_log.cmake
index fbb2349..732040b 100644
--- a/cmake/ecbuild_log.cmake
+++ b/cmake/ecbuild_log.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -15,11 +15,12 @@
# ecBuild provides macros for logging based on a log level set by the user,
# similar to the Python logging module:
#
-# :ecbuild_debug: logs a ``STATUS`` message if log level <= ``DEBUG``
-# :ecbuild_info: logs a ``STATUS`` message if log level <= ``INFO``
-# :ecbuild_warn: logs a ``WARNING`` message if log level <= ``WARN``
-# :ecbuild_error: logs a ``SEND_ERROR`` message if log level <= ``ERROR``
-# :ecbuild_critical: logs a ``FATAL_ERROR`` message if log level <= ``CRITICAL``
+# :ecbuild_debug: logs a ``STATUS`` message if log level <= ``DEBUG``
+# :ecbuild_info: logs a ``STATUS`` message if log level <= ``INFO``
+# :ecbuild_warn: logs a ``WARNING`` message if log level <= ``WARN``
+# :ecbuild_error: logs a ``SEND_ERROR`` message if log level <= ``ERROR``
+# :ecbuild_critical: logs a ``FATAL_ERROR`` message if log level <= ``CRITICAL``
+# :ecbuild_deprecate: logs a ``DEPRECATION`` message
#
# Input variables
# ---------------
@@ -32,6 +33,10 @@
# ECBUILD_NO_COLOUR : bool
# if set, does not colour log output (by default log output is coloured)
#
+# ECBUILD_NO_DEPRECATIONS : bool
+# if set, does not output deprecation messages (only set this if you *really*
+# know what you are doing!)
+#
# Usage
# -----
#
@@ -70,7 +75,7 @@ set(ECBUILD_ERROR 40)
set(ECBUILD_CRITICAL 50)
if( NOT DEFINED ECBUILD_LOG_LEVEL )
- set(ECBUILD_LOG_LEVEL ${ECBUILD_WARN})
+ set(ECBUILD_LOG_LEVEL ${ECBUILD_INFO})
elseif( NOT ECBUILD_LOG_LEVEL )
set(ECBUILD_LOG_LEVEL 60)
elseif( ECBUILD_LOG_LEVEL STREQUAL "DEBUG" )
@@ -122,8 +127,81 @@ endmacro( ecbuild_error )
##############################################################################
+macro( ecbuild_deprecate )
+ if( NOT ECBUILD_NO_DEPRECATIONS )
+ string(REPLACE ";" "" MSG ${ARGV})
+ message(DEPRECATION "${BoldRed}${MSG}${ColourReset}")
+ endif()
+endmacro( ecbuild_deprecate )
+
+##############################################################################
+
macro( ecbuild_critical MSG )
if( ECBUILD_LOG_LEVEL LESS 51)
message(FATAL_ERROR "${BoldMagenta}CRITICAL - ${MSG}${ColourReset}")
endif()
endmacro( ecbuild_critical )
+
+##############################################################################
+# macro for debugging a cmake variable
+
+macro( ecbuild_debug_var VAR )
+ if( ECBUILD_LOG_LEVEL LESS 11)
+ message(STATUS "${Blue}DEBUG - ${VAR} : ${${VAR}}${ColourReset}")
+ endif()
+endmacro()
+
+##############################################################################
+# macro for debugging a cmake variable
+
+macro( ecbuild_debug_list VAR )
+ if( ECBUILD_LOG_LEVEL LESS 11)
+ message( STATUS "${Blue}DEBUG - ${VAR}" )
+ foreach( _elem ${${VAR}} )
+ message( STATUS " ${_elem}" )
+ endforeach()
+ message(STATUS "${ColourReset}")
+ endif()
+endmacro()
+
+##############################################################################
+# macro for debugging a environment variable within cmake
+
+macro( ecbuild_debug_env_var VAR )
+ if( ECBUILD_LOG_LEVEL LESS 11)
+ message(STATUS "${Blue}DEBUG - ENV ${VAR} [$ENV{${VAR}}]${ColourReset}")
+ endif()
+endmacro()
+
+##############################################################################
+# macro for debugging a cmake variable
+
+macro( debug_var VAR )
+
+ message( WARNING "DEPRECATED debug_var() -- ${VAR} [${${VAR}}]" )
+
+endmacro()
+
+##############################################################################
+# macro for debugging a cmake list
+
+macro( debug_list VAR )
+
+ message( WARNING "DEPRECATED debug_list() -- ${VAR}:" )
+ foreach( _elem ${${VAR}} )
+ message( WARNING " ${_elem}" )
+ endforeach()
+
+endmacro()
+
+##############################################################################
+# macro for debugging a environment variable within cmake
+
+macro( debug_env_var VAR )
+
+ message( WARNING "DEPRECATED debug_env_var() -- ENV ${VAR} [$ENV{${VAR}}]" )
+
+endmacro()
+
+
+
diff --git a/cmake/ecbuild_pkgconfig.cmake b/cmake/ecbuild_pkgconfig.cmake
index 5bcca33..744727e 100644
--- a/cmake/ecbuild_pkgconfig.cmake
+++ b/cmake/ecbuild_pkgconfig.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_policies.cmake b/cmake/ecbuild_policies.cmake
index 06f856b..36ab7fe 100644
--- a/cmake/ecbuild_policies.cmake
+++ b/cmake/ecbuild_policies.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2015 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -6,13 +6,17 @@
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
-###############################################################################
-# define cmake policies
+##############################################################################
+#
+# ecBuild Policies
+# ================
#
# NOTE: This file needs to be included with NO_POLICY_SCOPE or it will have no
# effect!
# NOTE: Policies 1 through 17 will be set to NEW by requiring CMake 2.8.4 i.e.
# calling cmake_minimum_required( VERSION 2.8.4 FATAL_ERROR )
+#
+##############################################################################
# allow for empty spaces around library names
if( POLICY CMP0004 )
diff --git a/cmake/ecbuild_print_summary.cmake b/cmake/ecbuild_print_summary.cmake
index b3cddf0..83f4f9c 100644
--- a/cmake/ecbuild_print_summary.cmake
+++ b/cmake/ecbuild_print_summary.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -38,8 +38,6 @@ macro( ecbuild_print_summary )
if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
- ecbuild_define_links_target()
-
get_property( langs GLOBAL PROPERTY ENABLED_LANGUAGES )
message( STATUS "---------------------------------------------------------" )
@@ -89,7 +87,7 @@ macro( ecbuild_print_summary )
### FEATURE SUMMARY
- # debug_var( CMAKE_VERSION )
+ # ecbuild_debug_var( CMAKE_VERSION )
if( ${CMAKE_VERSION} VERSION_LESS "2.8.6" )
feature_summary( WHAT ALL )
else()
@@ -101,6 +99,6 @@ macro( ecbuild_print_summary )
# issue warnings / errors in case there are unused project files
ecbuild_warn_unused_files()
- endif( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
+ endif()
endmacro( ecbuild_print_summary )
diff --git a/cmake/ecbuild_project_files.cmake b/cmake/ecbuild_project_files.cmake
index 162a625..7e3789b 100644
--- a/cmake/ecbuild_project_files.cmake
+++ b/cmake/ecbuild_project_files.cmake
@@ -1,8 +1,8 @@
-# (C) Copyright 1996-2014 ECMWF.
-#
+# (C) Copyright 1996-2016 ECMWF.
+#
# This software is licensed under the terms of the Apache Licence Version 2.0
-# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
-# In applying this licence, ECMWF does not waive the privileges and immunities
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
@@ -50,7 +50,7 @@ macro( ecbuild_declare_project_files )
if( CHECK_UNUSED_FILES )
foreach( _afile ${ARGV} )
- # debug_var( _afile )
+ # ecbuild_debug_var( _afile )
get_property( _src_gen SOURCE ${_afile} PROPERTY GENERATED )
diff --git a/cmake/ecbuild_remove_fortran_flags.cmake b/cmake/ecbuild_remove_fortran_flags.cmake
new file mode 100644
index 0000000..74c8832
--- /dev/null
+++ b/cmake/ecbuild_remove_fortran_flags.cmake
@@ -0,0 +1,61 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+##############################################################################
+#.rst:
+#
+# ecbuild_remove_fortran_flags
+# =========================
+#
+# Remove Fortran compiler flags from CMAKE_Fortran_FLAGS. ::
+#
+# ecbuild_remove_fortran_flags( <flag1> [ <flag2> ... ] [ BUILD <build> ] )
+#
+# Options
+# -------
+#
+# BUILD : optional
+# remove flags from ``CMAKE_Fortran_FLAGS_<build>`` instead of
+# ``CMAKE_Fortran_FLAGS``
+#
+##############################################################################
+
+include( CheckFortranCompilerFlag )
+macro( ecbuild_remove_fortran_flags m_flags )
+
+ set( _flags ${m_flags} )
+ if( _flags AND CMAKE_Fortran_COMPILER_LOADED )
+
+ set( single_value_args BUILD )
+ set( multi_value_args )
+ cmake_parse_arguments( _PAR "" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} )
+
+ string( TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_CAPS )
+ string( TOUPPER ${_PAR_BUILD} _PAR_BUILD_CAPS )
+
+ if( _PAR_BUILD AND (CMAKE_BUILD_TYPE_CAPS MATCHES "${_PAR_BUILD_CAPS}") )
+
+ foreach( _flag ${_flags} )
+ string(REGEX REPLACE " *${_flag} *" " " CMAKE_Fortran_FLAGS_${_PAR_BUILD} ${CMAKE_Fortran_FLAGS_${_PAR_BUILD}})
+ ecbuild_debug( "Fortran FLAG [${_flag}] removed from build type ${_PAR_BUILD}" )
+ endforeach()
+
+ elseif( NOT _PAR_BUILD )
+
+ foreach( _flag ${_flags} )
+ string(REGEX REPLACE " *${_flag} *" " " CMAKE_Fortran_FLAGS ${CMAKE_Fortran_FLAGS} )
+ ecbuild_debug( "Fortran FLAG [${_flag}] removed" )
+ endforeach()
+
+ endif()
+
+ endif()
+ unset( _flags )
+
+endmacro()
+
diff --git a/cmake/ecbuild_requires_macro_version.cmake b/cmake/ecbuild_requires_macro_version.cmake
index 6c73fe7..e395ff0 100644
--- a/cmake/ecbuild_requires_macro_version.cmake
+++ b/cmake/ecbuild_requires_macro_version.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_separate_sources.cmake b/cmake/ecbuild_separate_sources.cmake
index 94aa182..a0a1c9b 100644
--- a/cmake/ecbuild_separate_sources.cmake
+++ b/cmake/ecbuild_separate_sources.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -83,9 +83,9 @@ macro( ecbuild_separate_sources )
endif()
endforeach()
-# debug_var( ${_PAR_TARGET}_h_srcs )
-# debug_var( ${_PAR_TARGET}_c_srcs )
-# debug_var( ${_PAR_TARGET}_cxx_srcs )
-# debug_var( ${_PAR_TARGET}_f_srcs )
+# ecbuild_debug_var( ${_PAR_TARGET}_h_srcs )
+# ecbuild_debug_var( ${_PAR_TARGET}_c_srcs )
+# ecbuild_debug_var( ${_PAR_TARGET}_cxx_srcs )
+# ecbuild_debug_var( ${_PAR_TARGET}_f_srcs )
endmacro( ecbuild_separate_sources )
diff --git a/cmake/ecbuild_setup_test_framework.cmake b/cmake/ecbuild_setup_test_framework.cmake
index 538a433..f38bafb 100644
--- a/cmake/ecbuild_setup_test_framework.cmake
+++ b/cmake/ecbuild_setup_test_framework.cmake
@@ -2,7 +2,7 @@ ecbuild_add_option( FEATURE TESTS
DEFAULT ON
DESCRIPTION "Enable the unit tests" )
-if( ENABLE_TESTS )
+if( ENABLE_TESTS AND CMAKE_CXX_COMPILER_LOADED )
# Try to find compiled boost
@@ -39,3 +39,7 @@ if( ENABLE_TESTS )
endif()
endif()
+
+if( NOT ENABLE_TESTS )
+ ecbuild_info("Tests have been disabled")
+endif()
\ No newline at end of file
diff --git a/cmake/ecbuild_source_flags.cmake b/cmake/ecbuild_source_flags.cmake
new file mode 100644
index 0000000..2414765
--- /dev/null
+++ b/cmake/ecbuild_source_flags.cmake
@@ -0,0 +1,30 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+set( __gen_source_flags ${CMAKE_CURRENT_LIST_DIR}/gen_source_flags.py )
+
+# Calls gen_source_flags.py to generate a CMake file with the per
+# source file flags for a given target.
+function( ecbuild_source_flags OUT TARGET DEFAULT_FLAGS SOURCES )
+
+ if( NOT PYTHONINTERP_FOUND OR PYTHON_VERSION VERSION_LESS 2.7 )
+ find_package( PythonInterp 2.7 REQUIRED )
+ endif()
+
+ set( OUTFILE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_source_flags.cmake )
+
+ if( ECBUILD_LOG_LEVEL LESS 11)
+ set( __debug "--debug" )
+ endif()
+ execute_process( COMMAND ${PYTHON_EXECUTABLE} ${__gen_source_flags}
+ ${ECBUILD_SOURCE_FLAGS} ${OUTFILE} "${DEFAULT_FLAGS}"
+ ${SOURCES} "${__debug}" )
+
+ set( ${OUT} ${OUTFILE} PARENT_SCOPE )
+
+endfunction()
diff --git a/cmake/ecbuild_system.cmake b/cmake/ecbuild_system.cmake
index fc07bf5..64f6fad 100644
--- a/cmake/ecbuild_system.cmake
+++ b/cmake/ecbuild_system.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -28,7 +28,7 @@ endif()
########################################################################################################
# ecbuild versioning support
-set( ECBUILD_CMAKE_MINIMUM "2.8.4" )
+set( ECBUILD_CMAKE_MINIMUM "2.8.10" )
if( ${CMAKE_VERSION} VERSION_LESS ${ECBUILD_CMAKE_MINIMUM} )
message(FATAL_ERROR "${PROJECT_NAME} requires at least CMake ${ECBUILD_CMAKE_MINIMUM} -- you are using ${CMAKE_COMMAND} [${CMAKE_VERSION}]\n Please, get a newer version of CMake @ www.cmake.org" )
endif()
@@ -66,6 +66,10 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
message( STATUS "toolchain ${CMAKE_TOOLCHAIN_FILE}" )
endif()
+ if( ECBUILD_CONFIG )
+ message( STATUS "config ${ECBUILD_CONFIG}" )
+ endif()
+
if( ECBUILD_CACHE )
include( ${ECBUILD_CACHE} )
message( STATUS "cache ${ECBUILD_CACHE}" )
@@ -93,7 +97,7 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
enable_testing()
# keep this until we modify the meaning to 'check' if installation worked
- add_custom_target( check COMMAND ${CMAKE_CTEST_COMMAND} -V )
+ add_custom_target( check COMMAND ${CMAKE_CTEST_COMMAND} )
############################################################################################
# define valid build types
@@ -121,19 +125,19 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
# include(CMakePrintSystemInformation) # available in cmake 2.8.4
if( CMAKE_CXX_COMPILER_LOADED )
- include(CheckIncludeFileCXX)
- include(CheckCXXCompilerFlag)
- include(CheckCXXSourceCompiles)
- include(CheckCXXSourceRuns)
+ include(CheckIncludeFileCXX)
+ include(CheckCXXCompilerFlag)
+ include(CheckCXXSourceCompiles)
+ include(CheckCXXSourceRuns)
endif()
if( CMAKE_Fortran_COMPILER_LOADED )
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/module CACHE PATH "directory for all fortran modules." )
- include(CheckFortranFunctionExists)
- if( CMAKE_C_COMPILER_LOADED AND ENABLE_FORTRAN_C_INTERFACE )
- include(FortranCInterface)
- endif()
- set( EC_HAVE_FORTRAN 1 )
+ include(CheckFortranFunctionExists)
+ if( CMAKE_C_COMPILER_LOADED AND ENABLE_FORTRAN_C_INTERFACE )
+ include(FortranCInterface)
+ endif()
+ set( EC_HAVE_FORTRAN 1 )
endif()
include(FeatureSummary) # support features in cmake
@@ -144,17 +148,18 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
# backport of cmake > 2.8.4 functions
if( "${CMAKE_VERSION}" VERSION_LESS "2.8.6" )
- include( ${CMAKE_CURRENT_LIST_DIR}/2.8/CMakePushCheckState.cmake )
+ include( ${CMAKE_CURRENT_LIST_DIR}/2.8/CMakePushCheckState.cmake )
else()
- include(CMakePushCheckState)
+ include(CMakePushCheckState)
endif()
############################################################################################
# add our macros
- include( ecbuild_debug_var )
include( ecbuild_log )
include( ecbuild_list_macros )
+ include( ecbuild_list_add_pattern )
+ include( ecbuild_list_exclude_pattern )
include( ecbuild_check_c_source_return )
include( ecbuild_check_cxx_source_return )
@@ -167,6 +172,7 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
include( ecbuild_generate_config_headers )
include( ecbuild_generate_rpc )
include( ecbuild_generate_yy )
+ include( ecbuild_generate_fortran_interfaces )
include( ecbuild_echo_targets )
include( ecbuild_features )
include( ecbuild_add_option )
@@ -202,30 +208,38 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
include( ecbuild_find_fortranlibs )
include( ecbuild_git )
include( ecbuild_enable_fortran )
+ include( ecbuild_source_flags )
include( ecbuild_bundle )
include( ecbuild_pkgconfig )
include( ecbuild_cache )
+ include( ecbuild_remove_fortran_flags )
include( ${CMAKE_CURRENT_LIST_DIR}/contrib/GetGitRevisionDescription.cmake )
############################################################################################
# kickstart the build system
- ecbuild_prepare_cache()
+ if( ECBUILD_CONFIG )
+ include( ${ECBUILD_CONFIG} )
+ endif()
+
+ ecbuild_prepare_cache()
include( ecbuild_define_options ) # define build options
+ include( ecbuild_compiler_flags ) # compiler flags
include( ecbuild_check_compiler ) # check for compiler characteristics
include( ecbuild_check_os ) # check for os characteristics
include( ecbuild_check_functions ) # check for available functions
- include( ecbuild_define_paths ) # define installation paths
- include( ecbuild_links_target ) # define the links target
+ include( ecbuild_define_paths ) # defines installation paths
+ include( ecbuild_define_libs_and_execs_target ) # defines the top level execs and libs
+ include( ecbuild_define_links_target ) # defines the links target
include( ecbuild_setup_test_framework ) # setup test framework
include( ecbuild_define_uninstall ) # define uninstall target
ecbuild_flush_cache()
############################################################################################
- # define the build timestamp
+ # define the build timestamp, unless the user provided one via EC_BUILD_TIMESTAMP
if( NOT DEFINED EC_BUILD_TIMESTAMP )
ecbuild_get_timestamp( EC_BUILD_TIMESTAMP )
@@ -234,5 +248,17 @@ if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME )
message( STATUS "---------------------------------------------------------" )
-endif()
+else()
+
+ # Allow subprojects with different compilation flags. This could be done by defining
+ # set( ECBUILD_C_FLAGS_DEBUG "-O0" )
+ # or
+ # set( ECBUILD_CONFIG "<subproject-config>.cmake" )
+ if( ECBUILD_CONFIG )
+ message( STATUS "---------------------------------------------------------" )
+ message( STATUS "config ${ECBUILD_CONFIG}" )
+ include( ${ECBUILD_CONFIG} )
+ endif()
+ include( ecbuild_compiler_flags )
+endif()
diff --git a/cmake/ecbuild_use_package.cmake b/cmake/ecbuild_use_package.cmake
index dd30323..04dd27c 100644
--- a/cmake/ecbuild_use_package.cmake
+++ b/cmake/ecbuild_use_package.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
@@ -105,6 +105,7 @@ macro( ecbuild_use_package )
# user defined dir with subprojects
if( NOT DEFINED ${pkgUPPER}_SOURCE AND DEFINED SUBPROJECT_DIRS )
+ ecbuild_warn("ecbuild_use_package(): setting SUBPROJECT_DIRS is deprecated")
ecbuild_debug("ecbuild_use_package(${_p_PROJECT}): scanning subproject directories ${SUBPROJECT_DIRS}")
foreach( dir ${SUBPROJECT_DIRS} )
if( EXISTS ${dir}/${_p_PROJECT} AND EXISTS ${dir}/${_p_PROJECT}/CMakeLists.txt )
@@ -119,7 +120,7 @@ macro( ecbuild_use_package )
if( DEFINED ${pkgUPPER}_SOURCE )
if( NOT EXISTS ${${pkgUPPER}_SOURCE} OR NOT EXISTS ${${pkgUPPER}_SOURCE}/CMakeLists.txt )
- message( FATAL_ERROR "User defined source directory '${${pkgUPPER}_SOURCE}' for project '${_p_PROJECT}' does not exist or does not contain a CMakeLists.txt file." )
+ ecbuild_critical("User defined source directory '${${pkgUPPER}_SOURCE}' for project '${_p_PROJECT}' does not exist or does not contain a CMakeLists.txt file.")
endif()
set( ${pkgUPPER}_subproj_dir_ "${${pkgUPPER}_SOURCE}" )
@@ -187,6 +188,8 @@ macro( ecbuild_use_package )
set( ${pkgUPPER}_FOUND 1 )
set( ${_p_PROJECT}_VERSION ${${pkgUPPER}_VERSION} )
+ list( APPEND ${pkgUPPER}_INCLUDE_DIRS ${${pkgUPPER}_TPL_INCLUDE_DIRS} )
+
endif()
endif()
@@ -221,15 +224,15 @@ macro( ecbuild_use_package )
# test version for Cases 1,2,3
- # debug_var( _p_PROJECT )
- # debug_var( _p_VERSION )
- # debug_var( ${pkgUPPER}_VERSION )
- # debug_var( ${_p_PROJECT}_VERSION )
- # debug_var( _just_added )
- # debug_var( _do_version_check )
- # debug_var( _source_description )
- # debug_var( ${pkgUPPER}_FOUND )
- # debug_var( ${pkgUPPER}_previous_subproj_ )
+ # ecbuild_debug_var( _p_PROJECT )
+ # ecbuild_debug_var( _p_VERSION )
+ # ecbuild_debug_var( ${pkgUPPER}_VERSION )
+ # ecbuild_debug_var( ${_p_PROJECT}_VERSION )
+ # ecbuild_debug_var( _just_added )
+ # ecbuild_debug_var( _do_version_check )
+ # ecbuild_debug_var( _source_description )
+ # ecbuild_debug_var( ${pkgUPPER}_FOUND )
+ # ecbuild_debug_var( ${pkgUPPER}_previous_subproj_ )
if( _p_VERSION AND _do_version_check )
if( _p_EXACT )
diff --git a/cmake/ecbuild_version.h.in b/cmake/ecbuild_version.h.in
index d274bf6..70c5f0a 100644
--- a/cmake/ecbuild_version.h.in
+++ b/cmake/ecbuild_version.h.in
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 1996-2014 ECMWF.
+ * (C) Copyright 1996-2016 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/ecbuild_warn_unused_files.cmake b/cmake/ecbuild_warn_unused_files.cmake
index c33b213..f983440 100644
--- a/cmake/ecbuild_warn_unused_files.cmake
+++ b/cmake/ecbuild_warn_unused_files.cmake
@@ -1,4 +1,4 @@
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/gen_source_flags.py b/cmake/gen_source_flags.py
new file mode 100644
index 0000000..b976d31
--- /dev/null
+++ b/cmake/gen_source_flags.py
@@ -0,0 +1,84 @@
+# (C) Copyright 1996-2016 ECMWF.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+# In applying this licence, ECMWF does not waive the privileges and immunities
+# granted to it by virtue of its status as an intergovernmental organisation
+# nor does it submit to any jurisdiction.
+
+"""
+Generate .cmake file to set source-file specific compiler flags based on
+rules defined in a JSON file.
+"""
+
+from argparse import ArgumentParser
+from fnmatch import fnmatch
+import logging
+from json import JSONDecoder
+from os import path
+
+log = logging.getLogger('gen_source_flags')
+
+
+def match(source, pattern, op, flags, indent=0):
+ if fnmatch(source, pattern):
+
+ suff = '' if op[0] in ('+', '=', '/') else ' (nested pattern)'
+ log.debug('%s-> pattern "%s" matches "%s"%s',
+ ' ' * (indent + 1), pattern, source, suff)
+
+ if op[0] == "+":
+ flags += [flag for flag in op[1:] if flag not in flags]
+ log.debug('%sappending %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
+
+ elif op[0] == "=":
+ flags = op[1:]
+ log.debug('%ssetting %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
+
+ elif op[0] == "/":
+ flags = [flag for flag in flags if flag not in op[1:]]
+ log.debug('%sremoving %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
+
+ else: # Nested rule
+ log.debug('%sapplying nested rules for "%s" (flags: %s)',
+ ' ' * (indent + 2), pattern, flags)
+ for nested_pattern, nested_op in op:
+ flags = match(source, nested_pattern, nested_op, flags, indent + 2)
+
+ return flags
+
+
+def generate(rules, out, default_flags, sources, debug=False):
+ logging.basicConfig(level=logging.DEBUG if debug else logging.INFO,
+ format='-- %(levelname)s - %(name)s: %(message)s')
+
+ with open(path.expanduser(rules)) as f:
+ rules = JSONDecoder(object_pairs_hook=list).decode(f.read())
+
+ with open(path.expanduser(out), 'w') as f:
+ for source in sources:
+ log.debug('%s (default flags: "%s")', source, default_flags)
+ flags = default_flags.split()
+ for pattern, op in rules:
+ flags = match(source, pattern, op, flags)
+
+ if flags:
+ log.debug(' ==> setting flags for %s to %s', source, ' '.join(flags))
+ f.write('set_source_files_properties(%s PROPERTIES COMPILE_FLAGS "%s")\n'
+ % (source, ' '.join(flags)))
+ else:
+ log.debug(' ==> flags for %s empty', source)
+
+
+def main():
+ """Parse arguments"""
+ parser = ArgumentParser(description=__doc__)
+ parser.add_argument('rules', metavar='RULES.json', help='JSON rules file')
+ parser.add_argument('out', metavar='OUT.cmake', help='CMake script to generate')
+ parser.add_argument('default_flags', help='Default compiler flags to use')
+ parser.add_argument('sources', metavar='file', nargs='+', help='Path to file to apply rules to')
+ parser.add_argument('--debug', '-d', action='store_true', help='Log debug messages')
+ generate(**vars(parser.parse_args()))
+
+if __name__ == '__main__':
+ main()
diff --git a/cmake/include/ecbuild/boost_test_framework.h b/cmake/include/ecbuild/boost_test_framework.h
index 09e61dd..f593b70 100644
--- a/cmake/include/ecbuild/boost_test_framework.h
+++ b/cmake/include/ecbuild/boost_test_framework.h
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 1996-2014 ECMWF.
+ * (C) Copyright 1996-2016 ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/cmake/project-config.cmake.in b/cmake/project-config.cmake.in
index 03f875b..6d48728 100644
--- a/cmake/project-config.cmake.in
+++ b/cmake/project-config.cmake.in
@@ -1,11 +1,13 @@
# Config file for the @PROJECT_NAME@ package
# Defines the following variables:
#
-# @PNAME at _INCLUDE_DIRS - include directories
-# @PNAME at _DEFINITIONS - preprocessor definitions
-# @PNAME at _LIBRARIES - libraries to link against
-# @PNAME at _FEATURES - list of enabled features
-# @PNAME at _VERSION - version of the package
+# @PNAME at _INCLUDE_DIRS - include directories
+# @PNAME at _DEFINITIONS - preprocessor definitions
+# @PNAME at _LIBRARIES - libraries to link against
+# @PNAME at _FEATURES - list of enabled features
+# @PNAME at _VERSION - version of the package
+# @PNAME at _GIT_SHA1 - Git revision of the package
+# @PNAME at _GIT_SHA1_SHORT - short Git revision of the package
#
# Also defines @PROJECT_NAME@ third-party library dependencies:
# @PNAME at _TPLS - package names of third-party library dependencies
@@ -26,12 +28,16 @@ set( @PNAME at _TPL_INCLUDE_DIRS "@CONF_TPL_INCLUDE_DIRS@" )
set( @PNAME at _TPL_DEFINITIONS "@CONF_TPL_DEFINITIONS@" )
set( @PNAME at _TPL_LIBRARIES "@CONF_TPL_LIBRARIES@" )
+set( @PNAME at _VERSION "@PACKAGE_VERSION@" )
+set( @PNAME at _GIT_SHA1 "@PACKAGE_GIT_SHA1@" )
+set( @PNAME at _GIT_SHA1_SHORT "@PACKAGE_GIT_SHA1_SHORT@" )
+
### export include paths as absolute paths
set( @PNAME at _INCLUDE_DIRS "" )
foreach( path ${@PNAME at _SELF_INCLUDE_DIRS} )
- get_filename_component( abspath ${path} ABSOLUTE )
- list( APPEND @PNAME at _INCLUDE_DIRS ${abspath} )
+ get_filename_component( abspath ${path} ABSOLUTE )
+ list( APPEND @PNAME at _INCLUDE_DIRS ${abspath} )
endforeach()
list( APPEND @PNAME at _INCLUDE_DIRS ${@PNAME at _TPL_INCLUDE_DIRS} )
@@ -47,7 +53,7 @@ set( @PNAME at _LIBRARIES ${@PNAME at _SELF_LIBRARIES} ${@PNAME at _TPL_LIBRARIE
set( @PNAME at _FEATURES "@CONF_FEATURES@" )
foreach( _f ${@PNAME at _FEATURES} )
- set( @PNAME at _HAVE_${_f} 1 )
+ set( @PNAME at _HAVE_${_f} 1 )
endforeach()
# Has this configuration been exported from a build tree?
@@ -58,22 +64,22 @@ if( EXISTS ${@PNAME at _CMAKE_DIR}/@CONF_IMPORT_FILE@ )
include( ${@PNAME at _IMPORT_FILE} )
endif()
+# here goes the imports of the TPL's
+
+include( ${CMAKE_CURRENT_LIST_FILE}.tpls OPTIONAL )
+
# insert definitions for IMPORTED targets
if( NOT @PROJECT_NAME at _BINARY_DIR )
if( @PNAME at _IS_BUILD_DIR_EXPORT )
- include( "@TOP_PROJECT_TARGETS_FILE@" OPTIONAL )
- else()
- include( "${@PNAME at _CMAKE_DIR}/@CMAKE_PROJECT_NAME at -targets.cmake" )
- endif()
+ include( "@TOP_PROJECT_TARGETS_FILE@" OPTIONAL )
+ else()
+ include( "${@PNAME at _CMAKE_DIR}/@PROJECT_NAME at -targets.cmake" )
+ endif()
endif()
-# here goes the imports of the TPL's
-
-include( ${CMAKE_CURRENT_LIST_FILE}.tpls OPTIONAL )
-
# publish this file as imported
set( @PNAME at _IMPORT_FILE ${CMAKE_CURRENT_LIST_FILE} )
@@ -82,9 +88,10 @@ mark_as_advanced( @PNAME at _IMPORT_FILE )
# set @PROJECT_NAME at _BASE_DIR for final installations or build directories
if( NOT @PROJECT_NAME@ )
- if( @PNAME at _IS_BUILD_DIR_EXPORT )
- set( @PROJECT_NAME at _BASE_DIR @CMAKE_BINARY_DIR@ )
- else()
- set( @PROJECT_NAME at _BASE_DIR @CMAKE_INSTALL_PREFIX@ )
- endif()
+ if( @PNAME at _IS_BUILD_DIR_EXPORT )
+ set( @PROJECT_NAME at _BASE_DIR @CMAKE_BINARY_DIR@ )
+ else()
+ get_filename_component( abspath ${CMAKE_CURRENT_LIST_DIR}/../../.. ABSOLUTE )
+ set( @PROJECT_NAME at _BASE_DIR ${abspath} )
+ endif()
endif()
diff --git a/cmake/sg.pl b/cmake/sg.pl
old mode 100755
new mode 100644
index 455161b..6bce843
--- a/cmake/sg.pl
+++ b/cmake/sg.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
#!/usr/local/share/perl56
-# (C) Copyright 1996-2014 ECMWF.
+# (C) Copyright 1996-2016 ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
diff --git a/magics-import.cmake.in b/magics-import.cmake.in
index 198c366..76fcb2b 100644
--- a/magics-import.cmake.in
+++ b/magics-import.cmake.in
@@ -1,5 +1,7 @@
if( @PNAME at _IS_BUILD_DIR_EXPORT )
set( MAGICS_METEOGRAM_SCRIPT @CMAKE_BINARY_DIR@/apps/metgram/metgram )
+ set( MAGPLUS_HOME @CMAKE_CURRENT_SOURCE_DIR@ )
else()
set( MAGICS_METEOGRAM_SCRIPT @CMAKE_INSTALL_PREFIX@/bin/metgram )
+ set( MAGPLUS_HOME @CMAKE_INSTALL_PREFIX@ )
endif()
diff --git a/python/Magics/Magics_interface.cc b/python/Magics/Magics_interface.cc
index 29d84b9..d1ed8bb 100755
--- a/python/Magics/Magics_interface.cc
+++ b/python/Magics/Magics_interface.cc
@@ -84,7 +84,12 @@ void tephi() {
void mimport() {
mag_import();
}
-
+void mmetgraph() {
+ mag_metgraph();
+}
+void mmetbufr() {
+ mag_metbufr();
+}
void wrepjson() {
mag_wrepjson();
}
@@ -93,10 +98,13 @@ void geojson() {
mag_geojson();
}
-void epsinput() {
+void metgraph() {
mag_epsinput();
}
+void epsinput() {
+ mag_epsinput();
+}
void epsgraph() {
mag_epsgraph();
}
diff --git a/python/Magics/macro.py b/python/Magics/macro.py
index 535e136..f15ed31 100644
--- a/python/Magics/macro.py
+++ b/python/Magics/macro.py
@@ -415,6 +415,8 @@ mepsgraph = make_action("mepsgraph", Magics.epsgraph)
mepsplumes = make_action("mepsplumes", Magics.epsplumes)
mtephi = make_action("mtephi", Magics.tephi)
+mmetgraph = make_action("mmetgraph", Magics.mmetgraph)
+mmetbufr = make_action("mmetbufr", Magics.mmetbufr)
def examine(*args):
for n in args:
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
index 1e12d66..db045ee 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Cray.cmake
@@ -1,4 +1,9 @@
####################################################################
+# ARCHITECTURE
+####################################################################
+set( CMAKE_SIZEOF_VOID_P 8 )
+
+####################################################################
# COMPILER
####################################################################
@@ -8,15 +13,11 @@ CMAKE_FORCE_C_COMPILER ( cc Cray )
CMAKE_FORCE_CXX_COMPILER ( CC Cray )
CMAKE_FORCE_Fortran_COMPILER ( ftn Cray )
-link_libraries("$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so")
-link_libraries("-lmpichf90_cray")
-link_libraries("-lmpichcxx_cray")
-
set( ECBUILD_FIND_MPI OFF )
set( ECBUILD_TRUST_FLAGS ON )
####################################################################
-# FLAGS COMMON TO ALL BUILD TYPES
+# OpenMP FLAGS
####################################################################
set( OMP_C_FLAGS "-homp" )
@@ -27,49 +28,12 @@ set( OMPSTUBS_C_FLAGS "-hnoomp" )
set( OMPSTUBS_CXX_FLAGS "-hnoomp" )
set( OMPSTUBS_Fortran_FLAGS "-hnoomp" )
-set( CMAKE_C_FLAGS "" CACHE STRING "" FORCE )
-set( CMAKE_CXX_FLAGS "" CACHE STRING "" FORCE )
-set( CMAKE_Fortran_FLAGS "-emf -rmoid" CACHE STRING "" FORCE ) # -emf activates .mods and uses lower case -rmoid produces a listing file
-
-####################################################################
-# RELEASE FLAGS
-####################################################################
-
-set( ECBUILD_C_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-set( ECBUILD_CXX_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-set( ECBUILD_Fortran_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-
-####################################################################
-# BIT REPRODUCIBLE FLAGS
-####################################################################
-
-set( ECBUILD_C_FLAGS_BIT "-O1 -G2 -hflex_mp=conservative -hadd_paren -hfp1 -DNDEBUG" )
-set( ECBUILD_CXX_FLAGS_BIT "-O1 -G2 -hflex_mp=conservative -hadd_paren -hfp1 -DNDEBUG" )
-set( ECBUILD_Fortran_FLAGS_BIT "-O1 -G2 -hflex_mp=conservative -hadd_paren -hfp1 -DNDEBUG" )
-
-####################################################################
-# RELWITHDEBINFO FLAGS
-####################################################################
-
-set( ECBUILD_C_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-set( ECBUILD_CXX_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-set( ECBUILD_Fortran_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-
####################################################################
-# DEBUG FLAGS
+# Fortran FLAGS
####################################################################
-set( ECBUILD_C_FLAGS_DEBUG "-O0 -G0" )
-set( ECBUILD_CXX_FLAGS_DEBUG "-O0 -G0" )
-set( ECBUILD_Fortran_FLAGS_DEBUG "-O0 -G0" )
-
-####################################################################
-# PRODUCTION FLAGS
-####################################################################
-
-set( ECBUILD_C_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
-set( ECBUILD_CXX_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
-set( ECBUILD_Fortran_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
+# -emf activates .mods and uses lower case -rmoid produces a listing file
+set( ECBUILD_Fortran_FLAGS "-emf -rmoid" )
####################################################################
# LINK FLAGS
@@ -78,4 +42,4 @@ set( ECBUILD_Fortran_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
set( ECBUILD_C_LINK_FLAGS "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
set( ECBUILD_CXX_LINK_FLAGS "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
set( ECBUILD_Fortran_LINK_FLAGS "-Wl,-Map,loadmap -Wl,--as-needed -Ktrap=fp" )
-
+set( ECBUILD_CXX_IMPLICIT_LINK_LIBRARIES "$ENV{CC_X86_64}/lib/x86-64/libcray-c++-rts.so" CACHE STRING "" )
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
index 3c890d5..e09bc56 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-GNU.cmake
@@ -1,4 +1,9 @@
####################################################################
+# ARCHITECTURE
+####################################################################
+set( CMAKE_SIZEOF_VOID_P 8 )
+
+####################################################################
# COMPILER
####################################################################
@@ -12,56 +17,20 @@ set( ECBUILD_FIND_MPI OFF )
set( ECBUILD_TRUST_FLAGS ON )
####################################################################
-# FLAGS COMMON TO ALL BUILD TYPES
+# OpenMP FLAGS
####################################################################
set( OMP_C_FLAGS "-fopenmp" )
set( OMP_CXX_FLAGS "-fopenmp" )
set( OMP_Fortran_FLAGS "-fopenmp" )
-set( CMAKE_C_FLAGS "" CACHE STRING "" FORCE )
-set( CMAKE_CXX_FLAGS "" CACHE STRING "" FORCE )
-set( CMAKE_Fortran_FLAGS "" CACHE STRING "" FORCE )
-
-####################################################################
-# RELEASE FLAGS
-####################################################################
-
-#set( ECBUILD_C_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-#set( ECBUILD_CXX_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-#set( ECBUILD_Fortran_FLAGS_RELEASE "-O3 -hfp3 -hscalar3 -hvector3 -DNDEBUG" )
-
-####################################################################
-# BIT REPRODUCIBLE FLAGS
-####################################################################
-
-set( ECBUILD_C_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG" )
-set( ECBUILD_CXX_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG" )
-set( ECBUILD_Fortran_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG -fno-range-check -ffree-line-length-300 -fconvert=big-endian" )
-
-####################################################################
-# RELWITHDEBINFO FLAGS
-####################################################################
-
-#set( ECBUILD_C_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-#set( ECBUILD_CXX_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-#set( ECBUILD_Fortran_FLAGS_RELWITHDEBINFO "-O2 -hfp1 -Gfast -DNDEBUG" )
-
####################################################################
# DEBUG FLAGS
####################################################################
-#set( ECBUILD_C_FLAGS_DEBUG "-O0 -G0" )
-#set( ECBUILD_CXX_FLAGS_DEBUG "-O0 -G0" )
-#set( ECBUILD_Fortran_FLAGS_DEBUG "-O0 -G0" )
-
-####################################################################
-# PRODUCTION FLAGS
-####################################################################
-
-#set( ECBUILD_C_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
-#set( ECBUILD_CXX_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
-#set( ECBUILD_Fortran_FLAGS_PRODUCTION "-O2 -hfp1 -G2" )
+set( ECBUILD_C_FLAGS_DEBUG "-O0 -g -ftrapv" )
+set( ECBUILD_CXX_FLAGS_DEBUG "-O0 -g -ftrapv" )
+set( ECBUILD_Fortran_FLAGS_DEBUG "-ffree-line-length-none -O0 -g -fcheck=bounds -fbacktrace -finit-real=snan -ffpe-trap=invalid,zero,overflow" )
####################################################################
# LINK FLAGS
@@ -70,4 +39,3 @@ set( ECBUILD_Fortran_FLAGS_BIT "-g -O2 -m64 -march=native -DNDEBUG -fno-range-c
set( ECBUILD_C_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
set( ECBUILD_CXX_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
set( ECBUILD_Fortran_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
-
diff --git a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
index 485b122..c569daf 100644
--- a/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
+++ b/share/ecbuild/toolchains/ecmwf-XC30-Intel.cmake
@@ -12,27 +12,23 @@ set( ECBUILD_FIND_MPI OFF )
set( ECBUILD_TRUST_FLAGS ON )
####################################################################
-# FLAGS COMMON TO ALL BUILD TYPES
+# OpenMP FLAGS
####################################################################
set( OMP_C_FLAGS "-qopenmp -qopenmp-threadprivate=compat -qopenmp-report=2 -qopt-report-phase=vec,openmp" )
set( OMP_CXX_FLAGS "-qopenmp -qopenmp-threadprivate=compat -qopenmp-report=2 -qopt-report-phase=vec,openmp" )
set( OMP_Fortran_FLAGS " -openmp -openmp-threadprivate=compat -openmp-report=2 -opt-report-phase=vec,openmp" ) # -[q] is missing on purpose, ifort does not take -q as flag
-# for diagnostics:
-# -diag-enable=vec -diag-file -Winline
-
-set( CMAKE_C_FLAGS "-fp-speculation=strict -fp-model precise -traceback" CACHE STRING "" FORCE )
-set( CMAKE_CXX_FLAGS "-fp-speculation=strict -fp-model precise -traceback" CACHE STRING "" FORCE )
-set( CMAKE_Fortran_FLAGS "-fp-speculation=strict -fp-model precise -convert big_endian -assume byterecl -traceback -fpe0" CACHE STRING "" FORCE )
-
####################################################################
-# RELEASE FLAGS
+# COMMON FLAGS
####################################################################
-#set( ECBUILD_C_FLAGS_RELEASE "not implemented" )
-#set( ECBUILD_CXX_FLAGS_RELEASE "not implemented" )
-#set( ECBUILD_Fortran_FLAGS_RELEASE "not implemented" )
+# for diagnostics:
+# -diag-enable=vec -diag-file -Winline
+
+set( ECBUILD_C_FLAGS "-fp-speculation=strict -fp-model precise -traceback")
+set( ECBUILD_CXX_FLAGS "-fp-speculation=strict -fp-model precise -traceback" )
+set( ECBUILD_Fortran_FLAGS "-fp-speculation=strict -fp-model precise -convert big_endian -assume byterecl -traceback -fpe0" )
####################################################################
# BIT REPRODUCIBLE FLAGS
@@ -43,28 +39,13 @@ set( ECBUILD_CXX_FLAGS_BIT "-O2 -xAVX -finline-function -finline-limit=500"
set( ECBUILD_Fortran_FLAGS_BIT "-O2 -xAVX -finline-function -finline-limit=500 -align array64byte" )
####################################################################
-# RELWITHDEBINFO FLAGS
-####################################################################
-
-#set( ECBUILD_C_FLAGS_RELWITHDEBINFO "not implemented" )
-#set( ECBUILD_CXX_FLAGS_RELWITHDEBINFO "not implemented" )
-#set( ECBUILD_Fortran_FLAGS_RELWITHDEBINFO "not implemented" )
-
-####################################################################
# DEBUG FLAGS
####################################################################
-set( ECBUILD_C_FLAGS_DEBUG "-g -O0" )
-set( ECBUILD_CXX_FLAGS_DEBUG "-g -O0" )
-set( ECBUILD_Fortran_FLAGS_DEBUG "-g -O0" ) # ??? -align array64byte
-
-####################################################################
-# PRODUCTION FLAGS
-####################################################################
-
-#set( ECBUILD_C_FLAGS_PRODUCTION "not implemented" )
-#set( ECBUILD_CXX_FLAGS_PRODUCTION "not implemented" )
-#set( ECBUILD_Fortran_FLAGS_PRODUCTION "not implemented" )
+set( ECBUILD_C_FLAGS_DEBUG "-O0 -g -traceback -fp-trap=common" )
+set( ECBUILD_CXX_FLAGS_DEBUG "-O0 -g -traceback -fp-trap=common" )
+# -check all implies -check bounds
+set( ECBUILD_Fortran_FLAGS_DEBUG "-O0 -g -traceback -warn all -heap-arrays -fpe-all=0 -fpe:0 -check all" )
####################################################################
# LINK FLAGS
@@ -73,4 +54,3 @@ set( ECBUILD_Fortran_FLAGS_DEBUG "-g -O0" ) # ??? -align array64byte
set( ECBUILD_C_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
set( ECBUILD_CXX_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
set( ECBUILD_Fortran_LINK_FLAGS "-Wl,-Map,load.map -Wl,--as-needed" )
-
diff --git a/share/magics/10m/10m_admin_0_boundary_lines_land.dbf b/share/magics/10m/10m_admin_0_boundary_lines_land.dbf
deleted file mode 100644
index e9710a2..0000000
Binary files a/share/magics/10m/10m_admin_0_boundary_lines_land.dbf and /dev/null differ
diff --git a/share/magics/10m/10m_admin_0_boundary_lines_land.shp b/share/magics/10m/10m_admin_0_boundary_lines_land.shp
deleted file mode 100644
index ddc43a4..0000000
Binary files a/share/magics/10m/10m_admin_0_boundary_lines_land.shp and /dev/null differ
diff --git a/share/magics/10m/10m_admin_0_boundary_lines_land.shx b/share/magics/10m/10m_admin_0_boundary_lines_land.shx
deleted file mode 100644
index 2d55eb6..0000000
Binary files a/share/magics/10m/10m_admin_0_boundary_lines_land.shx and /dev/null differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.dbf b/share/magics/10m/10m_admin_1_states_provinces_shp.dbf
deleted file mode 100644
index 7b8cd7c..0000000
Binary files a/share/magics/10m/10m_admin_1_states_provinces_shp.dbf and /dev/null differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.shp b/share/magics/10m/10m_admin_1_states_provinces_shp.shp
deleted file mode 100644
index be2a867..0000000
Binary files a/share/magics/10m/10m_admin_1_states_provinces_shp.shp and /dev/null differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.shx b/share/magics/10m/10m_admin_1_states_provinces_shp.shx
deleted file mode 100644
index 7f50b6f..0000000
Binary files a/share/magics/10m/10m_admin_1_states_provinces_shp.shx and /dev/null differ
diff --git a/share/magics/10m/10m_lakes.dbf b/share/magics/10m/10m_lakes.dbf
deleted file mode 100644
index 4e9589c..0000000
Binary files a/share/magics/10m/10m_lakes.dbf and /dev/null differ
diff --git a/share/magics/10m/10m_lakes.prj b/share/magics/10m/10m_lakes.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/10m/10m_lakes.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/10m/10m_lakes.shp b/share/magics/10m/10m_lakes.shp
deleted file mode 100644
index 8830600..0000000
Binary files a/share/magics/10m/10m_lakes.shp and /dev/null differ
diff --git a/share/magics/10m/10m_lakes.shx b/share/magics/10m/10m_lakes.shx
deleted file mode 100644
index 68691e5..0000000
Binary files a/share/magics/10m/10m_lakes.shx and /dev/null differ
diff --git a/share/magics/10m/10m_land.prj b/share/magics/10m/10m_land.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/10m/10m_land.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/10m/10m_land.shp b/share/magics/10m/10m_land.shp
deleted file mode 100644
index 5005af2..0000000
Binary files a/share/magics/10m/10m_land.shp and /dev/null differ
diff --git a/share/magics/10m/10m_land.shx b/share/magics/10m/10m_land.shx
deleted file mode 100644
index b965bae..0000000
Binary files a/share/magics/10m/10m_land.shx and /dev/null differ
diff --git a/share/magics/10m/10m_populated_places_simple.dbf b/share/magics/10m/10m_populated_places_simple.dbf
deleted file mode 100755
index 1823111..0000000
Binary files a/share/magics/10m/10m_populated_places_simple.dbf and /dev/null differ
diff --git a/share/magics/10m/10m_populated_places_simple.shp b/share/magics/10m/10m_populated_places_simple.shp
deleted file mode 100755
index 90d2b4e..0000000
Binary files a/share/magics/10m/10m_populated_places_simple.shp and /dev/null differ
diff --git a/share/magics/10m/10m_rivers_lake_centerlines.dbf b/share/magics/10m/10m_rivers_lake_centerlines.dbf
deleted file mode 100644
index 586c73a..0000000
Binary files a/share/magics/10m/10m_rivers_lake_centerlines.dbf and /dev/null differ
diff --git a/share/magics/10m/10m_rivers_lake_centerlines.prj b/share/magics/10m/10m_rivers_lake_centerlines.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/10m/10m_rivers_lake_centerlines.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/10m/10m_rivers_lake_centerlines.shp b/share/magics/10m/10m_rivers_lake_centerlines.shp
deleted file mode 100644
index 0d41d10..0000000
Binary files a/share/magics/10m/10m_rivers_lake_centerlines.shp and /dev/null differ
diff --git a/share/magics/10m/10m_rivers_lake_centerlines.shx b/share/magics/10m/10m_rivers_lake_centerlines.shx
deleted file mode 100644
index 3f4e642..0000000
Binary files a/share/magics/10m/10m_rivers_lake_centerlines.shx and /dev/null differ
diff --git a/share/magics/10m/ne_10m_admin_0_boundary_lines_land.VERSION.txt b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/10m/ne_10m_admin_0_boundary_lines_land.dbf b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.dbf
new file mode 100644
index 0000000..30c5e3c
Binary files /dev/null and b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.dbf differ
diff --git a/share/magics/10m/10m_admin_0_boundary_lines_land.prj b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.prj
similarity index 100%
rename from share/magics/10m/10m_admin_0_boundary_lines_land.prj
rename to share/magics/10m/ne_10m_admin_0_boundary_lines_land.prj
diff --git a/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shp b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shp
new file mode 100644
index 0000000..dfdcc3b
Binary files /dev/null and b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shp differ
diff --git a/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shx b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shx
new file mode 100644
index 0000000..8f81eef
Binary files /dev/null and b/share/magics/10m/ne_10m_admin_0_boundary_lines_land.shx differ
diff --git a/share/magics/10m/ne_10m_admin_1_states_provinces.VERSION.txt b/share/magics/10m/ne_10m_admin_1_states_provinces.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/10m/ne_10m_admin_1_states_provinces.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/10m/ne_10m_admin_1_states_provinces.dbf b/share/magics/10m/ne_10m_admin_1_states_provinces.dbf
new file mode 100644
index 0000000..281065f
Binary files /dev/null and b/share/magics/10m/ne_10m_admin_1_states_provinces.dbf differ
diff --git a/share/magics/10m_full/10m_admin_0_boundary_lines_land.prj b/share/magics/10m/ne_10m_admin_1_states_provinces.prj
similarity index 100%
rename from share/magics/10m_full/10m_admin_0_boundary_lines_land.prj
rename to share/magics/10m/ne_10m_admin_1_states_provinces.prj
diff --git a/share/magics/10m_full/10m_admin_1_states_provinces_shp.shp b/share/magics/10m/ne_10m_admin_1_states_provinces.shp
similarity index 65%
rename from share/magics/10m_full/10m_admin_1_states_provinces_shp.shp
rename to share/magics/10m/ne_10m_admin_1_states_provinces.shp
index c656806..75b2eb2 100644
Binary files a/share/magics/10m_full/10m_admin_1_states_provinces_shp.shp and b/share/magics/10m/ne_10m_admin_1_states_provinces.shp differ
diff --git a/share/magics/10m/ne_10m_admin_1_states_provinces.shx b/share/magics/10m/ne_10m_admin_1_states_provinces.shx
new file mode 100644
index 0000000..667bb14
Binary files /dev/null and b/share/magics/10m/ne_10m_admin_1_states_provinces.shx differ
diff --git a/share/magics/10m/ne_10m_land.VERSION.txt b/share/magics/10m/ne_10m_land.VERSION.txt
new file mode 100644
index 0000000..13d683c
--- /dev/null
+++ b/share/magics/10m/ne_10m_land.VERSION.txt
@@ -0,0 +1 @@
+3.0.1
\ No newline at end of file
diff --git a/share/magics/10m/ne_10m_land.dbf b/share/magics/10m/ne_10m_land.dbf
new file mode 100644
index 0000000..13d2656
Binary files /dev/null and b/share/magics/10m/ne_10m_land.dbf differ
diff --git a/share/magics/10m_full/10m_land.prj b/share/magics/10m/ne_10m_land.prj
similarity index 100%
copy from share/magics/10m_full/10m_land.prj
copy to share/magics/10m/ne_10m_land.prj
diff --git a/share/magics/10m/ne_10m_land.qpj b/share/magics/10m/ne_10m_land.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/10m/ne_10m_land.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/10m/ne_10m_land.shp b/share/magics/10m/ne_10m_land.shp
new file mode 100644
index 0000000..150a59b
Binary files /dev/null and b/share/magics/10m/ne_10m_land.shp differ
diff --git a/share/magics/10m/ne_10m_land.shx b/share/magics/10m/ne_10m_land.shx
new file mode 100644
index 0000000..2538381
Binary files /dev/null and b/share/magics/10m/ne_10m_land.shx differ
diff --git a/share/magics/10m/ne_10m_ocean.VERSION.txt b/share/magics/10m/ne_10m_ocean.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/10m/ne_10m_ocean.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/10m_full/10m_lakes.dbf b/share/magics/10m/ne_10m_ocean.dbf
similarity index 68%
rename from share/magics/10m_full/10m_lakes.dbf
rename to share/magics/10m/ne_10m_ocean.dbf
index 7c280b3..f09db52 100644
Binary files a/share/magics/10m_full/10m_lakes.dbf and b/share/magics/10m/ne_10m_ocean.dbf differ
diff --git a/share/magics/110m/110m_rivers_lake_centerlines.prj b/share/magics/10m/ne_10m_ocean.prj
similarity index 100%
rename from share/magics/110m/110m_rivers_lake_centerlines.prj
rename to share/magics/10m/ne_10m_ocean.prj
diff --git a/share/magics/10m/ne_10m_ocean.qpj b/share/magics/10m/ne_10m_ocean.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/10m/ne_10m_ocean.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/10m/ne_10m_ocean.shp b/share/magics/10m/ne_10m_ocean.shp
new file mode 100644
index 0000000..56c51cb
Binary files /dev/null and b/share/magics/10m/ne_10m_ocean.shp differ
diff --git a/share/magics/10m/ne_10m_ocean.shx b/share/magics/10m/ne_10m_ocean.shx
new file mode 100644
index 0000000..602abc4
Binary files /dev/null and b/share/magics/10m/ne_10m_ocean.shx differ
diff --git a/share/magics/10m/ne_10m_ocean_orig.VERSION.txt b/share/magics/10m/ne_10m_ocean_orig.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/10m/ne_10m_ocean_orig.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/10m/ne_10m_populated_places_simple.VERSION.txt b/share/magics/10m/ne_10m_populated_places_simple.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/10m/ne_10m_populated_places_simple.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/10m/ne_10m_populated_places_simple.dbf b/share/magics/10m/ne_10m_populated_places_simple.dbf
new file mode 100644
index 0000000..2d7ad1d
Binary files /dev/null and b/share/magics/10m/ne_10m_populated_places_simple.dbf differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.prj b/share/magics/10m/ne_10m_populated_places_simple.prj
similarity index 100%
copy from share/magics/10m/10m_admin_1_states_provinces_shp.prj
copy to share/magics/10m/ne_10m_populated_places_simple.prj
diff --git a/share/magics/10m/ne_10m_populated_places_simple.shp b/share/magics/10m/ne_10m_populated_places_simple.shp
new file mode 100644
index 0000000..b16d820
Binary files /dev/null and b/share/magics/10m/ne_10m_populated_places_simple.shp differ
diff --git a/share/magics/10m/10m_populated_places_simple.shx b/share/magics/10m/ne_10m_populated_places_simple.shx
old mode 100755
new mode 100644
similarity index 99%
rename from share/magics/10m/10m_populated_places_simple.shx
rename to share/magics/10m/ne_10m_populated_places_simple.shx
index 28c7910..c38358e
Binary files a/share/magics/10m/10m_populated_places_simple.shx and b/share/magics/10m/ne_10m_populated_places_simple.shx differ
diff --git a/share/magics/10m/ne_10m_rivers_lake_centerlines.VERSION.txt b/share/magics/10m/ne_10m_rivers_lake_centerlines.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/10m/ne_10m_rivers_lake_centerlines.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/10m/10m_land.dbf b/share/magics/10m/ne_10m_rivers_lake_centerlines.dbf
similarity index 70%
rename from share/magics/10m/10m_land.dbf
rename to share/magics/10m/ne_10m_rivers_lake_centerlines.dbf
index 2b21a34..8d38879 100644
Binary files a/share/magics/10m/10m_land.dbf and b/share/magics/10m/ne_10m_rivers_lake_centerlines.dbf differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.prj b/share/magics/10m/ne_10m_rivers_lake_centerlines.prj
similarity index 100%
copy from share/magics/10m/10m_admin_1_states_provinces_shp.prj
copy to share/magics/10m/ne_10m_rivers_lake_centerlines.prj
diff --git a/share/magics/10m/ne_10m_rivers_lake_centerlines.shp b/share/magics/10m/ne_10m_rivers_lake_centerlines.shp
new file mode 100644
index 0000000..a94581a
Binary files /dev/null and b/share/magics/10m/ne_10m_rivers_lake_centerlines.shp differ
diff --git a/share/magics/10m/ne_10m_rivers_lake_centerlines.shx b/share/magics/10m/ne_10m_rivers_lake_centerlines.shx
new file mode 100644
index 0000000..1a29f09
Binary files /dev/null and b/share/magics/10m/ne_10m_rivers_lake_centerlines.shx differ
diff --git a/share/magics/10m_full/10m_admin_0_boundary_lines_land.dbf b/share/magics/10m_full/10m_admin_0_boundary_lines_land.dbf
deleted file mode 100644
index e9710a2..0000000
Binary files a/share/magics/10m_full/10m_admin_0_boundary_lines_land.dbf and /dev/null differ
diff --git a/share/magics/10m_full/10m_admin_0_boundary_lines_land.shp b/share/magics/10m_full/10m_admin_0_boundary_lines_land.shp
deleted file mode 100644
index ddc43a4..0000000
Binary files a/share/magics/10m_full/10m_admin_0_boundary_lines_land.shp and /dev/null differ
diff --git a/share/magics/10m_full/10m_admin_0_boundary_lines_land.shx b/share/magics/10m_full/10m_admin_0_boundary_lines_land.shx
deleted file mode 100644
index 2d55eb6..0000000
Binary files a/share/magics/10m_full/10m_admin_0_boundary_lines_land.shx and /dev/null differ
diff --git a/share/magics/10m_full/10m_admin_1_states_provinces_shp.dbf b/share/magics/10m_full/10m_admin_1_states_provinces_shp.dbf
deleted file mode 100644
index c55e0ae..0000000
Binary files a/share/magics/10m_full/10m_admin_1_states_provinces_shp.dbf and /dev/null differ
diff --git a/share/magics/10m_full/10m_admin_1_states_provinces_shp.shx b/share/magics/10m_full/10m_admin_1_states_provinces_shp.shx
deleted file mode 100644
index 1fccbcf..0000000
Binary files a/share/magics/10m_full/10m_admin_1_states_provinces_shp.shx and /dev/null differ
diff --git a/share/magics/10m_full/10m_lakes.prj b/share/magics/10m_full/10m_lakes.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/10m_full/10m_lakes.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/10m_full/10m_lakes.shp b/share/magics/10m_full/10m_lakes.shp
deleted file mode 100644
index 666030f..0000000
Binary files a/share/magics/10m_full/10m_lakes.shp and /dev/null differ
diff --git a/share/magics/10m_full/10m_lakes.shx b/share/magics/10m_full/10m_lakes.shx
deleted file mode 100644
index 0fe6e07..0000000
Binary files a/share/magics/10m_full/10m_lakes.shx and /dev/null differ
diff --git a/share/magics/10m_full/10m_land.dbf b/share/magics/10m_full/10m_land.dbf
deleted file mode 100644
index 73af415..0000000
Binary files a/share/magics/10m_full/10m_land.dbf and /dev/null differ
diff --git a/share/magics/10m_full/10m_land.shp b/share/magics/10m_full/10m_land.shp
deleted file mode 100644
index 72750bd..0000000
Binary files a/share/magics/10m_full/10m_land.shp and /dev/null differ
diff --git a/share/magics/10m_full/10m_land.shx b/share/magics/10m_full/10m_land.shx
deleted file mode 100644
index 10a8433..0000000
Binary files a/share/magics/10m_full/10m_land.shx and /dev/null differ
diff --git a/share/magics/10m_full/10m_rivers_lake_centerlines.dbf b/share/magics/10m_full/10m_rivers_lake_centerlines.dbf
deleted file mode 100644
index 34991b9..0000000
Binary files a/share/magics/10m_full/10m_rivers_lake_centerlines.dbf and /dev/null differ
diff --git a/share/magics/10m_full/10m_rivers_lake_centerlines.shp b/share/magics/10m_full/10m_rivers_lake_centerlines.shp
deleted file mode 100644
index 6e55a53..0000000
Binary files a/share/magics/10m_full/10m_rivers_lake_centerlines.shp and /dev/null differ
diff --git a/share/magics/10m_full/10m_rivers_lake_centerlines.shx b/share/magics/10m_full/10m_rivers_lake_centerlines.shx
deleted file mode 100644
index 8d4fbca..0000000
Binary files a/share/magics/10m_full/10m_rivers_lake_centerlines.shx and /dev/null differ
diff --git a/share/magics/110m/110m_admin_0_boundary_lines_land.dbf b/share/magics/110m/110m_admin_0_boundary_lines_land.dbf
deleted file mode 100644
index 39218a3..0000000
Binary files a/share/magics/110m/110m_admin_0_boundary_lines_land.dbf and /dev/null differ
diff --git a/share/magics/110m/110m_admin_0_boundary_lines_land.prj b/share/magics/110m/110m_admin_0_boundary_lines_land.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/110m/110m_admin_0_boundary_lines_land.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/110m/110m_admin_0_boundary_lines_land.shx b/share/magics/110m/110m_admin_0_boundary_lines_land.shx
deleted file mode 100644
index 791fe09..0000000
Binary files a/share/magics/110m/110m_admin_0_boundary_lines_land.shx and /dev/null differ
diff --git a/share/magics/110m/110m_admin_1_states_provinces_shp.prj b/share/magics/110m/110m_admin_1_states_provinces_shp.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/110m/110m_admin_1_states_provinces_shp.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/110m/110m_lakes.prj b/share/magics/110m/110m_lakes.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/110m/110m_lakes.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/110m/110m_lakes.shp b/share/magics/110m/110m_lakes.shp
deleted file mode 100644
index 877312b..0000000
Binary files a/share/magics/110m/110m_lakes.shp and /dev/null differ
diff --git a/share/magics/110m/110m_lakes.shx b/share/magics/110m/110m_lakes.shx
deleted file mode 100644
index d8036a0..0000000
Binary files a/share/magics/110m/110m_lakes.shx and /dev/null differ
diff --git a/share/magics/110m/110m_land.dbf b/share/magics/110m/110m_land.dbf
deleted file mode 100644
index 82697ef..0000000
Binary files a/share/magics/110m/110m_land.dbf and /dev/null differ
diff --git a/share/magics/110m/110m_land.prj b/share/magics/110m/110m_land.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/110m/110m_land.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/110m/110m_land.sbx b/share/magics/110m/110m_land.sbx
deleted file mode 100644
index 256b42c..0000000
Binary files a/share/magics/110m/110m_land.sbx and /dev/null differ
diff --git a/share/magics/110m/110m_land.shp.xml b/share/magics/110m/110m_land.shp.xml
deleted file mode 100644
index 172bf2b..0000000
--- a/share/magics/110m/110m_land.shp.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<!--<!DOCTYPE metadata SYSTEM "http://www.esri.com/metadata/esriprof80.dtd">-->
-<metadata xml:lang="en"><Esri><CreaDate>20100226</CreaDate><CreaTime>03035000</CreaTime><SyncOnce>FALSE</SyncOnce><DataProperties><lineage><Process ToolSource="C:\Program Files\ArcGIS\ArcToolbox\Toolboxes\Data Management Tools.tbx\RepairGeometry" Date="20100207" Time="201213">RepairGeometry 110m-admin-0-country DELETE_NULL 110m-admin-0-country</Process><Process ToolSource="C:\Program Files\ArcGIS\ArcToolbox\Toolboxes\Data Management Tools.tbx\Dissolve" Date="20100207" Time="204703">Disso [...]
diff --git a/share/magics/110m/ne_110m_admin_0_boundary_lines_land.VERSION.txt b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/110m/ne_110m_admin_0_boundary_lines_land.dbf b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.dbf
new file mode 100644
index 0000000..abaed20
Binary files /dev/null and b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.dbf differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.prj b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.prj
similarity index 100%
copy from share/magics/10m/10m_admin_1_states_provinces_shp.prj
copy to share/magics/110m/ne_110m_admin_0_boundary_lines_land.prj
diff --git a/share/magics/110m/110m_admin_0_boundary_lines_land.shp b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.shp
similarity index 87%
rename from share/magics/110m/110m_admin_0_boundary_lines_land.shp
rename to share/magics/110m/ne_110m_admin_0_boundary_lines_land.shp
index 53a2f1f..d218ff8 100644
Binary files a/share/magics/110m/110m_admin_0_boundary_lines_land.shp and b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.shp differ
diff --git a/share/magics/110m/ne_110m_admin_0_boundary_lines_land.shx b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.shx
new file mode 100644
index 0000000..4141ab9
Binary files /dev/null and b/share/magics/110m/ne_110m_admin_0_boundary_lines_land.shx differ
diff --git a/share/magics/110m/ne_110m_admin_1_states_provinces.VERSION.txt b/share/magics/110m/ne_110m_admin_1_states_provinces.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/110m/ne_110m_admin_1_states_provinces.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/110m/110m_admin_1_states_provinces_shp.dbf b/share/magics/110m/ne_110m_admin_1_states_provinces.dbf
old mode 100644
new mode 100755
similarity index 57%
rename from share/magics/110m/110m_admin_1_states_provinces_shp.dbf
rename to share/magics/110m/ne_110m_admin_1_states_provinces.dbf
index 202134e..3f246b6
Binary files a/share/magics/110m/110m_admin_1_states_provinces_shp.dbf and b/share/magics/110m/ne_110m_admin_1_states_provinces.dbf differ
diff --git a/share/magics/10m_full/10m_admin_1_states_provinces_shp.prj b/share/magics/110m/ne_110m_admin_1_states_provinces.prj
old mode 100644
new mode 100755
similarity index 100%
rename from share/magics/10m_full/10m_admin_1_states_provinces_shp.prj
rename to share/magics/110m/ne_110m_admin_1_states_provinces.prj
diff --git a/share/magics/110m/ne_110m_admin_1_states_provinces.sbn b/share/magics/110m/ne_110m_admin_1_states_provinces.sbn
new file mode 100644
index 0000000..7e8970a
Binary files /dev/null and b/share/magics/110m/ne_110m_admin_1_states_provinces.sbn differ
diff --git a/share/magics/110m/ne_110m_admin_1_states_provinces.sbx b/share/magics/110m/ne_110m_admin_1_states_provinces.sbx
new file mode 100644
index 0000000..e915ffe
Binary files /dev/null and b/share/magics/110m/ne_110m_admin_1_states_provinces.sbx differ
diff --git a/share/magics/110m/110m_admin_1_states_provinces_shp.shp b/share/magics/110m/ne_110m_admin_1_states_provinces.shp
old mode 100644
new mode 100755
similarity index 99%
rename from share/magics/110m/110m_admin_1_states_provinces_shp.shp
rename to share/magics/110m/ne_110m_admin_1_states_provinces.shp
index 4ba5e68..92c85e7
Binary files a/share/magics/110m/110m_admin_1_states_provinces_shp.shp and b/share/magics/110m/ne_110m_admin_1_states_provinces.shp differ
diff --git a/share/magics/110m/110m_admin_1_states_provinces_shp.shx b/share/magics/110m/ne_110m_admin_1_states_provinces.shx
old mode 100644
new mode 100755
similarity index 80%
rename from share/magics/110m/110m_admin_1_states_provinces_shp.shx
rename to share/magics/110m/ne_110m_admin_1_states_provinces.shx
index 9ea7e19..6576aee
Binary files a/share/magics/110m/110m_admin_1_states_provinces_shp.shx and b/share/magics/110m/ne_110m_admin_1_states_provinces.shx differ
diff --git a/share/magics/110m/ne_110m_land.VERSION.txt b/share/magics/110m/ne_110m_land.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/110m/ne_110m_land.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/110m/ne_110m_land.dbf b/share/magics/110m/ne_110m_land.dbf
new file mode 100644
index 0000000..c267d54
Binary files /dev/null and b/share/magics/110m/ne_110m_land.dbf differ
diff --git a/share/magics/50m/50m_admin_0_boundary_lines_land.prj b/share/magics/110m/ne_110m_land.prj
similarity index 100%
rename from share/magics/50m/50m_admin_0_boundary_lines_land.prj
rename to share/magics/110m/ne_110m_land.prj
diff --git a/share/magics/110m/ne_110m_land.qpj b/share/magics/110m/ne_110m_land.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/110m/ne_110m_land.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/110m/110m_land.shp b/share/magics/110m/ne_110m_land.shp
similarity index 91%
rename from share/magics/110m/110m_land.shp
rename to share/magics/110m/ne_110m_land.shp
index 69ce127..55e1566 100644
Binary files a/share/magics/110m/110m_land.shp and b/share/magics/110m/ne_110m_land.shp differ
diff --git a/share/magics/110m/110m_land.shx b/share/magics/110m/ne_110m_land.shx
similarity index 74%
rename from share/magics/110m/110m_land.shx
rename to share/magics/110m/ne_110m_land.shx
index 0c82e83..7a1edfe 100644
Binary files a/share/magics/110m/110m_land.shx and b/share/magics/110m/ne_110m_land.shx differ
diff --git a/share/magics/110m/ne_110m_ocean.VERSION.txt b/share/magics/110m/ne_110m_ocean.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/110m/ne_110m_ocean.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/110m/110m_lakes.dbf b/share/magics/110m/ne_110m_ocean.dbf
similarity index 64%
rename from share/magics/110m/110m_lakes.dbf
rename to share/magics/110m/ne_110m_ocean.dbf
index eed23f4..77f93c6 100644
Binary files a/share/magics/110m/110m_lakes.dbf and b/share/magics/110m/ne_110m_ocean.dbf differ
diff --git a/share/magics/10m_full/10m_land.prj b/share/magics/110m/ne_110m_ocean.prj
similarity index 100%
copy from share/magics/10m_full/10m_land.prj
copy to share/magics/110m/ne_110m_ocean.prj
diff --git a/share/magics/110m/ne_110m_ocean.qpj b/share/magics/110m/ne_110m_ocean.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/110m/ne_110m_ocean.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/110m/ne_110m_ocean.shp b/share/magics/110m/ne_110m_ocean.shp
new file mode 100644
index 0000000..283f062
Binary files /dev/null and b/share/magics/110m/ne_110m_ocean.shp differ
diff --git a/share/magics/110m/ne_110m_ocean.shx b/share/magics/110m/ne_110m_ocean.shx
new file mode 100644
index 0000000..e95da9f
Binary files /dev/null and b/share/magics/110m/ne_110m_ocean.shx differ
diff --git a/share/magics/110m/ne_110m_rivers_lake_centerlines.VERSION.txt b/share/magics/110m/ne_110m_rivers_lake_centerlines.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/110m/ne_110m_rivers_lake_centerlines.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/110m/110m_rivers_lake_centerlines.dbf b/share/magics/110m/ne_110m_rivers_lake_centerlines.dbf
similarity index 97%
rename from share/magics/110m/110m_rivers_lake_centerlines.dbf
rename to share/magics/110m/ne_110m_rivers_lake_centerlines.dbf
index f381e9f..54b478a 100644
Binary files a/share/magics/110m/110m_rivers_lake_centerlines.dbf and b/share/magics/110m/ne_110m_rivers_lake_centerlines.dbf differ
diff --git a/share/magics/10m_full/10m_land.prj b/share/magics/110m/ne_110m_rivers_lake_centerlines.prj
similarity index 100%
copy from share/magics/10m_full/10m_land.prj
copy to share/magics/110m/ne_110m_rivers_lake_centerlines.prj
diff --git a/share/magics/110m/110m_rivers_lake_centerlines.shp b/share/magics/110m/ne_110m_rivers_lake_centerlines.shp
similarity index 99%
rename from share/magics/110m/110m_rivers_lake_centerlines.shp
rename to share/magics/110m/ne_110m_rivers_lake_centerlines.shp
index ce7f366..81a5baf 100644
Binary files a/share/magics/110m/110m_rivers_lake_centerlines.shp and b/share/magics/110m/ne_110m_rivers_lake_centerlines.shp differ
diff --git a/share/magics/110m/110m_rivers_lake_centerlines.shx b/share/magics/110m/ne_110m_rivers_lake_centerlines.shx
similarity index 63%
rename from share/magics/110m/110m_rivers_lake_centerlines.shx
rename to share/magics/110m/ne_110m_rivers_lake_centerlines.shx
index 4a2adf0..ea87d97 100644
Binary files a/share/magics/110m/110m_rivers_lake_centerlines.shx and b/share/magics/110m/ne_110m_rivers_lake_centerlines.shx differ
diff --git a/share/magics/50m/50m_admin_0_boundary_lines_land.shx b/share/magics/50m/50m_admin_0_boundary_lines_land.shx
deleted file mode 100644
index db003f7..0000000
Binary files a/share/magics/50m/50m_admin_0_boundary_lines_land.shx and /dev/null differ
diff --git a/share/magics/50m/50m_admin_1_states_provinces_shp.dbf b/share/magics/50m/50m_admin_1_states_provinces_shp.dbf
deleted file mode 100644
index 87a0bb6..0000000
Binary files a/share/magics/50m/50m_admin_1_states_provinces_shp.dbf and /dev/null differ
diff --git a/share/magics/50m/50m_admin_1_states_provinces_shp.prj b/share/magics/50m/50m_admin_1_states_provinces_shp.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/50m/50m_admin_1_states_provinces_shp.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/50m/50m_admin_1_states_provinces_shp.shp b/share/magics/50m/50m_admin_1_states_provinces_shp.shp
deleted file mode 100644
index 4d3c6a5..0000000
Binary files a/share/magics/50m/50m_admin_1_states_provinces_shp.shp and /dev/null differ
diff --git a/share/magics/50m/50m_admin_1_states_provinces_shp.shx b/share/magics/50m/50m_admin_1_states_provinces_shp.shx
deleted file mode 100644
index 0ea01f0..0000000
Binary files a/share/magics/50m/50m_admin_1_states_provinces_shp.shx and /dev/null differ
diff --git a/share/magics/50m/50m_lakes.prj b/share/magics/50m/50m_lakes.prj
deleted file mode 100644
index 9e35477..0000000
--- a/share/magics/50m/50m_lakes.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984", DATUM["D_WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]
\ No newline at end of file
diff --git a/share/magics/50m/50m_lakes.shp b/share/magics/50m/50m_lakes.shp
deleted file mode 100644
index d74e2b5..0000000
Binary files a/share/magics/50m/50m_lakes.shp and /dev/null differ
diff --git a/share/magics/50m/50m_lakes.shx b/share/magics/50m/50m_lakes.shx
deleted file mode 100644
index 1250aa9..0000000
Binary files a/share/magics/50m/50m_lakes.shx and /dev/null differ
diff --git a/share/magics/50m/50m_land.dbf b/share/magics/50m/50m_land.dbf
deleted file mode 100644
index 6919654..0000000
Binary files a/share/magics/50m/50m_land.dbf and /dev/null differ
diff --git a/share/magics/50m/50m_land.prj b/share/magics/50m/50m_land.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/50m/50m_land.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/50m/50m_land.shp b/share/magics/50m/50m_land.shp
deleted file mode 100644
index 8f0a1e6..0000000
Binary files a/share/magics/50m/50m_land.shp and /dev/null differ
diff --git a/share/magics/50m/50m_land.shx b/share/magics/50m/50m_land.shx
deleted file mode 100644
index 1dd4b14..0000000
Binary files a/share/magics/50m/50m_land.shx and /dev/null differ
diff --git a/share/magics/50m/50m_rivers_lake_centerlines.dbf b/share/magics/50m/50m_rivers_lake_centerlines.dbf
deleted file mode 100644
index 48edea4..0000000
Binary files a/share/magics/50m/50m_rivers_lake_centerlines.dbf and /dev/null differ
diff --git a/share/magics/50m/50m_rivers_lake_centerlines.prj b/share/magics/50m/50m_rivers_lake_centerlines.prj
deleted file mode 100644
index f45cbad..0000000
--- a/share/magics/50m/50m_rivers_lake_centerlines.prj
+++ /dev/null
@@ -1 +0,0 @@
-GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git a/share/magics/50m/50m_rivers_lake_centerlines.shp b/share/magics/50m/50m_rivers_lake_centerlines.shp
deleted file mode 100644
index cece3d0..0000000
Binary files a/share/magics/50m/50m_rivers_lake_centerlines.shp and /dev/null differ
diff --git a/share/magics/50m/50m_rivers_lake_centerlines.shp.xml b/share/magics/50m/50m_rivers_lake_centerlines.shp.xml
deleted file mode 100644
index 0caec6a..0000000
--- a/share/magics/50m/50m_rivers_lake_centerlines.shp.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<!--<!DOCTYPE metadata SYSTEM "http://www.esri.com/metadata/esriprof80.dtd">-->
-<metadata xml:lang="en"><Esri><MetaID>{3812ED81-D053-4AF8-A10D-6B5BCD28AB4F}</MetaID><CreaDate>20091201</CreaDate><CreaTime>01491200</CreaTime><SyncOnce>FALSE</SyncOnce><SyncDate>20091201</SyncDate><SyncTime>01491300</SyncTime><ModDate>20091201</ModDate><ModTime>01491300</ModTime><DataProperties><lineage><Process ToolSource="C:\Program Files\ArcGIS\ArcToolbox\Toolboxes\Data Management Tools.tbx\Dissolve" Date="20091201" Time="014915">Dissolve 50m-rivers-lake-centerlines C:\ProjectFiles\2 [...]
diff --git a/share/magics/50m/50m_rivers_lake_centerlines.shx b/share/magics/50m/50m_rivers_lake_centerlines.shx
deleted file mode 100644
index ac626bd..0000000
Binary files a/share/magics/50m/50m_rivers_lake_centerlines.shx and /dev/null differ
diff --git a/share/magics/50m/ne_50m_admin_0_boundary_lines_land.VERSION.txt b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/50m/50m_admin_0_boundary_lines_land.dbf b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.dbf
similarity index 68%
rename from share/magics/50m/50m_admin_0_boundary_lines_land.dbf
rename to share/magics/50m/ne_50m_admin_0_boundary_lines_land.dbf
index d4b04ea..f384f1c 100644
Binary files a/share/magics/50m/50m_admin_0_boundary_lines_land.dbf and b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.dbf differ
diff --git a/share/magics/10m/10m_admin_1_states_provinces_shp.prj b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.prj
similarity index 100%
rename from share/magics/10m/10m_admin_1_states_provinces_shp.prj
rename to share/magics/50m/ne_50m_admin_0_boundary_lines_land.prj
diff --git a/share/magics/50m/50m_admin_0_boundary_lines_land.shp b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.shp
similarity index 98%
rename from share/magics/50m/50m_admin_0_boundary_lines_land.shp
rename to share/magics/50m/ne_50m_admin_0_boundary_lines_land.shp
index 1ba5cf9..4f7e65c 100644
Binary files a/share/magics/50m/50m_admin_0_boundary_lines_land.shp and b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.shp differ
diff --git a/share/magics/50m/ne_50m_admin_0_boundary_lines_land.shx b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.shx
new file mode 100644
index 0000000..3d42f9f
Binary files /dev/null and b/share/magics/50m/ne_50m_admin_0_boundary_lines_land.shx differ
diff --git a/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.VERSION.txt b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.VERSION.txt
new file mode 100644
index 0000000..a2a5dfc
--- /dev/null
+++ b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.VERSION.txt
@@ -0,0 +1 @@
+2.0.0_rc2
\ No newline at end of file
diff --git a/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.dbf b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.dbf
new file mode 100644
index 0000000..b36577a
Binary files /dev/null and b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.dbf differ
diff --git a/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.prj b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.prj
new file mode 100644
index 0000000..4dcc580
--- /dev/null
+++ b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.017453292519943295],VERTCS["WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PARAMETER["Vertical_Shift",0.0],PARAMETER["Direction",1.0],UNIT["Meter",1.0]]]
\ No newline at end of file
diff --git a/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shp b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shp
new file mode 100644
index 0000000..fbeac3c
Binary files /dev/null and b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shp differ
diff --git a/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shx b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shx
new file mode 100644
index 0000000..87ee522
Binary files /dev/null and b/share/magics/50m/ne_50m_admin_1_states_provinces_lines_shp.shx differ
diff --git a/share/magics/50m/ne_50m_land.VERSION.txt b/share/magics/50m/ne_50m_land.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/50m/ne_50m_land.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/50m/ne_50m_land.dbf b/share/magics/50m/ne_50m_land.dbf
new file mode 100644
index 0000000..7150ea9
Binary files /dev/null and b/share/magics/50m/ne_50m_land.dbf differ
diff --git a/share/magics/10m_full/10m_land.prj b/share/magics/50m/ne_50m_land.prj
similarity index 100%
copy from share/magics/10m_full/10m_land.prj
copy to share/magics/50m/ne_50m_land.prj
diff --git a/share/magics/50m/ne_50m_land.qpj b/share/magics/50m/ne_50m_land.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/50m/ne_50m_land.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/50m/ne_50m_land.shp b/share/magics/50m/ne_50m_land.shp
new file mode 100644
index 0000000..25d3b2c
Binary files /dev/null and b/share/magics/50m/ne_50m_land.shp differ
diff --git a/share/magics/50m/ne_50m_land.shx b/share/magics/50m/ne_50m_land.shx
new file mode 100644
index 0000000..ded5bcb
Binary files /dev/null and b/share/magics/50m/ne_50m_land.shx differ
diff --git a/share/magics/50m/ne_50m_ocean.VERSION.txt b/share/magics/50m/ne_50m_ocean.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/50m/ne_50m_ocean.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/50m/50m_lakes.dbf b/share/magics/50m/ne_50m_ocean.dbf
similarity index 56%
rename from share/magics/50m/50m_lakes.dbf
rename to share/magics/50m/ne_50m_ocean.dbf
index 3a4b846..ac177e6 100644
Binary files a/share/magics/50m/50m_lakes.dbf and b/share/magics/50m/ne_50m_ocean.dbf differ
diff --git a/share/magics/10m_full/10m_land.prj b/share/magics/50m/ne_50m_ocean.prj
similarity index 100%
rename from share/magics/10m_full/10m_land.prj
rename to share/magics/50m/ne_50m_ocean.prj
diff --git a/share/magics/50m/ne_50m_ocean.qpj b/share/magics/50m/ne_50m_ocean.qpj
new file mode 100644
index 0000000..5fbc831
--- /dev/null
+++ b/share/magics/50m/ne_50m_ocean.qpj
@@ -0,0 +1 @@
+GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
diff --git a/share/magics/50m/ne_50m_ocean.shp b/share/magics/50m/ne_50m_ocean.shp
new file mode 100644
index 0000000..b9e2459
Binary files /dev/null and b/share/magics/50m/ne_50m_ocean.shp differ
diff --git a/share/magics/50m/ne_50m_ocean.shx b/share/magics/50m/ne_50m_ocean.shx
new file mode 100644
index 0000000..a4e33aa
Binary files /dev/null and b/share/magics/50m/ne_50m_ocean.shx differ
diff --git a/share/magics/50m/ne_50m_ocean_orig.VERSION.txt b/share/magics/50m/ne_50m_ocean_orig.VERSION.txt
new file mode 100644
index 0000000..359a5b9
--- /dev/null
+++ b/share/magics/50m/ne_50m_ocean_orig.VERSION.txt
@@ -0,0 +1 @@
+2.0.0
\ No newline at end of file
diff --git a/share/magics/50m/ne_50m_rivers_lake_centerlines.VERSION.txt b/share/magics/50m/ne_50m_rivers_lake_centerlines.VERSION.txt
new file mode 100644
index 0000000..56fea8a
--- /dev/null
+++ b/share/magics/50m/ne_50m_rivers_lake_centerlines.VERSION.txt
@@ -0,0 +1 @@
+3.0.0
\ No newline at end of file
diff --git a/share/magics/50m/ne_50m_rivers_lake_centerlines.dbf b/share/magics/50m/ne_50m_rivers_lake_centerlines.dbf
new file mode 100644
index 0000000..9002b07
Binary files /dev/null and b/share/magics/50m/ne_50m_rivers_lake_centerlines.dbf differ
diff --git a/share/magics/10m_full/10m_rivers_lake_centerlines.prj b/share/magics/50m/ne_50m_rivers_lake_centerlines.prj
similarity index 100%
rename from share/magics/10m_full/10m_rivers_lake_centerlines.prj
rename to share/magics/50m/ne_50m_rivers_lake_centerlines.prj
diff --git a/share/magics/50m/ne_50m_rivers_lake_centerlines.shp b/share/magics/50m/ne_50m_rivers_lake_centerlines.shp
new file mode 100644
index 0000000..1f418cb
Binary files /dev/null and b/share/magics/50m/ne_50m_rivers_lake_centerlines.shp differ
diff --git a/share/magics/50m/ne_50m_rivers_lake_centerlines.shx b/share/magics/50m/ne_50m_rivers_lake_centerlines.shx
new file mode 100644
index 0000000..92fb412
Binary files /dev/null and b/share/magics/50m/ne_50m_rivers_lake_centerlines.shx differ
diff --git a/share/magics/contour_ids.json b/share/magics/contour_ids.json
index 1e13780..d926fc7 100644
--- a/share/magics/contour_ids.json
+++ b/share/magics/contour_ids.json
@@ -1 +1,185 @@
-{"Contour shade (Range: -10 - 10)": 72, "925 hPa geopotential DEFAULT": 37, "850 hPa relative vorticity DEFAULT": 34, "925 hPa temperature DEFAULT": 39, "Mean wave period probability DEFAULT": 143, "Convective available potential energy (CAPE) probability DEFAULT": 117, "Ensemble mean for 300 hPa geopotential height DEFAULT": 121, "2m temperature extreme forecast index DEFAULT": 13, "Contour shade (Range: 30 - 100, green)": 109, "Contour (interval 5, thickness 2, blue)": 53, "300 hPa win [...]
\ No newline at end of file
+{
+ "10 m wind gust DEFAULT": 0,
+ "10m wind gust extreme forecast index DEFAULT": 1,
+ "10m wind gusts percentile DEFAULT": 2,
+ "10m wind gusts probability DEFAULT": 3,
+ "10m wind percentile DEFAULT": 4,
+ "10m wind probability DEFAULT": 5,
+ "10m wind speed DEFAULT": 6,
+ "10m wind speed extreme forecast index DEFAULT": 7,
+ "2 metre dew point temperature DEFAULT": 8,
+ "2 metre dew point temperature percentile DEFAULT": 9,
+ "2 metre dew point temperature probability DEFAULT": 10,
+ "200 hPa wind speed DEFAULT": 11,
+ "2m temperature DEFAULT": 12,
+ "2m temperature extreme forecast index DEFAULT": 13,
+ "2m temperature percentile DEFAULT": 14,
+ "2m temperature probability DEFAULT": 15,
+ "300 hPa geopotential DEFAULT": 16,
+ "300 hPa relative vorticity DEFAULT": 17,
+ "300 hPa wind speed DEFAULT": 18,
+ "315K (potential temperature level) potential vorticity DEFAULT": 19,
+ "500 hPa geopotential DEFAULT": 20,
+ "500 hPa relative humidity DEFAULT": 21,
+ "500 hPa relative vorticity DEFAULT": 22,
+ "500 hPa temperature DEFAULT": 23,
+ "500 hPa wind speed DEFAULT": 24,
+ "700 hPa divergence DEFAULT": 25,
+ "700 hPa geopotential DEFAULT": 26,
+ "700 hPa relative humidity DEFAULT": 27,
+ "700 hPa relative vorticity DEFAULT": 28,
+ "700 hPa temperature DEFAULT": 29,
+ "700 hPa vertical velocity DEFAULT": 30,
+ "700 hPa wind speed DEFAULT": 31,
+ "850 hPa geopotential DEFAULT": 32,
+ "850 hPa relative humidity DEFAULT": 33,
+ "850 hPa relative vorticity DEFAULT": 34,
+ "850 hPa temperature DEFAULT": 35,
+ "850 hPa wind speed DEFAULT": 36,
+ "925 hPa geopotential DEFAULT": 37,
+ "925 hPa relative humidity DEFAULT": 38,
+ "925 hPa temperature DEFAULT": 39,
+ "925 hPa wind speed DEFAULT": 40,
+ "Contour (Interval 10, green)": 41,
+ "Contour (Interval 2, red, dash)": 42,
+ "Contour (Interval 5, orange-red)": 43,
+ "Contour (Range: -10 - 02, thickness 3, blue-red)": 44,
+ "Contour (Range: -5 - 50, thickness 2, blue-red)": 45,
+ "Contour (Range: 1 - 250, thickness 2, blue)": 46,
+ "Contour (Range: 65 - 100)": 47,
+ "Contour (interval 1, black)": 48,
+ "Contour (interval 1, thickness 1, violet)": 49,
+ "Contour (interval 1, thickness 2, black)": 50,
+ "Contour (interval 4, thickness 2, brown)": 51,
+ "Contour (interval 5, thickness 2, black)": 52,
+ "Contour (interval 5, thickness 2, blue)": 53,
+ "Contour (interval 5, thickness 2, green)": 54,
+ "Contour (interval 5, thickness 2, red)": 55,
+ "Contour (min:150, mustard for orography)": 56,
+ "Contour and shade (Range: -48 - 56, interval 2)": 57,
+ "Contour dot shade (0-100%, blue-purple)": 58,
+ "Contour shade (0-1, intervals in octas)": 59,
+ "Contour shade (0-100%, blue-purple)": 60,
+ "Contour shade (0-100%, every 10% Blue to yellow)": 61,
+ "Contour shade (0-100%, every 10%)": 62,
+ "Contour shade (0-100%, green)": 63,
+ "Contour shade (0-100%, light blue-purple)": 64,
+ "Contour shade (0-100%, light green)": 65,
+ "Contour shade (0-100%, light red)": 66,
+ "Contour shade (0-100%, red)": 67,
+ "Contour shade (Coarse range: -15 - 15)": 68,
+ "Contour shade (Grey from 02 to 100)": 69,
+ "Contour shade (LESS CONTOURS) Range: -200 - 200": 70,
+ "Contour shade (MORE CONTOURS) Range: -200 - 200": 71,
+ "Contour shade (Range: -10 - 10)": 72,
+ "Contour shade (Range: -200 - -1)": 73,
+ "Contour shade (Range: -32 - 42, Interval 2)": 74,
+ "Contour shade (Range: -48 - 56)": 75,
+ "Contour shade (Range: -50 - -005 )": 76,
+ "Contour shade (Range: -50 - 50 )": 77,
+ "Contour shade (Range: -52 - 48)": 78,
+ "Contour shade (Range: -64 - 52)": 79,
+ "Contour shade (Range: -76 - 56)": 80,
+ "Contour shade (Range: 00 - 10 & 15 - 20)": 81,
+ "Contour shade (Range: 00 - 185)": 82,
+ "Contour shade (Range: 00 - 200)": 83,
+ "Contour shade (Range: 00 - 200), contours (warnings)": 84,
+ "Contour shade (Range: 00 - 200, Douglas sea scale)": 85,
+ "Contour shade (Range: 005 - 50 )": 86,
+ "Contour shade (Range: 025 to 100)": 87,
+ "Contour shade (Range: 03 - 50, Beaufort wind scale)": 88,
+ "Contour shade (Range: 05 - 10)": 89,
+ "Contour shade (Range: 05 - 250, with isolines)": 90,
+ "Contour shade (Range: 05 - 300, no isolines)": 91,
+ "Contour shade (Range: 08 - 25 in K, more levels)": 92,
+ "Contour shade (Range: 08 - 25), used for T spread": 93,
+ "Contour shade (Range: 1 - 200)": 94,
+ "Contour shade (Range: 1 to 1000)": 95,
+ "Contour shade (Range: 1 to 10000 as in operational web)": 96,
+ "Contour shade (Range: 10 - 100 as percentage)": 97,
+ "Contour shade (Range: 10 - 100, green)": 98,
+ "Contour shade (Range: 10 - 250, no isolines)": 99,
+ "Contour shade (Range: 10 - 70, yellow-red)": 100,
+ "Contour shade (Range: 2 - 30)": 101,
+ "Contour shade (Range: 2 - 30, more levels)": 102,
+ "Contour shade (Range: 2 - 50)": 103,
+ "Contour shade (Range: 2 - 50, interval 2)": 104,
+ "Contour shade (Range: 2 - 50, more levels)": 105,
+ "Contour shade (Range: 2 - 75)": 106,
+ "Contour shade (Range: 25 to 100 as percentage)": 107,
+ "Contour shade (Range: 30 - 100, all colours)": 108,
+ "Contour shade (Range: 30 - 100, green)": 109,
+ "Contour shade (Range: 5 - 70, all colours)": 110,
+ "Contour shade (Range: 5 - 70, yellow-red)": 111,
+ "Contour shade (Range: 65 - 100)": 112,
+ "Contour with H-L and labels (interval 5, black)": 113,
+ "Contour with H-L, no labels (interval 5, black)": 114,
+ "Contour with no labels (interval 5, black)": 115,
+ "Convective available potential energy (CAPE) DEFAULT": 116,
+ "Convective available potential energy (CAPE) probability DEFAULT": 117,
+ "Convective precipitation DEFAULT": 118,
+ "Convective precipitation percentile DEFAULT": 119,
+ "Convective precipitation probability DEFAULT": 120,
+ "Ensemble mean for 300 hPa geopotential height DEFAULT": 121,
+ "Ensemble mean for 500 hPa geopotential DEFAULT": 122,
+ "Ensemble mean for 850 hPa temperature DEFAULT": 123,
+ "Ensemble mean for 850 hPa wind speed DEFAULT": 124,
+ "Ensemble mean for mean sea level pressure DEFAULT": 125,
+ "Ensemble spread for 300 hPa geopotential height DEFAULT": 126,
+ "Ensemble spread for 500 hPa geopotential DEFAULT": 127,
+ "Ensemble spread for 850 hPa temperature DEFAULT": 128,
+ "Ensemble spread for 850 hPa wind speed DEFAULT": 129,
+ "Ensemble spread for mean sea level pressure DEFAULT": 130,
+ "High cloud cover DEFAULT": 131,
+ "Hurricane strike probability DEFAULT": 132,
+ "Low cloud cover DEFAULT": 133,
+ "Marker (Coarse range: 05 - 10) used for EFI WG": 134,
+ "Marker in kelly green (Coarse range: 06 - 10) used for EFI TP": 135,
+ "Maximum 2 metre temperature DEFAULT": 136,
+ "Maximum 2 metre temperature probability DEFAULT": 137,
+ "Mean period of total swell DEFAULT": 138,
+ "Mean period of wind waves DEFAULT": 139,
+ "Mean sea level pressure DEFAULT": 140,
+ "Mean wave period DEFAULT": 141,
+ "Mean wave period percentile DEFAULT": 142,
+ "Mean wave period probability DEFAULT": 143,
+ "Medium cloud cover DEFAULT": 144,
+ "Minimum 2 metre temperature DEFAULT": 145,
+ "Minimum 2 metre temperature probability DEFAULT": 146,
+ "Model orography from deterministic forecast DEFAULT": 147,
+ "Model orography from ensemble forecast DEFAULT": 148,
+ "Orography shading with 16 levels": 149,
+ "Orography shading with 28 levels": 150,
+ "Orography shading with 28 levels (brown)": 151,
+ "Probability of combined events of 2 metre Temperature and total precipitation DEFAULT": 152,
+ "Probability of combined events of wind gust and total snowfall DEFAULT": 153,
+ "Probability of combined events of wind speed and total precipitation DEFAULT": 154,
+ "Sea ice cover as fraction of a grid box DEFAULT": 155,
+ "Shade from 100 to 4500 (orange-blue)": 156,
+ "Significant height of total swell DEFAULT": 157,
+ "Significant height of wind waves DEFAULT": 158,
+ "Significant wave height DEFAULT": 159,
+ "Significant wave height percentile DEFAULT": 160,
+ "Significant wave height probability DEFAULT": 161,
+ "Snow coverage as percentage of a grid box DEFAULT": 162,
+ "Snow depth DEFAULT": 163,
+ "Stratiform precipitation DEFAULT": 164,
+ "Stratiform precipitation percentile DEFAULT": 165,
+ "Stratiform precipitation probability DEFAULT": 166,
+ "Temperature below 0 C": 167,
+ "Total precipitation DEFAULT": 168,
+ "Total precipitation extreme forecast index DEFAULT": 169,
+ "Total precipitation percentile DEFAULT": 170,
+ "Total precipitation probability DEFAULT": 171,
+ "Total snowfall DEFAULT": 172,
+ "Total snowfall probability DEFAULT": 173,
+ "Transparency grey (RGBA)": 174,
+ "Transparency grey for sct and bkn (or ovc) clouds": 175,
+ "Transparency light grey": 176,
+ "Transparency light grey for sct and bkn (or ovc) clouds": 177,
+ "Transparency white": 178,
+ "Transparency white for sct and bkn (or ovc) clouds": 179,
+ "Transparent grey (RGBA) 02-1 One level": 180,
+ "Tropical cyclone strike probability DEFAULT": 181,
+ "Tropical storm strike probability DEFAULT": 182
+}
diff --git a/share/magics/contours.json b/share/magics/contours.json
index a3532ff..76c47c3 100644
--- a/share/magics/contours.json
+++ b/share/magics/contours.json
@@ -1 +1,1317 @@
-{"41": {"contour_line_colour": "yellow_green", "contour_label_colour": "rgb(0.25,0.75,0)", "contour_label_height": "0.4", "contour_reference_level": "50", "contour_label_frequency": "1", "contour_hilo": "off", "contour_line_thickness": "2", "contour_level_selection_type": "interval", "contour_label": "on", "contour_min_level": "30", "contour_highlight_frequency": "3", "contour_highlight_colour": "kelly_green", "contour_highlight_thickness": "3", "legend": "on", "contour_interval": "10"}, [...]
\ No newline at end of file
+{
+ "100": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "10/15/20/25/30/40/50/60/70",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "10",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "clockwise",
+ "contour_shade_max_level_colour": "red",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "10",
+ "contour_shade_min_level_colour": "yellow",
+ "legend": "on"
+ },
+ "101": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "2/4/6/8/12/18/30",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.85,0.73,0.86)/RGB(0.76,0.53,0.77)/RGB(0.73,0.34,0.74)/RGB(0.85,0.13,0.88)/RGB(0.96,0,1.0)/RGB(0.98,0.51,1.0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "30",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "102": {
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "2/3/4/5/6/8/10/12/14/18/25/30",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "red",
+ "contour_reference_level": "2",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "BLUE_GREEN/BLUISH_GREEN/YELLOW_GREEN/YELLOW/ORANGE_YELLOW/YELLOWISH_ORANGE/ORANGE/TANGERINE/OCHRE/MUSTARD/TAN",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "30",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "103": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "2/4/8/12/18/25/50",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.85,0.73,0.86)/RGB(0.76,0.53,0.77)/RGB(0.73,0.34,0.74)/RGB(0.85,0.13,0.88)/RGB(0.96,0,1.0)/RGB(0.98,0.51,1.0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "50",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "104": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_interval": "2",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.6,0.9,1)/rgb(0.45,0.7,1)/rgb(0.3,0.5,1)/rgb(0.15,0.3,1)/rgb(0.8,1,0.2)/rgb(0.65,0.95,0)/rgb(0.5,0.85,0)/rgb(0.15,0.75,0.1)/rgb(0,0.55,0.19)/rgb(1,0.85,0)/rgb(1,0.74,0)/rgb(1,0.62,0)/rgb(1,0.5,0)/rgb(0.85,0.45,0)/rgb(1,0.75,0.75)/rgb(1,0.5,0.5)/rgb(1,0,0)/rgb(0.8,0,0)/rgb(0.6,0,0)/rgb(0.85,0.6,1)/rgb(0.75,0.4,1)/rgb(0.6,0.2,1)/rgb(0.5,0,0.9)/rgb(0.35,0,0.6)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "50",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "105": {
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "2/3/4/5/6/8/10/12/14/16/20/50",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "red",
+ "contour_reference_level": "2",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "BLUE_GREEN/BLUISH_GREEN/YELLOW_GREEN/YELLOW/ORANGE_YELLOW/YELLOWISH_ORANGE/ORANGE/TANGERINE/OCHRE/MUSTARD/TAN",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "50",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "106": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "2/6/12/18/30/40/75",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.85,0.73,0.86)/RGB(0.76,0.53,0.77)/RGB(0.73,0.34,0.74)/RGB(0.85,0.13,0.88)/RGB(0.96,0,1.0)/RGB(0.98,0.51,1.0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "50",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "2"
+ },
+ "107": {
+ "contour": "off",
+ "contour_interpolation_ceiling": "100",
+ "contour_label": "off",
+ "contour_level_list": "25/50/75/99/110",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_max_level_colour": "white",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "20",
+ "contour_shade_min_level_colour": "grey",
+ "legend": "on"
+ },
+ "108": {
+ "contour_hi_min_value": "15",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "30/40/50/60/70/80/90/100",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,1,0)/rgb(1,1,0.3)/rgb(1,0.85,0)/rgb(1,0.7,0)/rgb(1,0,0)/rgb(0.9,0,0.5)/rgb(0.7,0,0.7)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "30",
+ "legend": "on"
+ },
+ "109": {
+ "contour_hi_min_value": "15",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "30/40/50/60/70/80/90/100",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_max_level_colour": "evergreen",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "30",
+ "contour_shade_min_level_colour": "yellow",
+ "legend": "on"
+ },
+ "110": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/10/15/20/25/30/40/50/60/70",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.8,1,1)/rgb(0.5,0.95,1)/rgb(0,1,0)/rgb(1,1,0.3)/rgb(1,0.85,0)/rgb(1,0.7,0)/rgb(1,0,0)/rgb(0.9,0,0.5)/rgb(0.7,0,0.7)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "legend": "on"
+ },
+ "111": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/10/15/20/25/30/40/50/60/70",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "clockwise",
+ "contour_shade_max_level_colour": "red",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "yellow",
+ "legend": "on"
+ },
+ "112": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "65/80/95/200",
+ "contour_level_selection_type": "level_list",
+ "contour_line_thickness": "1",
+ "contour_min_level": "65",
+ "contour_reference_level": "65",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.8,1,0.8)/rgb(0.7,0.95,0.9)/rgb(0.6,0.75,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "65",
+ "contour_shade_min_level_colour": "yellowish_green",
+ "legend": "on"
+ },
+ "113": {
+ "contour_hi_colour": "black",
+ "contour_highlight_colour": "black",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "on",
+ "contour_hilo_suppress_radius": "30",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "2",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "1",
+ "contour_lo_colour": "black",
+ "legend": "on"
+ },
+ "114": {
+ "contour_hi_colour": "black",
+ "contour_highlight_colour": "black",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "on",
+ "contour_hilo_suppress_radius": "30",
+ "contour_interval": "5",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "1",
+ "contour_lo_colour": "black",
+ "legend": "on"
+ },
+ "115": {
+ "contour_highlight_colour": "black",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "1",
+ "legend": "on"
+ },
+ "134": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.6/0.8/1.5",
+ "contour_level_selection_type": "list",
+ "contour_shade": "on",
+ "contour_shade_colour_table": "bluish_purple/bluish_purple",
+ "contour_shade_height_table": "0.1/0.2",
+ "contour_shade_marker_table": "5/17",
+ "contour_shade_max_level": "1.5",
+ "contour_shade_min_level": "0.6",
+ "contour_shade_technique": "marker",
+ "legend": "on"
+ },
+ "135": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.6/0.8/1.5",
+ "contour_level_selection_type": "list",
+ "contour_shade": "on",
+ "contour_shade_colour_table": "kelly_green/kelly_green",
+ "contour_shade_height_table": "0.1/0.2",
+ "contour_shade_marker_table": "6/20",
+ "contour_shade_max_level": "1.5",
+ "contour_shade_min_level": "0.6",
+ "contour_shade_technique": "marker",
+ "legend": "on"
+ },
+ "149": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-4/-0.002/0.01/0.2/1/2/3/5/8/10/15/20/25/30/40/50/70",
+ "contour_level_selection_type": "level_list",
+ "contour_line_thickness": "3",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.15,0.5,0.4)/none/RGB(0.16,0.4,0)/RGB(0.2,0.5,0)/RGB(0.3,0.6,0)/RGB(0.4,0.7,0)/RGB(0.5,0.8,0)/RGB(0.7,0.9,0)/RGB(0.9,1,0)/RGB(0.9,0.8,0)/RGB(0.8,0.6,0)/RGB(0.7,0.45,0)/RGB(0.6,0.3,0)/RGB(0.45,0.2,0)/RGB(0.5,0.5,0.5)/RGB(1,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "70",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-4",
+ "legend": "on"
+ },
+ "150": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-4/-0.002/0.01/0.2/0.5/1/1.5/2/2.5/3/4/5/6/7/8/9/10/12.5/15/17.5/20/22.5/25/30/35/40/45/50/70",
+ "contour_level_selection_type": "level_list",
+ "contour_line_thickness": "3",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.15,0.5,0.4)/none/RGB(0.16,0.4,0)/RGB(0.18,0.45,0)/RGB(0.2,0.5,0)/RGB(0.25,0.55,0)/RGB(0.3,0.6,0)/RGB(0.35,0.65,0)/RGB(0.4,0.7,0)/RGB(0.45,0.75,0)/RGB(0.5,0.8,0)/RGB(0.57,0.83,0)/RGB(0.64,0.86,0)/RGB(0.7,0.9,0)/RGB(0.8,0.95,0)/RGB(0.9,1,0)/RGB(0.9,0.8,0)/RGB(0.85,0.7,0)/RGB(0.8,0.6,0)/RGB(0.75,0.52,0)/RGB(0.7,0.45,0)/RGB(0.65,0.37,0)/RGB(0.6,0.3,0)/RGB(0.45,0.2,0)/RGB(0.45,0.3,0.1)/RGB(0.5,0.4,0.3)/RGB(0.5,0.5,0.5)/RGB(1,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "70",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-4",
+ "legend": "on"
+ },
+ "151": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-4/-0.002/0.01/0.2/0.5/1/1.5/2/2.5/3/4/5/6/7/8/9/10/12.5/15/17.5/20/22.5/25/30/35/40/45/50/70",
+ "contour_level_selection_type": "level_list",
+ "contour_line_thickness": "3",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.38,0.14,0)/none/rgb(0.42,0.16,0)/rgb(0.46,0.18,0)/rgb(0.5,0.21,0)/rgb(0.54,0.24,0.01)/rgb(0.58,0.26,0.02)/rgb(0.62,0.28,0.03)/rgb(0.66,0.31,0.04)/rgb(0.7,0.34,0.06)/rgb(0.74,0.37,0.08)/rgb(0.78,0.4,0.1)/rgb(0.82,0.43,0.12)/rgb(0.86,0.46,0.14)/rgb(0.89,0.49,0.17)/rgb(0.92,0.52,0.2)/rgb(0.94,0.55,0.23)/rgb(0.96,0.58,0.26)/rgb(0.98,0.62,0.29)/rgb(1,0.66,0.32)/rgb(1,0.7,0.36)/rgb(1,0.74,0.4)/rgb(1,0.78,0.45)/rgb(1,0.82,0.5)/rgb(1,0.86,0.6)/rgb(1,0. [...]
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "70",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-4",
+ "legend": "on"
+ },
+ "156": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_interval": "200",
+ "contour_label": "off",
+ "contour_level_list": "100/200/300/500/750/1000/1250/1500/1750/2000/2250/2500/2750/3000/3500/4000/4500",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(1.00,0.35,0.00),rgb(1.00, 0.55, 0.00)/rgb(1.00, 0.67, 0.00)/rgb(1.00, 0.78, 0.00)/rgb(1.00, 0.89, 0.00)/rgb(1.00, 1.00, 0.00)/rgb(0.75, 0.98, 0.00)/rgb(0.60, 0.86, 0.10)/rgb(0.43, 0.77, 0.20)/rgb(0.30, 0.68, 0.40)/rgb(0.50, 0.90, 1.00)/rgb(0.50, 0.70, 1.00)/rgb(0.37, 0.50, 1.00)/rgb(0.20, 0.30, 0.90)/rgb(0.10, 0.15, 0.75)/rgb(0.00, 0.05, 0.55)/rgb(0.00, 0.00, 0.35)/rgb(0.00, 0.00, 0.20)",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_label_blanking": "on",
+ "contour_shade_max_level": "4200",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "100",
+ "legend": "on"
+ },
+ "167": {
+ "contour": "off",
+ "contour_label": "off",
+ "contour_level_list": "-70/0.0",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_list": "rgba(0.498,0.8,0.8,0.6)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "174": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_interpolation_ceiling": "1",
+ "contour_interpolation_floor": "0",
+ "contour_label": "off",
+ "contour_level_list": "0/0.1/0.2/0.3/0.4/0.5/0.6/0.7/0.8/0.9/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "none/rgba(0.66,0.66,0.66,0)/rgba(0.66,0.66,0.66,0.1)/rgba(0.66,0.66,0.66,0.2)/rgba(0.66,0.66,0.66,0.3)/rgba(0.66,0.66,0.66,0.4)/rgba(0.66,0.66,0.66,0.5)/rgba(0.66,0.66,0.66,0.6)/rgba(0.66,0.66,0.66,0.7)/rgba(0.66,0.66,0.66,0.8)/rgba(0.66,0.66,0.66,0.9)/rgba(0.66,0.66,0.66,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "175": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_interpolation_ceiling": "1",
+ "contour_interpolation_floor": "0",
+ "contour_label": "off",
+ "contour_level_list": "0.3125/0.6875/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgba(0.66,0.66,0.66,0.3)/rgba(0.66,0.66,0.66,0.7)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "176": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0/0.1/0.2/0.3/0.4/0.5/0.6/0.7/0.8/0.9/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "none/rgba(0.8,0.8,0.8,0)/rgba(0.8,0.8,0.8,0.1)/rgba(0.8,0.8,0.8,0.2)/rgba(0.8,0.8,0.8,0.3)/rgba(0.8,0.8,0.8,0.4)/rgba(0.8,0.8,0.8,0.5)/rgba(0.8,0.8,0.8,0.6)/rgba(0.8,0.8,0.8,0.7)/rgba(0.8,0.8,0.8,0.8)/rgba(0.8,0.8,0.8,0.9)/rgba(0.8,0.8,0.8,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "177": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.3125/0.6875/1.2",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgba(0.8,0.8,0.8,0.25)/rgba(0.8,0.8,0.8,0.6)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "178": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0/0.1/0.2/0.3/0.4/0.5/0.6/0.7/0.8/0.9/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "none/rgba(1,1,1,0)/rgba(1,1,1,0.1)/rgba(1,1,1,0.2)/rgba(1,1,1,0.3)/rgba(1,1,1,0.4)/rgba(1,1,1,0.5)/rgba(1,1,1,0.6)/rgba(1,1,1,0.7)/rgba(1,1,1,0.8)/rgba(1,1,1,0.9)/rgba(1,1,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "179": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.3125/0.6875/1.2",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgba(1,1,1,0.2)/rgba(1,1,1,0.5)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "180": {
+ "contour": "off",
+ "contour_interpolation_ceiling": "1.0",
+ "contour_label": "off",
+ "contour_level_list": "0.20/1.01",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_max_level_colour": "rgba(0.66,0.66,0.66,0.5)",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.2",
+ "contour_shade_min_level_colour": "rgba(0.66,0.66,0.66,0.5)",
+ "legend": "on"
+ },
+ "41": {
+ "contour_highlight_colour": "kelly_green",
+ "contour_highlight_frequency": "3",
+ "contour_highlight_thickness": "3",
+ "contour_hilo": "off",
+ "contour_interval": "10",
+ "contour_label": "on",
+ "contour_label_colour": "rgb(0.25,0.75,0)",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "yellow_green",
+ "contour_line_thickness": "2",
+ "contour_min_level": "30",
+ "contour_reference_level": "50",
+ "legend": "on"
+ },
+ "42": {
+ "contour_highlight_colour": "red",
+ "contour_highlight_frequency": "5",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "off",
+ "contour_interval": "2",
+ "contour_label": "on",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "red",
+ "contour_line_style": "dash",
+ "contour_max_level": "100",
+ "contour_min_level": "-100",
+ "legend": "on"
+ },
+ "43": {
+ "contour_highlight_colour": "orange",
+ "contour_highlight_frequency": "10",
+ "contour_highlight_thickness": "1",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "rgb(1,0.35,0)",
+ "contour_line_thickness": "3",
+ "contour_min_level": "10",
+ "legend": "on"
+ },
+ "44": {
+ "contour_highlight_colour": "red",
+ "contour_highlight_frequency": "10",
+ "contour_highlight_thickness": "1",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "black",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.3",
+ "contour_level_list": "-10/-5/-2/-1/-0.5/-0.2/0.2",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "blue",
+ "contour_line_thickness": "2",
+ "contour_reference_level": "0.2",
+ "legend": "on"
+ },
+ "45": {
+ "contour_highlight_colour": "blue",
+ "contour_highlight_frequency": "6",
+ "contour_highlight_thickness": "1",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "black",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.3",
+ "contour_level_list": "-5/5/10/20/50",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "red",
+ "contour_line_thickness": "2",
+ "contour_min_level": "-5",
+ "legend": "on"
+ },
+ "46": {
+ "contour_highlight_colour": "magenta",
+ "contour_highlight_frequency": "3",
+ "contour_highlight_thickness": "5",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "black",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.3",
+ "contour_level_list": "1/5/15/40/100/250",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "blue",
+ "contour_line_thickness": "2",
+ "contour_min_level": "-1",
+ "contour_reference_level": "15",
+ "legend": "on"
+ },
+ "47": {
+ "contour_highlight_frequency": "5",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "sky",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.3",
+ "contour_level_list": "65/80/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "green",
+ "contour_line_thickness": "2",
+ "contour_min_level": "65",
+ "contour_reference_level": "95",
+ "legend": "on"
+ },
+ "48": {
+ "contour_highlight_colour": "black",
+ "contour_highlight_frequency": "5",
+ "contour_highlight_style": "solid",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "off",
+ "contour_interval": "1",
+ "contour_label": "on",
+ "contour_label_frequency": "5",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "1",
+ "contour_reference_level": "1000",
+ "legend": "on"
+ },
+ "49": {
+ "contour_highlight_colour": "rgb(0.48,0.4,0.7)",
+ "contour_highlight_frequency": "100",
+ "contour_highlight_thickness": "5",
+ "contour_hilo": "off",
+ "contour_interval": "1",
+ "contour_label": "on",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "rgb(0.6,0.5,0.8)",
+ "contour_line_thickness": "2",
+ "contour_min_level": "1",
+ "contour_reference_level": "2",
+ "legend": "on"
+ },
+ "50": {
+ "contour_highlight_colour": "black",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "off",
+ "contour_interval": "1",
+ "contour_label": "on",
+ "contour_label_frequency": "5",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "51": {
+ "contour_highlight_colour": "brown",
+ "contour_highlight_thickness": "2",
+ "contour_hilo": "off",
+ "contour_interval": "4",
+ "contour_label": "on",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "brown",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "52": {
+ "contour_highlight_colour": "black",
+ "contour_highlight_thickness": "4",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "2",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "black",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "53": {
+ "contour_highlight_colour": "blue",
+ "contour_highlight_thickness": "4",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "2",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "blue",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "54": {
+ "contour_highlight_colour": "green",
+ "contour_highlight_thickness": "4",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "2",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "green",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "55": {
+ "contour_highlight_colour": "red",
+ "contour_highlight_thickness": "4",
+ "contour_hilo": "off",
+ "contour_interval": "5",
+ "contour_label": "on",
+ "contour_label_frequency": "2",
+ "contour_label_height": "0.4",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "red",
+ "contour_line_thickness": "2",
+ "legend": "on"
+ },
+ "56": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_frequency": "1",
+ "contour_label_height": "0.3",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "mustard",
+ "contour_min_level": "1.5",
+ "contour_reference_level": "0",
+ "legend": "on"
+ },
+ "57": {
+ "contour_highlight_colour": "rgb(0.4,0.1,1)",
+ "contour_highlight_frequency": "100",
+ "contour_highlight_style": "dash",
+ "contour_highlight_thickness": "3",
+ "contour_hilo": "off",
+ "contour_interval": "2",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_colour": "grey",
+ "contour_max_level": "56",
+ "contour_min_level": "-48",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.85)/rgb(0,0,0.85)/rgb(0.25,0,1)/rgb(0.25,0,1)/blue_purple/blue_purple/greenish_blue/greenish_blue/blue_green/blue_green/bluish_green/bluish_green/yellow_green/yellow_green/greenish_yellow/greenish_yellow/yellow/yellow/orangish_yellow/orangish_yellow/orange_yellow/orange_yellow/yellowish_orange/yellowish_orange/or [...]
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "56",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-48",
+ "legend": "on"
+ },
+ "58": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/125",
+ "contour_level_selection_type": "level_list",
+ "contour_max_level": "125",
+ "contour_min_level": "5",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_max_level": "125",
+ "contour_shade_max_level_colour": "blue_purple",
+ "contour_shade_method": "dot",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "cyan"
+ },
+ "59": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.01/0.1875/0.3125/0.4375/0.5625/0.6875/0.8125/0.99/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.86,0.86,0.86)/RGB(0.84,0.84,0.84)/RGB(0.82,0.82,0.82)/RGB(0.8,0.8,0.8)/RGB(0.78,0.78,0.78)/RGB(0.76,0.76,0.76)/RGB(0.74,0.74,0.74)/RGB(0.72,0.72,0.72)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.01",
+ "legend": "on"
+ },
+ "60": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_max_level_colour": "blue_purple",
+ "contour_shade_max_level_density": "550",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "cyan",
+ "contour_shade_min_level_density": "200",
+ "legend": "on"
+ },
+ "61": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/10/20/30/40/50/60/70/80/90/110",
+ "contour_level_selection_type": "level_list",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_max_level_colour": "yellow",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level_colour": "blue",
+ "legend": "on"
+ },
+ "62": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/10/20/30/40/50/60/70/80/90/110",
+ "contour_level_selection_type": "level_list",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "purple/reddish_orange/yellowish_orange/yellow/yellowish_green/kelly_green/cyan/greenish_blue/blue/violet",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "63": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_max_level_colour": "blue_green",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "yellow",
+ "legend": "on"
+ },
+ "64": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_max_level_colour": "rgb(0.7,0.55,1)",
+ "contour_shade_max_level_density": "550",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "rgb(0.85,1,1)",
+ "contour_shade_min_level_density": "200",
+ "legend": "on"
+ },
+ "65": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_max_level_colour": "rgb(0.75,1,1)",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "rgb(1,1,0.75)",
+ "legend": "on"
+ },
+ "66": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "clockwise",
+ "contour_shade_max_level_colour": "rgb(1,0.6,0.6)",
+ "contour_shade_max_level_density": "550",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "rgb(1,1,0.75)",
+ "contour_shade_min_level_density": "200",
+ "legend": "on"
+ },
+ "67": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "5/35/65/95/120",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "5",
+ "contour_reference_level": "5",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "clockwise",
+ "contour_shade_max_level_colour": "red",
+ "contour_shade_max_level_density": "550",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "yellow",
+ "contour_shade_min_level_density": "200",
+ "legend": "on"
+ },
+ "68": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-1.5/-0.75/-0.5/0.5/0.75/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "sky/rgb(0.8,0.9,0.9)/none/yellow/orange",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "69": {
+ "contour": "off",
+ "contour_interpolation_ceiling": "1.0",
+ "contour_label": "off",
+ "contour_level_list": "0.20/1.01",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_max_level_colour": "grey",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.2",
+ "contour_shade_min_level_colour": "grey",
+ "legend": "on"
+ },
+ "70": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-200/-100/-50/-20/-15/-11/-7/-5/-3/-1/1/3/5/7/11/15/20/50/100/200",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.3)/rgb(0,0,0.5)/rgb(0,0,0.9)/rgb(0,0.3,1)/rgb(0,0.45,1)/rgb(0,0.75,1)/rgb(0.2,0.95,1)/rgb(0.45,1,1)/rgb(0.75,1,1)/none/rgb(1,1,0)/rgb(1,0.9,0)/rgb(1,0.8,0)/rgb(1,0.6,0)/rgb(1,0.4,0)/rgb(1,0.3,0)/rgb(0.9,0,0)/rgb(0.5,0,0)/rgb(0.3,0,0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill"
+ },
+ "71": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-200/-100/-75/-50/-30/-20/-15/-13/-11/-9/-7/-5/-3/-1/1/3/5/7/9/11/13/15/20/30/50/75/100/200",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.3)/rgb(0,0,0.5)/rgb(0,0,0.7)/rgb(0,0,0.9)/rgb(0,0.15,1)/rgb(0,0.3,1)/rgb(0,0.45,1)/rgb(0,0.6,1)/rgb(0,0.75,1)/rgb(0,0.85,1)/rgb(0.2,0.95,1)/rgb(0.45,1,1)/rgb(0.75,1,1)/none/rgb(1,1,0)/rgb(1,0.9,0)/rgb(1,0.8,0)/rgb(1,0.7,0)/rgb(1,0.6,0)/rgb(1,0.5,0)/rgb(1,0.4,0)/rgb(1,0.3,0)/rgb(1,0.15,0)/rgb(0.9,0,0)/rgb(0.7,0,0)/rgb(0.5,0,0)/rgb(0.3,0,0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "72": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "black",
+ "contour_label_frequency": "1",
+ "contour_level_list": "-1.5/-0.90/-0.80/-0.70/-0.60/-0.5/-0.4/-0.3/0.3/0.4/0.5/0.6/0.7/0.8/0.9/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "black",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(1, 0, 0.8536, 1)/RGB(0.2348, 0, 1, 1)/RGB(0, 0.6768, 1, 1)/RGB(0, 1, 0.4116, 1)/RGB(0.5, 1, 0,1)/none/none/none/none/none/RGB(1, 1, 0, 1)/RGB(1, 0.75, 0, 1)/RGB(1, 0.5, 0, 1)/RGB(1, 0.25, 0, 1)/RGB(1, 0, 0, 1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "legend": "on"
+ },
+ "73": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-200/-100/-75/-50/-30/-20/-15/-13/-11/-9/-7/-5/-3/-1",
+ "contour_level_selection_type": "level_list",
+ "contour_max_level": "-1",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.3)/rgb(0,0,0.5)/rgb(0,0,0.7)/rgb(0,0,0.9)/rgb(0,0.15,1)/rgb(0,0.3,1)/rgb(0,0.45,1)/rgb(0,0.6,1)/rgb(0,0.75,1)/rgb(0,0.85,1)/rgb(0.2,0.95,1)/rgb(0.45,1,1)/rgb(0.75,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "-1",
+ "contour_shade_method": "area_fill"
+ },
+ "74": {
+ "contour": "off",
+ "contour_highlight_frequency": "100",
+ "contour_highlight_thickness": "5",
+ "contour_hilo": "off",
+ "contour_interval": "2",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_thickness": "3",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.3,0.3,0.3)/rgb(0.4,0.4,0.4)/rgb(0.5,0.5,0.5)/rgb(0.6,0.6,0.6)/rgb(0.7,0.7,0.7)/rgb(0.8,0.8,0.8)/rgb(0.35,0,0.6)/rgb(0.5,0,0.9)/rgb(0.6,0.2,1)/rgb(0.75,0.4,1)/rgb(0.85,0.6,1)/rgb(0,0,0.75)/rgb(0,0,1)/rgb(0.2,0.4,1)/rgb(0.4,0.7,1)/rgb(0.6,0.9,1)/rgb(0,0.55,0.19)/rgb(0.15,0.75,0.1)/rgb(0.5,0.85,0)/rgb(0.65,0.95,0)/rgb(0.8,1,0.2)/rgb(0.65,0.65,0)/rgb(0.8,0.8,0)/rgb(0.92,0.92,0)/rgb(1,1,0)/rgb(1,1,0.6)/rgb(0.85,0.45,0)/rgb(1,0.5,0)/rgb(1,0.62,0)/rgb [...]
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "42",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-32"
+ },
+ "75": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_interval": "4",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_thickness": "3",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.5)/rgb(0,0,0.85)/rgb(0.25,0,1)/blue_purple/greenish_blue/blue_green/bluish_green/yellow_green/greenish_yellow/yellow/orangish_yellow/orange_yellow/yellowish_orange/orange/reddish_orange/red_orange/orangish_red/red/magenta/magenta/magenta/magenta/magenta",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "56",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-48",
+ "legend": "on"
+ },
+ "76": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-50/-10/-5/-2/-1/-0.5/-0.3/-0.2/-0.1/-0.05",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.4)/rgb(0,0,0.75)/rgb(0,0,1)/rgb(0,0.3,1)/rgb(0,0.5,1)/rgb(0,0.7,1)/rgb(0,0.85,1)/rgb(0.1,1,1)/rgb(0.6,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill"
+ },
+ "77": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "-50/-10/-5/-2/-1/-0.5/-0.3/-0.2/-0.1/-0.05/0.05/0.1/0.2/0.3/0.5/1/2/5/10/50",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0,0,0.4)/rgb(0,0,0.75)/rgb(0,0,1)/rgb(0,0.3,1)/rgb(0,0.5,1)/rgb(0,0.7,1)/rgb(0,0.85,1)/rgb(0.1,1,1)/rgb(0.6,1,1)/none/rgb(1,1,0)/rgb(1,0.85,0)/rgb(1,0.7,0)/rgb(1,0.55,0)/rgb(1,0.4,0)/rgb(1,0.1,0)/rgb(0.85,0,0)/rgb(0.6,0,0)/rgb(0.4,0,0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill"
+ },
+ "78": {
+ "contour": "off",
+ "contour_highlight_frequency": "100",
+ "contour_highlight_thickness": "5",
+ "contour_hilo": "off",
+ "contour_interval": "4",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_thickness": "3",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.88,0.2,0.88)/rgb(0.68,0.2,0.68)/rgb(0.48,0.2,0.48)/rgb(0.28,0.2,0.28)/rgb(0.2,0,0.4)/rgb(0.35,0,0.5)/blue_purple/greenish_blue/rgb(0,0.8,1.0)/blue_green/bluish_green/yellow_green/greenish_yellow/rgb(1,1,0.5)/yellow/orange_yellow/yellowish_orange/rgb(1,0.45,0)/red/rgb(0.8,0,0)/burgundy/rose/magenta/rgb(1,0.5,1)/rgb(1,0.75,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "48",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-52"
+ },
+ "79": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_interval": "4",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_thickness": "3",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.2,0,0.4)/rgb(0.35,0,0.5)/rgb(0.42,0,0.6)/violet/rgb(0.5,0,0.85)/blue_purple/rgb(0.42,0.08,1)/rgb(0.36,0.16,1)/rgb(0.25,0.25,1)/rgb(0.1,0.4,1)/greenish_blue/rgb(0,0.6,1)/rgb(0,0.7,1)/rgb(0,0.8,1)/rgb(0,0.9,1)/blue_green/bluish_green/yellow_green/greenish_yellow/yellow/orangish_yellow/orange_yellow/yellowish_orange/orange/reddish_orange/red_orange/orangish_red/red/magenta",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "52",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-64",
+ "legend": "on"
+ },
+ "80": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_interval": "4",
+ "contour_label": "off",
+ "contour_level_selection_type": "interval",
+ "contour_line_thickness": "3",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.06,0.06,0.06)/rgb(0.08,0.08,0.08)/rgb(0.1,0.1,0.1)/rgb(0.12,0.12,0.12)/rgb(0.14,0.14,0.14)/rgb(0.16,0.16,0.16)/rgb(0.18,0.18,0.18)/rgb(0.2,0.2,0.2)/rgb(0.23,0.23,0.23)/rgb(0.26,0.26,0.26)/rgb(0.29,0.29,0.29)/rgb(0.32,0.32,0.32)/rgb(0.35,0.35,0.35)/rgb(0.38,0.38,0.38)/rgb(0.41,0.41,0.41/rgb(0.44,0.44,0.44)/rgb(0.48,0.48,0.48)/rgb(0.52,0.52,0.52)/rgb(0.56,0.56,0.56)/rgb(0.6,0.6,0.6)/rgb(0.64,0.64,0.64)/rgb(0.68,0.68,0.68)/rgb(0.72,0.72,0.72)/rgb( [...]
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "56",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "-76",
+ "legend": "on"
+ },
+ "81": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0/0.4/0.7/1/1.5/2/3/4/5/10/20",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.89,0.89,0.89)/RGB(0.93,0.93,0.93)/RGB(0.96,0.96,0.96)/none/RGB(0.73,0.73,0.73)/RGB(0.6,0.6,0.6)/RGB(0.52,0.52,0.52)/RGB(0.44,0.44,0.44)/RGB(0.37,0.37,0.37)/RGB(0.3,0.3,0.3)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill"
+ },
+ "82": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_label_colour": "black",
+ "contour_label_format": "(F4.1)",
+ "contour_level_list": "0.0/3.5/5.0/6.5/8.0/9.5/11.0/12.5/14.0/15.5/17.0/18.5",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "white",
+ "contour_min_level": "0",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "blue/greenish_blue/sky/yellowish_green/yellow/orange_yellow/yellowish_orange/orange/red/brown/charcoal",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0"
+ },
+ "83": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_label_colour": "black",
+ "contour_label_format": "(F4.1)",
+ "contour_level_list": "0/0.5/1/2/3/4/6/8/10/12/14/20",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "white",
+ "contour_min_level": "0",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "blue/greenish_blue/sky/yellowish_green/yellow/orange_yellow/yellowish_orange/orange/red/brown/charcoal",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0"
+ },
+ "84": {
+ "contour_highlight_colour": "red",
+ "contour_highlight_frequency": "5",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_label_colour": "black",
+ "contour_label_format": "(F4.1)",
+ "contour_level_list": "0/0.5/1/2/3/4/6/8/10/12/14/20",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "white",
+ "contour_min_level": "0",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.5,1,1)/rgb(0.1,1,1)/rgb(0,0.9,1)/rgb(0,0.8,1)/rgb(0,0.7,1)/rgb(0,0.6,1)/rgb(0,0.45,1)/rgb(0,0.2,1)/rgb(0,0,0.85)/rgb(0,0,0.65)/rgb(0,0,0.4)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0"
+ },
+ "85": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_label_colour": "black",
+ "contour_label_format": "(F4.1)",
+ "contour_level_list": "0/0.1/0.5/1.25/2.5/4/6/9/14/20",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "white",
+ "contour_min_level": "0",
+ "contour_reference_level": "0",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.75,1,1)/rgb(0.5,1,1)/rgb(0.2,1,1)/rgb(0,0.9,1)/rgb(0,0.75,1)/rgb(0,0.6,1)/rgb(0,0.3,1)/rgb(0,0,0.85)/rgb(0,0,0.4)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0"
+ },
+ "86": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.05/0.1/0.2/0.3/0.5/1/2/5/10/50",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(1,1,0)/rgb(1,0.85,0)/rgb(1,0.7,0)/rgb(1,0.55,0)/rgb(1,0.4,0)/rgb(1,0.1,0)/rgb(0.85,0,0)/rgb(0.6,0,0)/rgb(0.4,0,0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill"
+ },
+ "87": {
+ "contour": "off",
+ "contour_interpolation_ceiling": "1.0",
+ "contour_label": "off",
+ "contour_level_list": "0.25/0.50/0.75/0.99/1.1",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_max_level_colour": "white",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.25",
+ "contour_shade_min_level_colour": "grey",
+ "legend": "on"
+ },
+ "88": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.3/1.6/3.4/5.5/8.0/10.8/13.9/17.2/20.8/24.5/28.5/32.7/50.",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.85,1,1)/rgb(0.65,1,1)/rgb(0.45,0.95,1)/rgb(0.6,1,0.6)/rgb(0.65,0.95,0.2)/rgb(1,1,0)/rgb(1,0.85,0)/rgb(1,0.7,0)/rgb(1,0.5,0)/rgb(1,0,0)/rgb(0.9,0,0.5)/rgb(0.7,0,0.7)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0",
+ "legend": "on"
+ },
+ "89": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "on",
+ "contour_label_colour": "black",
+ "contour_label_frequency": "1",
+ "contour_level_list": "0.3/0.4/0.5/0.6/0.7/0.8/0.9/1.5",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "black",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "none/none/RGB(1, 1, 0, 1)/RGB(1, 0.75, 0, 1)/RGB(1, 0.5, 0, 1)/RGB(1, 0.25, 0, 1)/RGB(1, 0, 0, 1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.3",
+ "legend": "on"
+ },
+ "90": {
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.5/2/4/10/25/50/100/250",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "cyan/greenish_blue/blue/bluish_purple/magenta/orange/red/charcol",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.5"
+ },
+ "91": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.5/1/2/3/4/5/6/8/10/15/20/25/30/40/50/75/100/200/300",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.95,0.65,0.95)/rgb(0.85,0.55,0.85)/rgb(0.75,0.5,0.85)/rgb(0.6,0.6,1)/rgb(0,0.6,1)/rgb(0,0.8,1.0)/blue_green/bluish_green/yellow_green/greenish_yellow/rgb(1,1,0.5)/yellow/orange_yellow/yellowish_orange/rgb(1,0.45,0)/red/rgb(0.8,0,0)/burgundy",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.5"
+ },
+ "92": {
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.8/1.2/1.6/2.0/2.5/5.0/7.5/10.0/12.5/15.0/20.0/25.0",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "red",
+ "contour_reference_level": "2",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "BLUE_GREEN/BLUISH_GREEN/YELLOW_GREEN/YELLOW/ORANGE_YELLOW/YELLOWISH_ORANGE/ORANGE/TANGERINE/OCHRE/MUSTARD/TAN",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "25",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.8"
+ },
+ "93": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "0.8/1.5/2.5/4.5/8/14/25",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.85,0.73,0.86)/RGB(0.76,0.53,0.77)/RGB(0.73,0.34,0.74)/RGB(0.85,0.13,0.88)/RGB(0.96,0,1.0)/RGB(0.98,0.51,1.0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_max_level": "25",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "0.8"
+ },
+ "94": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "1/3/5/7/9/11/13/15/20/30/50/75/100/200",
+ "contour_level_selection_type": "level_list",
+ "contour_min_level": "1",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(1,1,0)/rgb(1,0.9,0)/rgb(1,0.8,0)/rgb(1,0.7,0)/rgb(1,0.6,0)/rgb(1,0.5,0)/rgb(1,0.4,0)/rgb(1,0.3,0)/rgb(1,0.15,0)/rgb(0.9,0,0)/rgb(0.7,0,0)/rgb(0.5,0,0)/rgb(0.3,0,0)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "1"
+ },
+ "95": {
+ "contour": "off",
+ "contour_label": "off",
+ "contour_level_list": "1/5/10/20/50/100/1000/5000",
+ "contour_level_selection_type": "level_list",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(0.64,0.64,0.64)/rgb(0.7,0.7,0.7)/rgb(0.76,0.76,0.76)/rgb(0.82,0.82,0.82)/rgb(0.88,0.88,0.88)/rgb(0.94,0.94,0.94)/rgb(1,1,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "1",
+ "legend": "on"
+ },
+ "96": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "1/2/5/10/15/20/30/40/50/70/100/200/500/10000",
+ "contour_level_selection_type": "level_list",
+ "contour_reference_level": "10",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "RGB(0.45,0.6,0.45)/RGB(0.59,0.75,0.59)/RGB(0.73,0.84,0.73)/RGB(0.87,0.87,0.87)/RGB(0.94,0.94,0.94)/RGB(1,1,1)/RGB(0.9,0.95,1)/RGB(0.8,0.9,1)/RGB(0.67,0.83,1)/RGB(0.5,0.75,1.0)/RGB(0.85,0.8,1)/RGB(0.75,0.68,1)/RGB(0.6,0.5,1)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_label_blanking": "off",
+ "contour_shade_max_level": "10000",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "1",
+ "legend": "on"
+ },
+ "97": {
+ "contour": "on",
+ "contour_highlight": "off",
+ "contour_interpolation_ceiling": "100",
+ "contour_label": "off",
+ "contour_level_list": "10/25/50/75/99/110",
+ "contour_level_selection_type": "level_list",
+ "contour_line_colour": "RGB(0.8,0.8,0.8)",
+ "contour_shade": "on",
+ "contour_shade_colour_direction": "anti_clockwise",
+ "contour_shade_colour_method": "calculate",
+ "contour_shade_max_level_colour": "white",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "5",
+ "contour_shade_min_level_colour": "grey",
+ "legend": "on"
+ },
+ "98": {
+ "contour": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_level_list": "10/15/20/25/30/40/50/60/80/100",
+ "contour_level_selection_type": "list",
+ "contour_line_thickness": "1",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "rgb(1,1,0.40)/greenish_yellow/rgb(0.58,1,0.0)/avocado/evergreen/rgb(0.0,0.33,0.28)/rgb(0.0,0.26,0.28)/rgb(0.0,0.20,0.44)/rgb(0.0,0.20,0.64)",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "10",
+ "legend": "on"
+ },
+ "99": {
+ "contour": "off",
+ "contour_highlight": "off",
+ "contour_hilo": "off",
+ "contour_label": "off",
+ "contour_label_frequency": "1",
+ "contour_level_list": "1/2.5/6/15/40/100/250",
+ "contour_level_selection_type": "level_list",
+ "contour_method": "linear",
+ "contour_shade": "on",
+ "contour_shade_colour_list": "cyan/greenish_blue/blue/bluish_purple/magenta/red/charcol",
+ "contour_shade_colour_method": "list",
+ "contour_shade_method": "area_fill",
+ "contour_shade_min_level": "1",
+ "legend": "on"
+ }
+}
diff --git a/share/magics/default.json b/share/magics/default.json
index 1bff616..a5d51d1 100644
--- a/share/magics/default.json
+++ b/share/magics/default.json
@@ -1 +1,112 @@
-{"default": [52, 55, 56, 60, 63, 69, 71, 72, 75, 77, 78, 82, 83, 89, 90, 93, 96, 98, 100, 101, 103, 106, 107, 109, 111, 112, 132, 156, 174, 176, 178, 181, 182], "shade": [57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 132, 134, 135, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180, 181, 182]}
\ No newline at end of file
+{
+ "default": [
+ 52,
+ 55,
+ 56,
+ 60,
+ 63,
+ 69,
+ 71,
+ 72,
+ 75,
+ 77,
+ 78,
+ 82,
+ 83,
+ 89,
+ 90,
+ 93,
+ 96,
+ 98,
+ 100,
+ 101,
+ 103,
+ 106,
+ 107,
+ 109,
+ 111,
+ 112,
+ 132,
+ 156,
+ 174,
+ 176,
+ 178,
+ 181,
+ 182
+ ],
+ "shade": [
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69,
+ 70,
+ 71,
+ 72,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 82,
+ 83,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 89,
+ 90,
+ 91,
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 106,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 132,
+ 134,
+ 135,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180,
+ 181,
+ 182
+ ]
+}
diff --git a/share/magics/ecmwf_logo_2014.svg b/share/magics/ecmwf_logo_2014.svg
new file mode 100644
index 0000000..1c84988
--- /dev/null
+++ b/share/magics/ecmwf_logo_2014.svg
@@ -0,0 +1,10 @@
+<g fill="#406DB3" transform="scale(.1)" id="ec_logo">
+ <path d="M1.286,52.728h35.836v-9.712H1.286C0.699,46.27,0.751,49.575,1.286,52.728z"/>
+ <path d="M120.622,56.097c-3.676,19.997-21.383,34.826-41.7,34.826c-5.915,0-12.206-1.492-17.54-3.789 c-5.603,2.616-11.786,3.789-18.084,3.789c-20.31,0-38.017-14.562-41.642-34.661l26.136-0.051 c2.872,6.509,9.482,10.72,16.579,10.72c7.623,0,14.713-5.182,17.277-12.327c2.458,7.313,9.547,12.327,17.273,12.327 c7.255,0,13.98-4.211,16.853-10.771L120.622,56.097z"/>
+ <path d="M120.622,39.634c-3.676-20.011-21.383-34.826-41.7-34.826c-5.915,0-12.206,1.492-17.54,3.842 C55.779,5.98,49.596,4.808,43.298,4.808c-20.31,0-38.017,14.549-41.642,34.661l26.136,0.051 c2.872-6.509,9.482-10.707,16.579-10.707c7.623,0,14.713,5.168,17.277,12.302c2.458-7.301,9.547-12.302,17.273-12.302 c7.255,0,13.98,4.198,16.853,10.757L120.622,39.634z" />
+ <path d="M178.878,13.899v12.83h-36.645v14.871h33.632v11.858h-33.632V70.47h37.423V83.3h-52.683v-69.4H178.878z" />
+ <path d="M230.588,32.416c-0.908-1.458-2.041-2.737-3.402-3.84c-1.36-1.101-2.9-1.959-4.617-2.576 c-1.718-0.614-3.516-0.923-5.395-0.923c-3.436,0-6.352,0.665-8.748,1.992c-2.397,1.329-4.342,3.11-5.832,5.347 c-1.491,2.235-2.575,4.779-3.256,7.63c-0.681,2.853-1.021,5.8-1.021,8.845c0,2.916,0.34,5.752,1.021,8.506 c0.681,2.755,1.765,5.233,3.256,7.436c1.49,2.203,3.435,3.97,5.832,5.297c2.396,1.329,5.312,1.993,8.748,1.993 c4.666,0,8.311-1.425,10.936-4.277c2.624-2.851,4.228-6.609,4.812-11.275h14.77 [...]
+ <path d="M275.689,13.899l16.231,47.725h0.195l15.357-47.725h21.48v69.4h-14.288V34.116h-0.194L297.462,83.3H285.7 l-17.01-48.697h-0.194V83.3h-14.288v-69.4H275.689z" />
+ <path d="M393.301,83.3l-11.762-47.239h-0.194L369.778,83.3h-15.455l-18.37-69.4h15.26l10.983,47.239h0.195 l12.053-47.239h14.288l11.858,47.822h0.194l11.372-47.822h14.969l-18.662,69.4H393.301z" />
+ <path d="M483.403,13.899v12.83h-33.534v16.038h29.063v11.858h-29.063V83.3h-15.26v-69.4H483.403z" />
+</g>
diff --git a/share/magics/epsg.json b/share/magics/epsg.json
index 91b22ba..367b8c1 100644
--- a/share/magics/epsg.json
+++ b/share/magics/epsg.json
@@ -1,220 +1,214 @@
{
-"definitions" : [
- {
- "polar_north" : {
- "definition" : "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "conic"
- }
- },
- {
- "polar_north_america" : {
- "definition" : "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "conic"
- }
-
-
- },
- {
- "lambert" : {
- "definition" : "+proj=lcc +lon_0=0 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : +180,
- "max_latitude" : 90,
- "method" : "conic"
- }
- },
- {
- "lambert_north_atlantic" : {
- "definition" : "+proj=lcc +lon_0=40w +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : +180,
- "max_latitude" : 90,
- "method" : "conic"
- }
- },
- {
- "EPSG:32661" : {
- "definition" : "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "conic"
-
- }
- },
- {
- "EPSG:4326" : {
- "definition" : "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "simple"
+ "definitions": [
+ {
+ "polar_north": {
+ "definition": "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "polar_north_america": {
+ "definition": "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "lambert": {
+ "definition": "+proj=lcc +lon_0=0 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "lambert_north_atlantic": {
+ "definition": "+proj=lcc +lon_0=40w +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "EPSG:32661": {
+ "definition": "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "EPSG:4326": {
+ "definition": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "simple",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "EPSG:3857": {
+ "definition": "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
+ "max_latitude": 85,
+ "max_longitude": 180,
+ "method": "simple",
+ "min_latitude": -85,
+ "min_longitude": -180
+ }
+ },
+ {
+ "cylindrical": {
+ "definition": "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "simple",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "geos": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84",
+ "max_latitude": 80,
+ "max_longitude": 70,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": -70
+ }
+ },
+ {
+ "meteosat_0": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=0",
+ "max_latitude": 80,
+ "max_longitude": 70,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": -70
+ }
+ },
+ {
+ "meteosat_575": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=57.5",
+ "max_latitude": 80,
+ "max_longitude": 130,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": -10
+ }
+ },
+ {
+ "meteosat_145": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=145",
+ "max_latitude": 80,
+ "max_longitude": 215,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": 75
+ }
+ },
+ {
+ "goes-e": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=-75",
+ "max_latitude": 80,
+ "max_longitude": -5,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": -145
+ }
+ },
+ {
+ "goes-w": {
+ "definition": "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=-135",
+ "max_latitude": 80,
+ "max_longitude": -65,
+ "method": "geos",
+ "min_latitude": -80,
+ "min_longitude": -205
+ }
+ },
+ {
+ "goode": {
+ "definition": "+proj=goode +ellps=WGS84",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "geos",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "collignon": {
+ "definition": "+proj=collg +ellps=WGS84",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "geos",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "mollweide": {
+ "definition": "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "geos",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "robinson": {
+ "definition": "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_def",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "geos",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "google": {
+ "definition": "+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",
+ "max_latitude": 90,
+ "max_longitude": 180,
+ "method": "simple",
+ "min_latitude": -90,
+ "min_longitude": -180
+ }
+ },
+ {
+ "efas": {
+ "definition": "+proj=laea +lat_0=48.0000000000 +lon_0=9.0000000000 +x_0=0.0000000000 +y_0=0.0000000000 +datum=WGS84 +a=6378388 +b=6378388 +no_defs",
+ "max_latitude": 89,
+ "max_longitude": 180,
+ "method": "conic",
+ "min_latitude": -20,
+ "min_longitude": -180
+ }
+ },
+ {
+ "bonne": {
+ "definition": "+proj=bonne +lon_0=0 +x_0=0 +y_0=0 +lat_1=60 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
+ "max_latitude": 89,
+ "max_longitude": 180,
+ "method": "geos",
+ "min_latitude": -89,
+ "min_longitude": -180
+ }
}
- },
- {
- "EPSG:3857" : {
- "definition" : "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -85,
- "max_longitude" : 180,
- "max_latitude" : 85,
- "method" : "simple"
- }
- },
- {
- "cylindrical" : {
- "definition" : "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "simple"
- }
- },
- {
- "geos" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84",
- "min_longitude" : -70,
- "min_latitude" : -80,
- "max_longitude" : 70,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
- {
- "meteosat_0" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=0",
- "min_longitude" : -70,
- "min_latitude" : -80,
- "max_longitude" : 70,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
- {
- "meteosat_575" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=57.5",
- "min_longitude" : -10,
- "min_latitude" : -80,
- "max_longitude" : 130,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
- {
- "meteosat_145" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=145",
- "min_longitude" : 75,
- "min_latitude" : -80,
- "max_longitude" : 215,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
- {
- "goes-e" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=-75",
- "min_longitude" : -145,
- "min_latitude" : -80,
- "max_longitude" : -5,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
- {
- "goes-w" : {
- "definition" : "+proj=geos +h=42164000 +ellps=WGS84 +lon_0=-135",
- "min_longitude" : -205,
- "min_latitude" : -80,
- "max_longitude" : -65,
- "max_latitude" : 80,
- "method" : "geos"
- }
- },
-
- {
- "goode" : {
- "definition" : "+proj=goode +ellps=WGS84",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "geos"
- }
- } ,
- {
- "collignon" : {
- "definition" : "+proj=collg +ellps=WGS84",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "geos"
- }
- },
- {
- "mollweide" : {
- "definition" : "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "geos"
- }
- },
- {
- "robinson" : {
- "definition" : "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_def",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "geos"
- }
- },
- {
- "google" : {
- "definition" : "+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",
- "min_longitude" : -180,
- "min_latitude" : -90,
- "max_longitude" : 180,
- "max_latitude" : 90,
- "method" : "simple"
- }
- },
- {
- "efas" : {
- "definition" : "+proj=laea +lat_0=48.0000000000 +lon_0=9.0000000000 +x_0=0.0000000000 +y_0=0.0000000000 +datum=WGS84 +a=6378388 +b=6378388 +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -20,
- "max_longitude" : 180,
- "max_latitude" : 89,
- "method" : "conic"
- }
- },
-
- {
- "bonne" : {
- "definition" : "+proj=bonne +lon_0=0 +x_0=0 +y_0=0 +lat_1=60 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
- "min_longitude" : -180,
- "min_latitude" : -89,
- "max_longitude" : 180,
- "max_latitude" : 89,
- "method" : "geos"
- }
- }
-
-]
+ ]
}
diff --git a/share/magics/layer_contours.json b/share/magics/layer_contours.json
index 7c51cda..49920b4 100644
--- a/share/magics/layer_contours.json
+++ b/share/magics/layer_contours.json
@@ -1 +1,605 @@
-{"0": [43, 88, 98, 104, 100], "3": [134, 89], "4": [43, 88, 98, 104, 100], "5": [62, 66, 67, 65, 63, 64, 60], "6": [98, 43, 110, 104, 88, 111], "7": [62, 66, 67, 65, 63, 64, 60], "8": [98, 43, 110, 104, 88, 111], "9": [134, 89], "10": [167, 80, 78, 57, 74, 42, 79, 75], "11": [167, 80, 78, 57, 74, 42, 79, 75], "12": [62, 66, 67, 65, 63, 64, 60], "14": [41, 108, 109], "15": [167, 80, 78, 57, 74, 42, 79, 75], "16": [68, 72], "17": [167, 80, 78, 57, 74, 42, 79, 75], "18": [62, 66, 67, 65, 63 [...]
\ No newline at end of file
+{
+ "0": [
+ 43,
+ 88,
+ 98,
+ 104,
+ 100
+ ],
+ "10": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "100": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "101": [
+ 62,
+ 66,
+ 67,
+ 64,
+ 60,
+ 65,
+ 63
+ ],
+ "102": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "103": [
+ 62,
+ 66,
+ 67,
+ 64,
+ 60,
+ 65,
+ 63
+ ],
+ "104": [
+ 61,
+ 62
+ ],
+ "105": [
+ 61,
+ 62
+ ],
+ "11": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "12": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "14": [
+ 41,
+ 108,
+ 109
+ ],
+ "15": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "16": [
+ 68,
+ 72
+ ],
+ "17": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "18": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "19": [
+ 51,
+ 115,
+ 54,
+ 55,
+ 53,
+ 52
+ ],
+ "20": [
+ 45,
+ 94,
+ 73,
+ 70,
+ 71
+ ],
+ "22": [
+ 41,
+ 108,
+ 109
+ ],
+ "24": [
+ 49,
+ 81,
+ 101
+ ],
+ "25": [
+ 51,
+ 115,
+ 54,
+ 55,
+ 53,
+ 52
+ ],
+ "26": [
+ 47,
+ 112
+ ],
+ "27": [
+ 45,
+ 94,
+ 73,
+ 70,
+ 71
+ ],
+ "28": [
+ 80,
+ 42,
+ 79,
+ 78
+ ],
+ "3": [
+ 134,
+ 89
+ ],
+ "30": [
+ 41,
+ 109,
+ 108,
+ 98
+ ],
+ "31": [
+ 45,
+ 94,
+ 73,
+ 70,
+ 71
+ ],
+ "32": [
+ 51,
+ 115,
+ 54,
+ 55,
+ 53,
+ 52
+ ],
+ "33": [
+ 47,
+ 112
+ ],
+ "34": [
+ 45,
+ 94,
+ 73,
+ 70,
+ 71
+ ],
+ "35": [
+ 167,
+ 80,
+ 42,
+ 79,
+ 78
+ ],
+ "36": [
+ 44,
+ 86,
+ 76,
+ 77
+ ],
+ "38": [
+ 43,
+ 98,
+ 110,
+ 111
+ ],
+ "39": [
+ 51,
+ 115,
+ 54,
+ 55,
+ 53,
+ 52
+ ],
+ "4": [
+ 43,
+ 88,
+ 98,
+ 104,
+ 100
+ ],
+ "40": [
+ 47,
+ 112
+ ],
+ "41": [
+ 45,
+ 94,
+ 73,
+ 70,
+ 71
+ ],
+ "42": [
+ 167,
+ 80,
+ 42,
+ 79,
+ 78
+ ],
+ "44": [
+ 98,
+ 43,
+ 110,
+ 111
+ ],
+ "45": [
+ 51,
+ 115,
+ 54,
+ 55,
+ 53,
+ 52
+ ],
+ "46": [
+ 47,
+ 112
+ ],
+ "47": [
+ 167,
+ 80,
+ 42,
+ 79,
+ 78
+ ],
+ "49": [
+ 98,
+ 43,
+ 110,
+ 111
+ ],
+ "5": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "50": [
+ 156
+ ],
+ "51": [
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "52": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "53": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "54": [
+ 62,
+ 66,
+ 67,
+ 64,
+ 60,
+ 65,
+ 63
+ ],
+ "55": [
+ 51,
+ 115,
+ 54,
+ 53,
+ 52,
+ 55
+ ],
+ "56": [
+ 51,
+ 115,
+ 54,
+ 53,
+ 52,
+ 55
+ ],
+ "57": [
+ 167,
+ 51,
+ 53,
+ 115,
+ 52
+ ],
+ "58": [
+ 53,
+ 115,
+ 52
+ ],
+ "59": [
+ 51,
+ 55,
+ 53,
+ 115,
+ 52
+ ],
+ "6": [
+ 98,
+ 43,
+ 110,
+ 104,
+ 88,
+ 111
+ ],
+ "60": [
+ 105,
+ 103,
+ 106
+ ],
+ "61": [
+ 105,
+ 103
+ ],
+ "62": [
+ 92,
+ 93
+ ],
+ "63": [
+ 102,
+ 101
+ ],
+ "64": [
+ 105,
+ 103
+ ],
+ "65": [
+ 179,
+ 59,
+ 178
+ ],
+ "66": [
+ 61,
+ 62
+ ],
+ "67": [
+ 175,
+ 59,
+ 174
+ ],
+ "68": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "69": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "7": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "72": [
+ 49,
+ 82
+ ],
+ "73": [
+ 49,
+ 82
+ ],
+ "74": [
+ 51,
+ 55,
+ 54,
+ 53,
+ 50,
+ 48,
+ 113,
+ 114,
+ 115,
+ 52
+ ],
+ "76": [
+ 49,
+ 82
+ ],
+ "77": [
+ 49,
+ 82
+ ],
+ "78": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "79": [
+ 177,
+ 59,
+ 176
+ ],
+ "8": [
+ 98,
+ 43,
+ 110,
+ 104,
+ 88,
+ 111
+ ],
+ "80": [
+ 167,
+ 80,
+ 78,
+ 57,
+ 74,
+ 42,
+ 79,
+ 75
+ ],
+ "81": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "82": [
+ 151,
+ 150,
+ 149,
+ 56
+ ],
+ "83": [
+ 149,
+ 56
+ ],
+ "84": [
+ 67,
+ 63,
+ 58,
+ 60
+ ],
+ "85": [
+ 67,
+ 63,
+ 58,
+ 60
+ ],
+ "86": [
+ 67,
+ 63,
+ 58,
+ 60
+ ],
+ "87": [
+ 180,
+ 87,
+ 69
+ ],
+ "88": [
+ 49,
+ 84,
+ 83
+ ],
+ "89": [
+ 49,
+ 84,
+ 85,
+ 83
+ ],
+ "9": [
+ 134,
+ 89
+ ],
+ "90": [
+ 49,
+ 84,
+ 83
+ ],
+ "91": [
+ 49,
+ 84,
+ 83
+ ],
+ "92": [
+ 62,
+ 66,
+ 67,
+ 65,
+ 63,
+ 64,
+ 60
+ ],
+ "93": [
+ 97,
+ 107
+ ],
+ "94": [
+ 95,
+ 96
+ ],
+ "95": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "96": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "97": [
+ 62,
+ 66,
+ 67,
+ 64,
+ 60,
+ 65,
+ 63
+ ],
+ "98": [
+ 46,
+ 91,
+ 99,
+ 90
+ ],
+ "99": [
+ 135,
+ 89
+ ]
+}
diff --git a/share/magics/layer_ids.json b/share/magics/layer_ids.json
index a43e7b6..a1d4cf9 100644
--- a/share/magics/layer_ids.json
+++ b/share/magics/layer_ids.json
@@ -1 +1,108 @@
-{"10m wind gust extreme forecast index": 3, "Convective available potential energy (CAPE)": 50, "2m temperature probability": 18, "300 hPa wind": 21, "925 hPa relative humidity": 46, "500 hPa relative humidity": 26, "Total precipitation extreme forecast index": 99, "2 metre dew point temperature": 10, "High cloud cover": 65, "Ensemble spread for mean sea level pressure": 64, "Model orography from ensemble forecast": 83, "300 hPa wind speed": 22, "10m wind speed extreme forecast index": 9 [...]
\ No newline at end of file
+{
+ "10 m wind gust": 0,
+ "100 metre wind": 1,
+ "10m wind": 2,
+ "10m wind gust extreme forecast index": 3,
+ "10m wind gusts percentile": 4,
+ "10m wind gusts probability": 5,
+ "10m wind percentile": 6,
+ "10m wind probability": 7,
+ "10m wind speed": 8,
+ "10m wind speed extreme forecast index": 9,
+ "2 metre dew point temperature": 10,
+ "2 metre dew point temperature percentile": 11,
+ "2 metre dew point temperature probability": 12,
+ "200 hPa wind": 13,
+ "200 hPa wind speed": 14,
+ "2m temperature": 15,
+ "2m temperature extreme forecast index": 16,
+ "2m temperature percentile": 17,
+ "2m temperature probability": 18,
+ "300 hPa geopotential": 19,
+ "300 hPa relative vorticity": 20,
+ "300 hPa wind": 21,
+ "300 hPa wind speed": 22,
+ "315K (Potential tempearture level) wind": 23,
+ "315K (potential temperature level) potential vorticity": 24,
+ "500 hPa geopotential": 25,
+ "500 hPa relative humidity": 26,
+ "500 hPa relative vorticity": 27,
+ "500 hPa temperature": 28,
+ "500 hPa wind": 29,
+ "500 hPa wind speed": 30,
+ "700 hPa divergence": 31,
+ "700 hPa geopotential": 32,
+ "700 hPa relative humidity": 33,
+ "700 hPa relative vorticity": 34,
+ "700 hPa temperature": 35,
+ "700 hPa vertical velocity": 36,
+ "700 hPa wind": 37,
+ "700 hPa wind speed": 38,
+ "850 hPa geopotential": 39,
+ "850 hPa relative humidity": 40,
+ "850 hPa relative vorticity": 41,
+ "850 hPa temperature": 42,
+ "850 hPa wind": 43,
+ "850 hPa wind speed": 44,
+ "925 hPa geopotential": 45,
+ "925 hPa relative humidity": 46,
+ "925 hPa temperature": 47,
+ "925 hPa wind": 48,
+ "925 hPa wind speed": 49,
+ "Convective available potential energy (CAPE)": 50,
+ "Convective available potential energy (CAPE) probability": 51,
+ "Convective precipitation": 52,
+ "Convective precipitation percentile": 53,
+ "Convective precipitation probability": 54,
+ "Ensemble mean for 300 hPa geopotential height": 55,
+ "Ensemble mean for 500 hPa geopotential": 56,
+ "Ensemble mean for 850 hPa temperature": 57,
+ "Ensemble mean for 850 hPa wind speed": 58,
+ "Ensemble mean for mean sea level pressure": 59,
+ "Ensemble spread for 300 hPa geopotential height": 60,
+ "Ensemble spread for 500 hPa geopotential": 61,
+ "Ensemble spread for 850 hPa temperature": 62,
+ "Ensemble spread for 850 hPa wind speed": 63,
+ "Ensemble spread for mean sea level pressure": 64,
+ "High cloud cover": 65,
+ "Hurricane strike probability": 66,
+ "Low cloud cover": 67,
+ "Maximum 2 metre temperature": 68,
+ "Maximum 2 metre temperature probability": 69,
+ "Mean direction and height of total swell": 70,
+ "Mean direction and height of wind waves": 71,
+ "Mean period of total swell": 72,
+ "Mean period of wind waves": 73,
+ "Mean sea level pressure": 74,
+ "Mean wave direction and height": 75,
+ "Mean wave period": 76,
+ "Mean wave period percentile": 77,
+ "Mean wave period probability": 78,
+ "Medium cloud cover": 79,
+ "Minimum 2 metre temperature": 80,
+ "Minimum 2 metre temperature probability": 81,
+ "Model orography from deterministic forecast": 82,
+ "Model orography from ensemble forecast": 83,
+ "Probability of combined events of 2 metre Temperature and total precipitation": 84,
+ "Probability of combined events of wind gust and total snowfall": 85,
+ "Probability of combined events of wind speed and total precipitation": 86,
+ "Sea ice cover as fraction of a grid box": 87,
+ "Significant height of total swell": 88,
+ "Significant height of wind waves": 89,
+ "Significant wave height": 90,
+ "Significant wave height percentile": 91,
+ "Significant wave height probability": 92,
+ "Snow coverage as percentage of a grid box": 93,
+ "Snow depth": 94,
+ "Stratiform precipitation": 95,
+ "Stratiform precipitation percentile": 96,
+ "Stratiform precipitation probability": 97,
+ "Total precipitation": 98,
+ "Total precipitation extreme forecast index": 99,
+ "Total precipitation percentile": 100,
+ "Total precipitation probability": 101,
+ "Total snowfall": 102,
+ "Total snowfall probability": 103,
+ "Tropical cyclone strike probability": 104,
+ "Tropical storm strike probability": 105
+}
diff --git a/share/magics/layers.json b/share/magics/layers.json
index 106d9ad..55a83cb 100644
--- a/share/magics/layers.json
+++ b/share/magics/layers.json
@@ -1 +1,1274 @@
-{"0": {"typeOfLevel": "surface", "marsStream": "oper", "level": "0", "marsClass": "od", "number": "0", "marsType": "fc", "units": "m s**-1", "shortName": "10fg", "paramId": "49", "stepRange": "23-24"}, "1": {"typeOfLevel": "surface", "marsStream": "oper", "level": "0", "marsClass": "od", "number": "0", "marsType": "fc", "units": "m s**-1", "shortName": "100v", "paramId": "228247", "stepRange": "0"}, "2": {"typeOfLevel": "surface", "marsStream": "oper", "level": "0", "marsClass": "od", "n [...]
\ No newline at end of file
+{
+ "0": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "49",
+ "shortName": "10fg",
+ "stepRange": "23-24",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "1": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "228247",
+ "shortName": "100v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "10": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "168",
+ "shortName": "2d",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "100": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "228",
+ "shortName": "tp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "101": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "228",
+ "shortName": "tp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "102": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "144",
+ "shortName": "sf",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m of water equivalent"
+ },
+ "103": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "144",
+ "shortName": "sf",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m of water equivalent"
+ },
+ "104": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "ep",
+ "number": "0",
+ "paramId": "131091",
+ "shortName": "ptd",
+ "stepRange": "24-72",
+ "typeOfLevel": "surface",
+ "units": "%"
+ },
+ "105": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "ep",
+ "number": "0",
+ "paramId": "131089",
+ "shortName": "pts",
+ "stepRange": "24-72",
+ "typeOfLevel": "surface",
+ "units": "%"
+ },
+ "11": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "168",
+ "shortName": "2d",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "12": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "168",
+ "shortName": "2d",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "13": {
+ "level": "200",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "14": {
+ "level": "200",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "15": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "167",
+ "shortName": "2t",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "16": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "efi",
+ "number": "0",
+ "paramId": "132167",
+ "shortName": "2ti",
+ "stepRange": "0-24",
+ "typeOfLevel": "surface",
+ "units": "(-1 to 1)"
+ },
+ "17": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "167",
+ "shortName": "2t",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "18": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "167",
+ "shortName": "2t",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "19": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "2": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "166",
+ "shortName": "10v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "20": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "138",
+ "shortName": "vo",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "s**-1"
+ },
+ "21": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "22": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "23": {
+ "level": "315",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "theta",
+ "units": "m s**-1"
+ },
+ "24": {
+ "level": "315",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "60",
+ "shortName": "pv",
+ "stepRange": "0",
+ "typeOfLevel": "theta",
+ "units": "K m**2 kg**-1 s**-1"
+ },
+ "25": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "26": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "157",
+ "shortName": "r",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "%"
+ },
+ "27": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "138",
+ "shortName": "vo",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "s**-1"
+ },
+ "28": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "29": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "3": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "efi",
+ "number": "0",
+ "paramId": "132049",
+ "shortName": "10fgi",
+ "stepRange": "0-24",
+ "typeOfLevel": "surface",
+ "units": "(-1 to 1)"
+ },
+ "30": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "31": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "155",
+ "shortName": "d",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "s**-1"
+ },
+ "32": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "33": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "157",
+ "shortName": "r",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "%"
+ },
+ "34": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "138",
+ "shortName": "vo",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "s**-1"
+ },
+ "35": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "36": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "135",
+ "shortName": "w",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "Pa s**-1"
+ },
+ "37": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "38": {
+ "level": "700",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "39": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "4": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "49",
+ "shortName": "10fg",
+ "stepRange": "21-24",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "40": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "157",
+ "shortName": "r",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "%"
+ },
+ "41": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "138",
+ "shortName": "vo",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "s**-1"
+ },
+ "42": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "43": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "44": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "45": {
+ "level": "925",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "46": {
+ "level": "925",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "157",
+ "shortName": "r",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "%"
+ },
+ "47": {
+ "level": "925",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "48": {
+ "level": "925",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "49": {
+ "level": "925",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "132",
+ "shortName": "v",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "5": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "49",
+ "shortName": "10fg",
+ "stepRange": "21-24",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "50": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "59",
+ "shortName": "cape",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "J kg**-1"
+ },
+ "51": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "59",
+ "shortName": "cape",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "J kg**-1"
+ },
+ "52": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "143",
+ "shortName": "cp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "53": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "143",
+ "shortName": "cp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "54": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "143",
+ "shortName": "cp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "55": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "56": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "57": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "em",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "58": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "em",
+ "number": "0",
+ "paramId": "10",
+ "shortName": "ws",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "59": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "em",
+ "number": "0",
+ "paramId": "151",
+ "shortName": "msl",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "Pa"
+ },
+ "6": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "166",
+ "shortName": "10v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "60": {
+ "level": "300",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "61": {
+ "level": "500",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m**2 s**-2"
+ },
+ "62": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "es",
+ "number": "0",
+ "paramId": "130",
+ "shortName": "t",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "K"
+ },
+ "63": {
+ "level": "850",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "es",
+ "number": "0",
+ "paramId": "10",
+ "shortName": "ws",
+ "stepRange": "0",
+ "typeOfLevel": "isobaricInhPa",
+ "units": "m s**-1"
+ },
+ "64": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "es",
+ "number": "0",
+ "paramId": "151",
+ "shortName": "msl",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "Pa"
+ },
+ "65": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "188",
+ "shortName": "hcc",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "(0 - 1)"
+ },
+ "66": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "ep",
+ "number": "0",
+ "paramId": "131090",
+ "shortName": "ph",
+ "stepRange": "24-72",
+ "typeOfLevel": "surface",
+ "units": "%"
+ },
+ "67": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "186",
+ "shortName": "lcc",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "(0 - 1)"
+ },
+ "68": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "201",
+ "shortName": "mx2t",
+ "stepRange": "23-24",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "69": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "201",
+ "shortName": "mx2t",
+ "stepRange": "21-24",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "7": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "166",
+ "shortName": "10v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "70": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140238",
+ "shortName": "mdts",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "degrees"
+ },
+ "71": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140235",
+ "shortName": "mdww",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "degrees"
+ },
+ "72": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140239",
+ "shortName": "mpts",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "s"
+ },
+ "73": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140236",
+ "shortName": "mpww",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "s"
+ },
+ "74": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "151",
+ "shortName": "msl",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "Pa"
+ },
+ "75": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140230",
+ "shortName": "mwd",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "degrees"
+ },
+ "76": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140232",
+ "shortName": "mwp",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "s"
+ },
+ "77": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "waef",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "140232",
+ "shortName": "mwp",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "s"
+ },
+ "78": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "waef",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "140232",
+ "shortName": "mwp",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "s"
+ },
+ "79": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "187",
+ "shortName": "mcc",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "(0 - 1)"
+ },
+ "8": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "166",
+ "shortName": "10v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "80": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "202",
+ "shortName": "mn2t",
+ "stepRange": "23-24",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "81": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "202",
+ "shortName": "mn2t",
+ "stepRange": "21-24",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "82": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m**2 s**-2"
+ },
+ "83": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "1",
+ "paramId": "129",
+ "shortName": "z",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m**2 s**-2"
+ },
+ "84": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "167",
+ "shortName": "2t",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "K"
+ },
+ "85": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "49",
+ "shortName": "10fg",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "86": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "166",
+ "shortName": "10v",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m s**-1"
+ },
+ "87": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "31",
+ "shortName": "ci",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "(0 - 1)"
+ },
+ "88": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140237",
+ "shortName": "shts",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "m"
+ },
+ "89": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140234",
+ "shortName": "shww",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "m"
+ },
+ "9": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "efi",
+ "number": "0",
+ "paramId": "132165",
+ "shortName": "10wsi",
+ "stepRange": "0-24",
+ "typeOfLevel": "surface",
+ "units": "(-1 to 1)"
+ },
+ "90": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "wave",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "140229",
+ "shortName": "swh",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "m"
+ },
+ "91": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "waef",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "140229",
+ "shortName": "swh",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "m"
+ },
+ "92": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "waef",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "140229",
+ "shortName": "swh",
+ "stepRange": "0",
+ "typeOfLevel": "meanSea",
+ "units": "m"
+ },
+ "93": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "141",
+ "shortName": "sd",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m of water equivalent"
+ },
+ "94": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "141",
+ "shortName": "sd",
+ "stepRange": "0",
+ "typeOfLevel": "surface",
+ "units": "m of water equivalent"
+ },
+ "95": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "142",
+ "shortName": "lsp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "96": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "142",
+ "shortName": "lsp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "97": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "pf",
+ "number": "50",
+ "paramId": "142",
+ "shortName": "lsp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "98": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "oper",
+ "marsType": "fc",
+ "number": "0",
+ "paramId": "228",
+ "shortName": "tp",
+ "stepRange": "24",
+ "typeOfLevel": "surface",
+ "units": "m"
+ },
+ "99": {
+ "level": "0",
+ "marsClass": "od",
+ "marsStream": "enfo",
+ "marsType": "efi",
+ "number": "0",
+ "paramId": "132228",
+ "shortName": "tpi",
+ "stepRange": "0-24",
+ "typeOfLevel": "surface",
+ "units": "(-1 to 1)"
+ }
+}
diff --git a/share/magics/level.json b/share/magics/level.json
index 63d9086..0df27d7 100644
--- a/share/magics/level.json
+++ b/share/magics/level.json
@@ -1 +1,202 @@
-{"200": [41, 108, 109], "850": [42, 43, 45, 47, 51, 52, 53, 54, 55, 70, 71, 73, 78, 79, 80, 92, 93, 94, 98, 101, 102, 110, 111, 112, 115, 167], "300": [41, 45, 51, 52, 53, 54, 55, 70, 71, 73, 94, 103, 105, 106, 108, 109, 115], "700": [42, 43, 44, 45, 47, 51, 52, 53, 54, 55, 70, 71, 73, 76, 77, 78, 79, 80, 86, 94, 98, 110, 111, 112, 115, 167], "315": [49, 81, 101], "0": [42, 43, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 72, 74, 75, 78, 79, [...]
\ No newline at end of file
+{
+ "0": [
+ 42,
+ 43,
+ 46,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69,
+ 72,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 82,
+ 83,
+ 84,
+ 85,
+ 87,
+ 88,
+ 89,
+ 90,
+ 91,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 103,
+ 104,
+ 105,
+ 107,
+ 110,
+ 111,
+ 113,
+ 114,
+ 115,
+ 134,
+ 135,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "200": [
+ 41,
+ 108,
+ 109
+ ],
+ "300": [
+ 41,
+ 45,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 70,
+ 71,
+ 73,
+ 94,
+ 103,
+ 105,
+ 106,
+ 108,
+ 109,
+ 115
+ ],
+ "315": [
+ 49,
+ 81,
+ 101
+ ],
+ "500": [
+ 41,
+ 42,
+ 45,
+ 47,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 70,
+ 71,
+ 73,
+ 78,
+ 79,
+ 80,
+ 94,
+ 98,
+ 103,
+ 105,
+ 108,
+ 109,
+ 112,
+ 115
+ ],
+ "700": [
+ 42,
+ 43,
+ 44,
+ 45,
+ 47,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 70,
+ 71,
+ 73,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 86,
+ 94,
+ 98,
+ 110,
+ 111,
+ 112,
+ 115,
+ 167
+ ],
+ "850": [
+ 42,
+ 43,
+ 45,
+ 47,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 70,
+ 71,
+ 73,
+ 78,
+ 79,
+ 80,
+ 92,
+ 93,
+ 94,
+ 98,
+ 101,
+ 102,
+ 110,
+ 111,
+ 112,
+ 115,
+ 167
+ ],
+ "925": [
+ 42,
+ 43,
+ 47,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 78,
+ 79,
+ 80,
+ 98,
+ 110,
+ 111,
+ 112,
+ 115,
+ 167
+ ]
+}
diff --git a/share/magics/marsClass.json b/share/magics/marsClass.json
index 051905e..a604d66 100644
--- a/share/magics/marsClass.json
+++ b/share/magics/marsClass.json
@@ -1 +1,93 @@
-{"od": [41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 134, 135, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180]}
\ No newline at end of file
+{
+ "od": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69,
+ 70,
+ 71,
+ 72,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 82,
+ 83,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 89,
+ 90,
+ 91,
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 106,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 113,
+ 114,
+ 115,
+ 134,
+ 135,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ]
+}
diff --git a/share/magics/marsStream.json b/share/magics/marsStream.json
index f641a2d..482dff8 100644
--- a/share/magics/marsStream.json
+++ b/share/magics/marsStream.json
@@ -1 +1,139 @@
-{"oper": [41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 86, 87, 88, 90, 91, 94, 95, 96, 97, 98, 99, 100, 101, 104, 107, 108, 109, 110, 111, 112, 113, 114, 115, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180], "waef": [49, 60, 62, 63, 64, 65, 66, 67, 82, 83, 84], "enfo": [42, 43, 46, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 72, 74, 75, 78, 79, 80, 88, 89, 90, 91, 92, 93, 98, 99 [...]
\ No newline at end of file
+{
+ "enfo": [
+ 42,
+ 43,
+ 46,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 72,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 88,
+ 89,
+ 90,
+ 91,
+ 92,
+ 93,
+ 98,
+ 99,
+ 100,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 106,
+ 110,
+ 111,
+ 115,
+ 134,
+ 135,
+ 149,
+ 167
+ ],
+ "oper": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 59,
+ 69,
+ 70,
+ 71,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 86,
+ 87,
+ 88,
+ 90,
+ 91,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 104,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 113,
+ 114,
+ 115,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "waef": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 82,
+ 83,
+ 84
+ ],
+ "wave": [
+ 49,
+ 82,
+ 83,
+ 84,
+ 85
+ ]
+}
diff --git a/share/magics/marsType.json b/share/magics/marsType.json
index b921d57..c6a02a0 100644
--- a/share/magics/marsType.json
+++ b/share/magics/marsType.json
@@ -1 +1,144 @@
-{"em": [51, 52, 53, 55, 115, 167], "efi": [68, 72, 89, 134, 135], "fc": [41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 94, 95, 96, 97, 98, 99, 100, 101, 104, 107, 108, 109, 110, 111, 112, 113, 114, 115, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180], "pf": [42, 43, 46, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 67, 74, 75, 78, 79, 80, 82, 83, 84, 88, [...]
\ No newline at end of file
+{
+ "efi": [
+ 68,
+ 72,
+ 89,
+ 134,
+ 135
+ ],
+ "em": [
+ 51,
+ 52,
+ 53,
+ 55,
+ 115,
+ 167
+ ],
+ "ep": [
+ 61,
+ 62
+ ],
+ "es": [
+ 92,
+ 93,
+ 101,
+ 102,
+ 103,
+ 105
+ ],
+ "fc": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 59,
+ 69,
+ 70,
+ 71,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 82,
+ 83,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 90,
+ 91,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 104,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 113,
+ 114,
+ 115,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "pf": [
+ 42,
+ 43,
+ 46,
+ 49,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 82,
+ 83,
+ 84,
+ 88,
+ 90,
+ 91,
+ 98,
+ 99,
+ 100,
+ 103,
+ 104,
+ 105,
+ 106,
+ 110,
+ 111,
+ 115,
+ 149,
+ 167
+ ]
+}
diff --git a/share/magics/number.json b/share/magics/number.json
index 7f494b0..e3016fb 100644
--- a/share/magics/number.json
+++ b/share/magics/number.json
@@ -1 +1,131 @@
-{"1": [56, 149], "0": [41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 59, 61, 62, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 134, 135, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180], "50": [42, 43, 46, 49, 51, 52, 53, 54, 55, 57, 58, 60, 62, 63, 64, 65, 66, 67, 74, 75, 78, 79, 80, 82, 83, 84, 88, [...]
\ No newline at end of file
+{
+ "0": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 59,
+ 61,
+ 62,
+ 68,
+ 69,
+ 70,
+ 71,
+ 72,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 82,
+ 83,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 89,
+ 90,
+ 91,
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 113,
+ 114,
+ 115,
+ 134,
+ 135,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "1": [
+ 56,
+ 149
+ ],
+ "50": [
+ 42,
+ 43,
+ 46,
+ 49,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 57,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 82,
+ 83,
+ 84,
+ 88,
+ 90,
+ 91,
+ 98,
+ 99,
+ 100,
+ 103,
+ 104,
+ 105,
+ 106,
+ 110,
+ 111,
+ 115,
+ 167
+ ]
+}
diff --git a/share/magics/paramId.json b/share/magics/paramId.json
index 3ecb5d7..61cd961 100644
--- a/share/magics/paramId.json
+++ b/share/magics/paramId.json
@@ -1 +1,347 @@
-{"151": [48, 50, 51, 52, 53, 54, 55, 103, 105, 113, 114, 115], "155": [45, 70, 71, 73, 94], "157": [47, 112], "60": [49, 81, 101], "132": [41, 43, 98, 108, 109, 110, 111], "130": [42, 51, 52, 53, 78, 79, 80, 92, 93, 115, 167], "135": [44, 76, 77, 86], "132228": [89, 135], "138": [45, 70, 71, 73, 94], "166": [43, 58, 60, 62, 63, 64, 65, 66, 67, 88, 98, 104, 110, 111], "131090": [61, 62], "49": [43, 58, 60, 62, 63, 64, 65, 66, 67, 88, 98, 100, 104], "140229": [49, 60, 62, 63, 64, 65, 66, 6 [...]
\ No newline at end of file
+{
+ "10": [
+ 52,
+ 53,
+ 101,
+ 102,
+ 115
+ ],
+ "129": [
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 103,
+ 105,
+ 106,
+ 115,
+ 149,
+ 150,
+ 151
+ ],
+ "130": [
+ 42,
+ 51,
+ 52,
+ 53,
+ 78,
+ 79,
+ 80,
+ 92,
+ 93,
+ 115,
+ 167
+ ],
+ "131089": [
+ 61,
+ 62
+ ],
+ "131090": [
+ 61,
+ 62
+ ],
+ "131091": [
+ 61,
+ 62
+ ],
+ "132": [
+ 41,
+ 43,
+ 98,
+ 108,
+ 109,
+ 110,
+ 111
+ ],
+ "207": [111],
+ "132049": [
+ 89,
+ 134
+ ],
+ "132165": [
+ 89,
+ 134
+ ],
+ "132167": [
+ 68,
+ 72
+ ],
+ "132228": [
+ 89,
+ 135
+ ],
+ "135": [
+ 44,
+ 76,
+ 77,
+ 86
+ ],
+ "138": [
+ 45,
+ 70,
+ 71,
+ 73,
+ 94
+ ],
+ "140229": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 83,
+ 84
+ ],
+ "140232": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 82
+ ],
+ "140234": [
+ 49,
+ 83,
+ 84,
+ 85
+ ],
+ "140236": [
+ 49,
+ 82
+ ],
+ "140237": [
+ 49,
+ 83,
+ 84
+ ],
+ "140239": [
+ 49,
+ 82
+ ],
+ "141": [
+ 95,
+ 96,
+ 97,
+ 107
+ ],
+ "142": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "143": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "144": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "151": [
+ 48,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 103,
+ 105,
+ 113,
+ 114,
+ 115
+ ],
+ "155": [
+ 45,
+ 70,
+ 71,
+ 73,
+ 94
+ ],
+ "157": [
+ 47,
+ 112
+ ],
+ "166": [
+ 43,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 104,
+ 110,
+ 111
+ ],
+ "167": [
+ 42,
+ 57,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "168": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "186": [
+ 59,
+ 174,
+ 175
+ ],
+ "187": [
+ 59,
+ 176,
+ 177
+ ],
+ "188": [
+ 59,
+ 178,
+ 179
+ ],
+ "201": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "202": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "228": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "31": [
+ 69,
+ 87,
+ 180
+ ],
+ "49": [
+ 43,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 100,
+ 104
+ ],
+ "59": [
+ 60,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 156
+ ],
+ "60": [
+ 49,
+ 81,
+ 101
+ ]
+}
diff --git a/share/magics/shortName.json b/share/magics/shortName.json
index d6b3ec0..9a88237 100644
--- a/share/magics/shortName.json
+++ b/share/magics/shortName.json
@@ -1 +1,346 @@
-{"ci": [69, 87, 180], "mpww": [49, 82], "ptd": [61, 62], "shts": [49, 83, 84], "10fg": [43, 58, 60, 62, 63, 64, 65, 66, 67, 88, 98, 100, 104], "vo": [45, 70, 71, 73, 94], "lsp": [46, 60, 62, 63, 64, 65, 66, 67, 90, 91, 99], "cp": [46, 60, 62, 63, 64, 65, 66, 67, 90, 91, 99], "10v": [43, 58, 60, 62, 63, 64, 65, 66, 67, 88, 98, 104, 110, 111], "mx2t": [42, 57, 60, 62, 63, 64, 65, 66, 67, 74, 75, 78, 79, 80, 167], "swh": [49, 60, 62, 63, 64, 65, 66, 67, 83, 84], "mwp": [49, 60, 62, 63, 64, [...]
\ No newline at end of file
+{
+ "10fg": [
+ 43,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 100,
+ 104
+ ],
+ "10fgi": [
+ 89,
+ 134
+ ],
+ "10v": [
+ 43,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 104,
+ 110,
+ 111
+ ],
+ "10wsi": [
+ 89,
+ 134
+ ],
+ "2d": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "2t": [
+ 42,
+ 57,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "2ti": [
+ 68,
+ 72
+ ],
+ "cape": [
+ 60,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 156
+ ],
+ "ci": [
+ 69,
+ 87,
+ 180
+ ],
+ "cp": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "d": [
+ 45,
+ 70,
+ 71,
+ 73,
+ 94
+ ],
+ "hcc": [
+ 59,
+ 178,
+ 179
+ ],
+ "lcc": [
+ 59,
+ 174,
+ 175
+ ],
+ "lsp": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "mcc": [
+ 59,
+ 176,
+ 177
+ ],
+ "mn2t": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "mpts": [
+ 49,
+ 82
+ ],
+ "mpww": [
+ 49,
+ 82
+ ],
+ "msl": [
+ 48,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 103,
+ 105,
+ 113,
+ 114,
+ 115
+ ],
+ "mwp": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 82
+ ],
+ "mx2t": [
+ 42,
+ 57,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 167
+ ],
+ "ph": [
+ 61,
+ 62
+ ],
+ "ptd": [
+ 61,
+ 62
+ ],
+ "pts": [
+ 61,
+ 62
+ ],
+ "pv": [
+ 49,
+ 81,
+ 101
+ ],
+ "r": [
+ 47,
+ 112
+ ],
+ "sd": [
+ 95,
+ 96,
+ 97,
+ 107
+ ],
+ "sf": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "shts": [
+ 49,
+ 83,
+ 84
+ ],
+ "shww": [
+ 49,
+ 83,
+ 84,
+ 85
+ ],
+ "swh": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 83,
+ 84
+ ],
+ "t": [
+ 42,
+ 51,
+ 52,
+ 53,
+ 78,
+ 79,
+ 80,
+ 92,
+ 93,
+ 115,
+ 167
+ ],
+ "tp": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "tpi": [
+ 89,
+ 135
+ ],
+ "v": [
+ 41,
+ 43,
+ 98,
+ 108,
+ 109,
+ 110,
+ 111
+ ],
+ "vo": [
+ 45,
+ 70,
+ 71,
+ 73,
+ 94
+ ],
+ "w": [
+ 44,
+ 76,
+ 77,
+ 86
+ ],
+ "ws": [
+ 52,
+ 53,
+ 101,
+ 102,
+ 115
+ ],
+ "z": [
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 103,
+ 105,
+ 106,
+ 115,
+ 149,
+ 150,
+ 151
+ ]
+}
diff --git a/share/magics/stepRange.json b/share/magics/stepRange.json
index 94ec6bd..9b0af42 100644
--- a/share/magics/stepRange.json
+++ b/share/magics/stepRange.json
@@ -1 +1,135 @@
-{"24": [46, 60, 62, 63, 64, 65, 66, 67, 90, 91, 99], "23-24": [42, 43, 57, 74, 75, 78, 79, 80, 88, 98, 100, 104, 167], "0": [41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 92, 93, 94, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180], "24-72": [61, 62], "0-24": [...]
\ No newline at end of file
+{
+ "0": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 69,
+ 70,
+ 71,
+ 73,
+ 74,
+ 75,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 81,
+ 82,
+ 83,
+ 84,
+ 85,
+ 86,
+ 87,
+ 88,
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 101,
+ 102,
+ 103,
+ 104,
+ 105,
+ 106,
+ 107,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 113,
+ 114,
+ 115,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "0-24": [
+ 68,
+ 72,
+ 89,
+ 134,
+ 135
+ ],
+ "21-24": [
+ 43,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 100,
+ 104
+ ],
+ "23-24": [
+ 42,
+ 43,
+ 57,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 88,
+ 98,
+ 100,
+ 104,
+ 167
+ ],
+ "24": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 99
+ ],
+ "24-72": [
+ 61,
+ 62
+ ]
+}
diff --git a/share/magics/symbols.svg b/share/magics/symbols.svg
index ee6a759..5501dfc 100644
--- a/share/magics/symbols.svg
+++ b/share/magics/symbols.svg
@@ -738,7 +738,7 @@
<snowflake cx='0' cy='0' r='0.2'/>
</g>
<g id='W_8'>
- <polyline points='0.2,0.2 0,-0.3 -0.2,0.2 0.2,0.2 0' fill='none'/>
+ <polyline points='0.2,0.2 0,-0.3 -0.2,0.2 0.2,0.2' fill='none'/>
</g>
<g id='W_9'>
<lightning cx='0' cy='0.3' r='0.7'/>
diff --git a/share/magics/typeOfLevel.json b/share/magics/typeOfLevel.json
index be051e4..58e39e5 100644
--- a/share/magics/typeOfLevel.json
+++ b/share/magics/typeOfLevel.json
@@ -1 +1,125 @@
-{"theta": [49, 81, 101], "isobaricInhPa": [41, 42, 43, 44, 45, 47, 51, 52, 53, 54, 55, 70, 71, 73, 76, 77, 78, 79, 80, 86, 92, 93, 94, 98, 101, 102, 103, 105, 106, 108, 109, 110, 111, 112, 115, 167], "surface": [42, 43, 46, 48, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 72, 74, 75, 78, 79, 80, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 100, 103, 104, 105, 107, 110, 111, 113, 114, 115, 134, 135, 149, 150, 151, 156, 167, 174, 175, 176, 177, 178, 179, 180], [...]
\ No newline at end of file
+{
+ "isobaricInhPa": [
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 47,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 70,
+ 71,
+ 73,
+ 76,
+ 77,
+ 78,
+ 79,
+ 80,
+ 86,
+ 92,
+ 93,
+ 94,
+ 98,
+ 101,
+ 102,
+ 103,
+ 105,
+ 106,
+ 108,
+ 109,
+ 110,
+ 111,
+ 112,
+ 115,
+ 167
+ ],
+ "meanSea": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 82,
+ 83,
+ 84,
+ 85
+ ],
+ "surface": [
+ 42,
+ 43,
+ 46,
+ 48,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69,
+ 72,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 87,
+ 88,
+ 89,
+ 90,
+ 91,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 103,
+ 104,
+ 105,
+ 107,
+ 110,
+ 111,
+ 113,
+ 114,
+ 115,
+ 134,
+ 135,
+ 149,
+ 150,
+ 151,
+ 156,
+ 167,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "theta": [
+ 49,
+ 81,
+ 101
+ ]
+}
diff --git a/share/magics/units.json b/share/magics/units.json
index 999ee2b..d02cb50 100644
--- a/share/magics/units.json
+++ b/share/magics/units.json
@@ -1 +1,177 @@
-{"m**2 s**-2": [51, 52, 53, 54, 55, 56, 103, 105, 106, 115, 149, 150, 151], "%": [47, 61, 62, 112], "J kg**-1": [60, 63, 64, 65, 66, 67, 156], "s**-1": [45, 70, 71, 73, 94], "K": [42, 51, 52, 53, 57, 58, 60, 62, 63, 64, 65, 66, 67, 74, 75, 78, 79, 80, 92, 93, 115, 167], "m": [46, 49, 60, 62, 63, 64, 65, 66, 67, 83, 84, 85, 90, 91, 99], "m of water equivalent": [46, 60, 62, 63, 64, 65, 66, 67, 90, 91, 95, 96, 97, 99, 107], "s": [49, 60, 62, 63, 64, 65, 66, 67, 82], "Pa": [48, 50, 51, 52, [...]
\ No newline at end of file
+{
+ "%": [
+ 47,
+ 61,
+ 62,
+ 112
+ ],
+ "(-1 to 1)": [
+ 68,
+ 72,
+ 89,
+ 134,
+ 135
+ ],
+ "(0 - 1)": [
+ 59,
+ 69,
+ 87,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
+ ],
+ "J kg**-1": [
+ 60,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 156
+ ],
+ "K": [
+ 42,
+ 51,
+ 52,
+ 53,
+ 57,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 74,
+ 75,
+ 78,
+ 79,
+ 80,
+ 92,
+ 93,
+ 115,
+ 167
+ ],
+ "K m**2 kg**-1 s**-1": [
+ 49,
+ 81,
+ 101
+ ],
+ "Pa": [
+ 48,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 103,
+ 105,
+ 113,
+ 114,
+ 115
+ ],
+ "Pa s**-1": [
+ 44,
+ 76,
+ 77,
+ 86
+ ],
+ "m": [
+ 46,
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 83,
+ 84,
+ 85,
+ 90,
+ 91,
+ 99
+ ],
+ "m of water equivalent": [
+ 46,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 90,
+ 91,
+ 95,
+ 96,
+ 97,
+ 99,
+ 107
+ ],
+ "m s**-1": [
+ 41,
+ 43,
+ 52,
+ 53,
+ 58,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 88,
+ 98,
+ 100,
+ 101,
+ 102,
+ 104,
+ 108,
+ 109,
+ 110,
+ 111,
+ 115
+ ],
+ "m**2 s**-2": [
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 103,
+ 105,
+ 106,
+ 115,
+ 149,
+ 150,
+ 151
+ ],
+ "s": [
+ 49,
+ 60,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ 67,
+ 82
+ ],
+ "s**-1": [
+ 45,
+ 70,
+ 71,
+ 73,
+ 94
+ ]
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3d1ba7d..6bf3b1c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -217,15 +217,18 @@ if( metview )
LegendVisitorAttributes.h
XmlRootNodeAttributes.h
WrepRootNodeAttributes.h
- QtDriverAttributes.h
ContinuousLegendMethodAttributes.h
HistogramLegendMethodAttributes.h
XmlBasicNodeAttributes.h
ImagePlottingAttributes.h
LookupTableModeAttributes.h
FixedTableModeAttributes.h
-
)
+ if(qt)
+ list(APPEND attributes_include
+ QtDriverAttributes.h)
+ endif()
+
install( FILES terralib/kernel/TeProjection.h
terralib/kernel/TeCoord2D.h
terralib/kernel/TeDefines.h
diff --git a/src/basic/CMakeLists.txt b/src/basic/CMakeLists.txt
index cbb2b4b..7e64b37 100644
--- a/src/basic/CMakeLists.txt
+++ b/src/basic/CMakeLists.txt
@@ -47,7 +47,7 @@ WebFormat.h
XmlMagics.cc
XmlMagics.h
)
-if ( HAVE_METVIEW )
+if ( metview )
list (APPEND metview_include
basic/MagicsObserver.h
basic/MagicsEvent.h
diff --git a/src/basic/FortranMagics.cc b/src/basic/FortranMagics.cc
index 9bfe7b0..647f06a 100644
--- a/src/basic/FortranMagics.cc
+++ b/src/basic/FortranMagics.cc
@@ -72,6 +72,7 @@
#ifdef HAVE_BUFR
#include "ObsDecoder.h"
+#include "EpsBufr.h"
#endif
#include "ObsJSon.h"
@@ -880,7 +881,22 @@ void FortranMagics::wrepjson()
action_->data(wrep);
}
+void FortranMagics::metbufr()
+{
+#ifdef HAVE_BUFR
+ actions();
+ action_ = new VisualAction();
+
+ EpsBufr* bufr = new EpsBufr();
+
+ top()->push_back(action_);
+ action_->data(bufr);
+ return;
+
+#endif
+ MagLog::warning() << "No Support for Weather Parameters Plotting" << endl;
+}
void FortranMagics::epsinput()
{
actions();
@@ -891,8 +907,18 @@ void FortranMagics::epsinput()
top()->push_back(action_);
action_->data(input);
}
+#include "MetgramGraph.h"
+void FortranMagics::metgraph()
+{
+ actions();
+ if ( !action_ ) {
+ MagLog::error() << "epscloud -> No data defined " << endl;
+ exit(1);
+ }
+ MetgramGraph* graph = new MetgramGraph();
-
+ action_->visdef(graph);
+}
void FortranMagics::epscloud()
{
diff --git a/src/basic/FortranMagics.h b/src/basic/FortranMagics.h
index 41c0a3a..d910b39 100644
--- a/src/basic/FortranMagics.h
+++ b/src/basic/FortranMagics.h
@@ -83,6 +83,10 @@ public:
//Wrep-Eps family!
void epsinput();
void wrepjson();
+
+ void metbufr();
+ void metgraph();
+
void epscloud();
void epsplumes();
void epsgraph();
diff --git a/src/basic/ViewNode.cc b/src/basic/ViewNode.cc
index 8693db0..a3636a5 100644
--- a/src/basic/ViewNode.cc
+++ b/src/basic/ViewNode.cc
@@ -92,7 +92,8 @@ void ViewNode::visit(MetaDataVisitor& metadata)
double imgheight = height * 100 / (100-drawing_top_-drawing_bottom_);
-
+ metadata.add("output_width", tostring(rootWidthResolution()));
+ metadata.add("output_height", tostring(rootHeightResolution()));
viewTransformation_->visit(metadata, left, top, imgwidth, imgheight, width, height);
BasicSceneObject::visit(metadata);
diff --git a/src/basic/XmlMagics.cc b/src/basic/XmlMagics.cc
index 918c853..0fb5f2a 100644
--- a/src/basic/XmlMagics.cc
+++ b/src/basic/XmlMagics.cc
@@ -69,9 +69,10 @@
#ifdef HAVE_SPOT
#include "ClassicMtgDecoder.h"
#include "EpsgramDecoder.h"
-#include "MetgramGraph.h"
+
#endif
+#include "MetgramGraph.h"
#include "EpsGraph.h"
using namespace magics;
@@ -679,11 +680,11 @@ void XmlMagics::metgram(const XmlNode& node)
void XmlMagics::metgraph(const XmlNode& node)
{
-#ifdef HAVE_SPOT
+
MetgramGraph* metgraph = new MetgramGraph();
metgraph->set(node);
top()->visdef(metgraph);
-#endif
+
}
diff --git a/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp b/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
index eeabbc8..74aa5fc 100644
--- a/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
+++ b/src/boost/geometry/extensions/gis/io/shapelib/shape_creator.hpp
@@ -36,6 +36,7 @@ public:
{
return m_filename.c_str();
}
+ virtual ~shapelib_file_create_exception() throw() { }
private :
std::string m_filename;
};
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index a036f8f..8cddf67 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -100,7 +100,7 @@ endforeach()
set( common_srcs ${common_srcs} PARENT_SCOPE )
set( common_templates ${common_templates} PARENT_SCOPE )
-if ( HAVE_METVIEW )
+if ( metview )
list (APPEND metview_include
common/MagLog.h
common/MagTranslator.h
diff --git a/src/common/Colour.cc b/src/common/Colour.cc
index 5cf8858..70f1568 100644
--- a/src/common/Colour.cc
+++ b/src/common/Colour.cc
@@ -313,6 +313,7 @@ void Colour::init() {
colours_["none"] = Rgb(-1., -1., -1.);
colours_["background"] = Rgb(1., 1., 1.);
colours_["foreground"] = Rgb(0., 0., 0.);
+ colours_["ecmwf_blue"] = Rgb(0.25, 0.43, 0.7);
colours_["red"] = Rgb(1.0000, 0.0000, 0.0000);
colours_["green"] = Rgb(0.0000, 1.0000, 0.0000);
colours_["blue"] = Rgb(0.0000, 0.0000, 1.0000);
diff --git a/src/common/GeoRectangularProjection.cc b/src/common/GeoRectangularProjection.cc
index 973affa..bdae818 100644
--- a/src/common/GeoRectangularProjection.cc
+++ b/src/common/GeoRectangularProjection.cc
@@ -82,7 +82,6 @@ PaperPoint GeoRectangularProjection::operator()(const UserPoint& point) const
}
-
TeCoord2D geo = TeCoord2D(point.x()*TeCDR, point.y()*TeCDR);
TeCoord2D xy = projection_->LL2PC(geo);
@@ -298,7 +297,6 @@ void GeoRectangularProjection::labels(const LabelPlotting& label, TopAxisVisitor
text->setJustification(MCENTRE);
text->setVerticalAlign(MBOTTOM);
text->push_back((*this)(point));
-
}
}
}
@@ -325,7 +323,6 @@ void GeoRectangularProjection::labels(const LabelPlotting& label, BottomAxisVisi
text->setJustification(MCENTRE);
text->setVerticalAlign(MTOP);
text->push_back((*this)(point));
-
}
}
}
@@ -352,7 +349,6 @@ void GeoRectangularProjection::labels(const LabelPlotting& label, LeftAxisVisito
text->setJustification(MRIGHT);
text->setVerticalAlign(MHALF);
text->push_back((*this)(point));
-
}
}
}
@@ -387,9 +383,9 @@ void GeoRectangularProjection::labels(const LabelPlotting& label, RightAxisVisit
}
}
}
+
double GeoRectangularProjection::patchDistance(double res) const
{
-
return res;
}
@@ -436,7 +432,6 @@ void GeoRectangularProjection::init()
// if ( min_latitude_ < -90) min_latitude_ = -90.;
// if ( max_latitude_ > 90 ) max_latitude_ = 90;
-
xpcmin_ = min_longitude_;
ypcmin_ = min_latitude_;
xpcmax_ = max_longitude_;
@@ -458,7 +453,6 @@ void GeoRectangularProjection::init()
askedxmax_ = std::max(xpcmin_, xpcmax_);
askedymin_ = std::min(ypcmin_, ypcmax_);
askedymax_ = std::max(ypcmin_, ypcmax_);
-
}
MercatorProjection::MercatorProjection()
@@ -522,17 +516,15 @@ void MercatorProjection::init()
askedxmax_ = std::max(xpcmin_, xpcmax_);
askedymin_ = std::min(ypcmin_, ypcmax_);
askedymax_ = std::max(ypcmin_, ypcmax_);
+}
-}
void MercatorProjection::fast_reproject(double& x, double& y) const
{
-
TeCoord2D geo = TeCoord2D(x*TeCDR, y*TeCDR);
TeCoord2D xy = projection_->LL2PC(geo);
x = xy.x();
y = xy.y();
-
}
@@ -581,13 +573,14 @@ void GeoRectangularProjection::coastSetting(map<string, string>& setting, double
}
setting["resolution"] = resol;
- setting["lakes"] = resol + "/" + resol + "_lakes";
- setting["land"] = resol + "/" + resol + "_land";
- setting["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- setting["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
+ setting["land"] = resol + "/ne_" + resol + "_land";
+ setting["ocean"] = resol + "/ne_" + resol + "_ocean";
+ setting["coast"] = resol + "/ne_" + resol + "_coastline";
+ setting["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ setting["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
//! \note Administraive borders hardcoded to 10m resolution (low res version do not contain all info)
- setting["administrative_boundaries"] = "10m/10m_admin_1_states_provinces_shp";
+ setting["administrative_boundaries"] = "10m/ne_10m_admin_1_states_provinces";
MagLog::dev() << "GeoRectangularProjection::coastSetting[" << abswidth << ", " << absheight << "]->" << ratio << " resol: "<<resol<< endl;
}
@@ -601,10 +594,6 @@ MatrixHandler* GeoRectangularProjection::prepareData(const AbstractMatrix& matri
void GeoRectangularProjection::populate(double lon, double lat, double value, vector<UserPoint>& out) const
{
-
-
-
-
while ( lon < min_longitude_)
lon += 360;
while ( lon > min_longitude_ + 360. )
@@ -613,7 +602,6 @@ void GeoRectangularProjection::populate(double lon, double lat, double value, ve
if ( !in(lon, lat) )
return;
-
out.push_back(UserPoint(lon, lat, value));
lon += 360.;
@@ -627,7 +615,6 @@ void GeoRectangularProjection::populate(double lon, double lat, double value, ve
out.push_back(UserPoint(lon, lat, value));
lon -= 360;
}
-
}
void GeoRectangularProjection::wraparound(const UserPoint& origin, stack<UserPoint>& out) const
@@ -636,8 +623,6 @@ void GeoRectangularProjection::wraparound(const UserPoint& origin, stack<UserPoi
if (point.y_ > max_latitude_ || point.y_ < min_latitude_ )
return;
-
-
while ( point.x_ < min_longitude_)
point.x_ += 360;
while ( point.x_ > min_longitude_ + 360. )
@@ -664,12 +649,10 @@ void GeoRectangularProjection::wraparound(const UserPoint& origin, stack<UserPoi
out.push(point);
point.x_ -= 360;
}
-
}
Polyline& GeoRectangularProjection::getPCBoundingBox() const
{
-
if ( PCEnveloppe_->empty() ) {
PCEnveloppe_->push_back(PaperPoint(xpcmin_, ypcmin_));
PCEnveloppe_->push_back(PaperPoint(xpcmin_, ypcmax_));
@@ -677,8 +660,6 @@ Polyline& GeoRectangularProjection::getPCBoundingBox() const
PCEnveloppe_->push_back(PaperPoint(xpcmax_, ypcmin_));
PCEnveloppe_->push_back(PaperPoint(xpcmin_, ypcmin_));
}
-
-
return *PCEnveloppe_;
}
@@ -692,7 +673,6 @@ Polyline& GeoRectangularProjection::getUserBoundingBox() const
userEnveloppe_->push_back(PaperPoint(max_longitude_, min_latitude_));
userEnveloppe_->push_back(PaperPoint(min_longitude_, min_latitude_));
}
-
return *userEnveloppe_;
}
@@ -714,20 +694,14 @@ void GeoRectangularProjection::setDefinition(const string& json)
if (json.empty())
return;
-
-
MagJSon helper;
helper.interpret(json);
XmlNode node = **helper.tree_.firstElement();
-
node.name("cylindrical");
-
-
set(node);
-
-
}
+
double MercatorProjection::patchDistance(double) const
{
return 1000000;
diff --git a/src/common/LogoPlotting.cc b/src/common/LogoPlotting.cc
index 064e67f..9da5368 100644
--- a/src/common/LogoPlotting.cc
+++ b/src/common/LogoPlotting.cc
@@ -61,8 +61,6 @@ void LogoPlotting::operator()(BasicGraphicsObjectContainer& tree) const
{
Symbol* symbol = new Symbol();
-
-
double x = (0.3 * 6.75 * 100) / tree.absoluteWidth();
x = 90;
double y = (0.3/tree.absoluteHeight())*100; // 0.2
@@ -80,7 +78,6 @@ UserLogoPlotting::UserLogoPlotting()
{
}
-
UserLogoPlotting::~UserLogoPlotting()
{
}
@@ -96,7 +93,6 @@ void UserLogoPlotting::print(ostream& out) const
void UserLogoPlotting::operator()(BasicGraphicsObjectContainer& tree) const
{
-
ImportObject* object = new ImportObject();
object->setPath(UserLogoPlottingAttributes::path_);
@@ -106,11 +102,10 @@ void UserLogoPlotting::operator()(BasicGraphicsObjectContainer& tree) const
double x = UserLogoPlottingAttributes::x_;
double y = UserLogoPlottingAttributes::y_;
-
-
- double height = tree.absoluteHeight();
- double width = tree.absoluteWidth();
- // Diemnsion
+
+ const double height = tree.absoluteHeight();
+ const double width = tree.absoluteWidth();
+ // Dimensions
if ( UserLogoPlottingAttributes::bottom_.empty() || UserLogoPlottingAttributes::left_.empty() ) {
if ( magCompare(UserLogoPlottingAttributes::units_, "cm") ) {
@@ -125,8 +120,5 @@ void UserLogoPlotting::operator()(BasicGraphicsObjectContainer& tree) const
y = bottom.percent();
}
object->setOrigin(PaperPoint(x, y));
-
tree.push_back(object);
}
-
-
diff --git a/src/common/MagicsCalls.cc b/src/common/MagicsCalls.cc
index 6471517..962dffe 100644
--- a/src/common/MagicsCalls.cc
+++ b/src/common/MagicsCalls.cc
@@ -1204,6 +1204,15 @@ void pepsinput_()
{
magics_->epsinput();
}
+void pmetgraph_()
+{
+ magics_->metgraph();
+}
+void pmetbufr_()
+{
+ magics_->metbufr();
+}
+
void pepscloud_()
{
magics_->epscloud();
@@ -1280,6 +1289,8 @@ void mag_geojson() { pgeojson_(); }
void mag_wrepjson() { pwrepjson_(); }
void mag_epsinput() { pepsinput_(); }
void mag_epscloud() { pepscloud_(); }
+void mag_metgraph() { pmetgraph_(); }
+void mag_metbufr() { pmetbufr_(); }
void mag_epsgraph() { pepsgraph_(); }
void mag_epswave() { pepswave_(); }
@@ -1469,11 +1480,11 @@ void mag_enqr(const char* fname, double *value)
special.push_back("subpage_y_length");
// parameters needs magics to get reday!
- string projection;
+ string projection;
- ParameterManager::get("subpage_map_projection", projection);
+ ParameterManager::get("subpage_map_projection", projection);
- for (vector<string>::iterator param = special.begin(); param != special.end(); ++param)
+ for (vector<string>::iterator param = special.begin(); param != special.end(); ++param) {
if (magCompare(name, *param) ) {
double val;
ParameterManager::get(name,val);
@@ -1482,6 +1493,7 @@ void mag_enqr(const char* fname, double *value)
name = name + "_internal";
}
}
+ }
double magics;
ParameterManager::get(name,magics);
*value=magics;
@@ -1548,9 +1560,7 @@ public:
bool operator()(double val)
{
ParameterManager::set(from_, val);
-
update(val);
-
return false;
}
@@ -1559,7 +1569,6 @@ public:
{
string orientation;
ParameterManager::get("axis_orientation", orientation);
-
if ( magCompare(orientation, "horizontal") )
{
@@ -1568,38 +1577,28 @@ public:
else
{
ParameterManager::set(vertical_, val);
-
}
}
void update(const string& val)
{
- string orientation;
- ParameterManager::get("axis_orientation", orientation);
-
-
- if ( magCompare(orientation, "horizontal") )
- {
- if (magCompare(val, "position_list") ){
- MagLog::warning() << "position_list is now using the user coordinates system and not cm" << endl;
- MagLog::warning() << "please check your coordinates system" << endl;
-
- }
- else
- ParameterManager::set(horizontal_, val);
- }
- else
- {
- if (magCompare(val, "position_list") ){
- MagLog::warning() << "position_list is now using the user coordinates system and not cm" << endl;
- MagLog::warning() << "please check your coordinates system" << endl;
+ string orientation;
+ ParameterManager::get("axis_orientation", orientation);
- }
- else
- ParameterManager::set(vertical_, val);
+ if (magCompare(val, "position_list") ){
+ MagLog::info() << "position_list is now using the user coordinates system and not cm" << endl;
+ return;
+ }
- }
+ if ( magCompare(orientation, "horizontal") )
+ {
+ ParameterManager::set(horizontal_, val);
}
+ else
+ {
+ ParameterManager::set(vertical_, val);
+ }
+ }
bool operator()(const string& value)
{
diff --git a/src/common/PolarStereographicProjection.cc b/src/common/PolarStereographicProjection.cc
index 981a57d..5531af7 100644
--- a/src/common/PolarStereographicProjection.cc
+++ b/src/common/PolarStereographicProjection.cc
@@ -406,9 +406,6 @@ double PolarStereographicProjection::getMaxY() const
return ymax_;
}
-
-
-
double PolarStereographicProjection::getMinPCX() const
{
return xpcmin_;
@@ -532,8 +529,6 @@ void PolarStereographicProjection::horizontalLabels(const LabelPlotting& label,
label.add(text);
text->setText(writeLongitude(geo));
text->push_back(point);
-
-
}
}
@@ -587,8 +582,6 @@ void PolarStereographicProjection::verticalLabels(const LabelPlotting& label, do
text->setVerticalAlign(MHALF);
text->setText(writeLongitude(geo));
text->push_back(point);
-
-
}
}
@@ -616,8 +609,6 @@ void PolarStereographicProjection::labels(const LabelPlotting& label, DrawingVis
label.add(text); // This will set the font!
text->setText(writeLatitude(point));
text->push_back(xy);
-
-
}
}
}
@@ -709,9 +700,6 @@ void PolarStereographicProjection::corners()
xmax_ = max_longitude_;
ymin_ = min_latitude_;
ymax_ = max_latitude_;
-
-
-
}
@@ -755,8 +743,6 @@ void PolarStereographicProjection::thin(MatrixHandler& matrix, double x, double
Transformation::thin(matrix, x, y, out);
return;
int yfactor = (int) ceil((float) x);
-
-
int columns = matrix.columns();
int rows = matrix.rows();
@@ -800,8 +786,6 @@ void PolarStereographicProjection::setNewPCBox(double minx, double miny, double
min_latitude_ = ll.y();
max_latitude_ = ur.y();
-
-
corners();
xpcmin_ = minx;
@@ -844,9 +828,6 @@ void PolarStereographicProjection::reprojectComponents(double& x, double& y, pai
// we the angle and the spped we compute u/v...
components.first = speed * cos(angle+rotation);
components.second = speed * sin(angle+rotation);
-
-
-
}
void PolarStereographicProjection::reprojectSpeedDirection(const PaperPoint& point, pair<double, double>& wind) const
@@ -880,13 +861,14 @@ void PolarStereographicProjection::coastSetting(map<string, string>& setting, do
resol = "50m";
}
setting["resolution"] = resol;
- setting["lakes"] = resol + "/" + resol + "_lakes";
- setting["land"] = resol + "/" + resol + "_land";
- setting["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- setting["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
+ setting["land"] = resol + "/ne_" + resol + "_land";
+ setting["ocean"] = resol + "/ne_" + resol + "_ocean";
+ setting["coast"] = resol + "/ne_" + resol + "_coastline";
+ setting["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ setting["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
//! \note Administraive borders hardcoded to 10m resolution (low res version do not contain all info)
- setting["administrative_boundaries"] = "10m/10m_admin_1_states_provinces_shp";
+ setting["administrative_boundaries"] = "10m/10m_admin_1_states_provinces";
MagLog::dev() << "GeoRectangularProjection::coastSetting[" << abswidth << ", " << absheight << "]->" << ratio << " resol: "<<resol<< endl;
}
@@ -899,57 +881,43 @@ void PolarStereographicProjection::wraparound(const UserPoint& point, stack<User
if ( in(point) ) {
duplicates.push(point);
}
-
}
Polyline& PolarStereographicProjection::getPCBoundingBox() const
{
-
-
if ( PCEnveloppe_->empty() ) {
getUserBoundingBox();
}
-
return *PCEnveloppe_;
}
Polyline& PolarStereographicProjection::getUserBoundingBox() const
{
-
- double minlat = -90;
- double maxlat = 90;
- double minlon = -180;
- double maxlon = 180;
+ const double minlat = -90.;
+ const double maxlat = 90.;
+ const double minlon = -180.;
+ const double maxlon = 180.;
if ( userEnveloppe_->empty() ) {
// left
for ( int lat = minlat; lat <= maxlat; lat++) {
userEnveloppe_->push_back(PaperPoint(minlon,lat));
-
}
// top
for ( int lon = minlon; lon <= maxlon; lon++) {
userEnveloppe_->push_back(PaperPoint(lon, maxlat));
-
}
// right
for ( int lat = maxlat; lat >= minlat; lat--) {
userEnveloppe_->push_back(PaperPoint(maxlon, lat));
-
}
// bottom
for ( int lon = maxlon; lon >= minlon; lon--) {
userEnveloppe_->push_back(PaperPoint(lon, minlat));
-
}
-
}
-
return *userEnveloppe_;
-
-
-
}
#include <boost/geometry/algorithms/distance.hpp>
@@ -965,7 +933,6 @@ double PolarStereographicProjection::patchDistance(double res) const
double x = xy1.distance(xy2);
*/
return 100000*res;
-
}
void PolarStereographicProjection::fast_reproject(double& x, double& y) const
@@ -974,7 +941,6 @@ void PolarStereographicProjection::fast_reproject(double& x, double& y) const
TeCoord2D xy = projection_->LL2PC(geo);
x = xy.x();
y = xy.y();
-
}
void PolarStereographicProjection::getNewDefinition(const UserPoint& ll, const UserPoint& ur, string& out) const
@@ -991,8 +957,8 @@ void PolarStereographicProjection::getNewDefinition(const UserPoint& ll, const U
def["subpage_upper_right_latitude"] = tostring(ur.y_);
::toxml(out, def);
out = "{" + out + "}";
-
}
+
void PolarStereographicProjection::setDefinition(const string& json)
{
if (json.empty())
@@ -1002,19 +968,13 @@ void PolarStereographicProjection::setDefinition(const string& json)
helper.interpret(json);
XmlNode node = **helper.tree_.firstElement();
-
node.name("polar_stereographic");
-
-
set(node);
-
-
}
+
UserPoint PolarStereographicProjection::reference() const
{
UserPoint ll = ( hemisphere_ == NORTH ) ? UserPoint(0, 60) : UserPoint(0, -60);
-
-
return ll;
}
diff --git a/src/common/Polyline.cc b/src/common/Polyline.cc
index 158d0d5..f645fe7 100644
--- a/src/common/Polyline.cc
+++ b/src/common/Polyline.cc
@@ -193,7 +193,7 @@ Polyline* Polyline::clone() const
return to;
}
-void Polyline::intersect(const Polyline& poly, vector<Polyline>& out) const
+void Polyline::intersect(const Polyline& poly, vector<Polyline> & out) const
{
vector<BoostPoly> clip;
@@ -204,6 +204,22 @@ void Polyline::intersect(const Polyline& poly, vector<Polyline>& out) const
out.push_back(Polyline());
out.back().copy(*this);
out.back().polygon_ = *c;
+/*
+ if(!c->inners().empty())
+ {
+ const int noHoles = c->inners().size();
+ for (int h=0; h<noHoles; ++h)
+ {
+ out.back().newHole();
+ const int noPointsHoles = c->inners()[h].size();
+ for (int hh=noPointsHoles-1; hh > 0;--hh)
+ {
+ using boost::geometry::get;
+ out.back().push_back_hole(PaperPoint(get<0>(c->inners()[h][hh]),get<1>(c->inners()[h][hh]) ));
+ }
+ }
+ }
+*/
}
}
catch(...) {
@@ -284,7 +300,7 @@ bool Polyline::sanityCheck()
// output flag true if input polygon modified.
boost::geometry::correct(polygon_);
bool io_rbModified = false;
- if (polygon_.outer().size() == 0)
+ if (polygon_.outer().empty())
return io_rbModified;
// we construct a "largest" polygon by iterating through the input.
diff --git a/src/common/Proj4Projection.cc b/src/common/Proj4Projection.cc
index bd9504b..db0eb4f 100644
--- a/src/common/Proj4Projection.cc
+++ b/src/common/Proj4Projection.cc
@@ -191,19 +191,18 @@ Proj4Projection::Proj4Projection(const string& definition) : definition_(definit
gridMinLat_(DBL_MAX),
gridMaxLon_(-DBL_MAX),
gridMaxLat_(-DBL_MAX)
-
{
//init();
EpsgConfig config;
config.init();
}
+
Proj4Projection::Proj4Projection(): gridMinLon_(DBL_MAX),
gridMinLat_(DBL_MAX),
gridMaxLon_(-DBL_MAX),
gridMaxLat_(-DBL_MAX)
{
-
//init();
EpsgConfig config;
config.init();
@@ -214,8 +213,7 @@ Proj4Projection::Proj4Projection(): gridMinLon_(DBL_MAX),
\brief Destructor
*/
Proj4Projection::~Proj4Projection()
-{
-
+{
}
void Proj4Projection::print(ostream& out) const
@@ -227,27 +225,18 @@ void Proj4Projection::print(ostream& out) const
Polyline& Proj4Projection::getPCBoundingBox() const
{
-
return *PCEnveloppe_;
}
Polyline& Proj4Projection::getUserBoundingBox() const
{
-
-
- return *userEnveloppe_;
-
-
-
+ return *userEnveloppe_;
}
void Proj4Projection::init()
{
-
MagLog::dev() << "Proj4Projection::init()" << *this << endl;
-
-
from_ = pj_init_plus("+proj=longlat +ellps=WGS84 +datum=WGS84");
projection_ = Epsg::find(*this);
to_ = pj_init_plus(projection_->definition());
@@ -257,8 +246,6 @@ void Proj4Projection::init()
ASSERT(false);
}
-
-
methods_["geos"] = &Proj4Projection::geos;
methods_["conic"] = &Proj4Projection::conic;
methods_["simple"] = &Proj4Projection::simple;
@@ -297,19 +284,14 @@ void Proj4Projection::full()
void Proj4Projection::corners()
{
// we have to update the PVBounding box!
-
min_pcx_ = min_longitude_;
min_pcy_ = min_latitude_;
max_pcx_ = max_longitude_;
max_pcy_ = max_latitude_;
-
fast_reproject(min_pcx_, min_pcy_);
fast_reproject(max_pcx_, max_pcy_);
-
-
-
Polyline box;
box.box(PaperPoint(min_pcx_, min_pcy_), PaperPoint(max_pcx_, max_pcy_));
@@ -325,7 +307,6 @@ void Proj4Projection::corners()
void Proj4Projection::centre()
{
-
}
PaperPoint Proj4Projection::operator()(const UserPoint& point) const
@@ -344,13 +325,9 @@ PaperPoint Proj4Projection::operator()(const UserPoint& point) const
int error = pj_transform(from_, to_, 1, 1, &x, &y, NULL);
if ( error ) {
MagLog::debug() << pj_strerrno(error) << " for " << point << endl;
-
return PaperPoint(-1000000, -10000000);
-
}
-
- return PaperPoint(x, y, point.value_, point.missing());
-
+ return PaperPoint(x, y, point.value_, point.missing());
}
PaperPoint Proj4Projection::operator()(const PaperPoint& point) const
@@ -380,11 +357,8 @@ void Proj4Projection::setNewPCBox(double minx, double miny, double maxx, double
void Proj4Projection::revert(const PaperPoint& xy, UserPoint& point) const
{
-
-
double x = xy.x();
double y = xy.y();
-
int error = pj_transform(to_, from_, 1, 1, &x, &y, NULL );
@@ -400,7 +374,6 @@ void Proj4Projection::revert(const PaperPoint& xy, UserPoint& point) const
}
-
bool Proj4Projection::needShiftedCoastlines() const
{
// Will need w new parameter to know!
@@ -429,9 +402,6 @@ void Proj4Projection::add(double lon, double lat)
if ( lat < gridMinLat_ ) gridMinLat_ = lat;
if ( lon > gridMaxLon_) gridMaxLon_ = lon;
if ( lat > gridMaxLat_ ) gridMaxLat_ = lat;
-
-
-
}
void Proj4Projection::conic()
@@ -495,7 +465,6 @@ void Proj4Projection::geos()
max_pcx_ = -DBL_MAX;
max_pcy_ = -DBL_MAX;
-
PCEnveloppe_->correct();
userEnveloppe_->correct();
@@ -525,13 +494,7 @@ void Proj4Projection::geos()
continue;
add(lat->second.back(), lat->first);
userEnveloppe_->push_back(PaperPoint(lat->second.back(), lat->first));
-
}
-
-
-
-
-
}
@@ -547,9 +510,7 @@ void Proj4Projection::boundingBox(double& xmin, double& ymin, double& xmax, doub
xmin = gridMinLon_-5;
ymax = gridMaxLat_;
xmax = gridMaxLon_+5;
-
//cout << "Bounding box ->" << xmin << " " << xmax << endl;
-
}
double Proj4Projection::getMinX() const
@@ -559,7 +520,6 @@ double Proj4Projection::getMinX() const
double Proj4Projection::getMinY() const
{
-
return gridMinLat_;
}
@@ -585,13 +545,11 @@ void Proj4Projection::setMinY(double y)
void Proj4Projection::setMaxX(double x)
{
-
max_longitude_ = x;
}
void Proj4Projection::setMaxY(double y)
{
-
max_latitude_ = y;
}
@@ -618,7 +576,6 @@ double Proj4Projection::getMaxPCY() const
void Proj4Projection::gridLongitudes(const GridPlotting& grid) const
{
-
Polyline boundaries;
for (Polyline::MagLine::const_iterator point = PCEnveloppe_->begin(); point != PCEnveloppe_->end(); ++point )
@@ -675,7 +632,6 @@ void Proj4Projection::gridLatitudes(const GridPlotting& grid) const
void Proj4Projection::labels(const LabelPlotting& label, DrawingVisitor& visitor) const
{
-
vector<double> pro4_longitudes;
pro4_longitudes.push_back(0);
pro4_longitudes.push_back(90);
@@ -702,7 +658,6 @@ void Proj4Projection::labels(const LabelPlotting& label, DrawingVisitor& visitor
text->setText(writeLatitude(point));
text->push_back(xy);
text->setBlanking(true);
-
}
}
}
@@ -710,7 +665,6 @@ void Proj4Projection::labels(const LabelPlotting& label, DrawingVisitor& visitor
void Proj4Projection::labels(const LabelPlotting& label, LeftAxisVisitor& visitor) const
{
-
if ( false ) {
const vector<double>& latitudes = label.latitudes();
@@ -727,20 +681,17 @@ void Proj4Projection::labels(const LabelPlotting& label, LeftAxisVisitor& visito
text->setJustification(MRIGHT);
text->setVerticalAlign(MHALF);
text->setBlanking(true);
-
}
}
else {
double x = max_pcx_ - ((max_pcx_-min_pcx_)*.1);
// we calculate the intersection of the longitudes with the left side
verticalLabels(label, min_pcx_, x, MRIGHT);
-
}
}
void Proj4Projection::labels(const LabelPlotting& label, RightAxisVisitor& visitor) const
{
-
if ( false ) {
const vector<double>& latitudes = label.latitudes();
for (unsigned int lat = 0; lat < latitudes.size(); lat++ )
@@ -756,20 +707,17 @@ void Proj4Projection::labels(const LabelPlotting& label, RightAxisVisitor& visit
text->setJustification(MLEFT);
text->setVerticalAlign(MHALF);
text->setBlanking(true);
-
}
}
else {
// we calculate the intersection of the longitudes with the right side
double x = min_pcx_ + ((max_pcx_-min_pcx_)*.1);
verticalLabels(label, max_pcx_, x, MLEFT);
-
}
}
void Proj4Projection::labels(const LabelPlotting& label, BottomAxisVisitor& visitor) const
{
-
if ( false ) {
const vector<double>& longitudes = label.longitudes();
const double lat = min_latitude_ + (max_latitude_-min_latitude_)*.8;
@@ -785,7 +733,6 @@ void Proj4Projection::labels(const LabelPlotting& label, BottomAxisVisitor& visi
text->setJustification(MCENTRE);
text->setVerticalAlign(MTOP);
text->setBlanking(true);
-
}
}
else {
@@ -809,10 +756,12 @@ inline double CX(double a, double b, double y)
{
return (a) ? (y - b)/a : 0;
}
+
inline double CY(double a, double b, double x)
{
return (a * x) + b;
}
+
inline bool between(double x, double x1, double x2)
{
return ( std::min(x1, x2) <= x && x <= std::max(x1, x2) );
@@ -820,7 +769,6 @@ inline bool between(double x, double x1, double x2)
void Proj4Projection::verticalLabels(const LabelPlotting& label, double x, double pos, Justification justif) const
{
-
const vector<double>& longitudes = label.longitudes();
for (vector<double>::const_iterator lon = longitudes.begin(); lon != longitudes.end(); ++lon)
{
@@ -845,15 +793,13 @@ void Proj4Projection::verticalLabels(const LabelPlotting& label, double x, doubl
text->setVerticalAlign(MHALF);
text->setText(writeLongitude(geo));
text->push_back(xy);
-
}
}
}
-
}
+
void Proj4Projection::horizontalLabels(const LabelPlotting& label, double y, double pos, VerticalAlign align) const
{
-
const vector<double>& longitudes = label.longitudes();
for (vector<double>::const_iterator lon = longitudes.begin(); lon != longitudes.end(); ++lon) {
// find the equation of the line using 2 points : lon/-20 -->lon/ +20
@@ -877,7 +823,6 @@ void Proj4Projection::horizontalLabels(const LabelPlotting& label, double y, dou
text->setVerticalAlign(align);
text->setText(writeLongitude(geo));
text->push_back(xy);
-
}
}
}
@@ -900,7 +845,6 @@ void Proj4Projection::labels(const LabelPlotting& label, TopAxisVisitor& visitor
text->setJustification(MCENTRE);
text->setVerticalAlign(MBOTTOM);
text->setBlanking(true);
-
}
}
else {
@@ -909,31 +853,26 @@ void Proj4Projection::labels(const LabelPlotting& label, TopAxisVisitor& visitor
horizontalLabels(label, max_pcy_, y, MBOTTOM);
}
}
+
void Proj4Projection::reprojectComponents(double& x, double& y, pair<double, double>& components) const
{
- double speed = sqrt((components.first * components.first) + (components.second * components.second));
- double angle = atan2(components.second,components.first);
-
-
+ const double speed = sqrt((components.first * components.first) + (components.second * components.second));
+ const double angle = atan2(components.second,components.first);
double ppx=x+cos(angle);
double ppy=y+sin(angle);
fast_reproject(ppx, ppy);
fast_reproject(x, y);
+ const double rotation = atan2((ppy - y), (ppx - x));
-
- double rotation = atan2((ppy - y), (ppx - x));
-
- // we the angle and the spped we compute u/v...
- components.first = speed * cos(rotation);
- components.second = speed * sin(rotation);
-
+ // we the angle and the spped we compute u/v...
+ components.first = speed * cos(rotation);
+ components.second = speed * sin(rotation);
}
void Proj4Projection::revert(const vector< std::pair<double, double> > & in, vector< std::pair<double, double> > & out) const
{
-
const_cast<Proj4Projection*>(this)->init();
out.reserve(in.size());
for ( vector< std::pair<double, double> >::const_iterator pt = in.begin(); pt != in.end(); ++pt) {
@@ -959,7 +898,6 @@ void Proj4Projection::revert(const vector< std::pair<double, double> > & in, vec
double lat = y*RAD_TO_DEG;
out.push_back(make_pair(lon, lat));
}
-
}
}
@@ -983,20 +921,21 @@ void Proj4Projection::coastSetting(map<string, string>& setting, double abswidth
}
resol = "110m";
setting["resolution"] = resol;
- setting["lakes"] = resol + "/" + resol + "_lakes";
- setting["land"] = resol + "/" + resol + "_land";
- setting["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- setting["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
- setting["administrative_boundaries"] = resol + "/" + resol + "_admin_1_states_provinces_shp";
+ setting["land"] = resol + "/ne_" + resol + "_land";
+ setting["ocean"] = resol + "/ne_" + resol + "_ocean";
+ setting["coast"] = resol + "/ne_" + resol + "_coastline";
+ setting["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ setting["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
+ setting["administrative_boundaries"] = resol + "/ne_" + resol + "_admin_1_states_provinces";
MagLog::dev() << "GeoRectangularProjection::coastSetting[" << abswidth << ", " << absheight << "]->" << ratio << " resol: "<<resol<< endl;
}
+
void Proj4Projection::visit(MetaDataVisitor& visitor,
double left, double top,
double width, double height,
double iwidth, double iheight)
{
-
ostringstream java;
double w = getMaxPCX() - getMinPCX();
double h = getMaxPCY() - getMinPCY();
@@ -1010,12 +949,10 @@ void Proj4Projection::visit(MetaDataVisitor& visitor,
java << "\"height\" : \"" << height << "\",";
java << "\"img_width\" : \"" << iwidth << "\",";
java << "\"img_height\" : \"" << iheight << "\",";
-
java << "\"pcxmin\" : \"" << getMinPCX() << "\",";
java << "\"pcymin\" : \"" << getMinPCY() << "\",";
java << "\"pcwidth\" : \"" << w << "\",";
java << "\"pcheight\" : \"" << h << "\"";
-
java << "}";
visitor.add("projection", java.str());
ostringstream wf;
@@ -1048,14 +985,15 @@ double Proj4Projection::patchDistance(double res) const {
double degree = ((x1-x2) * (x1-x2)) + ((y1-y2) * (y1-y2));
return 1000000000;
-
}
+
void Proj4Projection::collect(MetaDataCollector& collector) const
{
collector["Projection"] = definition_;
collector["Proj4 Definition"] = projection_->definition();
}
+
void Proj4Projection::getNewDefinition(const UserPoint& ll, const UserPoint& ur, string& out) const
{
map<string, string> def;
@@ -1067,26 +1005,17 @@ void Proj4Projection::getNewDefinition(const UserPoint& ll, const UserPoint& ur,
def["subpage_upper_right_latitude"] = tostring(ur.y_);
::toxml(out, def);
out = "{" + out + "}";
-
}
-
void Proj4Projection::setDefinition(const string& json)
{
if (json.empty())
return;
-
-
MagJSon helper;
helper.interpret(json);
XmlNode node = **helper.tree_.firstElement();
-
node.name("");
-
-
set(node);
-
-
}
diff --git a/src/common/magics_api.h b/src/common/magics_api.h
index f9a4487..7cc59bb 100644
--- a/src/common/magics_api.h
+++ b/src/common/magics_api.h
@@ -66,8 +66,8 @@ void mag_epsbar();
void mag_epsshading();
void mag_epswind();
void mag_epswave();
-
-
+void mag_metgraph();
+void mag_metbufr();
void mag_new(const char* page);
diff --git a/src/decoders/CMakeLists.txt b/src/decoders/CMakeLists.txt
index a65859b..b4b796f 100644
--- a/src/decoders/CMakeLists.txt
+++ b/src/decoders/CMakeLists.txt
@@ -53,6 +53,7 @@ XYList.h
shapefil.h
shpopen.c
dbfopen.c
+safileio.c
)
foreach( file ${_decoders_srcs} )
@@ -128,7 +129,7 @@ endif()
set( decoders_srcs ${decoders_srcs} PARENT_SCOPE )
-if ( HAVE_METVIEW )
+if ( metview )
list (APPEND metview_include
decoders/DateTime.h
decoders/GribDecoder.h
diff --git a/src/decoders/EpsBufr.cc b/src/decoders/EpsBufr.cc
index 41606c2..be86995 100644
--- a/src/decoders/EpsBufr.cc
+++ b/src/decoders/EpsBufr.cc
@@ -44,6 +44,8 @@ void EpsBufr::visit(Transformation& transformation)
{
decode();
transformation.setDataMinMaxX((minstep_ - shift_) * 3600, (maxstep_ + 6) * 3600, base_);
+ if ( same(miny_, maxy_) )
+ maxy_ = miny_ +5.;
transformation.setDataMinMaxY(miny_, maxy_);
}
@@ -56,8 +58,8 @@ void EpsBufr::decode()
MvObsSet set(path_.c_str());
MvObsSetIterator filter(set);
- MvLocation ll(latitude_-0.1, longitude_-0.1);
- MvLocation ur(latitude_+0.1, longitude_+0.1);
+ MvLocation ll(latitude_-0.01, longitude_-0.01);
+ MvLocation ur(latitude_+0.01, longitude_+0.01);
filter.setArea(ll, ur);
MvObs obs = filter();
@@ -77,9 +79,9 @@ void EpsBufr::decode()
MvLocation loc = obs.location();
// int subsets = obs.msgSubsetCount();
- float value = obs.value(param_descriptor_ );
- obs.value(5195);
- if ( value == kFortranBufrMissingValue )
+ float value = obs.value(param_descriptor_ );
+
+ if ( value == kBufrMissingValue )
{
obs = filter(NR_returnMsg); // Were going to the next message!
continue;
@@ -93,14 +95,14 @@ void EpsBufr::decode()
float step = obs.valueByOccurrence(i, 4024);
float value = obs.valueByOccurrence(i, param_descriptor_);
- if ( value == kFortranBufrMissingValue ) {
+ if ( value == kBufrMissingValue ) {
obs = filter(); // We going to the next subset!
break;
}
value = (value * param_scaling_factor_ ) + param_offset_factor_;
base_ = DateTime(obs.obsTime().CharValue());
- MagLog::dev() << "date--->" << base_ << endl;
+
if ( accumulated_) {
double total = value;
@@ -114,6 +116,7 @@ void EpsBufr::decode()
if ( maxy_ < value ) maxy_ = value;
curve1[step] = value;
+ MagLog::dev() << param_descriptor_ << " : " << step << "--->" << value << endl;
}
}
if ( param_descriptor_2_) {
@@ -132,7 +135,7 @@ void EpsBufr::decode()
float value = obs2.value( param_descriptor_2_ );
- if ( value == kFortranBufrMissingValue )
+ if ( value == kBufrMissingValue )
{
obs2 = filter(NR_returnMsg); // Were going to the next message!
continue;
@@ -146,7 +149,7 @@ void EpsBufr::decode()
float step = obs2.valueByOccurrence(i, 4024);
obs2.valueByOccurrence(i, 5195);
float value = obs2.valueByOccurrence(i, param_descriptor_2_);
- if ( value == kFortranBufrMissingValue ) {
+ if ( value == kBufrMissingValue ) {
obs2 = filter(); // We going to the next subset!
break;
}
@@ -163,6 +166,7 @@ void EpsBufr::decode()
DateTime date = base_ + Second(step->first * 3600);
(*point)["step"] = step->first * 3600;
(*point)["shift"] = minstep_ - shift_ *3600;
+ MagLog::dev() << step->first << "--->" << step->second << endl;
(*point)["year"] = date.date().year();
(*point)["month"] = date.date().month();
(*point)["day"] = date.date().day();
@@ -195,29 +199,16 @@ PointsHandler& EpsBufr::points()
void EpsBufr::visit(TextVisitor& title)
{
decode();
- if ( EpsBufrAttributes::information_ )
- {
- ostringstream out;
- tm convert = base_;
- locale loc("");
- out.imbue(loc);
- const std::time_put<char>& tfac = use_facet<time_put<char> >(loc);
- string format = "Forecast VT %A %e %B %Y %H UTC";
- tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());
-
- ostringstream line;
- UserPoint position(longitude_, latitude_);
- line << station_name_ << "(" << position.asLatitude() << ", " << position.asLongitude() << ")" << endl;
- title.add(new TextEntry(title_));
- title.add(new TextEntry(line.str()));
- title.add(new TextEntry(out.str()));
- }
- if ( short_title_ ) {
- title.add(new TextEntry(""));
- if ( param_title_.empty() )
- param_title_ = "" + param_descriptor_;
- title.add(new TextEntry(param_title_));
- }
+ title.update("json", "parameter_info", param_title_);
+ ostringstream station;
+ UserPoint position(longitude_, latitude_);
+ station << station_name_ << "(" << position.asLatitude() << ", " << position.asLongitude() << ")" << endl;
+ title.update("json", "station_info", station.str());
+ title.update("json", "date", base_.tostring("ECMWF Forecast from %A %e %B %Y %H UTC"));
+
+
+ return;
+
}
void EpsBufr::visit(MetaDataVisitor&)
diff --git a/src/decoders/GribDecoder.cc b/src/decoders/GribDecoder.cc
index a1c50d4..3f43193 100644
--- a/src/decoders/GribDecoder.cc
+++ b/src/decoders/GribDecoder.cc
@@ -17,7 +17,7 @@
******************************** LICENSE ********************************/
/*! \file GribDecoder.cc
- \brief Implementation of the Template class GribDecoder.
+ \brief Implementation of the class GribDecoder.
Magics Team - ECMWF 2004
@@ -72,9 +72,7 @@ GribDecoder::~GribDecoder()
if ( xComponent_ ) delete xComponent_;
if ( yComponent_ ) delete yComponent_;
if ( handle_ ) {
-
grib_handle_delete (handle_);
-
}
if (nearest_)
@@ -101,8 +99,8 @@ void GribDecoder::set(const GribLoop& loop, int index)
missing_fill_count_ = loop.missing_fill_count_;
wind_mode_ = auto_ptr<WindMode>(loop.wind_mode_->clone());
internalIndex_ = index;
-
}
+
long computeStep( const GribDecoder& grib,const string& key)
{
static map<string, double> stepUnits;
@@ -129,6 +127,7 @@ long computeStep( const GribDecoder& grib,const string& key)
factor = stepunit->second;
return step * factor;
}
+
long GribDecoder::getLong(const string& key, bool warnIfKeyAbsent) const
{
long val;
@@ -151,7 +150,6 @@ long GribDecoder::getLong(const string& key, bool warnIfKeyAbsent) const
string GribDecoder::getstring(const string& key, bool warnIfKeyAbsent, bool cache) const
{
-
if ( cache ) {
map<string, string>::const_iterator sk = sKeys_.find(key);
if ( sk != sKeys_.end() ) {
@@ -178,7 +176,6 @@ string GribDecoder::getstring(const string& key, bool warnIfKeyAbsent, bool cach
string GribDecoder::getString(const string& key, bool warnIfKeyAbsent) const
{
-
if ( Data::dimension_ == 1 )
return getstring(key, warnIfKeyAbsent, false);
@@ -228,7 +225,6 @@ double GribDecoder::getDouble(const string& key, bool warnIfKeyAbsent) const
void GribDecoder::setDouble(const string& key, double val) const
{
-
int err = grib_set_double(handle_, key.c_str(), val);
if ( err )
{
@@ -246,13 +242,11 @@ void GribDecoder::scale(const string& metadata, double& scaling, double& offset)
}
ParamJSon data = ParamJSon(metadata);
-
long table = 128; // hard-coded in case of GRIB 2
long centre = 98; // hard-coded in case of GRIB 2
ParamJSon::iterator pid = data.find("paramId");
-
long id = ( pid != data.end() ) ? tonumber(pid->second) : 0;
try {
@@ -263,12 +257,8 @@ void GribDecoder::scale(const string& metadata, double& scaling, double& offset)
}
catch (...) {
- MagLog::warning()
- << " Can not find information for the parameter [" << id
- << "." << table << "]\n";
+ MagLog::warning() << " Can not find information for the parameter [" << id << "." << table << "]\n";
}
-
-
}
void GribDecoder::read(Matrix **matrix)
@@ -294,13 +284,12 @@ void GribDecoder::read(Matrix **matrix)
MagLog::error() << msg.str() << std::endl;
throw MagicsException(msg.str());
}
-
interpretor_->scaling(*this, matrix);
}
catch (NoFactoryException&)
{
ostringstream msg;
- msg << "Grib Decoder: Representation [" << representation << "] not yet supported";
+ msg << "Grib Decoder - read: Representation [" << representation << "] not supported";
MagLog::error() << msg.str() << endl;
valid_ = false;
throw MagicsException(msg.str());
@@ -327,9 +316,9 @@ void GribDecoder::read(Matrix **matrix, const Transformation& transformation)
}
catch (NoFactoryException&)
{
- MagLog::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::error() << "Grib Decoder - read: Representation [" << representation << "] not supported.\n"<< std::endl;;
valid_ = false;
- throw MagicsException("Grib Decoder: Representation [] not yet supported.");
+ throw MagicsException("Grib Decoder: Representation [] not supported.");
}
}
@@ -368,30 +357,24 @@ void GribDecoder::release()
*point = 0;
}
points_.clear();
-
}
+
void GribDecoder::visit(Transformation& transformation)
{
-
if(transformation.coordinateType() == Transformation::GeoType )
return;
decode();
// Here are in a dump ode .. the coordinates are pixels.
if ( transformation.getAutomaticX() ) {
transformation.setMinMaxX(1, matrix_->columns());
-
}
if ( transformation.getAutomaticY() ) {
transformation.setMinMaxY(1, matrix_->rows());
-
}
-
-
-
}
+
void GribDecoder::decode2D()
{
-
if (xComponent_) return;
Matrix *w1 = 0;
Matrix *w2 = 0;
@@ -407,9 +390,8 @@ void GribDecoder::decode2D()
}
catch (NoFactoryException&)
{
- MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::warning() << "Grib Decoder: Vector cobination of representations [" << representation << "] not supported.\n"<< std::endl;;
valid_ = false;
-
}
readColourComponent();
openFirstComponent();
@@ -418,8 +400,6 @@ void GribDecoder::decode2D()
read(&w2);
Data::dimension_ = ( colourComponent_ ) ? 3 : 2;
-
-
wind_mode_->x(&xComponent_, &yComponent_, w1, w2);
interpretor_->keepOriginal(false);
}
@@ -427,7 +407,6 @@ void GribDecoder::decode2D()
void GribDecoder::customisedPoints(const AutomaticThinningMethod& thinning, const Transformation& transformation, const std::set<string>& request, CustomisedPointsList& points)
{
-
openFirstComponent();
long repres;
grib_get_long(handle_,"dataRepresentationType",&repres);
@@ -439,7 +418,6 @@ void GribDecoder::customisedPoints(const AutomaticThinningMethod& thinning, cons
// Compute the thinning factor...
-
double x1 = 0;
double y1 = 60;
double x2 = 0;
@@ -454,22 +432,15 @@ void GribDecoder::customisedPoints(const AutomaticThinningMethod& thinning, cons
double ystep = ( transformation.getMaxPCY() - transformation.getMinPCY())/ (thinning.y()-1);
int nb = (xstep/res);
-
-
-
xstep = nb * res;
ystep = int(ystep/res) * res;
-
customisedPoints(transformation, points, xstep, ystep, 0);
-
-
-
}
catch (NoFactoryException&)
{
- MagLog::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
- throw MagicsException("Grib Decoder: Representation [] not yet supported.");
+ MagLog::error() << "Grib Decoder - customisedPoints: Representation [" << representation << "] not supported.\n"<< std::endl;;
+ throw MagicsException("Grib Decoder: Representation [] not supported.");
}
}
@@ -499,7 +470,6 @@ bool compare(const pair<double, double>& pt1, const pair<double, double>& pt2)
{
if ( pt1.second != pt2.second)
return false;
-
return pt1.second < pt2.second;
}
@@ -509,15 +479,9 @@ bool compare(const pair<double, double>& pt1, const pair<double, double>& pt2)
void GribDecoder::newPoint(const Transformation& transformation, double lat, double lon, double uc, double vc, double cc, vector<CustomisedPoint*>& points, double grid)
{
-
-
-
std::stack<UserPoint> duplicates;
UserPoint geo(lon, lat);
-
-
-
transformation.wraparound(geo, duplicates);
while (duplicates.empty() == false) {
UserPoint pt = duplicates.top();
@@ -554,10 +518,8 @@ void GribDecoder::newPoint(const Transformation& transformation, double lat, dou
points.push_back(point);
if ( cc != -9999 ) {
point->insert(make_pair("colour_component", cc));
-
}
duplicates.pop();
-
}
}
@@ -565,7 +527,6 @@ void GribDecoder::newPoint(const Transformation& transformation, double lat, dou
struct Compare
{
-
template< typename T1, typename T2 >
bool operator()( T1 const& t1, T2 const& t2 ) const
{
@@ -594,9 +555,6 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
vector<pair<double, double> >::iterator pos = positions.begin();
out.reserve(positions.size());
-
-
-
int i = 0;
for ( pos = positions.begin(); pos != positions.end(); ++pos) {
double offset = 0.;
@@ -604,8 +562,6 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
double lon = pos->first;
double lat = pos->second;
-
-
i++;
while ( lon < minlon ) {
lon += 360;
@@ -616,7 +572,6 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
offset += 360.;
}
-
Index index = interpretor_->nearest(lat, lon);
//cout << "[" << lat << ", " << lon << "]-->[" << index.index_ << ", " << index.lat_ << ", " << index.lon_ << "]" << endl;
if ( index.index_ != -1 && !index.used_ ) {
@@ -624,7 +579,6 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
double u = uComponent(index.index_);
double v = vComponent(index.index_);
-
if ( u != missing && v != missing) {
CustomisedPoint *add = new CustomisedPoint(index.lon_+offset, index.lat_, "");
pair<double, double> value = (*wind_mode_)(u, v);
@@ -644,7 +598,6 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
}
}
-
else { // no thinning !
// get all the points of the index!
@@ -663,16 +616,14 @@ void GribDecoder::customisedPoints(const Transformation& transformation, Customi
out.push_back(add);
}
}
-
}
}
}
-
}
+
void GribDecoder::customisedPoints(const BasicThinningMethod& thinning, const Transformation& transformation, const std::set<string>& needs, CustomisedPointsList& points)
{
-
openFirstComponent();
long repres;
grib_get_long(handle_,"dataRepresentationType",&repres);
@@ -683,7 +634,6 @@ void GribDecoder::customisedPoints(const BasicThinningMethod& thinning, const Tr
}
// Compute the thinning factor...
-
double gap = 0;
// find the middle point :
UserPoint ll = transformation.reference();
@@ -691,26 +641,23 @@ void GribDecoder::customisedPoints(const BasicThinningMethod& thinning, const Tr
ll.y_ = ll.y_ + interpretor_->XResolution(*this);
PaperPoint xy2 = transformation(ll);
-
-
gap = xy1.distance(xy2);
if ( thinning.factor() == 1 ) {
gap = 0;
-
}
thinning_debug_ = ( needs.find("debug") != needs.end() );
customisedPoints(transformation, points,
gap * thinning.factor(),
gap * thinning.factor(), gap);
-
}
catch (NoFactoryException&)
{
- MagLog::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
- throw MagicsException("Grib Decoder: Representation [] not yet supported.");
+ MagLog::error() << "Grib Decoder- customisedPoints: Representation [" << representation << "] not supported.\n"<< std::endl;;
+ throw MagicsException("Grib Decoder: Representation [] not supported.");
}
}
+
void GribDecoder::decode2D(const Transformation&)
{
Data::dimension_ = 2;
@@ -718,8 +665,6 @@ void GribDecoder::decode2D(const Transformation&)
Matrix *w1 = 0;
Matrix *w2 = 0;
-
-
const string representation = getString("typeOfGrid");
try {
@@ -727,16 +672,14 @@ void GribDecoder::decode2D(const Transformation&)
interpretor_ = SimpleObjectMaker<GribInterpretor>::create(representation);
}
readColourComponent();
-
openFirstComponent();
read(&w1);
openSecondComponent();
read(&w2);
-
}
catch (NoFactoryException&)
{
- MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::warning() << "Grib Decoder: Vector representation [" << representation << "] not supported.\n"<< std::endl;;
}
wind_mode_->x(&xComponent_, &yComponent_, w1, w2);
}
@@ -744,13 +687,10 @@ void GribDecoder::decode2D(const Transformation&)
void GribDecoder::openFirstComponent()
{
-
-
grib_field_position_ = position_1_;
-
component1_ = open(component1_);
-
}
+
grib_handle* GribEntryDecoder::open(grib_handle* handle, bool) {
if ( !handle_ ) {
return handle_;
@@ -760,17 +700,16 @@ grib_handle* GribEntryDecoder::open(grib_handle* handle, bool) {
void GribDecoder::openSecondComponent()
{
-
grib_field_position_ = position_2_;
component2_ = open(component2_);
-
}
+
void GribDecoder::openThirdComponent()
{
grib_field_position_ = colour_position_;
colour_ = open(colour_, false);
-
}
+
void GribDecoder::readColourComponent()
{
grib_field_position_ = colour_position_;
@@ -778,14 +717,10 @@ void GribDecoder::readColourComponent()
colour_ = open(colour_, false);
read(&colourComponent_);
}
-
catch (...) {
colourComponent_ = 0;
valid_ = true;
}
-
-
-
}
grib_handle* GribDecoder::open(grib_handle* grib, bool sendmsg)
@@ -852,6 +787,8 @@ bool GribDecoder::id(const string& id, const string& where) const
}
return magCompare(id_, id);
}
+
+
bool GribDecoder::verify(const string& val) const
{
// we except a string with the following format "key1=val,key2=val2,...,keyn=valn"
@@ -902,17 +839,15 @@ void GribDecoder::decodePoints()
}
catch (NoFactoryException&)
{
- MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not supported.\n"<< std::endl;;
scaling =1 ; offset =0;
}
grib_iterator* iter = grib_iterator_new(handle_, flags, &error);
-
-
if (!iter)
{
- MagLog::error() << "Grib Iterator not yet supported on this kind of grib\n";
+ MagLog::error() << "Grib Iterator not yet supported on this kind of GRIB\n";
MagLog::broadcast();
throw MagicsException("Grib Iterator not yet supported.");
}
@@ -937,7 +872,7 @@ void GribDecoder::decodePoints()
grib_iterator* iter2 = grib_iterator_new(handle_, flags, &error);
if (!iter1 || !iter2)
{
- MagLog::error() << "Grib Iterator not yet supported on this kind of grib\n";
+ MagLog::error() << "Grib Iterator not yet supported on this kind of GRIB\n";
throw MagicsException("Grib Iterator not yet supported.");
}
@@ -956,8 +891,6 @@ void GribDecoder::decodePoints()
-
-
GribLoop::~GribLoop()
{
for (vector<GribDecoder*>::const_iterator g = gribs_.begin(); g != gribs_.end(); ++g)
@@ -998,13 +931,11 @@ void GribLoop::setToFirst()
{
currentDim_ = dimension_.begin();
currentPos_ = dim_.begin();
-
}
bool GribLoop::hasMore()
{
-
if (file_ == 0 ) {
file_ = fopen(path_.c_str(),"r");
if (!file_) {
@@ -1013,15 +944,11 @@ bool GribLoop::hasMore()
}
}
-
-
// Now we have to find the right Entry!!!
-
if ( currentDim_ == dimension_.end() )
return false;
-
if ( *currentDim_ == 1 ) {
if ( dim_.empty() ) {
// case 1 dimension= 1 and loop on all the fields!
@@ -1191,9 +1118,7 @@ public:
const long step = computeStep(grib_, "stepRange");
full = full + (step * -1);
}
-
return full.tostring(format);
-
}
string startDate(const XmlNode& node)
@@ -1254,11 +1179,8 @@ public:
full = full + step;
return full.tostring(format);
-
}
-
-
void visit(const XmlNode& node)
{
if ( magCompare(node.name(), "grib_info") )
@@ -1402,11 +1324,8 @@ void GribDecoder::nearestGridpoints(double *inlats, double *inlons, double *outl
retainGribNearestHandle = true; // more efficient
}
-
nearHandle = nearest_point_handle(retainGribNearestHandle);
-
-
for (int i=0; i < nb; i++)
{
if (nearHandle)
@@ -1434,14 +1353,13 @@ void GribDecoder::nearestGridpoints(double *inlats, double *inlons, double *outl
if (!retainGribNearestHandle && nearHandle) // was this a temporary handle?
grib_nearest_delete(nearHandle);
-
}
+
void GribDecoder::visit(ValuesCollector& points)
{
field_ = open(field_);
-
points.setCollected(true);
int nb = points.size();
@@ -1469,7 +1387,7 @@ void GribDecoder::visit(ValuesCollector& points)
}
catch (NoFactoryException&)
{
- MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not supported.\n"<< std::endl;;
scaling =1 ; offset =0;
}
@@ -1539,6 +1457,7 @@ void GribDecoder::visit(MagnifierCollector& magnifier)
points.advance();
}
}
+
const DateDescription& GribDecoder::timeStamp()
{
vector<string> need;
@@ -1551,13 +1470,10 @@ const DateDescription& GribDecoder::timeStamp()
for ( vector<string>::const_iterator t = need.begin(); t != need.end(); ++t )
tag1.decode(*t);
-
timeStamp_ = DateDescription(helper.get("grib", "valid-date"), index_, internalIndex_);
dataLevel_ = LevelDescription::level(helper.get("grib", "typeOfLevel"), tonumber(helper.get("grib", "level")), index_, internalIndex_);
-
return timeStamp_;
-
}
const LevelDescription& GribDecoder::level()
@@ -1576,7 +1492,6 @@ void GribDecoder::visit(MetaDataVisitor& meta)
need.push_back("<grib_info key='base-date' format='%Y-%m-%d %H:%M:00'/>");
need.push_back("<grib_info key='valid-date' format='%Y-%m-%d %H:%M:00'/>");
-
TagHandler helper;
GribTag tag1(*this, helper);
for ( vector<string>::const_iterator t = need.begin(); t != need.end(); ++t )
@@ -1683,15 +1598,53 @@ void GribDecoder::visit(MetaDataCollector& step)
}
catch (NoFactoryException&)
{
- MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n"<< std::endl;;
+ MagLog::warning() << "Grib Decoder: Representation [" << representation << "] not supported.\n"<< std::endl;;
information_[key->first]="N/A";
}
}
+ else if(key->first == "isOctahedral")
+ {
+ // Octahedral reduced Gaussian grids:
+ // - only reduced Gaussian grids can be octahedral
+ // - the isOctahedral key only works properly with global fields
+ string representation = getString("typeOfGrid");
+ if (representation == "reduced_gg")
+ {
+ if (getLong("global") == 1)
+ {
+ information_["isOctahedral"] = (getLong("isOctahedral") == 1) ? "yes" : "no";
+ }
+ }
+ }
+/*
+ // alternative code, for if we want to display in one line the Gaussian
+ // number and the octahedral flag.
+ else if(key->first == "GaussianNumber")
+ {
+ // e.g. N200 ('classic' reduced Gaussian) or O1280 ('octahedral' reduced Gaussian)
+ // - but only use prefix of N or O on global fields, because, as explained below,
+ // we don't know whether a sub-areas field is classic or octahedral
+ // Octahedral reduced Gaussian grids:
+ // - only reduced Gaussian grids can be octahedral
+ // - the isOctahedral key only works properly with global fields
+ string representation = getString("typeOfGrid");
+ if (representation == "reduced_gg")
+ {
+ long N = getLong("N");
+ string prefix("");
+ if (getLong("global") == 1)
+ {
+ prefix = (getLong("isOctahedral") == 1) ? "O" : "N";
+ }
+ information_["GaussianNumber"] = prefix + tostring(N);
+ }
+ }*/
}
+
//If key is found in information_ we copy it
- else
+ if(information_.find(key->first) != information_.end())
{
key->second=information_[key->first];
}
@@ -1873,8 +1826,8 @@ void GribDecoder::decodeRaster(const Transformation& transformation)
catch (NoFactoryException&)
{
- MagLog::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n";
- throw MagicsException("Grib Decoder: Representation [] not yet supported.");
+ MagLog::error() << "Grib Decoder: Raster representation [" << representation << "] not supported.\n";
+ throw MagicsException("Grib Decoder: Raster representation [] not supported.");
}
}
@@ -2345,7 +2298,6 @@ public:
title.back() += sat->second;
else
title.back() += "satellite identifier " + tostring(ident);
-
}
};
@@ -2416,7 +2368,6 @@ public:
~GribExpverHandler() {}
void operator()(TitleField& field, vector<string>& title, const GribDecoder& grib)
{
-
if ( !grib.getExpver() ) return;
ostringstream out;
string expver = grib.getString("mars.experimentVersionNumber");
@@ -2449,7 +2400,6 @@ public:
// title.add(out.str());
title.back() += "epsnumber?";
-
}
};
@@ -2484,6 +2434,7 @@ public:
*/
}
};
+
double GribDecoder::uComponent(int index)
{
return xValues_[index];
@@ -2493,6 +2444,7 @@ double GribDecoder::vComponent(int index)
{
return yValues_[index];
}
+
void GribDecoder::uComponent()
{
if ( xValues_ )
@@ -2505,6 +2457,7 @@ void GribDecoder::uComponent()
xValues_ = new double[nb];
grib_get_double_array(handle, "values", xValues_, &nb);
}
+
void GribDecoder::vComponent()
{
if ( yValues_ )
diff --git a/src/decoders/GribRegularInterpretor.cc b/src/decoders/GribRegularInterpretor.cc
index ebdcf51..f2ec7bb 100644
--- a/src/decoders/GribRegularInterpretor.cc
+++ b/src/decoders/GribRegularInterpretor.cc
@@ -167,14 +167,12 @@ void GribInterpretor::new_index(const GribDecoder& grib)
continue;
}
-
if ( minlat_ > lat) minlat_ = lat;
if ( maxlat_ < lat) maxlat_ = lat;
if ( minlon_ > lon) minlon_ = lon;
if ( maxlon_ < lon) maxlon_ = lon;
- if ( lon < 0 ) lon +=360.;
- ilat = floor((lat+90)/indexStep_);
+ ilat = floor((lat+90)/indexStep_);
ilon = floor(lon/indexStep_);
@@ -205,14 +203,10 @@ Index GribInterpretor::nearest(double ulat, double ulon)
return index;
if ( ulat > maxlat_ )
return index;
- bool out = true;
- if ( ulon >= minlon_ && ulon <= maxlon_)
- out = false;
- if ( ulon-360 >= minlon_ && ulon-360 <= maxlon_)
- out = false;
-
- if ( out )
- return index;
+ if ( ulon < minlon_ )
+ return index;
+ if ( ulon > maxlon_ )
+ return index;
if ( ulat == -1000. || ulon == -1000.)
@@ -223,7 +217,6 @@ Index GribInterpretor::nearest(double ulat, double ulon)
-
int ilat = floor((ulat+90)/indexStep_);
int ilon = floor(ulon/indexStep_);
int lat1, lat2;
@@ -975,12 +968,66 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
long global = grib.getLong("global");
// We have to determine if the field is global!
- if (global) {
- east = west + 360.;
- }
+ if (global) {
+ east = west + 360.;
+ }
vector<vector<double> > rows;
+
for ( int i = 0; i < nblat; i++) {
+ long numPts = 0;
+ long indexFirst, indexLast;
+ int globalPointsInThisRow = pl[i];
+ double dx = 360./pl[i];
+
+
+ // find which points are in this row; a sub-area of a reduced Gaussian grid
+ // contains a subset of the points from the global grid, with the points
+ // in exactly the same positions as the corresponding ones in the
+ // global grid. The GRIB_API function grib_get_reduced_row() does not
+ // produce the correct result when given a global field, so we need
+ // to make that a separate case.
+
+ double add = 0;
+
+ if (global) {
+ numPts = globalPointsInThisRow;
+ indexFirst = 0;
+ indexLast = numPts-1;
+
+ }
+ else {
+ grib_get_reduced_row(globalPointsInThisRow, west, east,
+ &numPts, &indexFirst,&indexLast);
+ add = 2*dx;
+ }
+
+ rows.push_back(vector<double>());
+
+ int n = indexFirst;
+
+
+ // the index of the first point is not necessarily smaller than the index
+ // of the second point, depending on the sub-area.
+ // we need to check whether the last index is the last point; however,
+ // grib_get_reduced_row() seems to sometimes return a numPoints which is 1
+ // greater than the number of global points in the row so we need a double
+ // check.
+ bool lastSubAreaIndexIsNotLastGlobalIndex = (indexLast != globalPointsInThisRow-1) &&
+ (indexLast != globalPointsInThisRow);
+
+ while (n != indexLast+1){
+ double thisLon = n*dx;
+ if ( thisLon > east +add) thisLon -= 360.;
+
+ rows.back().push_back(thisLon);
+ n++;
+ if (n == globalPointsInThisRow && lastSubAreaIndexIsNotLastGlobalIndex ) // wrap around?
+ n = 0;
+ }
+
+/*
+ // this is the previous version of the code (before using grib_get_reduced_row())
// compute find first grid point ..
double dx = 360./pl[i];
rows.push_back(vector<double>());
@@ -994,6 +1041,7 @@ void GribReducedGaussianInterpretor::interpretAsMatrix(const GribDecoder& grib,
}
}
+*/ // This line is suspicious! but I keep it ... Jsut in case!
std::sort(rows.back().begin(), rows.back().end());
diff --git a/src/decoders/InputMatrixInterpretor.cc b/src/decoders/InputMatrixInterpretor.cc
index 977f9d8..b885e24 100644
--- a/src/decoders/InputMatrixInterpretor.cc
+++ b/src/decoders/InputMatrixInterpretor.cc
@@ -106,7 +106,7 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
for (int i = 0; i < nblon; i++) {
in->columnsAxis().push_back(lon);
- lon += longitude_step_;
+ lon = longitude_ +( i * longitude_step_);
}
int nblat = in->rows();
@@ -115,7 +115,7 @@ Matrix* InputMatrixRegularInterpretor::geoInterpret(Matrix* in, const InputMatri
for (int i = 0; i < nblat; i++) {
in->rowsAxis().push_back(lat);
MagLog::dev()<< in->rowsAxis().back() << endl;
- lat += latitude_step_;
+ lat = latitude_ + (i*latitude_step_);
}
in->setMapsAxis();
in->missing(std::numeric_limits<double>::max());
diff --git a/src/decoders/ShapeDecoder.cc b/src/decoders/ShapeDecoder.cc
index db572ea..d96895c 100644
--- a/src/decoders/ShapeDecoder.cc
+++ b/src/decoders/ShapeDecoder.cc
@@ -33,10 +33,6 @@
#include "shapefil.h"
#include "Polyline.h"
-#include <boost/geometry/geometry.hpp>
-#include <boost/geometry/algorithms/make.hpp>
-
-// #define BOOST_VERSION 104700
ShapeDecoder::ShapeDecoder() :holes_(false)
{
@@ -53,7 +49,6 @@ ShapeDecoder::~ShapeDecoder()
delete *line;
*line = 0;
}
-
}
@@ -73,7 +68,7 @@ void ShapeDecoder::decode(const Transformation& transformation)
decode(transformation, no, all);
}
-/*! \brief Method to read llocation and names of state capitals
+/*! \brief Method to read location and names of state capitals
\todo When we can handle Unicode we should change "nameascii" back to "name"
@@ -129,7 +124,6 @@ void ShapeDecoder::customisedPoints(const std::set<string>&, CustomisedPointsLis
if ( !add )
continue;
-
psShape = SHPReadObject( hSHP, i );
string name = ( index != attributes.end() ) ? DBFReadStringAttribute(hDBF, i, index->second) : "?";
@@ -161,8 +155,6 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
{
if ( !this->empty() ) return;
try {
- SHPHandle hSHP;
- DBFHandle hDBF;
char szTitle[12];
double minx, miny, maxx, maxy;
transformation.smallestBoundingBox(minx, miny, maxx, maxy);
@@ -175,8 +167,8 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
string shp = path_ + ".shp";
string dbf = path_ + ".dbf";
- hSHP = SHPOpen( shp.c_str(), "rb" );
- hDBF = DBFOpen( dbf.c_str(), "rb" );
+ const SHPHandle hSHP = SHPOpen( shp.c_str(), "rb" );
+ const DBFHandle hDBF = DBFOpen( dbf.c_str(), "rb" );
if ( !hSHP || !hDBF ) {
MagLog::error() << "Can not open Shapefile " << shp << endl;
@@ -252,7 +244,6 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
rightlist = back();
}
-// bool hole = false;
for( j = 0, iPart = 1; j < psShape->nVertices; j++ )
{
if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j )
@@ -274,7 +265,6 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
}
if (in) {
inlist->push_back(new UserPoint(psShape->padfX[j], psShape->padfY[j], i));
-
}
if (left) {
leftlist->push_back(new UserPoint(psShape->padfX[j]-360., psShape->padfY[j], i));
@@ -284,7 +274,6 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
}
}
}
-
}
SHPDestroyObject(psShape);
@@ -299,20 +288,18 @@ void ShapeDecoder::decode(const Transformation& transformation, const string& fi
}
-
-
-
+/*! \brief Decoder to read land and lakes
+ \sa CoastPlotting::decode(const Layout& parent )
+*/
void ShapeDecoder::decode(vector<Polyline>& data, const Transformation& transformation)
{
Timer timer("Read Shape file ", "read shape file" + path_);
-
Polyline& geobox = transformation.getUserBoundingBox();
Polyline& box = transformation.getPCBoundingBox();
try {
SHPHandle hSHP;
int nShapeType, nEntities, i, iPart;
- bool hole=false;
double adfMinBound[4], adfMaxBound[4];
string shp = path_ + ".shp";
string dbf = path_ + ".dbf";
@@ -324,10 +311,11 @@ void ShapeDecoder::decode(vector<Polyline>& data, const Transformation& transfor
data.clear();
SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
- double south = transformation.getMinY();
- double north = transformation.getMaxY();
- double west = transformation.getMinX();
- double east = transformation.getMaxX();
+ const double south = transformation.getMinY();
+ const double north = transformation.getMaxY();
+ const double west = transformation.getMinX();
+ const double east = transformation.getMaxX();
+ //cout << " ShapeDecoder - BBox s: "<<south<<" n: " <<north<<" / w: "<<west<<" e: "<< east<< endl;
double shift = 0;
@@ -338,32 +326,23 @@ void ShapeDecoder::decode(vector<Polyline>& data, const Transformation& transfor
if ( ( east - west ) > 360. )
shift = 0;
-
-
- SHPObject *psShape = 0;
+ SHPObject *psShape = 0;
int nb = 0;
for( i = 0; i < nEntities; i++ )
{
- int j;
-
-
+ int j;
SHPDestroyObject(psShape);
-
-
psShape = SHPReadObject( hSHP, i );
bool in = true;
bool left = false;
bool right = false;
-
-
-
if ( psShape->dfYMax <= south ) continue;
if ( psShape->dfYMin >= north ) continue;
- if ( psShape->dfXMax + shift <= west) in = false;
- if ( psShape->dfXMin + shift >= east) in = false;
- if ( psShape->dfXMax + shift -360 > transformation.getMinX() && !same(psShape->dfXMax-360, transformation.getMinX())) {
+ if ( psShape->dfXMax + shift <= west) in = false;
+ if ( psShape->dfXMin + shift >= east) in = false;
+ if ( psShape->dfXMax + shift - 360 > transformation.getMinX() && !same(psShape->dfXMax-360, transformation.getMinX())) {
left = true;
}
if ( psShape->dfXMin + shift +360 < transformation.getMaxX() && !same(psShape->dfXMin+360, transformation.getMaxX() ) ) {
@@ -389,84 +368,48 @@ void ShapeDecoder::decode(vector<Polyline>& data, const Transformation& transfor
}
left = false;
- right=false;
+ right= false;
- for( j = 0, iPart = 1, hole = false; j < psShape->nVertices ; j++ )
+ for( j = 0, iPart = 1; j < psShape->nVertices ; j++ )
{
- bool patch = false;
if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j )
{
iPart++;
- hole=true;
- // We create a new hole!
-
- if (poly)
- poly->newHole();
- if (polyleft)
- polyleft->newHole();
- if (polyright)
- polyright->newHole();
+ if (poly) poly->newHole();
+ if (polyleft) polyleft->newHole();
+ if (polyright) polyright->newHole();
}
- else {
- double x = psShape->padfX[j];
- x += shift;
- double y = psShape->padfY[j];
-
- if ( iPart==1 ) {
- if ( poly ) {
- poly->push_back(PaperPoint(x, y));
- }
-
- if ( polyleft ) {
+ double x = psShape->padfX[j];
+ x += shift;
+ const double y = psShape->padfY[j];
- polyleft->push_back(PaperPoint(x-360, y));
- }
- if ( polyright ) {
- polyright->push_back(PaperPoint(x+360, y));
- }
-
- }
- else {
- if ( in ) {
- poly->push_back_hole(PaperPoint(x, y));
- }
-
- if ( polyleft ) {
-
- polyleft->push_back_hole(PaperPoint(x-360, y));
-
- }
- if ( polyright ) {
- polyright->push_back_hole(PaperPoint(x+360, y));
- }
- }
+ if ( iPart==1 ) {
+ if ( poly ) poly->push_back(PaperPoint(x, y));
+ if ( polyleft ) polyleft->push_back( PaperPoint(x-360, y));
+ if ( polyright ) polyright->push_back(PaperPoint(x+360, y));
+ }
+ else {
+ if ( poly ) poly->push_back_hole(PaperPoint(x, y));
+ if ( polyleft ) polyleft->push_back_hole( PaperPoint(x-360, y));
+ if ( polyright ) polyright->push_back_hole(PaperPoint(x+360, y));
}
-
-
-
}
-
-
- /// first we clip
- for (vector<Polyline*>::iterator poly = polys.begin(); poly != polys.end(); ++poly ) {
- (*poly)->sanityCheck();
- vector<Polyline> clipped;
- geobox.intersect(**poly, clipped);
+ /// first we clip
+ for (vector<Polyline*>::iterator poly = polys.begin(); poly != polys.end(); ++poly ) {
+ //(*poly)->sanityCheck();
+ vector<Polyline> clipped;
+ geobox.intersect(**poly, clipped);
// then we reproject!
- for (vector<Polyline>::iterator clip = clipped.begin(); clip != clipped.end(); ++clip ) {
- clip->reproject(transformation);
- clip->sanityCheck();
- box.intersect(*clip, data);
- }
-
- }
-
-
-
-
+ for (vector<Polyline>::iterator clip = clipped.begin(); clip != clipped.end(); ++clip ) {
+ clip->reproject(transformation);
+ //clip->sanityCheck();
+ box.intersect(*clip, data);
+ //data.push_back(*clip);
+ }
+ }
}
SHPDestroyObject(psShape);
SHPClose( hSHP );
@@ -476,5 +419,3 @@ void ShapeDecoder::decode(vector<Polyline>& data, const Transformation& transfor
MagLog::error() << "Can not open Shapefile " << path_ << endl;
}
}
-
-
diff --git a/src/decoders/dbfopen.c b/src/decoders/dbfopen.c
index 43b25ac..fbe7b06 100644
--- a/src/decoders/dbfopen.c
+++ b/src/decoders/dbfopen.c
@@ -1,5 +1,5 @@
/******************************************************************************
- * $Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $
+ * $Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $
*
* Project: Shapelib
* Purpose: Implementation of .dbf access API documented in dbf_api.html.
@@ -34,157 +34,128 @@
******************************************************************************
*
* $Log: dbfopen.c,v $
- * Revision 1.48 2003/03/10 14:51:27 warmerda
- * DBFWrite* calls now return FALSE if they have to truncate
+ * Revision 1.89 2011-07-24 05:59:25 fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
*
- * Revision 1.47 2002/11/20 03:32:22 warmerda
- * Ensure field name in DBFGetFieldIndex() is properly terminated.
+ * Revision 1.88 2011-05-13 17:35:17 fwarmerdam
+ * added DBFReorderFields() and DBFAlterFields() functions (from Even)
*
- * Revision 1.46 2002/10/09 13:10:21 warmerda
- * Added check that width is positive.
+ * Revision 1.87 2011-05-07 22:41:02 fwarmerdam
+ * ensure pending record is flushed when adding a native field (GDAL #4073)
*
- * Revision 1.45 2002/09/29 00:00:08 warmerda
- * added FTLogical and logical attribute read/write calls
+ * Revision 1.86 2011-04-17 15:15:29 fwarmerdam
+ * Removed unused variable.
*
- * Revision 1.44 2002/05/07 13:46:11 warmerda
- * Added DBFWriteAttributeDirectly().
+ * Revision 1.85 2010-12-06 16:09:34 fwarmerdam
+ * fix buffer read overrun fetching code page (bug 2276)
*
- * Revision 1.43 2002/02/13 19:39:21 warmerda
- * Fix casting issues in DBFCloneEmpty().
+ * Revision 1.84 2009-10-29 19:59:48 fwarmerdam
+ * avoid crash on truncated header (gdal #3093)
*
- * Revision 1.42 2002/01/15 14:36:07 warmerda
- * updated email address
+ * Revision 1.83 2008/11/12 14:28:15 fwarmerdam
+ * DBFCreateField() now works on files with records
*
- * Revision 1.41 2002/01/15 14:31:49 warmerda
- * compute rather than copying nHeaderLength in DBFCloneEmpty()
+ * Revision 1.82 2008/11/11 17:47:09 fwarmerdam
+ * added DBFDeleteField() function
*
- * Revision 1.40 2002/01/09 04:32:35 warmerda
- * fixed to read correct amount of header
+ * Revision 1.81 2008/01/03 17:48:13 bram
+ * in DBFCreate, use default code page LDID/87 (= 0x57, ANSI)
+ * instead of LDID/3. This seems to be the same as what ESRI
+ * would be doing by default.
*
- * Revision 1.39 2001/12/11 22:41:03 warmerda
- * improve io related error checking when reading header
+ * Revision 1.80 2007/12/30 14:36:39 fwarmerdam
+ * avoid syntax issue with last comment.
*
- * Revision 1.38 2001/11/28 16:07:31 warmerda
- * Cleanup to avoid compiler warnings as suggested by Richard Hash.
+ * Revision 1.79 2007/12/30 14:35:48 fwarmerdam
+ * Avoid char* / unsigned char* warnings.
*
- * Revision 1.37 2001/07/04 05:18:09 warmerda
- * do last fix properly
+ * Revision 1.78 2007/12/18 18:28:07 bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
*
- * Revision 1.36 2001/07/04 05:16:09 warmerda
- * fixed fieldname comparison in DBFGetFieldIndex
+ * Revision 1.77 2007/12/15 20:25:21 bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function. This is
+ * either the number from the LDID header field ("LDID/<number>") or as the
+ * content of an accompanying .CPG file. When creating a DBF file, the code can
+ * be set using DBFCreateEx.
*
- * Revision 1.35 2001/06/22 02:10:06 warmerda
- * fixed NULL shape support with help from Jim Matthews
+ * Revision 1.76 2007/12/12 22:21:32 bram
+ * DBFClose: check for NULL psDBF handle before trying to close it.
*
- * Revision 1.33 2001/05/31 19:20:13 warmerda
- * added DBFGetFieldIndex()
+ * Revision 1.75 2007/12/06 13:58:19 fwarmerdam
+ * make sure file offset calculations are done in as SAOffset
*
- * Revision 1.32 2001/05/31 18:15:40 warmerda
- * Added support for NULL fields in DBF files
+ * Revision 1.74 2007/12/06 07:00:25 fwarmerdam
+ * dbfopen now using SAHooks for fileio
*
- * Revision 1.31 2001/05/23 13:36:52 warmerda
- * added use of SHPAPI_CALL
+ * Revision 1.73 2007/09/03 19:48:11 fwarmerdam
+ * move DBFReadAttribute() static dDoubleField into dbfinfo
*
- * Revision 1.30 2000/12/05 14:43:38 warmerda
- * DBReadAttribute() white space trimming bug fix
+ * Revision 1.72 2007/09/03 19:34:06 fwarmerdam
+ * Avoid use of static tuple buffer in DBFReadTuple()
*
- * Revision 1.29 2000/10/05 14:36:44 warmerda
- * fix bug with writing very wide numeric fields
+ * Revision 1.71 2006/06/22 14:37:18 fwarmerdam
+ * avoid memory leak if dbfopen fread fails
*
- * Revision 1.28 2000/09/25 14:18:07 warmerda
- * Added some casts of strlen() return result to fix warnings on some
- * systems, as submitted by Daniel.
+ * Revision 1.70 2006/06/17 17:47:05 fwarmerdam
+ * use calloc() for dbfinfo in DBFCreate
*
- * Revision 1.27 2000/09/25 14:15:51 warmerda
- * added DBFGetNativeFieldType()
+ * Revision 1.69 2006/06/17 15:34:32 fwarmerdam
+ * disallow creating fields wider than 255
*
- * Revision 1.26 2000/07/07 13:39:45 warmerda
- * removed unused variables, and added system include files
+ * Revision 1.68 2006/06/17 15:12:40 fwarmerdam
+ * Fixed C++ style comments.
*
- * Revision 1.25 2000/05/29 18:19:13 warmerda
- * avoid use of uchar, and adding casting fix
+ * Revision 1.67 2006/06/17 00:24:53 fwarmerdam
+ * Don't treat non-zero decimals values as high order byte for length
+ * for strings. It causes serious corruption for some files.
+ * http://bugzilla.remotesensing.org/show_bug.cgi?id=1202
*
- * Revision 1.24 2000/05/23 13:38:27 warmerda
- * Added error checks on return results of fread() and fseek().
+ * Revision 1.66 2006/03/29 18:26:20 fwarmerdam
+ * fixed bug with size of pachfieldtype in dbfcloneempty
*
- * Revision 1.23 2000/05/23 13:25:49 warmerda
- * Avoid crashing if field or record are out of range in dbfread*attribute().
+ * Revision 1.65 2006/02/15 01:14:30 fwarmerdam
+ * added DBFAddNativeFieldType
*
- * Revision 1.22 1999/12/15 13:47:24 warmerda
- * Added stdlib.h to ensure that atof() is prototyped.
+ * Revision 1.64 2006/02/09 00:29:04 fwarmerdam
+ * Changed to put spaces into string fields that are NULL as
+ * per http://bugzilla.maptools.org/show_bug.cgi?id=316.
*
- * Revision 1.21 1999/12/13 17:25:46 warmerda
- * Added support for upper case .DBF extention.
+ * Revision 1.63 2006/01/25 15:35:43 fwarmerdam
+ * check success on DBFFlushRecord
*
- * Revision 1.20 1999/11/30 16:32:11 warmerda
- * Use atof() instead of sscanf().
+ * Revision 1.62 2006/01/10 16:28:03 fwarmerdam
+ * Fixed typo in CPLError.
*
- * Revision 1.19 1999/11/05 14:12:04 warmerda
- * updated license terms
+ * Revision 1.61 2006/01/10 16:26:29 fwarmerdam
+ * Push loading record buffer into DBFLoadRecord.
+ * Implement CPL error reporting if USE_CPL defined.
*
- * Revision 1.18 1999/07/27 00:53:28 warmerda
- * ensure that whole old field value clear on write of string
+ * Revision 1.60 2006/01/05 01:27:27 fwarmerdam
+ * added dbf deletion mark/fetch
*
- * Revision 1.1 1999/07/05 18:58:07 warmerda
- * New
+ * Revision 1.59 2005/03/14 15:20:28 fwarmerdam
+ * Fixed last change.
*
- * Revision 1.17 1999/06/11 19:14:12 warmerda
- * Fixed some memory leaks.
+ * Revision 1.58 2005/03/14 15:18:54 fwarmerdam
+ * Treat very wide fields with no decimals as double. This is
+ * more than 32bit integer fields.
*
- * Revision 1.16 1999/06/11 19:04:11 warmerda
- * Remoted some unused variables.
+ * Revision 1.57 2005/02/10 20:16:54 fwarmerdam
+ * Make the pszStringField buffer for DBFReadAttribute() static char [256]
+ * as per bug 306.
*
- * Revision 1.15 1999/05/11 03:19:28 warmerda
- * added new Tuple api, and improved extension handling - add from candrsn
+ * Revision 1.56 2005/02/10 20:07:56 fwarmerdam
+ * Fixed bug 305 in DBFCloneEmpty() - header length problem.
*
- * Revision 1.14 1999/05/04 15:01:48 warmerda
- * Added 'F' support.
+ * Revision 1.55 2004/09/26 20:23:46 fwarmerdam
+ * avoid warnings with rcsid and signed/unsigned stuff
*
- * Revision 1.13 1999/03/23 17:38:59 warmerda
- * DBFAddField() now actually does return the new field number, or -1 if
- * it fails.
- *
- * Revision 1.12 1999/03/06 02:54:46 warmerda
- * Added logic to convert shapefile name to dbf filename in DBFOpen()
- * for convenience.
- *
- * Revision 1.11 1998/12/31 15:30:34 warmerda
- * Improved the interchangability of numeric and string attributes. Add
- * white space trimming option for attributes.
- *
- * Revision 1.10 1998/12/03 16:36:44 warmerda
- * Use r+b instead of rb+ for binary access.
- *
- * Revision 1.9 1998/12/03 15:34:23 warmerda
- * Updated copyright message.
- *
- * Revision 1.8 1997/12/04 15:40:15 warmerda
- * Added newline character after field definitions.
- *
- * Revision 1.7 1997/03/06 14:02:10 warmerda
- * Ensure bUpdated is initialized.
- *
- * Revision 1.6 1996/02/12 04:54:41 warmerda
- * Ensure that DBFWriteAttribute() returns TRUE if it succeeds.
- *
- * Revision 1.5 1995/10/21 03:15:12 warmerda
- * Changed to use binary file access, and ensure that the
- * field name field is zero filled, and limited to 10 chars.
- *
- * Revision 1.4 1995/08/24 18:10:42 warmerda
- * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such
- * as on the Sun.
- *
- * Revision 1.3 1995/08/04 03:15:16 warmerda
- * Fixed up header.
- *
- * Revision 1.2 1995/08/04 03:14:43 warmerda
- * Added header.
+ * Revision 1.54 2004/09/15 16:26:10 fwarmerdam
+ * Treat all blank numeric fields as null too.
*/
-static char rcsid[] =
- "$Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $";
-
#include "shapefil.h"
#include <math.h>
@@ -192,14 +163,13 @@ static char rcsid[] =
#include <ctype.h>
#include <string.h>
+SHP_CVSID("$Id: dbfopen.c,v 1.89 2011-07-24 05:59:25 fwarmerdam Exp $")
+
#ifndef FALSE
# define FALSE 0
# define TRUE 1
#endif
-static int nStringFieldLen = 0;
-static char * pszStringField = NULL;
-
/************************************************************************/
/* SfRealloc() */
/* */
@@ -244,21 +214,29 @@ static void DBFWriteHeader(DBFHandle psDBF)
abyHeader[0] = 0x03; /* memo field? - just copying */
- /* date updated on close, record count preset at zero */
+ /* write out a dummy date */
+ abyHeader[1] = 95; /* YY */
+ abyHeader[2] = 7; /* MM */
+ abyHeader[3] = 26; /* DD */
- abyHeader[8] = psDBF->nHeaderLength % 256;
- abyHeader[9] = psDBF->nHeaderLength / 256;
+ /* record count preset at zero */
+
+ abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
+ abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
- abyHeader[10] = psDBF->nRecordLength % 256;
- abyHeader[11] = psDBF->nRecordLength / 256;
+ abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
+ abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
+
+ abyHeader[29] = (unsigned char) (psDBF->iLanguageDriver);
/* -------------------------------------------------------------------- */
/* Write the initial 32 byte file header, and all the field */
/* descriptions. */
/* -------------------------------------------------------------------- */
- fseek( psDBF->fp, 0, 0 );
- fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
- fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
+ psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+ psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
+ psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields,
+ psDBF->fp );
/* -------------------------------------------------------------------- */
/* Write out the newline character if there is room for it. */
@@ -268,7 +246,7 @@ static void DBFWriteHeader(DBFHandle psDBF)
char cNewline;
cNewline = 0x0d;
- fwrite( &cNewline, 1, 1, psDBF->fp );
+ psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
}
}
@@ -278,21 +256,104 @@ static void DBFWriteHeader(DBFHandle psDBF)
/* Write out the current record if there is one. */
/************************************************************************/
-static void DBFFlushRecord( DBFHandle psDBF )
+static int DBFFlushRecord( DBFHandle psDBF )
{
- int nRecordOffset;
+ SAOffset nRecordOffset;
if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
{
psDBF->bCurrentRecordModified = FALSE;
- nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord
- + psDBF->nHeaderLength;
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) psDBF->nCurrentRecord
+ + psDBF->nHeaderLength;
+
+ if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0
+ || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord,
+ psDBF->nRecordLength,
+ 1, psDBF->fp ) != 1 )
+ {
+ char szMessage[128];
+ sprintf( szMessage, "Failure writing DBF record %d.",
+ psDBF->nCurrentRecord );
+ psDBF->sHooks.Error( szMessage );
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/************************************************************************/
+/* DBFLoadRecord() */
+/************************************************************************/
+
+static int DBFLoadRecord( DBFHandle psDBF, int iRecord )
+
+{
+ if( psDBF->nCurrentRecord != iRecord )
+ {
+ SAOffset nRecordOffset;
+
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
+
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
+ {
+ char szMessage[128];
+ sprintf( szMessage, "fseek(%ld) failed on DBF file.\n",
+ (long) nRecordOffset );
+ psDBF->sHooks.Error( szMessage );
+ return FALSE;
+ }
+
+ if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord,
+ psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
+ {
+ char szMessage[128];
+ sprintf( szMessage, "fread(%d) failed on DBF file.\n",
+ psDBF->nRecordLength );
+ psDBF->sHooks.Error( szMessage );
+ return FALSE;
+ }
- fseek( psDBF->fp, nRecordOffset, 0 );
- fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ psDBF->nCurrentRecord = iRecord;
}
+
+ return TRUE;
+}
+
+/************************************************************************/
+/* DBFUpdateHeader() */
+/************************************************************************/
+
+void SHPAPI_CALL
+DBFUpdateHeader( DBFHandle psDBF )
+
+{
+ unsigned char abyFileHeader[32];
+
+ if( psDBF->bNoHeader )
+ DBFWriteHeader( psDBF );
+
+ DBFFlushRecord( psDBF );
+
+ psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+ psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
+
+ abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
+ abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
+ abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
+ abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
+
+ psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
+ psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
+
+ psDBF->sHooks.FFlush( psDBF->fp );
}
/************************************************************************/
@@ -305,10 +366,29 @@ DBFHandle SHPAPI_CALL
DBFOpen( const char * pszFilename, const char * pszAccess )
{
+ SAHooks sHooks;
+
+ SASetupDefaultHooks( &sHooks );
+
+ return DBFOpenLL( pszFilename, pszAccess, &sHooks );
+}
+
+/************************************************************************/
+/* DBFOpen() */
+/* */
+/* Open a .dbf file. */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFOpenLL( const char * pszFilename, const char * pszAccess, SAHooks *psHooks )
+
+{
DBFHandle psDBF;
- unsigned char *pabyBuf;
- int nFields, nHeadLen, nRecLen, iField, i;
+ SAFile pfCPG;
+ unsigned char *pabyBuf;
+ int nFields, nHeadLen, iField, i;
char *pszBasename, *pszFullname;
+ int nBufSize = 500;
/* -------------------------------------------------------------------- */
/* We only allow the access strings "rb" and "r+". */
@@ -342,20 +422,30 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
sprintf( pszFullname, "%s.dbf", pszBasename );
psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
- psDBF->fp = fopen( pszFullname, pszAccess );
+ psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
+ memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
if( psDBF->fp == NULL )
{
sprintf( pszFullname, "%s.DBF", pszBasename );
- psDBF->fp = fopen(pszFullname, pszAccess );
+ psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
}
-
+
+ sprintf( pszFullname, "%s.cpg", pszBasename );
+ pfCPG = psHooks->FOpen( pszFullname, "r" );
+ if( pfCPG == NULL )
+ {
+ sprintf( pszFullname, "%s.CPG", pszBasename );
+ pfCPG = psHooks->FOpen( pszFullname, "r" );
+ }
+
free( pszBasename );
free( pszFullname );
if( psDBF->fp == NULL )
{
free( psDBF );
+ if( pfCPG ) psHooks->FClose( pfCPG );
return( NULL );
}
@@ -366,10 +456,11 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
/* -------------------------------------------------------------------- */
/* Read Table Header info */
/* -------------------------------------------------------------------- */
- pabyBuf = (unsigned char *) malloc(500);
- if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
+ pabyBuf = (unsigned char *) malloc(nBufSize);
+ if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
{
- fclose( psDBF->fp );
+ psDBF->sHooks.FClose( psDBF->fp );
+ if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
free( pabyBuf );
free( psDBF );
return NULL;
@@ -379,11 +470,47 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
- psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
-
+ psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256;
+ psDBF->iLanguageDriver = pabyBuf[29];
+
+ if (nHeadLen < 32)
+ {
+ psDBF->sHooks.FClose( psDBF->fp );
+ if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
+ free( pabyBuf );
+ free( psDBF );
+ return NULL;
+ }
+
psDBF->nFields = nFields = (nHeadLen - 32) / 32;
- psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
+ psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength);
+
+/* -------------------------------------------------------------------- */
+/* Figure out the code page from the LDID and CPG */
+/* -------------------------------------------------------------------- */
+
+ psDBF->pszCodePage = NULL;
+ if( pfCPG )
+ {
+ size_t n;
+ memset( pabyBuf, 0, nBufSize);
+ psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
+ n = strcspn( (char *) pabyBuf, "\n\r" );
+ if( n > 0 )
+ {
+ pabyBuf[n] = '\0';
+ psDBF->pszCodePage = (char *) malloc(n + 1);
+ memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
+ }
+ psDBF->sHooks.FClose( pfCPG );
+ }
+ if( psDBF->pszCodePage == NULL && pabyBuf[29] != 0 )
+ {
+ sprintf( (char *) pabyBuf, "LDID/%d", psDBF->iLanguageDriver );
+ psDBF->pszCodePage = (char *) malloc(strlen((char*)pabyBuf) + 1);
+ strcpy( psDBF->pszCodePage, (char *) pabyBuf );
+ }
/* -------------------------------------------------------------------- */
/* Read in Field Definitions */
@@ -392,11 +519,12 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
psDBF->pszHeader = (char *) pabyBuf;
- fseek( psDBF->fp, 32, 0 );
- if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
+ psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
+ if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
{
- fclose( psDBF->fp );
+ psDBF->sHooks.FClose( psDBF->fp );
free( pabyBuf );
+ free( psDBF->pszCurrentRecord );
free( psDBF );
return NULL;
}
@@ -419,8 +547,17 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
}
else
{
+ psDBF->panFieldSize[iField] = pabyFInfo[16];
+ psDBF->panFieldDecimals[iField] = 0;
+
+/*
+** The following seemed to be used sometimes to handle files with long
+** string fields, but in other cases (such as bug 1202) the decimals field
+** just seems to indicate some sort of preferred formatting, not very
+** wide fields. So I have disabled this code. FrankW.
psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
psDBF->panFieldDecimals[iField] = 0;
+*/
}
psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
@@ -441,6 +578,9 @@ DBFOpen( const char * pszFilename, const char * pszAccess )
void SHPAPI_CALL
DBFClose(DBFHandle psDBF)
{
+ if( psDBF == NULL )
+ return;
+
/* -------------------------------------------------------------------- */
/* Write out header if not already written. */
/* -------------------------------------------------------------------- */
@@ -454,29 +594,12 @@ DBFClose(DBFHandle psDBF)
/* write access. */
/* -------------------------------------------------------------------- */
if( psDBF->bUpdated )
- {
- unsigned char abyFileHeader[32];
-
- fseek( psDBF->fp, 0, 0 );
- fread( abyFileHeader, 32, 1, psDBF->fp );
-
- abyFileHeader[1] = 95; /* YY */
- abyFileHeader[2] = 7; /* MM */
- abyFileHeader[3] = 26; /* DD */
-
- abyFileHeader[4] = psDBF->nRecords % 256;
- abyFileHeader[5] = (psDBF->nRecords/256) % 256;
- abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256;
- abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256;
-
- fseek( psDBF->fp, 0, 0 );
- fwrite( abyFileHeader, 32, 1, psDBF->fp );
- }
+ DBFUpdateHeader( psDBF );
/* -------------------------------------------------------------------- */
/* Close, and free resources. */
/* -------------------------------------------------------------------- */
- fclose( psDBF->fp );
+ psDBF->sHooks.FClose( psDBF->fp );
if( psDBF->panFieldOffset != NULL )
{
@@ -486,17 +609,44 @@ DBFClose(DBFHandle psDBF)
free( psDBF->pachFieldType );
}
+ if( psDBF->pszWorkField != NULL )
+ free( psDBF->pszWorkField );
+
free( psDBF->pszHeader );
free( psDBF->pszCurrentRecord );
+ free( psDBF->pszCodePage );
free( psDBF );
+}
- if( pszStringField != NULL )
- {
- free( pszStringField );
- pszStringField = NULL;
- nStringFieldLen = 0;
- }
+/************************************************************************/
+/* DBFCreate() */
+/* */
+/* Create a new .dbf file with default code page LDID/87 (0x57) */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreate( const char * pszFilename )
+
+{
+ return DBFCreateEx( pszFilename, "LDID/87" ); // 0x57
+}
+
+/************************************************************************/
+/* DBFCreateEx() */
+/* */
+/* Create a new .dbf file. */
+/************************************************************************/
+
+DBFHandle SHPAPI_CALL
+DBFCreateEx( const char * pszFilename, const char* pszCodePage )
+
+{
+ SAHooks sHooks;
+
+ SASetupDefaultHooks( &sHooks );
+
+ return DBFCreateLL( pszFilename, pszCodePage , &sHooks );
}
/************************************************************************/
@@ -506,13 +656,14 @@ DBFClose(DBFHandle psDBF)
/************************************************************************/
DBFHandle SHPAPI_CALL
-DBFCreate( const char * pszFilename )
+DBFCreateLL( const char * pszFilename, const char * pszCodePage, SAHooks *psHooks )
{
DBFHandle psDBF;
- FILE *fp;
+ SAFile fp;
char *pszFullname, *pszBasename;
- int i;
+ int i, ldid = -1;
+ char chZero = '\0';
/* -------------------------------------------------------------------- */
/* Compute the base (layer) name. If there is any extension */
@@ -530,29 +681,52 @@ DBFCreate( const char * pszFilename )
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
sprintf( pszFullname, "%s.dbf", pszBasename );
- free( pszBasename );
/* -------------------------------------------------------------------- */
/* Create the file. */
/* -------------------------------------------------------------------- */
- fp = fopen( pszFullname, "wb" );
+ fp = psHooks->FOpen( pszFullname, "wb" );
if( fp == NULL )
return( NULL );
+
+ psHooks->FWrite( &chZero, 1, 1, fp );
+ psHooks->FClose( fp );
- fputc( 0, fp );
- fclose( fp );
-
- fp = fopen( pszFullname, "rb+" );
+ fp = psHooks->FOpen( pszFullname, "rb+" );
if( fp == NULL )
return( NULL );
+
+ sprintf( pszFullname, "%s.cpg", pszBasename );
+ if( pszCodePage != NULL )
+ {
+ if( strncmp( pszCodePage, "LDID/", 5 ) == 0 )
+ {
+ ldid = atoi( pszCodePage + 5 );
+ if( ldid > 255 )
+ ldid = -1; // don't use 0 to indicate out of range as LDID/0 is a valid one
+ }
+ if( ldid < 0 )
+ {
+ SAFile fpCPG = psHooks->FOpen( pszFullname, "w" );
+ psHooks->FWrite( (char*) pszCodePage, strlen(pszCodePage), 1, fpCPG );
+ psHooks->FClose( fpCPG );
+ }
+ }
+ if( pszCodePage == NULL || ldid >= 0 )
+ {
+ psHooks->Remove( pszFullname );
+ }
+
+ free( pszBasename );
free( pszFullname );
/* -------------------------------------------------------------------- */
/* Create the info structure. */
/* -------------------------------------------------------------------- */
- psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
+ psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo));
+ memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
psDBF->fp = fp;
psDBF->nRecords = 0;
psDBF->nFields = 0;
@@ -571,14 +745,21 @@ DBFCreate( const char * pszFilename )
psDBF->bNoHeader = TRUE;
+ psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
+ psDBF->pszCodePage = NULL;
+ if( pszCodePage )
+ {
+ psDBF->pszCodePage = (char * ) malloc( strlen(pszCodePage) + 1 );
+ strcpy( psDBF->pszCodePage, pszCodePage );
+ }
+
return( psDBF );
}
/************************************************************************/
/* DBFAddField() */
/* */
-/* Add a field to a newly created .dbf file before any records */
-/* are written. */
+/* Add a field to a newly created .dbf or to an existing one */
/************************************************************************/
int SHPAPI_CALL
@@ -586,24 +767,74 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
DBFFieldType eType, int nWidth, int nDecimals )
{
+ char chNativeType = 'C';
+
+ if( eType == FTLogical )
+ chNativeType = 'L';
+ else if( eType == FTString )
+ chNativeType = 'C';
+ else
+ chNativeType = 'N';
+
+ return DBFAddNativeFieldType( psDBF, pszFieldName, chNativeType,
+ nWidth, nDecimals );
+}
+
+/************************************************************************/
+/* DBFGetNullCharacter() */
+/************************************************************************/
+
+static char DBFGetNullCharacter(char chType)
+{
+ switch (chType)
+ {
+ case 'N':
+ case 'F':
+ return '*';
+ case 'D':
+ return '0';
+ case 'L':
+ return '?';
+ default:
+ return ' ';
+ }
+}
+
+/************************************************************************/
+/* DBFAddField() */
+/* */
+/* Add a field to a newly created .dbf file before any records */
+/* are written. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName,
+ char chType, int nWidth, int nDecimals )
+
+{
char *pszFInfo;
int i;
+ int nOldRecordLength, nOldHeaderLength;
+ char *pszRecord;
+ char chFieldFill;
+ SAOffset nRecordOffset;
+
+ /* make sure that everything is written in .dbf */
+ if( !DBFFlushRecord( psDBF ) )
+ return -1;
/* -------------------------------------------------------------------- */
/* Do some checking to ensure we can add records to this file. */
/* -------------------------------------------------------------------- */
- if( psDBF->nRecords > 0 )
- return( -1 );
-
- if( !psDBF->bNoHeader )
- return( -1 );
-
- if( eType != FTDouble && nDecimals != 0 )
- return( -1 );
-
if( nWidth < 1 )
return -1;
+ if( nWidth > 255 )
+ nWidth = 255;
+
+ nOldRecordLength = psDBF->nRecordLength;
+ nOldHeaderLength = psDBF->nHeaderLength;
+
/* -------------------------------------------------------------------- */
/* SfRealloc all the arrays larger to hold the additional field */
/* information. */
@@ -611,16 +842,16 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
psDBF->nFields++;
psDBF->panFieldOffset = (int *)
- SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+ SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
psDBF->panFieldSize = (int *)
- SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+ SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
psDBF->panFieldDecimals = (int *)
- SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+ SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
psDBF->pachFieldType = (char *)
- SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+ SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
/* -------------------------------------------------------------------- */
/* Assign the new field information fields. */
@@ -629,13 +860,7 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
psDBF->nRecordLength += nWidth;
psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
-
- if( eType == FTLogical )
- psDBF->pachFieldType[psDBF->nFields-1] = 'L';
- else if( eType == FTString )
- psDBF->pachFieldType[psDBF->nFields-1] = 'C';
- else
- psDBF->pachFieldType[psDBF->nFields-1] = 'N';
+ psDBF->pachFieldType[psDBF->nFields-1] = chType;
/* -------------------------------------------------------------------- */
/* Extend the required header information. */
@@ -657,22 +882,63 @@ DBFAddField(DBFHandle psDBF, const char * pszFieldName,
pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
- if( eType == FTString )
+ if( chType == 'C' )
{
- pszFInfo[16] = nWidth % 256;
- pszFInfo[17] = nWidth / 256;
+ pszFInfo[16] = (unsigned char) (nWidth % 256);
+ pszFInfo[17] = (unsigned char) (nWidth / 256);
}
else
{
- pszFInfo[16] = nWidth;
- pszFInfo[17] = nDecimals;
+ pszFInfo[16] = (unsigned char) nWidth;
+ pszFInfo[17] = (unsigned char) nDecimals;
}
/* -------------------------------------------------------------------- */
/* Make the current record buffer appropriately larger. */
/* -------------------------------------------------------------------- */
psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
- psDBF->nRecordLength);
+ psDBF->nRecordLength);
+
+ /* we're done if dealing with new .dbf */
+ if( psDBF->bNoHeader )
+ return( psDBF->nFields - 1 );
+
+/* -------------------------------------------------------------------- */
+/* For existing .dbf file, shift records */
+/* -------------------------------------------------------------------- */
+
+ /* alloc record */
+ pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+
+ chFieldFill = DBFGetNullCharacter(chType);
+
+ for (i = psDBF->nRecords-1; i >= 0; --i)
+ {
+ nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ /* set new field's value to NULL */
+ memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
+
+ nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength;
+
+ /* move record to the new place*/
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ }
+
+ /* free record */
+ free(pszRecord);
+
+ /* force update of header with new header, record length and new field */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = FALSE;
return( psDBF->nFields-1 );
}
@@ -687,12 +953,9 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
char chReqType )
{
- int nRecordOffset;
unsigned char *pabyRec;
void *pReturnField = NULL;
- static double dDoubleField;
-
/* -------------------------------------------------------------------- */
/* Verify selection. */
/* -------------------------------------------------------------------- */
@@ -705,59 +968,42 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
/* -------------------------------------------------------------------- */
/* Have we read the record? */
/* -------------------------------------------------------------------- */
- if( psDBF->nCurrentRecord != hEntity )
- {
- DBFFlushRecord( psDBF );
-
- nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
- if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
- {
- fprintf( stderr, "fseek(%d) failed on DBF file.\n",
- nRecordOffset );
- return NULL;
- }
-
- if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
- 1, psDBF->fp ) != 1 )
- {
- fprintf( stderr, "fread(%d) failed on DBF file.\n",
- psDBF->nRecordLength );
- return NULL;
- }
-
- psDBF->nCurrentRecord = hEntity;
- }
+ if( !DBFLoadRecord( psDBF, hEntity ) )
+ return NULL;
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
/* -------------------------------------------------------------------- */
-/* Ensure our field buffer is large enough to hold this buffer. */
+/* Ensure we have room to extract the target field. */
/* -------------------------------------------------------------------- */
- if( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
+ if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength )
{
- nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
- pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
+ psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
+ if( psDBF->pszWorkField == NULL )
+ psDBF->pszWorkField = (char *) malloc(psDBF->nWorkFieldLength);
+ else
+ psDBF->pszWorkField = (char *) realloc(psDBF->pszWorkField,
+ psDBF->nWorkFieldLength);
}
/* -------------------------------------------------------------------- */
/* Extract the requested field. */
/* -------------------------------------------------------------------- */
- strncpy( pszStringField,
+ strncpy( psDBF->pszWorkField,
((const char *) pabyRec) + psDBF->panFieldOffset[iField],
psDBF->panFieldSize[iField] );
- pszStringField[psDBF->panFieldSize[iField]] = '\0';
+ psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0';
- pReturnField = pszStringField;
+ pReturnField = psDBF->pszWorkField;
/* -------------------------------------------------------------------- */
/* Decode the field. */
/* -------------------------------------------------------------------- */
if( chReqType == 'N' )
{
- dDoubleField = atof(pszStringField);
+ psDBF->dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
- pReturnField = &dDoubleField;
+ pReturnField = &(psDBF->dfDoubleField);
}
/* -------------------------------------------------------------------- */
@@ -768,7 +1014,7 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
{
char *pchSrc, *pchDst;
- pchDst = pchSrc = pszStringField;
+ pchDst = pchSrc = psDBF->pszWorkField;
while( *pchSrc == ' ' )
pchSrc++;
@@ -776,7 +1022,7 @@ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField,
*(pchDst++) = *(pchSrc++);
*pchDst = '\0';
- while( pchDst != pszStringField && *(--pchDst) == ' ' )
+ while( pchDst != psDBF->pszWorkField && *(--pchDst) == ' ' )
*pchDst = '\0';
}
#endif
@@ -850,35 +1096,45 @@ DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
}
+
/************************************************************************/
-/* DBFIsAttributeNULL() */
-/* */
-/* Return TRUE if value for field is NULL. */
+/* DBFIsValueNULL() */
/* */
-/* Contributed by Jim Matthews. */
+/* Return TRUE if the passed string is NULL. */
/************************************************************************/
-int SHPAPI_CALL
-DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
-
+static int DBFIsValueNULL( char chType, const char* pszValue )
{
- const char *pszValue;
+ int i;
- pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+ if( pszValue == NULL )
+ return TRUE;
- switch(psDBF->pachFieldType[iField])
+ switch(chType)
{
case 'N':
case 'F':
- /* NULL numeric fields have value "****************" */
- return pszValue[0] == '*';
+ /*
+ ** We accept all asterisks or all blanks as NULL
+ ** though according to the spec I think it should be all
+ ** asterisks.
+ */
+ if( pszValue[0] == '*' )
+ return TRUE;
+
+ for( i = 0; pszValue[i] != '\0'; i++ )
+ {
+ if( pszValue[i] != ' ' )
+ return FALSE;
+ }
+ return TRUE;
case 'D':
/* NULL date fields have value "00000000" */
return strncmp(pszValue,"00000000",8) == 0;
case 'L':
- /* NULL boolean fields have value "?" */
+ /* NULL boolean fields have value "?" */
return pszValue[0] == '?';
default:
@@ -888,20 +1144,42 @@ DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
}
/************************************************************************/
-/* DBFGetFieldCount() */
+/* DBFIsAttributeNULL() */
/* */
-/* Return the number of fields in this table. */
+/* Return TRUE if value for field is NULL. */
+/* */
+/* Contributed by Jim Matthews. */
/************************************************************************/
int SHPAPI_CALL
-DBFGetFieldCount( DBFHandle psDBF )
+DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
{
- return( psDBF->nFields );
+ const char *pszValue;
+
+ pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
+
+ if( pszValue == NULL )
+ return TRUE;
+
+ return DBFIsValueNULL( psDBF->pachFieldType[iField], pszValue );
}
/************************************************************************/
-/* DBFGetRecordCount() */
+/* DBFGetFieldCount() */
+/* */
+/* Return the number of fields in this table. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFGetFieldCount( DBFHandle psDBF )
+
+{
+ return( psDBF->nFields );
+}
+
+/************************************************************************/
+/* DBFGetRecordCount() */
/* */
/* Return the number of records in this table. */
/************************************************************************/
@@ -947,10 +1225,10 @@ DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName,
return( FTLogical);
else if( psDBF->pachFieldType[iField] == 'N'
- || psDBF->pachFieldType[iField] == 'F'
- || psDBF->pachFieldType[iField] == 'D' )
+ || psDBF->pachFieldType[iField] == 'F' )
{
- if( psDBF->panFieldDecimals[iField] > 0 )
+ if( psDBF->panFieldDecimals[iField] > 0
+ || psDBF->panFieldSize[iField] > 10 )
return( FTDouble );
else
return( FTInteger );
@@ -971,7 +1249,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
void * pValue )
{
- int nRecordOffset, i, j, nRetResult = TRUE;
+ int i, j, nRetResult = TRUE;
unsigned char *pabyRec;
char szSField[400], szFormat[20];
@@ -989,7 +1267,8 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
/* -------------------------------------------------------------------- */
if( hEntity == psDBF->nRecords )
{
- DBFFlushRecord( psDBF );
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
psDBF->nRecords++;
for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1002,17 +1281,8 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
/* Is this an existing record, but different than the last one */
/* we accessed? */
/* -------------------------------------------------------------------- */
- if( psDBF->nCurrentRecord != hEntity )
- {
- DBFFlushRecord( psDBF );
-
- nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
- fseek( psDBF->fp, nRecordOffset, 0 );
- fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
- psDBF->nCurrentRecord = hEntity;
- }
+ if( !DBFLoadRecord( psDBF, hEntity ) )
+ return FALSE;
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
@@ -1026,33 +1296,9 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
/* -------------------------------------------------------------------- */
if( pValue == NULL )
{
- switch(psDBF->pachFieldType[iField])
- {
- case 'N':
- case 'F':
- /* NULL numeric fields have value "****************" */
- memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*',
- psDBF->panFieldSize[iField] );
- break;
-
- case 'D':
- /* NULL date fields have value "00000000" */
- memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0',
- psDBF->panFieldSize[iField] );
- break;
-
- case 'L':
- /* NULL boolean fields have value "?" */
- memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?',
- psDBF->panFieldSize[iField] );
- break;
-
- default:
- /* empty string fields are considered NULL */
- memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0',
- psDBF->panFieldSize[iField] );
- break;
- }
+ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]),
+ DBFGetNullCharacter(psDBF->pachFieldType[iField]),
+ psDBF->panFieldSize[iField] );
return TRUE;
}
@@ -1068,7 +1314,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
{
int nWidth = psDBF->panFieldSize[iField];
- if( sizeof(szSField)-2 < nWidth )
+ if( (int) sizeof(szSField)-2 < nWidth )
nWidth = sizeof(szSField)-2;
sprintf( szFormat, "%%%dd", nWidth );
@@ -1086,7 +1332,7 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
{
int nWidth = psDBF->panFieldSize[iField];
- if( sizeof(szSField)-2 < nWidth )
+ if( (int) sizeof(szSField)-2 < nWidth )
nWidth = sizeof(szSField)-2;
sprintf( szFormat, "%%%d.%df",
@@ -1137,11 +1383,12 @@ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
/* as is to the field position in the record. */
/************************************************************************/
-int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
+int SHPAPI_CALL
+DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
void * pValue )
{
- int nRecordOffset, i, j;
+ int i, j;
unsigned char *pabyRec;
/* -------------------------------------------------------------------- */
@@ -1158,7 +1405,8 @@ int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
/* -------------------------------------------------------------------- */
if( hEntity == psDBF->nRecords )
{
- DBFFlushRecord( psDBF );
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
psDBF->nRecords++;
for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1171,17 +1419,8 @@ int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
/* Is this an existing record, but different than the last one */
/* we accessed? */
/* -------------------------------------------------------------------- */
- if( psDBF->nCurrentRecord != hEntity )
- {
- DBFFlushRecord( psDBF );
-
- nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
- fseek( psDBF->fp, nRecordOffset, 0 );
- fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
- psDBF->nCurrentRecord = hEntity;
- }
+ if( !DBFLoadRecord( psDBF, hEntity ) )
+ return FALSE;
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
@@ -1287,7 +1526,7 @@ int SHPAPI_CALL
DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
{
- int nRecordOffset, i;
+ int i;
unsigned char *pabyRec;
/* -------------------------------------------------------------------- */
@@ -1304,7 +1543,8 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
/* -------------------------------------------------------------------- */
if( hEntity == psDBF->nRecords )
{
- DBFFlushRecord( psDBF );
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
psDBF->nRecords++;
for( i = 0; i < psDBF->nRecordLength; i++ )
@@ -1317,17 +1557,8 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
/* Is this an existing record, but different than the last one */
/* we accessed? */
/* -------------------------------------------------------------------- */
- if( psDBF->nCurrentRecord != hEntity )
- {
- DBFFlushRecord( psDBF );
-
- nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
- fseek( psDBF->fp, nRecordOffset, 0 );
- fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
- psDBF->nCurrentRecord = hEntity;
- }
+ if( !DBFLoadRecord( psDBF, hEntity ) )
+ return FALSE;
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
@@ -1340,49 +1571,23 @@ DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
}
/************************************************************************/
-/* DBFReadTuple() */
+/* DBFReadTuple() */
/* */
-/* Read one of the attribute fields of a record. */
+/* Read a complete record. Note that the result is only valid */
+/* till the next record read for any reason. */
/************************************************************************/
const char SHPAPI_CALL1(*)
DBFReadTuple(DBFHandle psDBF, int hEntity )
{
- int nRecordOffset;
- unsigned char *pabyRec;
- static char *pReturnTuple = NULL;
-
- static int nTupleLen = 0;
-
-/* -------------------------------------------------------------------- */
-/* Have we read the record? */
-/* -------------------------------------------------------------------- */
if( hEntity < 0 || hEntity >= psDBF->nRecords )
return( NULL );
- if( psDBF->nCurrentRecord != hEntity )
- {
- DBFFlushRecord( psDBF );
-
- nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
-
- fseek( psDBF->fp, nRecordOffset, 0 );
- fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
-
- psDBF->nCurrentRecord = hEntity;
- }
-
- pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
+ if( !DBFLoadRecord( psDBF, hEntity ) )
+ return NULL;
- if ( nTupleLen < psDBF->nRecordLength) {
- nTupleLen = psDBF->nRecordLength;
- pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
- }
-
- memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
-
- return( pReturnTuple );
+ return (const char *) psDBF->pszCurrentRecord;
}
/************************************************************************/
@@ -1396,24 +1601,24 @@ DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
{
DBFHandle newDBF;
- newDBF = DBFCreate ( pszFilename );
+ newDBF = DBFCreateEx ( pszFilename, psDBF->pszCodePage );
if ( newDBF == NULL ) return ( NULL );
- newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
- memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
-
newDBF->nFields = psDBF->nFields;
newDBF->nRecordLength = psDBF->nRecordLength;
- newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
+ newDBF->nHeaderLength = psDBF->nHeaderLength;
+ newDBF->pszHeader = (char *) malloc ( newDBF->nHeaderLength );
+ memcpy ( newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength );
+
newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields );
memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
- newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
- memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
+ newDBF->pachFieldType = (char *) malloc ( sizeof(char) * psDBF->nFields );
+ memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(char)*psDBF->nFields );
newDBF->bNoHeader = TRUE;
newDBF->bUpdated = TRUE;
@@ -1460,7 +1665,7 @@ static void str_to_upper (char *string)
while (++i < len)
if (isalpha(string[i]) && islower(string[i]))
- string[i] = toupper ((int)string[i]);
+ string[i] = (char) toupper ((int)string[i]);
}
/************************************************************************/
@@ -1493,3 +1698,524 @@ DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
}
return(-1);
}
+
+/************************************************************************/
+/* DBFIsRecordDeleted() */
+/* */
+/* Returns TRUE if the indicated record is deleted, otherwise */
+/* it returns FALSE. */
+/************************************************************************/
+
+int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape )
+
+{
+/* -------------------------------------------------------------------- */
+/* Verify selection. */
+/* -------------------------------------------------------------------- */
+ if( iShape < 0 || iShape >= psDBF->nRecords )
+ return TRUE;
+
+/* -------------------------------------------------------------------- */
+/* Have we read the record? */
+/* -------------------------------------------------------------------- */
+ if( !DBFLoadRecord( psDBF, iShape ) )
+ return FALSE;
+
+/* -------------------------------------------------------------------- */
+/* '*' means deleted. */
+/* -------------------------------------------------------------------- */
+ return psDBF->pszCurrentRecord[0] == '*';
+}
+
+/************************************************************************/
+/* DBFMarkRecordDeleted() */
+/************************************************************************/
+
+int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape,
+ int bIsDeleted )
+
+{
+ char chNewFlag;
+
+/* -------------------------------------------------------------------- */
+/* Verify selection. */
+/* -------------------------------------------------------------------- */
+ if( iShape < 0 || iShape >= psDBF->nRecords )
+ return FALSE;
+
+/* -------------------------------------------------------------------- */
+/* Is this an existing record, but different than the last one */
+/* we accessed? */
+/* -------------------------------------------------------------------- */
+ if( !DBFLoadRecord( psDBF, iShape ) )
+ return FALSE;
+
+/* -------------------------------------------------------------------- */
+/* Assign value, marking record as dirty if it changes. */
+/* -------------------------------------------------------------------- */
+ if( bIsDeleted )
+ chNewFlag = '*';
+ else
+ chNewFlag = ' ';
+
+ if( psDBF->pszCurrentRecord[0] != chNewFlag )
+ {
+ psDBF->bCurrentRecordModified = TRUE;
+ psDBF->bUpdated = TRUE;
+ psDBF->pszCurrentRecord[0] = chNewFlag;
+ }
+
+ return TRUE;
+}
+
+/************************************************************************/
+/* DBFGetCodePage */
+/************************************************************************/
+
+const char SHPAPI_CALL1(*)
+DBFGetCodePage(DBFHandle psDBF )
+{
+ if( psDBF == NULL )
+ return NULL;
+ return psDBF->pszCodePage;
+}
+
+/************************************************************************/
+/* DBFDeleteField() */
+/* */
+/* Remove a field from a .dbf file */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFDeleteField(DBFHandle psDBF, int iField)
+{
+ int nOldRecordLength, nOldHeaderLength;
+ int nDeletedFieldOffset, nDeletedFieldSize;
+ SAOffset nRecordOffset;
+ char* pszRecord;
+ int i, iRecord;
+
+ if (iField < 0 || iField >= psDBF->nFields)
+ return FALSE;
+
+ /* make sure that everything is written in .dbf */
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
+
+ /* get information about field to be deleted */
+ nOldRecordLength = psDBF->nRecordLength;
+ nOldHeaderLength = psDBF->nHeaderLength;
+ nDeletedFieldOffset = psDBF->panFieldOffset[iField];
+ nDeletedFieldSize = psDBF->panFieldSize[iField];
+
+ /* update fields info */
+ for (i = iField + 1; i < psDBF->nFields; i++)
+ {
+ psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
+ psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
+ psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
+ psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
+ }
+
+ /* resize fields arrays */
+ psDBF->nFields--;
+
+ psDBF->panFieldOffset = (int *)
+ SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
+
+ psDBF->panFieldSize = (int *)
+ SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
+
+ psDBF->panFieldDecimals = (int *)
+ SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
+
+ psDBF->pachFieldType = (char *)
+ SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
+
+ /* update header information */
+ psDBF->nHeaderLength -= 32;
+ psDBF->nRecordLength -= nDeletedFieldSize;
+
+ /* overwrite field information in header */
+ memmove(psDBF->pszHeader + iField*32,
+ psDBF->pszHeader + (iField+1)*32,
+ sizeof(char) * (psDBF->nFields - iField)*32);
+
+ psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
+
+ /* update size of current record appropriately */
+ psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+ psDBF->nRecordLength);
+
+ /* we're done if we're dealing with not yet created .dbf */
+ if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+ return TRUE;
+
+ /* force update of header with new header and record length */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
+ /* alloc record */
+ pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
+
+ /* shift records to their new positions */
+ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ {
+ nRecordOffset =
+ nOldRecordLength * (SAOffset) iRecord + nOldHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* move record in two steps */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
+ psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
+ nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
+ 1, psDBF->fp );
+
+ }
+
+ /* TODO: truncate file */
+
+ /* free record */
+ free(pszRecord);
+
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = FALSE;
+
+ return TRUE;
+}
+
+/************************************************************************/
+/* DBFReorderFields() */
+/* */
+/* Reorder the fields of a .dbf file */
+/* */
+/* panMap must be exactly psDBF->nFields long and be a permutation */
+/* of [0, psDBF->nFields-1]. This assumption will not be asserted in the*/
+/* code of DBFReorderFields. */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFReorderFields( DBFHandle psDBF, int* panMap )
+{
+ SAOffset nRecordOffset;
+ int i, iRecord;
+ int *panFieldOffsetNew;
+ int *panFieldSizeNew;
+ int *panFieldDecimalsNew;
+ char *pachFieldTypeNew;
+ char *pszHeaderNew;
+ char *pszRecord;
+ char *pszRecordNew;
+
+ if ( psDBF->nFields == 0 )
+ return TRUE;
+
+ /* make sure that everything is written in .dbf */
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
+
+ panFieldOffsetNew = (int *) malloc(sizeof(int) * psDBF->nFields);
+ panFieldSizeNew = (int *) malloc(sizeof(int) * psDBF->nFields);
+ panFieldDecimalsNew = (int *) malloc(sizeof(int) * psDBF->nFields);
+ pachFieldTypeNew = (char *) malloc(sizeof(char) * psDBF->nFields);
+ pszHeaderNew = (char*) malloc(sizeof(char) * 32 * psDBF->nFields);
+
+ /* shuffle fields definitions */
+ for(i=0; i < psDBF->nFields; i++)
+ {
+ panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
+ panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
+ pachFieldTypeNew[i] = psDBF->pachFieldType[panMap[i]];
+ memcpy(pszHeaderNew + i * 32,
+ psDBF->pszHeader + panMap[i] * 32, 32);
+ }
+ panFieldOffsetNew[0] = 1;
+ for(i=1; i < psDBF->nFields; i++)
+ {
+ panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
+ }
+
+ free(psDBF->pszHeader);
+ psDBF->pszHeader = pszHeaderNew;
+
+ /* we're done if we're dealing with not yet created .dbf */
+ if ( !(psDBF->bNoHeader && psDBF->nRecords == 0) )
+ {
+ /* force update of header with new header and record length */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
+ /* alloc record */
+ pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+ pszRecordNew = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+
+ /* shuffle fields in records */
+ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ {
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+
+ pszRecordNew[0] = pszRecord[0];
+
+ for(i=0; i < psDBF->nFields; i++)
+ {
+ memcpy(pszRecordNew + panFieldOffsetNew[i],
+ pszRecord + psDBF->panFieldOffset[panMap[i]],
+ psDBF->panFieldSize[panMap[i]]);
+ }
+
+ /* write record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp );
+ }
+
+ /* free record */
+ free(pszRecord);
+ free(pszRecordNew);
+ }
+
+ free(psDBF->panFieldOffset);
+ free(psDBF->panFieldSize);
+ free(psDBF->panFieldDecimals);
+ free(psDBF->pachFieldType);
+
+ psDBF->panFieldOffset = panFieldOffsetNew;
+ psDBF->panFieldSize = panFieldSizeNew;
+ psDBF->panFieldDecimals =panFieldDecimalsNew;
+ psDBF->pachFieldType = pachFieldTypeNew;
+
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = FALSE;
+
+ return TRUE;
+}
+
+
+/************************************************************************/
+/* DBFAlterFieldDefn() */
+/* */
+/* Alter a field definition in a .dbf file */
+/************************************************************************/
+
+int SHPAPI_CALL
+DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
+ char chType, int nWidth, int nDecimals )
+{
+ int i;
+ int iRecord;
+ int nOffset;
+ int nOldWidth;
+ int nOldRecordLength;
+ int nRecordOffset;
+ char* pszFInfo;
+ char chOldType;
+ int bIsNULL;
+ char chFieldFill;
+
+ if (iField < 0 || iField >= psDBF->nFields)
+ return FALSE;
+
+ /* make sure that everything is written in .dbf */
+ if( !DBFFlushRecord( psDBF ) )
+ return FALSE;
+
+ chFieldFill = DBFGetNullCharacter(chType);
+
+ chOldType = psDBF->pachFieldType[iField];
+ nOffset = psDBF->panFieldOffset[iField];
+ nOldWidth = psDBF->panFieldSize[iField];
+ nOldRecordLength = psDBF->nRecordLength;
+
+/* -------------------------------------------------------------------- */
+/* Do some checking to ensure we can add records to this file. */
+/* -------------------------------------------------------------------- */
+ if( nWidth < 1 )
+ return -1;
+
+ if( nWidth > 255 )
+ nWidth = 255;
+
+/* -------------------------------------------------------------------- */
+/* Assign the new field information fields. */
+/* -------------------------------------------------------------------- */
+ psDBF->panFieldSize[iField] = nWidth;
+ psDBF->panFieldDecimals[iField] = nDecimals;
+ psDBF->pachFieldType[iField] = chType;
+
+/* -------------------------------------------------------------------- */
+/* Update the header information. */
+/* -------------------------------------------------------------------- */
+ pszFInfo = psDBF->pszHeader + 32 * iField;
+
+ for( i = 0; i < 32; i++ )
+ pszFInfo[i] = '\0';
+
+ if( (int) strlen(pszFieldName) < 10 )
+ strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
+ else
+ strncpy( pszFInfo, pszFieldName, 10);
+
+ pszFInfo[11] = psDBF->pachFieldType[iField];
+
+ if( chType == 'C' )
+ {
+ pszFInfo[16] = (unsigned char) (nWidth % 256);
+ pszFInfo[17] = (unsigned char) (nWidth / 256);
+ }
+ else
+ {
+ pszFInfo[16] = (unsigned char) nWidth;
+ pszFInfo[17] = (unsigned char) nDecimals;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Update offsets */
+/* -------------------------------------------------------------------- */
+ if (nWidth != nOldWidth)
+ {
+ for (i = iField + 1; i < psDBF->nFields; i++)
+ psDBF->panFieldOffset[i] += nWidth - nOldWidth;
+ psDBF->nRecordLength += nWidth - nOldWidth;
+
+ psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
+ psDBF->nRecordLength);
+ }
+
+ /* we're done if we're dealing with not yet created .dbf */
+ if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
+ return TRUE;
+
+ /* force update of header with new header and record length */
+ psDBF->bNoHeader = TRUE;
+ DBFUpdateHeader( psDBF );
+
+ if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
+ {
+ char* pszRecord = (char *) malloc(sizeof(char) * nOldRecordLength);
+ char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
+
+ pszOldField[nOldWidth] = 0;
+
+ /* move records to their new positions */
+ for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
+ {
+ nRecordOffset =
+ nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
+ bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+
+ if (nWidth != nOldWidth)
+ {
+ if ((chOldType == 'N' || chOldType == 'F') && pszOldField[0] == ' ')
+ {
+ /* Strip leading spaces when truncating a numeric field */
+ memmove( pszRecord + nOffset,
+ pszRecord + nOffset + nOldWidth - nWidth,
+ nWidth );
+ }
+ if (nOffset + nOldWidth < nOldRecordLength)
+ {
+ memmove( pszRecord + nOffset + nWidth,
+ pszRecord + nOffset + nOldWidth,
+ nOldRecordLength - (nOffset + nOldWidth));
+ }
+ }
+
+ /* Convert null value to the appropriate value of the new type */
+ if (bIsNULL)
+ {
+ memset( pszRecord + nOffset, chFieldFill, nWidth);
+ }
+
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* write record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ }
+
+ free(pszRecord);
+ free(pszOldField);
+ }
+ else if (nWidth > nOldWidth)
+ {
+ char* pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
+ char* pszOldField = (char *) malloc(sizeof(char) * (nOldWidth + 1));
+
+ pszOldField[nOldWidth] = 0;
+
+ /* move records to their new positions */
+ for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
+ {
+ nRecordOffset =
+ nOldRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* load record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
+
+ memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
+ bIsNULL = DBFIsValueNULL( chOldType, pszOldField );
+
+ if (nOffset + nOldWidth < nOldRecordLength)
+ {
+ memmove( pszRecord + nOffset + nWidth,
+ pszRecord + nOffset + nOldWidth,
+ nOldRecordLength - (nOffset + nOldWidth));
+ }
+
+ /* Convert null value to the appropriate value of the new type */
+ if (bIsNULL)
+ {
+ memset( pszRecord + nOffset, chFieldFill, nWidth);
+ }
+ else
+ {
+ if ((chOldType == 'N' || chOldType == 'F'))
+ {
+ /* Add leading spaces when expanding a numeric field */
+ memmove( pszRecord + nOffset + nWidth - nOldWidth,
+ pszRecord + nOffset, nOldWidth );
+ memset( pszRecord + nOffset, ' ', nWidth - nOldWidth );
+ }
+ else
+ {
+ /* Add trailing spaces */
+ memset(pszRecord + nOffset + nOldWidth, ' ', nWidth - nOldWidth);
+ }
+ }
+
+ nRecordOffset =
+ psDBF->nRecordLength * (SAOffset) iRecord + psDBF->nHeaderLength;
+
+ /* write record */
+ psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
+ psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
+ }
+
+ free(pszRecord);
+ free(pszOldField);
+ }
+
+ psDBF->nCurrentRecord = -1;
+ psDBF->bCurrentRecordModified = FALSE;
+
+ return TRUE;
+}
diff --git a/src/decoders/safileio.c b/src/decoders/safileio.c
new file mode 100644
index 0000000..f3affe2
--- /dev/null
+++ b/src/decoders/safileio.c
@@ -0,0 +1,286 @@
+/******************************************************************************
+ * $Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $
+ *
+ * Project: Shapelib
+ * Purpose: Default implementation of file io based on stdio.
+ * Author: Frank Warmerdam, warmerdam at pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2007, Frank Warmerdam
+ *
+ * This software is available under the following "MIT Style" license,
+ * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This
+ * option is discussed in more detail in shapelib.html.
+ *
+ * --
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ******************************************************************************
+ *
+ * $Log: safileio.c,v $
+ * Revision 1.4 2008-01-16 20:05:14 bram
+ * Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
+ * tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
+ * is only available on the Windows platform that decodes the UTF-8 filenames to wide
+ * character strings and feeds them to _wfopen and _wremove.
+ *
+ * Revision 1.3 2007/12/18 18:28:11 bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
+ *
+ * Revision 1.2 2007/12/15 20:25:30 bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function. This is
+ * either the number from the LDID header field ("LDID/<number>") or as the
+ * content of an accompanying .CPG file. When creating a DBF file, the code can
+ * be set using DBFCreateEx.
+ *
+ * Revision 1.1 2007/12/06 06:56:41 fwarmerdam
+ * new
+ *
+ */
+
+#include "shapefil.h"
+
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: safileio.c,v 1.4 2008-01-16 20:05:14 bram Exp $");
+
+#ifdef SHPAPI_UTF8_HOOKS
+# ifdef SHPAPI_WINDOWS
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+# pragma comment(lib, "kernel32.lib")
+# endif
+#endif
+
+/************************************************************************/
+/* SADFOpen() */
+/************************************************************************/
+
+SAFile SADFOpen( const char *pszFilename, const char *pszAccess )
+
+{
+ return (SAFile) fopen( pszFilename, pszAccess );
+}
+
+/************************************************************************/
+/* SADFRead() */
+/************************************************************************/
+
+SAOffset SADFRead( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+ return (SAOffset) fread( p, (size_t) size, (size_t) nmemb,
+ (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFWrite() */
+/************************************************************************/
+
+SAOffset SADFWrite( void *p, SAOffset size, SAOffset nmemb, SAFile file )
+
+{
+ return (SAOffset) fwrite( p, (size_t) size, (size_t) nmemb,
+ (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFSeek() */
+/************************************************************************/
+
+SAOffset SADFSeek( SAFile file, SAOffset offset, int whence )
+
+{
+ return (SAOffset) fseek( (FILE *) file, (long) offset, whence );
+}
+
+/************************************************************************/
+/* SADFTell() */
+/************************************************************************/
+
+SAOffset SADFTell( SAFile file )
+
+{
+ return (SAOffset) ftell( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFFlush() */
+/************************************************************************/
+
+int SADFFlush( SAFile file )
+
+{
+ return fflush( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFClose() */
+/************************************************************************/
+
+int SADFClose( SAFile file )
+
+{
+ return fclose( (FILE *) file );
+}
+
+/************************************************************************/
+/* SADFClose() */
+/************************************************************************/
+
+int SADRemove( const char *filename )
+
+{
+ return remove( filename );
+}
+
+/************************************************************************/
+/* SADError() */
+/************************************************************************/
+
+void SADError( const char *message )
+
+{
+ fprintf( stderr, "%s\n", message );
+}
+
+/************************************************************************/
+/* SASetupDefaultHooks() */
+/************************************************************************/
+
+void SASetupDefaultHooks( SAHooks *psHooks )
+
+{
+ psHooks->FOpen = SADFOpen;
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+ psHooks->Remove = SADRemove;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
+}
+
+
+
+
+#ifdef SHPAPI_WINDOWS
+
+/************************************************************************/
+/* Utf8ToWideChar */
+/************************************************************************/
+
+const wchar_t* Utf8ToWideChar( const char *pszFilename )
+{
+ int nMulti, nWide;
+ wchar_t *pwszFileName;
+
+ nMulti = strlen(pszFilename) + 1;
+ nWide = MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, 0, 0);
+ if( nWide == 0 )
+ {
+ return NULL;
+ }
+ pwszFileName = (wchar_t*) malloc(nWide * sizeof(wchar_t));
+ if ( pwszFileName == NULL )
+ {
+ return NULL;
+ }
+ if( MultiByteToWideChar( CP_UTF8, 0, pszFilename, nMulti, pwszFileName, nWide ) == 0 )
+ {
+ free( pwszFileName );
+ return NULL;
+ }
+ return pwszFileName;
+}
+
+/************************************************************************/
+/* SAUtf8WFOpen */
+/************************************************************************/
+
+SAFile SAUtf8WFOpen( const char *pszFilename, const char *pszAccess )
+{
+ SAFile file = NULL;
+ const wchar_t *pwszFileName, *pwszAccess;
+ pwszFileName = Utf8ToWideChar( pszFilename );
+ pwszAccess = Utf8ToWideChar( pszAccess );
+ if( pwszFileName != NULL && pwszFileName != NULL)
+ {
+ file = (SAFile) _wfopen( pwszFileName, pwszAccess );
+ }
+ free ((wchar_t*) pwszFileName);
+ free ((wchar_t*) pwszAccess);
+ return file;
+}
+
+/************************************************************************/
+/* SAUtf8WRemove() */
+/************************************************************************/
+
+int SAUtf8WRemove( const char *pszFilename )
+{
+ const wchar_t *pwszFileName = Utf8ToWideChar( pszFilename );
+ int rc = -1;
+ if( pwszFileName != NULL )
+ {
+ rc = _wremove( pwszFileName );
+ }
+ free ((wchar_t*) pwszFileName);
+ return rc;
+}
+
+#endif
+
+#ifdef SHPAPI_UTF8_HOOKS
+
+/************************************************************************/
+/* SASetupUtf8Hooks() */
+/************************************************************************/
+
+void SASetupUtf8Hooks( SAHooks *psHooks )
+{
+#ifdef SHPAPI_WINDOWS
+ psHooks->FOpen = SAUtf8WFOpen;
+ psHooks->Remove = SAUtf8WRemove;
+#else
+# error "no implementations of UTF-8 hooks available for this platform"
+#endif
+ psHooks->FRead = SADFRead;
+ psHooks->FWrite = SADFWrite;
+ psHooks->FSeek = SADFSeek;
+ psHooks->FTell = SADFTell;
+ psHooks->FFlush = SADFFlush;
+ psHooks->FClose = SADFClose;
+
+ psHooks->Error = SADError;
+ psHooks->Atof = atof;
+}
+
+#endif
diff --git a/src/decoders/shapefil.h b/src/decoders/shapefil.h
index 80af789..e90b1cc 100644
--- a/src/decoders/shapefil.h
+++ b/src/decoders/shapefil.h
@@ -1,8 +1,8 @@
-#ifndef _SHAPEFILE_H_INCLUDED
-#define _SHAPEFILE_H_INCLUDED
+#ifndef SHAPEFILE_H_INCLUDED
+#define SHAPEFILE_H_INCLUDED
/******************************************************************************
- * $Id: shapefil.h,v 1.26 2002/09/29 00:00:08 warmerda Exp $
+ * $Id: shapefil.h,v 1.52 2011-12-11 22:26:46 fwarmerdam Exp $
*
* Project: Shapelib
* Purpose: Primary include file for Shapelib.
@@ -36,82 +36,108 @@
* DEALINGS IN THE SOFTWARE.
******************************************************************************
*
- * $MagLog: shapefil.h,v $
- * Revision 1.26 2002/09/29 00:00:08 warmerda
- * added FTMagLogical and logical attribute read/write calls
+ * $Log: shapefil.h,v $
+ * Revision 1.52 2011-12-11 22:26:46 fwarmerdam
+ * upgrade .qix access code to use SAHooks (gdal #3365)
*
- * Revision 1.25 2002/05/07 13:46:30 warmerda
- * added DBFWriteAttributeDirectly().
+ * Revision 1.51 2011-07-24 05:59:25 fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
*
- * Revision 1.24 2002/04/10 16:59:54 warmerda
- * added SHPRewindObject
+ * Revision 1.50 2011-05-13 17:35:17 fwarmerdam
+ * added DBFReorderFields() and DBFAlterFields() functions (from Even)
*
- * Revision 1.23 2002/01/15 14:36:07 warmerda
- * updated email address
+ * Revision 1.49 2011-04-16 14:38:21 fwarmerdam
+ * avoid warnings with gcc on SHP_CVSID
*
- * Revision 1.22 2002/01/15 14:32:00 warmerda
- * try to improve SHPAPI_CALL docs
+ * Revision 1.48 2010-08-27 23:42:52 fwarmerdam
+ * add SHPAPI_CALL attribute in code
+ *
+ * Revision 1.47 2010-01-28 11:34:34 fwarmerdam
+ * handle the shape file length limits more gracefully (#3236)
*
- * Revision 1.21 2001/11/01 16:29:55 warmerda
- * move pabyRec into SHPInfo for thread safety
+ * Revision 1.46 2008-11-12 14:28:15 fwarmerdam
+ * DBFCreateField() now works on files with records
*
- * Revision 1.20 2001/07/20 13:06:02 warmerda
- * fixed SHPAPI attribute for SHPTreeFindLikelyShapes
+ * Revision 1.45 2008/11/11 17:47:10 fwarmerdam
+ * added DBFDeleteField() function
*
- * Revision 1.19 2001/05/31 19:20:13 warmerda
- * added DBFGetFieldIndex()
+ * Revision 1.44 2008/01/16 20:05:19 bram
+ * Add file hooks that accept UTF-8 encoded filenames on some platforms. Use SASetupUtf8Hooks
+ * tosetup the hooks and check SHPAPI_UTF8_HOOKS for its availability. Currently, this
+ * is only available on the Windows platform that decodes the UTF-8 filenames to wide
+ * character strings and feeds them to _wfopen and _wremove.
*
- * Revision 1.18 2001/05/31 18:15:40 warmerda
- * Added support for NULL fields in DBF files
+ * Revision 1.43 2008/01/10 16:35:30 fwarmerdam
+ * avoid _ prefix on #defined symbols (bug 1840)
*
- * Revision 1.17 2001/05/23 13:36:52 warmerda
- * added use of SHPAPI_CALL
+ * Revision 1.42 2007/12/18 18:28:14 bram
+ * - create hook for client specific atof (bugzilla ticket 1615)
+ * - check for NULL handle before closing cpCPG file, and close after reading.
*
- * Revision 1.16 2000/09/25 14:15:59 warmerda
- * added DBFGetNativeFieldType()
+ * Revision 1.41 2007/12/15 20:25:32 bram
+ * dbfopen.c now reads the Code Page information from the DBF file, and exports
+ * this information as a string through the DBFGetCodePage function. This is
+ * either the number from the LDID header field ("LDID/<number>") or as the
+ * content of an accompanying .CPG file. When creating a DBF file, the code can
+ * be set using DBFCreateEx.
*
- * Revision 1.15 2000/02/16 16:03:51 warmerda
- * added null shape support
+ * Revision 1.40 2007/12/06 07:00:25 fwarmerdam
+ * dbfopen now using SAHooks for fileio
*
- * Revision 1.14 1999/11/05 14:12:05 warmerda
- * updated license terms
+ * Revision 1.39 2007/12/04 20:37:56 fwarmerdam
+ * preliminary implementation of hooks api for io and errors
*
- * Revision 1.13 1999/06/02 18:24:21 warmerda
- * added trimming code
+ * Revision 1.38 2007/11/21 22:39:56 fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
*
- * Revision 1.12 1999/06/02 17:56:12 warmerda
- * added quad'' subnode support for trees
+ * Revision 1.37 2007/10/27 03:31:14 fwarmerdam
+ * limit default depth of tree to 12 levels (gdal ticket #1594)
*
- * Revision 1.11 1999/05/18 19:11:11 warmerda
- * Added example searching capability
+ * Revision 1.36 2007/09/10 23:33:15 fwarmerdam
+ * Upstreamed support for visibility flag in SHPAPI_CALL for the needs
+ * of GDAL (gdal ticket #1810).
*
- * Revision 1.10 1999/05/18 17:49:38 warmerda
- * added initial quadtree support
+ * Revision 1.35 2007/09/03 19:48:10 fwarmerdam
+ * move DBFReadAttribute() static dDoubleField into dbfinfo
*
- * Revision 1.9 1999/05/11 03:19:28 warmerda
- * added new Tuple api, and improved extension handling - add from candrsn
+ * Revision 1.34 2006/06/17 15:33:32 fwarmerdam
+ * added pszWorkField - bug 1202 (rso)
*
- * Revision 1.8 1999/03/23 17:22:27 warmerda
- * Added extern "C" protection for C++ users of shapefil.h.
+ * Revision 1.33 2006/02/15 01:14:30 fwarmerdam
+ * added DBFAddNativeFieldType
*
- * Revision 1.7 1998/12/31 15:31:07 warmerda
- * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options.
+ * Revision 1.32 2006/01/26 15:07:32 fwarmerdam
+ * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
*
- * Revision 1.6 1998/12/03 15:48:15 warmerda
- * Added SHPCalculateExtents().
+ * Revision 1.31 2006/01/05 01:27:27 fwarmerdam
+ * added dbf deletion mark/fetch
*
- * Revision 1.5 1998/11/09 20:57:16 warmerda
- * Altered SHPGetInfo() call.
+ * Revision 1.30 2005/01/03 22:30:13 fwarmerdam
+ * added support for saved quadtrees
*
- * Revision 1.4 1998/11/09 20:19:33 warmerda
- * Added 3D support, and use of SHPObject.
+ * Revision 1.29 2004/09/26 20:09:35 fwarmerdam
+ * avoid rcsid warnings
*
- * Revision 1.3 1995/08/23 02:24:05 warmerda
- * Added support for reading bounds.
+ * Revision 1.28 2003/12/29 06:02:18 fwarmerdam
+ * added cpl_error.h option
*
- * Revision 1.2 1995/08/04 03:17:39 warmerda
- * Added header.
+ * Revision 1.27 2003/04/21 18:30:37 warmerda
+ * added header write/update public methods
*
+ * Revision 1.26 2002/09/29 00:00:08 warmerda
+ * added FTLogical and logical attribute read/write calls
+ *
+ * Revision 1.25 2002/05/07 13:46:30 warmerda
+ * added DBFWriteAttributeDirectly().
+ *
+ * Revision 1.24 2002/04/10 16:59:54 warmerda
+ * added SHPRewindObject
+ *
+ * Revision 1.23 2002/01/15 14:36:07 warmerda
+ * updated email address
+ *
+ * Revision 1.22 2002/01/15 14:32:00 warmerda
+ * try to improve SHPAPI_CALL docs
*/
#include <stdio.h>
@@ -140,7 +166,7 @@ extern "C" {
/* is disabled. */
/* -------------------------------------------------------------------- */
#define DISABLE_MULTIPATCH_MEASURE
-
+
/* -------------------------------------------------------------------- */
/* SHPAPI_CALL */
/* */
@@ -176,29 +202,88 @@ extern "C" {
#endif
#ifndef SHPAPI_CALL
-# define SHPAPI_CALL
+# if defined(USE_GCC_VISIBILITY_FLAG)
+# define SHPAPI_CALL __attribute__ ((visibility("default")))
+# define SHPAPI_CALL1(x) __attribute__ ((visibility("default"))) x
+# else
+# define SHPAPI_CALL
+# endif
#endif
#ifndef SHPAPI_CALL1
# define SHPAPI_CALL1(x) x SHPAPI_CALL
#endif
+/* -------------------------------------------------------------------- */
+/* Macros for controlling CVSID and ensuring they don't appear */
+/* as unreferenced variables resulting in lots of warnings. */
+/* -------------------------------------------------------------------- */
+#ifndef DISABLE_CVSID
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define SHP_CVSID(string) static char cpl_cvsid[] __attribute__((used)) = string;
+# else
+# define SHP_CVSID(string) static char cpl_cvsid[] = string; \
+static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : cpl_cvsid ); }
+# endif
+#else
+# define SHP_CVSID(string)
+#endif
+
+/* -------------------------------------------------------------------- */
+/* On some platforms, additional file IO hooks are defined that */
+/* UTF-8 encoded filenames Unicode filenames */
+/* -------------------------------------------------------------------- */
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define SHPAPI_WINDOWS
+# define SHPAPI_UTF8_HOOKS
+#endif
+
+/* -------------------------------------------------------------------- */
+/* IO/Error hook functions. */
+/* -------------------------------------------------------------------- */
+typedef int *SAFile;
+
+#ifndef SAOffset
+typedef unsigned long SAOffset;
+#endif
+
+typedef struct {
+ SAFile (*FOpen) ( const char *filename, const char *access);
+ SAOffset (*FRead) ( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+ SAOffset (*FWrite)( void *p, SAOffset size, SAOffset nmemb, SAFile file);
+ SAOffset (*FSeek) ( SAFile file, SAOffset offset, int whence );
+ SAOffset (*FTell) ( SAFile file );
+ int (*FFlush)( SAFile file );
+ int (*FClose)( SAFile file );
+ int (*Remove) ( const char *filename );
+
+ void (*Error) ( const char *message );
+ double (*Atof) ( const char *str );
+} SAHooks;
+
+void SHPAPI_CALL SASetupDefaultHooks( SAHooks *psHooks );
+#ifdef SHPAPI_UTF8_HOOKS
+void SHPAPI_CALL SASetupUtf8Hooks( SAHooks *psHooks );
+#endif
+
/************************************************************************/
/* SHP Support. */
/************************************************************************/
typedef struct
{
- FILE *fpSHP;
- FILE *fpSHX;
+ SAHooks sHooks;
+
+ SAFile fpSHP;
+ SAFile fpSHX;
int nShapeType; /* SHPT_* */
- int nFileSize; /* SHP file */
+ unsigned int nFileSize; /* SHP file */
int nRecords;
int nMaxRecords;
- int *panRecOffset;
- int *panRecSize;
+ unsigned int *panRecOffset;
+ unsigned int *panRecSize;
double adBoundsMin[4];
double adBoundsMax[4];
@@ -271,15 +356,26 @@ typedef struct
double dfYMax;
double dfZMax;
double dfMMax;
+
+ int bMeasureIsUsed;
} SHPObject;
/* -------------------------------------------------------------------- */
/* SHP API Prototypes */
/* -------------------------------------------------------------------- */
+
+/* If pszAccess is read-only, the fpSHX field of the returned structure */
+/* will be NULL as it is not necessary to keep the SHX file open */
SHPHandle SHPAPI_CALL
SHPOpen( const char * pszShapeFile, const char * pszAccess );
SHPHandle SHPAPI_CALL
+ SHPOpenLL( const char *pszShapeFile, const char *pszAccess,
+ SAHooks *psHooks );
+SHPHandle SHPAPI_CALL
SHPCreate( const char * pszShapeFile, int nShapeType );
+SHPHandle SHPAPI_CALL
+ SHPCreateLL( const char * pszShapeFile, int nShapeType,
+ SAHooks *psHooks );
void SHPAPI_CALL
SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
double * padfMinBound, double * padfMaxBound );
@@ -294,19 +390,22 @@ void SHPAPI_CALL
void SHPAPI_CALL
SHPComputeExtents( SHPObject * psObject );
SHPObject SHPAPI_CALL1(*)
- SHPCreateObject( int nSHPType, int nShapeId,
- int nParts, int * panPartStart, int * panPartType,
- int nVertices, double * padfX, double * padfY,
- double * padfZ, double * padfM );
+ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
+ const int * panPartStart, const int * panPartType,
+ int nVertices,
+ const double * padfX, const double * padfY,
+ const double * padfZ, const double * padfM );
SHPObject SHPAPI_CALL1(*)
SHPCreateSimpleObject( int nSHPType, int nVertices,
- double * padfX, double * padfY, double * padfZ );
+ const double * padfX,
+ const double * padfY,
+ const double * padfZ );
int SHPAPI_CALL
SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
-void SHPAPI_CALL
- SHPClose( SHPHandle hSHP );
+void SHPAPI_CALL SHPClose( SHPHandle hSHP );
+void SHPAPI_CALL SHPWriteHeader( SHPHandle hSHP );
const char SHPAPI_CALL1(*)
SHPTypeName( int nSHPType );
@@ -320,6 +419,9 @@ const char SHPAPI_CALL1(*)
/* this can be two or four for binary or quad tree */
#define MAX_SUBNODE 4
+/* upper limit of tree levels for automatic estimation */
+#define MAX_DEFAULT_TREE_DEPTH 12
+
typedef struct shape_tree_node
{
/* region covered by this node */
@@ -343,6 +445,7 @@ typedef struct
int nMaxDepth;
int nDimension;
+ int nTotalCount;
SHPTreeNode *psRoot;
} SHPTree;
@@ -355,12 +458,8 @@ void SHPAPI_CALL
int SHPAPI_CALL
SHPWriteTree( SHPTree *hTree, const char * pszFilename );
-SHPTree SHPAPI_CALL
- SHPReadTree( const char * pszFilename );
int SHPAPI_CALL
- SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject );
-int SHPAPI_CALL
SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject );
int SHPAPI_CALL
SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId );
@@ -376,12 +475,37 @@ int SHPAPI_CALL1(*)
int SHPAPI_CALL
SHPCheckBoundsOverlap( double *, double *, double *, double *, int );
+int SHPAPI_CALL1(*)
+SHPSearchDiskTree( FILE *fp,
+ double *padfBoundsMin, double *padfBoundsMax,
+ int *pnShapeCount );
+
+
+typedef struct SHPDiskTreeInfo* SHPTreeDiskHandle;
+
+SHPTreeDiskHandle SHPAPI_CALL
+ SHPOpenDiskTree( const char* pszQIXFilename,
+ SAHooks *psHooks );
+
+void SHPAPI_CALL
+ SHPCloseDiskTree( SHPTreeDiskHandle hDiskTree );
+
+int SHPAPI_CALL1(*)
+SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree,
+ double *padfBoundsMin, double *padfBoundsMax,
+ int *pnShapeCount );
+
+int SHPAPI_CALL
+ SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename, SAHooks *psHooks );
+
/************************************************************************/
/* DBF Support. */
/************************************************************************/
typedef struct
{
- FILE *fp;
+ SAHooks sHooks;
+
+ SAFile fp;
int nRecords;
@@ -398,9 +522,17 @@ typedef struct
int nCurrentRecord;
int bCurrentRecordModified;
char *pszCurrentRecord;
+
+ int nWorkFieldLength;
+ char *pszWorkField;
int bNoHeader;
int bUpdated;
+
+ double dfDoubleField;
+
+ int iLanguageDriver;
+ char *pszCodePage;
} DBFInfo;
typedef DBFInfo * DBFHandle;
@@ -415,10 +547,18 @@ typedef enum {
#define XBASE_FLDHDR_SZ 32
+
DBFHandle SHPAPI_CALL
DBFOpen( const char * pszDBFFile, const char * pszAccess );
DBFHandle SHPAPI_CALL
+ DBFOpenLL( const char * pszDBFFile, const char * pszAccess,
+ SAHooks *psHooks );
+DBFHandle SHPAPI_CALL
DBFCreate( const char * pszDBFFile );
+DBFHandle SHPAPI_CALL
+ DBFCreateEx( const char * pszDBFFile, const char * pszCodePage );
+DBFHandle SHPAPI_CALL
+ DBFCreateLL( const char * pszDBFFile, const char * pszCodePage, SAHooks *psHooks );
int SHPAPI_CALL
DBFGetFieldCount( DBFHandle psDBF );
@@ -428,6 +568,20 @@ int SHPAPI_CALL
DBFAddField( DBFHandle hDBF, const char * pszFieldName,
DBFFieldType eType, int nWidth, int nDecimals );
+int SHPAPI_CALL
+ DBFAddNativeFieldType( DBFHandle hDBF, const char * pszFieldName,
+ char chType, int nWidth, int nDecimals );
+
+int SHPAPI_CALL
+ DBFDeleteField( DBFHandle hDBF, int iField );
+
+int SHPAPI_CALL
+ DBFReorderFields( DBFHandle psDBF, int* panMap );
+
+int SHPAPI_CALL
+ DBFAlterFieldDefn( DBFHandle psDBF, int iField, const char * pszFieldName,
+ char chType, int nWidth, int nDecimals );
+
DBFFieldType SHPAPI_CALL
DBFGetFieldInfo( DBFHandle psDBF, int iField,
char * pszFieldName, int * pnWidth, int * pnDecimals );
@@ -442,7 +596,7 @@ double SHPAPI_CALL
const char SHPAPI_CALL1(*)
DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
const char SHPAPI_CALL1(*)
- DBFReadMagLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
+ DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField );
int SHPAPI_CALL
DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
@@ -459,7 +613,7 @@ int SHPAPI_CALL
DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );
int SHPAPI_CALL
- DBFWriteMagLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
+ DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField,
const char lFieldValue);
int SHPAPI_CALL
DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
@@ -469,16 +623,25 @@ const char SHPAPI_CALL1(*)
int SHPAPI_CALL
DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple );
+int SHPAPI_CALL DBFIsRecordDeleted( DBFHandle psDBF, int iShape );
+int SHPAPI_CALL DBFMarkRecordDeleted( DBFHandle psDBF, int iShape,
+ int bIsDeleted );
+
DBFHandle SHPAPI_CALL
DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename );
void SHPAPI_CALL
DBFClose( DBFHandle hDBF );
+void SHPAPI_CALL
+ DBFUpdateHeader( DBFHandle hDBF );
char SHPAPI_CALL
DBFGetNativeFieldType( DBFHandle hDBF, int iField );
+const char SHPAPI_CALL1(*)
+ DBFGetCodePage(DBFHandle psDBF );
+
#ifdef __cplusplus
}
#endif
-#endif /* ndef _SHAPEFILE_H_INCLUDED */
+#endif /* ndef SHAPEFILE_H_INCLUDED */
diff --git a/src/decoders/shpopen.c b/src/decoders/shpopen.c
index e57ccee..d81f601 100644
--- a/src/decoders/shpopen.c
+++ b/src/decoders/shpopen.c
@@ -1,5 +1,5 @@
/******************************************************************************
- * $Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $
+ * $Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $
*
* Project: Shapelib
* Purpose: Implementation of core Shapefile read/write functions.
@@ -34,6 +34,112 @@
******************************************************************************
*
* $Log: shpopen.c,v $
+ * Revision 1.73 2012-01-24 22:33:01 fwarmerdam
+ * fix memory leak on failure to open .shp (gdal #4410)
+ *
+ * Revision 1.72 2011-12-11 22:45:28 fwarmerdam
+ * fix failure return from SHPOpenLL.
+ *
+ * Revision 1.71 2011-09-15 03:33:58 fwarmerdam
+ * fix missing cast (#2344)
+ *
+ * Revision 1.70 2011-07-24 05:59:25 fwarmerdam
+ * minimize use of CPLError in favor of SAHooks.Error()
+ *
+ * Revision 1.69 2011-07-24 03:24:22 fwarmerdam
+ * fix memory leaks in error cases creating shapefiles (#2061)
+ *
+ * Revision 1.68 2010-08-27 23:42:52 fwarmerdam
+ * add SHPAPI_CALL attribute in code
+ *
+ * Revision 1.67 2010-07-01 08:15:48 fwarmerdam
+ * do not error out on an object with zero vertices
+ *
+ * Revision 1.66 2010-07-01 07:58:57 fwarmerdam
+ * minor cleanup of error handling
+ *
+ * Revision 1.65 2010-07-01 07:27:13 fwarmerdam
+ * white space formatting adjustments
+ *
+ * Revision 1.64 2010-01-28 11:34:34 fwarmerdam
+ * handle the shape file length limits more gracefully (#3236)
+ *
+ * Revision 1.63 2010-01-28 04:04:40 fwarmerdam
+ * improve numerical accuracy of SHPRewind() algs (gdal #3363)
+ *
+ * Revision 1.62 2010-01-17 05:34:13 fwarmerdam
+ * Remove asserts on x/y being null (#2148).
+ *
+ * Revision 1.61 2010-01-16 05:07:42 fwarmerdam
+ * allow 0/nulls in shpcreateobject (#2148)
+ *
+ * Revision 1.60 2009-09-17 20:50:02 bram
+ * on Win32, define snprintf as alias to _snprintf
+ *
+ * Revision 1.59 2008-03-14 05:25:31 fwarmerdam
+ * Correct crash on buggy geometries (gdal #2218)
+ *
+ * Revision 1.58 2008/01/08 23:28:26 bram
+ * on line 2095, use a float instead of a double to avoid a compiler warning
+ *
+ * Revision 1.57 2007/12/06 07:00:25 fwarmerdam
+ * dbfopen now using SAHooks for fileio
+ *
+ * Revision 1.56 2007/12/04 20:37:56 fwarmerdam
+ * preliminary implementation of hooks api for io and errors
+ *
+ * Revision 1.55 2007/11/21 22:39:56 fwarmerdam
+ * close shx file in readonly mode (GDAL #1956)
+ *
+ * Revision 1.54 2007/11/15 00:12:47 mloskot
+ * Backported recent changes from GDAL (Ticket #1415) to Shapelib.
+ *
+ * Revision 1.53 2007/11/14 22:31:08 fwarmerdam
+ * checks after mallocs to detect for corrupted/voluntary broken shapefiles.
+ * http://trac.osgeo.org/gdal/ticket/1991
+ *
+ * Revision 1.52 2007/06/21 15:58:33 fwarmerdam
+ * fix for SHPRewindObject when rings touch at one vertex (gdal #976)
+ *
+ * Revision 1.51 2006/09/04 15:24:01 fwarmerdam
+ * Fixed up log message for 1.49.
+ *
+ * Revision 1.50 2006/09/04 15:21:39 fwarmerdam
+ * fix of last fix
+ *
+ * Revision 1.49 2006/09/04 15:21:00 fwarmerdam
+ * MLoskot: Added stronger test of Shapefile reading failures, e.g. truncated
+ * files. The problem was discovered by Tim Sutton and reported here
+ * https://svn.qgis.org/trac/ticket/200
+ *
+ * Revision 1.48 2006/01/26 15:07:32 fwarmerdam
+ * add bMeasureIsUsed flag from Craig Bruce: Bug 1249
+ *
+ * Revision 1.47 2006/01/04 20:07:23 fwarmerdam
+ * In SHPWriteObject() make sure that the record length is updated
+ * when rewriting an existing record.
+ *
+ * Revision 1.46 2005/02/11 17:17:46 fwarmerdam
+ * added panPartStart[0] validation
+ *
+ * Revision 1.45 2004/09/26 20:09:48 fwarmerdam
+ * const correctness changes
+ *
+ * Revision 1.44 2003/12/29 00:18:39 fwarmerdam
+ * added error checking for failed IO and optional CPL error reporting
+ *
+ * Revision 1.43 2003/12/01 16:20:08 warmerda
+ * be careful of zero vertex shapes
+ *
+ * Revision 1.42 2003/12/01 14:58:27 warmerda
+ * added degenerate object check in SHPRewindObject()
+ *
+ * Revision 1.41 2003/07/08 15:22:43 warmerda
+ * avoid warning
+ *
+ * Revision 1.40 2003/04/21 18:30:37 warmerda
+ * added header write/update public methods
+ *
* Revision 1.39 2002/08/26 06:46:56 warmerda
* avoid c++ comments
*
@@ -158,9 +264,6 @@
*
*/
-static char rcsid[] =
- "$Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $";
-
#include "shapefil.h"
#include <math.h>
@@ -168,13 +271,16 @@ static char rcsid[] =
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+SHP_CVSID("$Id: shpopen.c,v 1.73 2012-01-24 22:33:01 fwarmerdam Exp $")
typedef unsigned char uchar;
#if UINT_MAX == 65535
-typedef long int32;
+typedef unsigned long int32;
#else
-typedef int int32;
+typedef unsigned int int32;
#endif
#ifndef FALSE
@@ -188,6 +294,12 @@ typedef int int32;
# define MAX(a,b) ((a>b) ? a : b)
#endif
+#if defined(WIN32) || defined(_WIN32)
+# ifndef snprintf
+# define snprintf _snprintf
+# endif
+#endif
+
static int bBigEndian;
@@ -234,7 +346,7 @@ static void * SfRealloc( void * pMem, int nNewSize )
/* contents of the index (.shx) file. */
/************************************************************************/
-static void SHPWriteHeader( SHPHandle psSHP )
+void SHPAPI_CALL SHPWriteHeader( SHPHandle psSHP )
{
uchar abyHeader[100];
@@ -242,12 +354,18 @@ static void SHPWriteHeader( SHPHandle psSHP )
int32 i32;
double dValue;
int32 *panSHX;
+
+ if (psSHP->fpSHX == NULL)
+ {
+ psSHP->sHooks.Error( "SHPWriteHeader failed : SHX file is closed");
+ return;
+ }
/* -------------------------------------------------------------------- */
/* Prepare header block for .shp file. */
/* -------------------------------------------------------------------- */
for( i = 0; i < 100; i++ )
- abyHeader[i] = 0;
+ abyHeader[i] = 0;
abyHeader[2] = 0x27; /* magic cookie */
abyHeader[3] = 0x0a;
@@ -299,8 +417,12 @@ static void SHPWriteHeader( SHPHandle psSHP )
/* -------------------------------------------------------------------- */
/* Write .shp file header. */
/* -------------------------------------------------------------------- */
- fseek( psSHP->fpSHP, 0, 0 );
- fwrite( abyHeader, 100, 1, psSHP->fpSHP );
+ if( psSHP->sHooks.FSeek( psSHP->fpSHP, 0, 0 ) != 0
+ || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 )
+ {
+ psSHP->sHooks.Error( "Failure writing .shp header" );
+ return;
+ }
/* -------------------------------------------------------------------- */
/* Prepare, and write .shx file header. */
@@ -309,8 +431,12 @@ static void SHPWriteHeader( SHPHandle psSHP )
ByteCopy( &i32, abyHeader+24, 4 );
if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
- fseek( psSHP->fpSHX, 0, 0 );
- fwrite( abyHeader, 100, 1, psSHP->fpSHX );
+ if( psSHP->sHooks.FSeek( psSHP->fpSHX, 0, 0 ) != 0
+ || psSHP->sHooks.FWrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 )
+ {
+ psSHP->sHooks.Error( "Failure writing .shx header" );
+ return;
+ }
/* -------------------------------------------------------------------- */
/* Write out the .shx contents. */
@@ -319,15 +445,40 @@ static void SHPWriteHeader( SHPHandle psSHP )
for( i = 0; i < psSHP->nRecords; i++ )
{
- panSHX[i*2 ] = psSHP->panRecOffset[i]/2;
- panSHX[i*2+1] = psSHP->panRecSize[i]/2;
- if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
- if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
+ panSHX[i*2 ] = psSHP->panRecOffset[i]/2;
+ panSHX[i*2+1] = psSHP->panRecSize[i]/2;
+ if( !bBigEndian ) SwapWord( 4, panSHX+i*2 );
+ if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 );
}
- fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX );
+ if( (int)psSHP->sHooks.FWrite( panSHX, sizeof(int32)*2, psSHP->nRecords, psSHP->fpSHX )
+ != psSHP->nRecords )
+ {
+ psSHP->sHooks.Error( "Failure writing .shx contents" );
+ }
free( panSHX );
+
+/* -------------------------------------------------------------------- */
+/* Flush to disk. */
+/* -------------------------------------------------------------------- */
+ psSHP->sHooks.FFlush( psSHP->fpSHP );
+ psSHP->sHooks.FFlush( psSHP->fpSHX );
+}
+
+/************************************************************************/
+/* SHPOpen() */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPOpen( const char * pszLayer, const char * pszAccess )
+
+{
+ SAHooks sHooks;
+
+ SASetupDefaultHooks( &sHooks );
+
+ return SHPOpenLL( pszLayer, pszAccess, &sHooks );
}
/************************************************************************/
@@ -338,7 +489,7 @@ static void SHPWriteHeader( SHPHandle psSHP )
/************************************************************************/
SHPHandle SHPAPI_CALL
-SHPOpen( const char * pszLayer, const char * pszAccess )
+SHPOpenLL( const char * pszLayer, const char * pszAccess, SAHooks *psHooks )
{
char *pszFullname, *pszBasename;
@@ -347,7 +498,7 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
uchar *pabyBuf;
int i;
double dValue;
-
+
/* -------------------------------------------------------------------- */
/* Ensure the access string is one of the legal ones. We */
/* ensure the result string indicates binary to avoid common */
@@ -374,6 +525,7 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
psSHP->bUpdated = FALSE;
+ memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
/* -------------------------------------------------------------------- */
/* Compute the base (layer) name. If there is any extension */
@@ -382,9 +534,9 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
pszBasename = (char *) malloc(strlen(pszLayer)+5);
strcpy( pszBasename, pszLayer );
for( i = strlen(pszBasename)-1;
- i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
- && pszBasename[i] != '\\';
- i-- ) {}
+ i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+ && pszBasename[i] != '\\';
+ i-- ) {}
if( pszBasename[i] == '.' )
pszBasename[i] = '\0';
@@ -394,33 +546,46 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
/* a PC to Unix with upper case filenames won't work! */
/* -------------------------------------------------------------------- */
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
- sprintf( pszFullname, "%s.shp", pszBasename );
- psSHP->fpSHP = fopen(pszFullname, pszAccess );
+ sprintf( pszFullname, "%s.shp", pszBasename ) ;
+ psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
if( psSHP->fpSHP == NULL )
{
sprintf( pszFullname, "%s.SHP", pszBasename );
- psSHP->fpSHP = fopen(pszFullname, pszAccess );
+ psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
}
if( psSHP->fpSHP == NULL )
{
+ char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
+ sprintf( pszMessage, "Unable to open %s.shp or %s.SHP.",
+ pszBasename, pszBasename );
+ psHooks->Error( pszMessage );
+ free( pszMessage );
+
free( psSHP );
free( pszBasename );
free( pszFullname );
- return( NULL );
+
+ return NULL;
}
sprintf( pszFullname, "%s.shx", pszBasename );
- psSHP->fpSHX = fopen(pszFullname, pszAccess );
+ psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
if( psSHP->fpSHX == NULL )
{
sprintf( pszFullname, "%s.SHX", pszBasename );
- psSHP->fpSHX = fopen(pszFullname, pszAccess );
+ psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
}
if( psSHP->fpSHX == NULL )
{
- fclose( psSHP->fpSHP );
+ char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
+ sprintf( pszMessage, "Unable to open %s.shx or %s.SHX.",
+ pszBasename, pszBasename );
+ psHooks->Error( pszMessage );
+ free( pszMessage );
+
+ psSHP->sHooks.FClose( psSHP->fpSHP );
free( psSHP );
free( pszBasename );
free( pszFullname );
@@ -434,44 +599,51 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
/* Read the file size from the SHP file. */
/* -------------------------------------------------------------------- */
pabyBuf = (uchar *) malloc(100);
- fread( pabyBuf, 100, 1, psSHP->fpSHP );
+ psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
- psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256
- + pabyBuf[25] * 256 * 256
- + pabyBuf[26] * 256
- + pabyBuf[27]) * 2;
+ psSHP->nFileSize = ((unsigned int)pabyBuf[24] * 256 * 256 * 256
+ + (unsigned int)pabyBuf[25] * 256 * 256
+ + (unsigned int)pabyBuf[26] * 256
+ + (unsigned int)pabyBuf[27]) * 2;
/* -------------------------------------------------------------------- */
/* Read SHX file Header info */
/* -------------------------------------------------------------------- */
- fread( pabyBuf, 100, 1, psSHP->fpSHX );
-
- if( pabyBuf[0] != 0
+ if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1
+ || pabyBuf[0] != 0
|| pabyBuf[1] != 0
|| pabyBuf[2] != 0x27
|| (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
{
- fclose( psSHP->fpSHP );
- fclose( psSHP->fpSHX );
- free( psSHP );
+ psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
+ psSHP->sHooks.FClose( psSHP->fpSHP );
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ free( psSHP );
- return( NULL );
+ return( NULL );
}
psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
- + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
+ + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
psSHP->nShapeType = pabyBuf[32];
if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
{
- /* this header appears to be corrupt. Give up. */
- fclose( psSHP->fpSHP );
- fclose( psSHP->fpSHX );
- free( psSHP );
+ char szError[200];
+
+ sprintf( szError,
+ "Record count in .shp header is %d, which seems\n"
+ "unreasonable. Assuming header is corrupt.",
+ psSHP->nRecords );
+ psSHP->sHooks.Error( szError );
+ psSHP->sHooks.FClose( psSHP->fpSHP );
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ free( psSHP );
+ free(pabyBuf);
- return( NULL );
+ return( NULL );
}
/* -------------------------------------------------------------------- */
@@ -517,26 +689,72 @@ SHPOpen( const char * pszLayer, const char * pszAccess )
/* -------------------------------------------------------------------- */
psSHP->nMaxRecords = psSHP->nRecords;
- psSHP->panRecOffset =
- (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
- psSHP->panRecSize =
- (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );
-
+ psSHP->panRecOffset = (unsigned int *)
+ malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
+ psSHP->panRecSize = (unsigned int *)
+ malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
- fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );
+
+ if (psSHP->panRecOffset == NULL ||
+ psSHP->panRecSize == NULL ||
+ pabyBuf == NULL)
+ {
+ char szError[200];
+
+ sprintf(szError,
+ "Not enough memory to allocate requested memory (nRecords=%d).\n"
+ "Probably broken SHP file",
+ psSHP->nRecords );
+ psSHP->sHooks.Error( szError );
+ psSHP->sHooks.FClose( psSHP->fpSHP );
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ if (psSHP->panRecOffset) free( psSHP->panRecOffset );
+ if (psSHP->panRecSize) free( psSHP->panRecSize );
+ if (pabyBuf) free( pabyBuf );
+ free( psSHP );
+ return( NULL );
+ }
+
+ if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )
+ != psSHP->nRecords )
+ {
+ char szError[200];
+
+ sprintf( szError,
+ "Failed to read all values for %d records in .shx file.",
+ psSHP->nRecords );
+ psSHP->sHooks.Error( szError );
+
+ /* SHX is short or unreadable for some reason. */
+ psSHP->sHooks.FClose( psSHP->fpSHP );
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ free( psSHP->panRecOffset );
+ free( psSHP->panRecSize );
+ free( pabyBuf );
+ free( psSHP );
+
+ return( NULL );
+ }
+
+ /* In read-only mode, we can close the SHX now */
+ if (strcmp(pszAccess, "rb") == 0)
+ {
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ psSHP->fpSHX = NULL;
+ }
for( i = 0; i < psSHP->nRecords; i++ )
{
- int32 nOffset, nLength;
+ int32 nOffset, nLength;
- memcpy( &nOffset, pabyBuf + i * 8, 4 );
- if( !bBigEndian ) SwapWord( 4, &nOffset );
+ memcpy( &nOffset, pabyBuf + i * 8, 4 );
+ if( !bBigEndian ) SwapWord( 4, &nOffset );
- memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
- if( !bBigEndian ) SwapWord( 4, &nLength );
+ memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
+ if( !bBigEndian ) SwapWord( 4, &nLength );
- psSHP->panRecOffset[i] = nOffset*2;
- psSHP->panRecSize[i] = nLength*2;
+ psSHP->panRecOffset[i] = nOffset*2;
+ psSHP->panRecSize[i] = nLength*2;
}
free( pabyBuf );
@@ -553,13 +771,14 @@ void SHPAPI_CALL
SHPClose(SHPHandle psSHP )
{
+ if( psSHP == NULL )
+ return;
+
/* -------------------------------------------------------------------- */
/* Update the header if we have modified anything. */
/* -------------------------------------------------------------------- */
if( psSHP->bUpdated )
- {
SHPWriteHeader( psSHP );
- }
/* -------------------------------------------------------------------- */
/* Free all resources, and close files. */
@@ -567,8 +786,9 @@ SHPClose(SHPHandle psSHP )
free( psSHP->panRecOffset );
free( psSHP->panRecSize );
- fclose( psSHP->fpSHX );
- fclose( psSHP->fpSHP );
+ if ( psSHP->fpSHX != NULL)
+ psSHP->sHooks.FClose( psSHP->fpSHX );
+ psSHP->sHooks.FClose( psSHP->fpSHP );
if( psSHP->pabyRec != NULL )
{
@@ -590,6 +810,9 @@ SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
{
int i;
+
+ if( psSHP == NULL )
+ return;
if( pnEntities != NULL )
*pnEntities = psSHP->nRecords;
@@ -617,9 +840,27 @@ SHPHandle SHPAPI_CALL
SHPCreate( const char * pszLayer, int nShapeType )
{
- char *pszBasename, *pszFullname;
+ SAHooks sHooks;
+
+ SASetupDefaultHooks( &sHooks );
+
+ return SHPCreateLL( pszLayer, nShapeType, &sHooks );
+}
+
+/************************************************************************/
+/* SHPCreate() */
+/* */
+/* Create a new shape file and return a handle to the open */
+/* shape file with read/write access. */
+/************************************************************************/
+
+SHPHandle SHPAPI_CALL
+SHPCreateLL( const char * pszLayer, int nShapeType, SAHooks *psHooks )
+
+{
+ char *pszBasename = NULL, *pszFullname = NULL;
int i;
- FILE *fpSHP, *fpSHX;
+ SAFile fpSHP = NULL, fpSHX = NULL;
uchar abyHeader[100];
int32 i32;
double dValue;
@@ -640,9 +881,9 @@ SHPCreate( const char * pszLayer, int nShapeType )
pszBasename = (char *) malloc(strlen(pszLayer)+5);
strcpy( pszBasename, pszLayer );
for( i = strlen(pszBasename)-1;
- i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
- && pszBasename[i] != '\\';
- i-- ) {}
+ i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
+ && pszBasename[i] != '\\';
+ i-- ) {}
if( pszBasename[i] == '.' )
pszBasename[i] = '\0';
@@ -652,23 +893,29 @@ SHPCreate( const char * pszLayer, int nShapeType )
/* -------------------------------------------------------------------- */
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
sprintf( pszFullname, "%s.shp", pszBasename );
- fpSHP = fopen(pszFullname, "wb" );
+ fpSHP = psHooks->FOpen(pszFullname, "wb" );
if( fpSHP == NULL )
- return( NULL );
+ {
+ psHooks->Error( "Failed to create file .shp file." );
+ goto error;
+ }
sprintf( pszFullname, "%s.shx", pszBasename );
- fpSHX = fopen(pszFullname, "wb" );
+ fpSHX = psHooks->FOpen(pszFullname, "wb" );
if( fpSHX == NULL )
- return( NULL );
+ {
+ psHooks->Error( "Failed to create file .shx file." );
+ goto error;
+ }
- free( pszFullname );
- free( pszBasename );
+ free( pszFullname ); pszFullname = NULL;
+ free( pszBasename ); pszBasename = NULL;
/* -------------------------------------------------------------------- */
/* Prepare header block for .shp file. */
/* -------------------------------------------------------------------- */
for( i = 0; i < 100; i++ )
- abyHeader[i] = 0;
+ abyHeader[i] = 0;
abyHeader[2] = 0x27; /* magic cookie */
abyHeader[3] = 0x0a;
@@ -694,7 +941,11 @@ SHPCreate( const char * pszLayer, int nShapeType )
/* -------------------------------------------------------------------- */
/* Write .shp file header. */
/* -------------------------------------------------------------------- */
- fwrite( abyHeader, 100, 1, fpSHP );
+ if( psHooks->FWrite( abyHeader, 100, 1, fpSHP ) != 1 )
+ {
+ psHooks->Error( "Failed to write .shp header." );
+ goto error;
+ }
/* -------------------------------------------------------------------- */
/* Prepare, and write .shx file header. */
@@ -703,15 +954,26 @@ SHPCreate( const char * pszLayer, int nShapeType )
ByteCopy( &i32, abyHeader+24, 4 );
if( !bBigEndian ) SwapWord( 4, abyHeader+24 );
- fwrite( abyHeader, 100, 1, fpSHX );
+ if( psHooks->FWrite( abyHeader, 100, 1, fpSHX ) != 1 )
+ {
+ psHooks->Error( "Failed to write .shx header." );
+ goto error;
+ }
/* -------------------------------------------------------------------- */
/* Close the files, and then open them as regular existing files. */
/* -------------------------------------------------------------------- */
- fclose( fpSHP );
- fclose( fpSHX );
+ psHooks->FClose( fpSHP );
+ psHooks->FClose( fpSHX );
- return( SHPOpen( pszLayer, "r+b" ) );
+ return( SHPOpenLL( pszLayer, "r+b", psHooks ) );
+
+error:
+ if (pszFullname) free(pszFullname);
+ if (pszBasename) free(pszBasename);
+ if (fpSHP) psHooks->FClose( fpSHP );
+ if (fpSHX) psHooks->FClose( fpSHX );
+ return NULL;
}
/************************************************************************/
@@ -785,9 +1047,9 @@ SHPComputeExtents( SHPObject * psObject )
SHPObject SHPAPI_CALL1(*)
SHPCreateObject( int nSHPType, int nShapeId, int nParts,
- int * panPartStart, int * panPartType,
- int nVertices, double * padfX, double * padfY,
- double * padfZ, double * padfM )
+ const int * panPartStart, const int * panPartType,
+ int nVertices, const double *padfX, const double *padfY,
+ const double * padfZ, const double * padfM )
{
SHPObject *psObject;
@@ -796,6 +1058,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
psObject->nSHPType = nSHPType;
psObject->nShapeId = nShapeId;
+ psObject->bMeasureIsUsed = FALSE;
/* -------------------------------------------------------------------- */
/* Establish whether this shape type has M, and Z values. */
@@ -835,7 +1098,7 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
psObject->nParts = MAX(1,nParts);
psObject->panPartStart = (int *)
- malloc(sizeof(int) * psObject->nParts);
+ calloc(sizeof(int), psObject->nParts);
psObject->panPartType = (int *)
malloc(sizeof(int) * psObject->nParts);
@@ -844,17 +1107,21 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
for( i = 0; i < nParts; i++ )
{
- psObject->panPartStart[i] = panPartStart[i];
+ if( psObject->panPartStart != NULL )
+ psObject->panPartStart[i] = panPartStart[i];
+
if( panPartType != NULL )
psObject->panPartType[i] = panPartType[i];
else
psObject->panPartType[i] = SHPP_RING;
}
+
+ if( psObject->panPartStart[0] != 0 )
+ psObject->panPartStart[0] = 0;
}
/* -------------------------------------------------------------------- */
-/* Capture vertices. Note that Z and M are optional, but X and */
-/* Y are not. */
+/* Capture vertices. Note that X, Y, Z and M are optional. */
/* -------------------------------------------------------------------- */
if( nVertices > 0 )
{
@@ -863,18 +1130,19 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
psObject->padfZ = (double *) calloc(sizeof(double),nVertices);
psObject->padfM = (double *) calloc(sizeof(double),nVertices);
- assert( padfX != NULL );
- assert( padfY != NULL );
-
for( i = 0; i < nVertices; i++ )
{
- psObject->padfX[i] = padfX[i];
- psObject->padfY[i] = padfY[i];
+ if( padfX != NULL )
+ psObject->padfX[i] = padfX[i];
+ if( padfY != NULL )
+ psObject->padfY[i] = padfY[i];
if( padfZ != NULL && bHasZ )
psObject->padfZ[i] = padfZ[i];
if( padfM != NULL && bHasM )
psObject->padfM[i] = padfM[i];
}
+ if( padfM != NULL && bHasM )
+ psObject->bMeasureIsUsed = TRUE;
}
/* -------------------------------------------------------------------- */
@@ -895,8 +1163,8 @@ SHPCreateObject( int nSHPType, int nShapeId, int nParts,
SHPObject SHPAPI_CALL1(*)
SHPCreateSimpleObject( int nSHPType, int nVertices,
- double * padfX, double * padfY,
- double * padfZ )
+ const double * padfX, const double * padfY,
+ const double * padfZ )
{
return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
@@ -914,7 +1182,8 @@ int SHPAPI_CALL
SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
{
- int nRecordOffset, i, nRecordSize;
+ unsigned int nRecordOffset, nRecordSize=0;
+ int i;
uchar *pabyRec;
int32 i32;
@@ -943,19 +1212,19 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
/* -------------------------------------------------------------------- */
if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords )
{
- psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
+ psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100);
- psSHP->panRecOffset = (int *)
- SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords );
- psSHP->panRecSize = (int *)
- SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords );
+ psSHP->panRecOffset = (unsigned int *)
+ SfRealloc(psSHP->panRecOffset,sizeof(unsigned int) * psSHP->nMaxRecords );
+ psSHP->panRecSize = (unsigned int *)
+ SfRealloc(psSHP->panRecSize,sizeof(unsigned int) * psSHP->nMaxRecords );
}
/* -------------------------------------------------------------------- */
/* Initialize record. */
/* -------------------------------------------------------------------- */
pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double)
- + psObject->nParts * 8 + 128);
+ + psObject->nParts * 8 + 128);
/* -------------------------------------------------------------------- */
/* Extract vertices for a Polygon or Arc. */
@@ -968,32 +1237,32 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
|| psObject->nSHPType == SHPT_ARCM
|| psObject->nSHPType == SHPT_MULTIPATCH )
{
- int32 nPoints, nParts;
- int i;
+ int32 nPoints, nParts;
+ int i;
- nPoints = psObject->nVertices;
- nParts = psObject->nParts;
+ nPoints = psObject->nVertices;
+ nParts = psObject->nParts;
- _SHPSetBounds( pabyRec + 12, psObject );
+ _SHPSetBounds( pabyRec + 12, psObject );
- if( bBigEndian ) SwapWord( 4, &nPoints );
- if( bBigEndian ) SwapWord( 4, &nParts );
+ if( bBigEndian ) SwapWord( 4, &nPoints );
+ if( bBigEndian ) SwapWord( 4, &nParts );
- ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
- ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
+ ByteCopy( &nPoints, pabyRec + 40 + 8, 4 );
+ ByteCopy( &nParts, pabyRec + 36 + 8, 4 );
nRecordSize = 52;
/*
* Write part start positions.
*/
- ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
+ ByteCopy( psObject->panPartStart, pabyRec + 44 + 8,
4 * psObject->nParts );
- for( i = 0; i < psObject->nParts; i++ )
- {
- if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
+ for( i = 0; i < psObject->nParts; i++ )
+ {
+ if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i );
nRecordSize += 4;
- }
+ }
/*
* Write multipatch part types if needed.
@@ -1012,19 +1281,19 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
/*
* Write the (x,y) vertex values.
*/
- for( i = 0; i < psObject->nVertices; i++ )
- {
- ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
- ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
+ for( i = 0; i < psObject->nVertices; i++ )
+ {
+ ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 );
+ ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 );
- if( bBigEndian )
+ if( bBigEndian )
SwapWord( 8, pabyRec + nRecordSize );
- if( bBigEndian )
+ if( bBigEndian )
SwapWord( 8, pabyRec + nRecordSize + 8 );
nRecordSize += 2 * 8;
- }
+ }
/*
* Write the Z coordinates (if any).
@@ -1052,13 +1321,14 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
/*
* Write the M values, if any.
*/
- if( psObject->nSHPType == SHPT_POLYGONM
- || psObject->nSHPType == SHPT_ARCM
+ if( psObject->bMeasureIsUsed
+ && (psObject->nSHPType == SHPT_POLYGONM
+ || psObject->nSHPType == SHPT_ARCM
#ifndef DISABLE_MULTIPATCH_MEASURE
- || psObject->nSHPType == SHPT_MULTIPATCH
+ || psObject->nSHPType == SHPT_MULTIPATCH
#endif
- || psObject->nSHPType == SHPT_POLYGONZ
- || psObject->nSHPType == SHPT_ARCZ )
+ || psObject->nSHPType == SHPT_POLYGONZ
+ || psObject->nSHPType == SHPT_ARCZ) )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1084,26 +1354,26 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
|| psObject->nSHPType == SHPT_MULTIPOINTZ
|| psObject->nSHPType == SHPT_MULTIPOINTM )
{
- int32 nPoints;
- int i;
+ int32 nPoints;
+ int i;
- nPoints = psObject->nVertices;
+ nPoints = psObject->nVertices;
_SHPSetBounds( pabyRec + 12, psObject );
- if( bBigEndian ) SwapWord( 4, &nPoints );
- ByteCopy( &nPoints, pabyRec + 44, 4 );
+ if( bBigEndian ) SwapWord( 4, &nPoints );
+ ByteCopy( &nPoints, pabyRec + 44, 4 );
- for( i = 0; i < psObject->nVertices; i++ )
- {
- ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
- ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
+ for( i = 0; i < psObject->nVertices; i++ )
+ {
+ ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 );
+ ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 );
- if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
- if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
- }
+ if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 );
+ if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 );
+ }
- nRecordSize = 48 + 16 * psObject->nVertices;
+ nRecordSize = 48 + 16 * psObject->nVertices;
if( psObject->nSHPType == SHPT_MULTIPOINTZ )
{
@@ -1123,8 +1393,9 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
}
}
- if( psObject->nSHPType == SHPT_MULTIPOINTZ
- || psObject->nSHPType == SHPT_MULTIPOINTM )
+ if( psObject->bMeasureIsUsed
+ && (psObject->nSHPType == SHPT_MULTIPOINTZ
+ || psObject->nSHPType == SHPT_MULTIPOINTM) )
{
ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1150,11 +1421,11 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
|| psObject->nSHPType == SHPT_POINTZ
|| psObject->nSHPType == SHPT_POINTM )
{
- ByteCopy( psObject->padfX, pabyRec + 12, 8 );
- ByteCopy( psObject->padfY, pabyRec + 20, 8 );
+ ByteCopy( psObject->padfX, pabyRec + 12, 8 );
+ ByteCopy( psObject->padfY, pabyRec + 20, 8 );
- if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
- if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
+ if( bBigEndian ) SwapWord( 8, pabyRec + 12 );
+ if( bBigEndian ) SwapWord( 8, pabyRec + 20 );
nRecordSize = 28;
@@ -1165,8 +1436,9 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
nRecordSize += 8;
}
- if( psObject->nSHPType == SHPT_POINTZ
- || psObject->nSHPType == SHPT_POINTM )
+ if( psObject->bMeasureIsUsed
+ && (psObject->nSHPType == SHPT_POINTZ
+ || psObject->nSHPType == SHPT_POINTM) )
{
ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 );
if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize );
@@ -1195,6 +1467,18 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
/* -------------------------------------------------------------------- */
if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
{
+ unsigned int nExpectedSize = psSHP->nFileSize + nRecordSize;
+ if( nExpectedSize < psSHP->nFileSize ) // due to unsigned int overflow
+ {
+ char str[128];
+ sprintf( str, "Failed to write shape object. "
+ "File size cannot reach %u + %u.",
+ psSHP->nFileSize, nRecordSize );
+ psSHP->sHooks.Error( str );
+ free( pabyRec );
+ return -1;
+ }
+
if( nShapeId == -1 )
nShapeId = psSHP->nRecords++;
@@ -1205,6 +1489,7 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
else
{
nRecordOffset = psSHP->panRecOffset[nShapeId];
+ psSHP->panRecSize[nShapeId] = nRecordSize-8;
}
/* -------------------------------------------------------------------- */
@@ -1225,10 +1510,15 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
/* -------------------------------------------------------------------- */
/* Write out record. */
/* -------------------------------------------------------------------- */
- if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0
- || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+ if( psSHP->sHooks.FSeek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 )
{
- printf( "Error in fseek() or fwrite().\n" );
+ psSHP->sHooks.Error( "Error in psSHP->sHooks.FSeek() while writing object to .shp file." );
+ free( pabyRec );
+ return -1;
+ }
+ if( psSHP->sHooks.FWrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 )
+ {
+ psSHP->sHooks.Error( "Error in psSHP->sHooks.Fwrite() while writing object to .shp file." );
free( pabyRec );
return -1;
}
@@ -1241,25 +1531,34 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
if( psSHP->adBoundsMin[0] == 0.0
&& psSHP->adBoundsMax[0] == 0.0
&& psSHP->adBoundsMin[1] == 0.0
- && psSHP->adBoundsMax[1] == 0.0
- && psObject->nSHPType != SHPT_NULL )
+ && psSHP->adBoundsMax[1] == 0.0 )
{
- psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
- psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
- psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
- psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+ if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 )
+ {
+ psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
+ psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
+ psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
+ psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
+ }
+ else
+ {
+ psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
+ psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
+ psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
+ psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
+ }
}
for( i = 0; i < psObject->nVertices; i++ )
{
- psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
- psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
- psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
- psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
- psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
- psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
- psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
- psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
+ psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]);
+ psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]);
+ psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]);
+ psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]);
+ psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]);
+ psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]);
+ psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]);
+ psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]);
}
return( nShapeId );
@@ -1276,7 +1575,9 @@ SHPObject SHPAPI_CALL1(*)
SHPReadObject( SHPHandle psSHP, int hEntity )
{
- SHPObject *psShape;
+ int nEntitySize, nRequiredSize;
+ SHPObject *psShape;
+ char szErrorMsg[128];
/* -------------------------------------------------------------------- */
/* Validate the record/entity number. */
@@ -1287,25 +1588,85 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* -------------------------------------------------------------------- */
/* Ensure our record buffer is large enough. */
/* -------------------------------------------------------------------- */
- if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize )
+ nEntitySize = psSHP->panRecSize[hEntity]+8;
+ if( nEntitySize > psSHP->nBufSize )
+ {
+ psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,nEntitySize);
+ if (psSHP->pabyRec == NULL)
+ {
+ char szError[200];
+
+ /* Reallocate previous successfull size for following features */
+ psSHP->pabyRec = (uchar *) malloc(psSHP->nBufSize);
+
+ sprintf( szError,
+ "Not enough memory to allocate requested memory (nBufSize=%d). "
+ "Probably broken SHP file", psSHP->nBufSize );
+ psSHP->sHooks.Error( szError );
+ return NULL;
+ }
+
+ /* Only set new buffer size after successfull alloc */
+ psSHP->nBufSize = nEntitySize;
+ }
+
+ /* In case we were not able to reallocate the buffer on a previous step */
+ if (psSHP->pabyRec == NULL)
{
- psSHP->nBufSize = psSHP->panRecSize[hEntity]+8;
- psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize);
+ return NULL;
}
/* -------------------------------------------------------------------- */
/* Read the record. */
/* -------------------------------------------------------------------- */
- fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 );
- fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );
+ if( psSHP->sHooks.FSeek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 )
+ {
+ /*
+ * TODO - mloskot: Consider detailed diagnostics of shape file,
+ * for example to detect if file is truncated.
+ */
+ char str[128];
+ sprintf( str,
+ "Error in fseek() reading object from .shp file at offset %u",
+ psSHP->panRecOffset[hEntity]);
+
+ psSHP->sHooks.Error( str );
+ return NULL;
+ }
+
+ if( psSHP->sHooks.FRead( psSHP->pabyRec, nEntitySize, 1, psSHP->fpSHP ) != 1 )
+ {
+ /*
+ * TODO - mloskot: Consider detailed diagnostics of shape file,
+ * for example to detect if file is truncated.
+ */
+ char str[128];
+ sprintf( str,
+ "Error in fread() reading object of size %u at offset %u from .shp file",
+ nEntitySize, psSHP->panRecOffset[hEntity] );
+
+ psSHP->sHooks.Error( str );
+ return NULL;
+ }
/* -------------------------------------------------------------------- */
/* Allocate and minimally initialize the object. */
/* -------------------------------------------------------------------- */
psShape = (SHPObject *) calloc(1,sizeof(SHPObject));
psShape->nShapeId = hEntity;
+ psShape->bMeasureIsUsed = FALSE;
+ if ( 8 + 4 > nEntitySize )
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nEntitySize = %d",
+ hEntity, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 );
+
if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
/* ==================================================================== */
@@ -1318,9 +1679,18 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
|| psShape->nSHPType == SHPT_ARCM
|| psShape->nSHPType == SHPT_MULTIPATCH )
{
- int32 nPoints, nParts;
- int i, nOffset;
+ int32 nPoints, nParts;
+ int i, nOffset;
+ if ( 40 + 8 + 4 > nEntitySize )
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nEntitySize = %d",
+ hEntity, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
/* -------------------------------------------------------------------- */
/* Get the X/Y bounds. */
/* -------------------------------------------------------------------- */
@@ -1329,30 +1699,79 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
/* -------------------------------------------------------------------- */
/* Extract part/point count, and build vertex and part arrays */
/* to proper size. */
/* -------------------------------------------------------------------- */
- memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
- memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
+ memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 );
+ memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 );
- if( bBigEndian ) SwapWord( 4, &nPoints );
- if( bBigEndian ) SwapWord( 4, &nParts );
+ if( bBigEndian ) SwapWord( 4, &nPoints );
+ if( bBigEndian ) SwapWord( 4, &nParts );
+
+ if (nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d.",
+ hEntity, nPoints, nParts);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+
+ /* With the previous checks on nPoints and nParts, */
+ /* we should not overflow here and after */
+ /* since 50 M * (16 + 8 + 8) = 1 600 MB */
+ nRequiredSize = 44 + 8 + 4 * nParts + 16 * nPoints;
+ if ( psShape->nSHPType == SHPT_POLYGONZ
+ || psShape->nSHPType == SHPT_ARCZ
+ || psShape->nSHPType == SHPT_MULTIPATCH )
+ {
+ nRequiredSize += 16 + 8 * nPoints;
+ }
+ if( psShape->nSHPType == SHPT_MULTIPATCH )
+ {
+ nRequiredSize += 4 * nParts;
+ }
+ if (nRequiredSize > nEntitySize)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d, nPoints=%d, nParts=%d, nEntitySize=%d.",
+ hEntity, nPoints, nParts, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
- psShape->nVertices = nPoints;
+ psShape->nVertices = nPoints;
psShape->padfX = (double *) calloc(nPoints,sizeof(double));
psShape->padfY = (double *) calloc(nPoints,sizeof(double));
psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
psShape->padfM = (double *) calloc(nPoints,sizeof(double));
- psShape->nParts = nParts;
+ psShape->nParts = nParts;
psShape->panPartStart = (int *) calloc(nParts,sizeof(int));
psShape->panPartType = (int *) calloc(nParts,sizeof(int));
+
+ if (psShape->padfX == NULL ||
+ psShape->padfY == NULL ||
+ psShape->padfZ == NULL ||
+ psShape->padfM == NULL ||
+ psShape->panPartStart == NULL ||
+ psShape->panPartType == NULL)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Not enough memory to allocate requested memory (nPoints=%d, nParts=%d) for shape %d. "
+ "Probably broken SHP file", hEntity, nPoints, nParts );
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
for( i = 0; i < nParts; i++ )
psShape->panPartType[i] = SHPP_RING;
@@ -1360,13 +1779,35 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* -------------------------------------------------------------------- */
/* Copy out the part array from the record. */
/* -------------------------------------------------------------------- */
- memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
- for( i = 0; i < nParts; i++ )
- {
- if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
- }
+ memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts );
+ for( i = 0; i < nParts; i++ )
+ {
+ if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i );
+
+ /* We check that the offset is inside the vertex array */
+ if (psShape->panPartStart[i] < 0
+ || (psShape->panPartStart[i] >= psShape->nVertices
+ && psShape->nVertices > 0) )
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : panPartStart[%d] = %d, nVertices = %d",
+ hEntity, i, psShape->panPartStart[i], psShape->nVertices);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+ if (i > 0 && psShape->panPartStart[i] <= psShape->panPartStart[i-1])
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : panPartStart[%d] = %d, panPartStart[%d] = %d",
+ hEntity, i, psShape->panPartStart[i], i - 1, psShape->panPartStart[i - 1]);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+ }
- nOffset = 44 + 8 + 4*nParts;
+ nOffset = 44 + 8 + 4*nParts;
/* -------------------------------------------------------------------- */
/* If this is a multipatch, we will also have parts types. */
@@ -1385,19 +1826,19 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* -------------------------------------------------------------------- */
/* Copy out the vertices from the record. */
/* -------------------------------------------------------------------- */
- for( i = 0; i < nPoints; i++ )
- {
- memcpy(psShape->padfX + i,
- psSHP->pabyRec + nOffset + i * 16,
- 8 );
+ for( i = 0; i < nPoints; i++ )
+ {
+ memcpy(psShape->padfX + i,
+ psSHP->pabyRec + nOffset + i * 16,
+ 8 );
- memcpy(psShape->padfY + i,
- psSHP->pabyRec + nOffset + i * 16 + 8,
- 8 );
+ memcpy(psShape->padfY + i,
+ psSHP->pabyRec + nOffset + i * 16 + 8,
+ 8 );
- if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
- if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
- }
+ if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+ if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+ }
nOffset += 16*nPoints;
@@ -1430,7 +1871,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* big enough, but really it will only occur for the Z shapes */
/* (options), and the M shapes. */
/* -------------------------------------------------------------------- */
- if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+ if( nEntitySize >= nOffset + 16 + 8*nPoints )
{
memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1444,8 +1885,8 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
}
+ psShape->bMeasureIsUsed = TRUE;
}
-
}
/* ==================================================================== */
@@ -1455,26 +1896,74 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
|| psShape->nSHPType == SHPT_MULTIPOINTM
|| psShape->nSHPType == SHPT_MULTIPOINTZ )
{
- int32 nPoints;
- int i, nOffset;
+ int32 nPoints;
+ int i, nOffset;
+
+ if ( 44 + 4 > nEntitySize )
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nEntitySize = %d",
+ hEntity, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+ memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
- memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
- if( bBigEndian ) SwapWord( 4, &nPoints );
+ if( bBigEndian ) SwapWord( 4, &nPoints );
+
+ if ( nPoints > 50 * 1000 * 1000)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nPoints = %d",
+ hEntity, nPoints);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
- psShape->nVertices = nPoints;
+ nRequiredSize = 48 + nPoints * 16;
+ if( psShape->nSHPType == SHPT_MULTIPOINTZ )
+ {
+ nRequiredSize += 16 + nPoints * 8;
+ }
+ if (nRequiredSize > nEntitySize)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nPoints = %d, nEntitySize = %d",
+ hEntity, nPoints, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+
+ psShape->nVertices = nPoints;
psShape->padfX = (double *) calloc(nPoints,sizeof(double));
psShape->padfY = (double *) calloc(nPoints,sizeof(double));
psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
psShape->padfM = (double *) calloc(nPoints,sizeof(double));
- for( i = 0; i < nPoints; i++ )
- {
- memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
- memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
+ if (psShape->padfX == NULL ||
+ psShape->padfY == NULL ||
+ psShape->padfZ == NULL ||
+ psShape->padfM == NULL)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Not enough memory to allocate requested memory (nPoints=%d) for shape %d. "
+ "Probably broken SHP file", hEntity, nPoints );
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+
+ for( i = 0; i < nPoints; i++ )
+ {
+ memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
+ memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );
- if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
- if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
- }
+ if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
+ if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
+ }
nOffset = 48 + 16*nPoints;
@@ -1486,10 +1975,10 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
- if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
+ if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );
/* -------------------------------------------------------------------- */
/* If we have a Z coordinate, collect that now. */
@@ -1518,7 +2007,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* big enough, but really it will only occur for the Z shapes */
/* (options), and the M shapes. */
/* -------------------------------------------------------------------- */
- if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
+ if( nEntitySize >= nOffset + 16 + 8*nPoints )
{
memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
@@ -1532,6 +2021,7 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
psSHP->pabyRec + nOffset + 16 + i*8, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
}
+ psShape->bMeasureIsUsed = TRUE;
}
}
@@ -1544,17 +2034,26 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
{
int nOffset;
- psShape->nVertices = 1;
+ psShape->nVertices = 1;
psShape->padfX = (double *) calloc(1,sizeof(double));
psShape->padfY = (double *) calloc(1,sizeof(double));
psShape->padfZ = (double *) calloc(1,sizeof(double));
psShape->padfM = (double *) calloc(1,sizeof(double));
- memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
- memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
+ if (20 + 8 + (( psShape->nSHPType == SHPT_POINTZ ) ? 8 : 0)> nEntitySize)
+ {
+ snprintf(szErrorMsg, sizeof(szErrorMsg),
+ "Corrupted .shp file : shape %d : nEntitySize = %d",
+ hEntity, nEntitySize);
+ psSHP->sHooks.Error( szErrorMsg );
+ SHPDestroyObject(psShape);
+ return NULL;
+ }
+ memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 );
+ memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 );
- if( bBigEndian ) SwapWord( 8, psShape->padfX );
- if( bBigEndian ) SwapWord( 8, psShape->padfY );
+ if( bBigEndian ) SwapWord( 8, psShape->padfX );
+ if( bBigEndian ) SwapWord( 8, psShape->padfY );
nOffset = 20 + 8;
@@ -1576,11 +2075,12 @@ SHPReadObject( SHPHandle psSHP, int hEntity )
/* big enough, but really it will only occur for the Z shapes */
/* (options), and the M shapes. */
/* -------------------------------------------------------------------- */
- if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 )
+ if( nEntitySize >= nOffset + 8 )
{
memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 );
if( bBigEndian ) SwapWord( 8, psShape->padfM );
+ psShape->bMeasureIsUsed = TRUE;
}
/* -------------------------------------------------------------------- */
@@ -1735,6 +2235,9 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
&& psObject->nSHPType != SHPT_POLYGONM )
return 0;
+ if( psObject->nVertices == 0 || psObject->nParts == 0 )
+ return 0;
+
/* -------------------------------------------------------------------- */
/* Process each of the rings. */
/* -------------------------------------------------------------------- */
@@ -1749,9 +2252,16 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
/* first ring is outer and all others are inner, but eventually */
/* we need to fix this to handle multiple island polygons and */
/* unordered sets of rings. */
+/* */
/* -------------------------------------------------------------------- */
- dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
- dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
+
+ /* Use point in the middle of segment to avoid testing
+ * common points of rings.
+ */
+ dfTestX = ( psObject->padfX[psObject->panPartStart[iOpRing]]
+ + psObject->padfX[psObject->panPartStart[iOpRing] + 1] ) / 2;
+ dfTestY = ( psObject->padfY[psObject->panPartStart[iOpRing]]
+ + psObject->padfY[psObject->panPartStart[iOpRing] + 1] ) / 2;
bInner = FALSE;
for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ )
@@ -1779,21 +2289,31 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
else
iNext = 0;
- if( (psObject->padfY[iEdge+nVertStart] < dfTestY
- && psObject->padfY[iNext+nVertStart] >= dfTestY)
- || (psObject->padfY[iNext+nVertStart] < dfTestY
- && psObject->padfY[iEdge+nVertStart] >= dfTestY) )
+ /* Rule #1:
+ * Test whether the edge 'straddles' the horizontal ray from the test point (dfTestY,dfTestY)
+ * The rule #1 also excludes edges collinear with the ray.
+ */
+ if ( ( psObject->padfY[iEdge+nVertStart] < dfTestY
+ && dfTestY <= psObject->padfY[iNext+nVertStart] )
+ || ( psObject->padfY[iNext+nVertStart] < dfTestY
+ && dfTestY <= psObject->padfY[iEdge+nVertStart] ) )
{
- if( psObject->padfX[iEdge+nVertStart]
- + (dfTestY - psObject->padfY[iEdge+nVertStart])
- / (psObject->padfY[iNext+nVertStart]
- - psObject->padfY[iEdge+nVertStart])
- * (psObject->padfX[iNext+nVertStart]
- - psObject->padfX[iEdge+nVertStart]) < dfTestX )
+ /* Rule #2:
+ * Test if edge-ray intersection is on the right from the test point (dfTestY,dfTestY)
+ */
+ double const intersect =
+ ( psObject->padfX[iEdge+nVertStart]
+ + ( dfTestY - psObject->padfY[iEdge+nVertStart] )
+ / ( psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart] )
+ * ( psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart] ) );
+
+ if (intersect < dfTestX)
+ {
bInner = !bInner;
- }
+ }
+ }
}
- }
+ } /* for iCheckRing */
/* -------------------------------------------------------------------- */
/* Determine the current order of this ring so we will know if */
@@ -1807,15 +2327,16 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject )
nVertCount = psObject->panPartStart[iOpRing+1]
- psObject->panPartStart[iOpRing];
- dfSum = 0.0;
- for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ )
+ if (nVertCount < 2)
+ continue;
+
+ dfSum = psObject->padfX[nVertStart] * (psObject->padfY[nVertStart+1] - psObject->padfY[nVertStart+nVertCount-1]);
+ for( iVert = nVertStart + 1; iVert < nVertStart+nVertCount-1; iVert++ )
{
- dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1]
- - psObject->padfY[iVert] * psObject->padfX[iVert+1];
+ dfSum += psObject->padfX[iVert] * (psObject->padfY[iVert+1] - psObject->padfY[iVert-1]);
}
- dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
- - psObject->padfY[iVert] * psObject->padfX[nVertStart];
+ dfSum += psObject->padfX[iVert] * (psObject->padfY[nVertStart] - psObject->padfY[iVert-1]);
/* -------------------------------------------------------------------- */
/* Reverse if necessary. */
diff --git a/src/drivers/BaseDriver.cc b/src/drivers/BaseDriver.cc
index 9eafa0b..a5920b0 100644
--- a/src/drivers/BaseDriver.cc
+++ b/src/drivers/BaseDriver.cc
@@ -442,7 +442,7 @@ double BaseDriver::LSF(MFloat *x,MFloat *y, int i0) const
else
{
angle=10.;
- MagLog::warning() << "BaseDriver: Devision through zero prevented in calculation of Label angle!" << endl;
+ MagLog::debug() << "BaseDriver: Devision through zero prevented in calculation of Label angle!" << endl;
}
return angle;
}
diff --git a/src/drivers/BaseDriverSymbols.h b/src/drivers/BaseDriverSymbols.h
index 0d338c9..e9dd4c1 100644
--- a/src/drivers/BaseDriverSymbols.h
+++ b/src/drivers/BaseDriverSymbols.h
@@ -253,7 +253,7 @@ MAGICS_NO_EXPORT void BaseDriver::renderSymbolItem(const SymbolItem& symbol, con
const MFloat pX = 1. / coordRatioX_;
const MFloat pY = 1. / coordRatioY_;
- MFloat scaling = convertCM(owner.getHeight()*1.5); // convertCM scales them up!
+ MFloat scaling = convertCM(symbol.height()*1.5); // convertCM scales them up!
const MFloat posX = owner[0].x() + ( symbol.x() * scaling * pX);
const MFloat posY = owner[0].y() + (setSymbolY(symbol.y()) * scaling * pY);
diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt
index 70eddc6..08e6930 100644
--- a/src/drivers/CMakeLists.txt
+++ b/src/drivers/CMakeLists.txt
@@ -19,7 +19,7 @@ list( APPEND _drivers_srcs
libimagequant/pngquant.c libimagequant/pngquant.h
)
-if( MAGICS_QT )
+if( qt )
list( APPEND _drivers_srcs
QtDriver.h QtDriver.cc
MgQ/MgQ.h
@@ -52,11 +52,17 @@ if( HAVE_CAIRO )
list( APPEND _drivers_srcs CairoDriver.h CairoDriver.cc )
endif()
-if ( HAVE_METVIEW )
+if ( metview )
list (APPEND metview_include
drivers/DriverManager.h
drivers/BaseDriver.h
${CMAKE_CURRENT_BINARY_DIR}/../params/BaseDriverAttributes.h
+ )
+ set( metview_include ${metview_include} PARENT_SCOPE )
+endif()
+
+if ( qt )
+ list (APPEND metview_include
drivers/MgQ/MgQPlotScene.h
drivers/MgQ/MgQScene.h
drivers/QtDriver.h
@@ -70,6 +76,7 @@ if ( HAVE_METVIEW )
set( metview_include ${metview_include} PARENT_SCOPE )
endif()
+
if( MAGICS_RASTER )
list( APPEND _drivers_srcs GDDriver.h GDDriver.cc )
endif()
diff --git a/src/drivers/CairoDriver.cc b/src/drivers/CairoDriver.cc
index 881f59a..0782e56 100644
--- a/src/drivers/CairoDriver.cc
+++ b/src/drivers/CairoDriver.cc
@@ -42,7 +42,7 @@ Something like:
Started: Mon Oct 15 20:49:32 2007
- \todo Fix 'convert' dependency
+ \todo Fix 'convert' dependency in "renderImage"
\todo Check how much drivers are dependent on writing temp files in local directory (thread safety)
*/
#include <cairo.h>
@@ -271,7 +271,7 @@ void CairoDriver::setupNewSurface() const
const SystemInfo info;
const string s1 = "%%Title: " + title_;
cairo_ps_surface_dsc_comment (surface_, s1.c_str());
- const string s2 = "%%Creator2: " + getMagicsVersionString();
+ const string s2 = "%%Creator2: "+ output_creator_+ " "+ getMagicsVersionString();
cairo_ps_surface_dsc_comment (surface_, s2.c_str());
const string s3 = "%%For: " + info.getUserID() + "@" + info.getHostName() + " " + info.getUserName();
cairo_ps_surface_dsc_comment (surface_, s3.c_str());
@@ -539,8 +539,8 @@ MAGICS_NO_EXPORT void CairoDriver::write_tiff() const
// DPI
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
- TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float) resolution_);
- TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float) resolution_);
+ TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float) 90.;// resolution_);
+ TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float) 90.;// resolution_);
unsigned char *buf;
if (TIFFScanlineSize(tif))
@@ -1579,10 +1579,10 @@ void CairoDriver::print(ostream& out) const
MAGICS_NO_EXPORT void CairoDriver::renderSymbols(const Symbol& symbol) const
{
debugOutput("Start CairoDriver Symbols");
-/*
+
if(symbol.getSymbol()=="logo_ecmwf")
{
- const string logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "ecmwf_logo.png";
+ const string logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "ecmwf_logo_2014.png";
cairo_surface_t *image = cairo_image_surface_create_from_png(logofile.c_str());
if(image)
@@ -1592,8 +1592,8 @@ MAGICS_NO_EXPORT void CairoDriver::renderSymbols(const Symbol& symbol) const
int h = cairo_image_surface_get_height(image);
cairo_translate (cr_, projectX(symbol[0].x()), projectY(symbol[0].y()));
- const MFloat scaling = convertCM(symbol.getHeight()*.5) / coordRatioY_;
-// cairo_scale (cr_, 0.3, 0.3);
+ const MFloat scaling = convertCM(symbol.getHeight()*.1) / coordRatioY_;
+ cairo_scale (cr_, 0.1, 0.1);
cairo_set_source_surface(cr_, image, w*scaling, h*scaling);
cairo_paint(cr_);
@@ -1602,9 +1602,8 @@ MAGICS_NO_EXPORT void CairoDriver::renderSymbols(const Symbol& symbol) const
}
else MagLog::warning() << "CairoDriver-> Could NOT read the logo file "<< logofile << " !" << endl;
}
-// else if(symbol.getSymbol().compare(0,7,"magics_")==0 )
else
-*/ {
+ {
BaseDriver::renderSymbols(symbol);
}
}
diff --git a/src/drivers/KMLDriver.cc b/src/drivers/KMLDriver.cc
index 55522b4..5f2b6d7 100755
--- a/src/drivers/KMLDriver.cc
+++ b/src/drivers/KMLDriver.cc
@@ -124,7 +124,9 @@ void KMLDriver::open()
<< " xmlns:atom=\"http://www.w3.org/2005/Atom\">\n"
<< "<Document>\n"<< " <name>"<<title_<<"</name>\n"
<< " <open>1</open>\n";
- pFile_ << " <atom:generator>"<<getMagicsVersionString()<<"</atom:generator>\n";
+ pFile_ << " <atom:generator>";
+ if(!output_creator_.empty()) pFile_ <<output_creator_<<" using ";
+ pFile_ <<getMagicsVersionString()<<"</atom:generator>\n";
if(!author_.empty()) pFile_ << " <atom:author><atom:name>"<<author_<<"</atom:name></atom:author>\n";
if(!link_.empty()) pFile_ << " <atom:link href=\""<<link_<<"\" />\n";
pFile_ << " <description>\n"
@@ -167,13 +169,13 @@ void KMLDriver::close()
if(ecmwf_logo_)
{
- const string logofilename = "kml_logo.png";
+ const string logofilename = "kml_logo_2014.png";
const string logofile = path + logofilename;
is_copied = copy_file(logofile,logofilename);
if(is_copied) kml_output_resource_list_.push_back(logofilename);
pFile_ << "<ScreenOverlay id=\"logo\">\n"
- << "<name>MagLogo</name>\n"
+ << "<name>MagicsLogo</name>\n"
<< "<Icon>\n"
<< " <href>"<<logofilename<<"</href>\n"
<< "</Icon>\n"
diff --git a/src/drivers/PostScriptDriver.cc b/src/drivers/PostScriptDriver.cc
index 805adab..3c6b9ed 100644
--- a/src/drivers/PostScriptDriver.cc
+++ b/src/drivers/PostScriptDriver.cc
@@ -1514,8 +1514,9 @@ MAGICS_NO_EXPORT void PostScriptDriver::writePSFileHeader() const
*ps << "%!PS-Adobe-3.0";
if(isEPS()) *ps << " EPSF-3.0";
- *ps << "\n%%Title: "<< title_
- << "\n%%Creator: "<< getMagicsVersionString() <<"\n%%CreationDate: " << info.getTime()
+ *ps << "\n%%Title: "<< title_<< "\n%%Creator: ";
+ if(!output_creator_.empty()) *ps << output_creator_<< " and ";
+ *ps << getMagicsVersionString() <<"\n%%CreationDate: " << info.getTime()
<< "\n%%For: " << info.getUserID() << "@" << info.getHostName() << " " << info.getUserName()<<"\n";
MFloat dimensionX = getXDeviceLength() * 72. / 2.54; // 72 = points / inch
diff --git a/src/drivers/QtDriver.cc b/src/drivers/QtDriver.cc
index 3b5a1d5..a332c02 100644
--- a/src/drivers/QtDriver.cc
+++ b/src/drivers/QtDriver.cc
@@ -2137,7 +2137,7 @@ void QtDriver::executeStep(int step,MgQLayerItem *layerItem) const
scene->currentSceneItem()->sceneLayerItem()->sceneLayer().execute(&layerItem->layer(),step,*this);
//layerItem->layer().execute(step,*this);
-"",
+
currentItem_=prevItem;
layoutItemStack_.pop();
diff --git a/src/drivers/SVGDriver.cc b/src/drivers/SVGDriver.cc
index d8c5215..06b5ef3 100644
--- a/src/drivers/SVGDriver.cc
+++ b/src/drivers/SVGDriver.cc
@@ -166,17 +166,18 @@ MAGICS_NO_EXPORT void SVGDriver::startPage() const
if(!desc_.empty()) pFile_<< "<desc>"<<desc_<<"</desc>\n";
const SystemInfo info;
- pFile_<< "<metadata id=\"MAGICSmetadata\">\n<rdf:RDF><cc:Work rdf:about=\"\">\n"
- << "\t<dc:format>image/svg+xml</dc:format>\n"
- << "\t<dc:title>"<<title_<<"</dc:title>\n"
- << "\t<dc:creator><cc:Agent><dc:title>"<<info.getUserID()<<" on "<<info.getHostName()<<"</dc:title></cc:Agent></dc:creator>\n"
- << "\t<dc:date>"<<info.getTime()<<"</dc:date>\n"
- << "\t<dc:language>en-GB</dc:language>\n"
- << "\t<dc:description>Meteorological plot generated by "<<getMagicsVersionString()<<"</dc:description>\n"
- << "\t<dc:publisher><cc:Agent>\n"
- << "\t <dc:title>"<<getMagicsVersionString()<<"</dc:title>\n"
- << "\t</cc:Agent></dc:publisher>\n"
- << "\t<dc:coverage>Plot of meteorological data</dc:coverage>\n";
+ pFile_ << "<metadata id=\"MAGICSmetadata\">\n<rdf:RDF><cc:Work rdf:about=\"\">\n"
+ << "\t<dc:format>image/svg+xml</dc:format>\n"
+ << "\t<dc:title>"<<title_<<"</dc:title>\n"
+ << "\t<dc:author>"<<info.getUserID()<<" on "<<info.getHostName()<<"</dc:author>\n"
+ << "\t<dc:date>"<<info.getTime()<<"</dc:date>\n"
+ << "\t<dc:language>en-GB</dc:language>\n";
+ if(!desc_.empty()) pFile_ << "\t<dc:description>"<<desc_<<"</dc:description>\n";
+ if(!output_creator_.empty()) pFile_ << "\t<dc:creator><cc:Agent><dc:title>"<<output_creator_<<"</dc:title></cc:Agent></dc:creator>\n";
+ pFile_ << "\t<dc:publisher><cc:Agent>\n"
+ << "\t <dc:title>"<<getMagicsVersionString()<<"</dc:title>\n"
+ << "\t</cc:Agent></dc:publisher>\n"
+ << "\t<dc:coverage>Plot of meteorological data</dc:coverage>\n";
if(!meta_.empty()) pFile_<< "<!-- \n"<<meta_<<"\n-->\n";
pFile_<<"</cc:Work></rdf:RDF>\n</metadata>\n";
/*
@@ -1052,8 +1053,8 @@ MAGICS_NO_EXPORT void SVGDriver::renderText(const Text& text) const
}
else
{
- pFile_ <<"<tspan "
- <<"font-size=\""<<dheight<<"cm\" font-family=\""<< ttf << "\" ";
+ pFile_ <<"<tspan dominant-baseline=\""<<verticalJustification<< "\""
+ <<" font-size=\""<<dheight<<"cm\" font-family=\""<< ttf << "\" ";
if(styles.find("bolditalic") != styles.end()) pFile_ <<"font-weight=\"bold\" font-style=\"italic\" ";
else if(styles.find("bold") != styles.end()) pFile_ <<"font-weight=\"bold\" ";
else if(styles.find("italic")!= styles.end()) pFile_ <<"font-style=\"italic\" ";
@@ -1103,10 +1104,12 @@ MAGICS_NO_EXPORT void SVGDriver::circle(const MFloat x, const MFloat y, const MF
else
{
const short i = (s<4) ? 1 : 0;
- const double rad = s*0.7853981634*r;
- pFile_ << "<path d=\"M"<<cx<<" "<<cy-r<<" A"<<r<<","<<r<<" 0 "<<i<<" 1 "
- << cx+cos(rad)<<" "<<cy+sin(rad)<<"\" "
- << "fill=\"rgb("
+ const double rad = s*0.7853981634;
+
+ if(s==2) pFile_ << "<path d=\"M"<<cx<<" "<<cy-r<<" v"<<r<<" h"<<r<<" a"<<r<<","<<r<<" 0 0 0 "<< -r<<","<<-r<<"\" ";
+ else if(s==4) pFile_ << "<path d=\"M"<<cx<<" "<<cy-r<<" v"<<2*r<<" a"<<r<<","<<r<<" 0 0 0 "<< 0<<","<<-2*r<<"\" ";
+ else if(s==6) pFile_ << "<path d=\"M"<<cx<<" "<<cy-r<<" v"<<r<<" h"<<-r<<" a"<<r<<","<<r<<" 1 1 0 "<< r<<","<<-r<<"\" ";
+ pFile_ << "fill=\"rgb("
<< static_cast<int>(currentColour_.red() *255) << ","
<< static_cast<int>(currentColour_.green()*255) << ","
<< static_cast<int>(currentColour_.blue() *255) << ")\""
@@ -1140,7 +1143,7 @@ MAGICS_NO_EXPORT void SVGDriver::circle(const MFloat x, const MFloat y, const MF
<< static_cast<int>(currentColour_.blue() *255) << ")\"";
openGroup(stream.str());
pFile_ << "<circle cx=\""<<cx<<"\" cy=\""<<cy<<"\" r=\""<<r<<"\"/>\n"
- << "<polyline points=\"0,"<<r*.9<<" 0,"<<-r*.9<<"\" width=\"2\" stroke=\"white\" fill=\"white\"/>"<< std::endl;
+ << "<polyline points=\""<<cx<<","<<cy+(r*.9)<<" "<<cx<<","<<cy-(r*.9)<<"\" width=\"2\" stroke=\"white\" fill=\"white\"/>"<< std::endl;
}
}
@@ -1476,24 +1479,40 @@ MAGICS_NO_EXPORT void SVGDriver::renderSymbols(const Symbol& symbol) const
debugOutput("Symbols - START");
closeGroup();
- const string location = logoLocation_;
-
- if(symbol.getSymbol()=="logo_ecmwf" && !magCompare(location,"INLINE") )
+ if(symbol.getSymbol()=="logo_ecmwf")
{
- if(inkscape_) pFile_ << "<g inkscape:groupmode=\"layer\" inkscape:label=\"ECMWF_logo\">\n"
+ if(inkscape_) pFile_ << "<g inkscape:groupmode=\"layer\" inkscape:label=\"ECMWF_logo\">\n"
<< " <title>ECMWF_logo</title>\n";
-
const MFloat x = projectX(symbol[0].x());
const MFloat y = projectY(symbol[0].y());
- string logofile;
- if(magCompare(location,"LOCAL")) logofile = "ecmwf_logo.png";
- else logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "ecmwf_logo.png";
- svg_output_resource_list_.push_back(logofile);
- pFile_ << "<a xlink:href=\"http://www.ecmwf.int\">"
+ if(!magCompare(logoLocation_,"INLINE") )
+ {
+ string logofile;
+ if(magCompare(logoLocation_,"LOCAL")) logofile = "ecmwf_logo.png";
+ else logofile = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "ecmwf_logo.png";
+ svg_output_resource_list_.push_back(logofile);
+ pFile_ << "<a xlink:href=\"http://www.ecmwf.int\">"
<< "<image x=\""<<x-(y*1.35)<<"\" y=\""<<setY(y+(y*.5))<<"\" width=\""<<y*5.4<<"\" height=\""<<y<<"\" xlink:href=\""<<logofile<<"\" />"
<< "</a>\n";
- if(inkscape_) pFile_ << "</g>\n";
+ }
+ else
+ {
+ pFile_ << "<g transform=\"translate("<<x-(y*1.35)<<","<<setY(y+(y*.5))<<")\">\n";
+ const string s = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "ecmwf_logo_2014.svg";
+ ifstream psfile(s.c_str());
+
+ if(!psfile){
+ MagLog::error() << "PostScriptDriver::copyMacro() --> Cannot open PostScript Macro file! " << s <<
+ " Is MAGPLUS_HOME set correctly?\n";
+ return;
+ }
+ char ch;
+ while (psfile.get(ch)){pFile_.put(ch);}
+ psfile.close();
+ pFile_ << "</g>\n";
+ }
+ if(inkscape_) pFile_ << "</g><!-- Logo end -->\n";
}
else
BaseDriver::renderSymbols(symbol);
diff --git a/src/drivers/libimagequant/CHANGELOG b/src/drivers/libimagequant/CHANGELOG
new file mode 100644
index 0000000..4714caa
--- /dev/null
+++ b/src/drivers/libimagequant/CHANGELOG
@@ -0,0 +1,130 @@
+version 2.5
+-----------
+ - replaced color search algorithm with vantage point tree, which is much faster and more reliable
+ - deprecated IE6 workaround
+
+version 2.4
+-----------
+ - fixed remapping of bright colors when dithering
+ - added libimagequant API to add fixed preset colors to the palette
+
+version 2.3
+-----------
+ - added ./configure script for better support of Intel C compiler and dependencies [thanks to pdknsk]
+ - tweaked quality metric to better estimate quality of images with large solid backgrounds [thanks to Rolf Timmermans]
+ - atomic file saves and fixed --skip-if-larger
+ - avoid applying quality setting to images that use palette already
+ - preserving standard PNG chunks (requires libpng 1.6)
+ - deprecated libpng 1.2 support
+
+version 2.2
+-----------
+ - preserving of unknown PNG chunks (enables optimized Android 9-patch images)
+ - improved color profile support: cHRM & gAMA as alternative to ICC profiles, OpenMP acceleration
+ - improved support for Intel C Compiler, speedup in 32-bit GCC, and some workarounds for Visual Studio's incomplete C support
+
+version 2.1
+-----------
+ - option to save files only if they're compressed better than the original
+ - option to generate posterized output (for use with 16-bit textures)
+ - support for ICC profiles via Little CMS library
+
+version 2.0
+-----------
+ - refactored codebase into pngquant and standalone libimagequant
+ - reduced memory usage by further 30% (and more for very large images)
+ - less precise remapping improving speed by 25% in higher speed settings
+ - --output option for writing converted file under the given path
+ - light dithering with --floyd=0.5
+ - fixed regression in dithering of alpha channel
+
+version 1.8
+-----------
+ - min/max quality option (number of colors is automatically adjusted for desired quality level)
+ - switched option parsing to getopt_long (syntax such as -s1 and --ext=ext is supported)
+ - significantly improved performance thanks to custom partial sorting
+ - optional Cocoa (Mac OS X) image reader for color profile support
+ - reduced memory usage by 20%
+ - remapping improved for very low number of colors
+
+version 1.7
+-----------
+ - new, accurate RGBA color similarity algorithm
+ - change of optional SSE3 code to SSE2 that is always enabled on x86-64
+ - optional OpenMP-based parallelisation of remapping
+ - changed long options to use double hyphen (-force to --force) [thanks to Jari Aalto]
+
+version 1.6
+-----------
+ - novel dithering algorithm that doesn't add noise unless necessary
+ - perceptual weighting of colors taking into account edges and noise
+ - much faster remapping
+ - improved portability, makefiles and man page
+
+version 1.5
+-----------
+ - palettes postprocessed with Voronoi iteration
+ - better RGBA color similarity algorithm and Floyd-Steinberg remapping
+ - SSE optimisations
+
+version 1.4
+-----------
+ - median cut is applied many times in a feedback loop
+ - speed/quality trade-off option
+ - faster remap of transparent areas
+
+version 1.3
+-----------
+ - significant changes to the algorithm: use of variance
+ to find largest dimensioin and to split most varying boxes
+ - use of premultiplied alpha for color blending
+ - conversion of output to gamma 2.2
+
+version 1.2
+-----------
+ - color computation done in floating point
+ - gamma correction applied
+ - dropped support for very old systems & compilers
+
+version 1.1
+-----------
+ - alpha-sensitive color reduction and dithering
+ - support -- and - arguments in command line
+ - number of colors optional (defaults to 256)
+ - increased maximum number of colors in histogram
+
+version 1.0
+-----------
+ - cleaned up Makefile.unx (better gcc optimizations, "clean" target)
+ - recompiled binaries with zlib 1.1.4
+
+version 0.95
+------------
+ - fixed Win32 filter bug (binary mode for stdin/stdout)
+ - fixed cosmetic "choosing colors" verbosity buglet
+ - fixed palette-size bug when number of colors in image < number requested
+ - fixed sample-depth bug (png_set_packing() not retroactively smart)
+
+version 0.91
+------------
+ - fixed some verbose/non-verbose oopers
+ - fixed Win32 (MSVC) portability issues (getpid(), random(), srandom())
+ - added Makefile.w32 for MSVC (tested with 5.0)
+
+version 0.90
+------------
+ - added support for multiple files on command line
+ - changed stdin support to write PNG stream to stdout (not "stdin-fs8.png")
+
+version 0.75
+------------
+ - added support for any type of input file [Glenn Randers-Pehrson]
+ - fixed palette-(re)scaling bug
+ - added -verbose and -quiet options (default now is -quiet)
+ - added palette-remapping to minimize size of tRNS chunk
+ - made Floyd-Steinberg dithering default
+ - changed output naming scheme to -fs8.png and -or8.png (FS or ordered dither)
+
+version 0.70
+------------
+ - first public release
diff --git a/src/drivers/libimagequant/COPYRIGHT b/src/drivers/libimagequant/COPYRIGHT
index 98de36b..20ac3db 100644
--- a/src/drivers/libimagequant/COPYRIGHT
+++ b/src/drivers/libimagequant/COPYRIGHT
@@ -1,5 +1,5 @@
© 1997-2002 by Greg Roelofs; based on an idea by Stefan Schneider.
-© 2009-2014 by Kornel Lesiński.
+© 2009-2015 by Kornel Lesiński.
All rights reserved.
diff --git a/src/drivers/libimagequant/MANUAL.md b/src/drivers/libimagequant/MANUAL.md
index 5eed37a..56c6ddb 100644
--- a/src/drivers/libimagequant/MANUAL.md
+++ b/src/drivers/libimagequant/MANUAL.md
@@ -16,7 +16,7 @@ Files needed for the library are only in the `lib/` directory inside the reposit
## Compiling and Linking
-The library can be linked with ANSI C and C++ programs. It has no external dependencies.
+The library can be linked with ANSI C, C++ and [Rust](https://crates.io/crates/imagequant/) programs. It has no external dependencies.
To build on Unix-like systems run:
@@ -32,6 +32,9 @@ Alternatively you can compile the library with your program simply by including
gcc -std=c99 -O3 -DNDEBUG lib/*.c yourprogram.c
+In [Rust](https://github.com/pornel/libimagequant-rust),
+if using Cargo, add `imagequant` to dependencies.
+
### Compiling on Windows/Visual Studio
The library can be compiled with any C compiler that has at least basic support for C99 (GCC, clang, ICC, C++ Builder, even Tiny C Compiler), but Visual Studio 2012 and older are not up to date with the 1999 C standard. There are 2 options for using `libimagequant` on Windows:
@@ -56,13 +59,13 @@ Please note that libimagequant only handles raw uncompressed bitmaps in memory a
#include "lib/libimagequant.h"
liq_attr *attr = liq_attr_create();
- liq_image *image = liq_image_create_rgba(attr, bitmap, width, height, 0);
+ liq_image *image = liq_image_create_rgba(attr, bitmap_rgba, width, height, 0);
liq_result *res = liq_quantize_image(attr, image);
- liq_write_remapped_image(res, image, bitmap, bitmap_size);
+ liq_write_remapped_image(res, image, bitmap_8bpp, bitmap_size);
const liq_palette *pal = liq_get_palette(res);
- // use image and palette here
+ // save image and palette here
liq_attr_destroy(attr);
liq_image_destroy(image);
@@ -198,7 +201,9 @@ Returns `LIQ_VALUE_OUT_OF_RANGE` if the dithering level is outside the 0-1 range
liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size);
-Remaps the image to palette and writes its pixels to the given buffer, 1 pixel per byte. Buffer must be large enough to fit the entire image, i.e. width×height bytes large. For safety, pass size of the buffer as `buffer_size`.
+Remaps the image to palette and writes its pixels to the given buffer, 1 pixel per byte.
+
+The buffer must be large enough to fit the entire image, i.e. width×height bytes large. For safety, pass the size of the buffer as `buffer_size`.
For best performance call `liq_get_palette()` *after* this function, as palette is improved during remapping.
@@ -211,9 +216,11 @@ Returns `LIQ_BUFFER_TOO_SMALL` if given size of the buffer is not enough to fit
// save image
}
-See `liq_get_palette()` and `liq_write_remapped_image_rows()`.
+See `liq_get_palette()`.
+
+The buffer is assumed to be contiguous, with rows ordered from top to bottom, and no gaps between rows. If you need to write rows with padding or upside-down order, then use `liq_write_remapped_image_rows()`.
-Please note that it only writes raw uncompressed pixels to memory. It does not perform any compression. If you'd like to create a PNG file then you need to pass the raw pixel data to another library, e.g. libpng or lodepng. See `rwpng.c` in `pngquant` project for an example how to do that.
+Please note that it only writes raw uncompressed pixels to memory. It does not perform any PNG compression. If you'd like to create a PNG file then you need to pass the raw pixel data to another library, e.g. libpng or lodepng. See `rwpng.c` in `pngquant` project for an example how to do that.
----
@@ -268,7 +275,7 @@ Returns the value set by `liq_set_speed()`.
liq_error liq_set_min_opacity(liq_attr* attr, int min);
-Alpha values higher than this will be rounded to opaque. This is a workaround for Internet Explorer 6 that truncates semitransparent values to completely transparent. The default is `255` (no change). 238 is a suggested value.
+Alpha values higher than this will be rounded to opaque. This is a workaround for Internet Explorer 6, but because this browser is not used any more, this option is deprecated and will be removed. The default is `255` (no change).
Returns `LIQ_VALUE_OUT_OF_RANGE` if the value is outside the 0-255 range.
@@ -364,11 +371,19 @@ Returns `LIQ_INVALID_POINTER` if `result` or `input_image` is `NULL`.
double liq_get_quantization_error(liq_result *result);
-Returns mean square error of quantization (square of difference between pixel values in the original image and remapped image). Alpha channel and gamma correction are taken into account, so the result isn't exactly the mean square error of all channels.
+Returns mean square error of quantization (square of difference between pixel values in the source image and its remapped version). Alpha channel, gamma correction and approximate importance of pixels is taken into account, so the result isn't exactly the mean square error of all channels.
For most images MSE 1-5 is excellent. 7-10 is OK. 20-30 will have noticeable errors. 100 is awful.
-This function should be called *after* `liq_write_remapped_image()`. It may return `-1` if the value is not available (this is affected by `liq_set_speed()` and `liq_set_quality()`).
+This function may return `-1` if the value is not available (this happens when a high speed has been requested, the image hasn't been remapped yet, and quality limit hasn't been set, see `liq_set_speed()` and `liq_set_quality()`). The value is not updated when multiple images are remapped, it applies only to the image used in `liq_quantize_image()` or the first image that has been remapped. See `liq_get_remapping_error()`.
+
+----
+
+ double liq_get_remapping_error(liq_result *result);
+
+Returns mean square error of last remapping done (square of difference between pixel values in the remapped image and its remapped version). Alpha channel and gamma correction are taken into account, so the result isn't exactly the mean square error of all channels.
+
+This function may return `-1` if the value is not available (this happens when a high speed has been requested or the image hasn't been remapped yet).
----
@@ -376,7 +391,7 @@ This function should be called *after* `liq_write_remapped_image()`. It may retu
Analoguous to `liq_get_quantization_error()`, but returns quantization error as quality value in the same 0-100 range that is used by `liq_set_quality()`.
-This function should be called *after* `liq_write_remapped_image()`. It may return `-1` if the value is not available (this is affected by `liq_set_speed()` and `liq_set_quality()`).
+It may return `-1` if the value is not available (see note in `liq_get_quantization_error()`).
This function can be used to add upper limit to quality options presented to the user, e.g.
@@ -395,6 +410,12 @@ This function can be used to add upper limit to quality options presented to the
----
+ double liq_get_remapping_quality(liq_result *result);
+
+Analoguous to `liq_get_remapping_error()`, but returns quantization error as quality value in the same 0-100 range that is used by `liq_set_quality()`.
+
+----
+
void liq_set_log_callback(liq_attr*, liq_log_callback_function*, void *user_info);
<p>
@@ -450,6 +471,18 @@ If the input is invalid, these all return -1.
---
+ liq_error liq_image_add_fixed_color(liq_image* img, liq_color color);
+
+Reserves a color in the output palette created from this image. It behaves as if the given color was used in the image and was very important.
+
+RGB values of `liq_color` are assumed to have the same gamma as the image.
+
+It must be called before the image is quantized.
+
+Returns error if more than 256 colors are added. If image is quantized to fewer colors than the number of fixed colors added, then excess fixed colors will be ignored.
+
+---
+
int liq_version();
Returns version of the library as an integer. Same as `LIQ_VERSION`. Human-readable version is defined as `LIQ_VERSION_STRING`.
diff --git a/src/drivers/libimagequant/Makefile b/src/drivers/libimagequant/Makefile
index 284e745..e4c5693 100644
--- a/src/drivers/libimagequant/Makefile
+++ b/src/drivers/libimagequant/Makefile
@@ -10,8 +10,6 @@ DLLDEF=libimagequant_dll.def
OBJS = pam.o mediancut.o blur.o mempool.o viter.o nearest.o libimagequant.o
SHAREDOBJS = $(subst .o,.lo,$(OBJS))
-BUILD_CONFIGURATION="$(CC) $(CFLAGS) $(LDFLAGS)"
-
DISTFILES = $(OBJS:.o=.c) *.h MANUAL.md COPYRIGHT Makefile configure
TARNAME = libimagequant-$(VERSION)
TARFILE = $(TARNAME)-src.tar.bz2
diff --git a/src/drivers/libimagequant/blur.c b/src/drivers/libimagequant/blur.c
index 9158ad4..2e50d23 100644
--- a/src/drivers/libimagequant/blur.c
+++ b/src/drivers/libimagequant/blur.c
@@ -1,3 +1,8 @@
+/*
+** © 2011-2015 by Kornel Lesiński.
+** All rights reserved.
+** See COPYRIGHT file for full license.
+*/
#include "libimagequant.h"
#include "pam.h"
@@ -8,6 +13,8 @@
*/
static void transposing_1d_blur(unsigned char *restrict src, unsigned char *restrict dst, unsigned int width, unsigned int height, const unsigned int size)
{
+ assert(size > 0);
+
for(unsigned int j=0; j < height; j++) {
unsigned char *restrict row = src + j*width;
diff --git a/src/drivers/libimagequant/configure b/src/drivers/libimagequant/configure
index 23f84d7..08476ff 100755
--- a/src/drivers/libimagequant/configure
+++ b/src/drivers/libimagequant/configure
@@ -21,14 +21,18 @@ for i in "$@"; do
case $i in
--help)
echo
- help "--prefix= installation directory [$PREFIX]"
- help "--extra-cflags= append to CFLAGS"
- help "--extra-ldflags= append to LDFLAGS"
+ help "--prefix=<dir> installation directory [$PREFIX]"
+ help "--extra-cflags=<flags> append to CFLAGS"
+ help "--extra-ldflags=<flags> append to LDFLAGS"
echo
help "--enable-debug"
help "--enable-sse/--disable-sse enable/disable SSE instructions"
echo
- help "--with-openmp compile with multicore support"
+ help "--with-openmp=static compile with multicore support"
+ echo
+ help "CC=<compiler> use given compiler command"
+ help "CFLAGS=<flags> pass options to the compiler"
+ help "LDFLAGS=<flags> pass options to the linker"
echo
exit 0
;;
@@ -54,6 +58,9 @@ for i in "$@"; do
--with-openmp)
OPENMP=1
;;
+ --with-openmp=static)
+ OPENMP=static
+ ;;
--prefix=*)
PREFIX=${i#*=}
;;
@@ -65,7 +72,7 @@ for i in "$@"; do
EXTRA_LDFLAGS="$EXTRA_LDFLAGS ${i#*=}"
;;
*)
- echo "error: unknown switch ${i%%=*}"
+ echo "error: unknown switch ${i%%=*} (see $0 --help for the list)"
exit 1
;;
esac
@@ -93,7 +100,7 @@ status() {
# Append to CFLAGS if compiler supports flag, with optional prerequisite.
# Fails on errors and warnings.
conditional_cflags() {
- if [ -z "$("$CC" -xc -S -o /dev/null $2 $1 <(echo) 2>&1)" ]; then
+ if [ -z "echo | $("$CC" -xc -S -o /dev/null $2 $1 2>&1)" ]; then
cflags "$1"
fi
}
@@ -107,8 +114,8 @@ error() {
echo
# basic check
-if ! "$CC" -xc -std=c99 <(echo "int main(){}") -o /dev/null &> /dev/null; then
- error "Compiler" "$CC is no C compiler"
+if ! echo "int main(){}" | "$CC" -xc -std=c99 -o /dev/null - > /dev/null; then
+ error "Compiler" "$CC failed to compile anything (make sure it's installed and supports C99)"
fi
status "Compiler" "$CC"
@@ -149,15 +156,19 @@ fi
# OpenMP
if [ -n "$OPENMP" ]; then
- if [[ "$("$CC" -xc -E -fopenmp <(echo -e \
- "#ifdef _OPENMP
+ if [ "static" = "$OPENMP" ]; then
+ OPENMPFLAGS="-static-libgcc -Bstatic -fopenmp -Bdynamic"
+ else
+ OPENMPFLAGS="-fopenmp"
+ fi
+ if [[ "$("$CC" -xc -E $OPENMPFLAGS <(echo "#ifdef _OPENMP
#include <omp.h>
#endif") 2>&1)" =~ "omp_get_thread_num" ]]; then
- cflags "-fopenmp"
- lflags "-fopenmp"
+ cflags "$OPENMPFLAGS"
+ lflags "$OPENMPFLAGS"
status "OpenMP" "yes"
else
- error "OpenMP" "not supported by compiler"
+ error "OpenMP" "not supported by compiler (please install a compiler that supports OpenMP (e.g. gcc) and specify it with the CC= argument)"
fi
else
# silence warnings about omp pragmas
@@ -202,4 +213,4 @@ VERSION = $VERSION
CC = $CC
CFLAGS = $CFLAGS
LDFLAGS = $LDFLAGS
-" > $CONFIG
+" > "$CONFIG"
diff --git a/src/drivers/libimagequant/libimagequant.c b/src/drivers/libimagequant/libimagequant.c
index 5812e37..5023971 100644
--- a/src/drivers/libimagequant/libimagequant.c
+++ b/src/drivers/libimagequant/libimagequant.c
@@ -3,7 +3,7 @@
** Copyright (C) 1989, 1991 by Jef Poskanzer.
** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
** Stefan Schneider.
-** © 2009-2013 by Kornel Lesinski.
+** © 2009-2015 by Kornel Lesinski.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
@@ -83,6 +83,8 @@ struct liq_image {
liq_image_get_rgba_row_callback *row_callback;
void *row_callback_user_info;
float min_opaque_val;
+ f_pixel fixed_colors[256];
+ unsigned short fixed_colors_count;
bool free_pixels, free_rows, free_rows_internal;
};
@@ -113,15 +115,15 @@ struct liq_result {
bool use_dither_map, fast_palette;
};
-static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, double gamma);
-static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels);
-static void contrast_maps(liq_image *image);
-static histogram *get_histogram(liq_image *input_image, const liq_attr *options);
-static const rgba_pixel *liq_image_get_row_rgba(liq_image *input_image, unsigned int row);
-static const f_pixel *liq_image_get_row_f(liq_image *input_image, unsigned int row);
-static void liq_remapping_result_destroy(liq_remapping_result *result);
+static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, const liq_image *img) LIQ_NONNULL;
+static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels) LIQ_NONNULL;
+static void contrast_maps(liq_image *image) LIQ_NONNULL;
+static histogram *get_histogram(liq_image *input_image, const liq_attr *options) LIQ_NONNULL;
+static const rgba_pixel *liq_image_get_row_rgba(liq_image *input_image, unsigned int row) LIQ_NONNULL;
+static const f_pixel *liq_image_get_row_f(liq_image *input_image, unsigned int row) LIQ_NONNULL;
+static void liq_remapping_result_destroy(liq_remapping_result *result) LIQ_NONNULL;
-static void liq_verbose_printf(const liq_attr *context, const char *fmt, ...)
+LIQ_NONNULL static void liq_verbose_printf(const liq_attr *context, const char *fmt, ...)
{
if (context->log_callback) {
va_list va;
@@ -138,14 +140,14 @@ static void liq_verbose_printf(const liq_attr *context, const char *fmt, ...)
}
}
-inline static void verbose_print(const liq_attr *attr, const char *msg)
+LIQ_NONNULL inline static void verbose_print(const liq_attr *attr, const char *msg)
{
if (attr->log_callback) {
attr->log_callback(attr, msg, attr->log_callback_user_info);
}
}
-static void liq_verbose_printf_flush(liq_attr *attr)
+LIQ_NONNULL static void liq_verbose_printf_flush(liq_attr *attr)
{
if (attr->log_flush_callback) {
attr->log_flush_callback(attr, attr->log_flush_callback_user_info);
@@ -196,7 +198,8 @@ LIQ_EXPORT bool liq_crash_if_invalid_pointer_given(void *pointer)
return test_access || true;
}
-static void liq_log_error(const liq_attr *attr, const char *msg) {
+LIQ_NONNULL static void liq_log_error(const liq_attr *attr, const char *msg)
+{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
liq_verbose_printf(attr, " error: %s", msg);
}
@@ -226,7 +229,13 @@ static unsigned int mse_to_quality(double mse)
return 0;
}
-LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int target)
+/** internally MSE is a sum of all channels with pixels 0..1 range,
+ but other software gives per-RGB-channel MSE for 0..255 range */
+static double mse_to_standard_mse(double mse) {
+ return mse * 65536.0/6.0;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_quality(liq_attr* attr, int minimum, int target)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
if (target < 0 || target > 100 || target < minimum || minimum < 0) return LIQ_VALUE_OUT_OF_RANGE;
@@ -236,20 +245,20 @@ LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int target)
return LIQ_OK;
}
-LIQ_EXPORT int liq_get_min_quality(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_quality(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return mse_to_quality(attr->max_mse);
}
-LIQ_EXPORT int liq_get_max_quality(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_max_quality(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return mse_to_quality(attr->target_mse);
}
-LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_max_colors(liq_attr* attr, int colors)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
if (colors < 2 || colors > 256) return LIQ_VALUE_OUT_OF_RANGE;
@@ -258,14 +267,14 @@ LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors)
return LIQ_OK;
}
-LIQ_EXPORT int liq_get_max_colors(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_max_colors(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return attr->max_colors;
}
-LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr *attr, int bits)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_posterization(liq_attr *attr, int bits)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
if (bits < 0 || bits > 4) return LIQ_VALUE_OUT_OF_RANGE;
@@ -274,19 +283,19 @@ LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr *attr, int bits)
return LIQ_OK;
}
-LIQ_EXPORT int liq_get_min_posterization(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_posterization(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return attr->min_posterization_output;
}
-LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_speed(liq_attr* attr, int speed)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
if (speed < 1 || speed > 10) return LIQ_VALUE_OUT_OF_RANGE;
- int iterations = MAX(8-speed,0); iterations += iterations * iterations/2;
+ unsigned int iterations = MAX(8-speed, 0); iterations += iterations * iterations/2;
attr->voronoi_iterations = iterations;
attr->voronoi_iteration_limit = 1.0/(double)(1<<(23-speed));
attr->feedback_loop_trials = MAX(56-9*speed, 0);
@@ -300,14 +309,14 @@ LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed)
return LIQ_OK;
}
-LIQ_EXPORT int liq_get_speed(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_speed(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return attr->speed;
}
-LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_output_gamma(liq_result* res, double gamma)
{
if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
if (gamma <= 0 || gamma >= 1.0) return LIQ_VALUE_OUT_OF_RANGE;
@@ -321,7 +330,7 @@ LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma)
return LIQ_OK;
}
-LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_opacity(liq_attr* attr, int min)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
if (min < 0 || min > 255) return LIQ_VALUE_OUT_OF_RANGE;
@@ -330,14 +339,14 @@ LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min)
return LIQ_OK;
}
-LIQ_EXPORT int liq_get_min_opacity(const liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_opacity(const liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
return MIN(255, 256.0 * attr->min_opaque_val);
}
-LIQ_EXPORT void liq_set_last_index_transparent(liq_attr* attr, int is_last)
+LIQ_EXPORT LIQ_NONNULL void liq_set_last_index_transparent(liq_attr* attr, int is_last)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
@@ -366,7 +375,7 @@ LIQ_EXPORT liq_attr* liq_attr_create()
return liq_attr_create_with_allocator(NULL, NULL);
}
-LIQ_EXPORT void liq_attr_destroy(liq_attr *attr)
+LIQ_EXPORT LIQ_NONNULL void liq_attr_destroy(liq_attr *attr)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
return;
@@ -378,7 +387,7 @@ LIQ_EXPORT void liq_attr_destroy(liq_attr *attr)
attr->free(attr);
}
-LIQ_EXPORT liq_attr* liq_attr_copy(liq_attr *orig)
+LIQ_EXPORT LIQ_NONNULL liq_attr* liq_attr_copy(liq_attr *orig)
{
if (!CHECK_STRUCT_TYPE(orig, liq_attr)) {
return NULL;
@@ -404,7 +413,7 @@ static void *liq_aligned_malloc(size_t size)
return ptr;
}
-static void liq_aligned_free(void *inptr)
+LIQ_NONNULL static void liq_aligned_free(void *inptr)
{
unsigned char *ptr = inptr;
size_t offset = ptr[-1] ^ 0x59;
@@ -442,13 +451,29 @@ LIQ_EXPORT liq_attr* liq_attr_create_with_allocator(void* (*custom_malloc)(size_
return attr;
}
-static bool liq_image_use_low_memory(liq_image *img)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_add_fixed_color(liq_image *img, liq_color color)
+{
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
+ if (img->fixed_colors_count > 255) return LIQ_BUFFER_TOO_SMALL;
+
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, img->gamma);
+ img->fixed_colors[img->fixed_colors_count++] = to_f(gamma_lut, (rgba_pixel){
+ .r = color.r,
+ .g = color.g,
+ .b = color.b,
+ .a = color.a,
+ });
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static bool liq_image_use_low_memory(liq_image *img)
{
img->temp_f_row = img->malloc(sizeof(img->f_pixels[0]) * img->width * omp_get_max_threads());
return img->temp_f_row != NULL;
}
-static bool liq_image_should_use_low_memory(liq_image *img, const bool low_memory_hint)
+LIQ_NONNULL static bool liq_image_should_use_low_memory(liq_image *img, const bool low_memory_hint)
{
return img->width * img->height > (low_memory_hint ? LIQ_HIGH_MEMORY_LIMIT/8 : LIQ_HIGH_MEMORY_LIMIT) / sizeof(f_pixel); // Watch out for integer overflow
}
@@ -497,7 +522,7 @@ static liq_image *liq_image_create_internal(liq_attr *attr, rgba_pixel* rows[],
return img;
}
-LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image *img, int ownership_flags)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_memory_ownership(liq_image *img, int ownership_flags)
{
if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
if (!img->rows || !ownership_flags || (ownership_flags & ~(LIQ_OWN_ROWS|LIQ_OWN_PIXELS))) {
@@ -524,7 +549,7 @@ LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image *img, int ownershi
return LIQ_OK;
}
-static bool check_image_size(const liq_attr *attr, const int width, const int height)
+LIQ_NONNULL static bool check_image_size(const liq_attr *attr, const int width, const int height)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
return false;
@@ -564,7 +589,7 @@ LIQ_EXPORT liq_image *liq_image_create_rgba_rows(liq_attr *attr, void* rows[], i
return liq_image_create_internal(attr, (rgba_pixel**)rows, NULL, NULL, width, height, gamma);
}
-LIQ_EXPORT liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma)
+LIQ_EXPORT LIQ_NONNULL liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma)
{
if (!check_image_size(attr, width, height)) {
return NULL;
@@ -583,6 +608,10 @@ LIQ_EXPORT liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int wi
}
liq_image *image = liq_image_create_internal(attr, rows, NULL, NULL, width, height, gamma);
+ if (!image) {
+ attr->free(rows);
+ return NULL;
+ }
image->free_rows = true;
image->free_rows_internal = true;
return image;
@@ -596,13 +625,13 @@ LIQ_EXPORT void liq_executing_user_callback(liq_image_get_rgba_row_callback *cal
callback(temp_row, row, width, user_info);
}
-inline static bool liq_image_can_use_rows(liq_image *img)
+LIQ_NONNULL inline static bool liq_image_can_use_rows(liq_image *img)
{
const bool iebug = img->min_opaque_val < 1.f;
return (img->rows && !iebug);
}
-static const rgba_pixel *liq_image_get_row_rgba(liq_image *img, unsigned int row)
+LIQ_NONNULL static const rgba_pixel *liq_image_get_row_rgba(liq_image *img, unsigned int row)
{
if (liq_image_can_use_rows(img)) {
return img->rows[row];
@@ -620,7 +649,7 @@ static const rgba_pixel *liq_image_get_row_rgba(liq_image *img, unsigned int row
return temp_row;
}
-static void convert_row_to_f(liq_image *img, f_pixel *row_f_pixels, const unsigned int row, const float gamma_lut[])
+LIQ_NONNULL static void convert_row_to_f(liq_image *img, f_pixel *row_f_pixels, const unsigned int row, const float gamma_lut[])
{
assert(row_f_pixels);
assert(!USE_SSE || 0 == ((uintptr_t)row_f_pixels & 15));
@@ -632,7 +661,7 @@ static void convert_row_to_f(liq_image *img, f_pixel *row_f_pixels, const unsign
}
}
-static const f_pixel *liq_image_get_row_f(liq_image *img, unsigned int row)
+LIQ_NONNULL static const f_pixel *liq_image_get_row_f(liq_image *img, unsigned int row)
{
if (!img->f_pixels) {
if (img->temp_f_row) {
@@ -661,13 +690,13 @@ static const f_pixel *liq_image_get_row_f(liq_image *img, unsigned int row)
return img->f_pixels + img->width * row;
}
-LIQ_EXPORT int liq_image_get_width(const liq_image *input_image)
+LIQ_EXPORT LIQ_NONNULL int liq_image_get_width(const liq_image *input_image)
{
if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
return input_image->width;
}
-LIQ_EXPORT int liq_image_get_height(const liq_image *input_image)
+LIQ_EXPORT LIQ_NONNULL int liq_image_get_height(const liq_image *input_image)
{
if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
return input_image->height;
@@ -675,7 +704,7 @@ LIQ_EXPORT int liq_image_get_height(const liq_image *input_image)
typedef void free_func(void*);
-free_func *get_default_free_func(liq_image *img)
+LIQ_NONNULL static free_func *get_default_free_func(liq_image *img)
{
// When default allocator is used then user-supplied pointers must be freed with free()
if (img->free_rows_internal || img->free != liq_aligned_free) {
@@ -684,7 +713,7 @@ free_func *get_default_free_func(liq_image *img)
return free;
}
-static void liq_image_free_rgba_source(liq_image *input_image)
+LIQ_NONNULL static void liq_image_free_rgba_source(liq_image *input_image)
{
if (input_image->free_pixels && input_image->pixels) {
get_default_free_func(input_image)(input_image->pixels);
@@ -697,7 +726,7 @@ static void liq_image_free_rgba_source(liq_image *input_image)
}
}
-LIQ_EXPORT void liq_image_destroy(liq_image *input_image)
+LIQ_EXPORT LIQ_NONNULL void liq_image_destroy(liq_image *input_image)
{
if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return;
@@ -731,7 +760,7 @@ LIQ_EXPORT void liq_image_destroy(liq_image *input_image)
input_image->free(input_image);
}
-LIQ_EXPORT liq_result *liq_quantize_image(liq_attr *attr, liq_image *img)
+LIQ_EXPORT LIQ_NONNULL liq_result *liq_quantize_image(liq_attr *attr, liq_image *img)
{
if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return NULL;
if (!CHECK_STRUCT_TYPE(img, liq_image)) {
@@ -744,13 +773,13 @@ LIQ_EXPORT liq_result *liq_quantize_image(liq_attr *attr, liq_image *img)
return NULL;
}
- liq_result *result = pngquant_quantize(hist, attr, img->gamma);
+ liq_result *result = pngquant_quantize(hist, attr, img);
pam_freeacolorhist(hist);
return result;
}
-LIQ_EXPORT liq_error liq_set_dithering_level(liq_result *res, float dither_level)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_dithering_level(liq_result *res, float dither_level)
{
if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
@@ -764,7 +793,7 @@ LIQ_EXPORT liq_error liq_set_dithering_level(liq_result *res, float dither_level
return LIQ_OK;
}
-static liq_remapping_result *liq_remapping_result_create(liq_result *result)
+LIQ_NONNULL static liq_remapping_result *liq_remapping_result_create(liq_result *result)
{
if (!CHECK_STRUCT_TYPE(result, liq_result)) {
return NULL;
@@ -785,14 +814,14 @@ static liq_remapping_result *liq_remapping_result_create(liq_result *result)
return res;
}
-LIQ_EXPORT double liq_get_output_gamma(const liq_result *result)
+LIQ_EXPORT LIQ_NONNULL double liq_get_output_gamma(const liq_result *result)
{
if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
return result->gamma;
}
-static void liq_remapping_result_destroy(liq_remapping_result *result)
+LIQ_NONNULL static void liq_remapping_result_destroy(liq_remapping_result *result)
{
if (!CHECK_STRUCT_TYPE(result, liq_remapping_result)) return;
@@ -803,7 +832,7 @@ static void liq_remapping_result_destroy(liq_remapping_result *result)
result->free(result);
}
-LIQ_EXPORT void liq_result_destroy(liq_result *res)
+LIQ_EXPORT LIQ_NONNULL void liq_result_destroy(liq_result *res)
{
if (!CHECK_STRUCT_TYPE(res, liq_result)) return;
@@ -820,45 +849,57 @@ LIQ_EXPORT void liq_result_destroy(liq_result *res)
res->free(res);
}
-LIQ_EXPORT double liq_get_quantization_error(liq_result *result)
-{
+
+LIQ_EXPORT LIQ_NONNULL double liq_get_quantization_error(liq_result *result) {
if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
if (result->palette_error >= 0) {
- return result->palette_error*65536.0/6.0;
+ return mse_to_standard_mse(result->palette_error);
}
+ return -1;
+}
+
+LIQ_EXPORT LIQ_NONNULL double liq_get_remapping_error(liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
if (result->remapping && result->remapping->palette_error >= 0) {
- return result->remapping->palette_error*65536.0/6.0;
+ return mse_to_standard_mse(result->remapping->palette_error);
}
- return result->palette_error;
+ return -1;
}
-LIQ_EXPORT int liq_get_quantization_quality(liq_result *result)
-{
+LIQ_EXPORT LIQ_NONNULL int liq_get_quantization_quality(liq_result *result) {
if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
if (result->palette_error >= 0) {
return mse_to_quality(result->palette_error);
}
+ return -1;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_remapping_quality(liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
if (result->remapping && result->remapping->palette_error >= 0) {
return mse_to_quality(result->remapping->palette_error);
}
- return result->palette_error;
+ return -1;
}
-static int compare_popularity(const void *ch1, const void *ch2)
+LIQ_NONNULL static int compare_popularity(const void *ch1, const void *ch2)
{
const float v1 = ((const colormap_item*)ch1)->popularity;
const float v2 = ((const colormap_item*)ch2)->popularity;
return v1 > v2 ? -1 : 1;
}
-static void sort_palette_qsort(colormap *map, int start, int nelem)
+LIQ_NONNULL static void sort_palette_qsort(colormap *map, int start, int nelem)
{
+ if (!nelem) return;
qsort(map->palette + start, nelem, sizeof(map->palette[0]), compare_popularity);
}
@@ -867,7 +908,7 @@ static void sort_palette_qsort(colormap *map, int start, int nelem)
(map)->palette[(a)] = (map)->palette[(b)]; \
(map)->palette[(b)] = tmp; }
-static void sort_palette(colormap *map, const liq_attr *options)
+LIQ_NONNULL static void sort_palette(colormap *map, const liq_attr *options)
{
/*
** Step 3.5 [GRR]: remap the palette colors so that all entries with
@@ -875,21 +916,30 @@ static void sort_palette(colormap *map, const liq_attr *options)
** therefore be omitted from the tRNS chunk.
*/
if (options->last_index_transparent) {
- for(unsigned int i=0; i < map->colors; i++) {
- if (map->palette[i].acolor.a < 1.0/256.0) {
- const unsigned int old = i, transparent_dest = map->colors-1;
+ for(unsigned int i=0; i < map->colors; i++) {
+ if (map->palette[i].acolor.a < 1.0/256.0) {
+ const unsigned int old = i, transparent_dest = map->colors-1;
- SWAP_PALETTE(map, transparent_dest, old);
+ SWAP_PALETTE(map, transparent_dest, old);
- /* colors sorted by popularity make pngs slightly more compressible */
- sort_palette_qsort(map, 0, map->colors-1);
- return;
+ /* colors sorted by popularity make pngs slightly more compressible */
+ sort_palette_qsort(map, 0, map->colors-1);
+ return;
}
}
}
+
+ unsigned int non_fixed_colors = 0;
+ for(unsigned int i = 0; i < map->colors; i++) {
+ if (map->palette[i].fixed) {
+ break;
+ }
+ non_fixed_colors++;
+ }
+
/* move transparent colors to the beginning to shrink trns chunk */
- unsigned int num_transparent=0;
- for(unsigned int i=0; i < map->colors; i++) {
+ unsigned int num_transparent = 0;
+ for(unsigned int i = 0; i < non_fixed_colors; i++) {
if (map->palette[i].acolor.a < 255.0/256.0) {
// current transparent color is swapped with earlier opaque one
if (i != num_transparent) {
@@ -906,9 +956,9 @@ static void sort_palette(colormap *map, const liq_attr *options)
* opaque and transparent are sorted separately
*/
sort_palette_qsort(map, 0, num_transparent);
- sort_palette_qsort(map, num_transparent, map->colors-num_transparent);
+ sort_palette_qsort(map, num_transparent, non_fixed_colors - num_transparent);
- if (map->colors > 16) {
+ if (non_fixed_colors > 9 && map->colors > 16) {
SWAP_PALETTE(map, 7, 1); // slightly improves compression
SWAP_PALETTE(map, 8, 2);
SWAP_PALETTE(map, 9, 3);
@@ -920,7 +970,7 @@ inline static unsigned int posterize_channel(unsigned int color, unsigned int bi
return (color & ~((1<<bits)-1)) | (color >> (8-bits));
}
-static void set_rounded_palette(liq_palette *const dest, colormap *const map, const double gamma, unsigned int posterize)
+LIQ_NONNULL static void set_rounded_palette(liq_palette *const dest, colormap *const map, const double gamma, unsigned int posterize)
{
float gamma_lut[256];
to_f_set_gamma(gamma_lut, gamma);
@@ -936,7 +986,7 @@ static void set_rounded_palette(liq_palette *const dest, colormap *const map, co
map->palette[x].acolor = to_f(gamma_lut, px); /* saves rounding error introduced by to_rgb, which makes remapping & dithering more accurate */
- if (!px.a) {
+ if (!px.a && !map->palette[x].fixed) {
px.r = 'L'; px.g = 'i'; px.b = 'q';
}
@@ -944,7 +994,7 @@ static void set_rounded_palette(liq_palette *const dest, colormap *const map, co
}
}
-LIQ_EXPORT const liq_palette *liq_get_palette(liq_result *result)
+LIQ_EXPORT LIQ_NONNULL const liq_palette *liq_get_palette(liq_result *result)
{
if (!CHECK_STRUCT_TYPE(result, liq_result)) return NULL;
@@ -958,11 +1008,10 @@ LIQ_EXPORT const liq_palette *liq_get_palette(liq_result *result)
return &result->int_palette;
}
-static float remap_to_palette(liq_image *const input_image, unsigned char *const *const output_pixels, colormap *const map, const bool fast)
+LIQ_NONNULL static float remap_to_palette(liq_image *const input_image, unsigned char *const *const output_pixels, colormap *const map, const bool fast)
{
const int rows = input_image->height;
const unsigned int cols = input_image->width;
- const float min_opaque_val = input_image->min_opaque_val;
double remapping_error=0;
if (!liq_image_get_row_f(input_image, 0)) { // trigger lazy conversion
@@ -981,13 +1030,11 @@ static float remap_to_palette(liq_image *const input_image, unsigned char *const
const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row);
unsigned int last_match=0;
for(unsigned int col = 0; col < cols; ++col) {
- f_pixel px = row_pixels[col];
float diff;
-
- output_pixels[row][col] = last_match = nearest_search(n, px, last_match, min_opaque_val, &diff);
+ output_pixels[row][col] = last_match = nearest_search(n, &row_pixels[col], last_match, &diff);
remapping_error += diff;
- viter_update_color(px, 1.0, map, last_match, omp_get_thread_num(), average_color);
+ viter_update_color(row_pixels[col], 1.0, map, last_match, omp_get_thread_num(), average_color);
}
}
@@ -1020,15 +1067,15 @@ inline static f_pixel get_dithered_pixel(const float dither_level, const float m
if (a > 1.0) { a = 1.0; }
else if (a < 0) { a = 0; }
- // If dithering error is crazy high, don't propagate it that much
- // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
- const float dither_error = sr*sr + sg*sg + sb*sb + sa*sa;
- if (dither_error > max_dither_error) {
- ratio *= 0.8;
- } else if (dither_error < 2.f/256.f/256.f) {
+ // If dithering error is crazy high, don't propagate it that much
+ // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
+ const float dither_error = sr*sr + sg*sg + sb*sb + sa*sa;
+ if (dither_error > max_dither_error) {
+ ratio *= 0.8;
+ } else if (dither_error < 2.f/256.f/256.f) {
// don't dither areas that don't have noticeable error — makes file smaller
return px;
- }
+ }
return (f_pixel){
.r=px.r + sr * ratio,
@@ -1043,11 +1090,10 @@ inline static f_pixel get_dithered_pixel(const float dither_level, const float m
If output_image_is_remapped is true, only pixels noticeably changed by error diffusion will be written to output image.
*/
-static void remap_to_palette_floyd(liq_image *input_image, unsigned char *const output_pixels[], const colormap *map, const float max_dither_error, const bool use_dither_map, const bool output_image_is_remapped, float base_dithering_level)
+LIQ_NONNULL static void remap_to_palette_floyd(liq_image *input_image, unsigned char *const output_pixels[], const colormap *map, const float max_dither_error, const bool use_dither_map, const bool output_image_is_remapped, float base_dithering_level)
{
const unsigned int rows = input_image->height, cols = input_image->width;
const unsigned char *dither_map = use_dither_map ? (input_image->dither_map ? input_image->dither_map : input_image->edges) : NULL;
- const float min_opaque_val = input_image->min_opaque_val;
const colormap_item *acolormap = map->palette;
@@ -1093,7 +1139,7 @@ static void remap_to_palette_floyd(liq_image *input_image, unsigned char *const
const f_pixel spx = get_dithered_pixel(dither_level, max_dither_error, thiserr[col + 1], row_pixels[col]);
const unsigned int guessed_match = output_image_is_remapped ? output_pixels[row][col] : last_match;
- output_pixels[row][col] = last_match = nearest_search(n, spx, guessed_match, min_opaque_val, NULL);
+ output_pixels[row][col] = last_match = nearest_search(n, &spx, guessed_match, NULL);
const f_pixel xp = acolormap[last_match].acolor;
f_pixel err = {
@@ -1179,9 +1225,24 @@ static void remap_to_palette_floyd(liq_image *input_image, unsigned char *const
nearest_free(n);
}
+/* fixed colors are always included in the palette, so it would be wasteful to duplicate them in palette from histogram */
+LIQ_NONNULL static void remove_fixed_colors_from_histogram(histogram *hist, const liq_image *input_image, const float target_mse)
+{
+ const float max_difference = MAX(target_mse/2.0, 2.0/256.0/256.0);
+ if (input_image->fixed_colors_count) {
+ for(int j=0; j < hist->size; j++) {
+ for(unsigned int i=0; i < input_image->fixed_colors_count; i++) {
+ if (colordifference(hist->achv[j].acolor, input_image->fixed_colors[i]) < max_difference) {
+ hist->achv[j] = hist->achv[--hist->size]; // remove color from histogram by overwriting with the last entry
+ j--; break; // continue searching histogram
+ }
+ }
+ }
+ }
+}
/* histogram contains information how many times each color is present in the image, weighted by importance_map */
-static histogram *get_histogram(liq_image *input_image, const liq_attr *options)
+LIQ_NONNULL static histogram *get_histogram(liq_image *input_image, const liq_attr *options)
{
unsigned int ignorebits=MAX(options->min_posterization_output, options->min_posterization_input);
const unsigned int cols = input_image->width, rows = input_image->height;
@@ -1236,14 +1297,15 @@ static histogram *get_histogram(liq_image *input_image, const liq_attr *options)
histogram *hist = pam_acolorhashtoacolorhist(acht, input_image->gamma, options->malloc, options->free);
pam_freeacolorhash(acht);
-
if (hist) {
liq_verbose_printf(options, " made histogram...%d colors found", hist->size);
+ remove_fixed_colors_from_histogram(hist, input_image, options->target_mse);
}
+
return hist;
}
-static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels)
+LIQ_NONNULL static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels)
{
/* IE6 makes colors with even slightest transparency completely transparent,
thus to improve situation in IE, make colors that are less than ~10% transparent
@@ -1271,9 +1333,9 @@ static void modify_alpha(liq_image *input_image, rgba_pixel *const row_pixels)
noise - approximation of areas with high-frequency noise, except straight edges. 1=flat, 0=noisy.
edges - noise map including all edges
*/
-static void contrast_maps(liq_image *image)
+LIQ_NONNULL static void contrast_maps(liq_image *image)
{
- const int cols = image->width, rows = image->height;
+ const unsigned int cols = image->width, rows = image->height;
if (cols < 4 || rows < 4 || (3*cols*rows) > LIQ_HIGH_MEMORY_LIMIT) {
return;
}
@@ -1283,19 +1345,22 @@ static void contrast_maps(liq_image *image)
unsigned char *restrict tmp = image->malloc(cols*rows);
if (!noise || !edges || !tmp) {
+ image->free(noise);
+ image->free(edges);
+ image->free(tmp);
return;
}
const f_pixel *curr_row, *prev_row, *next_row;
curr_row = prev_row = next_row = liq_image_get_row_f(image, 0);
- for (int j=0; j < rows; j++) {
+ for (unsigned int j=0; j < rows; j++) {
prev_row = curr_row;
curr_row = next_row;
next_row = liq_image_get_row_f(image, MIN(rows-1,j+1));
f_pixel prev, curr = curr_row[0], next=curr;
- for (int i=0; i < cols; i++) {
+ for (unsigned int i=0; i < cols; i++) {
prev=curr;
curr=next;
next = curr_row[MIN(cols-1,i+1)];
@@ -1343,7 +1408,7 @@ static void contrast_maps(liq_image *image)
liq_min3(edges, tmp, cols, rows);
liq_max3(tmp, edges, cols, rows);
- for(int i=0; i < cols*rows; i++) edges[i] = MIN(noise[i], edges[i]);
+ for(unsigned int i=0; i < cols*rows; i++) edges[i] = MIN(noise[i], edges[i]);
image->free(tmp);
@@ -1358,7 +1423,7 @@ static void contrast_maps(liq_image *image)
* and peeks 1 pixel above/below. Full 2d algorithm doesn't improve it significantly.
* Correct flood fill doesn't have visually good properties.
*/
-static void update_dither_map(unsigned char *const *const row_pointers, liq_image *input_image)
+LIQ_NONNULL static void update_dither_map(unsigned char *const *const row_pointers, liq_image *input_image)
{
const unsigned int width = input_image->width;
const unsigned int height = input_image->height;
@@ -1400,7 +1465,32 @@ static void update_dither_map(unsigned char *const *const row_pointers, liq_imag
input_image->edges = NULL;
}
-static void adjust_histogram_callback(hist_item *item, float diff)
+/**
+ * Palette can be NULL, in which case it creates a new palette from scratch.
+ */
+static colormap *add_fixed_colors_to_palette(colormap *palette, const int max_colors, const f_pixel fixed_colors[], const int fixed_colors_count, void* (*malloc)(size_t), void (*free)(void*))
+{
+ if (!fixed_colors_count) return palette;
+
+ colormap *newpal = pam_colormap(MIN(max_colors, (palette ? palette->colors : 0) + fixed_colors_count), malloc, free);
+ unsigned int i=0;
+ if (palette && fixed_colors_count < max_colors) {
+ unsigned int palette_max = MIN(palette->colors, max_colors - fixed_colors_count);
+ for(; i < palette_max; i++) {
+ newpal->palette[i] = palette->palette[i];
+ }
+ }
+ for(int j=0; j < MIN(max_colors, fixed_colors_count); j++) {
+ newpal->palette[i++] = (colormap_item){
+ .acolor = fixed_colors[j],
+ .fixed = true,
+ };
+ }
+ if (palette) pam_freecolormap(palette);
+ return newpal;
+}
+
+LIQ_NONNULL static void adjust_histogram_callback(hist_item *item, float diff)
{
item->adjusted_weight = (item->perceptual_weight+item->adjusted_weight) * (sqrtf(1.f+diff));
}
@@ -1410,9 +1500,10 @@ static void adjust_histogram_callback(hist_item *item, float diff)
feedback_loop_trials controls how long the search will take. < 0 skips the iteration.
*/
-static colormap *find_best_palette(histogram *hist, const liq_attr *options, const double max_mse, double *palette_error_p)
+static colormap *find_best_palette(histogram *hist, const liq_attr *options, const double max_mse, const f_pixel fixed_colors[], const unsigned int fixed_colors_count, double *palette_error_p)
{
unsigned int max_colors = options->max_colors;
+
// if output is posterized it doesn't make sense to aim for perfrect colors, so increase target_mse
// at this point actual gamma is not set, so very conservative posterization estimate is used
const double target_mse = MIN(max_mse, MAX(options->target_mse, pow((1<<options->min_posterization_output)/1024.0, 2)));
@@ -1423,9 +1514,15 @@ static colormap *find_best_palette(histogram *hist, const liq_attr *options, con
const double percent = (double)(feedback_loop_trials>0?feedback_loop_trials:1)/100.0;
do {
- colormap *newmap = mediancut(hist, options->min_opaque_val, max_colors,
- target_mse * target_mse_overshoot, MAX(MAX(90.0/65536.0, target_mse), least_error)*1.2,
+ colormap *newmap;
+ if (hist->size && fixed_colors_count < max_colors) {
+ newmap = mediancut(hist, max_colors-fixed_colors_count, target_mse * target_mse_overshoot, MAX(MAX(90.0/65536.0, target_mse), least_error)*1.2,
options->malloc, options->free);
+ } else {
+ feedback_loop_trials = 0;
+ newmap = NULL;
+ }
+ newmap = add_fixed_colors_to_palette(newmap, max_colors, fixed_colors, fixed_colors_count, options->malloc, options->free);
if (!newmap) {
return NULL;
}
@@ -1439,7 +1536,7 @@ static colormap *find_best_palette(histogram *hist, const liq_attr *options, con
// and histogram weights are adjusted based on remapping error to give more weight to poorly matched colors
const bool first_run_of_target_mse = !acolormap && target_mse > 0;
- double total_error = viter_do_iteration(hist, newmap, options->min_opaque_val, first_run_of_target_mse ? NULL : adjust_histogram_callback, !acolormap || options->fast_palette);
+ double total_error = viter_do_iteration(hist, newmap, first_run_of_target_mse ? NULL : adjust_histogram_callback, !acolormap || options->fast_palette);
// goal is to increase quality or to reduce number of colors used if quality is good enough
if (!acolormap || total_error < least_error || (total_error <= target_mse && newmap->colors < max_colors)) {
@@ -1475,39 +1572,39 @@ static colormap *find_best_palette(histogram *hist, const liq_attr *options, con
}
while(feedback_loop_trials > 0);
- // likely_colormap_index (used and set in viter_do_iteration) can't point to index outside colormap
- if (acolormap->colors < 256) {
- for(unsigned int j=0; j < hist->size; j++) {
- if (hist->achv[j].tmp.likely_colormap_index >= acolormap->colors) {
- hist->achv[j].tmp.likely_colormap_index = 0; // actual value doesn't matter, as the guess is out of date anyway
- }
- }
- }
*palette_error_p = least_error;
return acolormap;
}
-static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, const double gamma)
+static colormap *histogram_to_palette(const histogram *hist, const liq_attr *options) {
+ if (!hist->size) {
+ return NULL;
+ }
+ colormap *acolormap = pam_colormap(hist->size, options->malloc, options->free);
+ for(unsigned int i=0; i < hist->size; i++) {
+ acolormap->palette[i].acolor = hist->achv[i].acolor;
+ acolormap->palette[i].popularity = hist->achv[i].perceptual_weight;
+ }
+ return acolormap;
+}
+
+LIQ_NONNULL static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, const liq_image *img)
{
colormap *acolormap;
double palette_error = -1;
// no point having perfect match with imperfect colors (ignorebits > 0)
const bool fast_palette = options->fast_palette || hist->ignorebits > 0;
- const bool few_input_colors = hist->size <= options->max_colors;
+ const bool few_input_colors = hist->size+img->fixed_colors_count <= options->max_colors;
// If image has few colors to begin with (and no quality degradation is required)
// then it's possible to skip quantization entirely
if (few_input_colors && options->target_mse == 0) {
- acolormap = pam_colormap(hist->size, options->malloc, options->free);
- for(unsigned int i=0; i < hist->size; i++) {
- acolormap->palette[i].acolor = hist->achv[i].acolor;
- acolormap->palette[i].popularity = hist->achv[i].perceptual_weight;
- }
+ acolormap = add_fixed_colors_to_palette(histogram_to_palette(hist, options), options->max_colors, img->fixed_colors, img->fixed_colors_count, options->malloc, options->free);
palette_error = 0;
} else {
const double max_mse = options->max_mse * (few_input_colors ? 0.33 : 1.0); // when degrading image that's already paletted, require much higher improvement, since pal2pal often looks bad and there's little gain
- acolormap = find_best_palette(hist, options, max_mse, &palette_error);
+ acolormap = find_best_palette(hist, options, max_mse, img->fixed_colors, img->fixed_colors_count, &palette_error);
if (!acolormap) {
return NULL;
}
@@ -1519,12 +1616,19 @@ static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, c
if (!iterations && palette_error < 0 && max_mse < MAX_DIFF) iterations = 1; // otherwise total error is never calculated and MSE limit won't work
if (iterations) {
+ // likely_colormap_index (used and set in viter_do_iteration) can't point to index outside colormap
+ if (acolormap->colors < 256) for(unsigned int j=0; j < hist->size; j++) {
+ if (hist->achv[j].tmp.likely_colormap_index >= acolormap->colors) {
+ hist->achv[j].tmp.likely_colormap_index = 0; // actual value doesn't matter, as the guess is out of date anyway
+ }
+ }
+
verbose_print(options, " moving colormap towards local minimum");
double previous_palette_error = MAX_DIFF;
for(unsigned int i=0; i < iterations; i++) {
- palette_error = viter_do_iteration(hist, acolormap, options->min_opaque_val, NULL, i==0 || options->fast_palette);
+ palette_error = viter_do_iteration(hist, acolormap, NULL, i==0 || options->fast_palette);
if (fabs(previous_palette_error-palette_error) < iteration_limit) {
break;
@@ -1541,8 +1645,8 @@ static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, c
if (palette_error > max_mse) {
liq_verbose_printf(options, " image degradation MSE=%.3f (Q=%d) exceeded limit of %.3f (%d)",
- palette_error*65536.0/6.0, mse_to_quality(palette_error),
- max_mse*65536.0/6.0, mse_to_quality(max_mse));
+ mse_to_standard_mse(palette_error), mse_to_quality(palette_error),
+ mse_to_standard_mse(max_mse), mse_to_quality(max_mse));
pam_freecolormap(acolormap);
return NULL;
}
@@ -1560,13 +1664,13 @@ static liq_result *pngquant_quantize(histogram *hist, const liq_attr *options, c
.palette_error = palette_error,
.fast_palette = fast_palette,
.use_dither_map = options->use_dither_map,
- .gamma = gamma,
+ .gamma = img->gamma,
.min_posterization_output = options->min_posterization_output,
};
return result;
}
-LIQ_EXPORT liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size)
{
if (!CHECK_STRUCT_TYPE(result, liq_result)) {
return LIQ_INVALID_POINTER;
@@ -1591,7 +1695,7 @@ LIQ_EXPORT liq_error liq_write_remapped_image(liq_result *result, liq_image *inp
return liq_write_remapped_image_rows(result, input_image, rows);
}
-LIQ_EXPORT liq_error liq_write_remapped_image_rows(liq_result *quant, liq_image *input_image, unsigned char **row_pointers)
+LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image_rows(liq_result *quant, liq_image *input_image, unsigned char **row_pointers)
{
if (!CHECK_STRUCT_TYPE(quant, liq_result)) return LIQ_INVALID_POINTER;
if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return LIQ_INVALID_POINTER;
diff --git a/src/drivers/libimagequant/libimagequant.h b/src/drivers/libimagequant/libimagequant.h
index 2b66084..014604c 100644
--- a/src/drivers/libimagequant/libimagequant.h
+++ b/src/drivers/libimagequant/libimagequant.h
@@ -9,14 +9,18 @@
#define LIQ_EXPORT extern
#endif
-#define LIQ_VERSION 20305
-#define LIQ_VERSION_STRING "2.3.5"
+#define LIQ_VERSION 20502
+#define LIQ_VERSION_STRING "2.5.2"
#ifndef LIQ_PRIVATE
#if defined(__GNUC__) || defined (__llvm__)
#define LIQ_PRIVATE __attribute__((visibility("hidden")))
+#define LIQ_NONNULL __attribute__((nonnull))
+#define LIQ_USERESULT __attribute__((warn_unused_result))
#else
#define LIQ_PRIVATE
+#define LIQ_NONNULL
+#define LIQ_USERESULT
#endif
#endif
@@ -52,55 +56,60 @@ typedef enum liq_error {
enum liq_ownership {LIQ_OWN_ROWS=4, LIQ_OWN_PIXELS=8};
-LIQ_EXPORT liq_attr* liq_attr_create(void);
-LIQ_EXPORT liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
-LIQ_EXPORT liq_attr* liq_attr_copy(liq_attr* orig);
-LIQ_EXPORT void liq_attr_destroy(liq_attr* attr);
-
-LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors);
-LIQ_EXPORT int liq_get_max_colors(const liq_attr* attr);
-LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed);
-LIQ_EXPORT int liq_get_speed(const liq_attr* attr);
-LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min);
-LIQ_EXPORT int liq_get_min_opacity(const liq_attr* attr);
-LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr* attr, int bits);
-LIQ_EXPORT int liq_get_min_posterization(const liq_attr* attr);
-LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum);
-LIQ_EXPORT int liq_get_min_quality(const liq_attr* attr);
-LIQ_EXPORT int liq_get_max_quality(const liq_attr* attr);
-LIQ_EXPORT void liq_set_last_index_transparent(liq_attr* attr, int is_last);
-
-typedef void liq_log_callback_function(const liq_attr*, const char* message, void* user_info);
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create(void);
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_copy(liq_attr *orig) LIQ_NONNULL;
+LIQ_EXPORT void liq_attr_destroy(liq_attr *attr) LIQ_NONNULL;
+
+LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_max_colors(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_speed(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_opacity(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr* attr, int bits) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_posterization(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_quality(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_max_quality(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT void liq_set_last_index_transparent(liq_attr* attr, int is_last) LIQ_NONNULL;
+
+typedef void liq_log_callback_function(const liq_attr*, const char *message, void* user_info);
typedef void liq_log_flush_callback_function(const liq_attr*, void* user_info);
LIQ_EXPORT void liq_set_log_callback(liq_attr*, liq_log_callback_function*, void* user_info);
LIQ_EXPORT void liq_set_log_flush_callback(liq_attr*, liq_log_flush_callback_function*, void* user_info);
-LIQ_EXPORT liq_image* liq_image_create_rgba_rows(liq_attr* attr, void* rows[], int width, int height, double gamma);
-LIQ_EXPORT liq_image* liq_image_create_rgba(liq_attr* attr, void* bitmap, int width, int height, double gamma);
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba_rows(liq_attr *attr, void* rows[], int width, int height, double gamma) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba(liq_attr *attr, void* bitmap, int width, int height, double gamma) LIQ_NONNULL;
typedef void liq_image_get_rgba_row_callback(liq_color row_out[], int row, int width, void* user_info);
-LIQ_EXPORT liq_image* liq_image_create_custom(liq_attr* attr, liq_image_get_rgba_row_callback* row_callback, void* user_info, int width, int height, double gamma);
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_custom(liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void* user_info, int width, int height, double gamma);
-LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image* image, int ownership_flags);
-LIQ_EXPORT int liq_image_get_width(const liq_image* img);
-LIQ_EXPORT int liq_image_get_height(const liq_image* img);
-LIQ_EXPORT void liq_image_destroy(liq_image* img);
+LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image *image, int ownership_flags) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_image_add_fixed_color(liq_image *img, liq_color color) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_image_get_width(const liq_image *img) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_image_get_height(const liq_image *img) LIQ_NONNULL;
+LIQ_EXPORT void liq_image_destroy(liq_image *img) LIQ_NONNULL;
-LIQ_EXPORT liq_result* liq_quantize_image(liq_attr* options, liq_image* input_image);
+LIQ_EXPORT LIQ_USERESULT liq_result *liq_quantize_image(liq_attr *options, liq_image *input_image) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_set_dithering_level(liq_result* res, float dither_level);
-LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma);
-LIQ_EXPORT double liq_get_output_gamma(const liq_result* result);
+LIQ_EXPORT liq_error liq_set_dithering_level(liq_result *res, float dither_level) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT double liq_get_output_gamma(const liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT const liq_palette* liq_get_palette(liq_result* result);
+LIQ_EXPORT LIQ_USERESULT const liq_palette *liq_get_palette(liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT liq_error liq_write_remapped_image(liq_result* result, liq_image* input_image, void* buffer, size_t buffer_size);
-LIQ_EXPORT liq_error liq_write_remapped_image_rows(liq_result* result, liq_image* input_image, unsigned char** row_pointers);
+LIQ_EXPORT liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_write_remapped_image_rows(liq_result *result, liq_image *input_image, unsigned char **row_pointers) LIQ_NONNULL;
-LIQ_EXPORT double liq_get_quantization_error(liq_result* result);
-LIQ_EXPORT int liq_get_quantization_quality(liq_result* result);
+LIQ_EXPORT double liq_get_quantization_error(liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT int liq_get_quantization_quality(liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT double liq_get_remapping_error(liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT int liq_get_remapping_quality(liq_result *result) LIQ_NONNULL;
-LIQ_EXPORT void liq_result_destroy(liq_result*);
+LIQ_EXPORT void liq_result_destroy(liq_result *) LIQ_NONNULL;
+
+LIQ_EXPORT int liq_version(void);
#ifdef __cplusplus
}
diff --git a/src/drivers/libimagequant/mediancut.c b/src/drivers/libimagequant/mediancut.c
index b376c52..3fae039 100644
--- a/src/drivers/libimagequant/mediancut.c
+++ b/src/drivers/libimagequant/mediancut.c
@@ -2,7 +2,7 @@
** Copyright (C) 1989, 1991 by Jef Poskanzer.
** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
** Stefan Schneider.
-** © 2009-2013 by Kornel Lesinski.
+** © 2009-2015 by Kornel Lesinski.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
@@ -21,7 +21,7 @@
#define index_of_channel(ch) (offsetof(f_pixel,ch)/sizeof(float))
-static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], float min_opaque_val, const f_pixel center);
+static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], const f_pixel center);
struct box {
f_pixel color;
@@ -228,7 +228,7 @@ static f_pixel get_median(const struct box *b, hist_item achv[])
// technically the second color is not guaranteed to be sorted correctly
// but most of the time it is good enough to be useful
- return averagepixels(2, &achv[b->ind + median_start], 1.0, (f_pixel){0.5,0.5,0.5,0.5});
+ return averagepixels(2, &achv[b->ind + median_start], (f_pixel){0.5,0.5,0.5,0.5});
}
/*
@@ -269,7 +269,7 @@ inline static double color_weight(f_pixel median, hist_item h)
static void set_colormap_from_boxes(colormap *map, struct box* bv, unsigned int boxes, hist_item *achv);
static void adjust_histogram(hist_item *achv, const colormap *map, const struct box* bv, unsigned int boxes);
-double box_error(const struct box *box, const hist_item achv[])
+static double box_error(const struct box *box, const hist_item achv[])
{
f_pixel avg = box->color;
@@ -311,7 +311,7 @@ static bool total_box_error_below_target(double target_mse, struct box bv[], uns
** on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer
** Display," SIGGRAPH 1982 Proceedings, page 297.
*/
-LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*))
+LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*))
{
hist_item *achv = hist->achv;
struct box bv[newcolors];
@@ -321,7 +321,7 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, uns
*/
bv[0].ind = 0;
bv[0].colors = hist->size;
- bv[0].color = averagepixels(bv[0].colors, &achv[bv[0].ind], min_opaque_val, (f_pixel){0.5,0.5,0.5,0.5});
+ bv[0].color = averagepixels(bv[0].colors, &achv[bv[0].ind], (f_pixel){0.5,0.5,0.5,0.5});
bv[0].variance = box_variance(achv, &bv[0]);
bv[0].max_error = box_max_error(achv, &bv[0]);
bv[0].sum = 0;
@@ -330,20 +330,11 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, uns
unsigned int boxes = 1;
- // remember smaller palette for fast searching
- colormap *representative_subset = NULL;
- unsigned int subset_size = ceilf(powf(newcolors,0.7f));
-
/*
** Main loop: split boxes until we have enough.
*/
while (boxes < newcolors) {
- if (boxes == subset_size) {
- representative_subset = pam_colormap(boxes, malloc, free);
- set_colormap_from_boxes(representative_subset, bv, boxes, achv);
- }
-
// first splits boxes that exceed quality limit (to have colors for things like odd green pixel),
// later raises the limit to allow large smooth areas/gradients get colors.
const double current_max_mse = max_mse + (boxes/(double)newcolors)*16.0*max_mse;
@@ -383,14 +374,14 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, uns
const f_pixel previous_center = bv[bi].color;
bv[bi].colors = break_at;
bv[bi].sum = lowersum;
- bv[bi].color = averagepixels(bv[bi].colors, &achv[bv[bi].ind], min_opaque_val, previous_center);
+ bv[bi].color = averagepixels(bv[bi].colors, &achv[bv[bi].ind], previous_center);
bv[bi].total_error = -1;
bv[bi].variance = box_variance(achv, &bv[bi]);
bv[bi].max_error = box_max_error(achv, &bv[bi]);
bv[boxes].ind = indx + break_at;
bv[boxes].colors = clrs - break_at;
bv[boxes].sum = sm - lowersum;
- bv[boxes].color = averagepixels(bv[boxes].colors, &achv[bv[boxes].ind], min_opaque_val, previous_center);
+ bv[boxes].color = averagepixels(bv[boxes].colors, &achv[bv[boxes].ind], previous_center);
bv[boxes].total_error = -1;
bv[boxes].variance = box_variance(achv, &bv[boxes]);
bv[boxes].max_error = box_max_error(achv, &bv[boxes]);
@@ -405,7 +396,6 @@ LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, uns
colormap *map = pam_colormap(boxes, malloc, free);
set_colormap_from_boxes(map, bv, boxes, achv);
- map->subset_palette = representative_subset;
adjust_histogram(achv, map, bv, boxes);
return map;
@@ -443,7 +433,22 @@ static void adjust_histogram(hist_item *achv, const colormap *map, const struct
}
}
-static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], const float min_opaque_val, const f_pixel center)
+inline static f_pixel setalpha(f_pixel px, float new_a) {
+ if (px.a) {
+ px.r /= px.a;
+ px.g /= px.a;
+ px.b /= px.a;
+ }
+
+ px.r *= new_a;
+ px.g *= new_a;
+ px.b *= new_a;
+ px.a = new_a;
+
+ return px;
+}
+
+static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], f_pixel center)
{
double r = 0, g = 0, b = 0, a = 0, new_a=0, sum = 0;
float maxa = 0;
@@ -460,14 +465,13 @@ static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], const fl
if (sum) new_a /= sum;
- /** if there was at least one completely opaque color, "round" final color to opaque */
- if (new_a >= min_opaque_val && maxa >= (255.0/256.0)) new_a = 1;
+ center = setalpha(center, new_a);
sum=0;
// reverse iteration for cache locality with previous loop
for(int i = clrs-1; i >= 0; i--) {
double tmp, weight = 1.0f;
- f_pixel px = achv[i].acolor;
+ f_pixel px = setalpha(achv[i].acolor, new_a);
/* give more weight to colors that are further away from average
this is intended to prevent desaturation of images and fading of whites
@@ -478,27 +482,23 @@ static f_pixel averagepixels(unsigned int clrs, const hist_item achv[], const fl
weight += tmp*tmp;
tmp = (center.b - px.b);
weight += tmp*tmp;
+ tmp = (center.a - px.a);
+ weight += tmp*tmp;
weight *= achv[i].adjusted_weight;
sum += weight;
- if (px.a) {
- px.r /= px.a;
- px.g /= px.a;
- px.b /= px.a;
- }
-
- r += px.r * new_a * weight;
- g += px.g * new_a * weight;
- b += px.b * new_a * weight;
- a += new_a * weight;
+ r += px.r * weight;
+ g += px.g * weight;
+ b += px.b * weight;
+ a += px.a * weight;
}
if (sum) {
- a /= sum;
- r /= sum;
- g /= sum;
- b /= sum;
+ a /= sum;
+ r /= sum;
+ g /= sum;
+ b /= sum;
}
assert(!isnan(r) && !isnan(g) && !isnan(b) && !isnan(a));
diff --git a/src/drivers/libimagequant/mediancut.h b/src/drivers/libimagequant/mediancut.h
index e615c8d..d97696c 100644
--- a/src/drivers/libimagequant/mediancut.h
+++ b/src/drivers/libimagequant/mediancut.h
@@ -1,2 +1,2 @@
-LIQ_PRIVATE colormap *mediancut(histogram *hist, const float min_opaque_val, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*));
+LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*));
diff --git a/src/drivers/libimagequant/mempool.c b/src/drivers/libimagequant/mempool.c
index 032d80a..4bf7d2a 100644
--- a/src/drivers/libimagequant/mempool.c
+++ b/src/drivers/libimagequant/mempool.c
@@ -1,3 +1,8 @@
+/*
+** © 2011-2015 by Kornel Lesiński.
+** All rights reserved.
+** See COPYRIGHT file for full license.
+*/
#include "libimagequant.h"
#include "mempool.h"
diff --git a/src/drivers/libimagequant/nearest.c b/src/drivers/libimagequant/nearest.c
index e0a14d9..752c477 100644
--- a/src/drivers/libimagequant/nearest.c
+++ b/src/drivers/libimagequant/nearest.c
@@ -1,3 +1,8 @@
+/*
+** © 2011-2015 by Kornel Lesiński.
+** All rights reserved.
+** See COPYRIGHT file for full license.
+*/
#include "libimagequant.h"
#include "pam.h"
@@ -5,234 +10,181 @@
#include "mempool.h"
#include <stdlib.h>
-struct sorttmp {
- float radius;
- unsigned int index;
-};
+typedef struct vp_sort_tmp {
+ float distance_squared;
+ unsigned int idx;
+} vp_sort_tmp;
-struct head {
- // colors less than radius away from vantage_point color will have best match in candidates
+typedef struct vp_search_tmp {
+ float distance;
+ unsigned int idx;
+ int exclude;
+} vp_search_tmp;
+
+typedef struct vp_node {
+ struct vp_node *near, *far;
f_pixel vantage_point;
float radius;
- unsigned int num_candidates;
- f_pixel *candidates_color;
- unsigned short *candidates_index;
-};
+ unsigned int idx;
+} vp_node;
struct nearest_map {
- const colormap *map;
+ vp_node *root;
+ const colormap_item *palette;
float nearest_other_color_dist[256];
mempool mempool;
- struct head heads[];
};
-static unsigned int find_slow(const f_pixel px, const colormap *map)
-{
- unsigned int best=0;
- float bestdiff = colordifference(px, map->palette[0].acolor);
+static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate);
- for(unsigned int i=1; i < map->colors; i++) {
- float diff = colordifference(px, map->palette[i].acolor);
- if (diff < bestdiff) {
- best = i;
- bestdiff = diff;
- }
- }
- return best;
+static int vp_compare_distance(const void *ap, const void *bp) {
+ float a = ((const vp_sort_tmp*)ap)->distance_squared;
+ float b = ((const vp_sort_tmp*)bp)->distance_squared;
+ return a > b ? 1 : -1;
}
-static float distance_from_nearest_other_color(const colormap *map, const unsigned int i)
-{
- float second_best=MAX_DIFF;
- for(unsigned int j=0; j < map->colors; j++) {
- if (i == j) continue;
- float diff = colordifference(map->palette[i].acolor, map->palette[j].acolor);
- if (diff <= second_best) {
- second_best = diff;
- }
+static void vp_sort_indexes_by_distance(const f_pixel vantage_point, vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
+ for(int i=0; i < num_indexes; i++) {
+ indexes[i].distance_squared = colordifference(vantage_point, items[indexes[i].idx].acolor);
}
- return second_best;
+ qsort(indexes, num_indexes, sizeof(indexes[0]), vp_compare_distance);
}
-static int compareradius(const void *ap, const void *bp)
-{
- float a = ((const struct sorttmp*)ap)->radius;
- float b = ((const struct sorttmp*)bp)->radius;
- return a > b ? 1 : (a < b ? -1 : 0);
-}
-
-static struct head build_head(f_pixel px, const colormap *map, unsigned int num_candidates, mempool *m, float error_margin, bool skip_index[], unsigned int *skipped)
-{
- struct sorttmp colors[map->colors];
- unsigned int colorsused=0;
-
- for(unsigned int i=0; i < map->colors; i++) {
- if (skip_index[i]) continue; // colors in skip_index have been eliminated already in previous heads
- colors[colorsused].index = i;
- colors[colorsused].radius = colordifference(px, map->palette[i].acolor);
- colorsused++;
- }
-
- qsort(&colors, colorsused, sizeof(colors[0]), compareradius);
- assert(colorsused < 2 || colors[0].radius <= colors[1].radius); // closest first
-
- num_candidates = MIN(colorsused, num_candidates);
-
- struct head h = {
- .candidates_color = mempool_alloc(m, num_candidates * sizeof(h.candidates_color[0]), 0),
- .candidates_index = mempool_alloc(m, num_candidates * sizeof(h.candidates_index[0]), 0),
- .vantage_point = px,
- .num_candidates = num_candidates,
- };
- for(unsigned int i=0; i < num_candidates; i++) {
- h.candidates_color[i] = map->palette[colors[i].index].acolor;
- h.candidates_index[i] = colors[i].index;
- }
- // if all colors within this radius are included in candidates, then there cannot be any other better match
- // farther away from the vantage point than half of the radius. Due to alpha channel must assume pessimistic radius.
- h.radius = min_colordifference(px, h.candidates_color[num_candidates-1])/4.0f; // /4 = half of radius, but radius is squared
-
- for(unsigned int i=0; i < num_candidates; i++) {
- // divide again as that's matching certain subset within radius-limited subset
- // - 1/256 is a tolerance for miscalculation (seems like colordifference isn't exact)
- if (colors[i].radius < h.radius/4.f - error_margin) {
- skip_index[colors[i].index]=true;
- (*skipped)++;
+/*
+ * Usually it should pick farthest point, but picking most popular point seems to make search quicker anyway
+ */
+static int vp_find_best_vantage_point_index(vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
+ int best = 0;
+ float best_popularity = items[indexes[0].idx].popularity;
+ for(int i = 1; i < num_indexes; i++) {
+ if (items[indexes[i].idx].popularity > best_popularity) {
+ best_popularity = items[indexes[i].idx].popularity;
+ best = i;
}
}
- return h;
+ return best;
}
-static colormap *get_subset_palette(const colormap *map)
-{
- if (map->subset_palette) {
- return map->subset_palette;
+static vp_node *vp_create_node(mempool *m, vp_sort_tmp *indexes, int num_indexes, const colormap_item items[]) {
+ if (num_indexes <= 0) {
+ return NULL;
}
- unsigned int subset_size = (map->colors+3)/4;
- colormap *subset_palette = pam_colormap(subset_size, map->malloc, map->free);
+ vp_node *node = mempool_alloc(m, sizeof(node[0]), 0);
- for(unsigned int i=0; i < subset_size; i++) {
- subset_palette->palette[i] = map->palette[i];
+ if (num_indexes == 1) {
+ *node = (vp_node){
+ .vantage_point = items[indexes[0].idx].acolor,
+ .idx = indexes[0].idx,
+ .radius = MAX_DIFF,
+ };
+ return node;
}
- return subset_palette;
-}
+ const int ref = vp_find_best_vantage_point_index(indexes, num_indexes, items);
+ const int ref_idx = indexes[ref].idx;
-LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *map, bool fast)
-{
- colormap *subset_palette = get_subset_palette(map);
- const unsigned int num_vantage_points = map->colors > 16 ? MIN(map->colors/4, subset_palette->colors) : 0;
- const unsigned long heads_size = sizeof(struct head) * (num_vantage_points+1); // +1 is fallback head
+ // Removes the `ref_idx` item from remaining items, because it's included in the current node
+ num_indexes -= 1;
+ indexes[ref] = indexes[num_indexes];
- const unsigned long mempool_size = (sizeof(f_pixel) + sizeof(unsigned int)) * subset_palette->colors * map->colors/5 + (1<<14);
- mempool m = NULL;
- struct nearest_map *centroids = mempool_create(&m, sizeof(*centroids) + heads_size /* heads array is appended to it */, mempool_size, map->malloc, map->free);
- centroids->mempool = m;
+ vp_sort_indexes_by_distance(items[ref_idx].acolor, indexes, num_indexes, items);
- for(unsigned int i=0; i < map->colors; i++) {
- const float dist = distance_from_nearest_other_color(map,i);
- centroids->nearest_other_color_dist[i] = dist / 4.f; // half of squared distance
- }
+ // Remaining items are split by the median distance
+ const int half_idx = num_indexes/2;
- centroids->map = map;
+ *node = (vp_node){
+ .vantage_point = items[ref_idx].acolor,
+ .idx = ref_idx,
+ .radius = sqrtf(indexes[half_idx].distance_squared),
+ };
+ node->near = vp_create_node(m, indexes, half_idx, items);
+ node->far = vp_create_node(m, &indexes[half_idx], num_indexes - half_idx, items);
- unsigned int skipped=0;
- assert(map->colors > 0);
- bool skip_index[map->colors]; for(unsigned int j=0; j < map->colors; j++) skip_index[j]=false;
+ return node;
+}
- // floats and colordifference calculations are not perfect
- const float error_margin = fast ? 0 : 8.f/256.f/256.f;
- unsigned int h=0;
- for(; h < num_vantage_points; h++) {
- unsigned int num_candiadtes = 1+(map->colors - skipped)/((1+num_vantage_points-h)/2);
+LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *map, const bool fast) {
+ mempool m = NULL;
+ struct nearest_map *handle = mempool_create(&m, sizeof(handle[0]), sizeof(handle[0]) + sizeof(vp_node)*map->colors+16, map->malloc, map->free);
- centroids->heads[h] = build_head(subset_palette->palette[h].acolor, map, num_candiadtes, ¢roids->mempool, error_margin, skip_index, &skipped);
- if (centroids->heads[h].num_candidates == 0) {
- break;
- }
- }
+ vp_sort_tmp indexes[map->colors];
- // assumption that there is no better color within radius of vantage point color
- // holds true only for colors within convex hull formed by palette colors.
- // since finding proper convex hull is more than a few lines, this
- // is a cheap shot at finding just few key points.
- const f_pixel extrema[] = {
- {.a=0,0,0,0},
-
- {.a=.5,0,0,0}, {.a=.5,1,0,0},
- {.a=.5,0,0,1}, {.a=.5,1,0,1},
- {.a=.5,0,1,0}, {.a=.5,1,1,0},
- {.a=.5,0,1,1}, {.a=.5,1,1,1},
-
- {.a=1,0,0,0}, {.a=1,1,0,0},
- {.a=1,0,0,1}, {.a=1,1,0,1},
- {.a=1,0,1,0}, {.a=1,1,1,0},
- {.a=1,0,1,1}, {.a=1,1,1,1},
-
- {.a=1,.5, 0, 0}, {.a=1, 0,.5, 0}, {.a=1, 0, 0, .5},
- {.a=1,.5, 0, 1}, {.a=1, 0,.5, 1}, {.a=1, 0, 1, .5},
- {.a=1,.5, 1, 0}, {.a=1, 1,.5, 0}, {.a=1, 1, 0, .5},
- {.a=1,.5, 1, 1}, {.a=1, 1,.5, 1}, {.a=1, 1, 1, .5},
- };
- for(unsigned int i=0; i < sizeof(extrema)/sizeof(extrema[0]); i++) {
- skip_index[find_slow(extrema[i], map)]=0;
+ for(unsigned int i=0; i < map->colors; i++) {
+ indexes[i].idx = i;
}
- centroids->heads[h] = build_head((f_pixel){0,0,0,0}, map, map->colors, ¢roids->mempool, error_margin, skip_index, &skipped);
- centroids->heads[h].radius = MAX_DIFF;
+ vp_node *root = vp_create_node(&m, indexes, map->colors, map->palette);
+ *handle = (struct nearest_map){
+ .root = root,
+ .palette = map->palette,
+ .mempool = m,
+ };
- // get_subset_palette could have created a copy
- if (subset_palette != map->subset_palette) {
- pam_freecolormap(subset_palette);
+ for(unsigned int i=0; i < map->colors; i++) {
+ vp_search_tmp best = {
+ .distance = MAX_DIFF,
+ .exclude = i,
+ };
+ vp_search_node(root, &map->palette[i].acolor, &best);
+ handle->nearest_other_color_dist[i] = best.distance * best.distance / 4.0; // half of squared distance
}
- return centroids;
+ return handle;
}
-LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *centroids, const f_pixel px, int likely_colormap_index, const float min_opaque_val, float *diff)
-{
- const bool iebug = px.a > min_opaque_val;
+static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate) {
+ do {
+ const float distance = sqrtf(colordifference(node->vantage_point, *needle));
- const struct head *const heads = centroids->heads;
+ if (distance < best_candidate->distance && best_candidate->exclude != node->idx) {
+ best_candidate->distance = distance;
+ best_candidate->idx = node->idx;
+ }
- assert(likely_colormap_index < centroids->map->colors);
- const float guess_diff = colordifference(centroids->map->palette[likely_colormap_index].acolor, px);
- if (guess_diff < centroids->nearest_other_color_dist[likely_colormap_index]) {
+ // Recurse towards most likely candidate first to narrow best candidate's distance as soon as possible
+ if (distance < node->radius) {
+ if (node->near) {
+ vp_search_node(node->near, needle, best_candidate);
+ }
+ // The best node (final answer) may be just ouside the radius, but not farther than
+ // the best distance we know so far. The vp_search_node above should have narrowed
+ // best_candidate->distance, so this path is rarely taken.
+ if (node->far && distance >= node->radius - best_candidate->distance) {
+ node = node->far; // Fast tail recursion
+ } else {
+ break;
+ }
+ } else {
+ if (node->far) {
+ vp_search_node(node->far, needle, best_candidate);
+ }
+ if (node->near && distance <= node->radius + best_candidate->distance) {
+ node = node->near; // Fast tail recursion
+ } else {
+ break;
+ }
+ }
+ } while(true);
+}
+
+LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *handle, const f_pixel *px, const int likely_colormap_index, float *diff) {
+ const float guess_diff = colordifference(handle->palette[likely_colormap_index].acolor, *px);
+ if (guess_diff < handle->nearest_other_color_dist[likely_colormap_index]) {
if (diff) *diff = guess_diff;
return likely_colormap_index;
}
- for(unsigned int i=0; /* last head will always be selected */ ; i++) {
- float vantage_point_dist = colordifference(px, heads[i].vantage_point);
-
- if (vantage_point_dist <= heads[i].radius) {
- assert(heads[i].num_candidates);
- unsigned int ind=0;
- float dist = colordifference(px, heads[i].candidates_color[0]);
-
- /* penalty for making holes in IE */
- if (iebug && heads[i].candidates_color[0].a < 1) {
- dist += 1.f/1024.f;
- }
-
- for(unsigned int j=1; j < heads[i].num_candidates; j++) {
- float newdist = colordifference(px, heads[i].candidates_color[j]);
-
- /* penalty for making holes in IE */
- if (iebug && heads[i].candidates_color[j].a < 1) {
- newdist += 1.f/1024.f;
- }
-
- if (newdist < dist) {
- dist = newdist;
- ind = j;
- }
- }
- if (diff) *diff = dist;
- return heads[i].candidates_index[ind];
- }
+ vp_search_tmp best_candidate = {
+ .distance = sqrtf(guess_diff),
+ .idx = likely_colormap_index,
+ .exclude = -1,
+ };
+ vp_search_node(handle->root, px, &best_candidate);
+ if (diff) {
+ *diff = best_candidate.distance * best_candidate.distance;
}
+ return best_candidate.idx;
}
LIQ_PRIVATE void nearest_free(struct nearest_map *centroids)
diff --git a/src/drivers/libimagequant/nearest.h b/src/drivers/libimagequant/nearest.h
index 9745d95..0a98ca6 100644
--- a/src/drivers/libimagequant/nearest.h
+++ b/src/drivers/libimagequant/nearest.h
@@ -4,5 +4,5 @@
//
struct nearest_map;
LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *palette, const bool fast);
-LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *map, const f_pixel px, const int palette_index_guess, const float min_opaque, float *diff);
+LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *map, const f_pixel *px, const int palette_index_guess, float *diff);
LIQ_PRIVATE void nearest_free(struct nearest_map *map);
diff --git a/src/drivers/libimagequant/pam.c b/src/drivers/libimagequant/pam.c
index 647a8aa..d79da64 100644
--- a/src/drivers/libimagequant/pam.c
+++ b/src/drivers/libimagequant/pam.c
@@ -3,7 +3,7 @@
** Copyright (C) 1989, 1991 by Jef Poskanzer.
** Copyright (C) 1997, 2000, 2002 by Greg Roelofs; based on an idea by
** Stefan Schneider.
-** © 2009-2013 by Kornel Lesinski.
+** © 2009-2015 by Kornel Lesinski.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
@@ -105,7 +105,7 @@ LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const rgba
capacity = 8;
if (freestackp <= 0) {
// estimate how many colors are going to be + headroom
- const int mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 1024) * sizeof(struct acolorhist_arr_item);
+ const size_t mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 1024) * sizeof(struct acolorhist_arr_item);
new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
} else {
// freestack stores previously freed (reallocated) arrays that can be reused
@@ -118,7 +118,7 @@ LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const rgba
if (freestackp < stacksize-1) {
freestack[freestackp++] = other_items;
}
- const int mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 32*capacity) * sizeof(struct acolorhist_arr_item);
+ const size_t mempool_size = ((acht->rows + rows-row) * 2 * colors / (acht->rows + row + 1) + 32*capacity) * sizeof(struct acolorhist_arr_item);
new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
if (!new_items) return false;
memcpy(new_items, other_items, sizeof(other_items[0])*achl->capacity);
@@ -158,12 +158,12 @@ LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const rgba
LIQ_PRIVATE struct acolorhash_table *pam_allocacolorhash(unsigned int maxcolors, unsigned int surface, unsigned int ignorebits, void* (*malloc)(size_t), void (*free)(void*))
{
- const unsigned int estimated_colors = MIN(maxcolors, surface/(ignorebits + (surface > 512*512 ? 5 : 4)));
- const unsigned int hash_size = estimated_colors < 66000 ? 6673 : (estimated_colors < 200000 ? 12011 : 24019);
+ const size_t estimated_colors = MIN(maxcolors, surface/(ignorebits + (surface > 512*512 ? 6 : 5)));
+ const size_t hash_size = estimated_colors < 66000 ? 6673 : (estimated_colors < 200000 ? 12011 : 24019);
mempool m = NULL;
- const unsigned int buckets_size = hash_size * sizeof(struct acolorhist_arr_head);
- const unsigned int mempool_size = sizeof(struct acolorhash_table) + buckets_size + estimated_colors * sizeof(struct acolorhist_arr_item);
+ const size_t buckets_size = hash_size * sizeof(struct acolorhist_arr_head);
+ const size_t mempool_size = sizeof(struct acolorhash_table) + buckets_size + estimated_colors * sizeof(struct acolorhist_arr_item);
struct acolorhash_table *t = mempool_create(&m, sizeof(*t) + buckets_size, mempool_size, malloc, free);
if (!t) return NULL;
*t = (struct acolorhash_table){
@@ -244,7 +244,6 @@ LIQ_PRIVATE colormap *pam_colormap(unsigned int colors, void* (*malloc)(size_t),
*map = (colormap){
.malloc = malloc,
.free = free,
- .subset_palette = NULL,
.colors = colors,
};
memset(map->palette, 0, colors_size);
@@ -257,15 +256,11 @@ LIQ_PRIVATE colormap *pam_duplicate_colormap(colormap *map)
for(unsigned int i=0; i < map->colors; i++) {
dupe->palette[i] = map->palette[i];
}
- if (map->subset_palette) {
- dupe->subset_palette = pam_duplicate_colormap(map->subset_palette);
- }
return dupe;
}
LIQ_PRIVATE void pam_freecolormap(colormap *c)
{
- if (c->subset_palette) pam_freecolormap(c->subset_palette);
c->free(c);
}
diff --git a/src/drivers/libimagequant/pam.h b/src/drivers/libimagequant/pam.h
index 835f852..f20e71c 100644
--- a/src/drivers/libimagequant/pam.h
+++ b/src/drivers/libimagequant/pam.h
@@ -29,7 +29,7 @@
#define MAX_DIFF 1e20
#ifndef USE_SSE
-# if defined(__SSE__) && (defined(WIN32) || defined(__WIN32__))
+# if defined(__SSE__) && (defined(__amd64__) || defined(__X86_64__) || defined(_WIN64) || defined(WIN32) || defined(__WIN32__))
# define USE_SSE 1
# else
# define USE_SSE 0
@@ -166,23 +166,6 @@ inline static float colordifference_stdc(const f_pixel px, const f_pixel py)
colordifference_ch(px.b, py.b, alphas);
}
-ALWAYS_INLINE static double min_colordifference_ch(const double x, const double y, const double alphas);
-inline static double min_colordifference_ch(const double x, const double y, const double alphas)
-{
- const double black = x-y, white = black+alphas;
- return MIN(black*black , white*white) * 2.f;
-}
-
-/* least possible difference between colors (difference varies depending on background they're blended on) */
-ALWAYS_INLINE static float min_colordifference(const f_pixel px, const f_pixel py);
-inline static float min_colordifference(const f_pixel px, const f_pixel py)
-{
- const double alphas = py.a-px.a;
- return min_colordifference_ch(px.r, py.r, alphas) +
- min_colordifference_ch(px.g, py.g, alphas) +
- min_colordifference_ch(px.b, py.b, alphas);
-}
-
ALWAYS_INLINE static float colordifference(f_pixel px, f_pixel py);
inline static float colordifference(f_pixel px, f_pixel py)
{
@@ -243,13 +226,13 @@ typedef struct {
typedef struct {
f_pixel acolor;
float popularity;
+ bool fixed; // if true it's user-supplied and must not be changed (e.g in voronoi iteration)
} colormap_item;
typedef struct colormap {
unsigned int colors;
void* (*malloc)(size_t);
void (*free)(void*);
- struct colormap *subset_palette;
colormap_item palette[];
} colormap;
diff --git a/src/drivers/libimagequant/rwpng.c b/src/drivers/libimagequant/rwpng.c
index 4c095ff..07bcf71 100644
--- a/src/drivers/libimagequant/rwpng.c
+++ b/src/drivers/libimagequant/rwpng.c
@@ -5,7 +5,7 @@
---------------------------------------------------------------------------
© 1998-2000 by Greg Roelofs.
- © 2009-2014 by Kornel Lesiński.
+ © 2009-2015 by Kornel Lesiński.
All rights reserved.
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "png.h"
#include "rwpng.h"
@@ -55,8 +56,8 @@
#define omp_get_max_threads() 1
#endif
-#if PNG_LIBPNG_VER < 10600
-//typedef png_const_charp png_const_bytep;
+#if PNG_LIBPNG_VER < 10500
+typedef png_const_charp png_const_bytep;
#endif
static void rwpng_error_handler(png_structp png_ptr, png_const_charp msg);
@@ -70,11 +71,11 @@ void rwpng_version_info(FILE *fp)
const char *pngver = png_get_header_ver(NULL);
#if USE_COCOA
- fprintf(fp, " Using Apple Cocoa image reader and libpng %s.\n", pngver);
+ fprintf(fp, " Color profiles are supported via Cocoa. Using libpng %s.\n", pngver);
#elif USE_LCMS
- fprintf(fp, " Using libpng %s with Little CMS color profile support.\n", pngver);
+ fprintf(fp, " Color profiles are supported via Little CMS. Using libpng %s.\n", pngver);
#else
- fprintf(fp, " Using libpng %s.\n", pngver);
+ fprintf(fp, " Compiled without support for color profiles. Using libpng %s.\n", pngver);
#endif
#if PNG_LIBPNG_VER < 10600
@@ -122,11 +123,7 @@ static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t leng
return;
}
- if (write_state->maximum_file_size && write_state->bytes_written + length > write_state->maximum_file_size) {
- write_state->retval = TOO_LARGE_FILE;
- }
-
- if (!fwrite(data, 1, length, write_state->outfile)) {
+ if (!fwrite(data, length, 1, write_state->outfile)) {
write_state->retval = CANT_WRITE_ERROR;
}
@@ -139,7 +136,7 @@ static void user_flush_data(png_structp png_ptr)
}
-static png_bytepp rwpng_create_row_pointers(png_infop info_ptr, png_structp png_ptr, unsigned char *base, unsigned int height, unsigned int rowbytes)
+static png_bytepp rwpng_create_row_pointers(png_infop info_ptr, png_structp png_ptr, unsigned char *base, unsigned int height, png_size_t rowbytes)
{
if (!rowbytes) {
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
@@ -147,7 +144,7 @@ static png_bytepp rwpng_create_row_pointers(png_infop info_ptr, png_structp png_
png_bytepp row_pointers = malloc(height * sizeof(row_pointers[0]));
if (!row_pointers) return NULL;
- for(unsigned int row = 0; row < height; ++row) {
+ for(size_t row = 0; row < height; row++) {
row_pointers[row] = base + row * rowbytes;
}
return row_pointers;
@@ -188,7 +185,7 @@ static int read_chunk_callback(png_structp png_ptr, png_unknown_chunkp in_chunk)
26 = wrong PNG color type (no alpha channel)
*/
-pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr, int verbose)
+static pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr, int verbose)
{
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
@@ -226,7 +223,6 @@ pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr
png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
-
/* alternatively, could make separate calls to png_get_image_width(),
* etc., but want bit_depth and color_type for later [don't care about
* compression_type and filter_type => NULLs] */
@@ -234,6 +230,11 @@ pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr
png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, &mainprog_ptr->height,
&bit_depth, &color_type, NULL, NULL, NULL);
+ // For overflow safety reject images that won't fit in 32-bit
+ if (mainprog_ptr->width > INT_MAX/mainprog_ptr->height) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return PNG_OUT_OF_MEMORY_ERROR; /* not quite true, but whatever */
+ }
/* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
* transparency chunks to full alpha channel; strip 16-bit-per-sample
@@ -248,7 +249,7 @@ pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr
#else
fprintf(stderr, "pngquant readpng: image is neither RGBA nor GA\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- mainprog_ptr->retval = 26;
+ mainprog_ptr->retval = WRONG_INPUT_COLOR_TYPE;
return mainprog_ptr->retval;
#endif
}
@@ -282,7 +283,7 @@ pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
- if ((mainprog_ptr->rgba_data = malloc(rowbytes*mainprog_ptr->height)) == NULL) {
+ if ((mainprog_ptr->rgba_data = malloc(rowbytes * mainprog_ptr->height)) == NULL) {
fprintf(stderr, "pngquant readpng: unable to allocate image data\n");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return PNG_OUT_OF_MEMORY_ERROR;
@@ -468,7 +469,7 @@ static pngquant_error rwpng_write_image_init(rwpng_png_image *mainprog_ptr, png_
}
-void rwpng_write_end(png_infopp info_ptr_p, png_structpp png_ptr_p, png_bytepp row_pointers)
+static void rwpng_write_end(png_infopp info_ptr_p, png_structpp png_ptr_p, png_bytepp row_pointers)
{
png_write_info(*png_ptr_p, *info_ptr_p);
@@ -481,14 +482,14 @@ void rwpng_write_end(png_infopp info_ptr_p, png_structpp png_ptr_p, png_bytepp r
png_destroy_write_struct(png_ptr_p, info_ptr_p);
}
-void rwpng_set_gamma(png_infop info_ptr, png_structp png_ptr, double gamma)
+static void rwpng_set_gamma(png_infop info_ptr, png_structp png_ptr, double gamma)
{
/* remap sets gamma to 0.45455 */
png_set_gAMA(png_ptr, info_ptr, gamma);
png_set_sRGB(png_ptr, info_ptr, 0); // 0 = Perceptual
}
-pngquant_error rwpng_write_image8(FILE *outfile, const png8_image *mainprog_ptr)
+pngquant_error rwpng_write_image8(FILE *outfile, png8_image *mainprog_ptr)
{
png_structp png_ptr;
png_infop info_ptr;
@@ -554,10 +555,14 @@ pngquant_error rwpng_write_image8(FILE *outfile, const png8_image *mainprog_ptr)
rwpng_write_end(&info_ptr, &png_ptr, mainprog_ptr->row_pointers);
+ if (SUCCESS == write_state.retval && write_state.maximum_file_size && write_state.bytes_written > write_state.maximum_file_size) {
+ return TOO_LARGE_FILE;
+ }
+
return write_state.retval;
}
-pngquant_error rwpng_write_image24(FILE *outfile, const png24_image *mainprog_ptr)
+pngquant_error rwpng_write_image24(FILE *outfile, png24_image *mainprog_ptr)
{
png_structp png_ptr;
png_infop info_ptr;
@@ -605,7 +610,7 @@ static void rwpng_error_handler(png_structp png_ptr, png_const_charp msg)
* regardless of whether _BSD_SOURCE or anything else has (or has not)
* been defined. */
- fprintf(stderr, " error: %s\n", msg);
+ fprintf(stderr, " error: %s (libpng failed)\n", msg);
fflush(stderr);
mainprog_ptr = png_get_error_ptr(png_ptr);
diff --git a/src/drivers/libimagequant/rwpng.h b/src/drivers/libimagequant/rwpng.h
index 28daf7c..b031710 100644
--- a/src/drivers/libimagequant/rwpng.h
+++ b/src/drivers/libimagequant/rwpng.h
@@ -5,7 +5,7 @@
---------------------------------------------------------------------------
© 1998-2000 by Greg Roelofs.
- © 2009-2014 by Kornel Lesiński.
+ © 2009-2015 by Kornel Lesiński.
All rights reserved.
@@ -53,6 +53,7 @@ typedef enum {
WRONG_ARCHITECTURE = 18, // Missing SSE
PNG_OUT_OF_MEMORY_ERROR = 24,
LIBPNG_FATAL_ERROR = 25,
+ WRONG_INPUT_COLOR_TYPE = 26,
LIBPNG_INIT_ERROR = 35,
TOO_LARGE_FILE = 98,
TOO_LOW_QUALITY = 99,
@@ -116,8 +117,8 @@ typedef union {
void rwpng_version_info(FILE *fp);
pngquant_error rwpng_read_image24(FILE *infile, png24_image *mainprog_ptr, int verbose);
-pngquant_error rwpng_write_image8(FILE *outfile, const png8_image *mainprog_ptr);
-pngquant_error rwpng_write_image24(FILE *outfile, const png24_image *mainprog_ptr);
+pngquant_error rwpng_write_image8(FILE *outfile, png8_image *mainprog_ptr);
+pngquant_error rwpng_write_image24(FILE *outfile, png24_image *mainprog_ptr);
void rwpng_free_image24(png24_image *);
void rwpng_free_image8(png8_image *);
diff --git a/src/drivers/libimagequant/viter.c b/src/drivers/libimagequant/viter.c
index 109a165..b578c65 100644
--- a/src/drivers/libimagequant/viter.c
+++ b/src/drivers/libimagequant/viter.c
@@ -1,3 +1,8 @@
+/*
+** © 2011-2015 by Kornel Lesiński.
+** All rights reserved.
+** See COPYRIGHT file for full license.
+*/
#include "libimagequant.h"
#include "pam.h"
@@ -47,19 +52,21 @@ LIQ_PRIVATE void viter_finalize(colormap *map, const unsigned int max_threads, c
total += average_color[offset].total;
}
- if (total) {
+ if (total && !map->palette[i].fixed) {
map->palette[i].acolor = (f_pixel){
.a = a / total,
.r = r / total,
.g = g / total,
.b = b / total,
};
+ } else {
+ total = i/1024.0;
}
map->palette[i].popularity = total;
}
}
-LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, const float min_opaque_val, viter_callback callback, const bool fast_palette)
+LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, viter_callback callback, const bool fast_palette)
{
const unsigned int max_threads = omp_get_max_threads();
viter_state average_color[(VITER_CACHE_LINE_GAP+map->colors) * max_threads];
@@ -73,7 +80,7 @@ LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, cons
schedule(static) default(none) shared(average_color,callback) reduction(+:total_diff)
for(int j=0; j < hist_size; j++) {
float diff;
- unsigned int match = nearest_search(n, achv[j].acolor, achv[j].tmp.likely_colormap_index, min_opaque_val, &diff);
+ unsigned int match = nearest_search(n, &achv[j].acolor, achv[j].tmp.likely_colormap_index, &diff);
achv[j].tmp.likely_colormap_index = match;
total_diff += diff * achv[j].perceptual_weight;
diff --git a/src/drivers/libimagequant/viter.h b/src/drivers/libimagequant/viter.h
index c1a5b39..bbbaaa1 100644
--- a/src/drivers/libimagequant/viter.h
+++ b/src/drivers/libimagequant/viter.h
@@ -14,6 +14,6 @@ typedef void (*viter_callback)(hist_item *item, float diff);
LIQ_PRIVATE void viter_init(const colormap *map, const unsigned int max_threads, viter_state state[]);
LIQ_PRIVATE void viter_update_color(const f_pixel acolor, const float value, const colormap *map, unsigned int match, const unsigned int thread, viter_state average_color[]);
LIQ_PRIVATE void viter_finalize(colormap *map, const unsigned int max_threads, const viter_state state[]);
-LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, const float min_opaque_val, viter_callback callback, const bool fast_palette);
+LIQ_PRIVATE double viter_do_iteration(histogram *hist, colormap *const map, viter_callback callback, const bool fast_palette);
#endif
diff --git a/src/eckit_readers/MvPrepBufrPrep.cc b/src/eckit_readers/MvPrepBufrPrep.cc
index 36e6af5..f8e15a6 100644
--- a/src/eckit_readers/MvPrepBufrPrep.cc
+++ b/src/eckit_readers/MvPrepBufrPrep.cc
@@ -237,7 +237,7 @@ bool MvPrepBufrPrep::createDataDecodeLinks()
MvObsSetIterator iter( obsSet_ );
MvObs obs;
- while( obs = iter() ) //-- search all msgs for the required 'bufrdc' table names
+ while( (obs = iter()) ) //-- search all msgs for the required 'bufrdc' table names
{
if( obs.messageType() == 11 ) //-- skip if msg contains BUFR tables
continue;
diff --git a/src/params/BaseDriver.xml b/src/params/BaseDriver.xml
index dcc3484..7d4ebc2 100644
--- a/src/params/BaseDriver.xml
+++ b/src/params/BaseDriver.xml
@@ -4,42 +4,37 @@
These parameters are common to all the output drivers and can be used whichever output format is selected.
</documentation>
- <parameter member="title" to="string" default="Magics++ plot" from="string" name="output_title">
- <documentation>Defines a title for the output which gets displayed if the format supports it. </documentation>
+ <parameter member="title" to="string" default="Magics plot" from="string" name="output_title">
+ <documentation>Defines a title for the output which gets displayed if the format supports it.</documentation>
</parameter>
-
<parameter member="name" to="string" default="" from="string" name="output_name">
<documentation>Defines the root of output filename.</documentation>
</parameter>
-
<parameter member="firstnumber" to="bool" default="on" from="string" name="output_name_first_page_number">
<documentation>Determines whether, for the first page of multipage output, the number is included in the filename.</documentation>
</parameter>
-
<parameter member="firstvalue" to="int" default="1" from="int" name="output_name_first_page_number_value">
<documentation>Sets the number of the first page. All other pages are number from this value onwards.</documentation>
</parameter>
-
<parameter member="fullname" to="string" default="" from="string" name="output_fullname">
<documentation>Alternative way of specifying the output filename. Will be overwritten by output_name if defined.</documentation>
</parameter>
-
<parameter from="string" name="output_legacy_name" visible="no" default="" member="legacyname" to="string">
<documentation>Alternative way of specifying the output filename. Will be overwritten by output_name if defined.</documentation>
</parameter>
-
<parameter member="numberingwidth" to="int" default="1" from="int" name="output_file_minimal_width">
<documentation>Width of numbering of multi-file outputs (eg, 'plot.1.png' or 'plot.001.png').</documentation>
</parameter>
-
<parameter member="separator" to="string" default="." from="string" name="output_file_separator">
<documentation>Defines the separator between root name and the page number. Default is a dot.</documentation>
</parameter>
-
+ <parameter from="string" name="output_creator" visible="no" default="" member="output_creator" to="string">
+ <documentation for_docs="no">Option for software using magics to put their name and version.</documentation>
+ <release>2.27.0</release>
+ </parameter>
<parameter from="string" name="output_mgb_template" visible="no" default="" member="mgb_template" to="string">
<documentation for_docs="no">Path to the magics binary file to be used as a template</documentation>
</parameter>
-
<parameter member="debug" to="bool" default="off" from="string" name="output_debug">
<documentation>Defines if extra debug information are written in the output file (PS, EPS, SVG) or console (PNG).</documentation>
<release>2.1</release>
@@ -57,18 +52,16 @@
<set name="output_filelist_name" value="on"></set>
<release>2.7.10</release>
</parameter>
-
<parameter member="filelist_name" to="string" default="magics_outputs.lst" from="string" name="output_filelist_name">
<documentation>Defines the name of the file containing the list of generated files.</documentation>
<release>2.7.10</release>
</parameter>
-
<parameter name='output_filelist_reset' from='string' to='bool' member='filelist_reset' default='off'>
<documentation>Defines if the file containing the list of generated files is started from scratch or appends to previous file.</documentation>
<release>2.24.1</release>
</parameter>
-
<parameter from="intarray" name="output_frame_list" visible="no" default="intarray()" member="frame_list" to="intarray">
<documentation for_docs="no">Defines the list of frames to plot ( if empty, all the frames will be plotted!).</documentation>
</parameter>
-</class></magics>
+</class>
+</magics>
diff --git a/src/params/EpsGraph.xml b/src/params/EpsGraph.xml
index 218eea6..264be0a 100644
--- a/src/params/EpsGraph.xml
+++ b/src/params/EpsGraph.xml
@@ -46,7 +46,8 @@
<parameter member="legend_size" to="float" default="0.3" from="float" name="eps_legend_font_size"> </parameter>
<parameter member="legend_forecast_text" to="string" default="" from="string" name="eps_legend_forecast_text"> </parameter>
-
+
+
<parameter member="deterministic" to="bool" default="on" from="string" name="eps_deterministic">
<documentation> plot the deterministic Forecast </documentation>
</parameter>
@@ -60,7 +61,10 @@
<parameter member="deterministic_thickness" to="int" default="2" from="int" name="eps_deterministic_line_thickness">
<documentation>line style of deterministic Forecast </documentation>
</parameter>
- <parameter member="control" to="bool" default="on" from="string" name="eps_control">
+ <parameter member="deterministic_legend" to="string" default="High Resolution" from="string" name="eps_deterministic_legend_text">
+ <documentation> Text to be used in the legend </documentation>
+ </parameter>
+ <parameter member="control" to="bool" default="on" from="string" name="eps_control">
<documentation> plot the deterministic Forecast </documentation>
</parameter>
<parameter member="control_colour" to="Colour" default="red" from="string" name="eps_control_line_colour">
@@ -73,6 +77,10 @@
<parameter member="control_thickness" to="int" default="2" from="int" name="eps_control_line_thickness">
<documentation>line style of deterministic Forecast </documentation>
</parameter>
+
+ <parameter member="control_legend" to="string" default="ENS Control" from="string" name="eps_control_legend_text">
+ <documentation> Text to be used in the legend </documentation>
+ </parameter>
<parameter member="legend" to="bool" default="on" from="string" name="legend">
</parameter>
diff --git a/src/params/MarkerShadingTechnique.xml b/src/params/MarkerShadingTechnique.xml
index b897a00..9cf9faf 100644
--- a/src/params/MarkerShadingTechnique.xml
+++ b/src/params/MarkerShadingTechnique.xml
@@ -9,7 +9,7 @@
<documentation> Height table to be used with MARKER shading technique </documentation>
</parameter>
- <parameter member="type" to="string" default="index" from="string" name="contour_shade_marker_table_type" values="index/name">
+ <parameter member="type" to="string" default="index" from="string" name="contour_shade_marker_table_type" values="index/marker">
<documentation> index: using contour_shade_marker_table and definiing the markers by index, name: using contour_shade_marker_name_table and defining the symbols by their names </documentation>
</parameter>
diff --git a/src/params/PageID.xml b/src/params/PageID.xml
index e940bf1..598069b 100644
--- a/src/params/PageID.xml
+++ b/src/params/PageID.xml
@@ -1,60 +1,58 @@
<magics>
<class directory="common" inherits="NoPageID" prefix="page_id/page_id_line" xmltag="pageid" name="PageID">
-
<parameter member="height" to="float" default="0.25" from="float" name="page_id_line_height">
- <documentation> Height of identification line </documentation>
- <release>2.0 </release>
+ <documentation> Height of identification line</documentation>
+ <release>2.0</release>
</parameter>
- <parameter member="colour" to="Colour" default="blue" from="string" name="page_id_line_colour">
- <documentation> Colour of identification line. Default based on page_y_length </documentation>
- <release>2.0 </release>
+ <parameter member="colour" to="Colour" default="ecmwf_blue" from="string" name="page_id_line_colour">
+ <documentation>Colour of identification line. Default based on page_y_length</documentation>
+ <release>2.0</release>
</parameter>
-
<parameter member="magics" to="bool" default="on" from="string" name="page_id_line_magics">
- <documentation>Display magics version in identification line (ON/OFF) </documentation>
- <release>2.9 </release>
+ <documentation>Display magics version in identification line (ON/OFF)</documentation>
+ <release>2.9</release>
</parameter>
<parameter member="user_text" to="string" default="" from="string" name="page_id_line_user_text">
- <documentation> User-supplied text for inclusion in identification line </documentation>
- <release>2.0 </release>
+ <documentation>User-supplied text for inclusion in identification line</documentation>
+ <release>2.0</release>
</parameter>
<parameter member="system" to="bool" default="on" from="string" name="page_id_line_system_plot">
- <documentation> Plot system part of the identification line (ON/OFF) </documentation>
- <release>2.0 </release>
+ <documentation> Plot system part of the identification line (ON/OFF)</documentation>
+ <release>2.0</release>
</parameter>
<parameter member="date" to="bool" default="on" from="string" name="page_id_line_date_plot">
- <documentation> Plot date part of the identification line (ON/OFF) </documentation>
- <release>2.0 </release>
+ <documentation>Plot date part of the identification line (ON/OFF)</documentation>
+ <release>2.0</release>
</parameter>
<parameter member="errors" to="bool" default="on" from="string" name="page_id_line_errors_plot">
- <documentation> Plot error part of the identification line (ON/OFF) </documentation>
- <release>2.0 </release>
- <release_info> Parameter defined but not implemented: no plan </release_info>
+ <documentation> Plot error part of the identification line (ON/OFF)</documentation>
+ <release>2.0</release>
+ <release_info> Parameter defined but not implemented: no plan</release_info>
</parameter>
<parameter member="text" to="bool" default="on" from="string" name="page_id_line_user_text_plot">
- <documentation> Plot user text part of the identification line (ON/OFF) </documentation>
- <release>2.0 </release>
+ <documentation> Plot user text part of the identification line (ON/OFF)</documentation>
+ <release>2.0</release>
</parameter>
<parameter from="string" name="page_id_line_logo_plot" default="on" member="logo" to="NoLogoPlotting" include="LogoPlotting.h">
- <documentation>Plot logo part of the identification line (ON/OFF) </documentation>
- <option xml="logo" fortran="on" include="LogoPlotting.h" name="LogoPlotting"> </option>
- <option xml="nologo" fortran="off" include="LogoPlotting.h" name="NoLogoPlotting"> </option>
+ <documentation>Plot logo part of the identification line (ON/OFF)</documentation>
+ <option xml="logo" fortran="on" include="LogoPlotting.h" name="LogoPlotting"></option>
+ <option xml="nologo" fortran="off" include="LogoPlotting.h" name="NoLogoPlotting"></option>
</parameter>
<parameter member="font" to="string" default="sansserif" from="string" name="page_id_line_font">
- <documentation> Font to be used </documentation>
- <release>1.3 </release>
+ <documentation>Font to be used</documentation>
+ <release>1.3</release>
</parameter>
<parameter member="font_style" to="string" default="normal" from="string" name="page_id_line_font_style">
- <documentation> Style of the Font to be used </documentation>
- <release>1.3 </release>
+ <documentation> Style of the Font to be used</documentation>
+ <release>1.3</release>
</parameter>
</class></magics>
diff --git a/src/params/TextVisitor.xml b/src/params/TextVisitor.xml
index 70c06af..2e62044 100644
--- a/src/params/TextVisitor.xml
+++ b/src/params/TextVisitor.xml
@@ -94,12 +94,12 @@
</parameter>
- <parameter from="string" name="text_colour" default="blue" member="font_colour" to="Colour" metview_default="navy">
+ <parameter from="string" name="text_colour" default="navy" member="font_colour" to="Colour" metview_default="navy">
<documentation>Colour of text in text block (Full choice of colours) </documentation>
<release>1.0 </release>
</parameter>
- <parameter xml="font" from="string" name="text_font" default="sansserif" member="font" to="string">
+ <parameter xml="font" from="string" name="text_font" default="helvetica" member="font" to="string">
<documentation>Font name - please make sure this font is installed! </documentation>
<release>1.0 </release>
<release_info>Much improved in version 1.3. </release_info>
diff --git a/src/terralib/kernel/TeCentroid.cpp b/src/terralib/kernel/TeCentroid.cpp
index e9c304d..ecfe405 100644
--- a/src/terralib/kernel/TeCentroid.cpp
+++ b/src/terralib/kernel/TeCentroid.cpp
@@ -403,7 +403,7 @@ TeFindCentroidConcavePolygon ( const TePolygon& poly )
// if not able to find a centroid, log an error, but don't stop
if ( NSLICES > NMAXSLICES )
{
- string userText = "Polygon number " + poly.geomId ();
+ string userText = "Polygon number " + Te2String(poly.geomId());
TeErrorLog::instance().insert ( CENTROID_NOT_FOUND, userText );
diff --git a/src/terralib/kernel/TeDatabase.cpp b/src/terralib/kernel/TeDatabase.cpp
index c27806a..df55e56 100644
--- a/src/terralib/kernel/TeDatabase.cpp
+++ b/src/terralib/kernel/TeDatabase.cpp
@@ -36,6 +36,7 @@ of this library and its documentation.
#include <sys/stat.h>
#include <stdio.h>
#include <sstream>
+#include <cstring>
typedef map<int,TeNode> TeNodeMap;
@@ -2075,7 +2076,7 @@ bool TeDatabase::createCollectionTable(const string& tableName)
string collectionId;
unsigned int pos = tableName.rfind("_");
- if ( (pos != std::string::npos ) && (pos+1<tableName.size()) )
+ if ( (pos+1<tableName.size()) )
collectionId = tableName.substr(pos+1);
string idxName = "te_idx_c" + collectionId + "_clegid";
@@ -7202,7 +7203,7 @@ TeDatabase::updateArc(const string& table, TeArc &arc)
sql = "UPDATE"+ table +" SET ";
sql += "from_node=" + Te2String(arc.fromNode().geomId()) + ", ";
sql += "to_node=" + Te2String(arc.toNode().geomId());
- sql += " WHERE geom_id = " + arc.geomId();
+ sql += " WHERE geom_id = " + Te2String(arc.geomId());
return (this->execute(sql));
}
@@ -7420,7 +7421,7 @@ TeDatabase::updateCell(const string& table, TeCell &c)
sql += "upper_y=" + Te2String(b.upperRight().y(),15) + ", ";
sql += "col_number=" + Te2String(c.column()) + ", ";
sql += "row_number=" + Te2String(c.line());
- sql += " WHERE geom_id = " + c.geomId();
+ sql += " WHERE geom_id = " + Te2String(c.geomId());
return (this->execute(sql));
}
@@ -9473,7 +9474,7 @@ TeDatabasePortal::getView(TeView& view, const unsigned int& initIndex)
view.user(getData(initIndex+3));
view.isVisible(getBool(initIndex+4));
view.setCurrentBox(TeBox(getDouble(initIndex+5), getDouble(initIndex+6), getDouble(initIndex+7), getDouble(initIndex+8)));
- if(getData(initIndex+9) == "")
+ if(strncmp(getData(initIndex+9),"",1))
view.setCurrentTheme(-1);
else
view.setCurrentTheme(getInt(initIndex+9));
diff --git a/src/terralib/kernel/TeDecoderDatabase.cpp b/src/terralib/kernel/TeDecoderDatabase.cpp
index 2e41faa..21fc6b4 100644
--- a/src/terralib/kernel/TeDecoderDatabase.cpp
+++ b/src/terralib/kernel/TeDecoderDatabase.cpp
@@ -127,8 +127,8 @@ TeDecoderDatabase::clear()
delete []memAux_;
memAux_ = 0;
params_.status_ = TeRasterParams::TeNotReady;
- if (params_.mode_ == 'c' || params_.mode_ == 'w' &&
- (!params_.objectId_.empty() && params_.layerId_ > 0))
+ if ( ( (params_.mode_ == 'c') || (params_.mode_ == 'w') ) &&
+ ( !params_.objectId_.empty() && (params_.layerId_ > 0) ))
{
TeDatabasePortal* portal = db_->getPortal();
string sql = "SELECT geom_table FROM te_representation WHERE geom_type = 512";
diff --git a/src/terralib/kernel/TeDecoderDatabase.h b/src/terralib/kernel/TeDecoderDatabase.h
index d913536..fe96ea9 100644
--- a/src/terralib/kernel/TeDecoderDatabase.h
+++ b/src/terralib/kernel/TeDecoderDatabase.h
@@ -24,7 +24,7 @@ of this library and its documentation.
\brief This file deals with decoding of raster structures stored in a TerraLib database
*/
-#ifndef __TERRALIB_INTERNAL_DECODERDATADASE_H
+#ifndef __TERRALIB_INTERNAL_DECODERDATABASE_H
#define __TERRALIB_INTERNAL_DECODERDATABASE_H
#include "TeDefines.h"
diff --git a/src/terralib/kernel/TeDecoderMemoryMap.cpp b/src/terralib/kernel/TeDecoderMemoryMap.cpp
index 1a4def6..f93f5ac 100644
--- a/src/terralib/kernel/TeDecoderMemoryMap.cpp
+++ b/src/terralib/kernel/TeDecoderMemoryMap.cpp
@@ -360,7 +360,7 @@ TeDecoderMemoryMap::init()
m_hFile = open(params_.fileName_.c_str(),O_RDWR|O_CREAT,S_IRWXU);
mode = (PROT_READ | PROT_WRITE);
lseek(m_hFile, m_dwSize - 1, SEEK_SET);
- write(m_hFile, '\0', 1);
+ //write(m_hFile, '\0', 1);
}
else if (params_.mode_ == 'r')
{
diff --git a/src/terralib/kernel/TeProjection.cpp b/src/terralib/kernel/TeProjection.cpp
index d389ce3..1fb9b8a 100644
--- a/src/terralib/kernel/TeProjection.cpp
+++ b/src/terralib/kernel/TeProjection.cpp
@@ -2261,6 +2261,7 @@ TeGetTeProjectionFromWKT(const string& wkt)
char* wktchar = new char[wkt.size()];
strcpy(wktchar,wkt.c_str());
bool res = tokenizeWKT((char **) &wktchar, tokens);
+ delete [] wktchar;
if (!res)
return 0;
diff --git a/src/terralib/kernel/TeProxMatrixImplementation.cpp b/src/terralib/kernel/TeProxMatrixImplementation.cpp
index b5a7a17..4966950 100644
--- a/src/terralib/kernel/TeProxMatrixImplementation.cpp
+++ b/src/terralib/kernel/TeProxMatrixImplementation.cpp
@@ -209,7 +209,7 @@ TeProxMatrixGraphBreymann::saveTextFile (const string& name, map<string, string>
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size()); //number of objects
+ fprintf (fp, "%lu\n", ids->size()); //number of objects
map<string, string>::iterator it;
for (unsigned int i = 0; i < graph_.size(); i++)
@@ -264,7 +264,7 @@ TeProxMatrixGraphBreymann::saveGALFile (const string& name, map<string, string>*
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size() ); // first line: number of elements in matrix
+ fprintf (fp, "%lu\n", ids->size() ); // first line: number of elements in matrix
map<string, string>::iterator it;
for (unsigned int i = 0; i < graph_.size(); i++)
{
@@ -277,7 +277,7 @@ TeProxMatrixGraphBreymann::saveGALFile (const string& name, map<string, string>*
objId1 = it->second;
}
- fprintf (fp, "%s %d\n", objId1.c_str(), graph_[i].second.size());
+ fprintf (fp, "%s %lu\n", objId1.c_str(), graph_[i].second.size());
br_stl::Graph<string, TeProxMatrixAttributes>::Successor::iterator
start = graph_[i].second.begin(),
end = graph_[i].second.end();
@@ -313,7 +313,7 @@ TeProxMatrixGraphBreymann::saveGWTFile (const string& name, map<string, string>*
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size() ); // first line: number of elements in matrix
+ fprintf (fp, "%lu\n", ids->size() ); // first line: number of elements in matrix
map<string, string>::iterator it;
for (unsigned int i = 0; i < graph_.size(); i++)
{
@@ -356,7 +356,7 @@ TeProxMatrixGraphBreymann::saveTextFile (const string& name, vector<string>* ids
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size()); //number of objects
+ fprintf (fp, "%lu\n", ids->size()); //number of objects
vector<string>::iterator it = ids->begin();
int Id=1;
@@ -407,7 +407,7 @@ TeProxMatrixGraphBreymann::saveGALFile (const string& name, vector<string>* ids)
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size() ); // first line: number of elements in matrix
+ fprintf (fp, "%lu\n", ids->size() ); // first line: number of elements in matrix
vector<string>::iterator it = ids->begin();
int Id=1;
@@ -459,7 +459,7 @@ TeProxMatrixGraphBreymann::saveGWTFile (const string& name, vector<string>* ids)
FILE* fp = fopen(complete_name.c_str(),"w");
if (fp)
{
- fprintf (fp, "%d\n", ids->size() ); // first line: number of elements in matrix
+ fprintf (fp, "%lu\n", ids->size() ); // first line: number of elements in matrix
vector<string>::iterator it = ids->begin();
int Id=1;
while(it!=ids->end())
diff --git a/src/terralib/kernel/TeRaster.cpp b/src/terralib/kernel/TeRaster.cpp
index 201b9b1..2fbbde6 100644
--- a/src/terralib/kernel/TeRaster.cpp
+++ b/src/terralib/kernel/TeRaster.cpp
@@ -689,14 +689,14 @@ TeRaster::fillRaster(TeRaster* dstRaster, TeRasterTransform* transf, bool bestRe
if (!dstRaster ||
dstRaster->params().status_ != TeRasterParams::TeReadyToWrite)
{
- params_.errorMessage_ == "Destination raster non-existing or not ready to write";
+ params_.errorMessage_ = "Destination raster non-existing or not ready to write";
return false;
}
if (params_.status_ != TeRasterParams::TeReadyToRead &&
params_.status_ != TeRasterParams::TeReadyToWrite)
{
- params_.errorMessage_ == "Raster not ready to be extracted";
+ params_.errorMessage_ = "Raster not ready to be extracted";
return false;
}
diff --git a/src/terralib/kernel/TeStdFile.h b/src/terralib/kernel/TeStdFile.h
index cfe5230..8e92810 100644
--- a/src/terralib/kernel/TeStdFile.h
+++ b/src/terralib/kernel/TeStdFile.h
@@ -24,7 +24,7 @@ of this library and its documentation.
\brief This file contains a class for handling "stdio" files
*/
#ifndef __TERRALIB_INTERNAL_STDFILE_H
-#define __TERRALIB_INTERNAL_STSFILE_H
+#define __TERRALIB_INTERNAL_STDFILE_H
#include "TeDefines.h"
#include <stdio.h>
diff --git a/src/terralib/kernel/TeTin.cpp b/src/terralib/kernel/TeTin.cpp
index 8d796f3..b591b1d 100644
--- a/src/terralib/kernel/TeTin.cpp
+++ b/src/terralib/kernel/TeTin.cpp
@@ -1241,7 +1241,7 @@ TeTin::testDelaunayAt(long t, long v, std::set<long>& triangles)
// If not, change edge between tri and ntri
bool status;
- if ( status = this->swapEdges(t, tviz, e) )
+ if ( (status = this->swapEdges(t, tviz, e)) )
{
triangles.insert(t);
triangles.insert(tviz);
diff --git a/src/terralib/kernel/TeUtils.cpp b/src/terralib/kernel/TeUtils.cpp
index 9357a86..8028459 100644
--- a/src/terralib/kernel/TeUtils.cpp
+++ b/src/terralib/kernel/TeUtils.cpp
@@ -138,7 +138,7 @@ TeGetExtension ( const char* value )
return string("");
string name = string(value);
int len = strlen ( value );
- unsigned int ip = name.rfind('.');
+ size_t ip = name.rfind('.');
if (ip == std::string::npos)
return "";
else
@@ -168,7 +168,7 @@ TeGetBaseName ( const char* value )
return string("");
string name = string(value);
int ip = name.rfind('.');
- unsigned int is = name.rfind('\\');
+ size_t is = name.rfind('\\');
if (is == std::string::npos)
is = name.rfind('/');
return name.substr(is+1,ip-is-1);
diff --git a/src/terralib/kernel/yyTemporal.cpp b/src/terralib/kernel/yyTemporal.cpp
index 01aaa45..7013b55 100644
--- a/src/terralib/kernel/yyTemporal.cpp
+++ b/src/terralib/kernel/yyTemporal.cpp
@@ -360,7 +360,7 @@ yyloop:
}
if (yyerrflag) goto yyinrecovery;
#if defined(lint) || defined(__GNUC__)
- yyerror("syntax error");
+// yyerror("syntax error");
++yynerrs;
#endif
yyinrecovery:
@@ -483,7 +483,7 @@ to state %d\n", YYPREFIX, *yyssp, yystate);
*++yyvsp = yyval;
goto yyloop;
yyoverflow:
- yyerror("yacc stack overflow");
+// yyerror("yacc stack overflow");
yyabort:
return (1);
yyaccept:
diff --git a/src/visualisers/Boundaries.cc b/src/visualisers/Boundaries.cc
index 89ab77c..a4f0b75 100644
--- a/src/visualisers/Boundaries.cc
+++ b/src/visualisers/Boundaries.cc
@@ -70,7 +70,7 @@ void Boundaries::operator()(const map<string, string>& setting, BasicGraphicsObj
boundaries.setPath(file);
vector<string> treaty;
- treaty.push_back("Treaty");
+ treaty.push_back("International boundary");
treaty.push_back("Country_Boundary");
boundaries.decode(task.transformation(), "featurecla", treaty);
@@ -83,7 +83,7 @@ void Boundaries::operator()(const map<string, string>& setting, BasicGraphicsObj
file = share_folder + administrative_boundaries;
admistrative.setPath(file);
- admistrative.decode(task.transformation(),"iso", administrative_list_);
+ admistrative.decode(task.transformation(),"adm0_a3", administrative_list_);
const Transformation& transformation = task.transformation();
for ( ShapeDecoder::const_iterator boundary = admistrative.begin(); boundary != admistrative.end(); ++boundary)
@@ -93,7 +93,6 @@ void Boundaries::operator()(const map<string, string>& setting, BasicGraphicsObj
poly.setThickness(administrative_thickness_);
poly.setLineStyle(administrative_style_);
-
(**boundary).setToFirst();
while ((**boundary).more())
{
@@ -166,6 +165,3 @@ void NoBoundaries::print(ostream& out) const
out << "NoBoundaries[";
out << "]";
}
-
-
-
diff --git a/src/visualisers/CMakeLists.txt b/src/visualisers/CMakeLists.txt
index 1b5ed24..cbd1d18 100644
--- a/src/visualisers/CMakeLists.txt
+++ b/src/visualisers/CMakeLists.txt
@@ -195,7 +195,7 @@ endforeach()
set( visualisers_srcs ${visualisers_srcs} PARENT_SCOPE )
-if ( HAVE_METVIEW )
+if ( metview )
list (APPEND metview_include
visualisers/LegendMethod.h
visualisers/LookupTableMode.h
diff --git a/src/visualisers/Cities.cc b/src/visualisers/Cities.cc
index a571f7c..f2851bb 100644
--- a/src/visualisers/Cities.cc
+++ b/src/visualisers/Cities.cc
@@ -115,7 +115,7 @@ void Cities::operator()(const map<string, string>&, BasicGraphicsObjectContainer
Symbol::TextPosition position = (pos != positions.end() ) ? pos->second : Symbol::M_ABOVE;
- string cities = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "10m/10m_populated_places_simple";
+ string cities = getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + "10m/ne_10m_populated_places_simple";
std::set<string> need;
CustomisedPointsList points;
const Transformation& transformation = task.transformation();
@@ -189,5 +189,3 @@ void NoCities::print(ostream& out) const
out << "NoCities[";
out << "]";
}
-
-
diff --git a/src/visualisers/CoastPlotting.cc b/src/visualisers/CoastPlotting.cc
index 2de1b8d..2edb200 100644
--- a/src/visualisers/CoastPlotting.cc
+++ b/src/visualisers/CoastPlotting.cc
@@ -37,36 +37,11 @@
#include "Polyline.h"
#include "ParameterSettings.h"
-//#define BOOST_VERSION 104701
-#define BOOST_GEOMETRY_OVERLAY_NO_THROW
-
-#include <boost/geometry/geometry.hpp>
-#include <boost/geometry/geometries/point_xy.hpp>
-#include <boost/geometry/geometries/polygon.hpp>
-#include <boost/geometry/geometries/box.hpp>
-
-
-
using namespace magics;
#define PATH(a) getEnvVariable("MAGPLUS_HOME") + MAGPLUS_PATH_TO_SHARE_ + a;
-bool test110(const UserPoint& from, const UserPoint& to)
-{
- if (from.x_ == to.x_ )
- return true;
- if (abs(from.x_ - to.x_) == 360. )
- return true;
- return false;
-}
-
-bool test(const UserPoint& from, const UserPoint& to)
-{
- return ( abs(from.x_ - to.x_ ) > 1 || abs(from.y_ - to.y_ ) > 1);
-}
-
-
CoastPlotting::CoastPlotting()
{
MagLog::debug() << "DELETE COAST PLOTTING! " << endl;
@@ -101,24 +76,10 @@ void CoastPlotting::visit(LegendVisitor& legend)
void CoastPlotting::operator()(PreviewVisitor& parent)
{
const Transformation& transformation = parent.transformation();
- //transformation.coastSetting(coastSet_, 10, 5);
CoastPlotting& preview = parent.coastlines();
transformation.coastSetting(preview.coastSet_, 10, 5);
preview.decode(parent);
- for (vector<Polyline>::iterator poly = preview.ocean_.begin(); poly != preview.ocean_.end(); ++poly)
- {
- Polyline* npoly= poly->clone();
- npoly->setThickness(thickness_);
- npoly->setColour(*colour_);
- npoly->setLineStyle(style_);
- FillShadingProperties* shading = new FillShadingProperties();
- npoly->setFillColour(Colour("white"));
- npoly->setShading(shading);
- npoly->setFilled(true);
- parent.push_back(npoly);
- }
-
for (vector<Polyline>::iterator poly = preview.coast_.begin(); poly != preview.coast_.end(); ++poly)
{
Polyline* npoly= poly->clone();
@@ -129,7 +90,6 @@ void CoastPlotting::operator()(PreviewVisitor& parent)
npoly->setFillColour(Colour("cream"));
npoly->setShading(shading);
npoly->setFilled(true);
-
parent.push_back(npoly);
}
@@ -207,48 +167,37 @@ void CoastPlotting::operator()(DrawingVisitor& parent)
//if ( !layer_) layer_ = &parent;
const Transformation& transformation = parent.transformation();
-
transformation.collect(meta_);
-
-
coast_.clear();
ocean_.clear();
- lake_.clear();
- coastSet_["administrative_boundaries"] = "10m/10m_admin_1_states_provinces_shp";
+ coastSet_["administrative_boundaries"] = "10m/ne_10m_admin_1_states_provinces";
- if ( magCompare(NoCoastPlottingAttributes::resolution_, "full") ) {
- string resol = "10m";
- coastSet_["resolution"] = "10m full";
- coastSet_["lakes"] = resol + "_full/" + resol + "_lakes";
- coastSet_["land"] = resol + "_full/" + resol + "_land";
- coastSet_["rivers"] = resol + "_full/" + resol + "_rivers_lake_centerlines";
- coastSet_["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
- }
- else if ( magCompare(NoCoastPlottingAttributes::resolution_, "high") ) {
+ if ( magCompare(NoCoastPlottingAttributes::resolution_, "high") ||
+ magCompare(NoCoastPlottingAttributes::resolution_, "full") ) {
string resol = "10m";
coastSet_["resolution"] = resol;
- coastSet_["lakes"] = resol + "/" + resol + "_lakes";
- coastSet_["land"] = resol + "/" + resol + "_land";
- coastSet_["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- coastSet_["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
+ coastSet_["land"] = resol + "/ne_" + resol + "_land";
+ coastSet_["ocean"] = resol + "/ne_" + resol + "_ocean";
+ coastSet_["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ coastSet_["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
}
else if ( magCompare(NoCoastPlottingAttributes::resolution_, "medium") ) {
string resol = "50m";
coastSet_["resolution"] = resol;
- coastSet_["lakes"] = resol + "/" + resol + "_lakes";
- coastSet_["land"] = resol + "/" + resol + "_land";
- coastSet_["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- coastSet_["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
+ coastSet_["land"] = resol + "/ne_" + resol + "_land";
+ coastSet_["ocean"] = resol + "/ne_" + resol + "_ocean";
+ coastSet_["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ coastSet_["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
}
else if ( magCompare(NoCoastPlottingAttributes::resolution_, "low") ) {
string resol = "110m";
coastSet_["resolution"] = resol;
- coastSet_["lakes"] = resol + "/" + resol + "_lakes";
- coastSet_["land"] = resol + "/" + resol + "_land";
- coastSet_["rivers"] = resol + "/" + resol + "_rivers_lake_centerlines";
- coastSet_["boundaries"] = resol + "/" + resol + "_admin_0_boundary_lines_land";
+ coastSet_["land"] = resol + "/ne_" + resol + "_land";
+ coastSet_["ocean"] = resol + "/ne_" + resol + "_ocean";
+ coastSet_["rivers"] = resol + "/ne_" + resol + "_rivers_lake_centerlines";
+ coastSet_["boundaries"] = resol + "/ne_" + resol + "_admin_0_boundary_lines_land";
}
else { // automatic
transformation.coastSetting(coastSet_, parent.layout().absoluteWidth(), parent.layout().absoluteHeight());
@@ -277,7 +226,7 @@ void CoastPlotting::operator()(DrawingVisitor& parent)
/*!
- Here we send send a big rectangle for the ocean
+ Here we send a big rectangle for the ocean
We send the coastlines as land and lakes as holes of coastlines as polylines.
*/
void CoastPlotting::landsea(Layout& out)
@@ -287,19 +236,6 @@ void CoastPlotting::landsea(Layout& out)
}
-Polyline* CoastPlotting::ocean(Layout& out)
-{
- const Transformation& transformation = out.transformation();
- Polyline& box = transformation.getPCBoundingBox();
- Polyline* ocean = box.clone();
- setSeaShading(*ocean);
-
- out.push_back(ocean);
- return ocean;
-}
-
-
-
/*!
Here we send the coastlines as land.
We send the lakes as holes ... and the holes in the lakes as land!
@@ -310,8 +246,6 @@ void CoastPlotting::landonly(Layout& out)
{
Polyline* coast = poly->clone();
setLandShading(*coast);
-
-
out.push_back(coast);
}
}
@@ -324,66 +258,21 @@ void CoastPlotting::landonly(Layout& out)
*/
void CoastPlotting::seaonly(Layout& out)
{
- Polyline* big = ocean(out);
-
- for (vector<Polyline>::iterator poly = coast_.begin(); poly != coast_.end(); ++poly)
+ for (vector<Polyline>::iterator poly = ocean_.begin(); poly != ocean_.end(); ++poly)
{
- big->newHole(*poly);
-
- // Now we add the holes as sea polylines!
- for (Polyline::Holes::const_iterator hole = poly->beginHoles(); hole!= poly->endHoles(); ++hole) {
- Polyline* h = poly->getNew();
- setSeaShading(*h);
- poly->hole(hole, *h);
- out.push_back(h);
- }
+ Polyline* coast = poly->clone();
+ setSeaShading(*coast);
+ out.push_back(coast);
}
-
-
}
-#include <boost/geometry/algorithms/distance.hpp>
-
-void CoastPlotting::nolandsea(Layout& visitor)
+void CoastPlotting::nolandsea(Layout& out)
{
-
-
for (vector<Polyline>::iterator coast = coast_.begin(); coast != coast_.end(); ++coast)
{
- if ( coast->empty() )
- continue;
-
- Polyline* poly = new Polyline();
+ Polyline* poly = coast->clone();
setLine(*poly);
- Polyline::MagLine::const_iterator point = coast->begin();
- poly->push_back(*point);
- ++point;
- while ( point!=coast->end() ) {
-
- double dist = point->distance(poly->back());
- double res = tonumber(coastSet_["resolution"]);
-
- if ( dist > visitor.transformation().patchDistance(res) ) {
- if ( !poly->empty() ) {
- visitor.push_back(poly);
- poly = new Polyline();
- setLine(*poly);
- }
- }
-
- poly->push_back(*point);
- ++point;
-
- }
- visitor.push_back(poly);
- // now the lakes!
- for (Polyline::Holes::const_iterator lake = coast->beginHoles(); lake != coast->endHoles(); ++lake) {
- Polyline* poly = new Polyline();
- setLine(*poly);
- for ( Polyline::MagLine::const_iterator point = lake->begin(); point != lake->end(); ++point)
- poly->push_back(*point);
- visitor.push_back(poly);
- }
+ out.push_back(poly);
}
}
@@ -413,7 +302,6 @@ void CoastPlotting::setLandShading(Polyline& line)
{
FillShadingProperties* shading = new FillShadingProperties();
line.setFillColour(*land_colour_);
-
line.setColour(*land_colour_);
line.setShading(shading);
line.setFilled(true);
@@ -440,57 +328,41 @@ void CoastPlotting::decode(const Layout& parent )
{
//Read the shape file ...
Timer timer("geometry", "Simplify+clip");
-
- const Transformation& transformation = parent.transformation();
-
-
-
-
+ const Transformation& transformation = parent.transformation();
vector<Polyline> coastlines;
- vector<Polyline> lakes;
coast_.clear();
-
ShapeDecoder coastline_decoder;
- string file = PATH(coastSet_["land"]);
+ const string file = PATH(coastSet_["land"]);
coastline_decoder.setPath(file);
coastline_decoder.decode(coastlines, transformation);
- ShapeDecoder lake_decoder;
- file = PATH(coastSet_["lakes"]);
- lake_decoder.setPath(file);
- lake_decoder.decode(lakes, transformation);
-
-
-
-
- //! Secondly we try to put the lakes in the continents!!!
for (vector<Polyline>::iterator coast = coastlines.begin(); coast != coastlines.end(); ++coast )
{
- vector<Polyline> todolakes;
- for (vector<Polyline>::iterator l = lakes.begin(); l != lakes.end(); ++l )
- {
- // we find the lake!
- bool inside = l->in(*coast);
- if ( inside )
- {
- coast->newHole(*l);
- }
- else {
- todolakes.push_back(*l);
- }
- }
- lakes = todolakes;
coast_.push_back(*coast);
}
+ if( sea_ )
+ {
+ vector<Polyline> oceans;
+ ocean_.clear();
+ const string file_ocean = PATH(coastSet_["ocean"]);
+ coastline_decoder.setPath(file_ocean);
+ coastline_decoder.decode(oceans, transformation);
+
+ for (vector<Polyline>::iterator coast = oceans.begin(); coast != oceans.end(); ++coast )
+ {
+ ocean_.push_back(*coast);
+ }
+ }
}
void NoCoastPlotting::visit(MetaDataCollector& meta)
{
meta["Coastlines Resolution"] = coastSet_["resolution"];
meta["Coastlines DataSet"] = "Natural Earth";
+ meta["Coastlines Date"] = "February 2015";
for (map<string, string>::const_iterator entry = meta_.begin(); entry != meta_.end(); ++entry ) {
meta[entry->first] = entry->second;
}
diff --git a/src/visualisers/CoastPlotting.h b/src/visualisers/CoastPlotting.h
index 1ba6b0d..9fe1e26 100644
--- a/src/visualisers/CoastPlotting.h
+++ b/src/visualisers/CoastPlotting.h
@@ -54,19 +54,14 @@
Only the following extensions are required for shape files: [ dbf, shp, shx, prj ]. Extensions .sbn and sbx are undocumented formats used only by ESRI software.
- To extract subsets of shape files into other shape files use the ogr2ogr command line utility (from gdal) as follows:
-
- ogr2ogr <output_folder> <input_shape_file>.shp -where "<condition>"
+ The shape files are pre-processed in QGis (version 2.12 in Dec 2015) to make calculation at run time unnecessary.
+ Following actions are performed:
- For example, to ignore minor feature data in the 10m shape files we did the following:
+ - The original Lake and Land files are corrected for errors (Vector -> Geometry Tools -> Check Geometry Validity ...)
+ - The original Land geometries are simplified (Vector -> Geometry Tools -> Multipart to Singlepart ...)
+ - The lakes are subtracted from the Land to create the new Land files to be used in Magics (Vector -> Geoprocessing Tools -> Clip ...)
- ogr2ogr output_folder 10m_lakes.shp -where "ScaleRank < 7"
-
- Where 'ScaleRank' is one of the fields in the shape file. Information on which fields are present are given in the .dbf file (which can be opened with Open Office Spreadsheet).
-
- Conditions can be combined, for example
-
- ogr2ogr output_folder 10m_lakes.shp -where "ScaleRank = 1 AND Name2 != 'Great Lakes'"
+ The same is done with the Ocean and Lake files but in the third step "Union" is used.
*/
@@ -85,6 +80,7 @@
#include "MagTranslator.h"
#include "Polyline.h"
#include "Layer.h"
+
namespace magics {
class PreviewVisitor;
@@ -113,6 +109,7 @@ public :
virtual void layer(BasicGraphicsObjectContainer*) {}
virtual void visit(LegendVisitor&);
virtual void visit(MetaDataCollector&);
+
protected:
//! Method to print string about this class on to a stream of type ostream (virtual).
virtual void print(ostream& out) const { out << "NoCoastPlotting\n"; }
@@ -182,15 +179,11 @@ protected:
void setLine(Polyline&);
void setSeaShading(Polyline&);
void setLandShading(Polyline&);
- Polyline* ocean(Layout&);
string coast_resolution_;
vector<Polyline> coast_;
- vector<Polyline> lake_;
vector<Polyline> ocean_;
-
-
};
@@ -208,7 +201,6 @@ public:
ParameterManager::get(param, val);
return (*this)(val);
}
-
};
} // namespace magics
diff --git a/src/visualisers/EpsGraph.cc b/src/visualisers/EpsGraph.cc
index bee6f8f..7088769 100644
--- a/src/visualisers/EpsGraph.cc
+++ b/src/visualisers/EpsGraph.cc
@@ -506,14 +506,14 @@ public:
class EpsControl : public LegendEntry
{
public:
- EpsControl(double resolution, const string& type, double height) :
+ EpsControl(const string& model, double resolution, const string& type, double height) :
LegendEntry(" "), legend_size_(height)
{
ostringstream title;
// carefull here this text is depending of the resolution!
MagLog::dev() << "EpsControl=>resolution" << resolution << endl;
int km = maground(40000/(2*(resolution+1)+2));
- title << "ENS Control(" + tostring(km) + " km)";
+ title << model << "(" << tostring(km) + " km)";
title_ = title.str();
}
EpsControl(const string& title, double height) : LegendEntry(" "), legend_size_(height)
@@ -548,13 +548,13 @@ protected:
class EpsForecast : public LegendEntry
{
public:
- EpsForecast(double resolution, const string& type, double height) :
+ EpsForecast(const string& model, double resolution, const string& type, double height) :
LegendEntry(" "), legend_size_(height)
{
MagLog::dev() << "EpsForecsat=>resolution" << resolution << endl;
ostringstream title;
- int km = maground(40000/(2*(2*resolution+1)+2));
- title << "High Resolution (" + tostring(km) + " km)";
+ int km = maground(40000/(4*(resolution+1)));
+ title << model << " (" + tostring(km) + " km)";
title_ = title.str();
}
@@ -711,17 +711,11 @@ void EpsGraph::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
forecast->setColour(*deterministic_colour_);
forecast->setThickness(deterministic_thickness_);
forecast->setLineStyle(deterministic_style_);
-
-
-
-
resolution_ = (*points.front())["resolution"];
-
-
- DateTime base = points.front()->base();
+ DateTime base = points.front()->base();
vector<BasicGraphicsObject*> list, list2;
@@ -981,13 +975,15 @@ void EpsGraph::visit(LegendVisitor& legend)
if ( control_ ) {
MagLog::dev() << "LEGEND-> " << legend_control_text_ << endl;
if (legend_control_text_.empty() )
- legend.add(new EpsControl(resolution_, legend_resolution_, legend_size_));
+
+ legend.add(new EpsControl(control_legend_, resolution_, legend_resolution_, legend_size_));
else
+
legend.add(new EpsControl(legend_control_text_, legend_size_));
}
if ( forecast_ ) {
if (legend_forecast_text_.empty() )
- legend.add(new EpsForecast(resolution_, legend_resolution_, legend_size_));
+ legend.add(new EpsForecast(deterministic_legend_, resolution_, legend_resolution_, legend_size_));
else
legend.add(new EpsForecast(legend_forecast_text_, legend_size_));
}
@@ -1341,7 +1337,7 @@ void EpsWind::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
void EpsWave::visit(LegendVisitor& legend)
{
- MagFont font("sansserif", "normal", 0.25);
+ MagFont font(legend.font_, legend.font_style_, tonumber(legend.font_dimension_));
font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
vector<Colour> colours;
colours.push_back(Colour("greenish_blue"));
@@ -1361,7 +1357,7 @@ void EpsWave::visit(LegendVisitor& legend)
void EpsWind::visit(LegendVisitor& legend)
{
if ( !legend_ ) return;
- MagFont font("sansserif", "normal", 0.25);
+ MagFont font(legend.font_, legend.font_style_, tonumber(legend.font_dimension_));
font.colour(Colour("Rgb(0.2, 0.2, 0.2)"));
WindRoseEntry* wind = new WindRoseEntry(*colour_);
@@ -1545,19 +1541,19 @@ void triangle5(const pair<string, float>& direction, CustomisedPoint& point, Bas
double x0 = length;
- double x = x0 * cos(direction.second);
- double y = x0 * sin(direction.second);
- double x1 = x0 * cos(direction.second - shift);
- double y1 = x0 * sin(direction.second - shift);
- double x2 = x0 * cos(direction.second + shift);
- double y2 = x0 * sin(direction.second + shift);
+ double x1 = x0 * cos(direction.second);
+ double y1 = x0 * sin(direction.second);
+ double x = x0 * cos(direction.second - shift);
+ double y = x0 * sin(direction.second - shift);
+ double x2 = x0 * cos(direction.second - (2*shift));
+ double y2 = x0 * sin(direction.second - (2*shift));
- double px = previous * cos(direction.second);
- double py = previous * sin(direction.second);
- double px1 = previous * cos(direction.second - shift);
- double py1 = previous * sin(direction.second - shift);
- double px2 = previous * cos(direction.second + shift);
- double py2 = previous * sin(direction.second + shift);
+ double px1 = previous * cos(direction.second);
+ double py1 = previous * sin(direction.second);
+ double px = previous * cos(direction.second - shift);
+ double py = previous * sin(direction.second - shift);
+ double px2 = previous * cos(direction.second - (2*shift));
+ double py2 = previous * sin(direction.second - (2*shift));
previous = x0;
colour++;
@@ -1593,44 +1589,29 @@ void EpsWave::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
if (points.empty()) return;
-
vector<double> xpos;
-
-
-
DateTime base = points.front()->base();
- for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
+ for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
xpos.push_back((**point)["last"]);
}
-
-
map<string, float> directions;
- //if ( magCompare(convention_, "oceanographic" ) ) {
- directions["east"] = 0 + 3.14;
- directions["nord"] = 3.14 * 0.5 +3.14;
- directions["nord_east"] = 3.14*0.25 +3.14;
- directions["nord_west"] = 3.14*0.75 +3.14;
- directions["south"] = 3.14*1.5 +3.14;
- directions["south_east"] = 3.14*1.75 +3.14;
- directions["south_west"] = 3.14*1.25 +3.14;
- directions["west"] = 3.14 +3.14;
-// }
-// else {
-// directions["east"] = 0;
-// directions["nord"] = 3.14 * 0.5;
-// directions["nord_east"] = 3.14*0.25;
-// directions["nord_west"] = 3.14*0.75;
-// directions["svisitorh"] = 3.14*1.5;
-// directions["svisitorh_east"] = 3.14*1.75;
-// directions["svisitorh_west"] = 3.14*1.25;
-// directions["west"] = 3.14;
-// }
+ directions["east"] = 0 + 3.14;
+ directions["nord"] = 3.14 * 0.5 +3.14;
+ directions["nord_east"] = 3.14*0.25 +3.14;
+ directions["nord_west"] = 3.14*0.75 +3.14;
+ directions["south"] = 3.14*1.5 +3.14;
+ directions["south_east"] = 3.14*1.75 +3.14;
+ directions["south_west"] = 3.14*1.25 +3.14;
+ directions["west"] = 3.14 +3.14;
+
+
for (CustomisedPointsList::const_iterator point = points.begin(); point != points.end(); ++point) {
double total = 0;
+
for ( map<string, float>::const_iterator direction = directions.begin(); direction != directions.end(); ++direction) {
if ( (*point)->find(direction->first) == (*point)->end() ) {
@@ -1669,15 +1650,15 @@ void EpsWave::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
double x = (**point)["step"] + (**point)["shift"];
- Polyline* grid = new Polyline();
- grid->setColour(Colour("grey"));
- grid->setThickness(2);
- grid->setLineStyle(M_DOT);
- scale = 200;
- double l100 = 12*3600;
- for (float angle = 0; angle <= 2; angle+=0.1)
- grid->push_back(PaperPoint(x +(l100 * cos(3.14*angle)) , l100 * sin(3.14*angle)));
- visitor.push_back(grid);
+ Polyline* grid = new Polyline();
+ grid->setColour(Colour("grey"));
+ grid->setThickness(2);
+ grid->setLineStyle(M_DOT);
+ scale = 200;
+ double l100 = 12*3600;
+ for (float angle = 0; angle <= 2; angle+=0.1)
+ grid->push_back(PaperPoint(x +(l100 * cos(3.14*angle)) , l100 * sin(3.14*angle)));
+ visitor.push_back(grid);
@@ -1691,6 +1672,34 @@ void EpsWave::operator()(Data& data, BasicGraphicsObjectContainer& visitor)
{
triangle5(*direction, **point, visitor, x, ms);
}
+
+ // Draw the Control
+ if ( (*point)->find("control") != (*point)->end() ) {
+ Polyline* control = new Polyline();
+ control->setColour(Colour("red"));
+ control->setThickness(2);
+ control->setLineStyle(M_DASH);
+
+ double angle = (**point)["control"] - 180.;
+
+ control->push_back(PaperPoint(x , 0));
+ control->push_back(PaperPoint(x +(l100 * sin(angle*(3.14/180.))), l100 * cos(angle*(3.14/180.))));
+ visitor.push_back(control);
+ }
+
+ // Draw the Forecast
+ if ( (*point)->find("forecast") != (*point)->end() ) {
+ Polyline* hres = new Polyline();
+ hres->setColour(Colour("blue"));
+ hres->setThickness(2);
+ hres->setLineStyle(M_SOLID);
+
+
+ double angle = (**point)["forecast"]-180;
+ hres->push_back(PaperPoint(x , 0));
+ hres->push_back(PaperPoint(x +(l100 * sin(angle*(3.14/180.))), l100 * cos(angle*(3.14/180.))));
+ visitor.push_back(hres);
+ }
}
diff --git a/src/visualisers/EpsGraph.h b/src/visualisers/EpsGraph.h
index abb4202..3c77f78 100644
--- a/src/visualisers/EpsGraph.h
+++ b/src/visualisers/EpsGraph.h
@@ -64,7 +64,7 @@ public:
virtual void operator()(Data&, BasicGraphicsObjectContainer&);
virtual void visit(LegendVisitor&);
-
+ bool needLegend() { return legend_; }
// Implements the set method ...
void set(const map<string, string>& map ) { EpsGraphAttributes::set(map); }
diff --git a/src/visualisers/MetgramStyle.cc b/src/visualisers/MetgramStyle.cc
index cdf39f2..a6c8f18 100644
--- a/src/visualisers/MetgramStyle.cc
+++ b/src/visualisers/MetgramStyle.cc
@@ -78,12 +78,14 @@ DateTime readDate(CustomisedPoint& point)
MagDate date1((long)point["year"], (long)point["month"], (long)point["day"]);
magics::MagTime time((long)point["hours"], (long)point["minutes"], (long)point["seconds"]);
- //time -= Second(point["shift"] * 3600);
+ time -= Second(point["shift"] * 3600);
return DateTime(date1, time);
}
void MetgramBar::operator()(CustomisedPointsList& points, BasicGraphicsObjectContainer& visitor)
{
+ if ( points.empty() )
+ return;
vector<double> xpos;
vector<double> limits;
vector<double> ypos;
@@ -173,6 +175,8 @@ void MetgramBar::operator()(CustomisedPointsList& points, BasicGraphicsObjectCon
void MetgramCurve::operator()(CustomisedPointsList& points, BasicGraphicsObjectContainer& visitor)
{
+ if ( points.empty() )
+ return;
Polyline* curve1 = new Polyline();
curve1->setColour(*colour_);
curve1->setThickness(thickness_);
@@ -271,6 +275,8 @@ void MetgramCurve::operator()(CustomisedPointsList& points, BasicGraphicsObjectC
void MetgramFlags::operator()(CustomisedPointsList& points, BasicGraphicsObjectContainer& visitor)
{
+ if ( points.empty() )
+ return;
MagDate date((long)(*points.front())["year"], (long)(*points.front())["month"], (long)(*points.front())["day"]);
MagTime time((long)(*points.front())["hours"], (long)(*points.front())["minutes"], (long)(*points.front())["seconds"]);
DateTime base = DateTime(date, time);
diff --git a/src/visualisers/ObsItemFamily.cc b/src/visualisers/ObsItemFamily.cc
index d8373d9..51dd06a 100644
--- a/src/visualisers/ObsItemFamily.cc
+++ b/src/visualisers/ObsItemFamily.cc
@@ -131,15 +131,6 @@ void ObsCloudAndWind::operator()( CustomisedPoint& point, ComplexSymbol& symbol)
MagLog::debug() << " >>> "<<it->first<<" -> " << it->second << endl;
}
symbol.setHeight(owner_->size_);
- CustomisedPoint::const_iterator speed = point.find("wind_speed");
- if ( speed == point.end() ) return;
- CustomisedPoint::const_iterator direction = point.find("wind_direction");
- if ( direction == point.end() ) return;
-
- FlagItem* flag = new FlagItem();
- flag->setColour(colour);
- flag->length(owner_->size_*2.5); // Size to be adjusted later!
-
int total_cloud = maground((point["total_cloud"]/100.)*8);
MagLog::debug() << "total_cloud-->" << point["total_cloud"] << "--->" << total_cloud << endl;
@@ -156,7 +147,37 @@ void ObsCloudAndWind::operator()( CustomisedPoint& point, ComplexSymbol& symbol)
}
-MagLog::debug() << "OBS ITEM - ObsWind - Lon/Lat: "<<point.longitude()<<" / "<<point.latitude()
+ CustomisedPoint::const_iterator ispeed = point.find("wind_speed");
+ double speed = ( ispeed == point.end() ) ? 0 : ispeed->second;
+ CustomisedPoint::const_iterator idirection = point.find("wind_direction");
+ double direction = ( idirection == point.end() ) ? 0 : idirection->second;
+
+ if ( speed == 0 && direction == 0) {
+ // No wind information ...Just plot the nebulosity
+ SymbolItem* object = new SymbolItem();
+ object->x(0);
+ object->y(0);
+
+
+ object->colour(colour);
+
+
+ object->symbol(origin);
+
+ object->height(owner_->ring_size_*.35);
+
+ symbol.add(object);
+ return;
+ }
+
+ FlagItem* flag = new FlagItem();
+ flag->setColour(colour);
+ flag->length(owner_->size_*2.5); // Size to be adjusted later!
+
+
+
+
+ MagLog::debug() << "OBS ITEM - ObsWind - Lon/Lat: "<<point.longitude()<<" / "<<point.latitude()
<< "\n\twind_speed: " << point["wind_speed"]
<< "\n\twind_direction: " << point["wind_direction"]
<< "\n\tcloud amount: " << point["total_cloud"]<< "--->" << total_cloud << "--->" << origin << std::endl;
@@ -168,11 +189,11 @@ MagLog::debug() << "OBS ITEM - ObsWind - Lon/Lat: "<<point.longitude()<<" / "<<p
const Transformation& transformation = symbol.parent().transformation();
PaperPoint pp(point.longitude(), point.latitude());
- std::pair<double, double> wind = std::make_pair(speed->second, direction->second);
+ std::pair<double, double> wind = std::make_pair(speed, direction);
transformation.reprojectSpeedDirection(pp, wind);
- flag->speed(speed->second);
- flag->direction(direction->second);
+ flag->speed(speed);
+ flag->direction(direction);
if (point.latitude() <0 )
flag->setHemisphere(SOUTH);
diff --git a/src/visualisers/Streamlines.cc b/src/visualisers/Streamlines.cc
index 57daf6b..bf52b45 100644
--- a/src/visualisers/Streamlines.cc
+++ b/src/visualisers/Streamlines.cc
@@ -59,7 +59,11 @@ bool Streamlines::operator()(Data& data, BasicGraphicsObjectContainer& parent)
MatrixHandler& handler = *geo.prepareData(data.direction());
-
+ // We filter !
+ cout << "left->" << handler.left() << endl;
+ cout << "right->" << handler.right() << endl;
+ cout << "top->" << handler.top() << endl;
+ cout << "bottom->" << handler.bottom() << endl;
float* direction = new float[handler.rows()*handler.columns()];
int i = 0;
diff --git a/src/web/WrepJSon.cc b/src/web/WrepJSon.cc
index c8517ee..cd1a27c 100644
--- a/src/web/WrepJSon.cc
+++ b/src/web/WrepJSon.cc
@@ -864,6 +864,8 @@ void WrepJSon::cdf()
// setminmax ...
minx_ = std::numeric_limits<double>::max();
maxx_ = -std::numeric_limits<double>::max();
+ minClim_ = std::numeric_limits<double>::max();
+ maxClim_ = -std::numeric_limits<double>::max();
for (map<string, InputWrep>::iterator info = eps_.begin(); info != eps_.end(); ++info) {
// find the index in the steps..
@@ -885,6 +887,8 @@ void WrepJSon::cdf()
double value = correctEpsz(val->second[index]);
if ( minx_ > value ) minx_ = value;
if ( maxx_ < value ) maxx_ = value;
+ if ( minClim_ > value ) minClim_ = value;
+ if ( maxClim_ < value ) maxClim_ = value;
}
@@ -1297,36 +1301,42 @@ void WrepJSon::visit(TextVisitor& text)
if (height_ != -9999 )
text.update("json", "height", height.str());
text.update("json", "location", location.str());
- text.update("json", "grid_point", (mask_ < 0.5 ) ? " (EPS sea point) " : " (EPS land point) ");
+ text.update("json", "grid_point", (mask_ < 0.5 ) ? " (ENS sea point) " : " (ENS land point) ");
}
ostringstream full_correction;
ostringstream short_correction;
+
+
+
+
int dett = (points_along_meridian_ * 2) -1;
int epst = points_along_meridian_ -1;
+
if ( (correction_ && height_ != -9999 && param_info_!= "none") ) {
- full_correction << " reduced to " << height_ << " m (station height) from " << maground(detz_) << " m (T" << dett << ") and " << maground(epsz_) << " m (T" << epst <<")";
- short_correction << " reduced to " << height_ << " m (station height) from " << maground(epsz_) << " m (T" << epst <<")";
+ full_correction << " reduced to " << height_ << " m (station height) from " << maground(detz_) << " m (HRES) and " << maground(epsz_) << " m (ENS)";
+ short_correction << " reduced to " << height_ << " m (station height) from " << maground(epsz_) << " m (ENS)";
}
+
+
text.update("json", "full_temperature_correction_info", full_correction.str());
text.update("json", "short_temperature_correction_info", short_correction.str());
text.update("json", "parameter_info", (param_info_ == "none") ? "": param_info_ );
- if (param_info_ != "none")
+ if (param_info_ != "none") {
text.update("json", "station_name", station_name_);
+ if ( !expver_.empty() && expver_ != "0001")
+ text.update("json", "expver", " [" + expver_ + "] ");
-
- if ( !expver_.empty() && expver_ != "0001") {
- text.update("json", "expver", " [" + expver_ + "] ");
- }
+ }
text.update("json", "product_info", product_info_);
text.update("json", "plumes_interval", tostring(plumes_));
text.update("json", "efi_date", valid_time_);
- text.update("json", "min_max_values", "Max = " + tostring(maground(maxx_)) + ", Min = " + tostring(maground(minx_)));
+ text.update("json", "min_max_values", "Max = " + tostring(maground(maxClim_)) + ", Min = " + tostring(maground(minClim_)));
}
void WrepJSon::points(const Transformation& transformation, vector<UserPoint>& points)
diff --git a/src/web/WrepJSon.h b/src/web/WrepJSon.h
index 5269120..a3720bb 100644
--- a/src/web/WrepJSon.h
+++ b/src/web/WrepJSon.h
@@ -185,6 +185,8 @@ protected:
PointsList list_;
double minx_;
double maxx_;
+ double minClim_;
+ double maxClim_;
double miny_;
double maxy_;
double shift_;
diff --git a/utils/GRA01130000012300001 b/utils/GRA01130000012300001
new file mode 100644
index 0000000..159047c
Binary files /dev/null and b/utils/GRA01130000012300001 differ
diff --git a/utils/bufrgram.py b/utils/bufrgram.py
new file mode 100644
index 0000000..24e0e1e
--- /dev/null
+++ b/utils/bufrgram.py
@@ -0,0 +1,324 @@
+
+from Magics.macro import *
+import datetime
+import sys
+
+
+
+
+
+def bufrgram(data):
+
+
+ out = output(
+ output_formats="ps",
+ output_name_first_page_number='off',
+ output_name="bufrgram" ,
+ super_page_y_length=29.7,
+ super_page_x_length=21.,
+ )
+
+ y = 4.5
+ last = 22.5
+ suby = 3.
+ # define the cartesian projection
+ frame1 = page(
+ layout='positional',
+ page_x_length= 21.,
+ page_y_length= y+3.,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position= last
+ )
+ last = last - y;
+ projection = mmap(
+ subpage_map_projection='cartesian',
+ subpage_x_axis_type='date',
+ subpage_x_automatic='on',
+ subpage_y_axis_type='regular',
+ subpage_y_automatic='on',
+ subpage_y_length = suby,
+ subpage_y_position = 0.5
+ )
+ font_size = 0.35
+ # define horizontal axis
+
+ horizontal = maxis(
+ axis_orientation = "horizontal",
+ axis_date_type = "days",
+ axis_days_label = "both",
+ axis_days_label_colour= "navy",
+ axis_days_label_height = font_size,
+ axis_grid = "on",
+ axis_grid_colour = "navy",
+ axis_grid_line_style= "dash",
+ axis_line_colour= "navy",
+ axis_minor_tick= "on",
+ axis_minor_tick_colour= "navy",
+ axis_months_label= "off",
+ axis_tick_colour= "navy",
+ axis_type = "date",
+ axis_years_label = "off"
+ )
+
+
+ # define vertical axis
+
+ vertical = maxis(
+ axis_orientation = "vertical",
+ axis_grid = "on",
+ axis_grid_colour ="navy",
+ axis_grid_line_style = "dash",
+ axis_grid_reference_level = 0.,
+ axis_grid_reference_thickness = 1,
+ axis_line = "on",
+ axis_line_colour = "navy",
+ axis_tick_colour = "navy",
+ axis_tick_label_colour = "navy",
+ axis_tick_label_height = font_size
+ )
+
+ cc_data = mmetbufr(
+ epsbufr_parameter_title = "Cloud Amount (%)",
+ epsbufr_parameter_descriptor = 20010,
+ epsbufr_information = "on",
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ epsbufr_station_name = data["epsbufr_station_name"],
+
+
+ )
+ cc_graph = mmetgraph( eps_box_border_thickness = 2,
+ eps_box_width = 1.5,
+ metgram_plot_style = 'bar')
+ cc_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = ["<font size='0.5'> <json_info key='station_info'/></font>",
+ "<font size='0.5'> <json_info key='date'/></font>",
+ "<font size='0.5'> . </font>",
+ "<font size='0.4'> <json_info key='parameter_info'/></font> "]
+ )
+
+ frame2 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last -y;
+ rh_data = mmetbufr(
+ epsbufr_parameter_title = "850 hPa Relative Humidity (%)",
+ epsbufr_parameter_descriptor = 13003,
+ epsbufr_information = "on",
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ rh_graph = mmetgraph( )
+ rh_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = [
+ "<font size='0.4'> <json_info key='parameter_info'/></font> "]
+ )
+
+ frame3 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last -y;
+ precip_data = mmetbufr(
+
+ epsbufr_accumulated_parameter = "on",
+ epsbufr_parameter_title = "Precipitation",
+ epsbufr_parameter_descriptor = 13011,
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ precip_graph = mmetgraph(
+ metgram_plot_style = 'bar'
+ )
+ precip_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = [
+ "<font size='0.4'> <json_info key='parameter_info'/></font> "]
+ )
+ frame4 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last - (y/2) -0.5;
+ msl_data = mmetbufr(
+ epsbufr_parameter_scaling_factor = 0.01,
+ epsbufr_parameter_title = "MSL Pressure (hPa)",
+ epsbufr_parameter_descriptor = 10051,
+ epsbufr_information = "on",
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ msl_graph = mmetgraph(
+ )
+ msl_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = [
+ "<font size='0.4'> <json_info key='parameter_info'/></font> "]
+ )
+
+
+ frame5 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length= y/2,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+ wind_projection = mmap(
+ subpage_map_projection='cartesian',
+ subpage_x_axis_type='date',
+ subpage_x_automatic='on',
+ subpage_y_axis_type='regular',
+ subpage_y_min = -1.,
+ subpage_y_max = 1.,
+ subpage_y_length = suby/2,
+ subpage_y_position = 0.5
+ )
+ wind_vertical = maxis(
+ axis_orientation = "vertical",
+ axis_grid = "off",
+ axis_tick = "off",
+ axis_tick_label = "off",
+ )
+
+
+ last = last -y;
+ wind_data = mmetbufr(
+ epsbufr_parameter_title = "10m Wind (m/s)",
+ epsbufr_parameter_descriptor = 11003,
+ epsbufr_parameter_2_descriptor = 11004,
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ wind_graph = mmetgraph(
+ metgram_plot_style = 'flags'
+ )
+ wind_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = [
+ "<font size='0.4'> <json_info key='parameter_info'/></font> "]
+ )
+ frame6 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last - y;
+
+ min_data = mmetbufr(
+ epsbufr_parameter_title = "Temperature (C)",
+ epsbufr_parameter_descriptor = 12001,
+ epsbufr_information = "on",
+ epsbufr_parameter_offset_factor = -273.15,
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ min_graph = mmetgraph( metgram_curve_colour = "blue"
+ )
+ max_data = mmetbufr(
+ epsbufr_parameter_title = "",
+ epsbufr_parameter_descriptor = 12004,
+ epsbufr_information = "on",
+ epsbufr_parameter_offset_factor = -273.15,
+ epsbufr_input_filename = data["epsbufr_input_filename"],
+ epsbufr_station_latitude = data["epsbufr_station_latitude"],
+ epsbufr_station_longitude = data["epsbufr_station_longitude"],
+ )
+ max_graph = mmetgraph( metgram_curve_colour = "red"
+ )
+ tempe_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_lines = [
+ "<font size='0.4'> <json_info key='parameter_info'/> </font> "]
+ )
+
+ plot(
+ out,
+ frame1,
+ projection,
+ horizontal,
+ vertical,
+ cc_data, cc_graph, cc_text,
+ frame2,
+ projection,
+ horizontal,
+ vertical,
+ rh_data, rh_graph, rh_text,
+ frame3,
+ projection,
+ horizontal,
+ vertical,
+ precip_data, precip_graph, precip_text,
+ frame4,
+ projection,
+ horizontal,
+ vertical,
+ msl_data, msl_graph, msl_text,
+ frame5,
+ wind_projection,
+ horizontal,
+ wind_vertical,
+ wind_data, wind_graph, wind_text,
+ frame6,
+ projection,
+ horizontal,
+ vertical,
+ min_data, min_graph, max_data, max_graph, tempe_text,
+ )
+
+
+
+def main():
+ data = {
+ "epsbufr_input_filename" : "GRA01130000012300001",
+ "epsbufr_station_latitude" : 38.72,
+ "epsbufr_station_longitude" : 30.51,
+ "epsbufr_station_name" : "My Station",
+ }
+ bufrgram(data)
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/utils/epsgrams.py b/utils/epsgrams.py
new file mode 100644
index 0000000..913edf8
--- /dev/null
+++ b/utils/epsgrams.py
@@ -0,0 +1,424 @@
+import traceback
+import sys
+
+from gribapi import *
+import json
+from Magics.macro import *
+import numpy
+import datetime
+
+
+
+reference = datetime.datetime.now()
+
+def filename(path, param, type):
+ return ( "%s/%s_%s.grib" % (path, type, param) )
+
+
+def getdata(key, path, param, index, out):
+
+ f = open( filename(path, param, key))
+
+ mcount = grib_count_in_file(f)
+
+ if key == "deterministic":
+ key = "forecast"
+
+ for i in range(mcount):
+ gid = grib_new_from_file(f)
+ if i == 0 :
+ #param = str(grib_get(gid, "parameter"))
+
+ for l in range(len(index)):
+ out[l][param][key] = []
+
+ values = grib_get_elements(gid,"values",index)
+ for l in range(len(index)):
+
+ out[l][param][key].append(values[l])
+ grib_release(gid)
+ f.close()
+ return
+
+
+def control(path, param, index, out ):
+
+
+ f = open( filename(path, param, "control"))
+
+ mcount = grib_count_in_file(f)
+
+ for i in range(mcount):
+ gid = grib_new_from_file(f)
+ step = str(grib_get(gid, "step"))
+ if i == 0 :
+ #param = str(grib_get(gid, "parameter"))
+ date = str(grib_get(gid, "date"))
+ time = "%02d" % grib_get(gid, "time")
+
+
+ for l in range(len(index)):
+ out[l][param] = {}
+ out[l]["date"] = date
+ out[l]["time"] = time
+ out[l][param]["control"] = []
+ out[l][param]["steps"] = []
+
+ reference = datetime.datetime.strptime(date+time, '%Y%m%d%H%M')
+ values = grib_get_elements(gid,"values",index)
+ for l in range(len(index)):
+ out[l][param]["control"].append(values[l])
+ out[l][param]["steps"].append(step)
+ grib_release(gid)
+ f.close()
+ return
+
+
+
+def data(stations, param, path):
+ out = []
+ index = []
+
+ lsm = open("%s/lsm.cf" % (path,) )
+
+ detz_file = open("%s/det.z" % (path,) )
+ epsz_file = open("%s/eps.z" % (path,) )
+ gid = grib_new_from_file(lsm)
+ detz = grib_new_from_file(detz_file)
+ epsz = grib_new_from_file(epsz_file)
+
+
+ for station in stations:
+ nearest = grib_find_nearest(gid,station["lat"],station["lon"],1)
+ name = "%.2f_%.2f_%s.json" % (station["lat"], station["lon"], param)
+
+ out.append({
+ "station_name" : station["name"],
+ "output" : name,
+ "height": 8000.,
+ "metadata": {
+ "points_along_meridian" : grib_get(gid, "Nj"),
+ "deterministic_height": 142.679443359,
+ "eps_height": 149.973892212,
+ },
+ "location" : { "lat" : station["lat"], "lon" : station["lon"] },
+ "EPS_location" : { "distance": nearest[0].distance, "latitude" : nearest[0].lat, "longitude" : nearest[0].lon },
+ "forecast_location" : { "distance": nearest[0].distance, "latitude" : nearest[0].lat, "longitude" : nearest[0].lon },
+ })
+
+
+ index.append(nearest[0].index)
+ station[param] = name
+
+ eps = grib_get_elements(epsz,"values",index)
+ det = grib_get_elements(detz,"values",index)
+ for l in range(len(index)):
+ out[l]["metadata"]["deterministic_height"] = det[l]
+ out[l]["metadata"]["eps_height"] = eps[l]
+
+ grib_release(gid)
+ grib_release(detz)
+ grib_release(epsz)
+ lsm.close()
+ epsz_file.close()
+ detz_file.close()
+
+
+
+ control( path, param, index, out )
+ getdata("deterministic", path, param, index, out)
+ getdata("max", path, param, index, out)
+ getdata("min", path, param, index, out)
+ getdata("median", path, param, index, out)
+ getdata("ninty", path, param, index, out)
+ getdata("seventyfive", path, param, index, out)
+ getdata("twentyfive", path, param, index, out)
+ getdata("ten", path, param, index, out)
+
+
+ for i in out:
+ f = open("%s.data" % (param, ), 'w')
+ print >> f, json.dumps(i, indent=4, separators=(',', ': ') )
+
+
+
+def epsgrams(location):
+
+ z500 = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "z500")
+ precip = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "precip")
+ t850 = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "t850")
+
+ out = output(
+ output_formats=location["output_formats"],
+ output_name_first_page_number='off',
+ output_name=str(location["output_name"]) ,
+ super_page_y_length=29.7,
+ super_page_x_length=21.,
+ )
+
+ y = 6.
+ last = 21.5
+ suby = 4.5
+ # define the cartesian projection
+ frame1 = page(
+ layout='positional',
+ page_x_length= 21.,
+ page_y_length= y+3.,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position= last
+ )
+ last = last - y;
+ projection = mmap(
+ subpage_map_projection='cartesian',
+ subpage_x_axis_type='date',
+ subpage_x_automatic='on',
+ subpage_y_axis_type='regular',
+ subpage_y_automatic='on',
+ subpage_y_length = suby,
+ subpage_y_position = 0.5
+ )
+ font_size = 0.35
+ # define horizontal axis
+
+ horizontal = maxis(
+ axis_orientation = "horizontal",
+ axis_date_type = "days",
+ axis_days_label = "both",
+ axis_days_label_colour= "navy",
+ axis_days_label_height = font_size,
+ axis_grid = "on",
+ axis_grid_colour = "navy",
+ axis_grid_line_style= "dash",
+ axis_line_colour= "navy",
+ axis_minor_tick= "on",
+ axis_minor_tick_colour= "navy",
+ axis_months_label= "off",
+ axis_tick_colour= "navy",
+ axis_type = "date",
+ axis_years_label = "off"
+ )
+
+ # horizontal axis for bottom plot (with month and year)
+
+ horizontal_bot = maxis(
+ axis_orientation = "horizontal",
+ axis_date_type = "days",
+ axis_days_label = "both",
+ axis_days_label_colour= "navy",
+ axis_days_label_height = font_size,
+ axis_grid = "on",
+ axis_grid_colour = "navy",
+ axis_grid_line_style= "dash",
+ axis_line_colour= "navy",
+ axis_minor_tick= "on",
+ axis_minor_tick_colour= "navy",
+ axis_months_label= "on",
+ axis_months_label_colour= "navy",
+ axis_months_label_height = font_size,
+ axis_tick_colour= "navy",
+ axis_type = "date",
+ axis_years_label = "on",
+ axis_years_label_colour= "navy",
+ axis_years_label_height = font_size
+ )
+
+ # define vertical axis
+
+ vertical = maxis(
+ axis_orientation = "vertical",
+ axis_grid = "on",
+ axis_grid_colour ="navy",
+ axis_grid_line_style = "dash",
+ axis_grid_reference_level = 0.,
+ axis_grid_reference_thickness = 1,
+ axis_line = "on",
+ axis_line_colour = "navy",
+ axis_tick_colour = "navy",
+ axis_tick_label_colour = "navy",
+ axis_tick_label_height = font_size
+ )
+
+ cc_data = mwrepjson(
+ wrepjson_family = "eps",
+ wrepjson_input_filename = "tcc.data",
+ wrepjson_parameter = "tcc",
+ wrepjson_parameter_information = "Total Cloud Cover (okta) ",
+ wrepjson_parameter_scaling_factor = 8.,
+ wrepjson_product_information = "HRES Forecast and ENS Distribution "
+ )
+ cc_graph = mepsgraph( eps_box_border_thickness = 2,
+ eps_box_width = 1.5)
+ cc_text = mtext(
+ text_colour = "navy",
+ text_font_size = 0.2,
+ text_justification = "left",
+ text_line_1 = "<font size='0.5'>EPS Meteogram</font><font size='0.6'><json_info key='expver'/></font>",
+ text_line_2 = "<font size='0.5'><json_info key='station_name'/></font><font size='0.6'><json_info key='location'/></font> <font size='0.6'><json_info key='grid_point'/></font> <font size='0.6'><json_info key='height'/></font>",
+ text_line_3 = "<font size='0.5'><json_info key='product_info'/></font> <font size='0.6'><json_info key='date'/></font>",
+ text_line_4 = "<font size='0.5' colour='white'>.</font>",
+ text_line_5 = "<font size='0.35'><json_info key='parameter_info'/></font>",
+ text_line_count = 5,
+ )
+
+ frame2 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last -y;
+
+ pr_data = mwrepjson(
+ wrepjson_family = "eps",
+ wrepjson_input_filename = "pr.data",
+ wrepjson_parameter = "pr",
+ wrepjson_parameter_information = "Total Precipitation (mm/6h)",
+ wrepjson_parameter_scaling_factor = 1000.,
+ wrepjson_y_axis_threshold = 3.
+ )
+ pr_graph = mepsgraph( eps_box_border_thickness = 2,
+ eps_box_width = 1.5,
+ eps_maximum_font_size = 0.35)
+
+ ws_data = mwrepjson(wrepjson_family = "eps",
+ wrepjson_input_filename = "ws.data",
+ wrepjson_parameter = "ws",
+ wrepjson_parameter_information = "10m Wind Speed (m/s)",
+ )
+ ws_graph = mepsgraph( eps_box_border_thickness = 2,
+ eps_box_width = 1.5,
+ )
+ t2m_data = mwrepjson(
+
+ wrepjson_family = "eps",
+ wrepjson_input_filename = "2t.data",
+ wrepjson_parameter = "2t",
+ wrepjson_parameter_information = "2m Temperature(°C)",
+ wrepjson_parameter_offset_factor = -273.15,
+ wrepjson_temperature_correction = "on"
+ )
+ t2m_graph = mepsgraph( eps_box_border_thickness = 2,
+ eps_box_width = 1.5,
+ eps_font_colour = "navy",
+ eps_legend_font_size = font_size,
+ eps_grey_legend = "off",
+ legend='on'
+ )
+
+
+ frame3 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ last = last -y;
+ frame4 = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=y,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=last
+ )
+
+ text = mtext(
+ text_lines=["<json_info key='parameter_info'/>"],
+ text_html='true',
+ text_colour='navy',
+ text_font_size=font_size,
+ #text_mode='positional',
+ text_box_x_position=1.,
+ text_box_y_position=5.1,
+ text_box_x_length=10.,
+ text_box_y_length=2.5,
+ text_border='off',
+ text_justification='left',
+ )
+
+ t2m_text = mtext(
+ text_lines=["<json_info key='parameter_info'/><json_info key='full_temperature_correction_info'/>"],
+ text_html='true',
+ text_colour='navy',
+ text_font_size=font_size,
+ #text_mode='positional',
+ text_box_x_position=1.,
+ text_box_y_position=5.1,
+ text_box_x_length=10.,
+ text_box_y_length=2.5,
+ text_border='off',
+ text_justification='left',
+ )
+ legend = mlegend(
+ legend_text_colour = "navy",
+ legend_entry_text_width = 99.,
+ legend_entry_plot_direction = "row",
+ legend_text_font_size = font_size,
+ legend_box_mode='positional',
+ legend_box_x_position = 1.,
+ legend_box_y_position = -4.5,
+ legend_box_x_length = 12.,
+ legend_box_y_length = 5.,
+ )
+ plot(
+ out,
+ frame1,
+ projection,
+ horizontal,
+ vertical,
+ cc_data, cc_graph, cc_text,
+ frame2,
+ projection,
+ horizontal,
+ vertical,
+ pr_data, pr_graph, text,
+ frame3,
+ projection,
+ horizontal,
+ vertical,
+ ws_data, ws_graph, text,
+ frame4,
+ projection,
+ horizontal,
+ vertical,
+ t2m_data, t2m_graph, t2m_text,
+ legend
+ )
+
+'''
+
+'''
+def main():
+
+ if len(sys.argv) != 2 :
+ print "No station list given"
+ return 1
+
+ try:
+ stations = json.loads(open(sys.argv[1]).read())
+ params = ["tcc", "pr", "ws", "2t"]
+ for param in params :
+
+ data(stations["stations"], param, "/tmp/cgs/epsdata/eps20160118000001/grib")
+ for station in stations["stations"]:
+ epsgrams(station)
+ return 0
+
+
+ except GribInternalError,err:
+ if VERBOSE:
+ traceback.print_exc(file=sys.stderr)
+ else:
+ print >>sys.stderr,err.msg
+
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/utils/plumes.py b/utils/plumes.py
new file mode 100644
index 0000000..00f96fd
--- /dev/null
+++ b/utils/plumes.py
@@ -0,0 +1,676 @@
+import traceback
+import sys
+
+from gribapi import *
+import json
+from Magics.macro import *
+import numpy
+import datetime
+
+configuration = {
+ "z500" : {
+ "ensemble" : "ensemble_z500.grib",
+ "control" : "control_z500.grib",
+ "deterministic" : "deterministic_z500.grib",
+ "param" : "z500",
+ "factor":"0.01019",
+ "offset" : "0",
+ "d-1" : "deterministic_d-1_z500.grib",
+ "d-2" : "deterministic_d-2_z500.grib"
+
+ },
+ "t850" : {
+ "ensemble" : "ensemble_t850.grib",
+ "control" : "control_t850.grib",
+ "deterministic" : "deterministic_t850.grib",
+ "param" : "t850",
+ "factor": "1",
+ "offset" : "-273.15",
+ "d-1" : "deterministic_d-1_t850.grib",
+ "d-2" : "deterministic_d-2_t850.grib"
+ },
+ "precip" : {
+ "ensemble" : "ensemble_pr.grib",
+ "control" : "control_pr.grib",
+ "deterministic" : "deterministic_pr.grib",
+ "param" : "precip",
+ "factor": "1000.",
+ "offset" : "0",
+ "d-1" : "deterministic_d-1_pr.grib",
+ "d-2" : "deterministic_d-2_pr.grib"
+ }
+}
+
+reference = datetime.datetime.now()
+def ensemble(files, index, out):
+ f = open(files["ensemble"])
+
+ factor = float(files["factor"])
+ offset = float(files["offset"])
+
+ mcount = grib_count_in_file(f)
+
+
+ for i in range(mcount):
+ gid = grib_new_from_file(f)
+ step = str(grib_get(gid, "step"))
+
+ number = str(grib_get(gid, "number"))
+ param = str(grib_get(gid, "parameter"))
+ date = str(grib_get(gid, "date"))
+ time = "%02d" % grib_get(gid, "time")
+
+ values = grib_get_elements(gid,"values",index)
+ mean = []
+
+ for l in range(len(index)):
+ if not (param in out[l]) :
+ out[l][param] = {}
+ out[l][param]["steps"] = [-1]
+ out[l]["%s_mean" % param] = {}
+
+
+ if not (number in out[l][param] ) :
+ out[l][param][number]=[]
+ if not (step in out[l]["%s_mean" % param] ) :
+ out[l]["%s_mean" % param][step]=[]
+
+ if out[l][param]["steps"][-1] != step :
+ if out[l][param]["steps"][-1] == -1:
+ out[l][param]["steps"][-1] = step
+ else :
+ out[l][param]["steps"].append(step)
+
+
+
+
+ out[l][param][number].append(values[l]*factor + offset)
+ out[l]["%s_mean" % param][step].append(values[l]*factor + offset)
+ grib_release(gid)
+ f.close()
+
+ base = datetime.datetime.strptime(date+time, '%Y%m%d%H%M')
+ print base
+
+ for l in range(len(index)):
+ mean = {}
+
+
+ mean["y_values"] = []
+ mean["x_date_values"] = []
+ for s in out[l][param]["steps"]:
+ mean["y_values"].append(numpy.mean(out[l]["%s_mean" % param][s]))
+ valid = base + datetime.timedelta(hours=int(s))
+ mean["x_date_values"].append("%s" % valid)
+
+ out[l]["%s_mean" % param] = mean
+
+
+ return
+
+def deterministic(files, index, out):
+
+ f = open(files["deterministic"])
+ factor = float(files["factor"])
+ offset = float(files["offset"])
+
+ mcount = grib_count_in_file(f)
+
+
+ for i in range(mcount):
+ gid = grib_new_from_file(f)
+ if i == 0 :
+ param = str(grib_get(gid, "parameter"))
+
+ for l in range(len(index)):
+ out[l][param]["forecast"] = []
+
+ values = grib_get_elements(gid,"values",index)
+ for l in range(len(index)):
+ out[l][param]["forecast"].append(values[l]*factor+offset)
+
+ grib_release(gid)
+ f.close()
+ return
+
+def previous(files, key, index, out):
+
+ f = open(files[key])
+ factor = float(files["factor"])
+ offset = float(files["offset"])
+
+ mcount = grib_count_in_file(f)
+
+
+ for i in range(mcount):
+ gid = grib_new_from_file(f)
+ if i == 0 :
+ param = str(grib_get(gid, "parameter"))
+ step = str(grib_get(gid, "step"))
+ date = str(grib_get(gid, "date"))
+ time = "%02d" % grib_get(gid, "time")
+ for l in range(len(index)):
+ out[l][key] = {"y_values" : [], "x_date_values" : [] }
+ base = datetime.datetime.strptime(date+time, '%Y%m%d%H%M')
+ step = grib_get(gid, "step")
+ valid = base + datetime.timedelta(hours=step)
+
+
+ values = grib_get_elements(gid,"values",index)
+ for l in range(len(index)):
+
+ if ( valid > reference ) :
+ out[l][key]["y_values"].append(values[l]*factor+offset)
+ out[l][key]["x_date_values"].append("%s" % valid)
+
+
+ grib_release(gid)
+ f.close()
+ return
+
+def control(files, index, out):
+ global reference
+ f = open(files["control"])
+
+ factor = float(files["factor"])
+ offset = float(files["offset"])
+
+ mcount = grib_count_in_file(f)
+
+
+ for i in range(mcount):
+
+ gid = grib_new_from_file(f)
+ if i == 0 :
+
+ param = str(grib_get(gid, "parameter"))
+ date = str(grib_get(gid, "date"))
+ time = "%02d" % grib_get(gid, "time")
+
+ for l in range(len(index)):
+ out[l]["date"] = date
+ out[l]["time"] = time
+ out[l][param]["control"] = []
+ reference = datetime.datetime.strptime(date+time, '%Y%m%d%H%M')
+ values = grib_get_elements(gid,"values",index)
+ for l in range(len(index)):
+ out[l][param]["control"].append(values[l]*factor+offset)
+
+ grib_release(gid)
+ f.close()
+ return
+
+
+
+def data(stations, files):
+ out = []
+ index = []
+ lsm = open("lsm.cf")
+ gid = grib_new_from_file(lsm)
+
+ for station in stations:
+ nearest = grib_find_nearest(gid,station["lat"],station["lon"],1)
+ name = "%.2f_%.2f_%s.json" % (station["lat"], station["lon"], files["param"])
+ out.append({
+ "station_name" : station["name"],
+ "output" : name,
+ "location" : { "lat" : station["lat"], "lon" : station["lon"] },
+ "EPS_location" : { "distance": nearest[0].distance, "latitude" : nearest[0].lat, "longitude" : nearest[0].lon },
+ "forecast_location" : { "distance": nearest[0].distance, "latitude" : nearest[0].lat, "longitude" : nearest[0].lon }
+ })
+ index.append(nearest[0].index)
+ station[files["param"]] = name
+
+ grib_release(gid)
+ lsm.close()
+
+ ensemble(files, index, out)
+ control(files, index, out)
+ deterministic(files, index, out)
+ previous(files, "d-1", index, out)
+ previous(files, "d-2", index, out)
+ for i in out:
+ f = open(i["output"], 'w')
+ print >> f, json.dumps(i, indent=4, separators=(',', ': ') )
+
+
+
+def plumes(location):
+
+ z500 = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "z500")
+ precip = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "precip")
+ t850 = "%.2f_%.2f_%s.json" % (location["lat"], location["lon"], "t850")
+
+ out = output(
+ output_formats=location["output_formats"],
+ output_name_first_page_number='off',
+ output_name=str(location["output_name"]) ,
+ super_page_y_length=29.7,
+ super_page_x_length=21.,
+ )
+
+ # define the cartesian projection
+ top = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=12.,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=18.
+ )
+
+ projection = mmap(
+ subpage_map_projection='cartesian',
+ subpage_x_axis_type='date',
+ subpage_x_automatic='on',
+ subpage_y_axis_type='regular',
+ subpage_y_automatic='on',
+ subpage_y_length = 6.5,
+ subpage_y_position = 0.5
+ )
+
+ # define horizontal axis
+
+ horizontal = maxis(
+ axis_orientation = "horizontal",
+ axis_date_type = "days",
+ axis_days_label = "both",
+ axis_days_label_colour= "#0b265a",
+ axis_days_label_height = 0.4,
+ axis_grid = "on",
+ axis_grid_colour = "Rgb(0.5, 0.5, 0.5)",
+ axis_grid_line_style= "dash",
+ axis_line_colour= "#0b265a",
+ axis_minor_tick= "on",
+ axis_minor_tick_colour= "#0b265a",
+ axis_months_label= "off",
+ axis_tick_colour= "#0b265a",
+ axis_type = "date",
+ axis_years_label = "off"
+ )
+
+ # horizontal axis for bottom plot (with month and year)
+
+ horizontal_bot = maxis(
+ axis_orientation = "horizontal",
+ axis_date_type = "days",
+ axis_days_label = "both",
+ axis_days_label_colour= "#0b265a",
+ axis_days_label_height = 0.4,
+ axis_grid = "on",
+ axis_grid_colour = "Rgb(0.5, 0.5, 0.5)",
+ axis_grid_line_style= "dash",
+ axis_line_colour= "#0b265a",
+ axis_minor_tick= "on",
+ axis_minor_tick_colour= "#0b265a",
+ axis_months_label= "on",
+ axis_months_label_colour= "#0b265a",
+ axis_months_label_height = 0.4,
+ axis_tick_colour= "#0b265a",
+ axis_type = "date",
+ axis_years_label = "on",
+ axis_years_label_colour= "#0b265a",
+ axis_years_label_height = 0.4
+ )
+
+ # define vertical axis
+
+ vertical = maxis(
+ axis_orientation = "vertical",
+ axis_grid = "on",
+ axis_grid_colour =" grey",
+ axis_grid_line_style = "dash",
+ axis_grid_reference_level = 0.,
+ axis_grid_reference_thickness = 1,
+ axis_line = "on",
+ axis_line_colour = "#0b265a",
+ axis_tick_colour = "#0b265a",
+ axis_tick_label_colour = "#0b265a",
+ axis_tick_label_height = 0.4
+ )
+
+ tempe = mwrepjson(
+ wrepjson_family = "eps",
+ wrepjson_input_filename = t850,
+ wrepjson_parameter = "130",
+ wrepjson_temperature_correction= "on",
+ wrepjson_plumes_interval = 1.,
+ wrepjson_product_information= "ECMWF Ensemble Forecasts " ,
+ wrepjson_parameter_information= "Temperature 850hPa",
+ wrepjson_y_percentage = 15.
+ )
+
+ tempe_contour = mcont(
+ legend = "on",
+ contour_hilo = "off",
+ contour_label = "off",
+ contour_highlight = "off",
+ contour_level_list = [0.5, 10., 30., 50., 100.],
+ contour_level_selection_type = "list",
+ contour_line_colour = "grey",
+ contour_line_thickness = 2,
+ contour_method = "linear",
+ contour_shade = "on",
+ contour_shade_colour_list = ["#d0fd74", "#9fee01", "#789837", "#4f7600"],
+ contour_shade_colour_method = "list",
+ contour_shade_method = "area_fill"
+ )
+
+ tempe_plumes = mepsplumes (
+ eps_plume_line_colour = "#fa73bf",
+ eps_plume_forecast_line_colour = "#cd0174",
+ eps_plume_forecast_line_thickness = 5,
+ eps_plume_control_line_thickness = 5,
+ eps_plume_control_line_colour = "#cd0174",
+ eps_plume_line_style = "dot",
+ eps_plume_line_thickness = 2
+ )
+ t_1 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = t850,
+ wrepjson_keyword = "d-1",
+ wrepjson_title = "off",
+ )
+
+ t_1_graph = mgraph(
+ graph_line_colour = "navy",
+ graph_line_style = "dot",
+ graph_line_thickness = 5,
+ legend = "on",
+ legend_user_text = "D-1"
+ )
+ t_2 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = t850,
+ wrepjson_keyword = "d-2",
+ wrepjson_title = "off",
+ )
+
+ t_2_graph = mgraph(
+ graph_line_colour = "navy",
+ graph_line_style = "dot",
+ graph_line_thickness = 3,
+ legend = "on",
+ legend_user_text = "D-2"
+ )
+ tempe_mean = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = t850,
+ wrepjson_keyword = "130_mean",
+ wrepjson_title = "off",
+ )
+
+ tempe_mean_graph = mgraph(
+ graph_line_colour = "#BF00CD",
+ graph_line_style = "solid",
+ graph_line_thickness = 3,
+ legend = "on",
+ legend_user_text = "Mean"
+ )
+
+ # definition of the title
+
+ lines = [ "ECMWF Ensemble forecasts <json_info key='station_name'/>",
+ "Location: <json_info key='location'/>",
+ "Base Time: <json_info key='date'/>",
+ "<font size='0.1'> . </font>",
+ "<font size='0.4'><json_info key='parameter_info'/></font><font size='0.4'> - Probability for </font><font size='0.4'><json_info key='plumes_interval'/></font><font size='0.4'>°</font><font size='0.4'>C intervals</font>",
+ ]
+
+ title = mtext(
+ text_lines=lines,
+ text_html='true',
+ text_colour='#0b265a',
+ text_font_size=0.5,
+ text_mode='positional',
+ text_box_x_position=1.,
+ text_box_y_position=7.8,
+ text_box_x_length=10.,
+ text_box_y_length=2.5,
+ text_border='off',
+ text_justification='left',
+ )
+ legend = mlegend(
+ #legend_box_mode='positional',
+ legend_box_x_position=12.,
+ legend_box_y_position=8.5,
+ legend_box_x_length=11.,
+ legend_box_y_length=2.5,
+ legend_border='off',
+ #legend_column_count = 5,
+ #legend_entry_text_width = 60.,
+ legend_text_colour = "#0b265a",
+ legend_text_composition = "user_text_only",
+ legend_text_font_size = 0.35,
+ legend_user_lines = ["0.5-10%" , "1-30%", "30-50%", "50-100%", "HRES", "Control", "ENS" ]
+ )
+ # To the plot
+ middle = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=9.,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=9.5
+ )
+
+ rr = mwrepjson(
+ wrepjson_family = "eps",
+ wrepjson_input_filename = precip,
+ wrepjson_parameter = "143",
+ wrepjson_parameter_information= "Ensemble members of Total Precipitation (mm/6h)",
+ wrepjson_y_percentage = 15.
+ )
+
+ precip_plumes = mepsplumes (
+ eps_plume_line_colour = "#4a80e8",
+ eps_plume_forecast_line_colour = "#cd0174",
+ eps_plume_forecast_line_thickness = 5,
+ eps_plume_control_line_thickness = 5,
+ eps_plume_control_line_colour = "#cd0174",
+ eps_plume_line_style = "dot",
+ eps_plume_line_thickness = 2,
+ eps_plume_legend='off'
+ )
+ precip_mean = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = precip,
+ wrepjson_keyword = "143_mean",
+ wrepjson_title = "off",
+ )
+
+ precip_mean_graph = mgraph(
+ graph_line_colour = "#BF00CD",
+ graph_line_style = "dot",
+ graph_line_thickness = 3,
+ legend_user_text = "Mean"
+ )
+
+ rr_1 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = precip,
+ wrepjson_keyword = "d-1",
+ wrepjson_title = "off",
+ )
+
+ rr_1_graph = mgraph(
+ graph_line_colour = "navy",
+ graph_line_style = "dot",
+ graph_line_thickness = 5,
+ legend = "on",
+ legend_user_text = "D-1"
+ )
+ rr_2 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = precip,
+ wrepjson_keyword = "d-2",
+ wrepjson_title = "off",
+ )
+
+ rr_2_graph = mgraph(
+ graph_line_colour = "navy",
+ graph_line_style = "dot",
+ graph_line_thickness = 3,
+ legend = "on",
+ legend_user_text = "D-2"
+ )
+ short_title = mtext(
+ text_lines=["<json_info key='parameter_info'/>"],
+ text_html='true',
+ text_colour='#0b265a',
+ text_font_size=0.4,
+ text_mode='positional',
+ text_box_x_position=1.,
+ text_box_y_position=7.5,
+ text_box_x_length=10.,
+ text_box_y_length=2.5,
+ text_border='off',
+ text_justification='left',
+ )
+
+
+ # To the plot
+ bottom = page(
+ layout='positional',
+ page_x_length=21.,
+ page_y_length=9.,
+ page_id_line='off',
+ page_x_position=0.,
+ page_y_position=1.
+ )
+
+ geop = mwrepjson(
+ wrepjson_family = "eps",
+ wrepjson_input_filename = z500,
+ wrepjson_parameter = "129",
+ wrepjson_parameter_information = "Geopotential at 500 hPa - Probability for 2.5dam intervals",
+ wrepjson_plumes_interval = 2.5,
+ wrepjson_y_percentage = 15.
+ )
+
+ geop_contour = mcont(
+ legend="off",
+ contour_highlight= "off",
+ contour_hilo= "off",
+ contour_line_colour = "grey",
+ contour_label = "off",
+ contour_line_thickness = 2,
+ contour_level_list = [0.5, 10, 30, 50, 120],
+ contour_level_selection_type = "list",
+ contour_shade = "on",
+ contour_shade_colour_list = ["#a4bff3", "#4a80e8", "#174cb4", "#0b265a" ],
+ contour_shade_colour_method = "list",
+ contour_shade_method = "area_fill"
+ )
+
+ geop_plumes = mepsplumes (
+ eps_plume_line_colour = "#e86349",
+ eps_plume_forecast_line_colour = "#cee849",
+ eps_plume_forecast_line_thickness = 5,
+ eps_plume_control_line_thickness = 5,
+ eps_plume_control_line_colour = "#cee849",
+ eps_plume_line_style = "dot",
+ eps_plume_line_thickness = 2,
+ eps_plume_legend='off'
+ )
+ geop_mean = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = z500,
+ wrepjson_keyword = "129_mean", wrepjson_title = "off",
+
+ )
+
+ geop_mean_graph = mgraph(
+ graph_line_colour = "#cee849",
+ #graph_line_colour = "red",
+ graph_line_style = "dot",
+ graph_line_thickness = 3,
+ legend = "on",
+ legend_user_text = "Mean"
+ )
+
+ geop_1 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = z500,
+ wrepjson_keyword = "d-1", wrepjson_title = "off",
+ )
+
+ geop_1_graph = mgraph(
+ graph_line_colour = "#0b265a",
+ graph_line_style = "dot",
+ graph_line_thickness = 5,
+ legend = "on",
+ legend_user_text = "D-1"
+ )
+ geop_2 = mwrepjson(
+ wrepjson_family = "data",
+ wrepjson_input_filename = z500,
+ wrepjson_keyword = "d-2", wrepjson_title = "off",
+
+ )
+
+ geop_2_graph = mgraph(
+ graph_line_colour = "#0b265a",
+ graph_line_style = "dot",
+ graph_line_thickness = 3,
+ legend = "on",
+ legend_user_text = "D-2"
+ )
+
+
+ plot(
+ out,
+ top,
+ projection,
+ horizontal,
+ vertical,
+ tempe, tempe_contour, tempe_plumes,
+ title,
+
+ tempe_mean, tempe_mean_graph,
+ t_1, t_1_graph,t_2, t_2_graph,
+ legend,
+ middle,
+ projection, horizontal, vertical,
+ rr, precip_plumes,
+ precip_mean, precip_mean_graph,
+ rr_1, rr_1_graph,rr_2, rr_2_graph,
+ short_title,
+ bottom,
+ projection, horizontal_bot, vertical,
+ geop, geop_contour, geop_plumes,
+ geop_mean, geop_mean_graph,
+ geop_1, geop_1_graph, geop_2, geop_2_graph,
+ short_title
+ )
+
+def main():
+
+
+
+ if len(sys.argv) != 2 :
+ print "No station list given"
+ return 1
+
+ try:
+ stations = json.loads(open(sys.argv[1]).read())
+ params = ["t850", "precip", "z500"]
+
+ for param in params :
+ print "get", param
+ data(stations["stations"], configuration[param])
+ for station in stations["stations"]:
+ plumes(station)
+ return 0
+
+
+ except GribInternalError,err:
+ if VERBOSE:
+ traceback.print_exc(file=sys.stderr)
+ else:
+ print >>sys.stderr,err.msg
+
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/magics.git
More information about the debian-science-commits
mailing list