Skip to content

Commit

Permalink
eckit::geo iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
pmaciel committed Nov 28, 2024
1 parent af10b60 commit d5f6316
Show file tree
Hide file tree
Showing 10 changed files with 1,377 additions and 3 deletions.
12 changes: 10 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ ecbuild_add_option( FEATURE GEOGRAPHY
DESCRIPTION "Support for Geoiterator and nearest neighbour"
DEFAULT ON )

ecbuild_add_option( FEATURE ECKIT_GEO
DESCRIPTION "Support for Geoiterator and nearest neighbour (additional backend)"
CONDITION ENABLE_GEOGRAPHY
DEFAULT OFF )
if( ECKIT_GEO AND NOT TARGET eckit_geo )
find_library(ECKIT_GEO_LIB NAMES eckit_geo REQUIRED)
endif()

ecbuild_add_option( FEATURE JPG
DESCRIPTION "Support for JPG decoding/encoding"
DEFAULT ON )
Expand Down Expand Up @@ -485,7 +493,7 @@ ecbuild_pkgconfig(
IGNORE_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS} ${NETCDF_INCLUDE_DIRS}
VARIABLES HAVE_MEMFS HAVE_GEOGRAPHY HAVE_JPEG HAVE_LIBJASPER HAVE_LIBOPENJPEG
HAVE_ECCODES_THREADS HAVE_ECCODES_OMP_THREADS
HAVE_NETCDF HAVE_FORTRAN HAVE_PNG HAVE_AEC
HAVE_NETCDF HAVE_FORTRAN HAVE_PNG HAVE_AEC HAVE_ECKIT_GEO
)
if( HAVE_FORTRAN )
ecbuild_pkgconfig(
Expand All @@ -497,7 +505,7 @@ if( HAVE_FORTRAN )
${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS} ${NETCDF_INCLUDE_DIRS}
VARIABLES HAVE_MEMFS HAVE_GEOGRAPHY HAVE_JPEG HAVE_LIBJASPER HAVE_LIBOPENJPEG
HAVE_ECCODES_THREADS HAVE_ECCODES_OMP_THREADS
HAVE_NETCDF HAVE_PNG HAVE_AEC
HAVE_NETCDF HAVE_PNG HAVE_AEC HAVE_ECKIT_GEO
)
endif()

Expand Down
1 change: 1 addition & 0 deletions eccodes_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
#cmakedefine HAVE_NETCDF

#cmakedefine HAVE_GEOGRAPHY
#cmakedefine HAVE_ECKIT_GEO
#cmakedefine HAVE_MEMFS
#cmakedefine HAVE_FORTRAN

Expand Down
9 changes: 9 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ if( HAVE_MEMFS )
list(APPEND ECCODES_EXTRA_LIBRARIES eccodes_memfs)
endif()

if( eccodes_HAVE_GEOGRAPHY AND eccodes_HAVE_ECKIT_GEO )
list( APPEND eccodes_src_files
eccodes/geo/GeoIterator.cc
eccodes/geo/GeoIterator.h
eccodes/geo/GribSpec.cc
eccodes/geo/GribSpec.h )
list( APPEND ECCODES_EXTRA_LIBRARIES eckit_geo )
endif()

ecbuild_add_library( TARGET eccodes
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/grib_api_version.cc
# griby.cc gribl.cc
Expand Down
104 changes: 104 additions & 0 deletions src/eccodes/geo/GeoIterator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* (C) Copyright 2024- ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
*/


#include "eccodes/geo/GeoIterator.h"

#include "eckit/exception/Exceptions.h"

#include "eccodes/geo/GribSpec.h"


namespace eccodes::geo
{


GeoIterator::GeoIterator(grib_handle* h, unsigned long flags) :
spec_(new GribSpec(h)), grid_(eckit::geo::GridFactory::build(*spec_)), iter_(grid_->cbegin().release()), end_(grid_->cend().release())
{
h_ = h;
class_name_ = "geo_iterator";
flags_ = flags;
Assert(h_ != nullptr);

CODES_CHECK(codes_get_size(h_, "values", &nv_), "");
Assert(nv_ > 0);

data_ = (flags_ & GRIB_GEOITERATOR_NO_VALUES) ? nullptr : static_cast<double*>(grib_context_malloc(h_->context, nv_ * sizeof(double)));
Assert(data_ != nullptr);

auto size = nv_;
CODES_CHECK(codes_get_double_array(h_, "values", data_, &size), "");
Assert(nv_ == size);
}


int GeoIterator::init(grib_handle*, grib_arguments*)
{
NOTIMP;
}


int GeoIterator::next(double* lat, double* lon, double* val) const
{
if (iter_ == end_) {
return 0; // (false)
}

const auto p = *iter_;
const auto& q = std::get<eckit::geo::PointLonLat>(p);

*lat = q.lat;
*lon = q.lon;
if (val != nullptr && data_ != nullptr) {
*val = data_[iter_->index()];
}

++iter_;
return 1; // (true)
}


int GeoIterator::previous(double*, double*, double*) const
{
return GRIB_NOT_IMPLEMENTED;
}


int GeoIterator::reset()
{
iter_.reset(grid_->cbegin().release());
return GRIB_SUCCESS;
}


int GeoIterator::destroy()
{
if (data_ != nullptr) {
grib_context_free(h_->context, data_);
}
return Iterator::destroy();
}


bool GeoIterator::has_next() const
{
return iter_ != end_;
}


geo_iterator::Iterator*
GeoIterator::create() const
{
return new GeoIterator{ h_, flags_ };
}


} // namespace eccodes::geo
51 changes: 51 additions & 0 deletions src/eccodes/geo/GeoIterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* (C) Copyright 2024- ECMWF.
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
*/


#pragma once

#include <memory>

#include "eckit/geo/Grid.h"

// eccodes macros conflict with eckit
#ifdef Assert
#undef Assert
#endif

#include "geo_iterator/grib_iterator.h"


namespace eccodes::geo
{


class GeoIterator : public geo_iterator::Iterator
{
public:
explicit GeoIterator(grib_handle*, unsigned long flags);

private:
std::unique_ptr<const eckit::geo::Spec> spec_;
std::unique_ptr<const eckit::geo::Grid> grid_;
mutable eckit::geo::Grid::Iterator iter_;
eckit::geo::Grid::Iterator end_;

int init(grib_handle*, grib_arguments*) override;
int next(double* lat, double* lon, double* val) const override;
int previous(double* lat, double* lon, double* val) const override;
int reset() override;
int destroy() override;
bool has_next() const override;
geo_iterator::Iterator* create() const override;
};


} // namespace eccodes::geo
Loading

0 comments on commit d5f6316

Please sign in to comment.