OGRLayer * OGRTABDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRSIn, OGRwkbGeometryType /* eGeomTypeIn */, char ** /* papszOptions */ ) { IMapInfoFile *poFile; char *pszFullFilename; /* -------------------------------------------------------------------- */ /* If it's a single file mode file, then we may have already */ /* instantiated the low level layer. We would just need to */ /* reset the coordinate system and (potentially) bounds. */ /* -------------------------------------------------------------------- */ if( m_bSingleFile ) { if( m_bSingleLayerAlreadyCreated ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create new layers in this single file dataset."); return NULL; } m_bSingleLayerAlreadyCreated = TRUE; poFile = (IMapInfoFile *) m_papoLayers[0]; } /* -------------------------------------------------------------------- */ /* We need to initially create the file, and add it as a layer. */ /* -------------------------------------------------------------------- */ else { if( m_bCreateMIF ) { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "mif" ) ); poFile = new MIFFile; } else { pszFullFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, pszLayerName, "tab" ) ); poFile = new TABFile; } if( poFile->Open( pszFullFilename, "wb", FALSE ) != 0 ) { CPLFree( pszFullFilename ); delete poFile; return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; CPLFree( pszFullFilename ); } /* -------------------------------------------------------------------- */ /* Assign the coordinate system (if provided) and set */ /* reasonable bounds. */ /* -------------------------------------------------------------------- */ if( poSRSIn != NULL ) poFile->SetSpatialRef( poSRSIn ); if( !poFile->IsBoundsSet() && !m_bCreateMIF ) { if( poSRSIn != NULL && poSRSIn->GetRoot() != NULL && EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") ) poFile->SetBounds( -1000, -1000, 1000, 1000 ); else poFile->SetBounds( -30000000, -15000000, 30000000, 15000000 ); } if (m_bQuickSpatialIndexMode && poFile->SetQuickSpatialIndexMode() != 0) { CPLError( CE_Warning, CPLE_AppDefined, "Setting Quick Spatial Index Mode failed."); } return poFile; }
OGRLayer * OGRTABDataSource::ICreateLayer( const char *pszLayerName, OGRSpatialReference *poSRSIn, OGRwkbGeometryType /* eGeomTypeIn */, char **papszOptions ) { if( !m_bUpdate ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create layer on read-only dataset."); return nullptr; } // If it is a single file mode file, then we may have already // instantiated the low level layer. We would just need to // reset the coordinate system and (potentially) bounds. IMapInfoFile *poFile = nullptr; char *pszFullFilename = nullptr; const char *pszEncoding = CSLFetchNameValue( papszOptions, "ENCODING" ); const char *pszCharset( IMapInfoFile::EncodingToCharset( pszEncoding ) ); if( m_bSingleFile ) { if( m_bSingleLayerAlreadyCreated ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create new layers in this single file dataset."); return nullptr; } m_bSingleLayerAlreadyCreated = TRUE; poFile = (IMapInfoFile *) m_papoLayers[0]; if( pszEncoding ) poFile->SetCharset( pszCharset ); } else { if( m_bCreateMIF ) { pszFullFilename = CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "mif")); poFile = new MIFFile; if( poFile->Open(pszFullFilename, TABWrite, FALSE, pszCharset) != 0 ) { CPLFree(pszFullFilename); delete poFile; return nullptr; } } else { pszFullFilename = CPLStrdup(CPLFormFilename(m_pszDirectory, pszLayerName, "tab")); TABFile *poTABFile = new TABFile; if( poTABFile->Open(pszFullFilename, TABWrite, FALSE, m_nBlockSize, pszCharset) != 0 ) { CPLFree(pszFullFilename); delete poTABFile; return nullptr; } poFile = poTABFile; } m_nLayerCount++; m_papoLayers = static_cast<IMapInfoFile **>( CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount)); m_papoLayers[m_nLayerCount-1] = poFile; CPLFree(pszFullFilename); } poFile->SetDescription(poFile->GetName()); // Assign the coordinate system (if provided) and set // reasonable bounds. if( poSRSIn != nullptr ) { poFile->SetSpatialRef(poSRSIn); // SetSpatialRef() has cloned the passed geometry poFile->GetLayerDefn()->GetGeomFieldDefn(0)->SetSpatialRef( poFile->GetSpatialRef()); } // Pull out the bounds if supplied const char *pszOpt = nullptr; if( (pszOpt = CSLFetchNameValue(papszOptions, "BOUNDS")) != nullptr ) { double dfBounds[4]; if( CPLsscanf(pszOpt, "%lf,%lf,%lf,%lf", &dfBounds[0], &dfBounds[1], &dfBounds[2], &dfBounds[3]) != 4 ) { CPLError( CE_Failure, CPLE_IllegalArg, "Invalid BOUNDS parameter, expected min_x,min_y,max_x,max_y"); } else { poFile->SetBounds(dfBounds[0], dfBounds[1], dfBounds[2], dfBounds[3]); } } if( !poFile->IsBoundsSet() && !m_bCreateMIF ) { if( poSRSIn != nullptr && poSRSIn->GetRoot() != nullptr && EQUAL(poSRSIn->GetRoot()->GetValue(),"GEOGCS") ) poFile->SetBounds(-1000, -1000, 1000, 1000); else poFile->SetBounds(-30000000, -15000000, 30000000, 15000000); } if(m_bQuickSpatialIndexMode == TRUE && poFile->SetQuickSpatialIndexMode(TRUE) != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Setting Quick Spatial Index Mode failed."); } else if(m_bQuickSpatialIndexMode == FALSE && poFile->SetQuickSpatialIndexMode(FALSE) != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Setting Normal Spatial Index Mode failed."); } return poFile; }
int OGRTABDataSource::Create( const char * pszName, char **papszOptions ) { VSIStatBuf sStat; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); m_papszOptions = CSLDuplicate( papszOptions ); if( CSLFetchNameValue(papszOptions,"FORMAT") != NULL && EQUAL(CSLFetchNameValue(papszOptions,"FORMAT"),"MIF") ) m_bCreateMIF = TRUE; else if( EQUAL(CPLGetExtension(pszName),"mif") || EQUAL(CPLGetExtension(pszName),"mid") ) m_bCreateMIF = TRUE; /* -------------------------------------------------------------------- */ /* Create a new empty directory. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetExtension(pszName)) == 0 ) { if( VSIStat( pszName, &sStat ) == 0 ) { if( !VSI_ISDIR(sStat.st_mode) ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create dataset named %s,\n" "but that is an existing file.\n", pszName ); return FALSE; } } else { if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create directory %s.\n", pszName ); return FALSE; } } m_pszDirectory = CPLStrdup(pszName); } /* -------------------------------------------------------------------- */ /* Create a new single file. */ /* -------------------------------------------------------------------- */ else { IMapInfoFile *poFile; if( m_bCreateMIF ) poFile = new MIFFile; else poFile = new TABFile; if( poFile->Open( pszName, "wb", FALSE ) != 0 ) { delete poFile; return FALSE; } poFile->SetBounds( -30000000, -15000000, 30000000, 15000000 ); m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); m_bSingleFile = TRUE; } return TRUE; }