Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OGR 4 : * Purpose: WKB geometry related methods 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2022, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #ifndef OGR_WKB_H_INCLUDED 14 : #define OGR_WKB_H_INCLUDED 15 : 16 : #include <cstdint> 17 : 18 : #include "cpl_port.h" 19 : #include "ogr_core.h" 20 : 21 : #include <vector> 22 : 23 : bool CPL_DLL OGRWKBGetGeomType(const GByte *pabyWkb, size_t nWKBSize, 24 : bool &bNeedSwap, uint32_t &nType); 25 : bool OGRWKBPolygonGetArea(const GByte *&pabyWkb, size_t &nWKBSize, 26 : double &dfArea); 27 : bool OGRWKBMultiPolygonGetArea(const GByte *&pabyWkb, size_t &nWKBSize, 28 : double &dfArea); 29 : 30 : bool CPL_DLL OGRWKBGetBoundingBox(const GByte *pabyWkb, size_t nWKBSize, 31 : OGREnvelope3D &sEnvelope); 32 : 33 : bool CPL_DLL OGRWKBGetBoundingBox(const GByte *pabyWkb, size_t nWKBSize, 34 : OGREnvelope &sEnvelope); 35 : 36 : bool CPL_DLL OGRWKBIntersectsPessimistic(const GByte *pabyWkb, size_t nWKBSize, 37 : const OGREnvelope &sEnvelope); 38 : 39 : void CPL_DLL OGRWKBFixupCounterClockWiseExternalRing(GByte *pabyWkb, 40 : size_t nWKBSize); 41 : 42 : /** Modifies a PostGIS-style Extended WKB geometry to a regular WKB one. 43 : * pabyEWKB will be modified in place. 44 : * The return value will be either at the beginning of pabyEWKB or 4 bytes 45 : * later, and thus has the same lifetime of pabyEWKB. The function returns in 46 : * nWKBSizeOut the length of the returned WKB pointer. pnSRIDOut may be NULL, or 47 : * if not NULL, the function will return in it the SRID, if present, or INT_MIN 48 : * if not present. 49 : */ 50 : const GByte CPL_DLL *WKBFromEWKB(GByte *pabyEWKB, size_t nEWKBSize, 51 : size_t &nWKBSizeOut, int *pnSRIDOut); 52 : 53 : /** Object to update point coordinates in a WKB geometry */ 54 14894 : class CPL_DLL OGRWKBPointUpdater 55 : { 56 : public: 57 : OGRWKBPointUpdater(); 58 14896 : virtual ~OGRWKBPointUpdater() = default; 59 : 60 : /** Update method */ 61 : virtual bool update(bool bNeedSwap, void *x, void *y, void *z, void *m) = 0; 62 : }; 63 : 64 : bool CPL_DLL OGRWKBUpdatePoints(GByte *pabyWkb, size_t nWKBSize, 65 : OGRWKBPointUpdater &oUpdater); 66 : 67 : /** Transformation cache */ 68 : struct CPL_DLL OGRWKBTransformCache 69 : { 70 : #ifdef OGR_WKB_TRANSFORM_ALL_AT_ONCE 71 : std::vector<bool> abNeedSwap{}; 72 : std::vector<bool> abIsEmpty{}; 73 : std::vector<void *> apdfX{}; 74 : std::vector<void *> apdfY{}; 75 : std::vector<void *> apdfZ{}; 76 : std::vector<void *> apdfM{}; 77 : std::vector<double> adfX{}; 78 : std::vector<double> adfY{}; 79 : std::vector<double> adfZ{}; 80 : std::vector<double> adfM{}; 81 : std::vector<int> anErrorCodes{}; 82 : 83 : void clear(); 84 : #endif 85 : }; 86 : 87 : class OGRCoordinateTransformation; 88 : bool CPL_DLL OGRWKBTransform(GByte *pabyWkb, size_t nWKBSize, 89 : OGRCoordinateTransformation *poCT, 90 : OGRWKBTransformCache &oCache, 91 : OGREnvelope3D &sEnvelope); 92 : 93 : /************************************************************************/ 94 : /* OGRAppendBuffer */ 95 : /************************************************************************/ 96 : 97 : /** Append buffer that can be grown dynamically. */ 98 36 : class CPL_DLL OGRAppendBuffer 99 : { 100 : public: 101 : /** Constructor */ 102 : OGRAppendBuffer(); 103 : 104 : /** Destructor */ 105 : virtual ~OGRAppendBuffer(); 106 : 107 : /** Return the pointer at which nItemSize bytes can be written, 108 : * or nullptr in case of error. 109 : */ 110 138 : inline void *GetPtrForNewBytes(size_t nItemSize) 111 : { 112 138 : if (nItemSize > m_nCapacity - m_nSize) 113 : { 114 4 : if (!Grow(nItemSize)) 115 0 : return nullptr; 116 : } 117 138 : void *pRet = static_cast<GByte *>(m_pRawBuffer) + m_nSize; 118 138 : m_nSize += nItemSize; 119 138 : return pRet; 120 : } 121 : 122 : /** Return the number of valid bytes in the buffer. */ 123 159 : inline size_t GetSize() const 124 : { 125 159 : return m_nSize; 126 : } 127 : 128 : protected: 129 : /** Capacity of the buffer (ie number of bytes allocated). */ 130 : size_t m_nCapacity = 0; 131 : 132 : /** Number of valid bytes in the buffer. */ 133 : size_t m_nSize = 0; 134 : 135 : /** Raw buffer pointer. */ 136 : void *m_pRawBuffer = nullptr; 137 : 138 : /** Extend the capacity of m_pRawBuffer to be at least m_nSize + nItemSize 139 : * large. 140 : */ 141 : virtual bool Grow(size_t nItemSize) = 0; 142 : 143 : private: 144 : OGRAppendBuffer(const OGRAppendBuffer &) = delete; 145 : OGRAppendBuffer &operator=(const OGRAppendBuffer &) = delete; 146 : }; 147 : 148 : /************************************************************************/ 149 : /* OGRWKTToWKBTranslator */ 150 : /************************************************************************/ 151 : 152 : /** Translate WKT geometry to WKB geometry and append it to a buffer */ 153 : class CPL_DLL OGRWKTToWKBTranslator 154 : { 155 : OGRAppendBuffer &m_oAppendBuffer; 156 : bool m_bCanUseStrtod = false; 157 : 158 : public: 159 : /** Constructor */ 160 : explicit OGRWKTToWKBTranslator(OGRAppendBuffer &oAppendBuffer); 161 : 162 : /** Translate the WKT geometry starting at pabyWKTStart and of length nLength. 163 : * 164 : * If pabyWKTStart[nLength] can be dereferenced and temporarily modified, 165 : * set bCanAlterByteAfter to true, which will optimize performance. 166 : * 167 : * Returns the number of bytes of the generated WKB, or -1 in case of error. 168 : */ 169 : size_t TranslateWKT(void *pabyWKTStart, size_t nLength, 170 : bool bCanAlterByteAfter); 171 : }; 172 : 173 : #endif // OGR_WKB_H_INCLUDED