Skip to content

Commit

Permalink
GRIDEDIT-1546 Using the sample interpolator when getting the bathymet…
Browse files Browse the repository at this point in the history
…ry property
  • Loading branch information
BillSenior committed Nov 27, 2024
1 parent 0590970 commit b5149cf
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 98 deletions.
3 changes: 2 additions & 1 deletion libs/MeshKernel/include/MeshKernel/Mesh2D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ namespace meshkernel
enum class Property
{
Orthogonality = 0,
EdgeLength = 1
EdgeLength = 1,
Bathymetry = 2
};

/// @brief Default destructor
Expand Down
12 changes: 0 additions & 12 deletions libs/MeshKernelApi/include/MeshKernelApi/MeshKernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1152,18 +1152,6 @@ namespace meshkernelapi
const GeometryList& selectingPolygon,
const GeometryList& landBoundaries);

/// @brief Get the bathymetry data
/// @param[in] meshKernelId The id of the mesh state
/// @param[out] sampleData The mesh2d bathymetry data
/// @returns Error code
MKERNEL_API int mkernel_mesh2d_get_bathymetry_data(int meshKernelId, GeometryList& sampleData);

/// @brief get the bathymetry data size
/// @param[in] meshKernelId The id of the mesh state
/// @param[out] sampleDataSize The mesh2d bathymetry data size
/// @returns Error code
MKERNEL_API int mkernel_mesh2d_get_bathymetry_dimension(int meshKernelId, int& sampleDataSize);

/// @brief Gets the closest mesh2d node coordinates to a point, searching within a radius.
/// @param[in] meshKernelId Id of the grid state
/// @param[in] xCoordinateIn The x coordinate of the node to insert
Expand Down
22 changes: 22 additions & 0 deletions libs/MeshKernelApi/include/MeshKernelApi/PropertyCalculator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ namespace meshkernelapi
/// @brief Destructor
virtual ~PropertyCalculator() = default;

/// @brief Determine is the calculator can compute the desired results correctly.
///
/// This has a default implementation returning true.
virtual bool IsValid(const MeshKernelState& state) const;

/// @brief Calculate the property
virtual void Calculate(const MeshKernelState& state, const GeometryList& geometryList) const = 0;

Expand Down Expand Up @@ -69,4 +74,21 @@ namespace meshkernelapi
int Size(const MeshKernelState& state) const override;
};

/// @brief Interpolate the depths at the mesh node points.
class DepthSamplePropertyCalculator : public PropertyCalculator
{
public:
/// @brief The name of the sample data
static const std::string SampleName;

/// @brief Determine is the calculator can interpolate depth values correctly
bool IsValid(const MeshKernelState& state) const override;

/// @brief Calculate the edge-length for a mesh
void Calculate(const MeshKernelState& state, const GeometryList& geometryList) const override;

/// @brief Determine the size of the edge-length vector required
int Size(const MeshKernelState& state) const override;
};

} // namespace meshkernelapi
74 changes: 5 additions & 69 deletions libs/MeshKernelApi/src/MeshKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ namespace meshkernelapi
propertyId = static_cast<int>(meshkernel::Mesh2D::Property::EdgeLength);
propertyMap.emplace(propertyId, std::make_unique<EdgeLengthPropertyCalculator>());

propertyId = static_cast<int>(meshkernel::Mesh2D::Property::Bathymetry);
propertyMap.emplace(propertyId, std::make_unique<DepthSamplePropertyCalculator>());

return propertyMap;
}

