diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 310f71f8..46f24e12 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -166,6 +166,40 @@ jobs: with: name: ubuntu-20.04-${{ matrix.cxx }} path: ${{ runner.temp }}/fesapi-install + build_wheels_windows: + name: Build wheels on windows-latest + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Stub `setup.py` check + # It will be generated during CMake run + # https://github.com/pypa/cibuildwheel/issues/1139 + run: touch python/setup.py + - name: Build wheels + uses: pypa/cibuildwheel@v2.21.3 + env: + CIBW_BUILD: cp38-win_amd64 cp39-win_amd64 cp310-win_amd64 cp311-win_amd64 cp312-win_amd64 cp313-win_amd64 + CIBW_ARCHS: auto64 + CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 + CIBW_BEFORE_ALL: > + %VCPKG_INSTALLATION_ROOT%\vcpkg install boost-uuid minizip hdf5[zlib] && + cd ${{ runner.temp }} && + mkdir fesapi-build && + cd fesapi-build && + cmake -DCMAKE_TOOLCHAIN_FILE=%VCPKG_INSTALLATION_ROOT%\scripts\buildsystems\vcpkg.cmake -G"Visual Studio 17 2022" -A x64 -T host=x64 -Wno-dev -Wno-deprecated -DWITH_PYTHON_WRAPPING=TRUE -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/fesapi-install ${{ github.workspace }} && + cmake --build . --config Release -j2 && + cmake --build . --config Release --target INSTALL && + pip install delvewheel + CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: > + delvewheel repair --add-path ${{ runner.temp }}\fesapi-build\Release --namespace-pkg fesapi -w {dest_dir} {wheel} + CIBW_TEST_COMMAND: python ${{github.workspace}}\python\example\example.py + with: + package-dir: ./python + output-dir: wheelhouse + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-windows + path: ./wheelhouse/*.whl build_wheels_linux: name: Build wheels on ubuntu-latest runs-on: ubuntu-latest @@ -176,28 +210,20 @@ jobs: # https://github.com/pypa/cibuildwheel/issues/1139 run: touch python/setup.py - name: Build wheels - uses: pypa/cibuildwheel@v2.19.2 + uses: pypa/cibuildwheel@v2.21.3 env: CIBW_BUILD: cp38-manylinux_* cp39-manylinux_* cp310-manylinux_* cp311-manylinux_* cp312-manylinux_* cp313-manylinux_* CIBW_ARCHS: auto64 + CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 CIBW_BEFORE_ALL: > - yum install -y wget minizip-devel gcc-c++ boost-devel && + yum install -y wget gcc-c++ boost-devel && yum search epel-release && yum info epel-release && yum install -y epel-release && - yum --enablerepo=epel install -y cmake3 && - cd / && - wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.12/hdf5-1.12.3/src/hdf5-1.12.3.tar.gz && - tar xf hdf5-1.12.3.tar.gz && - mkdir hdf5-build && - cd hdf5-build && - cmake3 -G "Unix Makefiles" -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DHDF5_BUILD_TOOLS:BOOL=OFF -DHDF5_BUILD_EXAMPLES:BOOL=OFF -DHDF5_BUILD_CPP_LIB:BOOL=OFF -DHDF5_BUILD_HL_LIB:BOOL=OFF -DCMAKE_INSTALL_PREFIX:STRING=/hdf5-install ../hdf5-1.12.3 && - cmake3 --build . -j2 --config Release && - cmake3 --install . && - cd / && + yum --enablerepo=epel install -y minizip1.2-devel hdf5-devel cmake3 && mkdir build && cd build && - cmake3 -DCMAKE_BUILD_TYPE=Release -DHDF5_ROOT=/hdf5-install -DHDF5_USE_STATIC_LIBRARIES=TRUE -DWITH_PYTHON_WRAPPING=TRUE -DCMAKE_INSTALL_PREFIX:STRING=/fesapi-install {project} && + cmake3 -DCMAKE_BUILD_TYPE=Release -DWITH_PYTHON_WRAPPING=TRUE -DCMAKE_INSTALL_PREFIX:STRING=/fesapi-install {project} && cmake3 --build . -j2 --config Release && cmake3 --install . CIBW_REPAIR_WHEEL_COMMAND_LINUX: > @@ -209,7 +235,7 @@ jobs: output-dir: wheelhouse - uses: actions/upload-artifact@v4 with: - name: cibw-wheels-ubuntu-latest + name: cibw-wheels-manylinux_2_28 path: ./wheelhouse/*.whl build_wheels_mac: name: Build wheels on macos-14 @@ -221,10 +247,12 @@ jobs: # https://github.com/pypa/cibuildwheel/issues/1139 run: touch python/setup.py - name: Build wheels - uses: pypa/cibuildwheel@v2.19.2 + uses: pypa/cibuildwheel@v2.21.3 env: CIBW_BUILD: cp38-macosx_* cp39-macosx_* cp310-macosx_* cp311-macosx_* cp312-macosx_* cp313-macosx_* CIBW_ARCHS: auto64 + # See https://cibuildwheel.pypa.io/en/stable/cpp_standards/#macos-and-deployment-target-versions + MACOSX_DEPLOYMENT_TARGET: 10.14 CIBW_BEFORE_ALL: > brew install boost swig && git clone https://github.com/F2I-Consulting/Minizip.git ${{ github.workspace }}/../minizip && @@ -256,7 +284,7 @@ jobs: output-dir: wheelhouse - uses: actions/upload-artifact@v4 with: - name: cibw-wheels-macos-14 + name: cibw-wheels-macosx_arm64 path: ./wheelhouse/*.whl ubuntu-20-mpi: runs-on: ubuntu-20.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ac23ad..b0538172 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set (FESAPI_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) # version mechanism set (Fesapi_VERSION_MAJOR 2) -set (Fesapi_VERSION_MINOR 11) +set (Fesapi_VERSION_MINOR 12) set (Fesapi_VERSION_PATCH 0) set (Fesapi_VERSION_TWEAK 0) @@ -31,7 +31,7 @@ IF (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) ENDIF (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if (NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD 17) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -94,33 +94,8 @@ IF (NOT EXISTS ${SZIP_LIBRARY_DEBUG} AND WIN32 AND NOT ${HDF5_BUILT_AS_DYNAMIC_L MESSAGE(WARNING "The Szip library (SZIP_LIBRARY_DEBUG variable) does not look to be a valid file. Please modify it.") ENDIF () -# Boost DEPENDENCY : Uuid (and potentially regex) -unset(CAN_USE_STD_REGEX CACHE) -include(CheckCXXSourceCompiles) -check_cxx_source_compiles( - "#include - - //https://gcc.gnu.org/develop.html#timeline - int a = - #if !defined(__GLIBCXX__) || __GLIBCXX__ > 20150623 || __GLIBCXX__ == 20140422 || __GLIBCXX__ == 20140716 || __GLIBCXX__ == 20141030 - 1; - #else - fgsfds; - #endif - - int main () - { - return 0; - - }" - - CAN_USE_STD_REGEX -) -if (NOT CAN_USE_STD_REGEX) - find_package(Boost 1.44.0 REQUIRED regex) # 1.44 because we want boost::uuids::to_string method -else () - find_package(Boost 1.44.0 REQUIRED) # 1.44 because we want boost::uuids::to_string method -endif() +# Boost DEPENDENCY +find_package(Boost 1.44.0 REQUIRED) # 1.44 because we want boost::uuids::to_string method # ============================================================================ # some useful variables diff --git a/README.md b/README.md index f60c5925..3e85e8e6 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,16 @@ - build - fesapi (Git clone this repository into this folder "fesapi". You should then have a path fesapiEnv/fesapi/src) - dependencies - - The following compilers are known to work (used in CI) - - gcc from version 4.8 - - visual studio from version 2017 + - The following compilers are known to work + - gcc from version 8 + - visual studio from version 2019 - clang from version 5.0 # Prepare the dependencies Download (build and install if necessary) third party libraries: - HDF5: Versions of 1.8.* (starting from 1.8.18), 1.10.* ([starting from 1.10.2](https://www.hdfgroup.org/2018/04/why-should-i-care-about-the-hdf5-1-10-2-release/)), all 1.12.* and all 1.14.* should be ok. https://support.hdfgroup.org/ftp/HDF5/releases/ - MINIZIP : Version 1.1 is needed : it is the official version included in [current zlib distribution](https://www.zlib.net/) (look into "contrib" folder). You can directly install minizip development package on most of Linux distributions (https://packages.ubuntu.com/xenial/libminizip-dev). On Windows (or older Linux distributions), you can copy the CMakeLists.txt file from fesapi/cmake/minizip to the zlib minizip directory to help you to build minizip (we also provide a copy of minizip 1.1 with cmake files on github : https://github.com/F2I-Consulting/Minizip). It is also highly recommended to link minizip to the same zlib library than the one associated to your HDF5 library. -- BOOST : Starting from version 1.44.0 (and at least 1.67.0 if you don't want to face [valgrid false positives](https://www.boost.org/doc/libs/1_66_0/libs/uuid/doc/uuid.html#Design%20notes)). FYI, on windows, boost uuid depends on bcrypt library. +- BOOST (uuid) : Starting from version 1.44.0 (and at least 1.67.0 if you don't want to face [valgrid false positives](https://www.boost.org/doc/libs/1_66_0/libs/uuid/doc/uuid.html#Design%20notes)). FYI, on windows, boost uuid depends on bcrypt library. We advise you to install these third party libraries respectively into - fesapiEnv/dependencies/hdf5-particularVersion diff --git a/cmake/pyproject.toml.in b/cmake/pyproject.toml.in new file mode 100644 index 00000000..ac6d13f8 --- /dev/null +++ b/cmake/pyproject.toml.in @@ -0,0 +1,60 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = 'fesapi' +version = '${Fesapi_PYTHON_VERSION}' +authors = [ + {name = "F2I-CONSULTING"}, +] +maintainers = [ + {name = "F2I-CONSULTING"}, +] +description = "A library for using the Energistics data standards" +readme = "README.md" +classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Operating System :: MacOS', + 'Natural Language :: English', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Topic :: Software Development', + 'Topic :: Software Development :: Libraries', + 'Topic :: Software Development :: Libraries :: Application Frameworks ', + 'Topic :: File Formats', +] +keywords = [ + "energistics", + "resqml", + "eml", + "witsml", + "prodml", + "osdu", + "rddms", +] +requires-python = ">=3.8" + +[project.urls] +source = "https://github.com/F2I-Consulting/fesapi/issues" +releasenotes = "https://github.com/F2I-Consulting/fesapi/releases" +documentation = "https://www.f2i-consulting.com/fesapi/doxygen/" +issues = "https://github.com/F2I-Consulting/fesapi/issues" + +[tool.setuptools] +packages=['fesapi'] +package-dir={"fesapi" = "fesapi"} +ext-modules = [ + {name='fesapi._fesapi', sources=['swigGeneratedPythonWrapper.cpp'], library-dirs=['${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}'], libraries=['${ASSEMBLY_NAME}',], ${EXTRA_COMPILE_ARGS}} +] + +[tool.setuptools.package-data] +fesapi = ["*.dll", "*.so", "*.so.*"] diff --git a/cmake/setup.py.in b/cmake/setup.py.in deleted file mode 100644 index 8f9e91c8..00000000 --- a/cmake/setup.py.in +++ /dev/null @@ -1,65 +0,0 @@ -from setuptools import setup, Extension - -fesapi_module = Extension('_fesapi', - sources=['swigGeneratedPythonWrapper.cpp'], - library_dirs=['${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}'], - libraries=['${ASSEMBLY_NAME}',], - ${EXTRA_COMPILE_ARGS}, -) - -setup (name = 'fesapi', - version = '${Fesapi_PYTHON_VERSION}', - author = 'F2I-CONSULTING', - maintainer = 'F2I-CONSULTING', - url = 'https://github.com/F2I-Consulting/fesapi', - description = 'An API for the Energistics data standards', - long_description = '''**FESAPI** is an API for Energistics data standards (mainly RESQML™) - -### Examples - -A Python script and a Jupyter Notebook are available [here](https://github.com/F2I-Consulting/fesapi/tree/master/python/example). - -### Credits -This software was developed with : -- the gSOAP toolkit from Genivia Inc -- the date library from Howard Hinnant - -FESAPI Product incorporates RESQML™, WITSML™ and PRODML™ technology/standards provided by the Energistics Consortium, Inc. - -RESQML, WITSML and PRODML are trademarks or registered trademarks of Energistics Consortium, Inc.''', - long_description_content_type = 'text/markdown', - license = 'Apache 2.0', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX :: Linux', - 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Topic :: Software Development', - 'Topic :: Software Development :: Libraries', - 'Topic :: Software Development :: Libraries :: Application Frameworks ', - 'Topic :: File Formats', - ], - keywords='energistics,resqml,eml,witsml,prodml,osdu,rddms', - project_urls={ - 'Documentation': 'https://f2i-consulting.com/fesapi/doxygen/', - 'Discourse': 'https://discourse.f2i-consulting.com/', - 'Tracker': 'https://github.com/F2I-Consulting/fesapi/issues', - }, - python_requires='>=3.6', - include_package_data=True, - packages=['fesapi'], - package_dir={'fesapi': 'fesapi'}, - package_data={'fesapi': ['*.dll', '*.so', '*.so.*']}, - ext_package='fesapi', - ext_modules = [fesapi_module], -) diff --git a/example/example.cpp b/example/example.cpp index 533def07..dd1140e3 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -2468,7 +2468,26 @@ bool serialize(const string& filePath) EML2_NS::AbstractHdfProxy* hdfProxy = repo.createHdfProxy("", "Hdf Proxy", epcDoc.getStorageDirectory(), epcDoc.getName() + ".h5", COMMON_NS::DataObjectRepository::openingMode::OVERWRITE); //hdfProxy->setCompressionLevel(6); - localTime3dCrs = repo.createLocalTime3dCrs("", "Default local time CRS", 1.0, 0.1, 15, .0, gsoap_resqml2_0_1::eml20__LengthUom::m, 23031, gsoap_resqml2_0_1::eml20__TimeUom::s, gsoap_resqml2_0_1::eml20__LengthUom::m, "Unknown", false); // CRS translation is just for testing; + localTime3dCrs = repo.createLocalTime3dCrs("", "Default local time CRS", 1.0, 0.1, 15, .0, gsoap_resqml2_0_1::eml20__LengthUom::m, + "PROJCRS[\"ETRS89 Lambert Azimuthal Equal Area CRS\", BASEGEODCRS[\"ETRS89\"," + "DATUM[\"ETRS89\"," + "ELLIPSOID[\"GRS 80\", 6378137, 298.257222101, LENGTHUNIT[\"metre\", 1.0]]]]," + "CONVERSION[\"LAEA\"," + "METHOD[\"Lambert Azimuthal Equal Area\", ID[\"EPSG\", 9820]]," + "PARAMETER[\"Latitude of origin\", 52.0," + "ANGLEUNIT[\"degree\", 0.0174532925199433]]," + "PARAMETER[\"Longitude of origin\", 10.0," + "ANGLEUNIT[\"degree\", 0.0174532925199433]]," + "PARAMETER[\"False easting\", 4321000.0, LENGTHUNIT[\"metre\", 1.0]]," + "PARAMETER[\"False northing\", 3210000.0, LENGTHUNIT[\"metre\", 1.0]]]," + "CS[Cartesian, 2]," + "AXIS[\"(Y)\", north, ORDER[1]]," + "AXIS[\"(X)\", east, ORDER[2]]," + "LENGTHUNIT[\"metre\", 1.0]," + "SCOPE[\"Description of a purpose\"]," + "AREA[\"An area description\"]," + "ID[\"EuroGeographics\", \"ETRS-LAEA\"]]", + gsoap_resqml2_0_1::eml20__TimeUom::s, gsoap_resqml2_0_1::eml20__LengthUom::m, "Unknown", false); // CRS translation is just for testing; local3dCrs = repo.createLocalDepth3dCrs("", "Default local CRS", .0, .0, .0, .0, gsoap_resqml2_0_1::eml20__LengthUom::m, 23031, gsoap_resqml2_0_1::eml20__LengthUom::m, "Unknown", false); repo.setDefaultCrs(local3dCrs); @@ -5114,11 +5133,15 @@ void deserialize(const string & inputFile) cout << "Title is : " << crs->getTitle() << endl; if (crs->isProjectedCrsDefinedWithEpsg()) cout << "Projected : EPSG " << crs->getProjectedCrsEpsgCode() << endl; + else if (crs->isProjectedCrsDefinedWithWkt()) + cout << "Projected : WKT " << crs->getProjectedCrsWkt() << endl; else if (crs->isProjectedCrsUnknown()) cout << "Projected : Unknown." << "Reason is:" << crs->getProjectedCrsUnknownReason() << endl; if (crs->isVerticalCrsDefinedWithEpsg()) cout << "Vertical : EPSG one" << endl; + else if (crs->isVerticalCrsDefinedWithWkt()) + cout << "Vertical : WKT " << crs->getVerticalCrsWkt() << endl; else if (crs->isVerticalCrsUnknown()) cout << "Vertical : Unknown." << "Reason is:" << crs->getVerticalCrsUnknownReason() << endl; diff --git a/python/.gitignore b/python/.gitignore index 579386b4..65e3eee4 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -1,5 +1,5 @@ # ignore cmake and swig auto generated files -setup.py +pyproject.toml swigGeneratedPythonWrapper.cpp swigGeneratedPythonWrapper.h diff --git a/python/BUILD.md b/python/BUILD.md new file mode 100644 index 00000000..32460a87 --- /dev/null +++ b/python/BUILD.md @@ -0,0 +1,3 @@ +Enable CMake boolean variable SWIG_PYTHON_BUILTIN if you want more performance : read [SWIG documentation](http://swig.org/Doc4.0/SWIGDocumentation.html#Python_nn28) for more information about this "builtin" parameter. The main drawback of using such a parameter is that it will be harder/impossible for your Python IDE to enable autocompletion for your FESAPI python extension. The recommendation is to use SWIG_PYTHON_BUILTIN only in production. + +Please disable the SWIG_LINKED_TO_RELEASE cmake variable if you build FESAPI in Debug mode. \ No newline at end of file diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 883cc70d..dd2e23f3 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -28,11 +28,11 @@ else (WIN32) endif (WIN32) configure_file(${CMAKE_SOURCE_DIR}/cmake/swigPythonInclude.i.in ${CMAKE_SOURCE_DIR}/swig/swigPythonInclude.i) # Overwrite if different if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set (EXTRA_COMPILE_ARGS "extra_compile_args=['/DSWIG_TYPE_TABLE=FESTAPI']") + set (EXTRA_COMPILE_ARGS "extra-compile-args=['/DSWIG_TYPE_TABLE=FESTAPI']") else () - set (EXTRA_COMPILE_ARGS "extra_compile_args=['-DSWIG_TYPE_TABLE=FESTAPI', '-std=c++11']") + set (EXTRA_COMPILE_ARGS "extra-compile-args=['-DSWIG_TYPE_TABLE=FESTAPI', '-std=c++11']") endif() -configure_file(${CMAKE_SOURCE_DIR}/cmake/setup.py.in ${CMAKE_SOURCE_DIR}/python/setup.py) # Overwrite if different +configure_file(${CMAKE_SOURCE_DIR}/cmake/pyproject.toml.in ${CMAKE_SOURCE_DIR}/python/pyproject.toml) # Overwrite if different # SWIG execution message("Generating SWIG Python files...") diff --git a/python/README.md b/python/README.md index 32460a87..3bfd172c 100644 --- a/python/README.md +++ b/python/README.md @@ -1,3 +1,15 @@ -Enable CMake boolean variable SWIG_PYTHON_BUILTIN if you want more performance : read [SWIG documentation](http://swig.org/Doc4.0/SWIGDocumentation.html#Python_nn28) for more information about this "builtin" parameter. The main drawback of using such a parameter is that it will be harder/impossible for your Python IDE to enable autocompletion for your FESAPI python extension. The recommendation is to use SWIG_PYTHON_BUILTIN only in production. -Please disable the SWIG_LINKED_TO_RELEASE cmake variable if you build FESAPI in Debug mode. \ No newline at end of file +**FESAPI** is a library for Energistics data standards (mainly RESQML™) + +### Examples + +A Python script and a Jupyter Notebook are available [here](https://github.com/F2I-Consulting/fesapi/tree/master/python/example). + +### Credits +This software was developed with : +- the gSOAP toolkit from Genivia Inc +- the date library from Howard Hinnant + +FESAPI Product incorporates RESQML™, WITSML™ and PRODML™ technology/standards provided by the Energistics Consortium, Inc. + +RESQML, WITSML and PRODML are trademarks or registered trademarks of Energistics Consortium, Inc. diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 00000000..b9fe9648 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,6 @@ +from setuptools import setup + +# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html +# If compatibility with legacy builds or versions of tools that don’t support certain packaging standards (e.g. PEP 517 or PEP 660), +# a simple setup.py script can be added to your project (while keeping the configuration in pyproject.toml): +setup() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7247d64..41413b9f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,6 +72,8 @@ else () target_link_libraries (${CPP_LIBRARY_NAME} PRIVATE MINIZIP::MINIZIP) endif () +target_link_libraries (${CPP_LIBRARY_NAME} PRIVATE Boost::boost) + if (WIN32) if (NOT BUILD_SHARED_LIBS) target_compile_definitions(${CPP_LIBRARY_NAME} PRIVATE FESAPI_STATIC) @@ -79,9 +81,7 @@ if (WIN32) # It is necessary for Boost(.Uuid) 1.86 to define NOMINMAX on Windows target_compile_definitions(${CPP_LIBRARY_NAME} PRIVATE "NOMINMAX") - target_link_libraries (${CPP_LIBRARY_NAME} PRIVATE Boost::boost) - -# szip is linked because it is a potential dependency of hdf5 which is sometimes statically linked to fesapi. If hdf5 would be dynamically linked from fesapi (or if hdf5 does not depend at all to szip), szip could be not present in these linked libraries. + # szip is linked because it is a potential dependency of hdf5 which is sometimes statically linked to fesapi. If hdf5 would be dynamically linked from fesapi (or if hdf5 does not depend at all to szip), szip could be not present in these linked libraries. if (EXISTS ${SZIP_LIBRARY_RELEASE} AND EXISTS ${SZIP_LIBRARY_DEBUG}) target_link_libraries (${CPP_LIBRARY_NAME} PRIVATE optimized ${SZIP_LIBRARY_RELEASE} debug ${SZIP_LIBRARY_DEBUG}) elseif (EXISTS ${SZIP_LIBRARY_RELEASE}) @@ -112,12 +112,6 @@ elseif (UNIX) VERSION ${Fesapi_VERSION} SOVERSION ${Fesapi_VERSION_MAJOR}.${Fesapi_VERSION_MINOR}) - # We need to use Boost regex instead of std regex for gcc < 4.9 - if (NOT CAN_USE_STD_REGEX) - target_link_libraries(${CPP_LIBRARY_NAME} PRIVATE Boost::regex) - else () - target_link_libraries(${CPP_LIBRARY_NAME} PRIVATE Boost::boost) - endif() endif (WIN32) # ============================================================================ @@ -388,8 +382,19 @@ if (WITH_PYTHON_WRAPPING) TARGETS ${CPP_LIBRARY_NAME} RUNTIME DESTINATION ${FESAPI_ROOT_DIR}/python/fesapi/ ) + install( + TARGETS ${CPP_LIBRARY_NAME} + RUNTIME_DEPENDENCY_SET dep-set + ) + install( + RUNTIME_DEPENDENCY_SET dep-set + PRE_EXCLUDE_REGEXES "api-ms-.*" "ext-ms-.*" + POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" + DIRECTORIES ${CMAKE_BINARY_DIR} + RUNTIME DESTINATION ${FESAPI_ROOT_DIR}/python/fesapi/ + ) ENDIF (WIN32) - INSTALL(CODE "execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/python/setup.py bdist_wheel + INSTALL(CODE "execute_process(COMMAND \"${Python3_EXECUTABLE}\" -m build --wheel WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/python)") endif (WITH_PYTHON_WRAPPING) diff --git a/src/common/AbstractObject.cpp b/src/common/AbstractObject.cpp index 491578b2..d4644c2d 100644 --- a/src/common/AbstractObject.cpp +++ b/src/common/AbstractObject.cpp @@ -23,11 +23,6 @@ under the License. #include #include -#if !defined(__GLIBCXX__) || __GLIBCXX__ > 20150623 || __GLIBCXX__ == 20140422 || __GLIBCXX__ == 20140716 || __GLIBCXX__ == 20141030 -#include -#else -#include -#endif #include #include @@ -276,16 +271,9 @@ void AbstractObject::setUuid(const std::string & uuid) } else { - // https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions -#if !defined(__GLIBCXX__) || __GLIBCXX__ > 20150623 || __GLIBCXX__ == 20140422 || __GLIBCXX__ == 20140716 || __GLIBCXX__ == 20141030 if (!regex_match(uuid, regex("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"))) { throw invalid_argument("The uuid does not match the official uuid regular expression : " + uuid); } -#else - if (!boost::regex_match(uuid, boost::regex("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"))) { - throw invalid_argument("The uuid does not match the official uuid regular expression : " + uuid); - } -#endif if (gsoapProxy2_0_1 != nullptr) { gsoapProxy2_0_1->uuid = uuid; } else if (gsoapProxy2_3 != nullptr) { gsoapProxy2_3->uuid = uuid; } } @@ -805,8 +793,8 @@ std::unordered_map< std::string, std::string > AbstractObject::getExtraMetadataS { if (gsoapProxy2_0_1 != nullptr) { std::unordered_map< std::string, std::string > result; - for (size_t i = 0; i < static_cast(gsoapProxy2_0_1)->ExtraMetadata.size(); ++i) { - result[static_cast(gsoapProxy2_0_1)->ExtraMetadata[i]->Name] = static_cast(gsoapProxy2_0_1)->ExtraMetadata[i]->Value; + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + result[em->Name] = em->Value; } return result; @@ -815,13 +803,20 @@ std::unordered_map< std::string, std::string > AbstractObject::getExtraMetadataS throw logic_error("Not implemented yet."); } -vector AbstractObject::getExtraMetadata(const std::string & key) const +vector AbstractObject::getExtraMetadata(const std::string& key) const { vector result; if (gsoapProxy2_0_1 != nullptr) { - for (size_t i = 0; i < static_cast(gsoapProxy2_0_1)->ExtraMetadata.size(); ++i) { - if (static_cast(gsoapProxy2_0_1)->ExtraMetadata[i]->Name.compare(key) == 0) { - result.push_back(static_cast(gsoapProxy2_0_1)->ExtraMetadata[i]->Value); + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + if (em->Name.compare(key) == 0) { + result.push_back(em->Value); + } + } + } + else if (gsoapProxy2_3 != nullptr) { + for (gsoap_eml2_3::eml23__ExtensionNameValue const* em : static_cast(gsoapProxy2_3)->ExtensionNameValue) { + if (em->Name.compare(key) == 0) { + result.push_back(em->Value->__item); } } } @@ -829,53 +824,43 @@ vector AbstractObject::getExtraMetadata(const std::string & key) const return result; } -unsigned int AbstractObject::getExtraMetadataCount() const +uint64_t AbstractObject::getExtraMetadataCount() const { - size_t result = 0; + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { - result = static_cast(gsoapProxy2_0_1)->ExtraMetadata.size(); + return static_cast(gsoapProxy2_0_1)->ExtraMetadata.size(); } else if (gsoapProxy2_3 != nullptr) { - result = static_cast(gsoapProxy2_3)->ExtensionNameValue.size(); - } - else { - throw logic_error("Not implemented yet."); - } - - if (result > (std::numeric_limits::max)()) { - throw range_error("There are too much extra metadata."); + return static_cast(gsoapProxy2_3)->ExtensionNameValue.size(); } - return static_cast(result); + throw logic_error("Not implemented yet."); } -std::string AbstractObject::getExtraMetadataKeyAtIndex(unsigned int index) const +std::string AbstractObject::getExtraMetadataKeyAtIndex(uint64_t index) const { - if (getExtraMetadataCount() <= index) { - throw out_of_range("The index is out of range."); - } - if (gsoapProxy2_0_1 != nullptr) { - return (static_cast(gsoapProxy2_0_1)->ExtraMetadata)[index]->Name; + return (static_cast(gsoapProxy2_0_1)->ExtraMetadata).at(index)->Name; } else if (gsoapProxy2_3 != nullptr) { - return (static_cast(gsoapProxy2_3)->ExtensionNameValue)[index]->Name; + return (static_cast(gsoapProxy2_3)->ExtensionNameValue).at(index)->Name; } throw logic_error("Not implemented yet."); } -std::string AbstractObject::getExtraMetadataStringValueAtIndex(unsigned int index) const +std::string AbstractObject::getExtraMetadataStringValueAtIndex(uint64_t index) const { if (getExtraMetadataCount() <= index) { throw out_of_range("The index is out of range."); } if (gsoapProxy2_0_1 != nullptr) { - return (static_cast(gsoapProxy2_0_1)->ExtraMetadata)[index]->Value; + return (static_cast(gsoapProxy2_0_1)->ExtraMetadata).at(index)->Value; } else if (gsoapProxy2_3 != nullptr) { - return (static_cast(gsoapProxy2_3)->ExtensionNameValue)[index]->Value->__item; + return (static_cast(gsoapProxy2_3)->ExtensionNameValue).at(index)->Value->__item; } throw logic_error("Not implemented yet."); @@ -1046,15 +1031,10 @@ void AbstractObject::readArrayNdOfDoubleValues(gsoap_eml2_3::eml23__AbstractFloa case SOAP_TYPE_gsoap_eml2_3_eml23__FloatingPointXmlArray: { gsoap_eml2_3::eml23__FloatingPointXmlArray const* xmlArray = static_cast(arrayInput); -#if !defined(__GLIBCXX__) || __GLIBCXX__ > 20150623 || __GLIBCXX__ == 20140422 || __GLIBCXX__ == 20140716 || __GLIBCXX__ == 20141030 const std::regex ws_re("\\s+"); // whitespace std::sregex_token_iterator it(xmlArray->Values.begin(), xmlArray->Values.end(), ws_re, -1); std::sregex_token_iterator endToken; -#else - const boost::regex ws_re("\\s+"); // whitespace - boost::sregex_token_iterator it(xmlArray->Values.begin(), xmlArray->Values.end(), ws_re, -1); - boost::sregex_token_iterator endToken; -#endif + size_t index = 0; while (it != endToken) { arrayOutput[index++] = std::stod(*it++); diff --git a/src/common/AbstractObject.h b/src/common/AbstractObject.h index 104aaf20..b811df6e 100644 --- a/src/common/AbstractObject.h +++ b/src/common/AbstractObject.h @@ -609,7 +609,7 @@ namespace COMMON_NS * * @returns The extra metadata count of this instance. */ - DLL_IMPORT_OR_EXPORT unsigned int getExtraMetadataCount() const; + DLL_IMPORT_OR_EXPORT uint64_t getExtraMetadataCount() const; /** * Get the key of a key value pair at a particular index in the extra metadata set of this @@ -621,7 +621,7 @@ namespace COMMON_NS * * @returns The extra metadata key at @p index. */ - DLL_IMPORT_OR_EXPORT std::string getExtraMetadataKeyAtIndex(unsigned int index) const; + DLL_IMPORT_OR_EXPORT std::string getExtraMetadataKeyAtIndex(uint64_t index) const; /** * Get the value of a key value pair at a particular index in the extra metadata set of this @@ -633,7 +633,7 @@ namespace COMMON_NS * * @returns The extra metadata value at @p index. */ - DLL_IMPORT_OR_EXPORT std::string getExtraMetadataStringValueAtIndex(unsigned int index) const; + DLL_IMPORT_OR_EXPORT std::string getExtraMetadataStringValueAtIndex(uint64_t index) const; /** * Build and return an ETP1.2 URI from an Energistics dataobject. @@ -889,13 +889,8 @@ namespace COMMON_NS { gsoap_eml2_3::eml23__IntegerXmlArray const * xmlArray = static_cast(arrayInput); const std::regex ws_re("\\s+"); // whitespace -#if !defined(__GLIBCXX__) || __GLIBCXX__ > 20150623 || __GLIBCXX__ == 20140422 || __GLIBCXX__ == 20140716 || __GLIBCXX__ == 20141030 std::sregex_token_iterator it(xmlArray->Values.begin(), xmlArray->Values.end(), ws_re, -1); std::sregex_token_iterator endToken; -#else - boost::sregex_token_iterator it(xmlArray->Values.begin(), xmlArray->Values.end(), ws_re, -1); - boost::sregex_token_iterator endToken; -#endif size_t index = 0; while (it != endToken) { arrayOutput[index++] = std::stoll(*it++); diff --git a/src/common/DataObjectRepository.cpp b/src/common/DataObjectRepository.cpp index d707e798..470bbf2c 100644 --- a/src/common/DataObjectRepository.cpp +++ b/src/common/DataObjectRepository.cpp @@ -1166,7 +1166,7 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const s double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: @@ -1185,18 +1185,18 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const s EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalDepth3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, - verticalUom, verticalUnknownReason, isUpOriented); + projectedUom, projectedDefinition, + verticalUom, verticalDefinition, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, - verticalUom, verticalUnknownReason, isUpOriented); + projectedUom, projectedDefinition, + verticalUom, verticalDefinition, isUpOriented); default: throw std::invalid_argument("Unrecognized Energistics standard."); } @@ -1206,17 +1206,17 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const s double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalDepth3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, projectedEpsgCode, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, projectedEpsgCode, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); default: throw std::invalid_argument("Unrecognized Energistics standard."); } @@ -1225,17 +1225,17 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const s EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalDepth3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, verticalUom, verticalEpsgCode, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, verticalUom, verticalEpsgCode, isUpOriented); default: throw std::invalid_argument("Unrecognized Energistics standard."); @@ -1247,7 +1247,7 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const st double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: @@ -1268,21 +1268,21 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const st EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalTime3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, timeUom, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, timeUom, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); default: throw std::invalid_argument("Unrecognized Energistics standard."); } @@ -1293,19 +1293,19 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const st double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalTime3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, projectedEpsgCode, timeUom, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, projectedEpsgCode, timeUom, - verticalUom, verticalUnknownReason, isUpOriented); + verticalUom, verticalDefinition, isUpOriented); default: throw std::invalid_argument("Unrecognized Energistics standard."); } @@ -1314,19 +1314,19 @@ EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const st EML2_NS::AbstractLocal3dCrs* DataObjectRepository::createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { switch (defaultEmlVersion) { case DataObjectRepository::EnergisticsStandard::EML2_0: return new RESQML2_0_1_NS::LocalTime3dCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, timeUom, verticalUom, verticalEpsgCode, isUpOriented); case DataObjectRepository::EnergisticsStandard::EML2_3: return new EML2_3_NS::LocalEngineeringCompoundCrs(this, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, - projectedUom, projectedUnknownReason, + projectedUom, projectedDefinition, timeUom, verticalUom, verticalEpsgCode, isUpOriented); default: diff --git a/src/common/DataObjectRepository.h b/src/common/DataObjectRepository.h index a56bdb10..8ae0c7ae 100644 --- a/src/common/DataObjectRepository.h +++ b/src/common/DataObjectRepository.h @@ -828,11 +828,11 @@ namespace COMMON_NS double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which is fully unknown. Resulting local depth 3d CRS is - * stored into this repository + * @brief Creates a local depth 3d CRS which is fully defined by a string representation. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @@ -846,11 +846,11 @@ namespace COMMON_NS * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this depth CRS is actually an * elevation CRS. * @@ -859,13 +859,13 @@ namespace COMMON_NS DLL_IMPORT_OR_EXPORT EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unknown for its vertical part. Resulting local depth 3d CRS is - * stored into this repository + * part and which is defined by a string representation for its vertical part. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If projectedEpsgCode == 0. @@ -882,8 +882,8 @@ namespace COMMON_NS * @param projectedUom The unit of measure of the projected axis of this instance. * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this depth CRS is actually an * elevation CRS. * @@ -893,12 +893,12 @@ namespace COMMON_NS double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which is unknown for its projected part and which is - * identified by an EPSG code for its vertical part. Resulting local depth 3d CRS is - * stored into this repository + * @brief Creates a local depth 3d CRS which is defined by a string representation for its projected part + * and which is identified by an EPSG code for its vertical part. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -913,8 +913,8 @@ namespace COMMON_NS * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. * @param isUpOriented If true, indicates that this depth CRS is actually an @@ -925,8 +925,8 @@ namespace COMMON_NS DLL_IMPORT_OR_EXPORT EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * @brief Creates a local time 3d CRS which is fully identified by means of EPSG code. @@ -960,11 +960,11 @@ namespace COMMON_NS double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * @brief Creates a local time 3d CRS which is fully unknown. Resulting local time 3d CRS is - * stored into this repository + * @brief Creates a local time 3d CRS which is fully defined by a string representation. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @@ -978,12 +978,12 @@ namespace COMMON_NS * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that the Z offset if an elevation when * positive. If false, the Z offset if a depth when positive. * @@ -992,14 +992,14 @@ namespace COMMON_NS DLL_IMPORT_OR_EXPORT EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local time 3d CRS which is identified by an EPSG code for its projected - * part and which is unknown for its vertical part. Resulting local time 3d CRS is - * stored into this repository + * part and which is defined by a string representation for its vertical part. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If projectedEpsgCode == 0. @@ -1017,8 +1017,8 @@ namespace COMMON_NS * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that the Z offset if an elevation when * positive. If false, the Z offset if a depth when positive. * @@ -1029,12 +1029,12 @@ namespace COMMON_NS double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local time 3d CRS which unknown for its projected part and which is - * identified by an EPSG code for its vertical part. Resulting local time 3d CRS is - * stored into this repository + * @brief Creates a local time 3d CRS which is defined by a string representation for its projected part + * and which is identified by an EPSG code for its vertical part. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -1049,8 +1049,8 @@ namespace COMMON_NS * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. @@ -1062,9 +1062,9 @@ namespace COMMON_NS DLL_IMPORT_OR_EXPORT EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * @brief Creates a measured depth (MD) datum into this repository diff --git a/src/eml2/AbstractLocal3dCrs.cpp b/src/eml2/AbstractLocal3dCrs.cpp index 5f5124fd..4cc0df03 100644 --- a/src/eml2/AbstractLocal3dCrs.cpp +++ b/src/eml2/AbstractLocal3dCrs.cpp @@ -61,6 +61,8 @@ void AbstractLocal3dCrs::convertXyzPointsToGlobalCrs(double * xyzPoints, uint64_ double AbstractLocal3dCrs::getOriginOrdinal1() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->XOffset; } @@ -68,11 +70,13 @@ double AbstractLocal3dCrs::getOriginOrdinal1() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getOriginOrdinal1(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } double AbstractLocal3dCrs::getOriginOrdinal2() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->YOffset; } @@ -80,11 +84,13 @@ double AbstractLocal3dCrs::getOriginOrdinal2() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getOriginOrdinal2(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } double AbstractLocal3dCrs::getOriginDepthOrElevation() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ZOffset; } @@ -92,11 +98,13 @@ double AbstractLocal3dCrs::getOriginDepthOrElevation() const return static_cast(gsoapProxy2_3)->OriginVerticalCoordinate; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } double AbstractLocal3dCrs::getArealRotation() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ArealRotation->__item; } @@ -104,11 +112,13 @@ double AbstractLocal3dCrs::getArealRotation() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getAzimuth(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } gsoap_resqml2_0_1::eml20__PlaneAngleUom AbstractLocal3dCrs::getArealRotationUom() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ArealRotation->uom; } @@ -121,11 +131,13 @@ gsoap_resqml2_0_1::eml20__PlaneAngleUom AbstractLocal3dCrs::getArealRotationUom( return result; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } bool AbstractLocal3dCrs::isDepthOriented() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ZIncreasingDownward; } @@ -133,11 +145,13 @@ bool AbstractLocal3dCrs::isDepthOriented() const return static_cast(gsoapProxy2_3)->VerticalAxis->Direction == gsoap_eml2_3::eml23__VerticalDirection::down; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found.It is probably a partial one."); + throw logic_error("Not implemented yet."); } bool AbstractLocal3dCrs::isProjectedCrsDefinedWithEpsg() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ProjectedCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__ProjectedCrsEpsgCode; } @@ -145,25 +159,52 @@ bool AbstractLocal3dCrs::isProjectedCrsDefinedWithEpsg() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->isProjectedCrsDefinedWithEpsg(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); +} + +bool AbstractLocal3dCrs::isProjectedCrsDefinedWithWkt() const +{ + cannotBePartial(); + + if (gsoapProxy2_0_1 != nullptr) { + if (static_cast(gsoapProxy2_0_1)->ProjectedCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__ProjectedUnknownCrs && + static_cast(static_cast(gsoapProxy2_0_1)->ProjectedCrs)->Unknown == "WKT") { + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + if (em->Name.find("projectedCrsWkt") != std::string::npos) { + return true; + } + } + } + return false; + } + else if (gsoapProxy2_3 != nullptr) { + return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->isProjectedCrsDefinedWithWkt(); + } + + throw logic_error("Not implemented yet."); } bool AbstractLocal3dCrs::isProjectedCrsUnknown() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { - return static_cast(gsoapProxy2_0_1)->ProjectedCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__ProjectedUnknownCrs; + return static_cast(gsoapProxy2_0_1)->ProjectedCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__ProjectedUnknownCrs && + !isProjectedCrsDefinedWithWkt(); } else if (gsoapProxy2_3 != nullptr) { return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->isProjectedCrsUnknown(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } std::string AbstractLocal3dCrs::getProjectedCrsUnknownReason() const { - if (isProjectedCrsUnknown() == false) - throw invalid_argument("The associated projected Crs is not unknown."); + cannotBePartial(); + + if (!isProjectedCrsUnknown()) + throw invalid_argument("The associated projected CRS is not unknown."); if (gsoapProxy2_0_1 != nullptr) { return static_cast(static_cast(gsoapProxy2_0_1)->ProjectedCrs)->Unknown; @@ -172,11 +213,34 @@ std::string AbstractLocal3dCrs::getProjectedCrsUnknownReason() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getProjectedCrsUnknownReason(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); +} + +std::string AbstractLocal3dCrs::getProjectedCrsWkt() const +{ + cannotBePartial(); + + if (!isProjectedCrsDefinedWithWkt()) + throw invalid_argument("The associated projected CRS is not a WKT one."); + + if (gsoapProxy2_0_1 != nullptr) { + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + if (em->Name.find("projectedCrsWkt") != std::string::npos) { + return em->Value; + } + } + } + else if (gsoapProxy2_3 != nullptr) { + return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getProjectedCrsWkt(); + } + + throw logic_error("Not implemented yet."); } uint64_t AbstractLocal3dCrs::getProjectedCrsEpsgCode() const { + cannotBePartial(); + if (isProjectedCrsDefinedWithEpsg() == false) throw invalid_argument("The associated projected Crs is not an EPSG one."); @@ -187,11 +251,13 @@ uint64_t AbstractLocal3dCrs::getProjectedCrsEpsgCode() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getProjectedCrsEpsgCode(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } bool AbstractLocal3dCrs::isVerticalCrsDefinedWithEpsg() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->VerticalCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__VerticalCrsEpsgCode; } @@ -199,11 +265,35 @@ bool AbstractLocal3dCrs::isVerticalCrsDefinedWithEpsg() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->VerticalCrs->Uuid)->isVerticalCrsDefinedWithEpsg(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); +} + +bool AbstractLocal3dCrs::isVerticalCrsDefinedWithWkt() const +{ + cannotBePartial(); + + if (gsoapProxy2_0_1 != nullptr) { + if (static_cast(gsoapProxy2_0_1)->VerticalCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__VerticalUnknownCrs && + getVerticalCrsUnknownReason() == "WKT") { + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + if (em->Name.find("verticalCrsWkt") != std::string::npos) { + return true; + } + } + } + return false; + } + else if (gsoapProxy2_3 != nullptr) { + return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->isProjectedCrsDefinedWithWkt(); + } + + throw logic_error("Not implemented yet."); } bool AbstractLocal3dCrs::isVerticalCrsUnknown() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->VerticalCrs->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_eml20__VerticalUnknownCrs; } @@ -211,11 +301,13 @@ bool AbstractLocal3dCrs::isVerticalCrsUnknown() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->VerticalCrs->Uuid)->isVerticalCrsUnknown(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } std::string AbstractLocal3dCrs::getVerticalCrsUnknownReason() const { + cannotBePartial(); + if (!isVerticalCrsUnknown()) { throw invalid_argument("The associated vertical Crs is not unknown."); } @@ -227,11 +319,34 @@ std::string AbstractLocal3dCrs::getVerticalCrsUnknownReason() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->VerticalCrs->Uuid)->getVerticalCrsUnknownReason(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); +} + +std::string AbstractLocal3dCrs::getVerticalCrsWkt() const +{ + cannotBePartial(); + + if (!isVerticalCrsDefinedWithWkt()) + throw invalid_argument("The associated vertical CRS is not a WKT one."); + + if (gsoapProxy2_0_1 != nullptr) { + for (gsoap_resqml2_0_1::resqml20__NameValuePair const* em : static_cast(gsoapProxy2_0_1)->ExtraMetadata) { + if (em->Name.find("verticalCrsWkt") != std::string::npos) { + return em->Value; + } + } + } + else if (gsoapProxy2_3 != nullptr) { + return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->VerticalCrs->Uuid)->getVerticalCrsWkt(); + } + + throw logic_error("Not implemented yet."); } uint64_t AbstractLocal3dCrs::getVerticalCrsEpsgCode() const { + cannotBePartial(); + if (!isVerticalCrsDefinedWithEpsg()) { throw invalid_argument("The associated vertical Crs is not an EPSG one."); } @@ -243,11 +358,13 @@ uint64_t AbstractLocal3dCrs::getVerticalCrsEpsgCode() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->VerticalCrs->Uuid)->getVerticalCrsEpsgCode(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } gsoap_resqml2_0_1::eml20__LengthUom AbstractLocal3dCrs::getProjectedCrsUnit() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->ProjectedUom; } @@ -260,11 +377,13 @@ gsoap_resqml2_0_1::eml20__LengthUom AbstractLocal3dCrs::getProjectedCrsUnit() co return result; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } string AbstractLocal3dCrs::getProjectedCrsUnitAsString() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return gsoap_resqml2_0_1::soap_eml20__LengthUom2s(gsoapProxy2_0_1->soap, static_cast(gsoapProxy2_0_1)->ProjectedUom); } @@ -272,11 +391,13 @@ string AbstractLocal3dCrs::getProjectedCrsUnitAsString() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getProjectedCrsUnitAsString(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } gsoap_resqml2_0_1::eml20__LengthUom AbstractLocal3dCrs::getVerticalCrsUnit() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return static_cast(gsoapProxy2_0_1)->VerticalUom; } @@ -289,11 +410,13 @@ gsoap_resqml2_0_1::eml20__LengthUom AbstractLocal3dCrs::getVerticalCrsUnit() con return result; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } string AbstractLocal3dCrs::getVerticalCrsUnitAsString() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { return gsoap_resqml2_0_1::soap_eml20__LengthUom2s(gsoapProxy2_0_1->soap, static_cast(gsoapProxy2_0_1)->VerticalUom); } @@ -301,7 +424,7 @@ string AbstractLocal3dCrs::getVerticalCrsUnitAsString() const return static_cast(gsoapProxy2_3)->VerticalAxis->Uom; } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } std::string AbstractLocal3dCrs::getTimeUomAsString() const @@ -311,6 +434,8 @@ std::string AbstractLocal3dCrs::getTimeUomAsString() const gsoap_eml2_3::eml23__AxisOrder2d AbstractLocal3dCrs::getAxisOrder() const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { auto axisOrder = static_cast(gsoapProxy2_0_1)->ProjectedAxisOrder; const std::string axisOrderStr = gsoap_resqml2_0_1::soap_eml20__AxisOrder2d2s(gsoapProxy2_0_1->soap, axisOrder); @@ -325,11 +450,13 @@ gsoap_eml2_3::eml23__AxisOrder2d AbstractLocal3dCrs::getAxisOrder() const return getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->getAxisOrder(); } - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); + throw logic_error("Not implemented yet."); } void AbstractLocal3dCrs::setAxisOrder(gsoap_eml2_3::eml23__AxisOrder2d axisOrder) const { + cannotBePartial(); + if (gsoapProxy2_0_1 != nullptr) { const std::string axisOrderStr = gsoap_eml2_3::soap_eml23__AxisOrder2d2s(gsoapProxy2_0_1->soap, axisOrder); gsoap_resqml2_0_1::eml20__AxisOrder2d result; @@ -342,7 +469,6 @@ void AbstractLocal3dCrs::setAxisOrder(gsoap_eml2_3::eml23__AxisOrder2d axisOrder else if (gsoapProxy2_3 != nullptr) { getRepository()->getDataObjectByUuid(static_cast(gsoapProxy2_3)->LocalEngineering2dCrs->Uuid)->setAxisOrder(axisOrder); } - else { - throw logic_error("The local CRS UUID " + getUuid() + " cannot be found. It is probably a partial one."); - } + + throw logic_error("Not implemented yet."); } diff --git a/src/eml2/AbstractLocal3dCrs.h b/src/eml2/AbstractLocal3dCrs.h index 0aa7f7fc..9d313ea1 100644 --- a/src/eml2/AbstractLocal3dCrs.h +++ b/src/eml2/AbstractLocal3dCrs.h @@ -85,6 +85,13 @@ namespace EML2_NS */ DLL_IMPORT_OR_EXPORT bool isProjectedCrsDefinedWithEpsg() const; + /** + * Indicates either the associated projected CRS is given in a WKT format or not. + * + * @returns True if the projected CRS is given in a WKT format, false if not. + */ + DLL_IMPORT_OR_EXPORT bool isProjectedCrsDefinedWithWkt() const; + /** * Indicates either the associated projected CRS is unknown or not. * @@ -101,6 +108,15 @@ namespace EML2_NS */ DLL_IMPORT_OR_EXPORT std::string getProjectedCrsUnknownReason() const; + /** + * Gets the WKT of the projected CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The projected CRS WKT. + */ + DLL_IMPORT_OR_EXPORT std::string getProjectedCrsWkt() const; + /** * Gets the EPSG code of the projected CRS * @@ -117,6 +133,13 @@ namespace EML2_NS */ DLL_IMPORT_OR_EXPORT bool isVerticalCrsDefinedWithEpsg() const; + /** + * Indicates either the associated vertical CRS is given in a WKT format or not. + * + * @returns True if the vertical CRS is given in a WKT format, false if not. + */ + DLL_IMPORT_OR_EXPORT bool isVerticalCrsDefinedWithWkt() const; + /** * Indicates either the associated vertical CRS is unknown or not. * @@ -133,6 +156,15 @@ namespace EML2_NS */ DLL_IMPORT_OR_EXPORT std::string getVerticalCrsUnknownReason() const; + /** + * Gets the WKT of the vertical CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The vertical CRS WKT. + */ + DLL_IMPORT_OR_EXPORT std::string getVerticalCrsWkt() const; + /** * Gets the EPSG code of the vertical CRS * diff --git a/src/eml2_3/LocalEngineering2dCrs.cpp b/src/eml2_3/LocalEngineering2dCrs.cpp index aef462fb..d67640a0 100644 --- a/src/eml2_3/LocalEngineering2dCrs.cpp +++ b/src/eml2_3/LocalEngineering2dCrs.cpp @@ -126,7 +126,7 @@ LocalEngineering2dCrs::LocalEngineering2dCrs(COMMON_NS::DataObjectRepository* re } LocalEngineering2dCrs::LocalEngineering2dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, - std::string unknownReason, + std::string projectedDefinition, double originOrdinal1, double originOrdinal2, gsoap_eml2_3::eml23__LengthUom projectedUom, double azimuth, gsoap_eml2_3::eml23__PlaneAngleUom azimuthUom, eml23__NorthReferenceKind azimuthReference, eml23__AxisOrder2d axisOrder) @@ -142,9 +142,16 @@ LocalEngineering2dCrs::LocalEngineering2dCrs(COMMON_NS::DataObjectRepository* re azimuth, azimuthUom, azimuthReference, axisOrder); - auto* unknownCrs = soap_new_eml23__ProjectedUnknownCrs(gsoapProxy2_3->soap); - unknownCrs->Unknown = unknownReason; - local2dCrs->OriginProjectedCrs->AbstractProjectedCrs = unknownCrs; + if (projectedDefinition.size() < 5 || projectedDefinition.substr(0, 5) != "PROJC") { // Either PROJCRS or alias PROJCS + auto* unknownCrs = soap_new_eml23__ProjectedUnknownCrs(gsoapProxy2_3->soap); + unknownCrs->Unknown = projectedDefinition; + local2dCrs->OriginProjectedCrs->AbstractProjectedCrs = unknownCrs; + } + else { + auto* wktCrs = soap_new_eml23__ProjectedWktCrs(gsoapProxy2_3->soap); + wktCrs->WellKnownText = projectedDefinition; + local2dCrs->OriginProjectedCrs->AbstractProjectedCrs = wktCrs; + } repo->addDataObject(unique_ptr{this}); } @@ -174,6 +181,11 @@ bool LocalEngineering2dCrs::isProjectedCrsDefinedWithEpsg() const return static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__ProjectedEpsgCrs; } +bool LocalEngineering2dCrs::isProjectedCrsDefinedWithWkt() const +{ + return static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__ProjectedWktCrs; +} + bool LocalEngineering2dCrs::isProjectedCrsUnknown() const { return static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__ProjectedUnknownCrs; @@ -184,6 +196,11 @@ std::string LocalEngineering2dCrs::getProjectedCrsUnknownReason() const return static_cast(static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs)->Unknown; } +std::string LocalEngineering2dCrs::getProjectedCrsWkt() const +{ + return static_cast(static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs)->WellKnownText; +} + int64_t LocalEngineering2dCrs::getProjectedCrsEpsgCode() const { return static_cast(static_cast(gsoapProxy2_3)->OriginProjectedCrs->AbstractProjectedCrs)->EpsgCode; diff --git a/src/eml2_3/LocalEngineering2dCrs.h b/src/eml2_3/LocalEngineering2dCrs.h index 0b2e8080..edbcfafe 100644 --- a/src/eml2_3/LocalEngineering2dCrs.h +++ b/src/eml2_3/LocalEngineering2dCrs.h @@ -63,7 +63,8 @@ namespace EML2_3_NS * @param [in,out] repo If non-null, the repo. * @param guid Unique identifier. * @param title The title. - * @param unknownReason The reason why this CRS is unknown. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param originOrdinal1 The first origin ordinal. * @param originOrdinal2 The second origin ordinal. * @param projectedUom The projected uom. @@ -73,7 +74,7 @@ namespace EML2_3_NS * @param axisOrder The axis order of the projected CRS. */ LocalEngineering2dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, - std::string unknownReason, + std::string projectedDefinition, double originOrdinal1, double originOrdinal2, gsoap_eml2_3::eml23__LengthUom projectedUom, double azimuth, gsoap_eml2_3::eml23__PlaneAngleUom azimuthUom, gsoap_eml2_3::eml23__NorthReferenceKind azimuthReference, gsoap_eml2_3::eml23__AxisOrder2d axisOrder); @@ -126,6 +127,13 @@ namespace EML2_3_NS * @returns True if the projected CRS is defined with an EPSG code, false if not. */ DLL_IMPORT_OR_EXPORT bool isProjectedCrsDefinedWithEpsg() const; + + /** + * Indicates either the associated projected CRS is given in a WKT format or not. + * + * @returns True if the projected CRS is given in a WKT format, false if not. + */ + DLL_IMPORT_OR_EXPORT bool isProjectedCrsDefinedWithWkt() const; /** * Indicates either the associated projected CRS is unknown or not. @@ -143,6 +151,15 @@ namespace EML2_3_NS */ DLL_IMPORT_OR_EXPORT std::string getProjectedCrsUnknownReason() const; + /** + * Gets the WKT of the projected CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The projected CRS WKT. + */ + DLL_IMPORT_OR_EXPORT std::string getProjectedCrsWkt() const; + /** * Gets the EPSG code of the projected CRS * diff --git a/src/eml2_3/LocalEngineeringCompoundCrs.cpp b/src/eml2_3/LocalEngineeringCompoundCrs.cpp index 3b870edf..0c7e52aa 100644 --- a/src/eml2_3/LocalEngineeringCompoundCrs.cpp +++ b/src/eml2_3/LocalEngineeringCompoundCrs.cpp @@ -35,22 +35,22 @@ using namespace std; using namespace EML2_3_NS; using namespace gsoap_eml2_3; -void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, - uint64_t projectedEpsgCode, std::string unknownProjectedReason, +void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, + uint64_t projectedEpsgCode, std::string projectedDefinition, double originOrdinal1, double originOrdinal2, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, double azimuth, gsoap_eml2_3::eml23__PlaneAngleUom azimuthUom, gsoap_eml2_3::eml23__NorthReferenceKind azimuthReference, gsoap_eml2_3::eml23__AxisOrder2d axisOrder, - uint64_t verticalEpsgCode, std::string unknwownVerticalReason, + uint64_t verticalEpsgCode, std::string verticalDefinition, double originOrdinal3, gsoap_resqml2_0_1::eml20__LengthUom verticalUom, bool isUpOriented) { if (repo == nullptr) { throw invalid_argument("The soap context where the local CRS will be instantiated must exist."); } - if (unknownProjectedReason.empty() && projectedEpsgCode == 0) { + if (projectedDefinition.empty() && projectedEpsgCode == 0) { throw invalid_argument("The projected CRS must either have a non null EPSG code or a reason why it is unkown."); } - if (unknwownVerticalReason.empty() && verticalEpsgCode == 0) { + if (verticalDefinition.empty() && verticalEpsgCode == 0) { throw invalid_argument("The vertical CRS must either have a non null EPSG code or a reason why it is unkown."); } @@ -87,9 +87,9 @@ void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository * repo, c setMetadata(guid, title, "", -1, "", "", -1, ""); // 2d crs - LocalEngineering2dCrs* local2dCrs = !unknownProjectedReason.empty() - ? new LocalEngineering2dCrs(repo, boost::uuids::to_string(finalGen(gsoapProxy2_3->uuid + "_ProjectedUnknownCrs")), title + " LocalEngineering2dCrs", - unknownProjectedReason, + LocalEngineering2dCrs* local2dCrs = !projectedDefinition.empty() + ? new LocalEngineering2dCrs(repo, boost::uuids::to_string(finalGen(gsoapProxy2_3->uuid + "_ProjectedStringRepresentedCrs")), title + " LocalEngineering2dCrs", + projectedDefinition, originOrdinal1, originOrdinal2, projectedLengthUom, azimuth, azimuthUom, azimuthReference, axisOrder) @@ -102,9 +102,9 @@ void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository * repo, c repo->addRelationship(this, local2dCrs); // Vertical CRS - VerticalCrs* verticalCrs = !unknwownVerticalReason.empty() - ? new VerticalCrs(repo, boost::uuids::to_string(finalGen(gsoapProxy2_3->uuid + "_VerticalUnknownCrs")), title + " VerticalCrs", - unknwownVerticalReason, + VerticalCrs* verticalCrs = !verticalDefinition.empty() + ? new VerticalCrs(repo, boost::uuids::to_string(finalGen(gsoapProxy2_3->uuid + "_VerticalStringRepresentedCrs")), title + " VerticalCrs", + verticalDefinition, verticalLengthUom, isUpOriented) : new VerticalCrs(repo, boost::uuids::to_string(finalGen(gsoapProxy2_3->uuid + "_VerticalEpsgCrs")), title + " VerticalCrs", @@ -122,33 +122,33 @@ void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository * repo, c repo->addDataObject(unique_ptr{this}); } -void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, - uint64_t projectedEpsgCode, std::string unknownProjectedReason, +void LocalEngineeringCompoundCrs::init(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, + uint64_t projectedEpsgCode, std::string projectedDefinition, double originOrdinal1, double originOrdinal2, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, double azimuth, gsoap_eml2_3::eml23__PlaneAngleUom azimuthUom, gsoap_eml2_3::eml23__NorthReferenceKind azimuthReference, gsoap_eml2_3::eml23__AxisOrder2d axisOrder, - uint64_t verticalEpsgCode, std::string unknwownVerticalReason, + uint64_t verticalEpsgCode, std::string verticalDefinition, double originOrdinal3, gsoap_resqml2_0_1::eml20__LengthUom verticalUom, gsoap_resqml2_0_1::eml20__TimeUom timeUom, bool isUpOriented) { init(repo, guid, title, - projectedEpsgCode, unknownProjectedReason, + projectedEpsgCode, projectedDefinition, originOrdinal1, originOrdinal2, projectedUom, azimuth, azimuthUom, azimuthReference, axisOrder, - verticalEpsgCode, unknwownVerticalReason, + verticalEpsgCode, verticalDefinition, originOrdinal3, verticalUom, isUpOriented); static_cast(gsoapProxy2_3)->VerticalAxis->IsTime = true; static_cast(gsoapProxy2_3)->VerticalAxis->Uom = gsoap_resqml2_0_1::soap_eml20__TimeUom2s(gsoapProxy2_3->soap, timeUom); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { init(repo, guid, title, projectedEpsgCode, "", @@ -160,46 +160,46 @@ LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRe isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, - 0, projectedUnknownReason, + 0, projectedDefinition, originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, - 0, verticalUnknownReason, + 0, verticalDefinition, originOrdinal3, verticalUom, isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, projectedEpsgCode, "", originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, - 0, verticalUnknownReason, + 0, verticalDefinition, originOrdinal3, verticalUom, isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { init(repo, guid, title, - 0, projectedUnknownReason, + 0, projectedDefinition, originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, @@ -208,12 +208,12 @@ LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRe isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { init(repo, guid, title, projectedEpsgCode, "", @@ -225,49 +225,49 @@ LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRe isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, - 0, projectedUnknownReason, + 0, projectedDefinition, originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, - 0, verticalUnknownReason, + 0, verticalDefinition, originOrdinal3, verticalUom, timeUom, isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, projectedEpsgCode, "", originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, - 0, verticalUnknownReason, + 0, verticalDefinition, originOrdinal3, verticalUom, timeUom, isUpOriented); } -LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, +LocalEngineeringCompoundCrs::LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { init(repo, guid, title, - 0, projectedUnknownReason, + 0, projectedDefinition, originOrdinal1, originOrdinal2, projectedUom, arealRotation, gsoap_eml2_3::eml23__PlaneAngleUom::rad, gsoap_eml2_3::eml23__NorthReferenceKind::grid_x0020north, gsoap_eml2_3::eml23__AxisOrder2d::easting_x0020northing, diff --git a/src/eml2_3/LocalEngineeringCompoundCrs.h b/src/eml2_3/LocalEngineeringCompoundCrs.h index 29a4272e..0f65860d 100644 --- a/src/eml2_3/LocalEngineeringCompoundCrs.h +++ b/src/eml2_3/LocalEngineeringCompoundCrs.h @@ -65,10 +65,10 @@ namespace EML2_3_NS double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * Creates a local depth 3d CRS which is fully unknown. + * Creates a local depth 3d CRS which is fully defined by a string representation. * * @param [in,out] repo The repo where the underlying gsoap proxy is going to * be created. @@ -82,25 +82,25 @@ namespace EML2_3_NS * crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided - * using EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this local depth CRS is actually a * local elevation CRS and that the associated vertical CRS is * an elevation one as well. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unkown for its vertical part. + * part and which is defined by a string representation for its vertical part. * * @exception std::invalid_argument If projectedEpsgCode == 0. * @@ -119,20 +119,20 @@ namespace EML2_3_NS * @param projectedEpsgCode The epsg code of the associated projected CRS. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this local depth CRS is actually a * local elevation CRS and that the associated vertical CRS is * an elevation one as well. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which unkown for its projected part and which is + * @brief Creates a local depth 3d CRS which is defined by a string representation for its projected part and which is * identified by an EPSG code for its vertical part. * * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -148,19 +148,19 @@ namespace EML2_3_NS * @param arealRotation The areal rotation in radians regarding the projected crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using - * EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The epsg code of the associated vertical CRS. * @param isUpOriented If true, indicates that this local depth CRS is actually a * local elevation CRS and that the associated vertical CRS is * an elevation one as well. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * @brief Creates a local time 3d CRS which is fully identified by means of EPSG code. @@ -186,15 +186,15 @@ namespace EML2_3_NS * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * Creates a local time 3d CRS which is fully unknown. + * Creates a local time 3d CRS which is fully defined by a string representation. * * @param [in,out] repo The repo where the underlying gsoap proxy is going to * be created. @@ -209,26 +209,26 @@ namespace EML2_3_NS * crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided - * using EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unkown for its vertial part. + * part and which is defined by a string representation for its vertical part. * * @exception std::invalid_argument If projectedEpsgCode == 0. * @@ -247,20 +247,20 @@ namespace EML2_3_NS * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using - * EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local time 3d CRS which unkown for its projected part and which is + * @brief Creates a local time 3d CRS which is defined by a string representation for its projected part and which is * identified by an EPSG code for its vertical part. * * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -277,20 +277,20 @@ namespace EML2_3_NS * @param arealRotation The areal rotation in radians regarding the projected crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using - * EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ - LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository * repo, const std::string & guid, const std::string & title, + LocalEngineeringCompoundCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * Creates an instance of this class by wrapping a gsoap instance. diff --git a/src/eml2_3/VerticalCrs.cpp b/src/eml2_3/VerticalCrs.cpp index 7cec57dd..e9435150 100644 --- a/src/eml2_3/VerticalCrs.cpp +++ b/src/eml2_3/VerticalCrs.cpp @@ -59,7 +59,7 @@ VerticalCrs::VerticalCrs(COMMON_NS::DataObjectRepository* repo, const std::strin } VerticalCrs::VerticalCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, - std::string unknownReason, + std::string verticalDefinition, gsoap_eml2_3::eml23__LengthUom verticalUom, bool isUpOriented) { @@ -71,9 +71,16 @@ VerticalCrs::VerticalCrs(COMMON_NS::DataObjectRepository* repo, const std::strin eml23__VerticalCrs* verticalCrs = static_cast(gsoapProxy2_3); init(verticalCrs, guid, title, verticalUom, isUpOriented); - auto* unknownCrs = soap_new_eml23__VerticalUnknownCrs(gsoapProxy2_3->soap); - unknownCrs->Unknown = unknownReason; - verticalCrs->AbstractVerticalCrs = unknownCrs; + if (verticalDefinition.size() < 4 || verticalDefinition.substr(0, 4) != "VERT") { // Either VERTCRS or VERTICALCRS or VERT_CS + auto* unknownCrs = soap_new_eml23__VerticalUnknownCrs(gsoapProxy2_3->soap); + unknownCrs->Unknown = verticalDefinition; + verticalCrs->AbstractVerticalCrs = unknownCrs; + } + else { + auto* wktCrs = soap_new_eml23__VerticalWktCrs(gsoapProxy2_3->soap); + wktCrs->WellKnownText = verticalDefinition; + verticalCrs->AbstractVerticalCrs = wktCrs; + } repo->addDataObject(unique_ptr{this}); } @@ -83,6 +90,11 @@ bool VerticalCrs::isVerticalCrsDefinedWithEpsg() const return static_cast(gsoapProxy2_3)->AbstractVerticalCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__VerticalEpsgCrs; } +bool VerticalCrs::isVerticalCrsDefinedWithWkt() const +{ + return static_cast(gsoapProxy2_3)->AbstractVerticalCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__VerticalWktCrs; +} + bool VerticalCrs::isVerticalCrsUnknown() const { return static_cast(gsoapProxy2_3)->AbstractVerticalCrs->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__VerticalUnknownCrs; @@ -93,6 +105,11 @@ std::string VerticalCrs::getVerticalCrsUnknownReason() const return static_cast(static_cast(gsoapProxy2_3)->AbstractVerticalCrs)->Unknown; } +std::string VerticalCrs::getVerticalCrsWkt() const +{ + return static_cast(static_cast(gsoapProxy2_3)->AbstractVerticalCrs)->WellKnownText; +} + int64_t VerticalCrs::getVerticalCrsEpsgCode() const { return static_cast(static_cast(gsoapProxy2_3)->AbstractVerticalCrs)->EpsgCode; diff --git a/src/eml2_3/VerticalCrs.h b/src/eml2_3/VerticalCrs.h index c229476c..66dbf40e 100644 --- a/src/eml2_3/VerticalCrs.h +++ b/src/eml2_3/VerticalCrs.h @@ -55,12 +55,13 @@ namespace EML2_3_NS * @param [in,out] repo If non-null, the repo. * @param guid Unique identifier. * @param title The title. - * @param unknownReason The reason why this CRS is unknown. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param verticalUom The projected uom. * @param isUpOriented Defines if the vertical CRS axis is up oreinted or not. */ VerticalCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, - std::string unknownReason, + std::string verticalDefinition, gsoap_eml2_3::eml23__LengthUom verticalUom, bool isUpOriented); @@ -81,6 +82,13 @@ namespace EML2_3_NS */ DLL_IMPORT_OR_EXPORT bool isVerticalCrsDefinedWithEpsg() const; + /** + * Indicates either the associated vertical CRS is given in a WKT format or not. + * + * @returns True if the vertical CRS is given in a WKT format, false if not. + */ + DLL_IMPORT_OR_EXPORT bool isVerticalCrsDefinedWithWkt() const; + /** * Indicates either the associated vertical CRS is unknown or not. * @@ -97,6 +105,15 @@ namespace EML2_3_NS */ DLL_IMPORT_OR_EXPORT std::string getVerticalCrsUnknownReason() const; + /** + * Gets the WKT of the vertical CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The vertical CRS WKT. + */ + DLL_IMPORT_OR_EXPORT std::string getVerticalCrsWkt() const; + /** * Gets the EPSG code of the vertical CRS * diff --git a/src/resqml2/AbstractGridRepresentation.cpp b/src/resqml2/AbstractGridRepresentation.cpp index 4be0c8a9..4437e440 100644 --- a/src/resqml2/AbstractGridRepresentation.cpp +++ b/src/resqml2/AbstractGridRepresentation.cpp @@ -43,8 +43,7 @@ uint64_t AbstractGridRepresentation::getGridConnectionSetRepresentationCount() c RESQML2_NS::GridConnectionSetRepresentation * AbstractGridRepresentation::getGridConnectionSetRepresentation(uint64_t index) const { - const std::vector& gridConnectionSetRepresentationSet = getGridConnectionSetRepresentationSet(); - return gridConnectionSetRepresentationSet.at(index); + return getGridConnectionSetRepresentationSet().at(index); } gsoap_resqml2_0_1::resqml20__AbstractParentWindow* AbstractGridRepresentation::getParentWindow2_0_1() const @@ -80,7 +79,7 @@ COMMON_NS::DataObjectReference AbstractGridRepresentation::getParentGridDor() co } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { switch (parentWindow->soap_type()) { @@ -100,13 +99,7 @@ COMMON_NS::DataObjectReference AbstractGridRepresentation::getParentGridDor() co AbstractGridRepresentation* AbstractGridRepresentation::getParentGrid() const { - const string parentGridUuid = getParentGridDor().getUuid(); - - if (!parentGridUuid.empty()) { - return static_cast(getRepository()->getDataObjectByUuid(parentGridUuid)); - } - - return nullptr; + return static_cast(getRepository()->getDataObjectByUuid(getParentGridDor().getUuid())); } std::vector AbstractGridRepresentation::getChildGridSet() const @@ -120,12 +113,11 @@ uint64_t AbstractGridRepresentation::getChildGridCount() const { AbstractGridRepresentation * AbstractGridRepresentation::getChildGrid(uint64_t index) const { - const std::vector& childGridSet = getChildGridSet(); - return childGridSet.at(index); + return getChildGridSet().at(index); } -gsoap_resqml2_0_1::resqml20__Regrid* AbstractGridRepresentation::createRegrid2_0_1(unsigned int indexRegridStart, unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, double * childCellWeights, - const std::string & dimension, EML2_NS::AbstractHdfProxy * proxy, bool forceConstantCellCountPerInterval) +gsoap_resqml2_0_1::resqml20__Regrid* AbstractGridRepresentation::createRegrid2_0_1(uint32_t indexRegridStart, uint32_t* childCellCountPerInterval, uint32_t* parentCellCountPerInterval, uint64_t intervalCount, double* childCellWeights, + const std::string& dimension, EML2_NS::AbstractHdfProxy* proxy, bool forceConstantCellCountPerInterval) { gsoap_resqml2_0_1::resqml20__Regrid* regrid = gsoap_resqml2_0_1::soap_new_resqml20__Regrid(gsoapProxy2_0_1->soap); regrid->InitialIndexOnParentGrid = indexRegridStart; @@ -135,7 +127,7 @@ gsoap_resqml2_0_1::resqml20__Regrid* AbstractGridRepresentation::createRegrid2_0 if (intervalCount == 0) { throw invalid_argument("Cannot regrid an empty list of intervals."); } - else if (intervalCount == 1 || forceConstantCellCountPerInterval) { + else if (forceConstantCellCountPerInterval) { gsoap_resqml2_0_1::resqml20__IntegerConstantArray* xmlChildCountPerInterval = gsoap_resqml2_0_1::soap_new_resqml20__IntegerConstantArray(gsoapProxy2_0_1->soap); xmlChildCountPerInterval->Value = *childCellCountPerInterval; xmlChildCountPerInterval->Count = intervalCount; @@ -191,11 +183,11 @@ gsoap_resqml2_0_1::resqml20__Regrid* AbstractGridRepresentation::createRegrid2_0 // HDF uint64_t numValues = *childCellCountPerInterval; - if (forceConstantCellCountPerInterval) { + if (intervalCount > 1 && forceConstantCellCountPerInterval) { numValues *= intervalCount - 1; } else { - for (unsigned int i = 1; i < intervalCount; ++i) { + for (uint64_t i = 1; i < intervalCount; ++i) { numValues += childCellCountPerInterval[i]; } } @@ -205,8 +197,8 @@ gsoap_resqml2_0_1::resqml20__Regrid* AbstractGridRepresentation::createRegrid2_0 return regrid; } -gsoap_eml2_3::resqml22__Regrid* AbstractGridRepresentation::createRegrid2_2(unsigned int indexRegridStart, unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, double * childCellWeights, - const std::string & dimension, EML2_NS::AbstractHdfProxy * proxy, bool forceConstantCellCountPerInterval) +gsoap_eml2_3::resqml22__Regrid* AbstractGridRepresentation::createRegrid2_2(uint32_t indexRegridStart, uint32_t* childCellCountPerInterval, uint32_t* parentCellCountPerInterval, uint64_t intervalCount, double* childCellWeights, + const std::string& dimension, EML2_NS::AbstractHdfProxy* proxy, bool forceConstantCellCountPerInterval) { gsoap_eml2_3::resqml22__Regrid* regrid = gsoap_eml2_3::soap_new_resqml22__Regrid(gsoapProxy2_3->soap); regrid->InitialIndexOnParentGrid = indexRegridStart; @@ -216,7 +208,7 @@ gsoap_eml2_3::resqml22__Regrid* AbstractGridRepresentation::createRegrid2_2(unsi if (intervalCount == 0) { throw invalid_argument("Cannot regrid an empty list of intervals."); } - else if (intervalCount == 1 || forceConstantCellCountPerInterval) { + else if (forceConstantCellCountPerInterval) { gsoap_eml2_3::eml23__IntegerConstantArray* xmlChildCountPerInterval = gsoap_eml2_3::soap_new_eml23__IntegerConstantArray(gsoapProxy2_3->soap); xmlChildCountPerInterval->Value = *childCellCountPerInterval; xmlChildCountPerInterval->Count = intervalCount; @@ -265,9 +257,14 @@ gsoap_eml2_3::resqml22__Regrid* AbstractGridRepresentation::createRegrid2_2(unsi gsoap_eml2_3::eml23__FloatingPointExternalArray* hdf5ChildCellWeights = gsoap_eml2_3::soap_new_eml23__FloatingPointExternalArray(gsoapProxy2_3->soap); regrid->Intervals->ChildCellWeights = hdf5ChildCellWeights; hdf5ChildCellWeights->Values = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(gsoapProxy2_3->soap); - uint64_t numValues = 0; - for (uint64_t i = 0; i < intervalCount; ++i) { - numValues += childCellCountPerInterval[i]; + uint64_t numValues = *childCellCountPerInterval; + if (intervalCount > 1 && forceConstantCellCountPerInterval) { + numValues *= intervalCount - 1; + } + else { + for (uint64_t i = 1; i < intervalCount; ++i) { + numValues += childCellCountPerInterval[i]; + } } hdf5ChildCellWeights->Values->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/ParentWindow_" + dimension + "Regrid_ChildCellWeights", numValues, proxy)); @@ -291,65 +288,49 @@ void AbstractGridRepresentation::setParentWindow(uint64_t * cellIndices, uint64_ rep->ParentWindow = cpw; cpw->ParentGrid = parentGrid->newResqmlReference(); - if (cellIndexCount > 1) { + if (proxy == nullptr) { + proxy = getRepository()->getDefaultHdfProxy(); if (proxy == nullptr) { - proxy = getRepository()->getDefaultHdfProxy(); - if (proxy == nullptr) { - throw std::invalid_argument("A (default) HDF Proxy must be provided."); - } + throw std::invalid_argument("A (default) HDF Proxy must be provided."); } - getRepository()->addRelationship(this, proxy); + } + getRepository()->addRelationship(this, proxy); - gsoap_resqml2_0_1::resqml20__IntegerHdf5Array* hdf5CellIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerHdf5Array(rep->soap); - cpw->CellIndices = hdf5CellIndices; + gsoap_resqml2_0_1::resqml20__IntegerHdf5Array* hdf5CellIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerHdf5Array(rep->soap); + cpw->CellIndices = hdf5CellIndices; - hdf5CellIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write cell index null value in this method - hdf5CellIndices->Values = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(rep->soap); - hdf5CellIndices->Values->HdfProxy = proxy->newResqmlReference(); - hdf5CellIndices->Values->PathInHdfFile = getHdfGroup() + "/ParentWindow_CellIndices"; + hdf5CellIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write cell index null value in this method + hdf5CellIndices->Values = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(rep->soap); + hdf5CellIndices->Values->HdfProxy = proxy->newResqmlReference(); + hdf5CellIndices->Values->PathInHdfFile = getHdfGroup() + "/ParentWindow_CellIndices"; - // HDF - proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); - } - else { // cellIndexCount == 1 - gsoap_resqml2_0_1::resqml20__IntegerConstantArray* xmlCellIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerConstantArray(rep->soap); - xmlCellIndices->Value = *cellIndices; - xmlCellIndices->Count = 1; - cpw->CellIndices = xmlCellIndices; - } + // HDF + proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); } else if (gsoapProxy2_3 != nullptr) { - auto rep = static_cast(gsoapProxy2_3); + auto* rep = static_cast(gsoapProxy2_3); gsoap_eml2_3::resqml22__CellParentWindow* cpw = gsoap_eml2_3::soap_new_resqml22__CellParentWindow(rep->soap); rep->ParentWindow = cpw; cpw->ParentGridRepresentation = parentGrid->newEml23Reference(); - if (cellIndexCount > 1) { + if (proxy == nullptr) { + proxy = getRepository()->getDefaultHdfProxy(); if (proxy == nullptr) { - proxy = getRepository()->getDefaultHdfProxy(); - if (proxy == nullptr) { - throw std::invalid_argument("A (default) HDF Proxy must be provided."); - } + throw std::invalid_argument("A (default) HDF Proxy must be provided."); } - getRepository()->addRelationship(this, proxy); + } + getRepository()->addRelationship(this, proxy); - auto hdf5CellIndices = gsoap_eml2_3::soap_new_eml23__IntegerExternalArray(rep->soap); - cpw->CellIndices = hdf5CellIndices; + auto* hdf5CellIndices = gsoap_eml2_3::soap_new_eml23__IntegerExternalArray(rep->soap); + cpw->CellIndices = hdf5CellIndices; - hdf5CellIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write cell index null value in this method - hdf5CellIndices->Values = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(rep->soap); - hdf5CellIndices->Values->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/ParentWindow_CellIndices", cellIndexCount, proxy)); + hdf5CellIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write cell index null value in this method + hdf5CellIndices->Values = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(rep->soap); + hdf5CellIndices->Values->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/ParentWindow_CellIndices", cellIndexCount, proxy)); - // HDF - proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); - } - else { // cellIndexCount == 1 - auto xmlCellIndices = gsoap_eml2_3::soap_new_eml23__IntegerConstantArray(rep->soap); - xmlCellIndices->Value = *cellIndices; - xmlCellIndices->Count = 1; - cpw->CellIndices = xmlCellIndices; - } + // HDF + proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); } else { throw logic_error("Not implemented yet"); @@ -360,7 +341,7 @@ void AbstractGridRepresentation::setParentWindow(uint64_t * cellIndices, uint64_ void AbstractGridRepresentation::setParentWindow(unsigned int * columnIndices, uint64_t columnIndexCount, unsigned int kLayerIndexRegridStart, - unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, unsigned int intervalCount, + unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, AbstractColumnLayerGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy, double * childCellWeights) { @@ -378,40 +359,30 @@ void AbstractGridRepresentation::setParentWindow(unsigned int * columnIndices, u clpw->ParentGrid = parentGrid->newResqmlReference(); // COLUMN INDICES - if (columnIndexCount > 1) - { + if (proxy == nullptr) { + proxy = getRepository()->getDefaultHdfProxy(); if (proxy == nullptr) { - proxy = getRepository()->getDefaultHdfProxy(); - if (proxy == nullptr) { - throw std::invalid_argument("A (default) HDF Proxy must be provided."); - } + throw std::invalid_argument("A (default) HDF Proxy must be provided."); } - getRepository()->addRelationship(this, proxy); + } + getRepository()->addRelationship(this, proxy); - gsoap_resqml2_0_1::resqml20__IntegerHdf5Array* hdf5ColumnIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerHdf5Array(rep->soap); - clpw->ColumnIndices = hdf5ColumnIndices; + gsoap_resqml2_0_1::resqml20__IntegerHdf5Array* hdf5ColumnIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerHdf5Array(rep->soap); + clpw->ColumnIndices = hdf5ColumnIndices; - hdf5ColumnIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write column index null value in this method - hdf5ColumnIndices->Values = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(rep->soap); - hdf5ColumnIndices->Values->HdfProxy = proxy->newResqmlReference(); - hdf5ColumnIndices->Values->PathInHdfFile = getHdfGroup() + "/ParentWindow_ColumnIndices"; + hdf5ColumnIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write column index null value in this method + hdf5ColumnIndices->Values = gsoap_resqml2_0_1::soap_new_eml20__Hdf5Dataset(rep->soap); + hdf5ColumnIndices->Values->HdfProxy = proxy->newResqmlReference(); + hdf5ColumnIndices->Values->PathInHdfFile = getHdfGroup() + "/ParentWindow_ColumnIndices"; - // HDF - proxy->writeArrayNd(getHdfGroup(), "ParentWindow_ColumnIndices", COMMON_NS::AbstractObject::numericalDatatypeEnum::UINT32, columnIndices, &columnIndexCount, 1); - } - else if (columnIndexCount == 1) - { - gsoap_resqml2_0_1::resqml20__IntegerConstantArray* xmlColumnIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerConstantArray(rep->soap); - xmlColumnIndices->Value = *columnIndices; - xmlColumnIndices->Count = 1; - clpw->ColumnIndices = xmlColumnIndices; - } + // HDF + proxy->writeArrayNd(getHdfGroup(), "ParentWindow_ColumnIndices", COMMON_NS::AbstractObject::numericalDatatypeEnum::UINT32, columnIndices, &columnIndexCount, 1); // K Regrid clpw->KRegrid = createRegrid2_0_1(kLayerIndexRegridStart, childCellCountPerInterval, parentCellCountPerInterval, intervalCount, childCellWeights, "K", proxy); } else if (gsoapProxy2_3 != nullptr) { - auto rep = static_cast(gsoapProxy2_3); + auto* rep = static_cast(gsoapProxy2_3); gsoap_eml2_3::resqml22__ColumnLayerParentWindow* clpw = gsoap_eml2_3::soap_new_resqml22__ColumnLayerParentWindow(rep->soap); rep->ParentWindow = clpw; @@ -419,33 +390,23 @@ void AbstractGridRepresentation::setParentWindow(unsigned int * columnIndices, u clpw->ParentColumnLayerGridRepresentation = parentGrid->newEml23Reference(); // COLUMN INDICES - if (columnIndexCount > 1) - { + if (proxy == nullptr) { + proxy = getRepository()->getDefaultHdfProxy(); if (proxy == nullptr) { - proxy = getRepository()->getDefaultHdfProxy(); - if (proxy == nullptr) { - throw std::invalid_argument("A (default) HDF Proxy must be provided."); - } + throw std::invalid_argument("A (default) HDF Proxy must be provided."); } - getRepository()->addRelationship(this, proxy); + } + getRepository()->addRelationship(this, proxy); - gsoap_eml2_3::eml23__IntegerExternalArray* hdf5ColumnIndices = gsoap_eml2_3::soap_new_eml23__IntegerExternalArray(rep->soap); - clpw->ColumnIndices = hdf5ColumnIndices; + gsoap_eml2_3::eml23__IntegerExternalArray* hdf5ColumnIndices = gsoap_eml2_3::soap_new_eml23__IntegerExternalArray(rep->soap); + clpw->ColumnIndices = hdf5ColumnIndices; - hdf5ColumnIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write column index null value in this method - hdf5ColumnIndices->Values = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(rep->soap); - hdf5ColumnIndices->Values->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/ParentWindow_ColumnIndices", columnIndexCount, proxy)); + hdf5ColumnIndices->NullValue = -1; // Arbitrarily decided to something almost impossible since it has no interest to write column index null value in this method + hdf5ColumnIndices->Values = gsoap_eml2_3::soap_new_eml23__ExternalDataArray(rep->soap); + hdf5ColumnIndices->Values->ExternalDataArrayPart.push_back(createExternalDataArrayPart(getHdfGroup() + "/ParentWindow_ColumnIndices", columnIndexCount, proxy)); - // HDF - proxy->writeArrayNd(getHdfGroup(), "ParentWindow_ColumnIndices", COMMON_NS::AbstractObject::numericalDatatypeEnum::UINT32, columnIndices, &columnIndexCount, 1); - } - else if (columnIndexCount == 1) - { - gsoap_eml2_3::eml23__IntegerConstantArray* xmlColumnIndices = gsoap_eml2_3::soap_new_eml23__IntegerConstantArray(rep->soap); - xmlColumnIndices->Value = *columnIndices; - xmlColumnIndices->Count = 1; - clpw->ColumnIndices = xmlColumnIndices; - } + // HDF + proxy->writeArrayNd(getHdfGroup(), "ParentWindow_ColumnIndices", COMMON_NS::AbstractObject::numericalDatatypeEnum::UINT32, columnIndices, &columnIndexCount, 1); // K Regrid clpw->KRegrid = createRegrid2_2(kLayerIndexRegridStart, childCellCountPerInterval, parentCellCountPerInterval, intervalCount, childCellWeights, "K", proxy); @@ -458,9 +419,9 @@ void AbstractGridRepresentation::setParentWindow(unsigned int * columnIndices, u } void AbstractGridRepresentation::setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, uint64_t kIntervalCount, AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy, double * iChildCellWeights, double * jChildCellWeights, double * kChildCellWeights) { if (childCellCountPerIInterval == nullptr || parentCellCountPerIInterval == nullptr || iIntervalCount == 0 || @@ -482,7 +443,7 @@ void AbstractGridRepresentation::setParentWindow( ijkpw->KRegrid = createRegrid2_0_1(kCellIndexRegridStart, childCellCountPerKInterval, parentCellCountPerKInterval, kIntervalCount, kChildCellWeights, "K", proxy); } else if (gsoapProxy2_3 != nullptr) { - auto ijkpw = gsoap_eml2_3::soap_new_resqml22__IjkParentWindow(gsoapProxy2_3->soap); + auto* ijkpw = gsoap_eml2_3::soap_new_resqml22__IjkParentWindow(gsoapProxy2_3->soap); static_cast(gsoapProxy2_3)->ParentWindow = ijkpw; ijkpw->ParentIjkGridRepresentation = parentGrid->newEml23Reference(); @@ -500,9 +461,9 @@ void AbstractGridRepresentation::setParentWindow( } void AbstractGridRepresentation::setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, uint64_t kIntervalCount, AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy, double * iChildCellWeights, double * jChildCellWeights, double * kChildCellWeights) { if (constantChildCellCountPerIInterval == 0 || constantParentCellCountPerIInterval == 0 || iIntervalCount == 0 || @@ -524,7 +485,7 @@ void AbstractGridRepresentation::setParentWindow( ijkpw->KRegrid = createRegrid2_0_1(kCellIndexRegridStart, &constantChildCellCountPerKInterval, &constantParentCellCountPerKInterval, kIntervalCount, kChildCellWeights, "K", proxy, true); } else if (gsoapProxy2_3 != nullptr) { - auto ijkpw = gsoap_eml2_3::soap_new_resqml22__IjkParentWindow(gsoapProxy2_3->soap); + auto* ijkpw = gsoap_eml2_3::soap_new_resqml22__IjkParentWindow(gsoapProxy2_3->soap); static_cast(gsoapProxy2_3)->ParentWindow = ijkpw; ijkpw->ParentIjkGridRepresentation = parentGrid->newEml23Reference(); @@ -548,9 +509,9 @@ void AbstractGridRepresentation::setParentWindow( AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy, double * iChildCellWeights, double * jChildCellWeights, double * kChildCellWeights) { setParentWindow( - iCellIndexRegridStart, &iChildCellCount, &iParentCellCount, 1, - jCellIndexRegridStart, &jChildCellCount, &jParentCellCount, 1, - kCellIndexRegridStart, &kChildCellCount, &kParentCellCount, 1, + iCellIndexRegridStart, iChildCellCount, iParentCellCount, 1, + jCellIndexRegridStart, jChildCellCount, jParentCellCount, 1, + kCellIndexRegridStart, kChildCellCount, kParentCellCount, 1, parentGrid, proxy, iChildCellWeights, jChildCellWeights, kChildCellWeights); } @@ -568,7 +529,7 @@ void AbstractGridRepresentation::setForcedNonRegridedParentCell(uint64_t * cellI gsoap_resqml2_0_1::resqml20__AbstractIntegerArray* xmlCellIndices = nullptr; EML2_NS::AbstractHdfProxy * proxy = getRepository()->getDefaultHdfProxy(); - if (cellIndexCount > 1 && proxy != nullptr) + if (cellIndexCount > 0 && proxy != nullptr) { getRepository()->addRelationship(this, proxy); xmlCellIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerHdf5Array(parentWindow->soap); @@ -580,12 +541,6 @@ void AbstractGridRepresentation::setForcedNonRegridedParentCell(uint64_t * cellI // HDF proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); } - else if (cellIndexCount == 1) - { - xmlCellIndices = gsoap_resqml2_0_1::soap_new_resqml20__IntegerConstantArray(parentWindow->soap); - static_cast(xmlCellIndices)->Value = *cellIndices; - static_cast(xmlCellIndices)->Count = 1; - } else if (cellIndexCount == 0) throw invalid_argument("Cannot force an empty list of cells."); else @@ -602,14 +557,14 @@ void AbstractGridRepresentation::setForcedNonRegridedParentCell(uint64_t * cellI } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { gsoap_eml2_3::eml23__AbstractIntegerArray* xmlCellIndices = nullptr; EML2_NS::AbstractHdfProxy * proxy = getRepository()->getDefaultHdfProxy(); - if (cellIndexCount > 1 && proxy != nullptr) + if (cellIndexCount > 0 && proxy != nullptr) { getRepository()->addRelationship(this, proxy); xmlCellIndices = gsoap_eml2_3::soap_new_eml23__IntegerExternalArray(parentWindow->soap); @@ -621,12 +576,6 @@ void AbstractGridRepresentation::setForcedNonRegridedParentCell(uint64_t * cellI // HDF proxy->writeArrayNdOfUInt64Values(getHdfGroup(), "ParentWindow_CellIndices", cellIndices, &cellIndexCount, 1); } - else if (cellIndexCount == 1) - { - xmlCellIndices = gsoap_eml2_3::soap_new_eml23__IntegerConstantArray(parentWindow->soap); - static_cast(xmlCellIndices)->Value = *cellIndices; - static_cast(xmlCellIndices)->Count = 1; - } else if (cellIndexCount == 0) throw invalid_argument("Cannot force an empty list of cells."); else @@ -664,7 +613,7 @@ bool AbstractGridRepresentation::hasForcedNonRegridedParentCell() const } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { switch (parentWindow->soap_type()) { @@ -741,7 +690,7 @@ void AbstractGridRepresentation::setCellOverlap(uint64_t parentChildCellPairCoun } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { @@ -794,7 +743,7 @@ void AbstractGridRepresentation::setCellOverlap(uint64_t parentChildCellPairCoun } } -int64_t AbstractGridRepresentation::getParentCellIndexCount() const +uint64_t AbstractGridRepresentation::getParentCellIndexCount() const { if (gsoapProxy2_0_1 != nullptr) { gsoap_resqml2_0_1::resqml20__AbstractParentWindow* parentWindow = getParentWindow2_0_1(); @@ -803,42 +752,26 @@ int64_t AbstractGridRepresentation::getParentCellIndexCount() const { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__CellParentWindow) { - gsoap_resqml2_0_1::resqml20__CellParentWindow* cpw = static_cast(parentWindow); - if (cpw->CellIndices->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) - { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(cpw->CellIndices)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - return hdfProxy->getElementCount(dataset->PathInHdfFile); - } - else - throw invalid_argument("This list of cells can only be stored in HDF5 file."); + return getCountOfArray(static_cast(parentWindow)->CellIndices); } else - throw invalid_argument("This information is only avaialble for cell parent window."); + throw invalid_argument("This information is only available for cell parent window."); } else { throw invalid_argument("There is no parent window on this grid."); } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__CellParentWindow) { - auto cpw = static_cast(parentWindow); - if (cpw->CellIndices->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) - { - gsoap_eml2_3::eml23__ExternalDataArray const * dataset = static_cast(cpw->CellIndices)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getOrCreateHdfProxyFromDataArrayPart(dataset->ExternalDataArrayPart[0]); - return hdfProxy->getElementCount(dataset->ExternalDataArrayPart[0]->PathInExternalFile); - } - else - throw invalid_argument("This list of cells can only be stored in HDF5 file."); + return getCountOfArray(static_cast(parentWindow)->CellIndices); } else - throw invalid_argument("This information is only avaialble for cell parent window."); + throw invalid_argument("This information is only available for cell parent window."); } else { throw invalid_argument("There is no parent window on this grid."); @@ -869,7 +802,7 @@ void AbstractGridRepresentation::getParentCellIndices(uint64_t * parentCellIndic } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { @@ -890,7 +823,7 @@ void AbstractGridRepresentation::getParentCellIndices(uint64_t * parentCellIndic } } -int64_t AbstractGridRepresentation::getParentColumnIndexCount() const +uint64_t AbstractGridRepresentation::getParentColumnIndexCount() const { if (gsoapProxy2_0_1 != nullptr) { gsoap_resqml2_0_1::resqml20__AbstractParentWindow* parentWindow = getParentWindow2_0_1(); @@ -899,18 +832,10 @@ int64_t AbstractGridRepresentation::getParentColumnIndexCount() const { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__ColumnLayerParentWindow) { - gsoap_resqml2_0_1::resqml20__ColumnLayerParentWindow* clpw = static_cast(parentWindow); - if (clpw->ColumnIndices->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(clpw->ColumnIndices)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - return hdfProxy->getElementCount(dataset->PathInHdfFile); - } - else { - throw invalid_argument("This list of columns can only be stored in HDF5 file."); - } + return getCountOfArray(static_cast(parentWindow)->ColumnIndices); } else { - throw invalid_argument("This information is only avaialble for column layer parent window."); + throw invalid_argument("This information is only available for column layer parent window."); } } else { @@ -918,23 +843,16 @@ int64_t AbstractGridRepresentation::getParentColumnIndexCount() const } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__ColumnLayerParentWindow) { - auto cpw = static_cast(parentWindow); - if (cpw->ColumnIndices->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - gsoap_eml2_3::eml23__ExternalDataArray const * dataset = static_cast(cpw->ColumnIndices)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getOrCreateHdfProxyFromDataArrayPart(dataset->ExternalDataArrayPart[0]); - return hdfProxy->getElementCount(dataset->ExternalDataArrayPart[0]->PathInExternalFile); - } - else - throw invalid_argument("This list of cells can only be stored in HDF5 file."); + return getCountOfArray(static_cast(parentWindow)->ColumnIndices); } else - throw invalid_argument("This information is only available for cell parent window."); + throw invalid_argument("This information is only available for column layer parent window."); } else { throw invalid_argument("There is no parent window on this grid."); @@ -958,7 +876,7 @@ void AbstractGridRepresentation::getParentColumnIndices(uint64_t * parentColumnI readArrayNdOfUInt64Values(clpw->ColumnIndices, parentColumnIndices); } else { - throw invalid_argument("This information is only avaialble for column layer parent window."); + throw invalid_argument("This information is only available for column layer parent window."); } } else { @@ -966,7 +884,7 @@ void AbstractGridRepresentation::getParentColumnIndices(uint64_t * parentColumnI } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { @@ -976,7 +894,7 @@ void AbstractGridRepresentation::getParentColumnIndices(uint64_t * parentColumnI readArrayNdOfUInt64Values(cpw->ColumnIndices, parentColumnIndices); } else { - throw invalid_argument("This information is only available for cell parent window."); + throw invalid_argument("This information is only available for column layer parent window."); } } else { @@ -1029,7 +947,7 @@ uint64_t AbstractGridRepresentation::getRegridStartIndexOnParentGrid(char dimens } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { @@ -1120,7 +1038,7 @@ uint64_t AbstractGridRepresentation::getRegridIntervalCount(char dimension) cons } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { @@ -1223,7 +1141,7 @@ gsoap_resqml2_0_1::resqml20__AbstractIntegerArray* AbstractGridRepresentation::g gsoap_eml2_3::eml23__AbstractIntegerArray* AbstractGridRepresentation::getCellCountPerInterval2_2(char dimension, bool childVsParentCellCount) const { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__IjkParentWindow) { @@ -1324,11 +1242,9 @@ uint64_t AbstractGridRepresentation::getRegridConstantCellCountPerInterval(char switch (cellCountPerInterval->soap_type()) { case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray: return static_cast(cellCountPerInterval)->Value; case SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array: { - const uint64_t intervalCount = getRegridIntervalCount(dimension); - std::unique_ptr values(new uint64_t[intervalCount]); + std::unique_ptr values(new uint64_t[getRegridIntervalCount(dimension)]); getRegridCellCountPerInterval(dimension, values.get(), childVsParentCellCount); - uint64_t result = values[0]; - return result; + return values[0]; } default: throw logic_error("Not implemented yet"); } @@ -1338,11 +1254,9 @@ uint64_t AbstractGridRepresentation::getRegridConstantCellCountPerInterval(char switch (cellCountPerInterval->soap_type()) { case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray: return static_cast(cellCountPerInterval)->Value; case SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray: { - const uint64_t intervalCount = getRegridIntervalCount(dimension); - std::unique_ptr values(new uint64_t[intervalCount]); + std::unique_ptr values(new uint64_t[getRegridIntervalCount(dimension)]); getRegridCellCountPerInterval(dimension, values.get(), childVsParentCellCount); - uint64_t result = values[0]; - return result; + return values[0]; } default: throw logic_error("Not implemented yet"); } @@ -1430,7 +1344,7 @@ bool AbstractGridRepresentation::hasRegridChildCellWeights(char dimension) const } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__IjkParentWindow) @@ -1517,7 +1431,7 @@ void AbstractGridRepresentation::getRegridChildCellWeights(char dimension, doubl } } else if (gsoapProxy2_3 != nullptr) { - auto parentWindow = getParentWindow2_2(); + auto* parentWindow = getParentWindow2_2(); if (parentWindow != nullptr) { if (parentWindow->soap_type() == SOAP_TYPE_gsoap_eml2_3_resqml22__IjkParentWindow) { @@ -1761,7 +1675,7 @@ int64_t AbstractGridRepresentation::getCellFluidPhaseUnitIndices(int64_t * rockF return static_cast(rep->CellFluidPhaseUnits->PhaseUnitIndices)->NullValue; } else if (gsoapProxy2_3 != nullptr) { - auto rep = static_cast(gsoapProxy2_3); + auto const* rep = static_cast(gsoapProxy2_3); if (rep->CellFluidPhaseUnits->PhaseUnitIndices->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray) { gsoap_eml2_3::eml23__IntegerLatticeArray* latticeArray = static_cast(rep->CellFluidPhaseUnits->PhaseUnitIndices->CumulativeLength); if (latticeArray->StartValue == 1 && latticeArray->Offset.size() == 1 && @@ -1784,13 +1698,7 @@ int64_t AbstractGridRepresentation::getCellFluidPhaseUnitIndices(int64_t * rockF RESQML2_NS::RockFluidOrganizationInterpretation* AbstractGridRepresentation::getRockFluidOrganizationInterpretation() const { - const string rockfluidOrganizationInterpretationUuid = getRockFluidOrganizationInterpretationDor().getUuid(); - if (rockfluidOrganizationInterpretationUuid.empty()) { - return nullptr; - } - - return static_cast(getRepository()->getDataObjectByUuid(rockfluidOrganizationInterpretationUuid)); - + return static_cast(getRepository()->getDataObjectByUuid(getRockFluidOrganizationInterpretationDor().getUuid())); } bool AbstractGridRepresentation::isTruncated() const @@ -1805,12 +1713,10 @@ uint64_t AbstractGridRepresentation::getTruncatedFaceCount() const } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - return rep->TruncationCells->TruncationFaceCount; + return static_cast(gsoapProxy2_0_1)->TruncationCells->TruncationFaceCount; } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - return rep->TruncationCellPatch->TruncationFaceCount; + return static_cast(gsoapProxy2_3)->TruncationCellPatch->TruncationFaceCount; } else { throw logic_error("Not implemented yet"); @@ -1824,28 +1730,10 @@ void AbstractGridRepresentation::getNodeIndicesOfTruncatedFaces(uint64_t * nodeI } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->NodesPerTruncationFace->Elements->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) - { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->NodesPerTruncationFace->Elements)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt64Values(dataset->PathInHdfFile, nodeIndices); - } - else - throw logic_error("Not yet implemented"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->NodesPerTruncationFace->Elements, nodeIndices); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->NodesPerTruncationFace->Elements->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) - { - auto const* daPart = static_cast(rep->TruncationCellPatch->NodesPerTruncationFace->Elements)->Values->ExternalDataArrayPart[0]; - EML2_NS::AbstractHdfProxy * hdfProxy = getOrCreateHdfProxyFromDataArrayPart(daPart); - hdfProxy->readArrayNdOfUInt64Values(daPart->PathInExternalFile, nodeIndices); - } - else - throw logic_error("Not yet implemented"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->NodesPerTruncationFace->Elements, nodeIndices); } else { throw logic_error("Not implemented yet"); @@ -1859,50 +1747,10 @@ void AbstractGridRepresentation::getCumulativeNodeCountPerTruncatedFace(uint64_t } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) - { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->NodesPerTruncationFace->CumulativeLength)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt64Values(dataset->PathInHdfFile, nodeCountPerFace); - } - else if (rep->TruncationCells->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerLatticeArray) - { - nodeCountPerFace[0] = static_cast(rep->TruncationCells->NodesPerTruncationFace->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCells->NodesPerTruncationFace->CumulativeLength)->Offset[0]->Value; - const uint64_t faceCount = getTruncatedFaceCount(); - for (uint64_t nodeCountPerFaceIndex = 1; nodeCountPerFaceIndex < faceCount; ++nodeCountPerFaceIndex) { - nodeCountPerFace[nodeCountPerFaceIndex] = nodeCountPerFace[nodeCountPerFaceIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCells->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray) - { - throw range_error("The *cumulative* length of nodes count per cells cannot be constant."); - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->NodesPerTruncationFace->CumulativeLength, nodeCountPerFace); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) - { - auto const* daPart = static_cast(rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength)->Values->ExternalDataArrayPart[0]; - EML2_NS::AbstractHdfProxy * hdfProxy = getOrCreateHdfProxyFromDataArrayPart(daPart); - hdfProxy->readArrayNdOfUInt64Values(daPart->PathInExternalFile, nodeCountPerFace); - } - else if (rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray) - { - nodeCountPerFace[0] = static_cast(rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength)->Offset[0]->Value; - const uint64_t faceCount = getTruncatedFaceCount(); - for (uint64_t nodeCountPerFaceIndex = 1; nodeCountPerFaceIndex < faceCount; ++nodeCountPerFaceIndex) { - nodeCountPerFace[nodeCountPerFaceIndex] = nodeCountPerFace[nodeCountPerFaceIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray) - { - throw range_error("The *cumulative* length of nodes count per cells cannot be constant."); - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->NodesPerTruncationFace->CumulativeLength, nodeCountPerFace); } else { throw logic_error("Not implemented yet"); @@ -1947,12 +1795,10 @@ void AbstractGridRepresentation::getTruncatedCellIndices(uint64_t* cellIndices) } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation const* rep = static_cast(gsoapProxy2_0_1); - readArrayNdOfUInt64Values(rep->TruncationCells->ParentCellIndices, cellIndices); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->ParentCellIndices, cellIndices); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation const* rep = static_cast(gsoapProxy2_3); - readArrayNdOfUInt64Values(rep->TruncationCellPatch->ParentCellIndices, cellIndices); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->ParentCellIndices, cellIndices); } else { throw logic_error("Not implemented yet"); @@ -1966,24 +1812,10 @@ void AbstractGridRepresentation::getTruncatedFaceIndicesOfTruncatedCells(uint64_ } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->TruncationFacesPerCell->Elements->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->TruncationFacesPerCell->Elements)->Values; - getHdfProxyFromDataset(dataset)->readArrayNdOfUInt64Values(dataset->PathInHdfFile, faceIndices); - } - else - throw logic_error("Not implemented yet"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->TruncationFacesPerCell->Elements, faceIndices); } else if (gsoapProxy2_3 != nullptr) { - auto rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->TruncationFacesPerCell->Elements->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - auto const* daPart = static_cast(rep->TruncationCellPatch->TruncationFacesPerCell->Elements)->Values->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfUInt64Values(daPart->PathInExternalFile, faceIndices); - } - else - throw logic_error("Not implemented yet"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->TruncationFacesPerCell->Elements, faceIndices); } else { throw logic_error("Not implemented yet"); @@ -1992,53 +1824,15 @@ void AbstractGridRepresentation::getTruncatedFaceIndicesOfTruncatedCells(uint64_ void AbstractGridRepresentation::getCumulativeTruncatedFaceCountPerTruncatedCell(uint64_t * cumulativeFaceCountPerCell) const { - if (!isTruncated()) { throw invalid_argument("The grid is not truncated"); } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->TruncationFacesPerCell->CumulativeLength)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt64Values(dataset->PathInHdfFile, cumulativeFaceCountPerCell); - } - else if (rep->TruncationCells->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerLatticeArray) { - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCells->TruncationFacesPerCell->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCells->TruncationFacesPerCell->CumulativeLength)->Offset[0]->Value; - const uint64_t cellCount = getTruncatedCellCount(); - for (uint64_t cumulativeFaceCountPerCellIndex = 1; cumulativeFaceCountPerCellIndex < cellCount; ++cumulativeFaceCountPerCellIndex) { - cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex] = cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCells->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray) { - if (getTruncatedCellCount() > 1) - throw range_error("The cumulative length of faces count per cells cannot be constant if there is more than one cell in the grid"); - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCells->TruncationFacesPerCell->CumulativeLength)->Value; - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->TruncationFacesPerCell->CumulativeLength, cumulativeFaceCountPerCell); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - auto const* daPart = static_cast(rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength)->Values->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfUInt64Values(daPart->PathInExternalFile, cumulativeFaceCountPerCell); - } - else if (rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray) { - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength)->Offset[0]->Value; - const uint64_t cellCount = getTruncatedCellCount(); - for (uint64_t cumulativeFaceCountPerCellIndex = 1; cumulativeFaceCountPerCellIndex < cellCount; ++cumulativeFaceCountPerCellIndex) { - cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex] = cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray) { - if (getTruncatedCellCount() > 1) - throw range_error("The cumulative length of faces count per cells cannot be constant if there is more than one cell in the grid"); - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength)->Value; - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->TruncationFacesPerCell->CumulativeLength, cumulativeFaceCountPerCell); } else { throw logic_error("Not implemented yet"); @@ -2066,32 +1860,17 @@ void AbstractGridRepresentation::getNonTruncatedFaceIndicesOfTruncatedCells(uint } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->LocalFacesPerCell->Elements->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->LocalFacesPerCell->Elements)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt64Values(dataset->PathInHdfFile, faceIndices); - } - else - throw logic_error("Not yet implemented"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->LocalFacesPerCell->Elements, faceIndices); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->LocalFacesPerCell->Elements->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - auto const* daPart = static_cast(rep->TruncationCellPatch->LocalFacesPerCell->Elements)->Values->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfUInt64Values(daPart->PathInExternalFile, faceIndices); - } - else - throw logic_error("Not yet implemented"); + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->LocalFacesPerCell->Elements, faceIndices); } else { throw logic_error("Not implemented yet"); } } -void AbstractGridRepresentation::getCumulativeNonTruncatedFaceCountPerTruncatedCell(uint64_t * cumulativeFaceCountPerCell) const +void AbstractGridRepresentation::getCumulativeNonTruncatedFaceCountPerTruncatedCell(uint64_t* cumulativeFaceCountPerCell) const { if (!isTruncated()) { @@ -2099,47 +1878,10 @@ void AbstractGridRepresentation::getCumulativeNonTruncatedFaceCountPerTruncatedC } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->LocalFacesPerCell->CumulativeLength)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt64Values(dataset->PathInHdfFile, cumulativeFaceCountPerCell); - } - else if (rep->TruncationCells->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerLatticeArray) { - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCells->LocalFacesPerCell->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCells->LocalFacesPerCell->CumulativeLength)->Offset[0]->Value; - const uint64_t cellCount = getTruncatedCellCount(); - for (uint64_t cumulativeFaceCountPerCellIndex = 1; cumulativeFaceCountPerCellIndex < cellCount; ++cumulativeFaceCountPerCellIndex) { - cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex] = cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCells->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerConstantArray) { - if (getTruncatedCellCount() > 1) - throw range_error("The cumulative length of faces count per cells cannot be constant if there is more than one cell in the grid"); - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCells->LocalFacesPerCell->CumulativeLength)->Value; - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_0_1)->TruncationCells->LocalFacesPerCell->CumulativeLength, cumulativeFaceCountPerCell); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - auto const* daPart = static_cast(rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength)->Values->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfUInt64Values(daPart->PathInExternalFile, cumulativeFaceCountPerCell); - } - else if (rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerLatticeArray) { - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength)->StartValue; - const int64_t offsetValue = static_cast(rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength)->Offset[0]->Value; - const uint64_t cellCount = getTruncatedCellCount(); - for (uint64_t cumulativeFaceCountPerCellIndex = 1; cumulativeFaceCountPerCellIndex < cellCount; ++cumulativeFaceCountPerCellIndex) { - cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex] = cumulativeFaceCountPerCell[cumulativeFaceCountPerCellIndex - 1] + offsetValue; - } - } - else if (rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerConstantArray) { - if (getTruncatedCellCount() > 1) - throw range_error("The cumulative length of faces count per cells cannot be constant if there is more than one cell in the grid"); - cumulativeFaceCountPerCell[0] = static_cast(rep->TruncationCellPatch->LocalFacesPerCell->CumulativeLength)->Value; - } + readArrayNdOfUInt64Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->LocalFacesPerCell->CumulativeLength, cumulativeFaceCountPerCell); } else { throw logic_error("Not implemented yet"); @@ -2166,35 +1908,10 @@ void AbstractGridRepresentation::getTruncatedFaceIsRightHanded(uint8_t* cellFace } if (gsoapProxy2_0_1 != nullptr) { - gsoap_resqml2_0_1::resqml20__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_0_1); - - if (rep->TruncationCells->TruncationCellFaceIsRightHanded->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__BooleanHdf5Array) { - gsoap_resqml2_0_1::eml20__Hdf5Dataset const * dataset = static_cast(rep->TruncationCells->TruncationCellFaceIsRightHanded)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUInt8Values(dataset->PathInHdfFile, cellFaceIsRightHanded); - } - else if (rep->TruncationCells->TruncationCellFaceIsRightHanded->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__BooleanConstantArray) { - for (uint64_t i = 0; i < static_cast(rep->TruncationCells->TruncationCellFaceIsRightHanded)->Count; ++i) { - cellFaceIsRightHanded[i] = static_cast(rep->TruncationCells->TruncationCellFaceIsRightHanded)->Value; - } - } - else - throw logic_error("Not implemented yet."); + readArrayNdOfUInt8Values(static_cast(gsoapProxy2_0_1)->TruncationCells->TruncationCellFaceIsRightHanded, cellFaceIsRightHanded); } else if (gsoapProxy2_3 != nullptr) { - gsoap_eml2_3::resqml22__AbstractTruncatedColumnLayerGridRepresentation* rep = static_cast(gsoapProxy2_3); - - if (rep->TruncationCellPatch->TruncationCellFaceIsRightHanded->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__BooleanExternalArray) { - auto const* daPart = static_cast(rep->TruncationCellPatch->TruncationCellFaceIsRightHanded)->Values->ExternalDataArrayPart[0]; - getOrCreateHdfProxyFromDataArrayPart(daPart)->readArrayNdOfUInt8Values(daPart->PathInExternalFile, cellFaceIsRightHanded); - } - else if (rep->TruncationCellPatch->TruncationCellFaceIsRightHanded->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__BooleanConstantArray) { - for (int64_t i = 0; i < static_cast(rep->TruncationCellPatch->TruncationCellFaceIsRightHanded)->Count; ++i) { - cellFaceIsRightHanded[i] = static_cast(rep->TruncationCellPatch->TruncationCellFaceIsRightHanded)->Value; - } - } - else - throw logic_error("Not implemented yet."); + readArrayNdOfUInt8Values(static_cast(gsoapProxy2_3)->TruncationCellPatch->TruncationCellFaceIsRightHanded, cellFaceIsRightHanded); } else { throw logic_error("Not implemented yet"); diff --git a/src/resqml2/AbstractGridRepresentation.h b/src/resqml2/AbstractGridRepresentation.h index 5de37ae4..e4d2f49a 100644 --- a/src/resqml2/AbstractGridRepresentation.h +++ b/src/resqml2/AbstractGridRepresentation.h @@ -25,58 +25,6 @@ namespace RESQML2_NS /** @brief Proxy class for an abstract grid representation. */ class AbstractGridRepresentation : public AbstractRepresentation { - private: - - /** - * @param forceConstantCellCountPerInterval If true, will assume that the child and parent cell count per interval are constant. Then it will use constant xml array instead of hdf5 array for storage. - * The method will consequently only consider the first cell count per interval value in childCellCountPerInterval and parentCellCountPerInterval as the constant ones. - **/ - gsoap_resqml2_0_1::resqml20__Regrid* createRegrid2_0_1(unsigned int indexRegridStart, unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, double * childCellWeights, - const std::string & dimension, EML2_NS::AbstractHdfProxy * proxy, bool forceConstantCellCountPerInterval = false); - gsoap_eml2_3::resqml22__Regrid* createRegrid2_2(unsigned int indexRegridStart, unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, double * childCellWeights, - const std::string & dimension, EML2_NS::AbstractHdfProxy * proxy, bool forceConstantCellCountPerInterval = false); - - /* - * @param dimension It must be either 'i', 'j' ou 'k' (upper or lower case) for an ijk parent grid. 'k' for a strict column layer parent grid. - * @param childVsParentCellCount If true return the child cell count per interval. If false return the parent cell count per interval. - */ - gsoap_resqml2_0_1::resqml20__AbstractIntegerArray* getCellCountPerInterval2_0_1(char dimension, bool childVsParentCellCount) const; - gsoap_eml2_3::eml23__AbstractIntegerArray* getCellCountPerInterval2_2(char dimension, bool childVsParentCellCount) const; - - /** - * Gets the parent window 2 0 1 - * - * @returns Null if it fails, else the parent window 2 0 1. - */ - gsoap_resqml2_0_1::resqml20__AbstractParentWindow* getParentWindow2_0_1() const; - gsoap_eml2_3::resqml22__AbstractParentWindow* getParentWindow2_2() const; - - protected: - - /** - * Only to be used in partial transfer context - * - * @param [in,out] partialObject If non-null, the partial object. - * @param withTruncatedPillars True to with truncated pillars. - */ - AbstractGridRepresentation(gsoap_resqml2_0_1::eml20__DataObjectReference* partialObject, bool withTruncatedPillars) :AbstractRepresentation(partialObject), withTruncatedPillars(withTruncatedPillars) {} - - /** - * Default constructor - * - * @param withTruncatedPillars True to with truncated pillars. - */ - AbstractGridRepresentation(bool withTruncatedPillars) : withTruncatedPillars(withTruncatedPillars){} - - /** - * Creates an instance of this class by wrapping a gsoap instance. - * - * @param [in,out] fromGsoap If non-null, from gsoap. - * @param withTruncatedPillars True to with truncated pillars. - */ - AbstractGridRepresentation(gsoap_resqml2_0_1::resqml20__AbstractGridRepresentation* fromGsoap, bool withTruncatedPillars) : AbstractRepresentation(fromGsoap), withTruncatedPillars(withTruncatedPillars) {} - AbstractGridRepresentation(gsoap_eml2_3::resqml22__AbstractGridRepresentation* fromGsoap, bool withTruncatedPillars) : AbstractRepresentation(fromGsoap), withTruncatedPillars(withTruncatedPillars) {} - public: /** Destructor does nothing since the memory is managed by the gsoap context. */ @@ -85,9 +33,6 @@ namespace RESQML2_NS /** * Gets the count of (volumetric) cells in the grid. * - * @exception std::range_error If the cell count is strictly greater than unsigned int max. - * @exception std::logic_error If this grid is partial. - * * @returns The cell count. */ DLL_IMPORT_OR_EXPORT virtual uint64_t getCellCount() const = 0; @@ -106,9 +51,6 @@ namespace RESQML2_NS /** * Gets the count of grid connection set representations associated to this grid instance. * - * @exception std::range_error If the count of grid connection set representations is - * strictly greater than unsigned int max. - * * @returns The count of grid connection set representations associated to this grid instance. */ DLL_IMPORT_OR_EXPORT uint64_t getGridConnectionSetRepresentationCount() const; // It is mainly used in SWIG context for parsing the vector from a non C++ language. @@ -162,9 +104,6 @@ namespace RESQML2_NS /** * Gets the count of child grids of this grid. * - * @exception std::range_error If the count of child grids is strictly greater than unsigned - * int max. - * * @returns The count of child grids of this grid. */ DLL_IMPORT_OR_EXPORT uint64_t getChildGridCount() const; @@ -247,7 +186,7 @@ namespace RESQML2_NS */ DLL_IMPORT_OR_EXPORT void setParentWindow(unsigned int * columnIndices, uint64_t columnIndexCount, unsigned int kLayerIndexRegridStart, - unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, unsigned int intervalCount, + unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, class AbstractColumnLayerGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * childCellWeights = nullptr); @@ -326,9 +265,9 @@ namespace RESQML2_NS * per interval). Default value is nullptr. */ DLL_IMPORT_OR_EXPORT void setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, uint64_t kIntervalCount, class AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * iChildCellWeights = nullptr, double * jChildCellWeights = nullptr, double * kChildCellWeights = nullptr); /** @@ -422,9 +361,9 @@ namespace RESQML2_NS * * kIntervalCount). */ DLL_IMPORT_OR_EXPORT void setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, uint64_t kIntervalCount, class AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * iChildCellWeights = nullptr, double * jChildCellWeights = nullptr, double * kChildCellWeights = nullptr); /** @@ -547,7 +486,7 @@ namespace RESQML2_NS * * @returns The count of parent grid cells which are regridded. */ - DLL_IMPORT_OR_EXPORT int64_t getParentCellIndexCount() const; + DLL_IMPORT_OR_EXPORT uint64_t getParentCellIndexCount() const; /** * Gets the indices of the parent grid cells which are regridded. Please only run this method @@ -577,7 +516,7 @@ namespace RESQML2_NS * * @returns The count of parent grid columns which are regridded. */ - DLL_IMPORT_OR_EXPORT int64_t getParentColumnIndexCount() const; + DLL_IMPORT_OR_EXPORT uint64_t getParentColumnIndexCount() const; /** * Gets the indices of the parent grid columns which are regridded. Please only run this method @@ -1171,7 +1110,57 @@ namespace RESQML2_NS protected: - /** True to with truncated pillars */ + /** + * Only to be used in partial transfer context + * + * @param [in,out] partialObject If non-null, the partial object. + * @param withTruncatedPillars True to with truncated pillars. + */ + AbstractGridRepresentation(gsoap_resqml2_0_1::eml20__DataObjectReference* partialObject, bool withTruncatedPillars) :AbstractRepresentation(partialObject), withTruncatedPillars(withTruncatedPillars) {} + + /** + * Default constructor + * + * @param withTruncatedPillars True to with truncated pillars. + */ + AbstractGridRepresentation(bool withTruncatedPillars) : withTruncatedPillars(withTruncatedPillars) {} + + /** + * Creates an instance of this class by wrapping a gsoap instance. + * + * @param [in,out] fromGsoap If non-null, from gsoap. + * @param withTruncatedPillars True to with truncated pillars. + */ + AbstractGridRepresentation(gsoap_resqml2_0_1::resqml20__AbstractGridRepresentation* fromGsoap, bool withTruncatedPillars) : AbstractRepresentation(fromGsoap), withTruncatedPillars(withTruncatedPillars) {} + AbstractGridRepresentation(gsoap_eml2_3::resqml22__AbstractGridRepresentation* fromGsoap, bool withTruncatedPillars) : AbstractRepresentation(fromGsoap), withTruncatedPillars(withTruncatedPillars) {} + + /** True with truncated pillars */ bool withTruncatedPillars; + + private: + + /** + * @param forceConstantCellCountPerInterval If true, will assume that the child and parent cell count per interval are constant. Then it will use constant xml array instead of hdf5 array for storage. + * The method will consequently only consider the first cell count per interval value in childCellCountPerInterval and parentCellCountPerInterval as the constant ones. + **/ + gsoap_resqml2_0_1::resqml20__Regrid* createRegrid2_0_1(uint32_t indexRegridStart, uint32_t* childCellCountPerInterval, uint32_t* parentCellCountPerInterval, uint64_t intervalCount, double* childCellWeights, + const std::string& dimension, EML2_NS::AbstractHdfProxy* proxy, bool forceConstantCellCountPerInterval = false); + gsoap_eml2_3::resqml22__Regrid* createRegrid2_2(uint32_t indexRegridStart, uint32_t* childCellCountPerInterval, uint32_t* parentCellCountPerInterval, uint64_t intervalCount, double* childCellWeights, + const std::string& dimension, EML2_NS::AbstractHdfProxy* proxy, bool forceConstantCellCountPerInterval = false); + + /* + * @param dimension It must be either 'i', 'j' ou 'k' (upper or lower case) for an ijk parent grid. 'k' for a strict column layer parent grid. + * @param childVsParentCellCount If true return the child cell count per interval. If false return the parent cell count per interval. + */ + gsoap_resqml2_0_1::resqml20__AbstractIntegerArray* getCellCountPerInterval2_0_1(char dimension, bool childVsParentCellCount) const; + gsoap_eml2_3::eml23__AbstractIntegerArray* getCellCountPerInterval2_2(char dimension, bool childVsParentCellCount) const; + + /** + * Gets the parent window 2 0 1 + * + * @returns Null if it fails, else the parent window 2 0 1. + */ + gsoap_resqml2_0_1::resqml20__AbstractParentWindow* getParentWindow2_0_1() const; + gsoap_eml2_3::resqml22__AbstractParentWindow* getParentWindow2_2() const; }; } diff --git a/src/resqml2/AbstractIjkGridRepresentation.cpp b/src/resqml2/AbstractIjkGridRepresentation.cpp index 5d1c8a84..3dbe1aaf 100644 --- a/src/resqml2/AbstractIjkGridRepresentation.cpp +++ b/src/resqml2/AbstractIjkGridRepresentation.cpp @@ -370,32 +370,20 @@ void AbstractIjkGridRepresentation::getColumnsOfSplitCoordinateLines(unsigned in throw invalid_argument("There is no geometry or no split coordinate line in this IJK grid."); } - if (geom->SplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__IntegerHdf5Array) { - eml20__Hdf5Dataset const * dataset = static_cast(geom->SplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - hdfProxy->readArrayNdOfUIntValues(dataset->PathInHdfFile, columnIndices); - if (reverseIAxis || reverseJAxis) { - datasetValueCount = hdfProxy->getElementCount(dataset->PathInHdfFile); - } + readArrayNdOfUInt32Values(geom->SplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements, columnIndices); + if (reverseIAxis || reverseJAxis) { + datasetValueCount = getCountOfArray(geom->SplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements); } - else - throw std::logic_error("Not implemented yet"); } else { gsoap_eml2_3::resqml22__IjkGridGeometry* geom = static_cast(getPointGeometry2_2(0)); if (geom == nullptr || geom->ColumnLayerSplitCoordinateLines == nullptr) { throw invalid_argument("There is no geometry or no split coordinate line in this IJK grid."); } - if (geom->ColumnLayerSplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements->soap_type() == SOAP_TYPE_gsoap_eml2_3_eml23__IntegerExternalArray) { - gsoap_eml2_3::eml23__ExternalDataArray const * dataset = static_cast(geom->ColumnLayerSplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getOrCreateHdfProxyFromDataArrayPart(dataset->ExternalDataArrayPart[0]); - hdfProxy->readArrayNdOfUIntValues(dataset->ExternalDataArrayPart[0]->PathInExternalFile, columnIndices); - if (reverseIAxis || reverseJAxis) { - datasetValueCount = hdfProxy->getElementCount(dataset->ExternalDataArrayPart[0]->PathInExternalFile); - } - } - else { - throw std::logic_error("Not implemented yet"); + + readArrayNdOfUInt32Values(geom->ColumnLayerSplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements, columnIndices); + if (reverseIAxis || reverseJAxis) { + datasetValueCount = getCountOfArray(geom->ColumnLayerSplitCoordinateLines->ColumnsPerSplitCoordinateLine->Elements); } } diff --git a/src/resqml2/AbstractProperty.cpp b/src/resqml2/AbstractProperty.cpp index f4e7019d..fa55929d 100644 --- a/src/resqml2/AbstractProperty.cpp +++ b/src/resqml2/AbstractProperty.cpp @@ -233,7 +233,7 @@ bool AbstractProperty::useInterval() const throw logic_error("Not implemented yet"); } -unsigned int AbstractProperty::getElementCountPerValue() const +uint64_t AbstractProperty::getElementCountPerValue() const { uint64_t result; if (gsoapProxy2_0_1 != nullptr) { @@ -249,11 +249,7 @@ unsigned int AbstractProperty::getElementCountPerValue() const throw logic_error("Not implemented yet"); } - if (result > (std::numeric_limits::max)()) { - throw std::range_error("There are too much Element Count Per Value"); - } - - return static_cast(result); + return result; } gsoap_eml2_3::eml23__IndexableElement AbstractProperty::getAttachmentKind() const diff --git a/src/resqml2/AbstractProperty.h b/src/resqml2/AbstractProperty.h index d3001ab0..c7289c8d 100644 --- a/src/resqml2/AbstractProperty.h +++ b/src/resqml2/AbstractProperty.h @@ -74,7 +74,7 @@ namespace RESQML2_NS * * @returns The element count per value. */ - DLL_IMPORT_OR_EXPORT unsigned int getElementCountPerValue() const; + DLL_IMPORT_OR_EXPORT uint64_t getElementCountPerValue() const; /** * Gets the kind of elements on which the property values are attached to diff --git a/src/resqml2/ContinuousProperty.h b/src/resqml2/ContinuousProperty.h index 9e0fa391..a63816d1 100644 --- a/src/resqml2/ContinuousProperty.h +++ b/src/resqml2/ContinuousProperty.h @@ -583,7 +583,7 @@ namespace RESQML2_NS unsigned int numArrayDimensions, T * minimumValue = nullptr, T * maximumValue = nullptr) { - const unsigned int elementCount = getElementCountPerValue(); + const uint64_t elementCount = getElementCountPerValue(); // Some minimum and maximum values are given : No need to compute them. if (minimumValue != nullptr) { diff --git a/src/resqml2/DiscreteProperty.cpp b/src/resqml2/DiscreteProperty.cpp index d892bd73..c121bd53 100644 --- a/src/resqml2/DiscreteProperty.cpp +++ b/src/resqml2/DiscreteProperty.cpp @@ -317,7 +317,7 @@ void DiscreteProperty::pushBackHdf5ArrayOfValues( AbstractValuesProperty::pushBackHdf5ArrayOfValues(datatype, numValues, numArrayDimensions, nullValue, proxy); if (minimumValue != nullptr && maximumValue != nullptr) { - const unsigned int elementCount = getElementCountPerValue(); + const uint64_t elementCount = getElementCountPerValue(); for (unsigned int propIndex = 0; propIndex < elementCount; ++propIndex) { setMinimumValue(getMinimumValueSize() > propIndex ? (getMinimumValue(propIndex) > minimumValue[propIndex] ? minimumValue[propIndex] : getMinimumValue(propIndex)) @@ -379,7 +379,7 @@ void DiscreteProperty::setValuesOfInt64Hdf5ArrayOfValues( offsetValues, numArrayDimensions, proxy, patchIndex); if (computeMinMax) { - const unsigned int elementCount = getElementCountPerValue(); + const uint64_t elementCount = getElementCountPerValue(); uint64_t nValues = numValues[0]; //If count > 1, the last (fastest) dimension has the number of properties per indexable element of the representation. for (unsigned int dim = 1; dim < (elementCount == 1 ? numArrayDimensions : numArrayDimensions - 1); ++dim) { @@ -422,7 +422,7 @@ void DiscreteProperty::setValuesOfInt32Hdf5ArrayOfValues( offsetValues, numArrayDimensions, proxy, patchIndex); if (computeMinMax) { - const unsigned int elementCount = getElementCountPerValue(); + const uint64_t elementCount = getElementCountPerValue(); uint64_t nValues = numValues[0]; //If count > 1, the last (fastest) dimension has the number of properties per indexable element of the representation. for (unsigned int dim = 1; dim < (elementCount == 1 ? numArrayDimensions : numArrayDimensions - 1); ++dim) { diff --git a/src/resqml2_0_1/LocalDepth3dCrs.cpp b/src/resqml2_0_1/LocalDepth3dCrs.cpp index 4a521ade..254df062 100644 --- a/src/resqml2_0_1/LocalDepth3dCrs.cpp +++ b/src/resqml2_0_1/LocalDepth3dCrs.cpp @@ -55,7 +55,7 @@ LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const st double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { if (projectedEpsgCode == 0 || verticalEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -77,8 +77,8 @@ LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const st LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, verticalUom, isUpOriented); _resqml20__LocalDepth3dCrs* local3dCrs = static_cast<_resqml20__LocalDepth3dCrs*>(gsoapProxy2_0_1); @@ -86,19 +86,31 @@ LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const st // Projected CRS eml20__ProjectedUnknownCrs* projCrs = soap_new_eml20__ProjectedUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->ProjectedCrs = projCrs; - projCrs->Unknown = projectedUnknownReason; + if (projectedDefinition.size() < 5 || projectedDefinition.substr(0, 5) != "PROJC") { // Either PROJCRS or alias PROJCS + projCrs->Unknown = projectedDefinition; + } + else { + projCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:projectedCrsWkt", projectedDefinition); + } // Vertical CRS eml20__VerticalUnknownCrs* vertCrs = soap_new_eml20__VerticalUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->VerticalCrs = vertCrs; - vertCrs->Unknown = verticalUnknownReason; + if (verticalDefinition.size() < 4 || verticalDefinition.substr(0, 4) != "VERT") { // Either VERTCRS or VERTICALCRS or VERT_CS + vertCrs->Unknown = verticalDefinition; + } + else { + vertCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:verticalCrsWkt", verticalDefinition); + } } LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { if (projectedEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -114,14 +126,20 @@ LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const st // Vertical CRS eml20__VerticalUnknownCrs* vertCrs = soap_new_eml20__VerticalUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->VerticalCrs = vertCrs; - vertCrs->Unknown = verticalUnknownReason; + if (verticalDefinition.size() < 4 || verticalDefinition.substr(0, 4) != "VERT") { // Either VERTCRS or VERTICALCRS or VERT_CS + vertCrs->Unknown = verticalDefinition; + } + else { + vertCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:verticalCrsWkt", verticalDefinition); + } } LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { if (verticalEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -132,7 +150,13 @@ LocalDepth3dCrs::LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const st // Projected CRS eml20__ProjectedUnknownCrs* projCrs = soap_new_eml20__ProjectedUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->ProjectedCrs = projCrs; - projCrs->Unknown = projectedUnknownReason; + if (projectedDefinition.size() < 5 || projectedDefinition.substr(0, 5) != "PROJC") { // Either PROJCRS or alias PROJCS + projCrs->Unknown = projectedDefinition; + } + else { + projCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:projectedCrsWkt", projectedDefinition); + } // Vertical CRS eml20__VerticalCrsEpsgCode* vertCrs = soap_new_eml20__VerticalCrsEpsgCode(gsoapProxy2_0_1->soap); diff --git a/src/resqml2_0_1/LocalDepth3dCrs.h b/src/resqml2_0_1/LocalDepth3dCrs.h index 87677c60..3d7b3bcb 100644 --- a/src/resqml2_0_1/LocalDepth3dCrs.h +++ b/src/resqml2_0_1/LocalDepth3dCrs.h @@ -95,10 +95,10 @@ namespace RESQML2_0_1_NS double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * Creates a local depth 3d CRS which is fully unknown. + * Creates a local depth 3d CRS which is fully defined by a string representation. * Projected CRS (and consequently local CRS) is supposed to be an easting northing one for now. * * @param [in,out] repo The repo where the underlying gsoap proxy is going to @@ -115,12 +115,12 @@ namespace RESQML2_0_1_NS * crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided - * using EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this local depth CRS is actually a * local elevation CRS and that the associated vertical CRS is * an elevation one as well. @@ -128,12 +128,12 @@ namespace RESQML2_0_1_NS LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unkown for its vertical part. + * part and which is defined by a string representation for its vertical part. * Projected CRS (and consequently local CRS) is supposed to be an easting northing one for now. * * @exception std::invalid_argument If projectedEpsgCode == 0. @@ -153,8 +153,8 @@ namespace RESQML2_0_1_NS * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this local depth CRS is actually a * local elevation CRS and that the associated vertical CRS is * an elevation one as well. @@ -163,10 +163,10 @@ namespace RESQML2_0_1_NS double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which unkown for its projected part and which is + * @brief Creates a local depth 3d CRS which is defined by a string representation for its projected part and which is * identified by an EPSG code for its vertical part. * Projected CRS (and consequently local CRS) is supposed to be an easting northing one for now. * @@ -183,8 +183,8 @@ namespace RESQML2_0_1_NS * @param arealRotation The areal rotation in radians regarding the projected crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using - * EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. * @param isUpOriented If true, indicates that this local depth CRS is actually a @@ -194,8 +194,8 @@ namespace RESQML2_0_1_NS LocalDepth3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * Creates an instance of this class by wrapping a gsoap instance. diff --git a/src/resqml2_0_1/LocalTime3dCrs.cpp b/src/resqml2_0_1/LocalTime3dCrs.cpp index 8667a5ad..097882e9 100644 --- a/src/resqml2_0_1/LocalTime3dCrs.cpp +++ b/src/resqml2_0_1/LocalTime3dCrs.cpp @@ -58,7 +58,7 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { if (projectedEpsgCode == 0 || verticalEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -80,9 +80,9 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { init(repo, guid, title, originOrdinal1, originOrdinal2, originOrdinal3, arealRotation, projectedUom, timeUom, verticalUom, isUpOriented); _resqml20__LocalTime3dCrs* local3dCrs = static_cast<_resqml20__LocalTime3dCrs*>(gsoapProxy2_0_1); @@ -90,12 +90,24 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: // Projected CRS eml20__ProjectedUnknownCrs* projCrs = soap_new_eml20__ProjectedUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->ProjectedCrs = projCrs; - projCrs->Unknown = projectedUnknownReason; + if (projectedDefinition.size() < 5 || projectedDefinition.substr(0, 5) != "PROJC") { // Either PROJCRS or alias PROJCS + projCrs->Unknown = projectedDefinition; + } + else { + projCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:projectedCrsWkt", projectedDefinition); + } // Vertical CRS eml20__VerticalUnknownCrs* vertCrs = soap_new_eml20__VerticalUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->VerticalCrs = vertCrs; - vertCrs->Unknown = verticalUnknownReason; + if (verticalDefinition.size() < 4 || verticalDefinition.substr(0, 4) != "VERT") { // Either VERTCRS or VERTICALCRS or VERT_CS + vertCrs->Unknown = verticalDefinition; + } + else { + vertCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:verticalCrsWkt", verticalDefinition); + } } LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, @@ -103,7 +115,7 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented) { if (projectedEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -119,15 +131,21 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: // Vertical CRS eml20__VerticalUnknownCrs* vertCrs = soap_new_eml20__VerticalUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->VerticalCrs = vertCrs; - vertCrs->Unknown = verticalUnknownReason; + if (verticalDefinition.size() < 4 || verticalDefinition.substr(0, 4) != "VERT") { // Either VERTCRS or VERTICALCRS or VERT_CS + vertCrs->Unknown = verticalDefinition; + } + else { + vertCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:verticalCrsWkt", verticalDefinition); + } } LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented) + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented) { if (verticalEpsgCode == 0) { throw invalid_argument("The EPSG code must be positive."); @@ -138,7 +156,13 @@ LocalTime3dCrs::LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std: // Projected CRS eml20__ProjectedUnknownCrs* projCrs = soap_new_eml20__ProjectedUnknownCrs(gsoapProxy2_0_1->soap); local3dCrs->ProjectedCrs = projCrs; - projCrs->Unknown = projectedUnknownReason; + if (projectedDefinition.size() < 5 || projectedDefinition.substr(0, 5) != "PROJC") { // Either PROJCRS or alias PROJCS + projCrs->Unknown = projectedDefinition; + } + else { + projCrs->Unknown = "WKT"; + pushBackExtraMetadata("Energistics:RESQML2.0.1:projectedCrsWkt", projectedDefinition); + } // Vertical CRS eml20__VerticalCrsEpsgCode* vertCrs = soap_new_eml20__VerticalCrsEpsgCode(gsoapProxy2_0_1->soap); diff --git a/src/resqml2_0_1/LocalTime3dCrs.h b/src/resqml2_0_1/LocalTime3dCrs.h index 121dda87..3022c6b6 100644 --- a/src/resqml2_0_1/LocalTime3dCrs.h +++ b/src/resqml2_0_1/LocalTime3dCrs.h @@ -96,10 +96,10 @@ namespace RESQML2_0_1_NS double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * Creates a local depth 3d CRS which is fully unknown. + * Creates a local depth 3d CRS which is fully defined by a string representation. * * @param [in,out] repo The repo where the underlying gsoap proxy is going to * be created. @@ -114,26 +114,26 @@ namespace RESQML2_0_1_NS * crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided - * using EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this * instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided - * using EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unkown for its vertial part. + * part and which is defined by a string representation for its vertial part. * * @exception std::invalid_argument If projectedEpsgCode == 0. * @@ -152,8 +152,8 @@ namespace RESQML2_0_1_NS * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using - * EPSG or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented Indicates if the axis of the associated vertical CRS is up oriented or not. * It is important to rightly place @p originOrdinal3 in the space. */ @@ -162,10 +162,10 @@ namespace RESQML2_0_1_NS double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which unkown for its projected part and which is + * @brief Creates a local depth 3d CRS which is defined by a string representation for its projected part and which is * identified by an EPSG code for its vertical part. * * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -182,8 +182,8 @@ namespace RESQML2_0_1_NS * @param arealRotation The areal rotation in radians regarding the projected crs. * @param projectedUom The unit of measure of the projected axis of this * instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using - * EPSG or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. @@ -193,9 +193,9 @@ namespace RESQML2_0_1_NS LocalTime3dCrs(COMMON_NS::DataObjectRepository* repo, const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * Creates an instance of this class by wrapping a gsoap instance. diff --git a/src/resqml2_0_1/PolylineSetRepresentation.cpp b/src/resqml2_0_1/PolylineSetRepresentation.cpp index f21e7e49..419d723b 100644 --- a/src/resqml2_0_1/PolylineSetRepresentation.cpp +++ b/src/resqml2_0_1/PolylineSetRepresentation.cpp @@ -225,23 +225,7 @@ resqml20__PointGeometry* PolylineSetRepresentation::getPointGeometry2_0_1(uint64 uint64_t PolylineSetRepresentation::getPolylineCountOfPatch(uint64_t patchIndex) const { - if (patchIndex >= getPatchCount()) { - throw std::out_of_range("patchIndex id out of range."); - } - - resqml20__PolylineSetPatch* patch = static_cast<_resqml20__PolylineSetRepresentation*>(gsoapProxy2_0_1)->LinePatch[patchIndex]; - if (patch->ClosedPolylines->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__BooleanConstantArray) - { - return static_cast(patch->ClosedPolylines)->Count; - } - else if (patch->ClosedPolylines->soap_type() == SOAP_TYPE_gsoap_resqml2_0_1_resqml20__BooleanHdf5Array) - { - eml20__Hdf5Dataset const * dataset = static_cast(patch->ClosedPolylines)->Values; - EML2_NS::AbstractHdfProxy * hdfProxy = getHdfProxyFromDataset(dataset); - return hdfProxy->getElementCount(dataset->PathInHdfFile); - } - - return 0; + return getCountOfArray(static_cast<_resqml20__PolylineSetRepresentation*>(gsoapProxy2_0_1)->LinePatch.at(patchIndex)->ClosedPolylines); } uint64_t PolylineSetRepresentation::getPolylineCountOfAllPatches() const diff --git a/src/tools/date.h b/src/tools/date.h index d8fb7f26..beb627e4 100644 --- a/src/tools/date.h +++ b/src/tools/date.h @@ -45,9 +45,7 @@ #include #include #include -#if !(__cplusplus >= 201402) -# include -#endif +#include #include #include #include @@ -138,7 +136,7 @@ namespace date #endif #ifndef HAS_UNCAUGHT_EXCEPTIONS -# if __cplusplus > 201703 || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) +# if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define HAS_UNCAUGHT_EXCEPTIONS 1 # else # define HAS_UNCAUGHT_EXCEPTIONS 0 @@ -418,8 +416,8 @@ class year CONSTCD11 explicit operator int() const NOEXCEPT; CONSTCD11 bool ok() const NOEXCEPT; - static CONSTCD11 year (min)() NOEXCEPT { return year{-32767}; } - static CONSTCD11 year (max)() NOEXCEPT { return year{32767}; } + static CONSTCD11 year min() NOEXCEPT { return year{-32767}; } + static CONSTCD11 year max() NOEXCEPT { return year{32767}; } }; CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; @@ -1006,6 +1004,8 @@ struct is_clock inline constexpr bool is_clock_v = is_clock::value; + #endif // HAS_VOID_T //----------------+ @@ -1022,6 +1022,7 @@ class save_istream std::basic_ios& is_; CharT fill_; std::ios::fmtflags flags_; + std::streamsize precision_; std::streamsize width_; std::basic_ostream* tie_; std::locale loc_; @@ -1031,6 +1032,7 @@ class save_istream { is_.fill(fill_); is_.flags(flags_); + is_.precision(precision_); is_.width(width_); is_.imbue(loc_); is_.tie(tie_); @@ -1043,6 +1045,7 @@ class save_istream : is_(is) , fill_(is.fill()) , flags_(is.flags()) + , precision_(is.precision()) , width_(is.width(0)) , tie_(is.tie(nullptr)) , loc_(is.getloc()) @@ -1166,7 +1169,11 @@ struct no_overflow static const std::intmax_t d1 = R1::den / gcd_d1_d2; static const std::intmax_t n2 = R2::num / gcd_n1_n2; static const std::intmax_t d2 = R2::den / gcd_d1_d2; - static const std::intmax_t max = (std::numeric_limits::max)(); +#ifdef __cpp_constexpr + static const std::intmax_t max = std::numeric_limits::max(); +#else + static const std::intmax_t max = LLONG_MAX; +#endif template struct mul // overflow == false @@ -1309,7 +1316,7 @@ CONSTCD11 std::chrono::duration abs(std::chrono::duration d) { - return d >= d.zero() ? d : -d; + return d >= d.zero() ? d : static_cast(-d); } // round down @@ -1354,6 +1361,47 @@ using std::chrono::abs; #endif // HAS_CHRONO_ROUNDING +namespace detail +{ + +template +CONSTCD14 +inline +typename std::enable_if +< + !std::chrono::treat_as_floating_point::value, + To +>::type +round_i(const std::chrono::duration& d) +{ + return round(d); +} + +template +CONSTCD14 +inline +typename std::enable_if +< + std::chrono::treat_as_floating_point::value, + To +>::type +round_i(const std::chrono::duration& d) +{ + return d; +} + +template +CONSTCD11 +inline +std::chrono::time_point +round_i(const std::chrono::time_point& tp) +{ + using std::chrono::time_point; + return time_point{round_i(tp.time_since_epoch())}; +} + +} // detail + // trunc towards zero template CONSTCD11 @@ -1458,16 +1506,29 @@ operator-(const day& x, const days& y) NOEXCEPT return x + -y; } +namespace detail +{ + template -inline std::basic_ostream& -operator<<(std::basic_ostream& os, const day& d) +low_level_fmt(std::basic_ostream& os, const day& d) { detail::save_ostream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); os << static_cast(d); + return os; +} + +} // namespace detail + +template +inline +std::basic_ostream& +operator<<(std::basic_ostream& os, const day& d) +{ + detail::low_level_fmt(os, d); if (!d.ok()) os << " is not a valid day"; return os; @@ -1585,10 +1646,12 @@ operator-(const month& x, const months& y) NOEXCEPT return x + -y; } +namespace detail +{ + template -inline std::basic_ostream& -operator<<(std::basic_ostream& os, const month& m) +low_level_fmt(std::basic_ostream& os, const month& m) { if (m.ok()) { @@ -1596,7 +1659,20 @@ operator<<(std::basic_ostream& os, const month& m) os << format(os.getloc(), fmt, m); } else - os << static_cast(m) << " is not a valid month"; + os << static_cast(m); + return os; +} + +} // namespace detail + +template +inline +std::basic_ostream& +operator<<(std::basic_ostream& os, const month& m) +{ + detail::low_level_fmt(os, m); + if (!m.ok()) + os << " is not a valid month"; return os; } @@ -1627,7 +1703,7 @@ inline bool year::ok() const NOEXCEPT { - return y_ != (std::numeric_limits::min)(); + return y_ != std::numeric_limits::min(); } CONSTCD11 @@ -1710,10 +1786,12 @@ operator-(const year& x, const years& y) NOEXCEPT return year{static_cast(x) - y.count()}; } +namespace detail +{ + template -inline std::basic_ostream& -operator<<(std::basic_ostream& os, const year& y) +low_level_fmt(std::basic_ostream& os, const year& y) { detail::save_ostream _(os); os.fill('0'); @@ -1721,6 +1799,17 @@ operator<<(std::basic_ostream& os, const year& y) os.width(4 + (y < year{0})); os.imbue(std::locale::classic()); os << static_cast(y); + return os; +} + +} // namespace detail + +template +inline +std::basic_ostream& +operator<<(std::basic_ostream& os, const year& y) +{ + detail::low_level_fmt(os, y); if (!y.ok()) os << " is not a valid year"; return os; @@ -1846,10 +1935,12 @@ operator-(const weekday& x, const days& y) NOEXCEPT return x + -y; } +namespace detail +{ + template -inline std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday& wd) +low_level_fmt(std::basic_ostream& os, const weekday& wd) { if (wd.ok()) { @@ -1857,7 +1948,20 @@ operator<<(std::basic_ostream& os, const weekday& wd) os << format(fmt, wd); } else - os << static_cast(wd.wd_) << " is not a valid weekday"; + os << wd.c_encoding(); + return os; +} + +} // namespace detail + +template +inline +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday& wd) +{ + detail::low_level_fmt(os, wd); + if (!wd.ok()) + os << " is not a valid weekday"; return os; } @@ -1966,15 +2070,26 @@ weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCE # pragma GCC diagnostic pop #endif // __GNUC__ +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const weekday_indexed& wdi) +{ + return low_level_fmt(os, wdi.weekday()) << '[' << wdi.index() << ']'; +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { - os << wdi.weekday() << '[' << wdi.index(); - if (!(1 <= wdi.index() && wdi.index() <= 5)) - os << " is not a valid index"; - os << ']'; + detail::low_level_fmt(os, wdi); + if (!wdi.ok()) + os << " is not a valid weekday_indexed"; return os; } @@ -2024,12 +2139,27 @@ operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT return !(x == y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const weekday_last& wdl) +{ + return low_level_fmt(os, wdl.weekday()) << "[last]"; +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl) { - return os << wdl.weekday() << "[last]"; + detail::low_level_fmt(os, wdl); + if (!wdl.ok()) + os << " is not a valid weekday_last"; + return os; } CONSTCD11 @@ -2204,12 +2334,28 @@ operator-(const year_month& ym, const years& dy) NOEXCEPT return ym + -dy; } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const year_month& ym) +{ + low_level_fmt(os, ym.year()) << '/'; + return low_level_fmt(os, ym.month()); +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month& ym) { - return os << ym.year() << '/' << ym.month(); + detail::low_level_fmt(os, ym); + if (!ym.ok()) + os << " is not a valid year_month"; + return os; } // month_day @@ -2289,12 +2435,28 @@ operator>=(const month_day& x, const month_day& y) NOEXCEPT return !(x < y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const month_day& md) +{ + low_level_fmt(os, md.month()) << '/'; + return low_level_fmt(os, md.day()); +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day& md) { - return os << md.month() << '/' << md.day(); + detail::low_level_fmt(os, md); + if (!md.ok()) + os << " is not a valid month_day"; + return os; } // month_day_last @@ -2351,12 +2513,27 @@ operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT return !(x < y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const month_day_last& mdl) +{ + return low_level_fmt(os, mdl.month()) << "/last"; +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_day_last& mdl) { - return os << mdl.month() << "/last"; + detail::low_level_fmt(os, mdl); + if (!mdl.ok()) + os << " is not a valid month_day_last"; + return os; } // month_weekday @@ -2403,12 +2580,28 @@ operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT return !(x == y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const month_weekday& mwd) +{ + low_level_fmt(os, mwd.month()) << '/'; + return low_level_fmt(os, mwd.weekday_indexed()); +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday& mwd) { - return os << mwd.month() << '/' << mwd.weekday_indexed(); + detail::low_level_fmt(os, mwd); + if (!mwd.ok()) + os << " is not a valid month_weekday"; + return os; } // month_weekday_last @@ -2455,12 +2648,28 @@ operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT return !(x == y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const month_weekday_last& mwdl) +{ + low_level_fmt(os, mwdl.month()) << '/'; + return low_level_fmt(os, mwdl.weekday_last()); +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { - return os << mwdl.month() << '/' << mwdl.weekday_last(); + detail::low_level_fmt(os, mwdl); + if (!mwdl.ok()) + os << " is not a valid month_weekday_last"; + return os; } // year_month_day_last @@ -2610,12 +2819,28 @@ operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT return !(x < y); } +namespace detail +{ + +template +std::basic_ostream& +low_level_fmt(std::basic_ostream& os, const year_month_day_last& ymdl) +{ + low_level_fmt(os, ymdl.year()) << '/'; + return low_level_fmt(os, ymdl.month_day_last()); +} + +} // namespace detail + template inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { - return os << ymdl.year() << '/' << ymdl.month_day_last(); + detail::low_level_fmt(os, ymdl); + if (!ymdl.ok()) + os << " is not a valid year_month_day_last"; + return os; } template @@ -2846,12 +3071,13 @@ operator<<(std::basic_ostream& os, const year_month_day& ymd) os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.imbue(std::locale::classic()); - os << ymd.year() << '-'; + os << static_cast(ymd.year()) << '-'; os.width(2); os << static_cast(ymd.month()) << '-'; - os << ymd.day(); + os.width(2); + os << static_cast(ymd.day()); if (!ymd.ok()) - os << " is not a valid date"; + os << " is not a valid year_month_day"; return os; } @@ -3087,8 +3313,12 @@ inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { - return os << ymwdi.year() << '/' << ymwdi.month() - << '/' << ymwdi.weekday_indexed(); + detail::low_level_fmt(os, ymwdi.year()) << '/'; + detail::low_level_fmt(os, ymwdi.month()) << '/'; + detail::low_level_fmt(os, ymwdi.weekday_indexed()); + if (!ymwdi.ok()) + os << " is not a valid year_month_weekday"; + return os; } template @@ -3264,7 +3494,12 @@ inline std::basic_ostream& operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { - return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); + detail::low_level_fmt(os, ymwdl.year()) << '/'; + detail::low_level_fmt(os, ymwdl.month()) << '/'; + detail::low_level_fmt(os, ymwdl.weekday_last()); + if (!ymwdl.ok()) + os << " is not a valid year_month_weekday_last"; + return os; } template @@ -3681,11 +3916,12 @@ struct undocumented {explicit undocumented() = default;}; // Example: width<4>::value == 2 // Example: width<10>::value == 1 // Example: width<1000>::value == 3 -template +template struct width { - static CONSTDATA unsigned value = 1 + width::value; + static_assert(d > 0, "width called with zero denominator"); + static CONSTDATA unsigned value = 1 + width::value; }; template @@ -3714,9 +3950,10 @@ class decimal_format_seconds { using CT = typename std::common_type::type; using rep = typename CT::rep; + static unsigned CONSTDATA trial_width = + detail::width::value; public: - static unsigned constexpr width = detail::width::value < 19 ? - detail::width::value : 6u; + static unsigned CONSTDATA width = trial_width < 19 ? trial_width : 6u; using precision = std::chrono::duration::value>>; @@ -3765,6 +4002,7 @@ class decimal_format_seconds std::chrono::duration d = s_ + sub_s_; if (d < std::chrono::seconds{10}) os << '0'; + os.precision(width+6); os << std::fixed << d.count(); return os; } @@ -3955,9 +4193,7 @@ make24(std::chrono::hours h, bool is_pm) NOEXCEPT template using time_of_day = hh_mm_ss; -template ::value>::type> +template CONSTCD11 inline hh_mm_ss> @@ -3970,9 +4206,8 @@ template inline typename std::enable_if < - !std::chrono::treat_as_floating_point::value && - std::ratio_less::value - , std::basic_ostream& + !std::is_convertible::value, + std::basic_ostream& >::type operator<<(std::basic_ostream& os, const sys_time& tp) { @@ -3993,7 +4228,7 @@ inline std::basic_ostream& operator<<(std::basic_ostream& os, const local_time& ut) { - return (os << sys_time{ut.time_since_epoch()}); + return (date::operator<<(os, sys_time{ut.time_since_epoch()})); } namespace detail @@ -4552,7 +4787,11 @@ struct fields hh_mm_ss tod{}; bool has_tod = false; +#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ <= 409) + fields() : ymd{nanyear/0/0}, wd{8u}, tod{}, has_tod{false} {} +#else fields() = default; +#endif fields(year_month_day ymd_) : ymd(ymd_) {} fields(weekday wd_) : wd(wd_) {} @@ -4734,7 +4973,7 @@ scan_keyword(std::basic_istream& is, FwdIter kb, FwdIter ke) is.setstate(std::ios::eofbit); break; } - auto c = static_cast(toupper(ic)); + auto c = static_cast(toupper(static_cast(ic))); bool consume = false; // For each keyword which might match, see if the indx character is c // If a match if found, consume c @@ -4747,7 +4986,7 @@ scan_keyword(std::basic_istream& is, FwdIter kb, FwdIter ke) { if (*st == might_match) { - if (c == static_cast(toupper((*ky)[indx]))) + if (c == static_cast(toupper(static_cast((*ky)[indx])))) { consume = true; if (ky->size() == indx+1) @@ -5974,8 +6213,13 @@ to_stream(std::basic_ostream& os, const CharT* fmt, const std::chrono::seconds* offset_sec = nullptr) { using CT = typename std::common_type::type; - auto ld = floor(tp); - fields fds{year_month_day{ld}, hh_mm_ss{tp-local_seconds{ld}}}; + auto ld = std::chrono::time_point_cast(tp); + fields fds; + if (ld <= tp) + fds = fields{year_month_day{ld}, hh_mm_ss{tp-local_seconds{ld}}}; + else + fds = fields{year_month_day{ld - days{1}}, + hh_mm_ss{days{1} - (local_seconds{ld} - tp)}}; return to_stream(os, fmt, fds, abbrev, offset_sec); } @@ -5988,8 +6232,13 @@ to_stream(std::basic_ostream& os, const CharT* fmt, using CT = typename std::common_type::type; const std::string abbrev("UTC"); CONSTDATA seconds offset{0}; - auto sd = floor(tp); - fields fds{year_month_day{sd}, hh_mm_ss{tp-sys_seconds{sd}}}; + auto sd = std::chrono::time_point_cast(tp); + fields fds; + if (sd <= tp) + fds = fields{year_month_day{sd}, hh_mm_ss{tp-sys_seconds{sd}}}; + else + fds = fields{year_month_day{sd - days{1}}, + hh_mm_ss{days{1} - (sys_seconds{sd} - tp)}}; return to_stream(os, fmt, fds, &abbrev, &offset); } @@ -6102,8 +6351,11 @@ read_signed(std::basic_istream& is, unsigned m = 1, unsigned M = if (('0' <= c && c <= '9') || c == '-' || c == '+') { if (c == '-' || c == '+') + { (void)is.get(); - auto x = static_cast(read_unsigned(is, (std::max)(m, 1u), M)); + --M; + } + auto x = static_cast(read_unsigned(is, std::max(m, 1u), M)); if (!is.fail()) { if (c == '-') @@ -6122,9 +6374,16 @@ long double read_long_double(std::basic_istream& is, unsigned m = 1, unsigned M = 10) { unsigned count = 0; + unsigned fcount = 0; + unsigned long long i = 0; + unsigned long long f = 0; + bool parsing_fraction = false; +#if ONLY_C_LOCALE + typename Traits::int_type decimal_point = '.'; +#else auto decimal_point = Traits::to_int_type( std::use_facet>(is.getloc()).decimal_point()); - std::string buf; +#endif while (true) { auto ic = is.peek(); @@ -6132,18 +6391,25 @@ read_long_double(std::basic_istream& is, unsigned m = 1, unsigned break; if (Traits::eq_int_type(ic, decimal_point)) { - buf += '.'; decimal_point = Traits::eof(); - is.get(); + parsing_fraction = true; } else { auto c = static_cast(Traits::to_char_type(ic)); if (!('0' <= c && c <= '9')) break; - buf += c; - (void)is.get(); + if (!parsing_fraction) + { + i = 10*i + static_cast(c - '0'); + } + else + { + f = 10*f + static_cast(c - '0'); + ++fcount; + } } + (void)is.get(); if (++count == M) break; } @@ -6152,7 +6418,7 @@ read_long_double(std::basic_istream& is, unsigned m = 1, unsigned is.setstate(std::ios::failbit); return 0; } - return std::stold(buf); + return static_cast(i) + static_cast(f)/std::pow(10.L, fcount); } struct rs @@ -6261,7 +6527,14 @@ read(std::basic_istream& is, int a0, Args&& ...args) *e++ = static_cast(CharT(u % 10) + CharT{'0'}); u /= 10; } while (u > 0); +#if defined(__GNUC__) && __GNUC__ >= 11 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif std::reverse(buf, e); +#if defined(__GNUC__) && __GNUC__ >= 11 +#pragma GCC diagnostic pop +#endif for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) read(is, *p); } @@ -6309,6 +6582,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; + using detail::round_i; typename std::basic_istream::sentry ok{is, true}; if (ok) { @@ -6324,20 +6598,20 @@ from_stream(std::basic_istream& is, const CharT* fmt, auto modified = CharT{}; auto width = -1; - CONSTDATA int not_a_year = (numeric_limits::min)(); + CONSTDATA int not_a_year = numeric_limits::min(); CONSTDATA int not_a_2digit_year = 100; - CONSTDATA int not_a_century = not_a_year / 100; + CONSTDATA int not_a_century = numeric_limits::min(); CONSTDATA int not_a_month = 0; CONSTDATA int not_a_day = 0; - CONSTDATA int not_a_hour = (numeric_limits::min)(); + CONSTDATA int not_a_hour = numeric_limits::min(); CONSTDATA int not_a_hour_12_value = 0; CONSTDATA int not_a_minute = not_a_hour; - CONSTDATA Duration not_a_second = (Duration::min)(); + CONSTDATA Duration not_a_second = Duration::min(); CONSTDATA int not_a_doy = -1; CONSTDATA int not_a_weekday = 8; CONSTDATA int not_a_week_num = 100; CONSTDATA int not_a_ampm = -1; - CONSTDATA minutes not_a_offset = (minutes::min)(); + CONSTDATA minutes not_a_offset = minutes::min(); int Y = not_a_year; // c, F, Y * int y = not_a_2digit_year; // D, x, y * @@ -6517,12 +6791,12 @@ from_stream(std::basic_istream& is, const CharT* fmt, CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH; int tM; - long double S; + long double S{}; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), + checked_set(s, round_i(duration{S}), not_a_second, is); ws(is); int tY = not_a_year; @@ -6597,12 +6871,12 @@ from_stream(std::basic_istream& is, const CharT* fmt, CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH = not_a_hour; int tM = not_a_minute; - long double S; + long double S{}; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), + checked_set(s, round_i(duration{S}), not_a_second, is); #endif } @@ -6918,7 +7192,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, #else auto nm = detail::ampm_names(); auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - tp = i; + tp = static_cast(i); #endif checked_set(p, tp, not_a_ampm, is); } @@ -6952,14 +7226,14 @@ from_stream(std::basic_istream& is, const CharT* fmt, // "%I:%M:%S %p" using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - long double S; + long double S{}; int tI = not_a_hour_12_value; int tM = not_a_minute; read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(I, tI, not_a_hour_12_value, is); checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), + checked_set(s, round_i(duration{S}), not_a_second, is); ws(is); auto nm = detail::ampm_names(); @@ -7008,9 +7282,9 @@ from_stream(std::basic_istream& is, const CharT* fmt, { using dfs = detail::decimal_format_seconds; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - long double S; + long double S{}; read(is, rld{S, 1, width == -1 ? w : static_cast(width)}); - checked_set(s, round(duration{S}), + checked_set(s, round_i(duration{S}), not_a_second, is); } #if !ONLY_C_LOCALE @@ -7042,12 +7316,12 @@ from_stream(std::basic_istream& is, const CharT* fmt, CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; int tH = not_a_hour; int tM = not_a_minute; - long double S; + long double S{}; read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, CharT{':'}, rld{S, 1, w}); checked_set(H, tH, not_a_hour, is); checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), + checked_set(s, round_i(duration{S}), not_a_second, is); } else @@ -7253,7 +7527,12 @@ from_stream(std::basic_istream& is, const CharT* fmt, { auto c = static_cast(Traits::to_char_type(ic)); if (c == '-') + { neg = true; + (void)is.get(); + } + else if (c == '+') + (void)is.get(); } if (modified == CharT{}) { @@ -7442,7 +7721,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, goto broken; G = tG; } - if (Y < static_cast((year::min)()) || Y > static_cast((year::max)())) + if (Y < static_cast(year::min()) || Y > static_cast(year::max())) Y = not_a_year; bool computed = false; if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) @@ -7469,9 +7748,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) + weeks{U-1} + (weekday{static_cast(wd)} - Sunday); - if (Y == not_a_year) - Y = static_cast(ymd_trial.year()); - else if (year{Y} != ymd_trial.year()) + if (year{Y} != ymd_trial.year()) goto broken; if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); @@ -7488,9 +7765,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) + weeks{W-1} + (weekday{static_cast(wd)} - Monday); - if (Y == not_a_year) - Y = static_cast(ymd_trial.year()); - else if (year{Y} != ymd_trial.year()) + if (year{Y} != ymd_trial.year()) goto broken; if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); @@ -7505,11 +7780,11 @@ from_stream(std::basic_istream& is, const CharT* fmt, if (j != not_a_doy && Y != not_a_year) { auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; - if (m == 0) + if (m == not_a_month) m = static_cast(static_cast(ymd_trial.month())); else if (month(static_cast(m)) != ymd_trial.month()) goto broken; - if (d == 0) + if (d == not_a_day) d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; @@ -7595,6 +7870,8 @@ from_stream(std::basic_istream& is, const CharT* fmt, goto broken; } } + else // I is ambiguous, AM or PM? + goto broken; } } if (H != not_a_hour) @@ -7639,7 +7916,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, year& y, { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.year().ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7655,7 +7932,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, month& m, { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7671,7 +7948,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, day& d, { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.day().ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7687,7 +7964,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, weekday& wd { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.wd.ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7703,7 +7980,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, year_month& { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7719,7 +7996,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, month_day& { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7735,7 +8012,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, { using CT = std::chrono::seconds; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.ok()) is.setstate(std::ios::failbit); if (!is.fail()) @@ -7750,15 +8027,16 @@ from_stream(std::basic_istream& is, const CharT* fmt, std::chrono::minutes* offset = nullptr) { using CT = typename std::common_type::type; + using detail::round_i; std::chrono::minutes offset_local{}; auto offptr = offset ? offset : &offset_local; fields fds{}; fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offptr); + date::from_stream(is, fmt, fds, abbrev, offptr); if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) is.setstate(std::ios::failbit); if (!is.fail()) - tp = round(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); + tp = round_i(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); return is; } @@ -7769,13 +8047,14 @@ from_stream(std::basic_istream& is, const CharT* fmt, std::chrono::minutes* offset = nullptr) { using CT = typename std::common_type::type; + using detail::round_i; fields fds{}; fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) is.setstate(std::ios::failbit); if (!is.fail()) - tp = round(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); + tp = round_i(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); return is; } @@ -7788,12 +8067,13 @@ from_stream(std::basic_istream& is, const CharT* fmt, { using Duration = std::chrono::duration; using CT = typename std::common_type::type; + using detail::round_i; fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); + date::from_stream(is, fmt, fds, abbrev, offset); if (!fds.has_tod) is.setstate(std::ios::failbit); if (!is.fail()) - d = std::chrono::duration_cast(fds.tod.to_duration()); + d = round_i(fds.tod.to_duration()); return is; } @@ -7816,6 +8096,25 @@ struct parse_manip , offset_(offset) {} +#if HAS_STRING_VIEW + parse_manip(const CharT* format, Parsable& tp, + std::basic_string* abbrev = nullptr, + std::chrono::minutes* offset = nullptr) + : format_(format) + , tp_(tp) + , abbrev_(abbrev) + , offset_(offset) + {} + + parse_manip(std::basic_string_view format, Parsable& tp, + std::basic_string* abbrev = nullptr, + std::chrono::minutes* offset = nullptr) + : format_(format) + , tp_(tp) + , abbrev_(abbrev) + , offset_(offset) + {} +#endif // HAS_STRING_VIEW }; template @@ -7823,14 +8122,14 @@ std::basic_istream& operator>>(std::basic_istream& is, const parse_manip& x) { - return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); + return date::from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); } template inline auto parse(const std::basic_string& format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), + -> decltype(date::from_stream(std::declval&>(), format.c_str(), tp), parse_manip{format, tp}) { @@ -7842,7 +8141,7 @@ inline auto parse(const std::basic_string& format, Parsable& tp, std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), + -> decltype(date::from_stream(std::declval&>(), format.c_str(), tp, &abbrev), parse_manip{format, tp, &abbrev}) { @@ -7854,7 +8153,7 @@ inline auto parse(const std::basic_string& format, Parsable& tp, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), + -> decltype(date::from_stream(std::declval&>(), format.c_str(), tp, std::declval*>(), &offset), @@ -7868,7 +8167,7 @@ inline auto parse(const std::basic_string& format, Parsable& tp, std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), + -> decltype(date::from_stream(std::declval&>(), format.c_str(), tp, &abbrev, &offset), parse_manip{format, tp, &abbrev, &offset}) { @@ -7881,7 +8180,7 @@ template inline auto parse(const CharT* format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), format, tp), + -> decltype(date::from_stream(std::declval&>(), format, tp), parse_manip{format, tp}) { return {format, tp}; @@ -7891,7 +8190,7 @@ template inline auto parse(const CharT* format, Parsable& tp, std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), format, + -> decltype(date::from_stream(std::declval&>(), format, tp, &abbrev), parse_manip{format, tp, &abbrev}) { @@ -7902,7 +8201,7 @@ template inline auto parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, + -> decltype(date::from_stream(std::declval&>(), format, tp, std::declval*>(), &offset), parse_manip{format, tp, nullptr, &offset}) { @@ -7914,7 +8213,7 @@ inline auto parse(const CharT* format, Parsable& tp, std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, + -> decltype(date::from_stream(std::declval&>(), format, tp, &abbrev, &offset), parse_manip{format, tp, &abbrev, &offset}) { diff --git a/swig/swigEml2Include.i b/swig/swigEml2Include.i index 0707f29a..061e4c1b 100644 --- a/swig/swigEml2Include.i +++ b/swig/swigEml2Include.i @@ -626,6 +626,13 @@ namespace EML2_NS */ bool isProjectedCrsDefinedWithEpsg() const; + /** + * Indicates either the associated projected CRS is given in a WKT format or not. + * + * @returns True if the projected CRS is given in a WKT format, false if not. + */ + bool isProjectedCrsDefinedWithWkt() const; + /** * Indicates either the associated projected CRS is unknown or not. * @@ -642,6 +649,15 @@ namespace EML2_NS */ std::string getProjectedCrsUnknownReason() const; + /** + * Gets the WKT of the projected CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The projected CRS WKT. + */ + std::string getProjectedCrsWkt() const; + /** * Gets the EPSG code of the projected CRS * @@ -658,6 +674,13 @@ namespace EML2_NS */ bool isVerticalCrsDefinedWithEpsg() const; + /** + * Indicates either the associated vertical CRS is given in a WKT format or not. + * + * @returns True if the vertical CRS is given in a WKT format, false if not. + */ + bool isVerticalCrsDefinedWithWkt() const; + /** * Indicates either the associated vertical CRS is unknown or not. * @@ -674,6 +697,15 @@ namespace EML2_NS */ std::string getVerticalCrsUnknownReason() const; + /** + * Gets the WKT of the vertical CRS + * + * @exception std::invalid_argument If the associated projected CRS is not a WKT one. + * + * @returns The vertical CRS WKT. + */ + std::string getVerticalCrsWkt() const; + /** * Gets the EPSG code of the vertical CRS * diff --git a/swig/swigModule.i b/swig/swigModule.i index 45e13a90..8a473dfe 100644 --- a/swig/swigModule.i +++ b/swig/swigModule.i @@ -706,7 +706,7 @@ namespace COMMON_NS * * @returns The extra metadata count of this instance. */ - unsigned int getExtraMetadataCount() const; + uint64_t getExtraMetadataCount() const; /** * Get the key of a key value pair at a particular index in the extra metadata set of this @@ -718,7 +718,7 @@ namespace COMMON_NS * * @returns The extra metadata key at @p index. */ - std::string getExtraMetadataKeyAtIndex(unsigned int index) const; + std::string getExtraMetadataKeyAtIndex(uint64_t index) const; /** * Get the value of a key value pair at a particular index in the extra metadata set of this @@ -730,7 +730,7 @@ namespace COMMON_NS * * @returns The extra metadata value at @p index. */ - std::string getExtraMetadataStringValueAtIndex(unsigned int index) const; + std::string getExtraMetadataStringValueAtIndex(uint64_t index) const; /** * Build and return an ETP1.2 URI from an Energistics dataobject. @@ -1122,15 +1122,15 @@ import com.f2i_consulting.fesapi.*; * * @returns A pointer to the new local depth 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which is fully unknown. Resulting local depth 3d CRS is - * stored into this repository + * @brief Creates a local depth 3d CRS which is fully defined by a string representation. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @@ -1144,26 +1144,26 @@ import com.f2i_consulting.fesapi.*; * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this depth CRS is actually an * elevation CRS. * * @returns A pointer to the new local depth 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local depth 3d CRS which is identified by an EPSG code for its projected - * part and which is unknown for its vertical part. Resulting local depth 3d CRS is - * stored into this repository + * part and which is defined by a string representation for its vertical part. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If projectedEpsgCode == 0. @@ -1180,23 +1180,23 @@ import com.f2i_consulting.fesapi.*; * @param projectedUom The unit of measure of the projected axis of this instance. * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that this depth CRS is actually an * elevation CRS. * * @returns A pointer to the new local depth 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local depth 3d CRS which is unknown for its projected part and which is - * identified by an EPSG code for its vertical part. Resulting local depth 3d CRS is - * stored into this repository + * @brief Creates a local depth 3d CRS which is defined by a string representation for its projected part + * and which is identified by an EPSG code for its vertical part. + * Resulting local depth 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -1211,8 +1211,8 @@ import com.f2i_consulting.fesapi.*; * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. * @param isUpOriented If true, indicates that this depth CRS is actually an @@ -1220,11 +1220,11 @@ import com.f2i_consulting.fesapi.*; * * @returns A pointer to the new local depth 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalDepth3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * @brief Creates a local time 3d CRS which is fully identified by means of EPSG code. @@ -1253,16 +1253,16 @@ import com.f2i_consulting.fesapi.*; * * @returns A pointer to the new local time 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** - * @brief Creates a local time 3d CRS which is fully unknown. Resulting local time 3d CRS is - * stored into this repository + * @brief Creates a local time 3d CRS which is fully defined by a string representation. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @@ -1276,28 +1276,28 @@ import com.f2i_consulting.fesapi.*; * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that the Z offset if an elevation when * positive. If false, the Z offset if a depth when positive. * * @returns A pointer to the new local time 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** * @brief Creates a local time 3d CRS which is identified by an EPSG code for its projected - * part and which is unknown for its vertical part. Resulting local time 3d CRS is - * stored into this repository + * part and which is defined by a string representation for its vertical part. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If projectedEpsgCode == 0. @@ -1315,24 +1315,24 @@ import com.f2i_consulting.fesapi.*; * @param projectedEpsgCode The EPSG code of the associated projected CRS. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. - * @param verticalUnknownReason Indicates why the vertical CRS cannot be provided using EPSG - * or GML. + * @param verticalDefinition If starting with "VERT" then it gives the WKT definition of the vertical CRS. + * Otherwise, it defines why this vertical CRS should be considered as unknown. * @param isUpOriented If true, indicates that the Z offset if an elevation when * positive. If false, the Z offset if a depth when positive. * * @returns A pointer to the new local time 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, gsoap_resqml2_0_1::eml20__LengthUom projectedUom, uint64_t projectedEpsgCode, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string & verticalUnknownReason, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, const std::string& verticalDefinition, bool isUpOriented); /** - * @brief Creates a local time 3d CRS which unknown for its projected part and which is - * identified by an EPSG code for its vertical part. Resulting local time 3d CRS is - * stored into this repository + * @brief Creates a local time 3d CRS which is defined by a string representation for its projected part + * and which is identified by an EPSG code for its vertical part. + * Resulting local time 3d CRS is stored into this repository * * @exception std::invalid_argument If the default RESQML version is unrecognized. * @exception std::invalid_argument If verticalEpsgCode == 0. @@ -1347,8 +1347,8 @@ import com.f2i_consulting.fesapi.*; * origin of the vertical CRS. * @param arealRotation The areal rotation in radians regarding the projected CRS. * @param projectedUom The unit of measure of the projected axis of this instance. - * @param projectedUnknownReason Indicates why the projected CRS cannot be provided using EPSG - * or GML. + * @param projectedDefinition If starting with "PROJCRS" or "PROJCS" then it gives the WKT definition of the projected CRS. + * Otherwise, it defines why this projected CRS should be considered as unknown. * @param timeUom The unit of measure of the Z offset of this instance. * @param verticalUom The unit of measure of the vertical axis of this instance. * @param verticalEpsgCode The EPSG code of the associated vertical CRS. @@ -1357,12 +1357,12 @@ import com.f2i_consulting.fesapi.*; * * @returns A pointer to the new local time 3d CRS. */ - EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string & guid, const std::string & title, + EML2_NS::AbstractLocal3dCrs* createLocalTime3dCrs(const std::string& guid, const std::string& title, double originOrdinal1, double originOrdinal2, double originOrdinal3, double arealRotation, - gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string & projectedUnknownReason, + gsoap_resqml2_0_1::eml20__LengthUom projectedUom, const std::string& projectedDefinition, gsoap_resqml2_0_1::eml20__TimeUom timeUom, - gsoap_resqml2_0_1::eml20__LengthUom verticalUom, unsigned int verticalEpsgCode, bool isUpOriented); + gsoap_resqml2_0_1::eml20__LengthUom verticalUom, uint64_t verticalEpsgCode, bool isUpOriented); /** * @brief Creates a reference point (such as a MD datum) into this repository diff --git a/swig/swigResqml2Include.i b/swig/swigResqml2Include.i index 1e6f120e..c0eb10b2 100644 --- a/swig/swigResqml2Include.i +++ b/swig/swigResqml2Include.i @@ -3566,63 +3566,923 @@ namespace RESQML2_NS * @returns The total count of cells in the grid. */ uint64_t getCellCount() const; - + + /** + * Gets the parent grid of this grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the parent window of this grid is neither an IJK, column + * layer nor cell window. + * + * @returns nullptr if this grid is not a child grid (not an LGR), otherwise the parent grid. + */ AbstractGridRepresentation* getParentGrid() const; + + /** + * Gets the count of child grids of this grid. + * + * @exception std::range_error If the count of child grids is strictly greater than unsigned + * int max. + * + * @returns The count of child grids of this grid. + */ uint64_t getChildGridCount() const; + + /** + * Gets a particular child grid of this grid. + * + * @exception std::out_of_range If index >= getChildGridCount(). + * + * @param index Zero-based index of the the child grid we look for. + * + * @returns The child grid at position @p index. + */ AbstractGridRepresentation* getChildGrid(uint64_t index) const; + + /** + * Indicates that this grid takes place into another unstructured parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If @p cellIndexCount is 0 or @p cellIndices is nullptr or + * @p parentGrid is nullptr. + * @exception std::invalid_argument If cellIndexCount > 1 and @p proxy is + * nullptr and no default HDF proxy is defined in the + * repository. + * + * @param [in] cellIndices Identifies the cells (of the parent grid) which are regridded. + * @param cellIndexCount Identifies the count of cells (of the parent grid) which are + * regridded. + * @param [in] parentGrid The parent grid which is regridded. + * @param [in,out] proxy (Optional) The HDF proxy where to store the numerical values. + * If nullptr (default), then the proxy will be the default + * proxy of the repository. This parameter is unused if @p + * cellIndexCount is 1 since no numerical value need to be store + * in an HDF proxy (pure XML). + */ void setParentWindow(uint64_t * cellIndices, uint64_t cellIndexCount, UnstructuredGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr); + + /** + * Indicates that this grid takes place into another column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If @p columnIndices is nullptr or @p columnIndexCount is + * 0 or + * @p childCellCountPerInterval is nullptr or @p + * parentCellCountPerInterval is nullptr or @p intervalCount + * is 0 or @p parentGrid is nullptr. + * @exception std::invalid_argument If an HDF proxy is required to store numerical values but + * @p proxy is nullptr and no default HDF proxy is defined + * in the repository. + * + * @param [in] columnIndices Identifies the columns (of the parent grid) which + * are regridded. The size is @p columnIndexCount. + * @param columnIndexCount Identifies the count of columns (of the parent + * grid) which are regridded. + * @param kLayerIndexRegridStart K index of the first K layer of all above parent + * grid columns to be regridded. + * @param [in] childCellCountPerInterval The count of cells per K interval in this (child) + * grid. The size is @p intervalCount. + * @param [in] parentCellCountPerInterval The count of cells per K interval in the parent + * grid. The size is @p intervalCount. + * @param intervalCount The count of intervals on K dimension. Intervals + * are portions of cells to regrid which does not + * overlap with each others. Intervals are the same + * for all the regridded columns. + * @param [in] parentGrid The parent grid which is regridded. + * @param [in,out] proxy (Optional) The HDF proxy where to store the + * numerical values. If nullptr (default), then the + * proxy will be the default proxy of the + * repository. This parameter is unused if no + * numerical value need to be store in an HDF proxy + * (pure XML). + * @param [in] childCellWeights (Optional) The weights that are proportional to + * the relative K sizes of child cells within each K + * interval. This is useful to set up child cells of + * different K sizes inside the intervals. The + * weights need not to be normalized. The count of + * double values must be equal to the count of all + * child cells on K dimension (sum of child cells + * per interval). Default value is nullptr. + */ void setParentWindow(unsigned int * columnIndices, uint64_t columnIndexCount, unsigned int kLayerIndexRegridStart, - unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, unsigned int intervalCount, + unsigned int * childCellCountPerInterval, unsigned int * parentCellCountPerInterval, uint64_t intervalCount, class AbstractColumnLayerGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * childCellWeights = nullptr); + + /** + * Indicates that this grid takes place into another IJK parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If @p childCellCountPerIInterval is nullptr or @p + * parentCellCountPerIInterval is nullptr or @p + * iIntervalCount is 0 or @p childCellCountPerJInterval is + * nullptr or @p parentCellCountPerJInterval is nullptr or + * @p jIntervalCount is 0 or @p childCellCountPerKInterval + * is nullptr or @p parentCellCountPerKInterval is nullptr + * or @p kIntervalCount is 0 or @p parentGrid is nullptr. + * @exception std::invalid_argument If an HDF proxy is required to store numerical values but + * @p proxy is nullptr and no default HDF proxy is defined + * in the repository. + * + * @param iCellIndexRegridStart I index of the first parent grid cell to be + * regridded. + * @param [in] childCellCountPerIInterval The count of cells per I interval in this (child) + * grid. The size is @p iIntervalCount. + * @param [in] parentCellCountPerIInterval The count of cells per I interval in the parent + * grid. The size is @p iIntervalCount. + * @param iIntervalCount The count of intervals on I dimension. Intervals + * are portions of cells to regrid which does not + * overlap with each others. + * @param jCellIndexRegridStart J index of the first parent grid cell to be + * regridded. + * @param [in] childCellCountPerJInterval The count of cells per J interval in this (child) + * grid. The size is @p jIntervalCount. + * @param [in] parentCellCountPerJInterval The count of cells per J interval in the parent + * grid. The size is @p jIntervalCount. + * @param jIntervalCount The count of intervals on J dimension. Intervals + * are portions of cells to regrid which does not + * overlap with each others. + * @param kCellIndexRegridStart K index of the first parent grid cell to be + * regridded. + * @param [in] childCellCountPerKInterval The count of cells per K interval in this (child) + * grid. The size is @p kIntervalCount. + * @param [in] parentCellCountPerKInterval The count of cells per K interval in the parent + * grid. The size is @p kIntervalCount. + * @param kIntervalCount The count of intervals on K dimension. Intervals + * are portions of cells to regrid which does not + * overlap with each others. + * @param [in] parentGrid The parent grid which is regridded. + * @param [in,out] proxy (Optional) The HDF proxy where to store the + * numerical values. If nullptr (default), then the + * proxy will be the default proxy of the + * repository. This parameter is unused if no + * numerical value need to be store in an HDF proxy + * (pure XML). + * @param [in] iChildCellWeights (Optional) The weights that are proportional to + * the relative I sizes of child cells within each I + * interval. This is useful to set up child cells of + * different I sizes inside the intervals. The + * weights need not to be normalized. The count of + * double values must be equal to the count of all + * child cells on I dimension (sum of child cells + * per interval). Default value is nullptr. + * @param [in] jChildCellWeights (Optional) The weights that are proportional to + * the relative J sizes of child cells within each J + * interval. This is useful to set up child cells of + * different J sizes inside the intervals. The + * weights need not to be normalized. The count of + * double values must be equal to the count of all + * child cells on J dimension (sum of child cells + * per interval). Default value is nullptr. + * @param [in] kChildCellWeights (Optional) The weights that are proportional to + * the relative K sizes of child cells within each K + * interval. This is useful to set up child cells of + * different K sizes inside the intervals. The + * weights need not to be normalized. The count of + * double values must be equal to the count of all + * child cells on K dimension (sum of child cells + * per interval). Default value is nullptr. + */ void setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int * childCellCountPerIInterval, unsigned int * parentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int * childCellCountPerJInterval, unsigned int * parentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int * childCellCountPerKInterval, unsigned int * parentCellCountPerKInterval, uint64_t kIntervalCount, AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * iChildCellWeights = nullptr, double * jChildCellWeights = nullptr, double * kChildCellWeights = nullptr); + + /** + * @brief Indicates that this grid takes place into another IJK parent grid. This method + * assumes that the count of cells per regrid interval is constant in both child and + * parent grids. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If @p constantChildCellCountPerIInterval is 0 or @p + * constantParentCellCountPerIInterval is 0 or @p + * iIntervalCount is 0 or + * @p constantChildCellCountPerJInterval is 0 or @p + * constantParentCellCountPerJInterval is 0 or @p + * jIntervalCount is 0 or + * @p constantChildCellCountPerKInterval is 0 or @p + * constantParentCellCountPerKInterval is 0 or @p + * kIntervalCount is 0 or + * @p parentGrid is nullptr. + * @exception std::invalid_argument If an HDF proxy is required to store numerical values but + * @p proxy is nullptr and no default HDF proxy is defined + * in the repository. + * + * @param iCellIndexRegridStart I index of the first parent grid cell to + * be regridded. + * @param constantChildCellCountPerIInterval The constant count of cells per I + * interval in this (child) grid. + * @param constantParentCellCountPerIInterval The constant count of cells per I + * interval in the parent grid. + * @param iIntervalCount The count of intervals on I dimension. + * Intervals are portions of cells to regrid + * which does not overlap with each others. + * @param jCellIndexRegridStart J index of the first parent grid cell to + * be regridded. + * @param constantChildCellCountPerJInterval The constant count of cells per J + * interval in this (child) grid. + * @param constantParentCellCountPerJInterval The constant count of cells per J + * interval in the parent grid. + * @param jIntervalCount The count of intervals on J dimension. + * Intervals are portions of cells to regrid + * which does not overlap with each others. + * @param kCellIndexRegridStart K index of the first parent grid cell to + * be regridded. + * @param constantChildCellCountPerKInterval The constant count of cells per K + * interval in this (child) grid. + * @param constantParentCellCountPerKInterval The constant count of cells per K + * interval in the parent grid. + * @param kIntervalCount The count of intervals on K dimension. + * Intervals are portions of cells to regrid + * which does not overlap with each others. + * @param [in] parentGrid The parent grid which is regridded. + * @param [in,out] proxy (Optional) The HDF proxy where to store + * the numerical values. If nullptr + * (default), then the proxy will be the + * default proxy of the repository. This + * parameter is unused if no numerical value + * need to be store in an HDF proxy (pure + * XML). + * @param [in] iChildCellWeights (Optional) The weights that are + * proportional to the relative I sizes of + * child cells within each I interval. This + * is useful to set up child cells of + * different I sizes inside the intervals. + * The weights need not to be normalized. + * The count of double values must be equal + * to the count of all child cells on I + * dimension + * (constantChildCellCountPerIInterval * + * iIntervalCount). Default value is + * nullptr. + * @param [in] jChildCellWeights (Optional) The weights that are + * proportional to the relative J sizes of + * child cells within each J interval. This + * is useful to set up child cells of + * different J sizes inside the intervals. + * The weights need not to be normalized. + * The count of double values must be equal + * to the count of all child cells on J + * dimension + * (constantChildCellCountPerJInterval + * * jIntervalCount). + * @param [in] kChildCellWeights (Optional) The weights that are + * proportional to the relative K sizes of + * child cells within each K interval. This + * is useful to set up child cells of + * different K sizes inside the intervals. + * The weights need not to be normalized. + * The count of double values must be equal + * to the count of all child cells on K + * dimension + * (constantChildCellCountPerKInterval + * * kIntervalCount). + */ void setParentWindow( - unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, unsigned int iIntervalCount, - unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, unsigned int jIntervalCount, - unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, unsigned int kIntervalCount, + unsigned int iCellIndexRegridStart, unsigned int constantChildCellCountPerIInterval, unsigned int constantParentCellCountPerIInterval, uint64_t iIntervalCount, + unsigned int jCellIndexRegridStart, unsigned int constantChildCellCountPerJInterval, unsigned int constantParentCellCountPerJInterval, uint64_t jIntervalCount, + unsigned int kCellIndexRegridStart, unsigned int constantChildCellCountPerKInterval, unsigned int constantParentCellCountPerKInterval, uint64_t kIntervalCount, AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * iChildCellWeights = nullptr, double * jChildCellWeights = nullptr, double * kChildCellWeights = nullptr); + + /** + * Indicates that this grid takes place into another IJK parent grid. This method assumes that + * there is only one regrid interval per dimension. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If @p iChildCellCount is 0 or @p iParentCellCount is 0 or + * @p jChildCellCount is 0 or @p jParentCellCount is 0 or @p + * kChildCellCount is 0 or @p kParentCellCount is 0 or @p + * parentGrid is nullptr. + * @exception std::invalid_argument If an HDF proxy is required to store numerical values but + * @p proxy is nullptr and no default HDF proxy is defined + * in the repository. + * + * @param iCellIndexRegridStart I index of the first parent grid cell to + * be regridded. + * @param iChildCellCount The count of cells for the unique I interval in this + * (child) grid. + * @param iParentCellCount The count of cells for the unique I interval in the + * parent grid. + * @param jCellIndexRegridStart J index of the first parent grid cell to + * be regridded. + * @param jChildCellCount The count of cells for the unique J interval in this + * (child) grid. + * @param jParentCellCount The count of cells for the unique J interval in the + * parent grid. + * @param kCellIndexRegridStart K index of the first parent grid cell to + * be regridded. + * @param kChildCellCount The count of cells for the unique K interval in this + * (child) grid. + * @param kParentCellCount The count of cells for the unique K interval in the + * parent grid. + * @param [in] parentGrid The parent grid which is regridded. + * @param [in,out] proxy (Optional) The HDF proxy where to store the numerical + * values. If nullptr (default), then the proxy will be + * the default proxy of the repository. This parameter + * is unused if no numerical value need to be store in + * an HDF proxy (pure XML). + * @param [in] iChildCellWeights (Optional) The weights that are proportional to the + * relative I sizes of child cells. This is useful to + * set up child cells of different I sizes inside the + * unique interval. The weights need not to be + * normalized. The count of double values must be equal + * to @p iChildCellCount. Default value is nullptr. + * @param [in] jChildCellWeights (Optional) The weights that are proportional to the + * relative J sizes of child cells. This is useful to + * set up child cells of different J sizes inside the + * unique interval. The weights need not to be + * normalized. The count of double values must be equal + * to @p jChildCellCount. Default value is nullptr. + * @param [in] kChildCellWeights (Optional) The weights that are proportional to the + * relative K sizes of child cells. This is useful to + * set up child cells of different K sizes inside the + * unique interval. The weights need not to be + * normalized. The count of double values must be equal + * to @p kChildCellCount. Default value is nullptr. + */ void setParentWindow( unsigned int iCellIndexRegridStart, unsigned int iChildCellCount, unsigned int iParentCellCount, unsigned int jCellIndexRegridStart, unsigned int jChildCellCount, unsigned int jParentCellCount, unsigned int kCellIndexRegridStart, unsigned int kChildCellCount, unsigned int kParentCellCount, AbstractIjkGridRepresentation* parentGrid, EML2_NS::AbstractHdfProxy * proxy = nullptr, double * iChildCellWeights = nullptr, double * jChildCellWeights = nullptr, double * kChildCellWeights = nullptr); - void setForcedNonRegridedParentCell(uint64_t * cellIndices, uint64_t cellIndexCount); - int64_t getParentCellIndexCount() const; + + /** + * When a parent windows has been defined, this method allows to force some parent cells to be + * noted as non regridded. It mainly allows non-rectangular local grids to be specified. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p cellIndices is nullptr or @p cellIndexCount is 0. + * @exception std::invalid_argument If an HDF proxy is required and no default HDF proxy is + * defined in the repository. + * + * @param [in] cellIndices The indices of the parent cells to be noted as non regridded. The + * size is @p cellIndexCount. + * @param cellIndexCount Number of cells to be noted as non regridded. + */ + void setForcedNonRegridedParentCell(uint64_t * cellIndices, uint64_t cellIndexCount); + + /** + * Set optional cell overlap information between the current grid (the child) and the parent + * grid. Use this data-object when the child grid has an explicitly defined geometry, and these + * relationships cannot be inferred from the regrid descriptions. An overlap volume information + * can be associated to each overlapping (parent cell, child cell) pair. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined. + * @exception std::invalid_argument If @p parentChildCellPairCount is 0 or + * @p parentChildCellPair is nullptr. + * @exception std::invalid_argument If no default HDF proxy is defined in the repository. + * + * @param parentChildCellPairCount Number of (parent cell, child cell) pairs that + * overlap. + * @param [in] parentChildCellPair The (parent cell index, child cell index) pair for + * each overlap. The size is 2 * + * parentChildCellPairCount. + * parentChildCellPair[2i] are parent cell indices + * and parentChildCellPair[2i+1] are child cell + * indices. + * @param volumeUom The volume unit of measure. + * @param [in] overlapVolumes (Optional) The overlapping volume for each (parent + * cell, child cell) that overlaps. Size is @p + * parentChildCellPairCount. Default value is nullptr. + */ + void setCellOverlap(uint64_t parentChildCellPairCount, uint64_t* parentChildCellPair, + const std::string& volumeUom, double* overlapVolumes = nullptr); + + /** + * Gets the count of parent grid cells which are regridded. Please only run this method for an + * unstructured parent grid. Please use regrid information for IJK parent grid or (regrid information + * and columIndexCount) for strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is not an unstructured parent window. + * @exception std::invalid_argument If the list of regridded cells is not stored in an HDF5 file. + * + * @returns The count of parent grid cells which are regridded. + */ + uint64_t getParentCellIndexCount() const; + + /** + * Gets the indices of the parent grid cells which are regridded. Please only run this method + * for an unstructured parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is not an unstructured parent window. + * @exception std::invalid_argument If the list of regridded cells is not stored in an HDF5 + * file. + * + * @param [out] parentCellIndices An array for receiving the regridded cells indices. This + * array must have been preallocated with a size of + * getParentCellIndexCount(). + */ void getParentCellIndices(uint64_t * parentCellIndices) const; - int64_t getParentColumnIndexCount() const; + + /** + * Gets the count of parent grid columns which are regridded. Please only run this method for a + * strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is not a column layer parent window. + * @exception std::invalid_argument If the list of regridded cells is not stored in an HDF5 + * file. + * + * @returns The count of parent grid columns which are regridded. + */ + uint64_t getParentColumnIndexCount() const; + + /** + * Gets the indices of the parent grid columns which are regridded. Please only run this method + * for a strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is not a column layer parent window. + * @exception std::invalid_argument If the list of regridded cells is not stored in an HDF5 + * file. + * + * @param [out] parentColumnIndices An array for collecting the regridded column indices. This + * array must have been preallocated with a size of + * getParentColumnIndexCount(). + */ void getParentColumnIndices(uint64_t * parentColumnIndices) const; + + /** + * Get the I, J or K index of the first parent grid cell to be regridded. Please only run this + * method for an IJK parent grid or a strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * + * @param dimension The dimension of the index we look for. It must be either 'i', 'j' or 'k' + * (upper or lower case) for an IJK parent grid or 'k' for a strict column + * layer parent grid. + * + * @returns The regrid start index on the parent grid in dimension @p dimension. + */ uint64_t getRegridStartIndexOnParentGrid(char dimension) const; + + /** + * Gets the count of intervals which are regridded on a particular dimension. Intervals are + * portions of cells to regrid which does not overlap with each others. Please only run this + * method for an IJK parent grid or a strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * + * @param dimension The dimension of the interval count we look for. It must be either 'i', + * 'j' or 'k' (upper or lower case) for an IJK parent grid or 'k' for a + * strict column layer parent grid. + * + * @returns The regrid interval count in dimension @p dimension. + */ uint64_t getRegridIntervalCount(char dimension) const; + + /** + * Checks if the cell count per interval (in the child grid or in the parent grid) is constant + * against a particular dimension. Intervals are portions of cells to regrid which does not + * overlap with each others. Please only run this method for an IJK parent grid or a strict + * column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * @exception std::invalid_argument If there exists no regrid interval in dimension @p + * dimension. + * + * @param dimension The dimension of the interval we look for. It must be either + * 'i', 'j' ou 'k' (upper or lower case) for an IJK parent grid + * or 'k' for a strict column layer parent grid. + * @param childVsParentCellCount If true, checks if the child cell count per interval is + * constant. If false, checks if the parent cell count per + * interval is constant. + * + * @returns True if the regrid cell count per interval is constant in dimension @p dimension, + * false if not. + */ bool isRegridCellCountPerIntervalConstant(char dimension, bool childVsParentCellCount) const; + + /** + * Gets the constant cell count per interval (in the child grid or in the parent grid) against a + * particular dimension. Intervals are portions of cells to regrid which does not overlap with + * each others. Please only run this method for an IJK parent grid or a strict column layer + * parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the cell count per interval in dimension @p dimension + * is neither an integer constant array nor a HDF5 integer + * array. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * @exception std::invalid_argument If there exists no regrid interval in dimension @p + * dimension. + * + * @param dimension The dimension of the interval we look for. It must be either + * 'i', 'j' ou 'k' (upper or lower case) for an IJK parent grid + * or 'k' for a strict column layer parent grid. + * @param childVsParentCellCount If true, gets the constant child cell count per interval. If + * false, gets the constant parent cell count per interval. + * + * @returns The regrid constant cell count per interval in dimension @p dimension. + */ uint64_t getRegridConstantCellCountPerInterval(char dimension, bool childVsParentCellCount) const; + + /** + * Gets the regrid cell count per interval (in the child grid or in the parent grid) against a + * particular dimension. Intervals are portions of cells to regrid which does not overlap with + * each others. Please only run this method for an IJK parent grid or a strict column layer + * parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the cell count per interval in dimension @p dimension + * is neither an integer constant array nor a HDF5 integer + * array. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * @exception std::invalid_argument If there exists no regrid interval in dimension @p + * dimension. + * + * @param dimension The dimension of the interval we look for. It must be + * either 'i', 'j' ou 'k' (upper or lower case) for an + * IJK parent grid or 'k' for a strict column layer + * parent grid. + * @param [in] childCellCountPerInterval An array to receive the regrid cell count per + * interval. It must have been preallocated with a size + * of getRegridIntervalCount(). + * @param childVsParentCellCount If true, gets the child cell count per interval. If + * false, gets the parent cell count per interval. + */ void getRegridCellCountPerInterval(char dimension, uint64_t * childCellCountPerInterval, bool childVsParentCellCount) const; + + /** + * Checks if regrid child cell weights have been defined for a given dimension. Please only run + * this method for an IJK parent grid or a strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * @exception std::invalid_argument If there exists no regrid interval in dimension @p + * dimension. + * + * @param dimension The dimension from which we look for regrid child cell weights. It must + * be either 'i', 'j' ou 'k' (upper or lower case) for an IJK parent grid or + * 'k' for a strict column layer parent grid. + * + * @returns True if regrid child cell weights have been defined in dimension @p dimension, false + * if not. + */ bool hasRegridChildCellWeights(char dimension) const; + + /** + * Gets the regrid child cell weights for a given dimension. Please only run this method for an + * IJK parent grid or a strict column layer parent grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined of if the defined + * parent window is neither an IJK nor a column layer parent + * window. + * @exception std::invalid_argument If @p dimension differs from 'i', 'j' or 'k' (upper or + * lower case) for an IJK parent window or if it differs + * from 'k' (upper or lower case) for a column layer parent + * window. + * @exception std::invalid_argument If there exists no regrid interval in dimension @p + * dimension. + * @exception std::invalid_argument If the regrid child cell weights in dimension @p + * dimension are not stored in an HDF5 file. + * + * @param dimension The dimension from which we look for regrid child cell + * weights. It must be either 'i', 'j' ou 'k' (upper or lower + * case) for an IJK parent grid or 'k' for a strict column layer + * parent grid. + * @param [in,out] childCellWeights An array for receiving the regrid child cell weights. It + * must have been preallocated with a size equal to the sum of + * regrid child cell count per interval (using + * getRegridCellCountPerInterval()). + */ void getRegridChildCellWeights(char dimension, double * childCellWeights) const; + + /** + * When a parent windows has been defined, this method checks if some parent cells have been + * noted to be forced not to be regridded. It mainly occurs in case of non-rectangular local + * grids. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no parent window is already defined. + * + * @returns True if some parent cells have been forced not to be regridded, false if not. + */ bool hasForcedNonRegridedParentCell() const; + /** + * Sets the stratigraphic organization interpretation which is associated to this grid + * representation. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If no default HDF proxy is defined in the repository. + * + * @param [in] stratiUnitIndices Index of the stratigraphic unit of a given stratigraphic + * column for each cell. Array length is the number of cells in + * the grid or the blocked well. + * @param nullValue The value which is used to tell the association between a + * cell and a stratigraphic unit is unavailable. + * @param [in] stratiOrgInterp The stratigraphic organization interpretation which is + * associated to this grid representation. + */ void setCellAssociationWithStratigraphicOrganizationInterpretation(int64_t * stratiUnitIndices, int64_t nullValue, RESQML2_NS::AbstractStratigraphicOrganizationInterpretation* stratiOrgInterp); + + /** + * Gets the stratigraphic organization interpretation which is associated to this grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * + * @returns nullptr if no stratigraphic organization interpretation is associated to this grid + * representation. Otherwise return the associated stratigraphic organization + * interpretation. + */ RESQML2_NS::AbstractStratigraphicOrganizationInterpretation* getStratigraphicOrganizationInterpretation() const; + + /** + * Queries if there exists some association between stratigraphic unit indices and the cells of + * this grid. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * + * @returns True if this grid representation has got some association between stratigraphic unit + * indices and cells. + */ bool hasCellStratigraphicUnitIndices() const; + + /** + * Gets the stratigraphic unit indices (regarding the associated stratigraphic organization + * interpretation) of each cell of this grid representation. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the associated stratigraphic unit indices are not + * stored in a HDF5 integer array. + * @exception std::invalid_argument If the cells of this grid are not associated with + * stratigraphic units indices. + * + * @param [out] stratiUnitIndices An array to receive the stratigraphic unit indices associated + * to the cells of this grid. It must be preallocated with a + * count equal to getCellCount(). It will be filled in with the + * stratigraphic unit indices ordered as grid cells are ordered. + * + * @returns The null value. The null value is used to tell the association between a cell and + * stratigraphic unit is unavailable. + */ int64_t getCellStratigraphicUnitIndices(int64_t * stratiUnitIndices); - + + /** + * Indicates whether this grid instance contains truncated pillars or not. + * + * @returns True if truncated pillars exist, false if not. + */ bool isTruncated() const; + + /** + * Gets the truncated face count. It does not include face of truncated cells which are not + * truncated. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * + * @returns The truncated face count. + */ uint64_t getTruncatedFaceCount() const; + + /** + * Gets all the node indices of the truncated faces. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the node indices of the truncated faces are not stored + * in a HDF5 integer array. + * @exception std::invalid_argument If this grid is not truncated. + * + * @param [out] nodeIndices An array to receive the node indices of the truncated faces. It must + * be preallocated with the last value returned by + * getCumulativeNodeCountOfTruncatedFaces(). + */ void getNodeIndicesOfTruncatedFaces(uint64_t * nodeIndices) const; + + /** + * Gets the cumulative node count per truncated face. First value is the count of nodes in the + * first face. Second value is the count of nodes in the first and in the second face. Third + * value is the count of nodes in the first and in the second and in the third face. Etc... The + * length of the output array is equal to getTruncatedFaceCount(). A single node count should be + * at least 3. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of nodes count per cells is + * constant (it is stored in a constant integer array). + * + * @param [in] nodeCountPerFace An array to receive the cumulative node count per truncated + * face. It must be preallocated with getTruncatedFaceCount() + * (equals to last value of + * getCumulativeTruncatedFaceCountPerTruncatedCell()) + */ void getCumulativeNodeCountPerTruncatedFace(uint64_t * nodeCountPerFace) const; + + /** + * Get the node count per truncated face. This method is less efficient than + * getCumulativeNodeCountPerTruncatedFace(). First value is the count of nodes in the first + * face. Second value is the count of nodes in the second face. etc... + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of nodes count per cells is + * constant (it is stored in a constant integer array). + * + * @param [out] nodeCountPerFace An array to receive the node count per truncated face. It + * must be preallocated with getTruncatedFaceCount() (equals to last + * value of getCumulativeTruncatedFaceCountPerTruncatedCell()). + */ void getNodeCountPerTruncatedFace(uint64_t * nodeCountPerFace) const; + + /** + * Gets the truncated cell count. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * + * @returns The truncated cell count. + */ uint64_t getTruncatedCellCount() const; + + /** + * Gets the parent cell index for each of the truncation cells. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the parent cell indices are stored neither in a HDF5 + * integer array nor in a constant integer array. + * @exception std::invalid_argument If this grid is not truncated. + * + * @param [out] cellIndices An array to receive the parent cell index of each truncation cell. It + * must be preallocated with getTruncatedCellCount. + */ void getTruncatedCellIndices(uint64_t* cellIndices) const; + + /** + * Gets all the truncated face indices of all the truncated cells. It does not get the non + * truncated face indices of a truncated cell. Please use + * getNonTruncatedFaceIndicesOfTruncatedCells() in addition to this method in order to get the + * full list of face indices for a truncated cell. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the truncated face indices are not stored in a HDF5 + * integer array. + * @exception std::invalid_argument If this grid is not truncated. + * + * @param [out] faceIndices An array to receive the truncated face indices of all the truncated + * cells. It must be preallocated with the last value returned by + * getCumulativeTruncatedFaceCountPerTruncatedCell() + */ void getTruncatedFaceIndicesOfTruncatedCells(uint64_t * faceIndices) const; + + /** + * Gets the cumulative truncated face count per truncated cell. It does not take into account + * the non truncated face of a truncated cell. First value is the count of faces in the first + * cell. Second value is the count of faces in the first and in the second cell. Third value is + * the count of faces in the first and in the second and in the third cell. Etc... The length of + * the output array is equal to getTruncatedCellCount(). A single face count should be at least + * 4. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of truncated faces count per + * cells is constant (it is stored in a constant integer + * array) while there is more than one cell in the grid. + * + * @param [out] cumulativeFaceCountPerCell An array to receive the cumulative truncated face + * count per truncated cell. It must be pre allocated + * with getTruncatedCellCount(). + */ void getCumulativeTruncatedFaceCountPerTruncatedCell(uint64_t * cumulativeFaceCountPerCell) const; + + /** + * Gets the truncated face count per truncated cell. This method is less efficient than + * getCumulativeTruncatedFaceCountPerTruncatedCell(). First value is the count of faces in the + * first cell. Second value is the count of faces in the second cell. etc... + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of faces count per cells is + * constant (it is stored in a constant integer array) while + * there is more than one cell in the grid. + * + * @param [out] faceCountPerCell An array to receive the truncated face count per truncated + * cell. It must be preallocated with getTruncatedCellCount() + */ void getTruncatedFaceCountPerTruncatedCell(uint64_t * faceCountPerCell) const; + + /** + * Gets all the non truncated face indices of all the truncated cells. It does not get the + * truncated face indices of a truncated cell. Please use + * getTruncatedFaceIndicesOfTruncatedCells() in addition to this method in order to get the full + * list of face indices for a truncated cell. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the non truncated face indices are not stored in a + * HDF5 integer array. + * @exception std::invalid_argument If this grid is not truncated. + * + * @param [out] faceIndices An array to receive the non truncated face indices of all the + * truncated cells.It must be pre allocated with the last value returned + * by getCumulativeNonTruncatedFaceCountPerTruncatedCell() + */ void getNonTruncatedFaceIndicesOfTruncatedCells(uint64_t * faceIndices) const; + + /** + * Get the cumulative non truncated face count per truncated cell. It does not take into account + * the truncated face indices of a truncated cell. First value is the count of faces in the + * first cell. Second value is the count of faces in the first and in the second cell. Third + * value is the count of faces in the first and in the second and in the third cell. Etc... + * Count of this array is equal to getTruncatedCellCount(). A single face count should be at + * least 4. + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of non truncated faces count per + * cells is constant (it is stored in a constant integer + * array) while there is more than one cell in the grid. + * + * @param [out] cumulativeFaceCountPerCell An array to receive the cumulative non truncated face + * count per truncated cell. It must be preallocated with + * getTruncatedCellCount() + */ void getCumulativeNonTruncatedFaceCountPerTruncatedCell(uint64_t * cumulativeFaceCountPerCell) const; + + /** + * Gets the non truncated face count per cell. This method is less efficient than + * getCumulativeNonTruncatedFaceCountPerTruncatedCell(). First value is the count of faces in + * the first cell. Second value is the count of faces in the second cell. etc... + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::invalid_argument If this grid is not truncated. + * @exception std::range_error If the cumulative length of non truncated faces count per + * cells is constant (it is stored in a constant integer + * array) while there is more than one cell in the grid. + * + * @param [out] faceCountPerCell An array to receive the non truncated face count per + * truncated cell. It must be pre allocated with + * getTruncatedCellCount() + */ void getNonTruncatedFaceCountPerTruncatedCell(uint64_t * faceCountPerCell) const; + + /** + * Retrieves the orientation of each truncated face (i.e. if each truncated face is right handed + * or not). + * + * @exception std::logic_error If the underlying gSOAP instance is not a RESQML2.0 one. + * @exception std::logic_error If the orientation of the truncated faces is neither + * stored in a HDF5 boolean array nor in a boolean constant + * array. + * @exception std::invalid_argument If this grid is not truncated. + * + * @param [out] cellFaceIsRightHanded An array to receive the orientation of truncated faces. + * Value '0' means left handed and value other than '0' + * means right handed. It must be preallocated with + * getTruncatedFaceCount() + */ void getTruncatedFaceIsRightHanded(uint8_t* cellFaceIsRightHanded) const; }; @@ -5093,7 +5953,7 @@ namespace RESQML2_NS * * @returns The element count per value. */ - unsigned int getElementCountPerValue() const; + uint64_t getElementCountPerValue() const; /** * Gets the kind of elements on which the property values are attached to