OGRLayer * OGRMemDataSource::ICreateLayer( const char *pszLayerName, OGRSpatialReference *poSRSIn, OGRwkbGeometryType eType, char **papszOptions ) { // Create the layer object. OGRSpatialReference* poSRS = poSRSIn; if( poSRS ) { poSRS = poSRS->Clone(); poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); } OGRMemLayer *poLayer = new OGRMemLayer(pszLayerName, poSRS, eType); if( poSRS ) { poSRS->Release(); } if( CPLFetchBool(papszOptions, "ADVERTIZE_UTF8", false) ) poLayer->SetAdvertizeUTF8(true); // Add layer to data source layer list. papoLayers = static_cast<OGRMemLayer **>( CPLRealloc(papoLayers, sizeof(OGRMemLayer *) * (nLayers + 1))); papoLayers[nLayers++] = poLayer; return poLayer; }
OGRLayer *OGRAmigoCloudDataSource::ICreateLayer( const char *pszNameIn, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { if( !bReadWrite ) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return NULL; } /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ CPLString osName(pszNameIn); OGRAmigoCloudTableLayer* poLayer = new OGRAmigoCloudTableLayer(this, osName); const bool bGeomNullable = CPLFetchBool(papszOptions, "GEOMETRY_NULLABLE", true); poLayer->SetDeferredCreation(eGType, poSpatialRef, bGeomNullable); papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
/* * Open() */ bool OGRNGWDataset::Open( const std::string &osUrlIn, const std::string &osResourceIdIn, char **papszOpenOptionsIn, bool bUpdateIn, int nOpenFlagsIn ) { osUrl = osUrlIn; osResourceId = osResourceIdIn; bReadWrite = bUpdateIn; osUserPwd = CSLFetchNameValueDef( papszOpenOptionsIn, "USERPWD", CPLGetConfigOption("NGW_USERPWD", "")); nBatchSize = atoi( CSLFetchNameValueDef( papszOpenOptionsIn, "BATCH_SIZE", CPLGetConfigOption("NGW_BATCH_SIZE", "-1") ) ); nPageSize = atoi( CSLFetchNameValueDef(papszOpenOptionsIn, "PAGE_SIZE", CPLGetConfigOption("NGW_PAGE_SIZE", "-1") ) ); if( nPageSize == 0 ) { nPageSize = -1; } nCacheExpires = atoi( CSLFetchNameValueDef(papszOpenOptionsIn, "CACHE_EXPIRES", CPLGetConfigOption("NGW_CACHE_EXPIRES", "604800") ) ); nCacheMaxSize = atoi( CSLFetchNameValueDef(papszOpenOptionsIn, "CACHE_MAX_SIZE", CPLGetConfigOption("NGW_CACHE_MAX_SIZE", "67108864") ) ); bExtInNativeData = CPLFetchBool( papszOpenOptionsIn, "NATIVE_DATA", CPLTestBool( CPLGetConfigOption("NGW_NATIVE_DATA", "NO") ) ); return Init( nOpenFlagsIn ); }
OGRLayer *OGRAmigoCloudDataSource::ICreateLayer( const char *pszNameIn, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { if( !bReadWrite ) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return nullptr; } CPLString osName(pszNameIn); OGRAmigoCloudTableLayer* poLayer = new OGRAmigoCloudTableLayer(this, osName); const bool bGeomNullable = CPLFetchBool(papszOptions, "GEOMETRY_NULLABLE", true); OGRSpatialReference* poSRSClone = poSpatialRef; if( poSRSClone ) { poSRSClone = poSRSClone->Clone(); poSRSClone->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); } poLayer->SetDeferredCreation(eGType, poSRSClone, bGeomNullable); if( poSRSClone ) poSRSClone->Release(); papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
int GNMDatabaseNetwork::CheckNetworkExist(const char *pszFilename, char **papszOptions) { // check if path exist // if path exist check if network already present and OVERWRITE option // else create the path if(FormName(pszFilename, papszOptions) != CE_None) { return TRUE; } if(NULL == m_poDS) { m_poDS = (GDALDataset*) GDALOpenEx( m_soNetworkFullName, GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, papszOptions ); } const bool bOverwrite = CPLFetchBool(papszOptions, "OVERWRITE", false); std::vector<int> anDeleteLayers; int i; for(i = 0; i < m_poDS->GetLayerCount(); ++i) { OGRLayer* poLayer = m_poDS->GetLayer(i); if(NULL == poLayer) continue; if(EQUAL(poLayer->GetName(), GNM_SYSLAYER_META) || EQUAL(poLayer->GetName(), GNM_SYSLAYER_GRAPH) || EQUAL(poLayer->GetName(), GNM_SYSLAYER_FEATURES) ) { anDeleteLayers.push_back(i); } } if(anDeleteLayers.empty()) return FALSE; if( bOverwrite ) { for(i = (int)anDeleteLayers.size(); i > 0; i--) { CPLDebug("GNM", "Delete layer: %d", i); if(m_poDS->DeleteLayer(anDeleteLayers[i - 1]) != OGRERR_NONE) return TRUE; } return FALSE; } else { return TRUE; } }
OGRLayer * OGRMemDataSource::ICreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMemLayer *poLayer = new OGRMemLayer( pszLayerName, poSRS, eType ); if( CPLFetchBool(papszOptions, "ADVERTIZE_UTF8", false) ) poLayer->SetAdvertizeUTF8(true); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = static_cast<OGRMemLayer **>( CPLRealloc( papoLayers, sizeof(OGRMemLayer *) * (nLayers+1) ) ); papoLayers[nLayers++] = poLayer; return poLayer; }
OGRLayer *GNMGenericNetwork::GetPath(GNMGFID nStartFID, GNMGFID nEndFID, GNMGraphAlgorithmType eAlgorithm, char **papszOptions) { if(!m_bIsGraphLoaded && LoadGraph() != CE_None) { return NULL; } GDALDriver* poMEMDrv = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("Memory"); if (poMEMDrv == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load 'Memory' driver"); return NULL; } GDALDataset* poMEMDS = poMEMDrv->Create("dummy_name", 0, 0, 0, GDT_Unknown, NULL); OGRSpatialReference oDstSpaRef(GetProjectionRef()); OGRLayer* poMEMLayer = poMEMDS->CreateLayer(GetAlgorithmName(eAlgorithm, true), &oDstSpaRef, wkbGeometryCollection, NULL); OGRGNMWrappedResultLayer* poResLayer = new OGRGNMWrappedResultLayer(poMEMDS, poMEMLayer); const bool bReturnEdges = CPLFetchBool(papszOptions, GNM_MD_FETCHEDGES, true); const bool bReturnVertices = CPLFetchBool(papszOptions, GNM_MD_FETCHVERTEX, true); switch (eAlgorithm) { case GATDijkstraShortestPath: { GNMPATH path = m_oGraph.DijkstraShortestPath(nStartFID, nEndFID); // fill features in result layer FillResultLayer(poResLayer, path, 1, bReturnVertices, bReturnEdges); } break; case GATKShortestPath: { int nK = atoi(CSLFetchNameValueDef(papszOptions, GNM_MD_NUM_PATHS, "1")); CPLDebug("GNM", "Search %d path(s)", nK); std::vector<GNMPATH> paths = m_oGraph.KShortestPaths(nStartFID, nEndFID, nK); // fill features in result layer for(size_t i = 0; i < paths.size(); ++i) { FillResultLayer(poResLayer, paths[i], static_cast<int>(i + 1), bReturnVertices, bReturnEdges); } } break; case GATConnectedComponents: { GNMVECTOR anEmitters; if(NULL != papszOptions) { char** papszEmitter = CSLFetchNameValueMultiple(papszOptions, GNM_MD_EMITTER); for(int i = 0; papszEmitter[i] != NULL; ++i) { GNMGFID nEmitter = atol(papszEmitter[i]); anEmitters.push_back(nEmitter); } CSLDestroy(papszEmitter); } if(nStartFID != -1) { anEmitters.push_back(nStartFID); } if(nStartFID != -1) { anEmitters.push_back(nEndFID); } GNMPATH path = m_oGraph.ConnectedComponents(anEmitters); // fill features in result layer FillResultLayer(poResLayer, path, 1, bReturnVertices, bReturnEdges); } break; } return poResLayer; }
OGRErr OGRCSVEditableLayerSynchronizer::EditableSyncToDisk(OGRLayer* poEditableLayer, OGRLayer** ppoDecoratedLayer) { CPLAssert( m_poCSVLayer == *ppoDecoratedLayer ); CPLString osLayerName(m_poCSVLayer->GetName()); CPLString osFilename(m_poCSVLayer->GetFilename()); const bool bCreateCSVT = m_poCSVLayer->GetCreateCSVT(); CPLString osCSVTFilename(CPLResetExtension(osFilename, "csvt")); VSIStatBufL sStatBuf; const bool bHasCSVT = VSIStatL(osCSVTFilename, &sStatBuf) == 0; CPLString osTmpFilename(osFilename); CPLString osTmpCSVTFilename(osFilename); if( VSIStatL(osFilename, &sStatBuf) == 0 ) { osTmpFilename += "_ogr_tmp.csv"; osTmpCSVTFilename += "_ogr_tmp.csvt"; } const char chDelimiter = m_poCSVLayer->GetDelimiter(); OGRCSVLayer* poCSVTmpLayer = new OGRCSVLayer( osLayerName, NULL, osTmpFilename, true, true, chDelimiter ); poCSVTmpLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions); poCSVTmpLayer->SetCRLF( m_poCSVLayer->GetCRLF() ); poCSVTmpLayer->SetCreateCSVT( bCreateCSVT || bHasCSVT ); poCSVTmpLayer->SetWriteBOM( m_poCSVLayer->GetWriteBOM() ); if( m_poCSVLayer->GetGeometryFormat() == OGR_CSV_GEOM_AS_WKT ) poCSVTmpLayer->SetWriteGeometry( wkbNone, OGR_CSV_GEOM_AS_WKT, NULL ); OGRErr eErr = OGRERR_NONE; OGRFeatureDefn* poEditableFDefn = poEditableLayer->GetLayerDefn(); for( int i=0; eErr == OGRERR_NONE && i < poEditableFDefn->GetFieldCount(); i++ ) { OGRFieldDefn oFieldDefn(poEditableFDefn->GetFieldDefn(i)); int iGeomFieldIdx = 0; if( (EQUAL(oFieldDefn.GetNameRef(), "WKT") && (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex("")) >= 0) || (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex(oFieldDefn.GetNameRef())) >= 0 ) { OGRGeomFieldDefn oGeomFieldDefn( poEditableFDefn->GetGeomFieldDefn(iGeomFieldIdx) ); eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn ); } else { eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } } const bool bHasXY = ( !m_poCSVLayer->GetXField().empty() && !m_poCSVLayer->GetYField().empty() ); const bool bHasZ = ( !m_poCSVLayer->GetZField().empty() ); if( bHasXY && !CPLFetchBool(m_papszOpenOptions, "KEEP_GEOM_COLUMNS", true) ) { if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetXField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetXField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetYField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetYField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } if( bHasZ && poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetZField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetZField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } } int nFirstGeomColIdx = 0; if( m_poCSVLayer->HasHiddenWKTColumn() ) { poCSVTmpLayer->SetWriteGeometry( poEditableFDefn->GetGeomFieldDefn(0)->GetType(), OGR_CSV_GEOM_AS_WKT, poEditableFDefn->GetGeomFieldDefn(0)->GetNameRef()); nFirstGeomColIdx = 1; } if( !(poEditableFDefn->GetGeomFieldCount() == 1 && bHasXY) ) { for( int i=nFirstGeomColIdx; eErr == OGRERR_NONE && i < poEditableFDefn->GetGeomFieldCount(); i++ ) { OGRGeomFieldDefn oGeomFieldDefn( poEditableFDefn->GetGeomFieldDefn(i) ); if( poCSVTmpLayer->GetLayerDefn()->GetGeomFieldIndex(oGeomFieldDefn.GetNameRef()) >= 0 ) continue; eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn ); } } OGRFeature* poFeature = NULL; poEditableLayer->ResetReading(); while( eErr == OGRERR_NONE && (poFeature = poEditableLayer->GetNextFeature()) != NULL ) { OGRFeature* poNewFeature = new OGRFeature( poCSVTmpLayer->GetLayerDefn() ); poNewFeature->SetFrom(poFeature); if( bHasXY ) { OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { poNewFeature->SetField( m_poCSVLayer->GetXField(), static_cast<OGRPoint*>(poGeom)->getX()); poNewFeature->SetField( m_poCSVLayer->GetYField(), static_cast<OGRPoint*>(poGeom)->getY()); if( bHasZ ) { poNewFeature->SetField( m_poCSVLayer->GetZField(), static_cast<OGRPoint*>(poGeom)->getZ()); } } } eErr = poCSVTmpLayer->CreateFeature(poNewFeature); delete poFeature; delete poNewFeature; } delete poCSVTmpLayer; if( eErr != OGRERR_NONE ) { CPLError(CE_Failure, CPLE_AppDefined, "Error while creating %s", osTmpFilename.c_str()); VSIUnlink( osTmpFilename ); VSIUnlink( CPLResetExtension(osTmpFilename, "csvt") ); return eErr; } delete m_poCSVLayer; if( osFilename != osTmpFilename ) { CPLString osTmpOriFilename(osFilename + ".ogr_bak"); CPLString osTmpOriCSVTFilename(osCSVTFilename + ".ogr_bak"); if( VSIRename( osFilename, osTmpOriFilename ) != 0 || (bHasCSVT && VSIRename( osCSVTFilename, osTmpOriCSVTFilename ) != 0 ) || VSIRename( osTmpFilename, osFilename) != 0 || (bHasCSVT && VSIRename( osTmpCSVTFilename, osCSVTFilename ) != 0) ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot rename files"); *ppoDecoratedLayer = NULL; m_poCSVLayer = NULL; return OGRERR_FAILURE; } VSIUnlink( osTmpOriFilename ); if( bHasCSVT ) VSIUnlink( osTmpOriCSVTFilename ); } VSILFILE* fp = VSIFOpenL( osFilename, "rb+" ); if( fp == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot reopen updated %s", osFilename.c_str()); *ppoDecoratedLayer = NULL; m_poCSVLayer = NULL; return OGRERR_FAILURE; } m_poCSVLayer = new OGRCSVLayer( osLayerName, fp, osFilename, false, /* new */ true, /* update */ chDelimiter ); m_poCSVLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions); *ppoDecoratedLayer = m_poCSVLayer; return OGRERR_NONE; }
OGRLayer * OGRShapeDataSource::ICreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { // To ensure that existing layers are created. GetLayerCount(); /* -------------------------------------------------------------------- */ /* Check that the layer doesn't already exist. */ /* -------------------------------------------------------------------- */ if (GetLayerByName(pszLayerName) != NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Layer '%s' already exists", pszLayerName); return NULL; } /* -------------------------------------------------------------------- */ /* Verify we are in update mode. */ /* -------------------------------------------------------------------- */ if( !bDSUpdate ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Data source %s opened read-only. " "New layer %s cannot be created.", pszName, pszLayerName ); return NULL; } /* -------------------------------------------------------------------- */ /* Figure out what type of layer we need. */ /* -------------------------------------------------------------------- */ int nShapeType = -1; if( wkbFlatten(eType) == wkbUnknown || eType == wkbLineString ) nShapeType = SHPT_ARC; else if( eType == wkbPoint ) nShapeType = SHPT_POINT; else if( eType == wkbPolygon ) nShapeType = SHPT_POLYGON; else if( eType == wkbMultiPoint ) nShapeType = SHPT_MULTIPOINT; else if( eType == wkbPoint25D ) nShapeType = SHPT_POINTZ; else if( eType == wkbPointM ) nShapeType = SHPT_POINTM; else if( eType == wkbPointZM ) nShapeType = SHPT_POINTZ; else if( eType == wkbLineString25D ) nShapeType = SHPT_ARCZ; else if( eType == wkbLineStringM ) nShapeType = SHPT_ARCM; else if( eType == wkbLineStringZM ) nShapeType = SHPT_ARCZ; else if( eType == wkbMultiLineString ) nShapeType = SHPT_ARC; else if( eType == wkbMultiLineString25D ) nShapeType = SHPT_ARCZ; else if( eType == wkbMultiLineStringM ) nShapeType = SHPT_ARCM; else if( eType == wkbMultiLineStringZM ) nShapeType = SHPT_ARCZ; else if( eType == wkbPolygon25D ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbPolygonM ) nShapeType = SHPT_POLYGONM; else if( eType == wkbPolygonZM ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbMultiPolygon ) nShapeType = SHPT_POLYGON; else if( eType == wkbMultiPolygon25D ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbMultiPolygonM ) nShapeType = SHPT_POLYGONM; else if( eType == wkbMultiPolygonZM ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbMultiPoint25D ) nShapeType = SHPT_MULTIPOINTZ; else if( eType == wkbMultiPointM ) nShapeType = SHPT_MULTIPOINTM; else if( eType == wkbMultiPointZM ) nShapeType = SHPT_MULTIPOINTZ; else if( eType == wkbNone ) nShapeType = SHPT_NULL; /* -------------------------------------------------------------------- */ /* Has the application overridden this with a special creation */ /* option? */ /* -------------------------------------------------------------------- */ const char *pszOverride = CSLFetchNameValue( papszOptions, "SHPT" ); if( pszOverride == NULL ) { /* ignore */; } else if( EQUAL(pszOverride,"POINT") ) { nShapeType = SHPT_POINT; eType = wkbPoint; } else if( EQUAL(pszOverride,"ARC") ) { nShapeType = SHPT_ARC; eType = wkbLineString; } else if( EQUAL(pszOverride,"POLYGON") ) { nShapeType = SHPT_POLYGON; eType = wkbPolygon; } else if( EQUAL(pszOverride,"MULTIPOINT") ) { nShapeType = SHPT_MULTIPOINT; eType = wkbMultiPoint; } else if( EQUAL(pszOverride,"POINTZ") ) { nShapeType = SHPT_POINTZ; eType = wkbPoint25D; } else if( EQUAL(pszOverride,"ARCZ") ) { nShapeType = SHPT_ARCZ; eType = wkbLineString25D; } else if( EQUAL(pszOverride,"POLYGONZ") ) { nShapeType = SHPT_POLYGONZ; eType = wkbPolygon25D; } else if( EQUAL(pszOverride,"MULTIPOINTZ") ) { nShapeType = SHPT_MULTIPOINTZ; eType = wkbMultiPoint25D; } else if( EQUAL(pszOverride,"POINTM") ) { nShapeType = SHPT_POINTM; eType = wkbPointM; } else if( EQUAL(pszOverride,"ARCM") ) { nShapeType = SHPT_ARCM; eType = wkbLineStringM; } else if( EQUAL(pszOverride,"POLYGONM") ) { nShapeType = SHPT_POLYGONM; eType = wkbPolygonM; } else if( EQUAL(pszOverride,"MULTIPOINTM") ) { nShapeType = SHPT_MULTIPOINTM; eType = wkbMultiPointM; } else if( EQUAL(pszOverride,"POINTZM") ) { nShapeType = SHPT_POINTZ; eType = wkbPointZM; } else if( EQUAL(pszOverride,"ARCZM") ) { nShapeType = SHPT_ARCZ; eType = wkbLineStringZM; } else if( EQUAL(pszOverride,"POLYGONZM") ) { nShapeType = SHPT_POLYGONZ; eType = wkbPolygonZM; } else if( EQUAL(pszOverride,"MULTIPOINTZM") ) { nShapeType = SHPT_MULTIPOINTZ; eType = wkbMultiPointZM; } else if( EQUAL(pszOverride,"NONE") || EQUAL(pszOverride,"NULL") ) { nShapeType = SHPT_NULL; eType = wkbNone; } else { CPLError( CE_Failure, CPLE_NotSupported, "Unknown SHPT value of `%s' passed to Shapefile layer" "creation. Creation aborted.", pszOverride ); return NULL; } if( nShapeType == -1 ) { CPLError( CE_Failure, CPLE_NotSupported, "Geometry type of `%s' not supported in shapefiles. " "Type can be overridden with a layer creation option " "of SHPT=POINT/ARC/POLYGON/MULTIPOINT/POINTZ/ARCZ/POLYGONZ/" "MULTIPOINTZ.", OGRGeometryTypeToName(eType) ); return NULL; } /* -------------------------------------------------------------------- */ /* What filename do we use, excluding the extension? */ /* -------------------------------------------------------------------- */ char *pszFilenameWithoutExt = NULL; if( bSingleFileDataSource && nLayers == 0 ) { char *pszPath = CPLStrdup(CPLGetPath(pszName)); char *pszFBasename = CPLStrdup(CPLGetBasename(pszName)); pszFilenameWithoutExt = CPLStrdup(CPLFormFilename(pszPath, pszFBasename, NULL)); CPLFree( pszFBasename ); CPLFree( pszPath ); } else if( bSingleFileDataSource ) { // This is a very weird use case : the user creates/open a datasource // made of a single shapefile 'foo.shp' and wants to add a new layer // to it, 'bar'. So we create a new shapefile 'bar.shp' in the same // directory as 'foo.shp' // So technically, we will not be any longer a single file // datasource ... Ahem ahem. char *pszPath = CPLStrdup(CPLGetPath(pszName)); pszFilenameWithoutExt = CPLStrdup(CPLFormFilename(pszPath, pszLayerName, NULL)); CPLFree( pszPath ); } else { pszFilenameWithoutExt = CPLStrdup(CPLFormFilename(pszName, pszLayerName, NULL)); } /* -------------------------------------------------------------------- */ /* Create the shapefile. */ /* -------------------------------------------------------------------- */ const bool l_b2GBLimit = CPLTestBool(CSLFetchNameValueDef( papszOptions, "2GB_LIMIT", "FALSE" )); SHPHandle hSHP = NULL; if( nShapeType != SHPT_NULL ) { char *pszFilename = CPLStrdup(CPLFormFilename( NULL, pszFilenameWithoutExt, "shp" )); hSHP = SHPCreateLL( pszFilename, nShapeType, const_cast<SAHooks *>(VSI_SHP_GetHook(l_b2GBLimit)) ); if( hSHP == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open Shapefile `%s'.", pszFilename ); CPLFree( pszFilename ); CPLFree( pszFilenameWithoutExt ); return NULL; } SHPSetFastModeReadObject( hSHP, TRUE ); CPLFree( pszFilename ); } /* -------------------------------------------------------------------- */ /* Has a specific LDID been specified by the caller? */ /* -------------------------------------------------------------------- */ const char *pszLDID = CSLFetchNameValue( papszOptions, "ENCODING" ); /* -------------------------------------------------------------------- */ /* Create a DBF file. */ /* -------------------------------------------------------------------- */ char *pszFilename = CPLStrdup(CPLFormFilename( NULL, pszFilenameWithoutExt, "dbf" )); DBFHandle hDBF = DBFCreateLL( pszFilename, (pszLDID != NULL) ? pszLDID : "LDID/87", const_cast<SAHooks *>(VSI_SHP_GetHook(b2GBLimit)) ); if( hDBF == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open Shape DBF file `%s'.", pszFilename ); CPLFree( pszFilename ); CPLFree( pszFilenameWithoutExt ); SHPClose(hSHP); return NULL; } CPLFree( pszFilename ); /* -------------------------------------------------------------------- */ /* Create the .prj file, if required. */ /* -------------------------------------------------------------------- */ if( poSRS != NULL ) { CPLString osPrjFile = CPLFormFilename( NULL, pszFilenameWithoutExt, "prj"); // The shape layer needs its own copy. poSRS = poSRS->Clone(); poSRS->morphToESRI(); char *pszWKT = NULL; VSILFILE *fp = NULL; if( poSRS->exportToWkt( &pszWKT ) == OGRERR_NONE && (fp = VSIFOpenL( osPrjFile, "wt" )) != NULL ) { VSIFWriteL( pszWKT, strlen(pszWKT), 1, fp ); VSIFCloseL( fp ); } CPLFree( pszWKT ); poSRS->morphFromESRI(); } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ // OGRShapeLayer constructor expects a filename with an extension (that // could be random actually), otherwise this is going to cause problems with // layer names that have a dot (not speaking about the one before the shp) pszFilename = CPLStrdup(CPLFormFilename( NULL, pszFilenameWithoutExt, "shp" )); OGRShapeLayer *poLayer = new OGRShapeLayer( this, pszFilename, hSHP, hDBF, poSRS, true, true, eType ); CPLFree( pszFilenameWithoutExt ); CPLFree( pszFilename ); poLayer->SetResizeAtClose( CPLFetchBool( papszOptions, "RESIZE", false ) ); poLayer->CreateSpatialIndexAtClose( CPLFetchBool( papszOptions, "SPATIAL_INDEX", false ) ); poLayer->SetModificationDate( CSLFetchNameValue( papszOptions, "DBF_DATE_LAST_UPDATE" ) ); poLayer->SetAutoRepack( CPLFetchBool( papszOptions, "AUTO_REPACK", true ) ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ AddLayer(poLayer); return poLayer; }
bool OGRShapeDataSource::OpenFile( const char *pszNewName, bool bUpdate ) { const char *pszExtension = CPLGetExtension( pszNewName ); if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx") && !EQUAL(pszExtension,"dbf") ) return false; /* -------------------------------------------------------------------- */ /* SHPOpen() should include better (CPL based) error reporting, */ /* and we should be trying to distinguish at this point whether */ /* failure is a result of trying to open a non-shapefile, or */ /* whether it was a shapefile and we want to report the error */ /* up. */ /* */ /* Care is taken to suppress the error and only reissue it if */ /* we think it is appropriate. */ /* -------------------------------------------------------------------- */ CPLPushErrorHandler( CPLQuietErrorHandler ); SHPHandle hSHP = bUpdate ? DS_SHPOpen( pszNewName, "r+" ) : DS_SHPOpen( pszNewName, "r" ); CPLPopErrorHandler(); if( hSHP == NULL && (!EQUAL(CPLGetExtension(pszNewName),"dbf") || strstr(CPLGetLastErrorMsg(),".shp") == NULL) ) { CPLString osMsg = CPLGetLastErrorMsg(); CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() ); return false; } CPLErrorReset(); /* -------------------------------------------------------------------- */ /* Open the .dbf file, if it exists. To open a dbf file, the */ /* filename has to either refer to a successfully opened shp */ /* file or has to refer to the actual .dbf file. */ /* -------------------------------------------------------------------- */ DBFHandle hDBF = NULL; if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName), "dbf") ) { if( bUpdate ) { hDBF = DS_DBFOpen( pszNewName, "r+" ); if( hSHP != NULL && hDBF == NULL ) { for( int i = 0; i < 2; i++ ) { VSIStatBufL sStat; const char* pszDBFName = CPLResetExtension(pszNewName, (i == 0 ) ? "dbf" : "DBF"); VSILFILE* fp = NULL; if( VSIStatExL( pszDBFName, &sStat, VSI_STAT_EXISTS_FLAG) == 0 ) { fp = VSIFOpenL(pszDBFName, "r+"); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s exists, " "but cannot be opened in update mode", pszDBFName ); SHPClose(hSHP); return false; } VSIFCloseL(fp); break; } } } } else { hDBF = DS_DBFOpen( pszNewName, "r" ); } } else { hDBF = NULL; } if( hDBF == NULL && hSHP == NULL ) return false; /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer = new OGRShapeLayer( this, pszNewName, hSHP, hDBF, NULL, false, bUpdate, wkbNone ); poLayer->SetModificationDate( CSLFetchNameValue( papszOpenOptions, "DBF_DATE_LAST_UPDATE" ) ); poLayer->SetAutoRepack( CPLFetchBool( papszOpenOptions, "AUTO_REPACK", true ) ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ AddLayer(poLayer); return true; }
/* * ICreateLayer */ OGRLayer *OGRNGWDataset::ICreateLayer( const char *pszNameIn, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char **papszOptions ) { if( !bReadWrite ) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return nullptr; } // Check permissions as we create new layer in memory and will create in during SyncToDisk. FetchPermissions(); if( !stPermissions.bResourceCanCreate ) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not permitted."); return nullptr; } // Check input parameters. if( eGType < wkbPoint || eGType > wkbMultiPolygon ) { CPLError(CE_Failure, CPLE_AppDefined, "Unsupported geometry type: %s", OGRGeometryTypeToName(eGType)); return nullptr; } if( !poSpatialRef ) { CPLError(CE_Failure, CPLE_AppDefined, "Undefined spatial reference"); return nullptr; } poSpatialRef->AutoIdentifyEPSG(); const char *pszEPSG = poSpatialRef->GetAuthorityCode( nullptr ); int nEPSG = -1; if( pszEPSG != nullptr ) { nEPSG = atoi( pszEPSG ); } if( nEPSG != 3857 ) // TODO: Check NextGIS Web supported SRS. { CPLError(CE_Failure, CPLE_AppDefined, "Unsupported spatial reference EPSG code: %d", nEPSG); return nullptr; } // Do we already have this layer? If so, should we blow it away? bool bOverwrite = CPLFetchBool(papszOptions, "OVERWRITE", "NO"); for( int iLayer = 0; iLayer < nLayers; ++iLayer ) { if( EQUAL(pszNameIn, papoLayers[iLayer]->GetName()) ) { if( bOverwrite ) { DeleteLayer( iLayer ); break; } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszNameIn ); return nullptr; } } } // Create layer. std::string osKey = CSLFetchNameValueDef( papszOptions, "KEY", ""); std::string osDesc = CSLFetchNameValueDef( papszOptions, "DESCRIPTION", ""); OGRNGWLayer *poLayer = new OGRNGWLayer( this, pszNameIn, poSpatialRef, eGType, osKey, osDesc ); papoLayers = (OGRNGWLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRNGWLayer*)); papoLayers[nLayers++] = poLayer; return poLayer; }
CPLErr CPL_STDCALL GDALComputeProximity( GDALRasterBandH hSrcBand, GDALRasterBandH hProximityBand, char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hSrcBand, "GDALComputeProximity", CE_Failure ); VALIDATE_POINTER1( hProximityBand, "GDALComputeProximity", CE_Failure ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Are we using pixels or georeferenced coordinates for distances? */ /* -------------------------------------------------------------------- */ double dfDistMult = 1.0; const char *pszOpt = CSLFetchNameValue( papszOptions, "DISTUNITS" ); if( pszOpt ) { if( EQUAL(pszOpt, "GEO") ) { GDALDatasetH hSrcDS = GDALGetBandDataset( hSrcBand ); if( hSrcDS ) { double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; GDALGetGeoTransform( hSrcDS, adfGeoTransform ); if( std::abs(adfGeoTransform[1]) != std::abs(adfGeoTransform[5]) ) CPLError( CE_Warning, CPLE_AppDefined, "Pixels not square, distances will be inaccurate." ); dfDistMult = std::abs(adfGeoTransform[1]); } } else if( !EQUAL(pszOpt, "PIXEL") ) { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognized DISTUNITS value '%s', should be GEO or PIXEL.", pszOpt ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* What is our maxdist value? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue( papszOptions, "MAXDIST" ); const double dfMaxDist = pszOpt ? CPLAtof(pszOpt) / dfDistMult : GDALGetRasterBandXSize(hSrcBand) + GDALGetRasterBandYSize(hSrcBand); CPLDebug( "GDAL", "MAXDIST=%g, DISTMULT=%g", dfMaxDist, dfDistMult ); /* -------------------------------------------------------------------- */ /* Verify the source and destination are compatible. */ /* -------------------------------------------------------------------- */ const int nXSize = GDALGetRasterBandXSize( hSrcBand ); const int nYSize = GDALGetRasterBandYSize( hSrcBand ); if( nXSize != GDALGetRasterBandXSize( hProximityBand ) || nYSize != GDALGetRasterBandYSize( hProximityBand )) { CPLError( CE_Failure, CPLE_AppDefined, "Source and proximity bands are not the same size." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Get input NODATA value. */ /* -------------------------------------------------------------------- */ double dfSrcNoDataValue = 0.0; double *pdfSrcNoData = NULL; if( CPLFetchBool( papszOptions, "USE_INPUT_NODATA", false ) ) { int bSrcHasNoData = 0; dfSrcNoDataValue = GDALGetRasterNoDataValue( hSrcBand, &bSrcHasNoData ); if( bSrcHasNoData ) pdfSrcNoData = &dfSrcNoDataValue; } /* -------------------------------------------------------------------- */ /* Get output NODATA value. */ /* -------------------------------------------------------------------- */ float fNoDataValue = 0.0f; pszOpt = CSLFetchNameValue( papszOptions, "NODATA" ); if( pszOpt != NULL ) { fNoDataValue = static_cast<float>(CPLAtof(pszOpt)); } else { int bSuccess = FALSE; fNoDataValue = static_cast<float>( GDALGetRasterNoDataValue( hProximityBand, &bSuccess ) ); if( !bSuccess ) fNoDataValue = 65535.0; } /* -------------------------------------------------------------------- */ /* Is there a fixed value we wish to force the buffer area to? */ /* -------------------------------------------------------------------- */ double dfFixedBufVal = 0.0; bool bFixedBufVal = false; pszOpt = CSLFetchNameValue( papszOptions, "FIXED_BUF_VAL" ); if( pszOpt ) { dfFixedBufVal = CPLAtof(pszOpt); bFixedBufVal = true; } /* -------------------------------------------------------------------- */ /* Get the target value(s). */ /* -------------------------------------------------------------------- */ int *panTargetValues = NULL; int nTargetValues = 0; pszOpt = CSLFetchNameValue( papszOptions, "VALUES" ); if( pszOpt != NULL ) { char **papszValuesTokens = CSLTokenizeStringComplex( pszOpt, ",", FALSE, FALSE); nTargetValues = CSLCount(papszValuesTokens); panTargetValues = static_cast<int *>( CPLCalloc(sizeof(int), nTargetValues) ); for( int i = 0; i < nTargetValues; i++ ) panTargetValues[i] = atoi(papszValuesTokens[i]); CSLDestroy( papszValuesTokens ); } /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); CPLFree(panTargetValues); return CE_Failure; } /* -------------------------------------------------------------------- */ /* We need a signed type for the working proximity values kept */ /* on disk. If our proximity band is not signed, then create a */ /* temporary file for this purpose. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hWorkProximityBand = hProximityBand; GDALDatasetH hWorkProximityDS = NULL; const GDALDataType eProxType = GDALGetRasterDataType(hProximityBand); CPLErr eErr = CE_None; // TODO(schwehr): Localize after removing gotos. float *pafProximity = NULL; int *panNearX = NULL; int *panNearY = NULL; GInt32 *panSrcScanline = NULL; if( eProxType == GDT_Byte || eProxType == GDT_UInt16 || eProxType == GDT_UInt32 ) { GDALDriverH hDriver = GDALGetDriverByName("GTiff"); if( hDriver == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GDALComputeProximity needs GTiff driver" ); eErr = CE_Failure; goto end; } CPLString osTmpFile = CPLGenerateTempFilename( "proximity" ); hWorkProximityDS = GDALCreate( hDriver, osTmpFile, nXSize, nYSize, 1, GDT_Float32, NULL ); if( hWorkProximityDS == NULL ) { eErr = CE_Failure; goto end; } hWorkProximityBand = GDALGetRasterBand( hWorkProximityDS, 1 ); } /* -------------------------------------------------------------------- */ /* Allocate buffer for two scanlines of distances as floats */ /* (the current and last line). */ /* -------------------------------------------------------------------- */ pafProximity = static_cast<float *>(VSI_MALLOC2_VERBOSE(sizeof(float), nXSize)); panNearX = static_cast<int *>(VSI_MALLOC2_VERBOSE(sizeof(int), nXSize)); panNearY = static_cast<int *>(VSI_MALLOC2_VERBOSE(sizeof(int), nXSize)); panSrcScanline = static_cast<GInt32 *>(VSI_MALLOC2_VERBOSE(sizeof(GInt32), nXSize)); if( pafProximity == NULL || panNearX == NULL || panNearY == NULL || panSrcScanline == NULL) { eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Loop from top to bottom of the image. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nXSize; i++ ) { panNearX[i] = -1; panNearY[i] = -1; } for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ ) { // Read for target values. eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr != CE_None ) break; for( int i = 0; i < nXSize; i++ ) pafProximity[i] = -1.0; // Left to right. ProcessProximityLine( panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Right to Left. ProcessProximityLine( panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Write out results. eErr = GDALRasterIO( hWorkProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; if( !pfnProgress( 0.5 * (iLine+1) / static_cast<double>(nYSize), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Loop from bottom to top of the image. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nXSize; i++ ) { panNearX[i] = -1; panNearY[i] = -1; } for( int iLine = nYSize-1; eErr == CE_None && iLine >= 0; iLine-- ) { // Read first pass proximity. eErr = GDALRasterIO( hWorkProximityBand, GF_Read, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; // Read pixel values. eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr != CE_None ) break; // Right to left. ProcessProximityLine( panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Left to right. ProcessProximityLine( panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Final post processing of distances. for( int i = 0; i < nXSize; i++ ) { if( pafProximity[i] < 0.0 ) pafProximity[i] = fNoDataValue; else if( pafProximity[i] > 0.0 ) { if( bFixedBufVal ) pafProximity[i] = static_cast<float>( dfFixedBufVal ); else pafProximity[i] = static_cast<float>(pafProximity[i] * dfDistMult); } } // Write out results. eErr = GDALRasterIO( hProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; if( !pfnProgress( 0.5 + 0.5 * (nYSize-iLine) / static_cast<double>( nYSize ), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree( panNearX ); CPLFree( panNearY ); CPLFree( panSrcScanline ); CPLFree( pafProximity ); CPLFree( panTargetValues ); if( hWorkProximityDS != NULL ) { CPLString osProxFile = GDALGetDescription( hWorkProximityDS ); GDALClose( hWorkProximityDS ); GDALDeleteDataset( GDALGetDriverByName( "GTiff" ), osProxFile ); } return eErr; }
GDALDataset * RCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, CPL_UNUSED int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { const int nBands = poSrcDS->GetRasterCount(); const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); const bool bASCII = CPLFetchBool(papszOptions, "ASCII", false); const bool bCompressed = CPLFetchBool(papszOptions, "COMPRESS", !bASCII); // Some some rudimentary checks. // Setup the filename to actually use. We prefix with // /vsigzip/ if we want compressed output. const CPLString osAdjustedFilename = std::string(bCompressed ? "/vsigzip/" : "") + pszFilename; // Create the file. VSILFILE *fp = VSIFOpenL(osAdjustedFilename, "wb"); if( fp == NULL ) { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create file %s.", pszFilename); return NULL; } // Write header with version, etc. if( bASCII ) { const char *pszHeader = "RDA2\nA\n"; VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp); } else { const char *pszHeader = "RDX2\nX\n"; VSIFWriteL(pszHeader, 1, strlen(pszHeader), fp); } RWriteInteger(fp, bASCII, 2); RWriteInteger(fp, bASCII, 133377); RWriteInteger(fp, bASCII, 131840); // Establish the primary pairlist with one component object. RWriteInteger(fp, bASCII, 1026); RWriteInteger(fp, bASCII, 1); // Write the object name. Eventually we should derive this // from the filename, possible with override by a creation option. RWriteString(fp, bASCII, "gg"); // For now we write the raster as a numeric array with attributes (526). RWriteInteger(fp, bASCII, 526); RWriteInteger(fp, bASCII, nXSize * nYSize * nBands); // Write the raster data. CPLErr eErr = CE_None; double *padfScanline = static_cast<double *>(CPLMalloc(nXSize * sizeof(double))); for( int iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBand *poBand = poSrcDS->GetRasterBand(iBand + 1); for( int iLine = 0; iLine < nYSize && eErr == CE_None; iLine++ ) { eErr = poBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfScanline, nXSize, 1, GDT_Float64, sizeof(double), 0, NULL); if( bASCII ) { for( int iValue = 0; iValue < nXSize; iValue++ ) { char szValue[128] = { '\0' }; CPLsnprintf(szValue, sizeof(szValue), "%.16g\n", padfScanline[iValue]); VSIFWriteL(szValue, 1, strlen(szValue), fp); } } else { for( int iValue = 0; iValue < nXSize; iValue++ ) CPL_MSBPTR64(padfScanline + iValue); VSIFWriteL(padfScanline, 8, nXSize, fp); } if( eErr == CE_None && !pfnProgress((iLine + 1) / static_cast<double>(nYSize), NULL, pProgressData) ) { eErr = CE_Failure; CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()"); } } } CPLFree(padfScanline); // Write out the dims attribute. RWriteInteger(fp, bASCII, 1026); RWriteInteger(fp, bASCII, 1); RWriteString(fp, bASCII, "dim"); RWriteInteger(fp, bASCII, 13); RWriteInteger(fp, bASCII, 3); RWriteInteger(fp, bASCII, nXSize); RWriteInteger(fp, bASCII, nYSize); RWriteInteger(fp, bASCII, nBands); RWriteInteger(fp, bASCII, 254); // Terminate overall pairlist. RWriteInteger(fp, bASCII, 254); // Cleanup. VSIFCloseL(fp); if( eErr != CE_None ) return NULL; // Re-open dataset, and copy any auxiliary pam information. GDALPamDataset *poDS = static_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly)); if( poDS ) poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT); return poDS; }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return nullptr; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return nullptr; } const int nBands = poSrcDS->GetRasterCount(); if( nBands != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 && nBands != 4 #endif ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 "or 4 (RGBA) " #endif "bands.", nBands ); return nullptr; } const GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return nullptr; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != nullptr ) { fQuality = static_cast<float>( CPLAtof(pszQUALITY) ); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return nullptr; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef( papszOptions, "PRESET", "DEFAULT" ); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return nullptr; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return nullptr; } // TODO: Get rid of this macro in a reasonable way. #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != nullptr) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return nullptr; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX-1); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = static_cast<float>(CPLAtof(pszPSNR)); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return nullptr; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); #if WEBP_ENCODER_ABI_VERSION >= 0x0002 FETCH_AND_SET_OPTION_INT("PARTITION_LIMIT", partition_limit, 0, 100); #endif #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sConfig.lossless = CPLFetchBool(papszOptions, "LOSSLESS", false); if (sConfig.lossless) sPicture.use_argb = 1; #endif if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return nullptr; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer = reinterpret_cast<GByte *>( VSIMalloc( nBands * nXSize * nYSize ) ); if (pabyBuffer == nullptr) { return nullptr; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return nullptr; } WebPUserData sUserData; sUserData.fp = fpImage; sUserData.pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress; sUserData.pProgressData = pProgressData; /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = &sUserData; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sPicture.progress_hook = WEBPDatasetProgressHook; #endif if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return nullptr; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, nBands, nullptr, nBands, nBands * nXSize, 1, nullptr ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ #if WEBP_ENCODER_ABI_VERSION >= 0x0100 if (eErr == CE_None && nBands == 4) { if (!WebPPictureImportRGBA(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError( CE_Failure, CPLE_AppDefined, "WebPPictureImportRGBA() failed" ); eErr = CE_Failure; } } else #endif if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { #if WEBP_ENCODER_ABI_VERSION >= 0x0100 const char* pszErrorMsg = nullptr; switch(sPicture.error_code) { case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break; case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break; case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break; case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break; case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break; case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less " "SEGMENTS, or increase PARTITION_LIMIT value"; break; case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break; case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while flushing bytes"; break; case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break; case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; default: CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode returned an unknown error code: %d", sPicture.error_code); pszErrorMsg = "Unknown WebP error type."; break; } CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed : %s", pszErrorMsg); #else CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); #endif eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return nullptr; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If writing to stdout, we can't reopen it, so return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = reinterpret_cast<WEBPDataset*>( WEBPDataset::Open( &oOpenInfo ) ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return nullptr; }
/** Apply a vertical shift grid to a source (DEM typically) dataset. * * hGridDataset will typically use WGS84 as horizontal datum (but this is * not a requirement) and its values are the values to add to go from geoid * elevations to WGS84 ellipsoidal heights. * * hGridDataset will be on-the-fly reprojected and resampled to the projection * and resolution of hSrcDataset, using bilinear resampling by default. * * Both hSrcDataset and hGridDataset must be single band datasets, and have * a valid geotransform and projection. * * On success, a reference will be taken on hSrcDataset and hGridDataset. * Reference counting semantics on the source and grid datasets should be * honoured. That is, don't just GDALClose() it, unless it was opened with * GDALOpenShared(), but rather use GDALReleaseDataset() if wanting to * immediately release the reference(s) and make the returned dataset the * owner of them. * * Valid use cases: * * \code * hSrcDataset = GDALOpen(...) * hGridDataset = GDALOpen(...) * hDstDataset = GDALApplyVerticalShiftGrid(hSrcDataset, hGridDataset, ...) * GDALReleaseDataset(hSrcDataset); * GDALReleaseDataset(hGridDataset); * if( hDstDataset ) * { * // Do things with hDstDataset * GDALClose(hDstDataset) // will close hSrcDataset and hGridDataset * } * \endcode * * @param hSrcDataset source (DEM) dataset. Must not be NULL. * @param hGridDataset vertical grid shift dataset. Must not be NULL. * @param bInverse if set to FALSE, hGridDataset values will be added to * hSrcDataset. If set to TRUE, they will be subtracted. * @param dfSrcUnitToMeter the factor to convert values from hSrcDataset to * meters (1.0 if source values are in meter). * @param dfDstUnitToMeter the factor to convert shifted values from meter * (1.0 if output values must be in meter). * @param papszOptions list of options, or NULL. Supported options are: * <ul> * <li>RESAMPLING=NEAREST/BILINEAR/CUBIC. Defaults to BILINEAR.</li> * <li>MAX_ERROR=val. Maximum error measured in input pixels that is allowed in * approximating the transformation (0.0 for exact calculations). Defaults * to 0.125</li> * <li>DATATYPE=Byte/UInt16/Int16/Float32/Float64. Output data type. If not * specified will be the same as the one of hSrcDataset. * <li>ERROR_ON_MISSING_VERT_SHIFT=YES/NO. Whether a missing/nodata value in * hGridDataset should cause I/O requests to fail. Default is NO (in which case * 0 will be used) * <li>SRC_SRS=srs_def. Override projection on hSrcDataset; * </ul> * * @return a new dataset corresponding to hSrcDataset adjusted with * hGridDataset, or NULL. If not NULL, it must be closed with GDALClose(). * * @since GDAL 2.2 */ GDALDatasetH GDALApplyVerticalShiftGrid( GDALDatasetH hSrcDataset, GDALDatasetH hGridDataset, int bInverse, double dfSrcUnitToMeter, double dfDstUnitToMeter, const char* const* papszOptions ) { VALIDATE_POINTER1( hSrcDataset, "GDALApplyVerticalShiftGrid", nullptr ); VALIDATE_POINTER1( hGridDataset, "GDALApplyVerticalShiftGrid", nullptr ); double adfSrcGT[6]; if( GDALGetGeoTransform(hSrcDataset, adfSrcGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no geotransform."); return nullptr; } const char* pszSrcProjection = CSLFetchNameValueDef(papszOptions, "SRC_SRS", GDALGetProjectionRef(hSrcDataset)); if( pszSrcProjection == nullptr || pszSrcProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hSrcDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band source dataset is supported."); return nullptr; } double adfGridGT[6]; if( GDALGetGeoTransform(hGridDataset, adfGridGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no geotransform."); return nullptr; } const char* pszGridProjection = GDALGetProjectionRef(hGridDataset); if( pszGridProjection == nullptr || pszGridProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hGridDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band grid dataset is supported."); return nullptr; } GDALDataType eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDataset,1)); const char* pszDataType = CSLFetchNameValue(papszOptions, "DATATYPE"); if( pszDataType ) eDT = GDALGetDataTypeByName(pszDataType); if( eDT == GDT_Unknown ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid DATATYPE=%s", pszDataType); return nullptr; } const int nSrcXSize = GDALGetRasterXSize(hSrcDataset); const int nSrcYSize = GDALGetRasterYSize(hSrcDataset); OGRSpatialReference oSRS; CPLString osSrcProjection(pszSrcProjection); oSRS.SetFromUserInput(osSrcProjection); if( oSRS.IsCompound() ) { OGR_SRSNode* poNode = oSRS.GetRoot()->GetChild(1); if( poNode != nullptr ) { char* pszWKT = nullptr; poNode->exportToWkt(&pszWKT); osSrcProjection = pszWKT; CPLFree(pszWKT); } } void* hTransform = GDALCreateGenImgProjTransformer3( pszGridProjection, adfGridGT, osSrcProjection, adfSrcGT ); if( hTransform == nullptr ) return nullptr; GDALWarpOptions* psWO = GDALCreateWarpOptions(); psWO->hSrcDS = hGridDataset; psWO->eResampleAlg = GRA_Bilinear; const char* pszResampling = CSLFetchNameValue(papszOptions, "RESAMPLING"); if( pszResampling ) { if( EQUAL(pszResampling, "NEAREST") ) psWO->eResampleAlg = GRA_NearestNeighbour; else if( EQUAL(pszResampling, "BILINEAR") ) psWO->eResampleAlg = GRA_Bilinear; else if( EQUAL(pszResampling, "CUBIC") ) psWO->eResampleAlg = GRA_Cubic; } psWO->eWorkingDataType = GDT_Float32; int bHasNoData = FALSE; const double dfSrcNoData = GDALGetRasterNoDataValue( GDALGetRasterBand(hGridDataset, 1), &bHasNoData ); if( bHasNoData ) { psWO->padfSrcNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); psWO->padfSrcNoDataReal[0] = dfSrcNoData; } psWO->padfDstNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); const bool bErrorOnMissingShift = CPLFetchBool( papszOptions, "ERROR_ON_MISSING_VERT_SHIFT", false ); psWO->padfDstNoDataReal[0] = (bErrorOnMissingShift) ? -std::numeric_limits<float>::infinity() : 0.0; psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions, "INIT_DEST", "NO_DATA"); psWO->pfnTransformer = GDALGenImgProjTransform; psWO->pTransformerArg = hTransform; const double dfMaxError = CPLAtof(CSLFetchNameValueDef(papszOptions, "MAX_ERROR", "0.125")); if( dfMaxError > 0.0 ) { psWO->pTransformerArg = GDALCreateApproxTransformer( psWO->pfnTransformer, psWO->pTransformerArg, dfMaxError ); psWO->pfnTransformer = GDALApproxTransform; GDALApproxTransformerOwnsSubtransformer(psWO->pTransformerArg, TRUE); } psWO->nBandCount = 1; psWO->panSrcBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panSrcBands[0] = 1; psWO->panDstBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panDstBands[0] = 1; VRTWarpedDataset* poReprojectedGrid = new VRTWarpedDataset(nSrcXSize, nSrcYSize); // This takes a reference on hGridDataset CPLErr eErr = poReprojectedGrid->Initialize(psWO); CPLAssert(eErr == CE_None); CPL_IGNORE_RET_VAL(eErr); GDALDestroyWarpOptions(psWO); poReprojectedGrid->SetGeoTransform(adfSrcGT); poReprojectedGrid->AddBand(GDT_Float32, nullptr); GDALApplyVSGDataset* poOutDS = new GDALApplyVSGDataset( reinterpret_cast<GDALDataset*>(hSrcDataset), poReprojectedGrid, eDT, CPL_TO_BOOL(bInverse), dfSrcUnitToMeter, dfDstUnitToMeter, // Undocumented option. For testing only atoi(CSLFetchNameValueDef(papszOptions, "BLOCKSIZE", "256")) ); poReprojectedGrid->ReleaseRef(); if( !poOutDS->IsInitOK() ) { delete poOutDS; return nullptr; } poOutDS->SetDescription( GDALGetDescription( hSrcDataset ) ); return reinterpret_cast<GDALDatasetH>(poOutDS); }
int OGRAmigoCloudDataSource::Open( const char * pszFilename, char** papszOpenOptionsIn, int bUpdateIn ) { bReadWrite = CPL_TO_BOOL(bUpdateIn); pszName = CPLStrdup( pszFilename ); pszProjectId = CPLStrdup(pszFilename + strlen("AMIGOCLOUD:")); char* pchSpace = strchr(pszProjectId, ' '); if( pchSpace ) *pchSpace = '\0'; if( pszProjectId[0] == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing project id"); return FALSE; } osAPIKey = CSLFetchNameValueDef(papszOpenOptionsIn, "AMIGOCLOUD_API_KEY", CPLGetConfigOption("AMIGOCLOUD_API_KEY", "")); if (osAPIKey.empty()) { osAPIKey = OGRAMIGOCLOUDGetOptionValue(pszFilename, "AMIGOCLOUD_API_KEY"); } if (osAPIKey.empty()) { CPLError(CE_Failure, CPLE_AppDefined, "AMIGOCLOUD_API_KEY is not defined.\n"); return FALSE; } OGRLayer* poSchemaLayer = ExecuteSQLInternal("SELECT current_schema()"); if( poSchemaLayer ) { OGRFeature* poFeat = poSchemaLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { osCurrentSchema = poFeat->GetFieldAsString(0); } delete poFeat; } ReleaseResultSet(poSchemaLayer); } if( osCurrentSchema.empty() ) return FALSE; CPLString osDatasets = OGRAMIGOCLOUDGetOptionValue(pszFilename, "datasets"); if (!osDatasets.empty()) { char** papszTables = CSLTokenizeString2(osDatasets, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*)); papoLayers[nLayers ++] = new OGRAmigoCloudTableLayer(this, papszTables[i]); } CSLDestroy(papszTables); // If OVERWRITE: YES, truncate the layer. if( nLayers==1 && CPLFetchBool(papszOpenOptionsIn, "OVERWRITE", false) ) { TruncateDataset(papoLayers[0]->GetTableName()); } return TRUE; } else { // If 'datasets' word is in the filename, but no dataset id specified, // print the list of available datasets if(std::string(pszFilename).find("datasets") != std::string::npos) ListDatasets(); } return TRUE; }
OGRLayer * OGRMySQLDataSource::ICreateLayer( const char * pszLayerNameIn, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { MYSQL_RES *hResult=nullptr; CPLString osCommand; const char *pszGeometryType; const char *pszGeomColumnName; const char *pszExpectedFIDName; char *pszLayerName; // int nDimension = 3; // MySQL only supports 2d currently /* -------------------------------------------------------------------- */ /* Make sure there isn't an active transaction already. */ /* -------------------------------------------------------------------- */ InterruptLongResult(); if( CPLFetchBool(papszOptions, "LAUNDER", true) ) pszLayerName = LaunderName( pszLayerNameIn ); else pszLayerName = CPLStrdup( pszLayerNameIn ); // if( wkbFlatten(eType) == eType ) // nDimension = 2; CPLDebug("MYSQL","Creating layer %s.", pszLayerName); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ for( int iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != nullptr && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszLayerName ); CPLFree( pszLayerName ); return nullptr; } } } pszGeomColumnName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if (!pszGeomColumnName) pszGeomColumnName="SHAPE"; pszExpectedFIDName = CSLFetchNameValue( papszOptions, "FID" ); if (!pszExpectedFIDName) pszExpectedFIDName = CSLFetchNameValue( papszOptions, "MYSQL_FID" ); if (!pszExpectedFIDName) pszExpectedFIDName="OGR_FID"; const bool bFID64 = CPLFetchBool(papszOptions, "FID64", false); const char* pszFIDType = bFID64 ? "BIGINT": "INT"; CPLDebug("MYSQL","Geometry Column Name %s.", pszGeomColumnName); CPLDebug("MYSQL","FID Column Name %s.", pszExpectedFIDName); const char *pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" ); const bool bHasSI = ( eType != wkbNone && (pszSI == nullptr || CPLTestBool(pszSI)) ); if( wkbFlatten(eType) == wkbNone ) { osCommand.Printf( "CREATE TABLE `%s` ( " " %s %s UNIQUE NOT NULL AUTO_INCREMENT )", pszLayerName, pszExpectedFIDName, pszFIDType ); } else { osCommand.Printf( "CREATE TABLE `%s` ( " " %s %s UNIQUE NOT NULL AUTO_INCREMENT, " " %s GEOMETRY %s)", pszLayerName, pszExpectedFIDName, pszFIDType, pszGeomColumnName, bHasSI ? "NOT NULL" : ""); } if( CSLFetchNameValue( papszOptions, "ENGINE" ) != nullptr ) { osCommand += " ENGINE = "; osCommand += CSLFetchNameValue( papszOptions, "ENGINE" ); } if( !mysql_query(GetConn(), osCommand ) ) { if( mysql_field_count( GetConn() ) == 0 ) CPLDebug("MYSQL","Created table %s.", pszLayerName); else { ReportError( osCommand ); return nullptr; } } else { ReportError( osCommand ); return nullptr; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; // Calling this does no harm InitializeMetadataTables(); /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ int nSRSId = GetUnknownSRID(); if( poSRS != nullptr ) nSRSId = FetchSRSId( poSRS ); /* -------------------------------------------------------------------- */ /* Sometimes there is an old crufty entry in the geometry_columns */ /* table if things were not properly cleaned up before. We make */ /* an effort to clean out such cruft. */ /* */ /* -------------------------------------------------------------------- */ osCommand.Printf( "DELETE FROM geometry_columns WHERE f_table_name = '%s'", pszLayerName ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return nullptr; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; /* -------------------------------------------------------------------- */ /* Attempt to add this table to the geometry_columns table, if */ /* it is a spatial layer. */ /* -------------------------------------------------------------------- */ if( eType != wkbNone ) { const int nCoordDimension = eType == wkbFlatten(eType) ? 2 : 3; pszGeometryType = OGRToOGCGeomType(eType); if( nSRSId == GetUnknownSRID() ) osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " TYPE) values " " ('%s', '%s', %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, pszGeometryType ); else osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " SRID, " " TYPE) values " " ('%s', '%s', %d, %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, nSRSId, pszGeometryType ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return nullptr; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; } /* -------------------------------------------------------------------- */ /* Create the spatial index. */ /* */ /* We're doing this before we add geometry and record to the table */ /* so this may not be exactly the best way to do it. */ /* -------------------------------------------------------------------- */ if( bHasSI ) { osCommand.Printf( "ALTER TABLE `%s` ADD SPATIAL INDEX(`%s`) ", pszLayerName, pszGeomColumnName); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return nullptr; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMySQLTableLayer *poLayer; OGRErr eErr; poLayer = new OGRMySQLTableLayer( this, pszLayerName, TRUE, nSRSId ); eErr = poLayer->Initialize(pszLayerName); if (eErr == OGRERR_FAILURE) return nullptr; if( eType != wkbNone ) poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->SetNullable(FALSE); poLayer->SetLaunderFlag( CPLFetchBool(papszOptions, "LAUNDER", true) ); poLayer->SetPrecisionFlag( CPLFetchBool(papszOptions, "PRECISION", true)); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRMySQLLayer **) CPLRealloc( papoLayers, sizeof(OGRMySQLLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszLayerName ); return poLayer; }
OGRLayer * OGROCIDataSource::ICreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { char szCommand[1024]; char *pszSafeLayerName = CPLStrdup(pszLayerName); poSession->CleanName( pszSafeLayerName ); CPLDebug( "OCI", "In Create Layer ..." ); bNoLogging = CPLFetchBool( papszOptions, "NO_LOGGING", false ); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; if( CPLFetchBool( papszOptions, "TRUNCATE", false ) ) { CPLDebug( "OCI", "Calling TruncateLayer for %s", pszLayerName ); TruncateLayer( pszSafeLayerName ); } else { for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszSafeLayerName, papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( pszSafeLayerName ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszSafeLayerName ); CPLFree( pszSafeLayerName ); return NULL; } } } } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ char szSRSId[100]; if( CSLFetchNameValue( papszOptions, "SRID" ) != NULL ) strcpy( szSRSId, CSLFetchNameValue( papszOptions, "SRID" ) ); else if( poSRS != NULL ) snprintf( szSRSId, sizeof(szSRSId), "%d", FetchSRSId( poSRS ) ); else strcpy( szSRSId, "NULL" ); /* -------------------------------------------------------------------- */ /* Determine name of geometry column to use. */ /* -------------------------------------------------------------------- */ const char *pszGeometryName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if( pszGeometryName == NULL ) pszGeometryName = "ORA_GEOMETRY"; const bool bGeomNullable = CPLFetchBool(papszOptions, "GEOMETRY_NULLABLE", true); /* -------------------------------------------------------------------- */ /* Create a basic table with the FID. Also include the */ /* geometry if this is not a PostGIS enabled table. */ /* -------------------------------------------------------------------- */ const char *pszExpectedFIDName = CPLGetConfigOption( "OCI_FID", "OGR_FID" ); OGROCIStatement oStatement( poSession ); /* -------------------------------------------------------------------- */ /* If geometry type is wkbNone, do not create a geometry column. */ /* -------------------------------------------------------------------- */ if ( CSLFetchNameValue( papszOptions, "TRUNCATE" ) == NULL ) { if (eType == wkbNone) { snprintf( szCommand, sizeof(szCommand), "CREATE TABLE \"%s\" ( " "%s INTEGER PRIMARY KEY)", pszSafeLayerName, pszExpectedFIDName); } else { snprintf( szCommand, sizeof(szCommand), "CREATE TABLE \"%s\" ( " "%s INTEGER PRIMARY KEY, " "%s %s%s )", pszSafeLayerName, pszExpectedFIDName, pszGeometryName, SDO_GEOMETRY, (!bGeomNullable) ? " NOT NULL":""); } if (bNoLogging) { char szCommand2[1024]; strncpy( szCommand2, szCommand, sizeof(szCommand) ); snprintf( szCommand, sizeof(szCommand), "%s NOLOGGING " "VARRAY %s.SDO_ELEM_INFO STORE AS SECUREFILE LOB (NOCACHE NOLOGGING) " "VARRAY %s.SDO_ORDINATES STORE AS SECUREFILE LOB (NOCACHE NOLOGGING) ", szCommand2, pszGeometryName, pszGeometryName); } if( oStatement.Execute( szCommand ) != CE_None ) { CPLFree( pszSafeLayerName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ const char *pszLoaderFile = CSLFetchNameValue(papszOptions,"LOADER_FILE"); OGROCIWritableLayer *poLayer; if( pszLoaderFile == NULL ) poLayer = new OGROCITableLayer( this, pszSafeLayerName, eType, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), TRUE, TRUE ); else poLayer = new OGROCILoaderLayer( this, pszSafeLayerName, pszGeometryName, EQUAL(szSRSId,"NULL") ? -1 : atoi(szSRSId), pszLoaderFile ); /* -------------------------------------------------------------------- */ /* Set various options on the layer. */ /* -------------------------------------------------------------------- */ poLayer->SetLaunderFlag( CPLFetchBool(papszOptions, "LAUNDER", false) ); poLayer->SetPrecisionFlag( CPLFetchBool(papszOptions, "PRECISION", true)); if( CSLFetchNameValue(papszOptions,"DIM") != NULL ) poLayer->SetDimension( atoi(CSLFetchNameValue(papszOptions,"DIM")) ); poLayer->SetOptions( papszOptions ); if( eType != wkbNone && !bGeomNullable ) poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->SetNullable(FALSE); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGROCILayer **) CPLRealloc( papoLayers, sizeof(OGROCILayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszSafeLayerName ); return poLayer; }
int OGRBNADataSource::Create( const char *pszFilename, char **papszOptions ) { if( fpOutput != nullptr) { CPLAssert( false ); return FALSE; } if( strcmp(pszFilename,"/dev/stdout") == 0 ) pszFilename = "/vsistdout/"; /* -------------------------------------------------------------------- */ /* Do not override exiting file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) == 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Create the output file. */ /* -------------------------------------------------------------------- */ pszName = CPLStrdup( pszFilename ); fpOutput = VSIFOpenL( pszFilename, "wb" ); if( fpOutput == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create BNA file %s.", pszFilename ); return FALSE; } /* EOL token */ const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); if( pszCRLFFormat == nullptr ) { #ifdef WIN32 bUseCRLF = true; #else bUseCRLF = false; #endif } else if( EQUAL(pszCRLFFormat,"CRLF") ) bUseCRLF = true; else if( EQUAL(pszCRLFFormat,"LF") ) bUseCRLF = false; else { CPLError( CE_Warning, CPLE_AppDefined, "LINEFORMAT=%s not understood, use one of CRLF or LF.", pszCRLFFormat ); #ifdef WIN32 bUseCRLF = true; #else bUseCRLF = false; #endif } /* Multi line or single line format ? */ bMultiLine = CPLFetchBool( papszOptions, "MULTILINE", true); /* Number of identifiers per record */ const char* pszNbOutID = CSLFetchNameValue ( papszOptions, "NB_IDS"); if (pszNbOutID == nullptr) { nbOutID = NB_MIN_BNA_IDS; } else if (EQUAL(pszNbOutID, "NB_SOURCE_FIELDS")) { nbOutID = -1; } else { nbOutID = atoi(pszNbOutID); if (nbOutID <= 0) { CPLError( CE_Warning, CPLE_AppDefined, "NB_ID=%s not understood. Must be >=%d and <=%d or equal to NB_SOURCE_FIELDS", pszNbOutID, NB_MIN_BNA_IDS, NB_MAX_BNA_IDS ); nbOutID = NB_MIN_BNA_IDS; } if (nbOutID > NB_MAX_BNA_IDS) { CPLError( CE_Warning, CPLE_AppDefined, "NB_ID=%s not understood. Must be >=%d and <=%d or equal to NB_SOURCE_FIELDS", pszNbOutID, NB_MIN_BNA_IDS, NB_MAX_BNA_IDS ); nbOutID = NB_MAX_BNA_IDS; } } /* Ellipses export as ellipses or polygons ? */ bEllipsesAsEllipses = CPLFetchBool( papszOptions, "ELLIPSES_AS_ELLIPSES", true); /* Number of coordinate pairs per line */ const char* pszNbPairPerLine = CSLFetchNameValue( papszOptions, "NB_PAIRS_PER_LINE"); if (pszNbPairPerLine) { nbPairPerLine = atoi(pszNbPairPerLine); if (nbPairPerLine <= 0) nbPairPerLine = (bMultiLine == FALSE) ? 1000000000 : 1; if (bMultiLine == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "NB_PAIR_PER_LINE option is ignored when MULTILINE=NO" ); } } else { nbPairPerLine = (bMultiLine == FALSE) ? 1000000000 : 1; } /* Coordinate precision */ const char* pszCoordinatePrecision = CSLFetchNameValue( papszOptions, "COORDINATE_PRECISION" ); if (pszCoordinatePrecision) { coordinatePrecision = atoi(pszCoordinatePrecision); if (coordinatePrecision <= 0) coordinatePrecision = 0; else if (coordinatePrecision >= 20) coordinatePrecision = 20; } else { coordinatePrecision = 10; } pszCoordinateSeparator = const_cast<char *>( CSLFetchNameValue( papszOptions, "COORDINATE_SEPARATOR" ) ); if (pszCoordinateSeparator == nullptr) pszCoordinateSeparator = CPLStrdup(","); else pszCoordinateSeparator = CPLStrdup(pszCoordinateSeparator); return TRUE; }
OGRLayer *OGRCARTODataSource::ICreateLayer( const char *pszNameIn, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { if (!bReadWrite) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return NULL; } /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszNameIn,papoLayers[iLayer]->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszNameIn ); return NULL; } } } CPLString osName(pszNameIn); if( CPLFetchBool(const_cast<const char**>(papszOptions), "LAUNDER", true) ) { char* pszTmp = OGRPGCommonLaunderName(pszNameIn); osName = pszTmp; CPLFree(pszTmp); } OGRCARTOTableLayer* poLayer = new OGRCARTOTableLayer(this, osName); const bool bGeomNullable = CPLFetchBool(const_cast<const char**>(papszOptions), "GEOMETRY_NULLABLE", true); int nSRID = (poSpatialRef && eGType != wkbNone) ? FetchSRSId( poSpatialRef ) : 0; bool bCartoify = CPLFetchBool(const_cast<const char**>(papszOptions), "CARTODBFY", CPLFetchBool(const_cast<const char**>(papszOptions), "CARTODBIFY", true)); if( bCartoify ) { if( nSRID != 4326 ) { if( eGType != wkbNone ) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot register table in dashboard with " "cdb_cartodbfytable() since its SRS is not EPSG:4326"); } bCartoify = false; } } poLayer->SetLaunderFlag( CPLFetchBool(const_cast<const char**>(papszOptions), "LAUNDER", true) ); poLayer->SetDeferredCreation(eGType, poSpatialRef, bGeomNullable, bCartoify); papoLayers = (OGRCARTOTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTOTableLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
OGRErr PDFWritableVectorDataset::SyncToDisk() { if (nLayers == 0 || !bModified) return OGRERR_NONE; bModified = FALSE; OGREnvelope sGlobalExtent; int bHasExtent = FALSE; for(int i=0;i<nLayers;i++) { OGREnvelope sExtent; if (papoLayers[i]->GetExtent(&sExtent) == OGRERR_NONE) { bHasExtent = TRUE; sGlobalExtent.Merge(sExtent); } } if (!bHasExtent || sGlobalExtent.MinX == sGlobalExtent.MaxX || sGlobalExtent.MinY == sGlobalExtent.MaxY) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot compute spatial extent of features"); return OGRERR_FAILURE; } PDFCompressMethod eStreamCompressMethod = COMPRESS_DEFLATE; const char* pszStreamCompressMethod = CSLFetchNameValue(papszOptions, "STREAM_COMPRESS"); if (pszStreamCompressMethod) { if( EQUAL(pszStreamCompressMethod, "NONE") ) eStreamCompressMethod = COMPRESS_NONE; else if( EQUAL(pszStreamCompressMethod, "DEFLATE") ) eStreamCompressMethod = COMPRESS_DEFLATE; else { CPLError( CE_Warning, CPLE_NotSupported, "Unsupported value for STREAM_COMPRESS."); } } const char* pszGEO_ENCODING = CSLFetchNameValueDef(papszOptions, "GEO_ENCODING", "ISO32000"); const char* pszDPI = CSLFetchNameValue(papszOptions, "DPI"); double dfDPI = DEFAULT_DPI; if( pszDPI != nullptr ) { dfDPI = CPLAtof(pszDPI); if (dfDPI < DEFAULT_DPI) dfDPI = DEFAULT_DPI; } else { dfDPI = DEFAULT_DPI; } const char* pszWriteUserUnit = CSLFetchNameValue(papszOptions, "WRITE_USERUNIT"); bool bWriteUserUnit; if( pszWriteUserUnit != nullptr ) bWriteUserUnit = CPLTestBool( pszWriteUserUnit ); else bWriteUserUnit = ( pszDPI == nullptr ); const char* pszNEATLINE = CSLFetchNameValue(papszOptions, "NEATLINE"); int nMargin = atoi(CSLFetchNameValueDef(papszOptions, "MARGIN", "0")); PDFMargins sMargins; sMargins.nLeft = nMargin; sMargins.nRight = nMargin; sMargins.nTop = nMargin; sMargins.nBottom = nMargin; const char* pszLeftMargin = CSLFetchNameValue(papszOptions, "LEFT_MARGIN"); if (pszLeftMargin) sMargins.nLeft = atoi(pszLeftMargin); const char* pszRightMargin = CSLFetchNameValue(papszOptions, "RIGHT_MARGIN"); if (pszRightMargin) sMargins.nRight = atoi(pszRightMargin); const char* pszTopMargin = CSLFetchNameValue(papszOptions, "TOP_MARGIN"); if (pszTopMargin) sMargins.nTop = atoi(pszTopMargin); const char* pszBottomMargin = CSLFetchNameValue(papszOptions, "BOTTOM_MARGIN"); if (pszBottomMargin) sMargins.nBottom = atoi(pszBottomMargin); const char* pszExtraImages = CSLFetchNameValue(papszOptions, "EXTRA_IMAGES"); const char* pszExtraStream = CSLFetchNameValue(papszOptions, "EXTRA_STREAM"); const char* pszExtraLayerName = CSLFetchNameValue(papszOptions, "EXTRA_LAYER_NAME"); const char* pszOGRDisplayField = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_FIELD"); const char* pszOGRDisplayLayerNames = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_LAYER_NAMES"); const bool bWriteOGRAttributes = CPLFetchBool(papszOptions, "OGR_WRITE_ATTRIBUTES", true); const char* pszOGRLinkField = CSLFetchNameValue(papszOptions, "OGR_LINK_FIELD"); const char* pszOffLayers = CSLFetchNameValue(papszOptions, "OFF_LAYERS"); const char* pszExclusiveLayers = CSLFetchNameValue(papszOptions, "EXCLUSIVE_LAYERS"); const char* pszJavascript = CSLFetchNameValue(papszOptions, "JAVASCRIPT"); const char* pszJavascriptFile = CSLFetchNameValue(papszOptions, "JAVASCRIPT_FILE"); /* -------------------------------------------------------------------- */ /* Create file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(GetDescription(), "wb"); if( fp == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create PDF file %s.\n", GetDescription() ); return OGRERR_FAILURE; } GDALPDFWriter oWriter(fp); double dfRatio = (sGlobalExtent.MaxY - sGlobalExtent.MinY) / (sGlobalExtent.MaxX - sGlobalExtent.MinX); int nWidth, nHeight; if (dfRatio < 1) { nWidth = 1024; nHeight = static_cast<int>(nWidth * dfRatio); } else { nHeight = 1024; nWidth = static_cast<int>(nHeight / dfRatio); } GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, nullptr ); double adfGeoTransform[6]; adfGeoTransform[0] = sGlobalExtent.MinX; adfGeoTransform[1] = (sGlobalExtent.MaxX - sGlobalExtent.MinX) / nWidth; adfGeoTransform[2] = 0; adfGeoTransform[3] = sGlobalExtent.MaxY; adfGeoTransform[4] = 0; adfGeoTransform[5] = - (sGlobalExtent.MaxY - sGlobalExtent.MinY) / nHeight; poSrcDS->SetGeoTransform(adfGeoTransform); OGRSpatialReference* poSRS = papoLayers[0]->GetSpatialRef(); if (poSRS) { char* pszWKT = nullptr; poSRS->exportToWkt(&pszWKT); poSrcDS->SetProjection(pszWKT); CPLFree(pszWKT); } oWriter.SetInfo(poSrcDS, papszOptions); oWriter.StartPage(poSrcDS, dfDPI, bWriteUserUnit, pszGEO_ENCODING, pszNEATLINE, &sMargins, eStreamCompressMethod, bWriteOGRAttributes); int iObj = 0; char** papszLayerNames = CSLTokenizeString2(pszOGRDisplayLayerNames,",",0); for(int i=0;i<nLayers;i++) { CPLString osLayerName; if (CSLCount(papszLayerNames) < nLayers) osLayerName = papoLayers[i]->GetName(); else osLayerName = papszLayerNames[i]; oWriter.WriteOGRLayer((OGRDataSourceH)this, i, pszOGRDisplayField, pszOGRLinkField, osLayerName, bWriteOGRAttributes, iObj); } CSLDestroy(papszLayerNames); oWriter.EndPage(pszExtraImages, pszExtraStream, pszExtraLayerName, pszOffLayers, pszExclusiveLayers); if (pszJavascript) oWriter.WriteJavascript(pszJavascript); else if (pszJavascriptFile) oWriter.WriteJavascriptFile(pszJavascriptFile); oWriter.Close(); delete poSrcDS; return OGRERR_NONE; }