Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: SOSI Translator 4 : * Purpose: Implements OGRSOSIDriver. 5 : * Author: Thomas Hirsch, <thomas.hirsch statkart no> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2010, Thomas Hirsch 9 : * Copyright (c) 2010, Even Rouault <even dot rouault at spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #ifndef OGR_SOSI_H_INCLUDED 15 : #define OGR_SOSI_H_INCLUDED 16 : 17 : #include "ogrsf_frmts.h" 18 : #include "fyba.h" 19 : #include <map> 20 : 21 : // Note: WRITE_SUPPORT not defined, since this is only partially implemented 22 : 23 : /* interpolation of arcs(BUEP) creates # points for a full circle */ 24 : #define ARC_INTERPOLATION_FULL_CIRCLE 36.0 25 : 26 : typedef std::map<std::string, std::string> S2S; 27 : typedef std::map<std::string, unsigned int> S2I; 28 : 29 : void RegisterOGRSOSI(); 30 : 31 : class ORGSOSILayer; /* defined below */ 32 : class OGRSOSIDataSource; /* defined below */ 33 : 34 : /************************************************************************ 35 : * OGRSOSILayer * 36 : * OGRSOSILayer reports all the OGR Features generated by the data * 37 : * source, in an orderly fashion. * 38 : ************************************************************************/ 39 : 40 : class OGRSOSILayer final : public OGRLayer 41 : { 42 : int nNextFID; 43 : 44 : OGRSOSIDataSource *poParent; /* used to call methods from data source */ 45 : LC_FILADM *poFileadm; /* ResetReading needs to refer to the file struct */ 46 : OGRFeatureDefn *poFeatureDefn; /* the common definition of all features 47 : returned by this layer */ 48 : S2I *poHeaderDefn; 49 : 50 : LC_SNR_ADM oSnradm; 51 : LC_BGR oNextSerial; /* used by FYBA to iterate through features */ 52 : LC_BGR *poNextSerial; 53 : 54 : public: 55 : OGRSOSILayer(OGRSOSIDataSource *poPar, OGRFeatureDefn *poFeatDefn, 56 : LC_FILADM *poFil, S2I *poHeadDefn); 57 : ~OGRSOSILayer(); 58 : 59 : void ResetReading() override; 60 : OGRFeature *GetNextFeature() override; 61 : OGRFeatureDefn *GetLayerDefn() override; 62 : #ifdef WRITE_SUPPORT 63 : OGRErr CreateField(OGRFieldDefn *poField, int bApproxOK = TRUE) override; 64 : OGRErr ICreateFeature(OGRFeature *poFeature) override; 65 : #endif 66 : int TestCapability(const char *) override; 67 : }; 68 : 69 : /************************************************************************ 70 : * OGRSOSIDataSource * 71 : * OGRSOSIDataSource reads a SOSI file, prebuilds the features, and * 72 : * creates one OGRSOSILayer per geometry type * 73 : ************************************************************************/ 74 : class OGRSOSIDataSource final : public GDALDataset 75 : { 76 : OGRSOSILayer **papoLayers; 77 : int nLayers; 78 : 79 : #define MODE_READING 0 80 : #define MODE_WRITING 1 81 : int nMode; 82 : 83 : void buildOGRPoint(long nSerial); 84 : void buildOGRLineString(int nNumCoo, long nSerial); 85 : void buildOGRMultiPoint(int nNumCoo, long nSerial); 86 : void buildOGRLineStringFromArc(long nSerial); 87 : 88 : public: 89 : OGRSpatialReference *poSRS; 90 : const char *pszEncoding; 91 : unsigned int nNumFeatures; 92 : OGRGeometry **papoBuiltGeometries; /* OGRSOSIDataSource prebuilds some 93 : * features upon opening, te be used by 94 : * the more complex geometries later. */ 95 : // FYBA specific 96 : LC_BASEADM *poBaseadm; 97 : LC_FILADM *poFileadm; 98 : 99 : S2I *poPolyHeaders; /* Contain the header definitions of the four feature 100 : layers */ 101 : S2I *poPointHeaders; 102 : S2I *poCurveHeaders; 103 : S2I *poTextHeaders; 104 : 105 : OGRSOSIDataSource(); 106 : ~OGRSOSIDataSource(); 107 : 108 : int Open(const char *pszFilename, int bUpdate); 109 : #ifdef WRITE_SUPPORT 110 : int Create(const char *pszFilename); 111 : #endif 112 0 : int GetLayerCount() override 113 : { 114 0 : return nLayers; 115 : } 116 : 117 : OGRLayer *GetLayer(int) override; 118 : #ifdef WRITE_SUPPORT 119 : OGRLayer *ICreateLayer(const char *pszName, 120 : const OGRSpatialReference *poSpatialRef = NULL, 121 : OGRwkbGeometryType eGType = wkbUnknown, 122 : char **papszOptions = NULL) override; 123 : #endif 124 : }; 125 : 126 : /************************************************************************ 127 : * OGRSOSIDataTypes * 128 : * OGRSOSIDataTypes provides the correct data types for some of the * 129 : * most common SOSI elements. * 130 : ************************************************************************/ 131 : 132 : class OGRSOSISimpleDataType 133 : { 134 : CPLString osName; 135 : OGRFieldType nType; 136 : 137 : public: 138 : OGRSOSISimpleDataType(); 139 : OGRSOSISimpleDataType(const char *pszName, OGRFieldType nType); 140 : ~OGRSOSISimpleDataType(); 141 : 142 : void setType(const char *pszName, OGRFieldType nType); 143 : 144 1110 : const char *GetName() const 145 : { 146 1110 : return osName.c_str(); 147 : } 148 : 149 483 : OGRFieldType GetType() const 150 : { 151 483 : return nType; 152 : } 153 : }; 154 : 155 : class OGRSOSIDataType 156 : { 157 : OGRSOSISimpleDataType *poElements = nullptr; 158 : int nElementCount = 0; 159 : 160 : OGRSOSIDataType &operator=(const OGRSOSIDataType &) = delete; 161 : 162 : public: 163 : explicit OGRSOSIDataType(int nSize); 164 : 165 1481 : OGRSOSIDataType(const OGRSOSIDataType &oSrc) 166 1481 : : poElements(nullptr), nElementCount(oSrc.nElementCount) 167 : { 168 3271 : poElements = new OGRSOSISimpleDataType[nElementCount]; 169 3271 : for (int i = 0; i < nElementCount; i++) 170 1790 : poElements[i] = oSrc.poElements[i]; 171 1481 : } 172 : 173 1481 : OGRSOSIDataType(OGRSOSIDataType &&oSrc) noexcept 174 1481 : : poElements(oSrc.poElements), nElementCount(oSrc.nElementCount) 175 : { 176 1481 : oSrc.poElements = nullptr; 177 1481 : oSrc.nElementCount = 0; 178 1481 : } 179 : 180 : ~OGRSOSIDataType(); 181 : 182 : void setElement(int nIndex, const char *name, OGRFieldType type); 183 : 184 486 : OGRSOSISimpleDataType *getElements() 185 : { 186 486 : return poElements; 187 : } 188 : 189 1041 : int getElementCount() 190 : { 191 1041 : return nElementCount; 192 : } 193 : }; 194 : 195 : typedef std::map<CPLString, OGRSOSIDataType> C2F; 196 : 197 : void SOSIInitTypes(); 198 : void SOSICleanupTypes(); 199 : OGRSOSIDataType *SOSIGetType(const CPLString &name); 200 : int SOSITypeToInt(const char *value); 201 : double SOSITypeToReal(const char *value); 202 : void SOSITypeToDate(const char *value, int *date); 203 : void SOSITypeToDateTime(const char *value, int *date); 204 : 205 : #endif /* OGR_SOSI_H_INCLUDED */