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