Expand Down Expand Up @@ -531,73 +534,6 @@ namespace meshkernelapi
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_get_bathymetry_data(int meshKernelId, GeometryList& sampleData)
{
lastExitCode = meshkernel::ExitCode::Success;
try
{
if (!meshKernelState.contains(meshKernelId))
{
throw meshkernel::MeshKernelError("The selected mesh kernel id does not exist.");
}

if (meshKernelState[meshKernelId].m_mesh2d == nullptr)
{
throw meshkernel::MeshKernelError("The selected mesh2d does not exist.");
}

if (meshKernelState[meshKernelId].m_sampleInterpolator == nullptr)
{
throw meshkernel::MeshKernelError("The selected sample interpolator does not exist.");
}

if (sampleData.num_coordinates != static_cast<int>(meshKernelState[meshKernelId].m_mesh2d->GetNumNodes()))
{
throw meshkernel::MeshKernelError("GeometryList has wrong dimensions {} /= {}",
sampleData.num_coordinates,
meshKernelState[meshKernelId].m_mesh2d->GetNumNodes());
}

std::span<double> interpolatedSampleData(sampleData.values, sampleData.num_coordinates);
meshKernelState[meshKernelId].m_sampleInterpolator->Interpolate("depth", meshKernelState[meshKernelId].m_mesh2d->Nodes(), interpolatedSampleData);
}
catch (...)
{
lastExitCode = HandleException();
}
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_get_bathymetry_dimension(int meshKernelId, int& sampleDataSize)
{
lastExitCode = meshkernel::ExitCode::Success;
sampleDataSize = -1;
try
{
if (!meshKernelState.contains(meshKernelId))
{
throw meshkernel::MeshKernelError("The selected mesh kernel id does not exist.");
}

if (meshKernelState[meshKernelId].m_sampleInterpolator == nullptr)
{
throw meshkernel::MeshKernelError("The sample interpolator does not exist.");
}

if (!meshKernelState[meshKernelId].m_sampleInterpolator->Contains("depth"))
{
throw meshkernel::MeshKernelError("The sample interpolator does not contains depth values.");
}

sampleDataSize = static_cast<int>(meshKernelState[meshKernelId].m_mesh2d->GetNumNodes());
}
catch (...)
{
lastExitCode = HandleException();
}
return lastExitCode;
}

MKERNEL_API int mkernel_mesh2d_snap_to_landboundary(int meshKernelId, const GeometryList& selectingPolygon, const GeometryList& landBoundaries)
{
lastExitCode = meshkernel::ExitCode::Success;
Expand Down Expand Up @@ -1621,12 +1557,12 @@ namespace meshkernelapi
throw meshkernel::MeshKernelError("The selected mesh kernel id does not exist.");
}

if (const auto& mesh2d = meshKernelState.at(meshKernelId).m_mesh2d; !mesh2d || mesh2d->GetNumNodes() <= 0)
if (const auto& mesh2d = meshKernelState.at(meshKernelId).m_mesh2d; mesh2d == nullptr || mesh2d->GetNumNodes() <= 0)
{
return lastExitCode;
}

if (propertyCalculators.contains(propertyValue) && propertyCalculators[propertyValue] != nullptr)
if (propertyCalculators.contains(propertyValue) && propertyCalculators[propertyValue] != nullptr && propertyCalculators[propertyValue]->IsValid(meshKernelState.at(meshKernelId)))
{
propertyCalculators[propertyValue]->Calculate(meshKernelState.at(meshKernelId), geometryList);
}
Expand Down
36 changes: 34 additions & 2 deletions libs/MeshKernelApi/src/PropertyCalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

#include <algorithm>

bool meshkernelapi::PropertyCalculator::IsValid(const MeshKernelState& state [[maybe_unused]]) const
{
return true;
}

void meshkernelapi::OrthogonalityPropertyCalculator::Calculate(const MeshKernelState& state, const GeometryList& geometryList) const
{
std::vector<double> values = state.m_mesh2d->GetOrthogonality();

if (static_cast<size_t>(geometryList.num_coordinates) < values.size())
{
throw meshkernel::MeshKernelError("GeometryList with wrong dimensions");
throw meshkernel::ConstraintError("GeometryList with wrong dimensions, {} must be greater than or equal to {}",
geometryList.num_coordinates, Size(state));
}

std::ranges::copy(values, geometryList.values);
Expand All @@ -26,7 +32,8 @@ void meshkernelapi::EdgeLengthPropertyCalculator::Calculate(const MeshKernelStat

if (static_cast<size_t>(geometryList.num_coordinates) < values.size())
{
throw meshkernel::MeshKernelError("GeometryList with wrong dimensions");
throw meshkernel::ConstraintError("GeometryList with wrong dimensions, {} must be greater than or equal to {}",
geometryList.num_coordinates, Size(state));
}

std::ranges::copy(values, geometryList.values);
Expand All @@ -36,3 +43,28 @@ int meshkernelapi::EdgeLengthPropertyCalculator::Size(const MeshKernelState& sta
{
return static_cast<int>(state.m_mesh2d->GetNumEdges());
}

const std::string meshkernelapi::DepthSamplePropertyCalculator::SampleName = "depth";

bool meshkernelapi::DepthSamplePropertyCalculator::IsValid(const MeshKernelState& state) const
{
return state.m_sampleInterpolator != nullptr;
}

void meshkernelapi::DepthSamplePropertyCalculator::Calculate(const MeshKernelState& state, const GeometryList& geometryList) const
{

if (geometryList.num_coordinates < Size(state))
{
throw meshkernel::ConstraintError("GeometryList with wrong dimensions, {} must be greater than or equal to {}",
geometryList.num_coordinates, Size(state));
}

std::span<double> interpolatedSampleData(geometryList.values, geometryList.num_coordinates);
state.m_sampleInterpolator->Interpolate(SampleName, state.m_mesh2d->Nodes(), interpolatedSampleData);
}

int meshkernelapi::DepthSamplePropertyCalculator::Size(const MeshKernelState& state) const
{
return static_cast<int>(state.m_mesh2d->GetNumNodes());
}
Loading

0 comments on commit b5149cf

Please sign in to comment.