Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: SDTS Translator 4 : * Purpose: Implements OGRSDTSDataSource class 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1999, Frank Warmerdam 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_sdts.h" 14 : #include "cpl_conv.h" 15 : #include "cpl_string.h" 16 : 17 : /************************************************************************/ 18 : /* OGRSDTSDataSource() */ 19 : /************************************************************************/ 20 : 21 1 : OGRSDTSDataSource::OGRSDTSDataSource() 22 1 : : poTransfer(nullptr), nLayers(0), papoLayers(nullptr), poSRS(nullptr) 23 : { 24 1 : } 25 : 26 : /************************************************************************/ 27 : /* ~OGRSDTSDataSource() */ 28 : /************************************************************************/ 29 : 30 2 : OGRSDTSDataSource::~OGRSDTSDataSource() 31 : 32 : { 33 9 : for (int i = 0; i < nLayers; i++) 34 8 : delete papoLayers[i]; 35 : 36 1 : CPLFree(papoLayers); 37 : 38 1 : if (poSRS) 39 1 : poSRS->Release(); 40 : 41 1 : if (poTransfer) 42 1 : delete poTransfer; 43 2 : } 44 : 45 : /************************************************************************/ 46 : /* GetLayer() */ 47 : /************************************************************************/ 48 : 49 44 : OGRLayer *OGRSDTSDataSource::GetLayer(int iLayer) 50 : 51 : { 52 44 : if (iLayer < 0 || iLayer >= nLayers) 53 0 : return nullptr; 54 : else 55 44 : return papoLayers[iLayer]; 56 : } 57 : 58 : /************************************************************************/ 59 : /* Open() */ 60 : /************************************************************************/ 61 : 62 1 : int OGRSDTSDataSource::Open(const char *pszFilename, int bTestOpen) 63 : 64 : { 65 : /* -------------------------------------------------------------------- */ 66 : /* Verify that the extension is DDF if we are testopening. */ 67 : /* -------------------------------------------------------------------- */ 68 1 : if (bTestOpen && !(strlen(pszFilename) > 4 && 69 1 : EQUAL(pszFilename + strlen(pszFilename) - 4, ".ddf"))) 70 0 : return FALSE; 71 : 72 : /* -------------------------------------------------------------------- */ 73 : /* Check a few bits of the header to see if it looks like an */ 74 : /* SDTS file (really, if it looks like an ISO8211 file). */ 75 : /* -------------------------------------------------------------------- */ 76 1 : if (bTestOpen) 77 : { 78 1 : VSILFILE *fp = VSIFOpenL(pszFilename, "rb"); 79 1 : if (fp == nullptr) 80 0 : return FALSE; 81 : 82 1 : char pachLeader[10] = {}; 83 1 : if (VSIFReadL(pachLeader, 1, 10, fp) != 10 || 84 1 : (pachLeader[5] != '1' && pachLeader[5] != '2' && 85 0 : pachLeader[5] != '3') || 86 3 : pachLeader[6] != 'L' || 87 1 : (pachLeader[8] != '1' && pachLeader[8] != ' ')) 88 : { 89 0 : VSIFCloseL(fp); 90 0 : return FALSE; 91 : } 92 : 93 1 : VSIFCloseL(fp); 94 : } 95 : 96 : /* -------------------------------------------------------------------- */ 97 : /* Create a transfer, and open it. */ 98 : /* -------------------------------------------------------------------- */ 99 1 : poTransfer = new SDTSTransfer(); 100 : 101 1 : GUInt32 nInitialErrorCounter = CPLGetErrorCounter(); 102 2 : if (!poTransfer->Open(pszFilename) || 103 1 : CPLGetErrorCounter() > nInitialErrorCounter + 100) 104 : { 105 0 : delete poTransfer; 106 0 : poTransfer = nullptr; 107 : 108 0 : return FALSE; 109 : } 110 : 111 : /* -------------------------------------------------------------------- */ 112 : /* Initialize the projection. */ 113 : /* -------------------------------------------------------------------- */ 114 1 : SDTS_XREF *poXREF = poTransfer->GetXREF(); 115 : 116 1 : poSRS = new OGRSpatialReference(); 117 1 : poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); 118 : 119 1 : if (EQUAL(poXREF->pszSystemName, "UTM")) 120 : { 121 1 : poSRS->SetUTM(poXREF->nZone, TRUE); 122 : } 123 : 124 1 : if (EQUAL(poXREF->pszDatum, "NAS")) 125 1 : poSRS->SetGeogCS("NAD27", "North_American_Datum_1927", "Clarke 1866", 126 : 6378206.4, 294.978698213901); 127 : 128 0 : else if (EQUAL(poXREF->pszDatum, "NAX")) 129 0 : poSRS->SetGeogCS("NAD83", "North_American_Datum_1983", "GRS 1980", 130 : 6378137, 298.257222101); 131 : 132 0 : else if (EQUAL(poXREF->pszDatum, "WGC")) 133 0 : poSRS->SetGeogCS("WGS 72", "WGS_1972", "NWL 10D", 6378135, 298.26); 134 : 135 : else /* if( EQUAL(poXREF->pszDatum,"WGE") ) or default case */ 136 0 : poSRS->SetGeogCS("WGS 84", "WGS_1984", "WGS 84", 6378137, 137 : 298.257223563); 138 : 139 : /* -------------------------------------------------------------------- */ 140 : /* Initialize a layer for each source dataset layer. */ 141 : /* -------------------------------------------------------------------- */ 142 : 143 9 : for (int iLayer = 0; iLayer < poTransfer->GetLayerCount(); iLayer++) 144 : { 145 8 : if (poTransfer->GetLayerType(iLayer) == SLTRaster) 146 0 : continue; 147 : 148 8 : SDTSIndexedReader *poReader = poTransfer->GetLayerIndexedReader(iLayer); 149 8 : if (poReader == nullptr) 150 0 : continue; 151 8 : if (CPLGetErrorCounter() > nInitialErrorCounter + 100) 152 0 : return FALSE; 153 : 154 16 : papoLayers = 155 8 : (OGRSDTSLayer **)CPLRealloc(papoLayers, sizeof(void *) * ++nLayers); 156 8 : papoLayers[nLayers - 1] = new OGRSDTSLayer(poTransfer, iLayer, this); 157 : } 158 : 159 1 : return TRUE; 160 : }