OGRLayer *OGRDGNDataSource::CreateLayer( const char *pszLayerName, 
                                         OGRSpatialReference *poSRS, 
                                         OGRwkbGeometryType eGeomType, 
                                         char **papszExtraOptions )

{
    const char *pszSeed, *pszMasterUnit = "m", *pszSubUnit = "cm";
    const char *pszValue;
    int nUORPerSU=1, nSUPerMU=100;
    int nCreationFlags = 0, b3DRequested;
    double dfOriginX = -21474836.0,  /* default origin centered on zero */
           dfOriginY = -21474836.0,  /* with two decimals of precision */
           dfOriginZ = -21474836.0;

/* -------------------------------------------------------------------- */
/*      Ensure only one layer gets created.                             */
/* -------------------------------------------------------------------- */
    if( nLayers > 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "DGN driver only supports one layer will all the elements in it." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      If the coordinate system is geographic, we should use a         */
/*      localized default origin and resolution.                        */
/* -------------------------------------------------------------------- */
    if( poSRS != NULL && poSRS->IsGeographic() )
    {
        dfOriginX = -200.0;
        dfOriginY = -200.0;
        
        pszMasterUnit = "d";
        pszSubUnit = "s";
        nSUPerMU = 3600;
        nUORPerSU = 1000;
    }

/* -------------------------------------------------------------------- */
/*      Parse out various creation options.                             */
/* -------------------------------------------------------------------- */
    CSLInsertStrings( papszOptions, 0, papszExtraOptions );

    b3DRequested = CSLFetchBoolean( papszOptions, "3D", 
                                    (((int) eGeomType) & wkb25DBit) );

    pszSeed = CSLFetchNameValue( papszOptions, "SEED" );
    if( pszSeed )
        nCreationFlags |= DGNCF_USE_SEED_ORIGIN | DGNCF_USE_SEED_UNITS;
    else if( b3DRequested )
        pszSeed = CPLFindFile( "gdal", "seed_3d.dgn" );
    else
        pszSeed = CPLFindFile( "gdal", "seed_2d.dgn" );

    if( pszSeed == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "No seed file provided, and unable to find seed_2d.dgn." );
        return NULL;
    }
    
    if( CSLFetchBoolean( papszOptions, "COPY_WHOLE_SEED_FILE", TRUE ) )
        nCreationFlags |= DGNCF_COPY_WHOLE_SEED_FILE;
    if( CSLFetchBoolean( papszOptions, "COPY_SEED_FILE_COLOR_TABLE", TRUE ) )
        nCreationFlags |= DGNCF_COPY_SEED_FILE_COLOR_TABLE;
    
    pszValue = CSLFetchNameValue( papszOptions, "MASTER_UNIT_NAME" );
    if( pszValue != NULL )
    {
        nCreationFlags &= ~DGNCF_USE_SEED_UNITS;
        pszMasterUnit = pszValue;
    }
    
    pszValue = CSLFetchNameValue( papszOptions, "SUB_UNIT_NAME" );
    if( pszValue != NULL )
    {
        nCreationFlags &= ~DGNCF_USE_SEED_UNITS;
        pszSubUnit = pszValue;
    }


    pszValue = CSLFetchNameValue( papszOptions, "SUB_UNITS_PER_MASTER_UNIT" );
    if( pszValue != NULL )
    {
        nCreationFlags &= ~DGNCF_USE_SEED_UNITS;
        nSUPerMU = atoi(pszValue);
    }

    pszValue = CSLFetchNameValue( papszOptions, "UOR_PER_SUB_UNIT" );
    if( pszValue != NULL )
    {
        nCreationFlags &= ~DGNCF_USE_SEED_UNITS;
        nUORPerSU = atoi(pszValue);
    }

    pszValue = CSLFetchNameValue( papszOptions, "ORIGIN" );
    if( pszValue != NULL )
    {
        char **papszTuple = CSLTokenizeStringComplex( pszValue, " ,", 
                                                      FALSE, FALSE );

        nCreationFlags &= ~DGNCF_USE_SEED_ORIGIN;
        if( CSLCount(papszTuple) == 3 )
        {
            dfOriginX = atof(papszTuple[0]);
            dfOriginY = atof(papszTuple[1]);
            dfOriginZ = atof(papszTuple[2]);
        }
        else if( CSLCount(papszTuple) == 2 )
        {
            dfOriginX = atof(papszTuple[0]);
            dfOriginY = atof(papszTuple[1]);
            dfOriginZ = 0.0;
        }
        else
        {
            CSLDestroy(papszTuple);
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "ORIGIN is not a valid 2d or 3d tuple.\n"
                      "Separate tuple values with comma." );
            return FALSE;
        }
        CSLDestroy(papszTuple);
    }

