/****************************************************************************** * Project: PROJ * Purpose: Grid management * Author: Even Rouault, * ****************************************************************************** * Copyright (c) 2019, Even Rouault, * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #ifndef GRIDS_HPP_INCLUDED #define GRIDS_HPP_INCLUDED #include #include #include "proj.h" #include "proj/util.hpp" NS_PROJ_START struct ExtentAndRes { bool isGeographic; // whether extent and resolutions are in a geographic or // projected CRS double west; // in radian for geographic, in CRS units otherwise double south; // in radian for geographic, in CRS units otherwise double east; // in radian for geographic, in CRS units otherwise double north; // in radian for geographic, in CRS units otherwise double resX; // in radian for geographic, in CRS units otherwise double resY; // in radian for geographic, in CRS units otherwise bool fullWorldLongitude() const; bool contains(const ExtentAndRes &other) const; bool intersects(const ExtentAndRes &other) const; }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL Grid { protected: std::string m_name; int m_width; int m_height; ExtentAndRes m_extent; Grid(const std::string &nameIn, int widthIn, int heightIn, const ExtentAndRes &extentIn); public: PROJ_FOR_TEST virtual ~Grid(); PROJ_FOR_TEST int width() const { return m_width; } PROJ_FOR_TEST int height() const { return m_height; } PROJ_FOR_TEST const ExtentAndRes &extentAndRes() const { return m_extent; } PROJ_FOR_TEST const std::string &name() const { return m_name; } PROJ_FOR_TEST virtual bool isNullGrid() const { return false; } PROJ_FOR_TEST virtual bool hasChanged() const = 0; }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL VerticalShiftGrid : public Grid { protected: std::vector> m_children{}; public: PROJ_FOR_TEST VerticalShiftGrid(const std::string &nameIn, int widthIn, int heightIn, const ExtentAndRes &extentIn); PROJ_FOR_TEST ~VerticalShiftGrid() override; PROJ_FOR_TEST const VerticalShiftGrid *gridAt(double lon, double lat) const; PROJ_FOR_TEST virtual bool isNodata(float /*val*/, double /* multiplier */) const = 0; // x = 0 is western-most column, y = 0 is southern-most line PROJ_FOR_TEST virtual bool valueAt(int x, int y, float &out) const = 0; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0; }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL VerticalShiftGridSet { protected: std::string m_name{}; std::string m_format{}; std::vector> m_grids{}; VerticalShiftGridSet(); public: PROJ_FOR_TEST virtual ~VerticalShiftGridSet(); PROJ_FOR_TEST static std::unique_ptr open(PJ_CONTEXT *ctx, const std::string &filename); PROJ_FOR_TEST const std::string &name() const { return m_name; } PROJ_FOR_TEST const std::string &format() const { return m_format; } PROJ_FOR_TEST const std::vector> & grids() const { return m_grids; } PROJ_FOR_TEST const VerticalShiftGrid *gridAt(double lon, double lat) const; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx); PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx); }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL HorizontalShiftGrid : public Grid { protected: std::vector> m_children{}; public: PROJ_FOR_TEST HorizontalShiftGrid(const std::string &nameIn, int widthIn, int heightIn, const ExtentAndRes &extentIn); PROJ_FOR_TEST ~HorizontalShiftGrid() override; PROJ_FOR_TEST const HorizontalShiftGrid *gridAt(double lon, double lat) const; // x = 0 is western-most column, y = 0 is southern-most line PROJ_FOR_TEST virtual bool valueAt(int x, int y, bool compensateNTConvention, float &lonShift, float &latShift) const = 0; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0; }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL HorizontalShiftGridSet { protected: std::string m_name{}; std::string m_format{}; std::vector> m_grids{}; HorizontalShiftGridSet(); public: PROJ_FOR_TEST virtual ~HorizontalShiftGridSet(); PROJ_FOR_TEST static std::unique_ptr open(PJ_CONTEXT *ctx, const std::string &filename); PROJ_FOR_TEST const std::string &name() const { return m_name; } PROJ_FOR_TEST const std::string &format() const { return m_format; } PROJ_FOR_TEST const std::vector> & grids() const { return m_grids; } PROJ_FOR_TEST const HorizontalShiftGrid *gridAt(double lon, double lat) const; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx); PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx); }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL GenericShiftGrid : public Grid { protected: std::vector> m_children{}; public: PROJ_FOR_TEST GenericShiftGrid(const std::string &nameIn, int widthIn, int heightIn, const ExtentAndRes &extentIn); PROJ_FOR_TEST ~GenericShiftGrid() override; PROJ_FOR_TEST const GenericShiftGrid *gridAt(double x, double y) const; PROJ_FOR_TEST virtual std::string unit(int sample) const = 0; PROJ_FOR_TEST virtual std::string description(int sample) const = 0; PROJ_FOR_TEST virtual std::string metadataItem(const std::string &key, int sample = -1) const = 0; PROJ_FOR_TEST virtual int samplesPerPixel() const = 0; // x = 0 is western-most column, y = 0 is southern-most line PROJ_FOR_TEST virtual bool valueAt(int x, int y, int sample, float &out) const = 0; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx) = 0; }; // --------------------------------------------------------------------------- class PROJ_GCC_DLL GenericShiftGridSet { protected: std::string m_name{}; std::string m_format{}; std::vector> m_grids{}; GenericShiftGridSet(); public: PROJ_FOR_TEST virtual ~GenericShiftGridSet(); PROJ_FOR_TEST static std::unique_ptr open(PJ_CONTEXT *ctx, const std::string &filename); PROJ_FOR_TEST const std::string &name() const { return m_name; } PROJ_FOR_TEST const std::string &format() const { return m_format; } PROJ_FOR_TEST const std::vector> & grids() const { return m_grids; } PROJ_FOR_TEST const GenericShiftGrid *gridAt(double x, double y) const; PROJ_FOR_TEST virtual void reassign_context(PJ_CONTEXT *ctx); PROJ_FOR_TEST virtual bool reopen(PJ_CONTEXT *ctx); }; // --------------------------------------------------------------------------- typedef std::vector> ListOfHGrids; typedef std::vector> ListOfVGrids; typedef std::vector> ListOfGenericGrids; ListOfVGrids pj_vgrid_init(PJ *P, const char *grids); ListOfHGrids pj_hgrid_init(PJ *P, const char *grids); ListOfGenericGrids pj_generic_grid_init(PJ *P, const char *grids); PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp); double pj_vgrid_value(PJ *P, const ListOfVGrids &, PJ_LP lp, double vmultiplier); PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp, PJ_DIRECTION direction); const GenericShiftGrid *pj_find_generic_grid(const ListOfGenericGrids &grids, const PJ_LP &input, GenericShiftGridSet *&gridSetOut); bool pj_bilinear_interpolation_three_samples( PJ_CONTEXT *ctx, const GenericShiftGrid *grid, const PJ_LP &lp, int idx1, int idx2, int idx3, double &v1, double &v2, double &v3, bool &must_retry); NS_PROJ_END #endif // GRIDS_HPP_INCLUDED