Esempio n. 1
0
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;
}
Esempio n. 3
0
/*
 * 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 );
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
    }
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
/*
 * 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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
/** 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);
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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;
}
Esempio n. 21
0
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;
}