/* -------------------------------------------------------------------- */
/*      Try creating the base file.                                     */
/* -------------------------------------------------------------------- */
    hDGN = DGNCreate( pszName, pszSeed, nCreationFlags, 
                      dfOriginX, dfOriginY, dfOriginZ, 
                      nSUPerMU, nUORPerSU, pszMasterUnit, pszSubUnit );
    if( hDGN == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
    OGRDGNLayer *poLayer;

    poLayer = new OGRDGNLayer( pszLayerName, hDGN, TRUE );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRDGNLayer **)
        CPLRealloc( papoLayers,  sizeof(OGRDGNLayer *) * (nLayers+1) );
    papoLayers[nLayers++] = poLayer;
    
    return poLayer;
}
Example #2
0
GDALDataset *AirSARDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( poOpenInfo->fpL == NULL || poOpenInfo->nHeaderBytes < 800 )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Check for AirSAR/ keyword.                                      */
/* -------------------------------------------------------------------- */
    if( !STARTS_WITH_CI((char *) poOpenInfo->pabyHeader, "RECORD LENGTH IN BYTES") )
        return NULL;

    if( strstr((char *) poOpenInfo->pabyHeader, "COMPRESSED") == NULL
        || strstr((char *) poOpenInfo->pabyHeader, "JPL AIRCRAFT") == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Parse the header fields.  We turn all the transform the         */
/*      keywords by converting spaces to underscores so they will be    */
/*      "well behaved" as metadata keywords.                            */
/* -------------------------------------------------------------------- */
    char **papszMD = ReadHeader( poOpenInfo->fpL, 0, "MH", 20 );

    if( papszMD == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The AIRSAR driver does not support update access to existing"
                  " datasets.\n" );
        CSLDestroy( papszMD );
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    AirSARDataset *poDS = new AirSARDataset();

/* -------------------------------------------------------------------- */
/*      Extract some key information.                                   */
/* -------------------------------------------------------------------- */

    poDS->nRasterXSize =
        atoi(CSLFetchNameValue(papszMD,"MH_NUMBER_OF_SAMPLES_PER_RECORD"));
    poDS->nRasterYSize =
        atoi(CSLFetchNameValue(papszMD,"MH_NUMBER_OF_LINES_IN_IMAGE"));

    poDS->nRecordLength = atoi(
        CSLFetchNameValue( papszMD, "MH_RECORD_LENGTH_IN_BYTES" ) );

    poDS->nDataStart = atoi(
        CSLFetchNameValue( papszMD, "MH_BYTE_OFFSET_OF_FIRST_DATA_RECORD" ));

/* -------------------------------------------------------------------- */
/*      Adopt the openinfo file pointer.                                */
/* -------------------------------------------------------------------- */
    poDS->fp = poOpenInfo->fpL;
    poOpenInfo->fpL = NULL;

/* -------------------------------------------------------------------- */
/*      Read and merge parameter header into metadata.  Prefix          */
/*      parameter header values with PH_.                               */
/* -------------------------------------------------------------------- */
    int nPHOffset = 0;

    if( CSLFetchNameValue( papszMD,
                           "MH_BYTE_OFFSET_OF_PARAMETER_HEADER" ) != NULL )
    {
        nPHOffset = atoi(CSLFetchNameValue(
                        papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER"));
        char **papszPHInfo = ReadHeader( poDS->fp, nPHOffset, "PH", 100 );

        papszMD = CSLInsertStrings( papszMD, CSLCount(papszMD), papszPHInfo );

        CSLDestroy( papszPHInfo );
    }

/* -------------------------------------------------------------------- */
/*      Read and merge calibration header into metadata.  Prefix        */
/*      parameter header values with CH_.                               */
/* -------------------------------------------------------------------- */
    if( nPHOffset != 0 )
    {
        char **papszCHInfo = ReadHeader( poDS->fp,
                                         nPHOffset+poDS->nRecordLength,
                                         "CH", 18 );

        papszMD = CSLInsertStrings( papszMD, CSLCount(papszMD), papszCHInfo );

        CSLDestroy( papszCHInfo );
    }

/* -------------------------------------------------------------------- */
/*      Assign metadata to dataset.                                     */
/* -------------------------------------------------------------------- */
    poDS->SetMetadata( papszMD );
    CSLDestroy( papszMD );

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->SetBand( 1, new AirSARRasterBand( poDS, 1 ));
    poDS->SetBand( 2, new AirSARRasterBand( poDS, 2 ));
    poDS->SetBand( 3, new AirSARRasterBand( poDS, 3 ));
    poDS->SetBand( 4, new AirSARRasterBand( poDS, 4 ));
    poDS->SetBand( 5, new AirSARRasterBand( poDS, 5 ));
    poDS->SetBand( 6, new AirSARRasterBand( poDS, 6 ));

    poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SYMMETRIZED_COVARIANCE" );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}