|
|
|
@ -1,5 +1,8 @@
|
|
|
|
|
#pragma once |
|
|
|
|
#include "basedata.h" |
|
|
|
|
#include "geohelpers.h" |
|
|
|
|
|
|
|
|
|
using michlib::M_PI; |
|
|
|
|
|
|
|
|
|
class Simple2DData: public BaseData |
|
|
|
|
{ |
|
|
|
@ -7,6 +10,8 @@ class Simple2DData: public BaseData
|
|
|
|
|
size_t nx = 0, ny = 0; |
|
|
|
|
real xstep = 0.0, ystep = 0.0; |
|
|
|
|
|
|
|
|
|
static real D(real lon1, real lat1, real lon2, real lat2) { return michlib::GCD(lon1 * M_PI / 180.0, lat1 * M_PI / 180.0, lon2 * M_PI / 180.0, lat2 * M_PI / 180.0) * 6371.0; } |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
using BaseData::IsFill; |
|
|
|
|
using BaseData::V; |
|
|
|
@ -59,12 +64,66 @@ class Simple2DData: public BaseData
|
|
|
|
|
|
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
real dVdX(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy)) return Fillval(); |
|
|
|
|
if(ix == 0 || IsFill(ix - 1, iy)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix + 1, iy)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix + 1, iy) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix + 1, iy), Lat(ix + 1, iy)); |
|
|
|
|
} |
|
|
|
|
if(ix == nx - 1 || IsFill(ix + 1, iy)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix - 1, iy)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy) - V(ix - 1, iy)) / D(Lon(ix - 1, iy), Lat(ix - 1, iy), Lon(ix, iy), Lat(ix, iy)); |
|
|
|
|
} |
|
|
|
|
return 0.5 * ((V(ix + 1, iy) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix + 1, iy), Lat(ix + 1, iy)) + |
|
|
|
|
(V(ix, iy) - V(ix - 1, iy)) / D(Lon(ix - 1, iy), Lat(ix - 1, iy), Lon(ix, iy), Lat(ix, iy))); |
|
|
|
|
} |
|
|
|
|
real dVdY(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy)) return Fillval(); |
|
|
|
|
|
|
|
|
|
if(iy == 0 || IsFill(ix, iy - 1)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy + 1)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy + 1) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix, iy + 1), Lat(ix, iy + 1)); |
|
|
|
|
} |
|
|
|
|
if(iy == ny - 1 || IsFill(ix, iy + 1)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy - 1)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy) - V(ix, iy - 1)) / D(Lon(ix, iy - 1), Lat(ix, iy - 1), Lon(ix, iy), Lat(ix, iy)); |
|
|
|
|
} |
|
|
|
|
return 0.5 * ((V(ix, iy + 1) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix, iy + 1), Lat(ix, iy + 1)) + |
|
|
|
|
(V(ix, iy) - V(ix, iy - 1)) / D(Lon(ix, iy - 1), Lat(ix, iy - 1), Lon(ix, iy), Lat(ix, iy))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
real Grad(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
real grx = dVdX(ix, iy); |
|
|
|
|
real gry = dVdY(ix, iy); |
|
|
|
|
if(grx == Fillval() || gry == Fillval()) return Fillval(); |
|
|
|
|
return michlib::Hypot(grx, gry); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
real Grad(size_t i) const { return Grad(i % Nx(), i / Nx()); } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class Rect2DData: public BaseData |
|
|
|
|
{ |
|
|
|
|
std::vector<real> lon, lat; |
|
|
|
|
|
|
|
|
|
static real D(real lon1, real lat1, real lon2, real lat2) { return michlib::GCD(lon1 * M_PI / 180.0, lat1 * M_PI / 180.0, lon2 * M_PI / 180.0, lat2 * M_PI / 180.0) * 6371.0; } |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
using BaseData::IsFill; |
|
|
|
|
using BaseData::V; |
|
|
|
@ -92,4 +151,56 @@ class Rect2DData: public BaseData
|
|
|
|
|
|
|
|
|
|
real Ix2Lon(size_t ix) const { return lon[ix]; } |
|
|
|
|
real Iy2Lat(size_t iy) const { return lat[iy]; } |
|
|
|
|
|
|
|
|
|
real dVdX(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy)) return Fillval(); |
|
|
|
|
if(ix == 0 || IsFill(ix - 1, iy)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix + 1, iy)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix + 1, iy) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix + 1, iy), Lat(ix + 1, iy)); |
|
|
|
|
} |
|
|
|
|
if(ix == Nx() - 1 || IsFill(ix + 1, iy)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix - 1, iy)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy) - V(ix - 1, iy)) / D(Lon(ix - 1, iy), Lat(ix - 1, iy), Lon(ix, iy), Lat(ix, iy)); |
|
|
|
|
} |
|
|
|
|
return 0.5 * ((V(ix + 1, iy) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix + 1, iy), Lat(ix + 1, iy)) + |
|
|
|
|
(V(ix, iy) - V(ix - 1, iy)) / D(Lon(ix - 1, iy), Lat(ix - 1, iy), Lon(ix, iy), Lat(ix, iy))); |
|
|
|
|
} |
|
|
|
|
real dVdY(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy)) return Fillval(); |
|
|
|
|
|
|
|
|
|
if(iy == 0 || IsFill(ix, iy - 1)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy + 1)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy + 1) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix, iy + 1), Lat(ix, iy + 1)); |
|
|
|
|
} |
|
|
|
|
if(iy == Ny() - 1 || IsFill(ix, iy + 1)) |
|
|
|
|
{ |
|
|
|
|
if(IsFill(ix, iy - 1)) |
|
|
|
|
return Fillval(); |
|
|
|
|
else |
|
|
|
|
return (V(ix, iy) - V(ix, iy - 1)) / D(Lon(ix, iy - 1), Lat(ix, iy - 1), Lon(ix, iy), Lat(ix, iy)); |
|
|
|
|
} |
|
|
|
|
return 0.5 * ((V(ix, iy + 1) - V(ix, iy)) / D(Lon(ix, iy), Lat(ix, iy), Lon(ix, iy + 1), Lat(ix, iy + 1)) + |
|
|
|
|
(V(ix, iy) - V(ix, iy - 1)) / D(Lon(ix, iy - 1), Lat(ix, iy - 1), Lon(ix, iy), Lat(ix, iy))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
real Grad(size_t ix, size_t iy) const |
|
|
|
|
{ |
|
|
|
|
real grx = dVdX(ix, iy); |
|
|
|
|
real gry = dVdY(ix, iy); |
|
|
|
|
if(grx == Fillval() || gry == Fillval()) return Fillval(); |
|
|
|
|
return michlib::Hypot(grx, gry); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
real Grad(size_t i) const { return Grad(i % Nx(), i / Nx()); } |
|
|
|
|
}; |
|
|
|
|