예제 #1
0
int main( int nArgc, char ** papszArgv )

{
    int   nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg;
    const char *pszFormat = "ESRI Shapefile";
    const char *pszTileIndexField = "LOCATION";
    const char *pszOutputName = NULL;
    int write_absolute_path = FALSE;
    int skip_different_projection = FALSE;
    char* current_path = NULL;
    int accept_different_schemas = FALSE;
    int bFirstWarningForNonMatchingAttributes = TRUE;
    
    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(papszArgv[0]))
        exit(1);
/* -------------------------------------------------------------------- */
/*      Register format(s).                                             */
/* -------------------------------------------------------------------- */
    OGRRegisterAll();
    
/* -------------------------------------------------------------------- */
/*      Processing command line arguments.                              */
/* -------------------------------------------------------------------- */
    for( iArg = 1; iArg < nArgc; iArg++ )
    {
        if( EQUAL(papszArgv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 )
        {
            pszFormat = papszArgv[++iArg];
        }
        else if( EQUAL(papszArgv[iArg],"-write_absolute_path"))
        {
            write_absolute_path = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-skip_different_projection"))
        {
            skip_different_projection = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-accept_different_schemas"))
        {
            accept_different_schemas = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 )
        {
            pszTileIndexField = papszArgv[++iArg];
        }
        else if( EQUAL(papszArgv[iArg],"-lnum") 
                 || EQUAL(papszArgv[iArg],"-lname") )
        {
            iArg++;
            bLayersWildcarded = FALSE;
        }
        else if( papszArgv[iArg][0] == '-' )
            Usage();
        else if( pszOutputName == NULL )
            pszOutputName = papszArgv[iArg];
        else if( nFirstSourceDataset == -1 )
            nFirstSourceDataset = iArg;
    }

    if( pszOutputName == NULL || nFirstSourceDataset == -1 )
        Usage();

/* -------------------------------------------------------------------- */
/*      Try to open as an existing dataset for update access.           */
/* -------------------------------------------------------------------- */
    GDALDataset *poDstDS;
    OGRLayer *poDstLayer = NULL;

    poDstDS = (GDALDataset*) OGROpen( pszOutputName, TRUE, NULL );

/* -------------------------------------------------------------------- */
/*      If that failed, find the driver so we can create the tile index.*/
/* -------------------------------------------------------------------- */
    if( poDstDS == NULL )
    {
        OGRSFDriverRegistrar     *poR = OGRSFDriverRegistrar::GetRegistrar();
        GDALDriver              *poDriver = NULL;
        int                      iDriver;

        for( iDriver = 0;
             iDriver < poR->GetDriverCount() && poDriver == NULL;
             iDriver++ )
        {
            if( EQUAL(poR->GetDriver(iDriver)->GetDescription(),pszFormat) )
            {
                poDriver = poR->GetDriver(iDriver);
            }
        }

        if( poDriver == NULL )
        {
            fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
            fprintf( stderr, "The following drivers are available:\n" );
        
            for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
            {
                fprintf( stderr, "  -> `%s'\n", poR->GetDriver(iDriver)->GetDescription() );
            }
            exit( 1 );
        }

        if( !CSLTestBoolean( CSLFetchNameValueDef(poDriver->GetMetadata(), GDAL_DCAP_CREATE, "FALSE") ) )
        {
            fprintf( stderr, "%s driver does not support data source creation.\n",
                    pszFormat );
            exit( 1 );
        }

/* -------------------------------------------------------------------- */
/*      Now create it.                                                  */
/* -------------------------------------------------------------------- */
        
        poDstDS = poDriver->Create( pszOutputName, 0, 0, 0, GDT_Unknown, NULL );
        if( poDstDS == NULL )
        {
            fprintf( stderr, "%s driver failed to create %s\n", 
                    pszFormat, pszOutputName );
            exit( 1 );
        }

        if( poDstDS->GetLayerCount() == 0 )
        {
            OGRFieldDefn oLocation( pszTileIndexField, OFTString );
            
            oLocation.SetWidth( 200 );
            
            if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' )
            {
                nFirstSourceDataset++;
            }
            
            OGRSpatialReference* poSrcSpatialRef = NULL;
            
            /* Fetches the SRS of the first layer and use it when creating the tileindex layer */
            if (nFirstSourceDataset < nArgc)
            {
                GDALDataset* poDS = (GDALDataset*) OGROpen(papszArgv[nFirstSourceDataset], FALSE, NULL);
                if (poDS)
                {
                    int iLayer;

                    for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
                    {
                        int bRequested = bLayersWildcarded;
                        OGRLayer *poLayer = poDS->GetLayer(iLayer);

                        for( iArg = 1; iArg < nArgc && !bRequested; iArg++ )
                        {
                            if( EQUAL(papszArgv[iArg],"-lnum") 
                                && atoi(papszArgv[iArg+1]) == iLayer )
                                bRequested = TRUE;
                            else if( EQUAL(papszArgv[iArg],"-lname") 
                                     && EQUAL(papszArgv[iArg+1],
                                              poLayer->GetLayerDefn()->GetName()) )
                                bRequested = TRUE;
                        }

                        if( !bRequested )
                            continue;
                            
                        if ( poLayer->GetSpatialRef() )
                            poSrcSpatialRef = poLayer->GetSpatialRef()->Clone();
                        break;
                    }
                }
                
                GDALClose( (GDALDatasetH)poDS );
            }

            poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef );
            poDstLayer->CreateField( &oLocation, OFTString );
            
            OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef );
        }
    }

/* -------------------------------------------------------------------- */
/*      Identify target layer and field.                                */
/* -------------------------------------------------------------------- */
    int   iTileIndexField;

    poDstLayer = poDstDS->GetLayer(0);
    if( poDstLayer == NULL )
    {
        fprintf( stderr, "Can't find any layer in output tileindex!\n" );
        exit( 1 );
    }

    iTileIndexField = 
        poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField );
    if( iTileIndexField == -1 )
    {
        fprintf( stderr, "Can't find %s field in tile index dataset.\n", 
                pszTileIndexField );
        exit( 1 );
    }

    OGRFeatureDefn* poFeatureDefn = NULL;

    /* Load in memory existing file names in SHP */
    int nExistingLayers = 0;
    char** existingLayersTab = NULL;
    OGRSpatialReference* alreadyExistingSpatialRef = NULL;
    int alreadyExistingSpatialRefValid = FALSE;
    nExistingLayers = poDstLayer->GetFeatureCount();
    if (nExistingLayers)
    {
        int i;
        existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*));
        for(i=0;i<nExistingLayers;i++)
        {
            OGRFeature* feature = poDstLayer->GetNextFeature();
            existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField));
            if (i == 0)
            {
                GDALDataset       *poDS;
                char* filename = CPLStrdup(existingLayersTab[i]);
                int j;
                for(j=strlen(filename)-1;j>=0;j--)
                {
                    if (filename[j] == ',')
                        break;
                }
                if (j >= 0)
                {
                    int iLayer = atoi(filename + j + 1);
                    filename[j] = 0;
                    poDS = (GDALDataset*) OGROpen(filename, FALSE, NULL);
                    if (poDS)
                    {
                        OGRLayer *poLayer = poDS->GetLayer(iLayer);
                        if (poLayer)
                        {
                            alreadyExistingSpatialRefValid = TRUE;
                            alreadyExistingSpatialRef =
                                    (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL;
                                    
                            if (poFeatureDefn == NULL)
                                poFeatureDefn = poLayer->GetLayerDefn()->Clone();
                        }
                        GDALClose( (GDALDatasetH)poDS );
                    }
                }
            }
        }
    }


    if (write_absolute_path)
    {
        current_path = CPLGetCurrentDir();
        if (current_path == NULL)
        {
            fprintf( stderr, "This system does not support the CPLGetCurrentDir call. "
                             "The option -write_absolute_path will have no effect\n");
            write_absolute_path = FALSE;
        }
    }
/* ==================================================================== */
/*      Process each input datasource in turn.                          */
/* ==================================================================== */

	for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ )
    {
        int i;
        GDALDataset       *poDS;

        if( papszArgv[nFirstSourceDataset][0] == '-' )
        {
            nFirstSourceDataset++;
            continue;
        }
        
        char* fileNameToWrite;
        VSIStatBuf sStatBuf;

        if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) &&
            VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0)
        {
            fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset]));
        }
        else
        {
            fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]);
        }

        poDS = (GDALDataset*) OGROpen( papszArgv[nFirstSourceDataset], FALSE, NULL );

        if( poDS == NULL )
        {
            fprintf( stderr, "Failed to open dataset %s, skipping.\n", 
                    papszArgv[nFirstSourceDataset] );
            CPLFree(fileNameToWrite);
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Check all layers, and see if they match requests.               */
/* -------------------------------------------------------------------- */
        int iLayer;

        for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
        {
            int bRequested = bLayersWildcarded;
            OGRLayer *poLayer = poDS->GetLayer(iLayer);

            for( iArg = 1; iArg < nArgc && !bRequested; iArg++ )
            {
                if( EQUAL(papszArgv[iArg],"-lnum") 
                    && atoi(papszArgv[iArg+1]) == iLayer )
                    bRequested = TRUE;
                else if( EQUAL(papszArgv[iArg],"-lname") 
                         && EQUAL(papszArgv[iArg+1],
                                  poLayer->GetLayerDefn()->GetName()) )
                    bRequested = TRUE;
            }

            if( !bRequested )
                continue;

            /* Checks that the layer is not already in tileindex */
            for(i=0;i<nExistingLayers;i++)
            {
                char        szLocation[5000];
                sprintf( szLocation, "%s,%d", 
                        fileNameToWrite, iLayer );
                if (EQUAL(szLocation, existingLayersTab[i]))
                {
                    fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n",
                            iLayer, papszArgv[nFirstSourceDataset]);
                    break;
                }
            }
            if (i != nExistingLayers)
            {
                continue;
            }

            OGRSpatialReference* spatialRef = poLayer->GetSpatialRef();
            if (alreadyExistingSpatialRefValid)
            {
                if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL &&
                     spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) ||
                    ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL)))
                {
                    fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as "
                                "other files in the tileindex. This may cause problems when "
                                "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset],
                                (skip_different_projection) ? " Skipping it" : "");
                    if (skip_different_projection)
                    {
                        continue;
                    }
                }
            }
            else
            {
                alreadyExistingSpatialRefValid = TRUE;
                alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL;
            }

/* -------------------------------------------------------------------- */
/*		Check if all layers in dataset have the same attributes	schema. */
/* -------------------------------------------------------------------- */
			if( poFeatureDefn == NULL )
			{
				poFeatureDefn = poLayer->GetLayerDefn()->Clone();
			}
			else if ( !accept_different_schemas )
			{
				OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn();
				assert(NULL != poFeatureDefnCur);

				int fieldCount = poFeatureDefnCur->GetFieldCount();

				if( fieldCount != poFeatureDefn->GetFieldCount())
				{
					fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n",
                             poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]);
                    if (bFirstWarningForNonMatchingAttributes)
                    {
                        fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n"
                                         "but this may result in a tileindex incompatible with MapServer\n");
                        bFirstWarningForNonMatchingAttributes = FALSE;
                    }
					continue;
				}
				
                int bSkip = FALSE;
				for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ )
				{
 					OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn);
 					OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn);

					/* XXX - Should those pointers be checked against NULL? */ 
					assert(NULL != poField);
					assert(NULL != poFieldCur);

					if( poField->GetType() != poFieldCur->GetType() 
						|| poField->GetWidth() != poFieldCur->GetWidth() 
						|| poField->GetPrecision() != poFieldCur->GetPrecision() 
						|| !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) )
					{
						fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n",
                                 poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]);
                        if (bFirstWarningForNonMatchingAttributes)
                        {
                            fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n"
                                             "but this may result in a tileindex incompatible with MapServer\n");
                            bFirstWarningForNonMatchingAttributes = FALSE;
                        }
                        bSkip = TRUE; 
                        break;
					}
				}
                
                if (bSkip)
                    continue;
			}


/* -------------------------------------------------------------------- */
/*      Get layer extents, and create a corresponding polygon           */
/*      geometry.                                                       */
/* -------------------------------------------------------------------- */
            OGREnvelope sExtents;
            OGRPolygon oRegion;
            OGRLinearRing oRing;

            if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE )
            {
                fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", 
                        poLayer->GetLayerDefn()->GetName(), 
                        papszArgv[nFirstSourceDataset] );
                continue;
            }
            
            oRing.addPoint( sExtents.MinX, sExtents.MinY );
            oRing.addPoint( sExtents.MinX, sExtents.MaxY );
            oRing.addPoint( sExtents.MaxX, sExtents.MaxY );
            oRing.addPoint( sExtents.MaxX, sExtents.MinY );
            oRing.addPoint( sExtents.MinX, sExtents.MinY );

            oRegion.addRing( &oRing );

/* -------------------------------------------------------------------- */
/*      Add layer to tileindex.                                         */
/* -------------------------------------------------------------------- */
            char        szLocation[5000];
            OGRFeature  oTileFeat( poDstLayer->GetLayerDefn() );

            sprintf( szLocation, "%s,%d", 
                     fileNameToWrite, iLayer );
            oTileFeat.SetGeometry( &oRegion );
            oTileFeat.SetField( iTileIndexField, szLocation );

            if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE )
            {
                fprintf( stderr, "Failed to create feature on tile index ... terminating." );
                GDALClose( (GDALDatasetH) poDstDS );
                exit( 1 );
            }
        }

/* -------------------------------------------------------------------- */
/*      Cleanup this data source.                                       */
/* -------------------------------------------------------------------- */
        CPLFree(fileNameToWrite);
        GDALClose( (GDALDatasetH)poDS );
    }

/* -------------------------------------------------------------------- */
/*      Close tile index and clear buffers.                             */
/* -------------------------------------------------------------------- */
    GDALClose( (GDALDatasetH) poDstDS );
	OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn );
  
    if (alreadyExistingSpatialRef != NULL)
        OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef );
  
    CPLFree(current_path);
    
    if (nExistingLayers)
    {
        int i;
        for(i=0;i<nExistingLayers;i++)
        {
            CPLFree(existingLayersTab[i]);
        }
        CPLFree(existingLayersTab);
    }

    OGRCleanupAll();

    return 0;
}
예제 #2
0
void IDADataset::ProcessGeoref()

{
    OGRSpatialReference oSRS;

    if( nProjection == 3 ) 
    {
        oSRS.SetWellKnownGeogCS( "WGS84" );
    }
    else if( nProjection == 4 ) 
    {
        oSRS.SetLCC( dfParallel1, dfParallel2, 
                     dfLatCenter, dfLongCenter, 
                     0.0, 0.0 );
        oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 
                        6378206.4, 293.97869821389662 );
    }
    else if( nProjection == 6 ) 
    {
        oSRS.SetLAEA( dfLatCenter, dfLongCenter, 0.0, 0.0 );
        oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 
                        6370997.0, 0.0 );
    }
    else if( nProjection == 8 )
    {
        oSRS.SetACEA( dfParallel1, dfParallel2, 
                      dfLatCenter, dfLongCenter, 
                      0.0, 0.0 );
        oSRS.SetGeogCS( "Clarke 1866", "Clarke 1866", "Clarke 1866", 
                        6378206.4, 293.97869821389662 );
    }
    else if( nProjection == 9 ) 
    {
        oSRS.SetGH( dfLongCenter, 0.0, 0.0 );
        oSRS.SetGeogCS( "Sphere", "Sphere", "Sphere", 
                        6370997.0, 0.0 );
    }

    if( oSRS.GetRoot() != NULL )
    {
        CPLFree( pszProjection );
        pszProjection = NULL;

        oSRS.exportToWkt( &pszProjection );
    }

    adfGeoTransform[0] = 0 - dfDX * dfXCenter;
    adfGeoTransform[1] = dfDX;
    adfGeoTransform[2] = 0.0;
    adfGeoTransform[3] =  dfDY * dfYCenter;
    adfGeoTransform[4] = 0.0;
    adfGeoTransform[5] = -dfDY;

    if( nProjection == 3 )
    {
        adfGeoTransform[0] += dfLongCenter;
        adfGeoTransform[3] += dfLatCenter;
    }
}
CPLErr GDALRasterizeLayersBuf(void *pData, int nBufXSize, int nBufYSize,
                              GDALDataType eBufType,
                              int nPixelSpace, int nLineSpace,
                              int nLayerCount, OGRLayerH *pahLayers,
                              const char *pszDstProjection,
                              double *padfDstGeoTransform,
                              GDALTransformerFunc pfnTransformer,
                              void *pTransformArg, double dfBurnValue,
                              char **papszOptions,
                              GDALProgressFunc pfnProgress,
                              void *pProgressArg)

{
#ifndef OGR_ENABLED
    CPLError(CE_Failure, CPLE_NotSupported, "GDALRasterizeLayersBuf() unimplemented in a non OGR build");
    return CE_Failure;
#else
/* -------------------------------------------------------------------- */
/*      If pixel and line spaceing are defaulted assign reasonable      */
/*      value assuming a packed buffer.                                 */
/* -------------------------------------------------------------------- */
    if (nPixelSpace == 0)
        nPixelSpace = GDALGetDataTypeSize(eBufType) / 8;

    if (nLineSpace == 0)
        nLineSpace = nPixelSpace * nBufXSize;

    if (pfnProgress == NULL)
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if (nLayerCount == 0)
        return CE_None;

    int              bAllTouched      = CSLFetchBoolean(papszOptions, "ALL_TOUCHED", FALSE);
    const char       *pszOpt          = CSLFetchNameValue(papszOptions, "BURN_VALUE_FROM");
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if (pszOpt)
    {
        if (EQUAL(pszOpt, "Z"))
            eBurnValueSource = GBV_Z;

        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* ==================================================================== */
/*      Read thes pecified layers transfoming and rasterizing           */
/*      geometries.                                                     */
/* ==================================================================== */
    CPLErr     eErr = CE_None;
    int        iLayer;
    const char *pszBurnAttribute =
        CSLFetchNameValue(papszOptions, "ATTRIBUTE");

    pfnProgress(0.0, NULL, pProgressArg);

    for (iLayer = 0; iLayer < nLayerCount; iLayer++)
    {
        int      iBurnField = -1;
        OGRLayer *poLayer   = (OGRLayer*) pahLayers[iLayer];

        if (!poLayer)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Layer element number %d is NULL, skipping.\n", iLayer);
            continue;
        }

/* -------------------------------------------------------------------- */
/*      If the layer does not contain any features just skip it.        */
/*      Do not force the feature count, so if driver doesn't know       */
/*      exact number of features, go down the normal way.               */
/* -------------------------------------------------------------------- */
        if (poLayer->GetFeatureCount(FALSE) == 0)
            continue;

        if (pszBurnAttribute)
        {
            iBurnField =
                poLayer->GetLayerDefn()->GetFieldIndex(pszBurnAttribute);
            if (iBurnField == -1)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Failed to find field %s on layer %s, skipping.\n",
                         pszBurnAttribute,
                         poLayer->GetLayerDefn()->GetName());
                continue;
            }
        }

/* -------------------------------------------------------------------- */
/*      If we have no transformer, create the one from input file       */
/*      projection. Note that each layer can be georefernced            */
/*      separately.                                                     */
/* -------------------------------------------------------------------- */
        int bNeedToFreeTransformer = FALSE;

        if (pfnTransformer == NULL)
        {
            char *pszProjection = NULL;
            bNeedToFreeTransformer = TRUE;

            OGRSpatialReference *poSRS = poLayer->GetSpatialRef();
            if (!poSRS)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Failed to fetch spatial reference on layer %s "
                         "to build transformer, assuming matching coordinate systems.\n",
                         poLayer->GetLayerDefn()->GetName());
            }
            else
                poSRS->exportToWkt(&pszProjection);

            pTransformArg =
                GDALCreateGenImgProjTransformer3(pszProjection, NULL,
                                                 pszDstProjection,
                                                 padfDstGeoTransform);
            pfnTransformer = GDALGenImgProjTransform;

            CPLFree(pszProjection);
        }

        OGRFeature *poFeat;

        poLayer->ResetReading();

        while ((poFeat = poLayer->GetNextFeature()) != NULL)
        {
            OGRGeometry *poGeom = poFeat->GetGeometryRef();

            if (pszBurnAttribute)
                dfBurnValue = poFeat->GetFieldAsDouble(iBurnField);

            gv_rasterize_one_shape((unsigned char*) pData, 0,
                                   nBufXSize, nBufYSize,
                                   1, eBufType, bAllTouched, poGeom,
                                   &dfBurnValue, eBurnValueSource,
                                   pfnTransformer, pTransformArg);

            delete poFeat;
        }

        poLayer->ResetReading();

        if (!pfnProgress(1, "", pProgressArg))
        {
            CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated");
            eErr = CE_Failure;
        }

        if (bNeedToFreeTransformer)
        {
            GDALDestroyTransformer(pTransformArg);
            pTransformArg  = NULL;
            pfnTransformer = NULL;
        }
    }

    return eErr;
#endif /* def OGR_ENABLED */
}
예제 #4
0
GDALDataset *HF2Dataset::Open( GDALOpenInfo * poOpenInfo )

{
    CPLString osOriginalFilename(poOpenInfo->pszFilename);

    if (!Identify(poOpenInfo))
        return NULL;

    GDALOpenInfo* poOpenInfoToDelete = NULL;
    /*  GZipped .hf2 files are common, so automagically open them */
    /*  if the /vsigzip/ has not been explicitely passed */
    CPLString osFilename(poOpenInfo->pszFilename);
    if ((EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "hfz") ||
        (strlen(poOpenInfo->pszFilename) > 6 &&
         EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "hf2.gz"))) &&
         !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
    {
        osFilename = "/vsigzip/";
        osFilename += poOpenInfo->pszFilename;
        poOpenInfo = poOpenInfoToDelete =
                new GDALOpenInfo(osFilename.c_str(), GA_ReadOnly,
                                 poOpenInfo->papszSiblingFiles);
    }

/* -------------------------------------------------------------------- */
/*      Parse header                                                    */
/* -------------------------------------------------------------------- */

    int nXSize, nYSize;
    memcpy(&nXSize, poOpenInfo->pabyHeader + 6, 4);
    CPL_LSBPTR32(&nXSize);
    memcpy(&nYSize, poOpenInfo->pabyHeader + 10, 4);
    CPL_LSBPTR32(&nYSize);

    GUInt16 nTileSize;
    memcpy(&nTileSize, poOpenInfo->pabyHeader + 14, 2);
    CPL_LSBPTR16(&nTileSize);

    float fVertPres, fHorizScale;
    memcpy(&fVertPres, poOpenInfo->pabyHeader + 16, 4);
    CPL_LSBPTR32(&fVertPres);
    memcpy(&fHorizScale, poOpenInfo->pabyHeader + 20, 4);
    CPL_LSBPTR32(&fHorizScale);

    GUInt32 nExtendedHeaderLen;
    memcpy(&nExtendedHeaderLen, poOpenInfo->pabyHeader + 24, 4);
    CPL_LSBPTR32(&nExtendedHeaderLen);

    delete poOpenInfoToDelete;
    poOpenInfoToDelete = NULL;

    if (nTileSize < 8)
        return NULL;
    if (nXSize <= 0 || nXSize > INT_MAX - nTileSize ||
        nYSize <= 0 || nYSize > INT_MAX - nTileSize)
        return NULL;
    /* To avoid later potential int overflows */
    if (nExtendedHeaderLen > 1024 * 65536)
        return NULL;

    if (!GDALCheckDatasetDimensions(nXSize, nYSize))
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Parse extended blocks                                           */
/* -------------------------------------------------------------------- */

    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    VSIFSeekL(fp, 28, SEEK_SET);

    int bHasExtent = FALSE;
    double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0;
    int bHasUTMZone = FALSE;
    GInt16 nUTMZone = 0;
    int bHasEPSGDatumCode = FALSE;
    GInt16 nEPSGDatumCode = 0;
    int bHasEPSGCode = FALSE;
    GInt16 nEPSGCode = 0;
    int bHasRelativePrecision = FALSE;
    float fRelativePrecision = 0;
    char szApplicationName[256];
    szApplicationName[0] = 0;

    GUInt32 nExtendedHeaderOff = 0;
    while(nExtendedHeaderOff < nExtendedHeaderLen)
    {
        char pabyBlockHeader[24];
        VSIFReadL(pabyBlockHeader, 24, 1, fp);

        char szBlockName[16 + 1];
        memcpy(szBlockName, pabyBlockHeader + 4, 16);
        szBlockName[16] = 0;
        GUInt32 nBlockSize;
        memcpy(&nBlockSize, pabyBlockHeader + 20, 4);
        CPL_LSBPTR32(&nBlockSize);
        if (nBlockSize > 65536)
            break;

        nExtendedHeaderOff += 24 + nBlockSize;

        if (strcmp(szBlockName, "georef-extents") == 0 &&
            nBlockSize == 34)
        {
            char pabyBlockData[34];
            VSIFReadL(pabyBlockData, 34, 1, fp);

            memcpy(&dfMinX, pabyBlockData + 2, 8);
            CPL_LSBPTR64(&dfMinX);
            memcpy(&dfMaxX, pabyBlockData + 2 + 8, 8);
            CPL_LSBPTR64(&dfMaxX);
            memcpy(&dfMinY, pabyBlockData + 2 + 8 + 8, 8);
            CPL_LSBPTR64(&dfMinY);
            memcpy(&dfMaxY, pabyBlockData + 2 + 8 + 8 + 8, 8);
            CPL_LSBPTR64(&dfMaxY);

            bHasExtent = TRUE;
        }
        else if (strcmp(szBlockName, "georef-utm") == 0 &&
                nBlockSize == 2)
        {
            VSIFReadL(&nUTMZone, 2, 1, fp);
            CPL_LSBPTR16(&nUTMZone);
            CPLDebug("HF2", "UTM Zone = %d", nUTMZone);

            bHasUTMZone = TRUE;
        }
        else if (strcmp(szBlockName, "georef-datum") == 0 &&
                 nBlockSize == 2)
        {
            VSIFReadL(&nEPSGDatumCode, 2, 1, fp);
            CPL_LSBPTR16(&nEPSGDatumCode);
            CPLDebug("HF2", "EPSG Datum Code = %d", nEPSGDatumCode);

            bHasEPSGDatumCode = TRUE;
        }
        else if (strcmp(szBlockName, "georef-epsg-prj") == 0 &&
                 nBlockSize == 2)
        {
            VSIFReadL(&nEPSGCode, 2, 1, fp);
            CPL_LSBPTR16(&nEPSGCode);
            CPLDebug("HF2", "EPSG Code = %d", nEPSGCode);

            bHasEPSGCode = TRUE;
        }
        else if (strcmp(szBlockName, "precis-rel") == 0 &&
                 nBlockSize == 4)
        {
            VSIFReadL(&fRelativePrecision, 4, 1, fp);
            CPL_LSBPTR32(&fRelativePrecision);

            bHasRelativePrecision = TRUE;
        }
        else if (strcmp(szBlockName, "app-name") == 0 &&
                 nBlockSize < 256)
        {
            VSIFReadL(szApplicationName, nBlockSize, 1, fp);
            szApplicationName[nBlockSize] = 0;
        }
        else
        {
            CPLDebug("HF2", "Skipping block %s", szBlockName);
            VSIFSeekL(fp, nBlockSize, SEEK_CUR);
        }
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    HF2Dataset         *poDS;

    poDS = new HF2Dataset();
    poDS->fp = fp;
    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;
    poDS->nTileSize = nTileSize;
    CPLDebug("HF2", "nXSize = %d, nYSize = %d, nTileSize = %d", nXSize, nYSize, nTileSize);
    if (bHasExtent)
    {
        poDS->adfGeoTransform[0] = dfMinX;
        poDS->adfGeoTransform[3] = dfMaxY;
        poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nXSize;
        poDS->adfGeoTransform[5] = -(dfMaxY - dfMinY) / nYSize;
    }
    else
    {
        poDS->adfGeoTransform[1] = fHorizScale;
        poDS->adfGeoTransform[5] = fHorizScale;
    }

    if (bHasEPSGCode)
    {
        OGRSpatialReference oSRS;
        if (oSRS.importFromEPSG(nEPSGCode) == OGRERR_NONE)
            oSRS.exportToWkt(&poDS->pszWKT);
    }
    else
    {
        int bHasSRS = FALSE;
        OGRSpatialReference oSRS;
        oSRS.SetGeogCS("unknown", "unknown", "unknown", SRS_WGS84_SEMIMAJOR, SRS_WGS84_INVFLATTENING); 
        if (bHasEPSGDatumCode)
        {
            if (nEPSGDatumCode == 23 || nEPSGDatumCode == 6326)
            {
                bHasSRS = TRUE;
                oSRS.SetWellKnownGeogCS("WGS84");
            }
            else if (nEPSGDatumCode >= 6000)
            {
                char szName[32];
                sprintf( szName, "EPSG:%d", nEPSGDatumCode-2000 );
                oSRS.SetWellKnownGeogCS( szName );
                bHasSRS = TRUE;
            }
        }

        if (bHasUTMZone && ABS(nUTMZone) >= 1 && ABS(nUTMZone) <= 60)
        {
            bHasSRS = TRUE;
            oSRS.SetUTM(ABS(nUTMZone), nUTMZone > 0);
        }
        if (bHasSRS)
            oSRS.exportToWkt(&poDS->pszWKT);
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    int i;
    for( i = 0; i < poDS->nBands; i++ )
    {
        poDS->SetBand( i+1, new HF2RasterBand( poDS, i+1, GDT_Float32 ) );
        poDS->GetRasterBand(i+1)->SetUnitType("m");
    }

    if (szApplicationName[0] != '\0')
        poDS->SetMetadataItem("APPLICATION_NAME", szApplicationName);
    poDS->SetMetadataItem("VERTICAL_PRECISION", CPLString().Printf("%f", fVertPres));
    if (bHasRelativePrecision)
        poDS->SetMetadataItem("RELATIVE_VERTICAL_PRECISION", CPLString().Printf("%f", fRelativePrecision));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( osOriginalFilename.c_str() );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, osOriginalFilename.c_str() );
    return( poDS );
}
예제 #5
0
GDALDataset *CTGDataset::Open( GDALOpenInfo * poOpenInfo )

{
    int         i;

    if (!Identify(poOpenInfo))
        return NULL;

    CPLString osFilename(poOpenInfo->pszFilename);

    /*  GZipped grid_cell.gz files are common, so automagically open them */
    /*  if the /vsigzip/ has not been explicitly passed */
    const char* pszFilename = CPLGetFilename(poOpenInfo->pszFilename);
    if ((EQUAL(pszFilename, "grid_cell.gz") ||
         EQUAL(pszFilename, "grid_cell1.gz") ||
         EQUAL(pszFilename, "grid_cell2.gz")) &&
        !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9))
    {
        osFilename = "/vsigzip/";
        osFilename += poOpenInfo->pszFilename;
    }

    if (poOpenInfo->eAccess == GA_Update)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The CTG driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Find dataset characteristics                                    */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    char szHeader[HEADER_LINE_COUNT * 80+1];
    szHeader[HEADER_LINE_COUNT * 80] = 0;
    if (VSIFReadL(szHeader, 1, HEADER_LINE_COUNT * 80, fp) != HEADER_LINE_COUNT * 80)
    {
        VSIFCloseL(fp);
        return NULL;
    }

    for(i=HEADER_LINE_COUNT * 80 - 1;i>=0;i--)
    {
        if (szHeader[i] == ' ')
            szHeader[i] = 0;
        else
            break;
    }

    char szField[11];
    int nRows = atoi(ExtractField(szField, szHeader, 0, 10));
    int nCols = atoi(ExtractField(szField, szHeader, 20, 10));

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    CTGDataset         *poDS;

    poDS = new CTGDataset();
    poDS->fp = fp;
    fp = NULL;
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    poDS->SetMetadataItem("TITLE", szHeader + 4 * 80);

    poDS->nCellSize = atoi(ExtractField(szField, szHeader, 35, 5));
    if (poDS->nCellSize <= 0 || poDS->nCellSize >= 10000)
    {
        delete poDS;
        return NULL;
    }
    poDS->nNWEasting = atoi(ExtractField(szField, szHeader + 3*80, 40, 10));
    poDS->nNWNorthing = atoi(ExtractField(szField, szHeader + 3*80, 50, 10));
    poDS->nUTMZone = atoi(ExtractField(szField, szHeader, 50, 5));
    if (poDS->nUTMZone <= 0 || poDS->nUTMZone > 60)
    {
        delete poDS;
        return NULL;
    }

    OGRSpatialReference oSRS;
    oSRS.importFromEPSG(32600 + poDS->nUTMZone);
    oSRS.exportToWkt(&poDS->pszProjection);

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the imagery                                                */
/* -------------------------------------------------------------------- */
    GByte* pabyImage = (GByte*)VSICalloc(nCols * nRows, 6 * sizeof(int));
    if (pabyImage == NULL)
    {
        delete poDS;
        return NULL;
    }
    poDS->pabyImage = pabyImage;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 6;
    for( i = 0; i < poDS->nBands; i++ )
    {
        poDS->SetBand( i+1, new CTGRasterBand( poDS, i+1 ) );
        poDS->GetRasterBand(i+1)->SetDescription(apszBandDescription[i]);
    }

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

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #6
0
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate,
                                  int bTestOpen )

{
    SHPHandle   hSHP;
    DBFHandle   hDBF;
    const char *pszExtension = CPLGetExtension( pszNewName );

    (void) bTestOpen;

    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 distinquish 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 );
    if( bUpdate )
        hSHP = SHPOpen( pszNewName, "r+" );
    else
        hSHP = 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.                   */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") )
    {
        if( bUpdate )
            hDBF = DBFOpen( pszNewName, "r+" );
        else
            hDBF = DBFOpen( pszNewName, "r" );
    }
    else
        hDBF = NULL;
        
    if( hDBF == NULL && hSHP == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Is there an associated .prj file we can read?                   */
/* -------------------------------------------------------------------- */
    OGRSpatialReference *poSRS = NULL;
    const char  *pszPrjFile = CPLResetExtension( pszNewName, "prj" );
    FILE        *fp = NULL;

    fp = VSIFOpen( pszPrjFile, "r" );

#ifndef WIN32
    if( NULL == fp )
    {
        pszPrjFile = CPLResetExtension( pszNewName, "PRJ" );
        fp = VSIFOpen( pszPrjFile, "r" );
    }
#endif

    if( fp != NULL )
    {
        char    **papszLines;

        VSIFClose( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        poSRS = new OGRSpatialReference();
        if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE )
        {
            delete poSRS;
            poSRS = NULL;
        }
        CSLDestroy( papszLines );
    }

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

    poLayer = new OGRShapeLayer( pszNewName, hSHP, hDBF, poSRS, bUpdate,
                                 wkbNone );


    poLayer->InitializeIndexSupport( pszNewName );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
    papoLayers = (OGRShapeLayer **)
        CPLRealloc( papoLayers,  sizeof(OGRShapeLayer *) * (nLayers+1) );
    papoLayers[nLayers++] = poLayer;
    
    return TRUE;
}
예제 #7
0
OGRLayer*  OGRVRTDataSource::InstanciateWarpedLayer(
                                        CPLXMLNode *psLTree,
                                        const char *pszVRTDirectory,
                                        int bUpdate,
                                        int nRecLevel)
{
    if( !EQUAL(psLTree->pszValue,"OGRVRTWarpedLayer") )
        return NULL;

    CPLXMLNode *psSubNode;
    OGRLayer* poSrcLayer = NULL;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
        if( psSubNode->eType != CXT_Element )
            continue;

        poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory,
                                 bUpdate, nRecLevel + 1);
        if( poSrcLayer != NULL )
            break;
    }

    if( poSrcLayer == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot instanciate source layer" );
        return NULL;
    }

    const char* pszTargetSRS = CPLGetXMLValue(psLTree, "TargetSRS", NULL);
    if( pszTargetSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Missing TargetSRS element within OGRVRTWarpedLayer" );
        delete poSrcLayer;
        return NULL;
    }

    const char* pszGeomFieldName = CPLGetXMLValue(psLTree, "WarpedGeomFieldName", NULL);
    int iGeomField = 0;
    if( pszGeomFieldName != NULL )
    {
        iGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(pszGeomFieldName);
        if( iGeomField < 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot find source geometry field '%s'", pszGeomFieldName );
            delete poSrcLayer;
            return NULL;
        }
    }

    OGRSpatialReference* poSrcSRS;
    OGRSpatialReference* poTargetSRS;
    const char* pszSourceSRS = CPLGetXMLValue(psLTree, "SrcSRS", NULL);

    if( pszSourceSRS == NULL )
    {
        poSrcSRS = poSrcLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetSpatialRef();
        if( poSrcSRS != NULL)
            poSrcSRS = poSrcSRS->Clone();
    }
    else
    {
        poSrcSRS = new OGRSpatialReference();
        if( poSrcSRS->SetFromUserInput(pszSourceSRS) != OGRERR_NONE )
        {
            delete poSrcSRS;
            poSrcSRS = NULL;
        }
    }

    if( poSrcSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to import source SRS" );
        delete poSrcLayer;
        return NULL;
    }

    poTargetSRS = new OGRSpatialReference();
    if( poTargetSRS->SetFromUserInput(pszTargetSRS) != OGRERR_NONE )
    {
        delete poTargetSRS;
        poTargetSRS = NULL;
    }

    if( poTargetSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to import target SRS" );
        delete poSrcSRS;
        delete poSrcLayer;
        return NULL;
    }

    if( pszSourceSRS == NULL && poSrcSRS->IsSame(poTargetSRS) )
    {
        delete poSrcSRS;
        delete poTargetSRS;
        return poSrcLayer;
    }

    OGRCoordinateTransformation* poCT =
        OGRCreateCoordinateTransformation( poSrcSRS, poTargetSRS );
    OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ?
        OGRCreateCoordinateTransformation( poTargetSRS, poSrcSRS ) : NULL;

    delete poSrcSRS;
    delete poTargetSRS;

    if( poCT == NULL )
    {
        delete poSrcLayer;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Build the OGRWarpedLayer.                                       */
/* -------------------------------------------------------------------- */

    OGRWarpedLayer* poLayer = new OGRWarpedLayer(poSrcLayer, iGeomField,
                                                 TRUE, poCT, poReversedCT);

/* -------------------------------------------------------------------- */
/*      Set Extent if provided                                          */
/* -------------------------------------------------------------------- */
    const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL );
    const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL );
    const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL );
    const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL );
    if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
        pszExtentXMax != NULL && pszExtentYMax != NULL )
    {
        poLayer->SetExtent( CPLAtof(pszExtentXMin),
                            CPLAtof(pszExtentYMin),
                            CPLAtof(pszExtentXMax),
                            CPLAtof(pszExtentYMax) );
    }

    return poLayer;
}
예제 #8
0
bool QgsImageWarper::createDestinationDataset(
    const QString &outputName, GDALDatasetH hSrcDS, GDALDatasetH &hDstDS,
    uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans,
    const QString& compression, const QString &projection )
{
    // create the output file
    GDALDriverH driver = GDALGetDriverByName( "GTiff" );
    if ( driver == NULL )
    {
        return false;
    }
    char **papszOptions = NULL;
    papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toAscii() );
    hDstDS = GDALCreate( driver,
                         QFile::encodeName( outputName ).constData(), resX, resY,
                         GDALGetRasterCount( hSrcDS ),
                         GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ),
                         papszOptions );
    if ( hDstDS == NULL )
    {
        return false;
    }

    if ( CE_None != GDALSetGeoTransform( hDstDS, adfGeoTransform ) )
    {
        return false;
    }

    if ( !projection.isEmpty() )
    {
        OGRSpatialReference oTargetSRS;
        if ( projection.startsWith( "EPSG", Qt::CaseInsensitive ) )
        {
            QString epsg = projection.mid( projection.indexOf( ":" ) + 1 );
            oTargetSRS.importFromEPSG( epsg.toInt() );
        }
        else
        {
            oTargetSRS.importFromProj4( projection.toLatin1().data() );
        }

        char *wkt = NULL;
        OGRErr err = oTargetSRS.exportToWkt( &wkt );
        if ( err != CE_None || GDALSetProjection( hDstDS, wkt ) != CE_None )
        {
            OGRFree( wkt );
            return false;
        }
        OGRFree( wkt );
    }

    for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i )
    {
        GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 );
        GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS, i + 1 );
        GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand );
        GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) );
        if ( cTable )
        {
            GDALSetRasterColorTable( hDstBand, cTable );
        }

        int success;
        double noData = GDALGetRasterNoDataValue( hSrcBand, &success );
        if ( success )
        {
            GDALSetRasterNoDataValue( hDstBand, noData );
        }
        else if ( useZeroAsTrans )
        {
            GDALSetRasterNoDataValue( hDstBand, 0 );
        }
    }

    return true;
}
예제 #9
0
GDALDataset *LCPDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is a FARSITE LCP file    */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The LCP driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    LCPDataset  *poDS;
    VSILFILE        *fpImage;

    fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (fpImage == NULL)
        return NULL;

    poDS = new LCPDataset();
    poDS->fpImage = fpImage;

/* -------------------------------------------------------------------- */
/*      Read the header and extract some information.                   */
/* -------------------------------------------------------------------- */
   int bHaveCrownFuels, bHaveGroundFuels;
   int nBands, i;
   long nWidth = -1, nHeight = -1;
   int nTemp, nTemp2;
   char szTemp[32];
   char* pszList;

   VSIFSeekL( poDS->fpImage, 0, SEEK_SET );
   if (VSIFReadL( poDS->pachHeader, 1, LCP_HEADER_SIZE, poDS->fpImage ) != LCP_HEADER_SIZE)
   {
       CPLError(CE_Failure, CPLE_FileIO, "File too short");
       delete poDS;
       return NULL;
   }

   nWidth = CPL_LSBINT32PTR (poDS->pachHeader + 4164);
   nHeight = CPL_LSBINT32PTR (poDS->pachHeader + 4168);

   poDS->nRasterXSize = nWidth;
   poDS->nRasterYSize = nHeight;

   if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
   {
       delete poDS;
       return NULL;
   }

   // crown fuels = canopy height, canopy base height, canopy bulk density
   // 21 = have them, 20 = don't have them
   bHaveCrownFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 0) - 20 );
   // ground fuels = duff loading, coarse woody
   bHaveGroundFuels = ( CPL_LSBINT32PTR (poDS->pachHeader + 4) - 20 );

   if( bHaveCrownFuels )
   {
       if( bHaveGroundFuels )
           nBands = 10;
       else
           nBands = 8;
   }
   else
   {
       if( bHaveGroundFuels )
           nBands = 7;
       else
           nBands = 5;
   }

   // add dataset-level metadata

   nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 8);
   sprintf(szTemp, "%d", nTemp);
   poDS->SetMetadataItem( "LATITUDE", szTemp );

   nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 4204);
   if ( nTemp == 0 )
      poDS->SetMetadataItem( "LINEAR_UNIT", "Meters" );
   if ( nTemp == 1 )
      poDS->SetMetadataItem( "LINEAR_UNIT", "Feet" );

   poDS->pachHeader[LCP_HEADER_SIZE-1] = '\0';
   poDS->SetMetadataItem( "DESCRIPTION", poDS->pachHeader + 6804 );


/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */

   int          iPixelSize;
   iPixelSize = nBands * 2;
   int          bNativeOrder;

   if (nWidth > INT_MAX / iPixelSize)
   {
       CPLError( CE_Failure, CPLE_AppDefined,  "Int overflow occured");
       delete poDS;
       return NULL;
   }

#ifdef CPL_LSB
   bNativeOrder = TRUE;
#else
   bNativeOrder = FALSE;
#endif

   pszList = (char*)CPLMalloc(2048);

   for( int iBand = 1; iBand <= nBands; iBand++ )
   {
        GDALRasterBand  *poBand = NULL;

        poBand = new RawRasterBand(
                     poDS, iBand, poDS->fpImage, LCP_HEADER_SIZE + ((iBand-1)*2),
                     iPixelSize, iPixelSize * nWidth, GDT_Int16, bNativeOrder, TRUE );

        poDS->SetBand(iBand, poBand);

        switch ( iBand ) {
        case 1:
           poBand->SetDescription("Elevation");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4224);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Meters" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "ELEVATION_UNIT_NAME", "Feet" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 44);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 48);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 52);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ELEVATION_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4244 + 255) = '\0';
           poBand->SetMetadataItem( "ELEVATION_FILE", poDS->pachHeader + 4244 );

           break;

        case 2:
           poBand->SetDescription("Slope");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4226);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Degrees" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "SLOPE_UNIT_NAME", "Percent" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 456);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 460);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 464);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "SLOPE_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4500 + 255) = '\0';
           poBand->SetMetadataItem( "SLOPE_FILE", poDS->pachHeader + 4500 );

           break;

        case 3:
           poBand->SetDescription("Aspect");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4228);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass categories" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Grass degrees" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "ASPECT_UNIT_NAME", "Azimuth degrees" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 868);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 872);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 876);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "ASPECT_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 4756 + 255) = '\0';
           poBand->SetMetadataItem( "ASPECT_FILE", poDS->pachHeader + 4756 );

           break;

        case 4:
           int nMinFM, nMaxFM;

           poBand->SetDescription("Fuel models");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4230);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "FUEL_MODEL_OPTION", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models AND no conversion file needed" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models BUT no conversion file needed" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "no custom models BUT conversion file needed" );
           if ( nTemp == 3 )
              poBand->SetMetadataItem( "FUEL_MODEL_OPTION_DESC", "custom models AND conversion file needed" );

           nMinFM = CPL_LSBINT32PTR (poDS->pachHeader + 1280);
           sprintf(szTemp, "%d", nMinFM);
           poBand->SetMetadataItem( "FUEL_MODEL_MIN", szTemp );

           nMaxFM = CPL_LSBINT32PTR (poDS->pachHeader + 1284);
           sprintf(szTemp, "%d", nMaxFM);
           poBand->SetMetadataItem( "FUEL_MODEL_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1288);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "FUEL_MODEL_NUM_CLASSES", szTemp );

           if (nTemp > 0 && nTemp <= 100) {
              strcpy(pszList, "");
              for ( i = 0; i <= nTemp; i++ ) {
                  nTemp2 = CPL_LSBINT32PTR (poDS->pachHeader + (1292+(i*4))) ;
                  if ( nTemp2 >= nMinFM && nTemp2 <= nMaxFM ) {
                     sprintf(szTemp, "%d", nTemp2);
                     strcat(pszList, szTemp);
                     if (i < (nTemp) )
                        strcat(pszList, ",");
                  }
              }
           }
           poBand->SetMetadataItem( "FUEL_MODEL_VALUES", pszList );

           *(poDS->pachHeader + 5012 + 255) = '\0';
           poBand->SetMetadataItem( "FUEL_MODEL_FILE", poDS->pachHeader + 5012 );

           break;

        case 5:
           poBand->SetDescription("Canopy cover");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4232);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_UNIT", szTemp );

           if ( nTemp == 0 )
              poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Categories (0-4)" );
           if ( nTemp == 1 )
              poBand->SetMetadataItem( "CANOPY_COV_UNIT_NAME", "Percent" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1692);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1696);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 1700);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CANOPY_COV_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 5268 + 255) = '\0';
           poBand->SetMetadataItem( "CANOPY_COV_FILE", poDS->pachHeader + 5268 );

           break;

        case 6:
           if(bHaveCrownFuels) {
              poBand->SetDescription("Canopy height");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4234);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet" );
              if ( nTemp == 3 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Meters x 10" );
              if ( nTemp == 4 )
                 poBand->SetMetadataItem( "CANOPY_HT_UNIT_NAME", "Feet x 10" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2104);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2108);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2112);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CANOPY_HT_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 5524 + 255) = '\0';
              poBand->SetMetadataItem( "CANOPY_HT_FILE", poDS->pachHeader + 5524 );
           }
           else {
              poBand->SetDescription("Duff");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 6292 + 255) = '\0';
              poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );
           }
           break;

        case 7:
           if(bHaveCrownFuels) {
              poBand->SetDescription("Canopy base height");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4236);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_UNIT", szTemp );

              if ( nTemp == 1 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters" );
              if ( nTemp == 2 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet" );
              if ( nTemp == 3 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Meters x 10" );
              if ( nTemp == 4 )
                 poBand->SetMetadataItem( "CBH_UNIT_NAME", "Feet x 10" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2516);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2520);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2524);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CBH_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 5780 + 255) = '\0';
              poBand->SetMetadataItem( "CBH_FILE", poDS->pachHeader + 5780 );
           }
           else {
              poBand->SetDescription("Coarse woody debris");

              nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_OPTION", szTemp );

              //if ( nTemp == 1 )
              //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
              //if ( nTemp == 2 )
              //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_MIN", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_MAX", szTemp );

              nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
              sprintf(szTemp, "%d", nTemp);
              poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

              *(poDS->pachHeader + 6548 + 255) = '\0';
              poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );
           }
           break;

        case 8:
           poBand->SetDescription("Canopy bulk density");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4238);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_UNIT", szTemp );

           if ( nTemp == 1 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3" );
           if ( nTemp == 3 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "kg/m^3 x 100" );
           if ( nTemp == 4 )
              poBand->SetMetadataItem( "CBD_UNIT_NAME", "lb/ft^3 x 1000" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2928);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2932);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 2936);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CBD_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6036 + 255) = '\0';
           poBand->SetMetadataItem( "CBD_FILE", poDS->pachHeader + 6036 );

           break;

        case 9:
           poBand->SetDescription("Duff");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4240);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_UNIT", szTemp );

           if ( nTemp == 1 )
              poBand->SetMetadataItem( "DUFF_UNIT_NAME", "Mg/ha" );
           if ( nTemp == 2 )
              poBand->SetMetadataItem( "DUFF_UNIT_NAME", "t/ac" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3340);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3344);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3348);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "DUFF_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6292 + 255) = '\0';
           poBand->SetMetadataItem( "DUFF_FILE", poDS->pachHeader + 6292 );

           break;

        case 10:
           poBand->SetDescription("Coarse woody debris");

           nTemp = CPL_LSBINT16PTR (poDS->pachHeader + 4242);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_OPTION", szTemp );

           //if ( nTemp == 1 )
           //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );
           //if ( nTemp == 2 )
           //   poBand->SetMetadataItem( "CWD_UNIT_DESC", "?" );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3752);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_MIN", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3756);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_MAX", szTemp );

           nTemp = CPL_LSBINT32PTR (poDS->pachHeader + 3760);
           sprintf(szTemp, "%d", nTemp);
           poBand->SetMetadataItem( "CWD_NUM_CLASSES", szTemp );

           *(poDS->pachHeader + 6548 + 255) = '\0';
           poBand->SetMetadataItem( "CWD_FILE", poDS->pachHeader + 6548 );

           break;
        }
   }
   
/* -------------------------------------------------------------------- */
/*      Try to read projection file.                                    */
/* -------------------------------------------------------------------- */
    char        *pszDirname, *pszBasename;
    VSIStatBufL   sStatBuf;

    pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));

    poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "prj" );
    int nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );

    if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename))
    {
        poDS->osPrjFilename = CPLFormFilename( pszDirname, pszBasename, "PRJ" );
        nRet = VSIStatL( poDS->osPrjFilename, &sStatBuf );
    }

    if( nRet == 0 )
    {
        OGRSpatialReference     oSRS;

        char** papszPrj = CSLLoad( poDS->osPrjFilename );

        CPLDebug( "LCP", "Loaded SRS from %s", 
                  poDS->osPrjFilename.c_str() );

        if( oSRS.importFromESRI( papszPrj ) == OGRERR_NONE )
        {
            oSRS.exportToWkt( &(poDS->pszProjection) );
        }
        
        CSLDestroy(papszPrj);
    }

    CPLFree( pszDirname );
    CPLFree( pszBasename );

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

    CPLFree(pszList);

    return( poDS );
}
예제 #10
0
void E00GRIDDataset::ReadMetadata()

{
    if (bHasReadMetadata)
        return;

    bHasReadMetadata = TRUE;

    if (e00ReadPtr == NULL)
    {
        int nRoundedBlockXSize = ((nRasterXSize + VALS_PER_LINE - 1) /
                                                VALS_PER_LINE) * VALS_PER_LINE;
        vsi_l_offset nValsToSkip =
                               (vsi_l_offset)nRasterYSize * nRoundedBlockXSize;
        vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE;
        int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + nBytesEOL;
        vsi_l_offset nPos = nDataStart + nLinesToSkip * nBytesPerLine;
        VSIFSeekL(fp, nPos, SEEK_SET);
    }
    else
    {
        nLastYOff = -1;

        const unsigned int BUFFER_SIZE = 65536;
        const unsigned int NEEDLE_SIZE = 3*5;
        const unsigned int nToRead = BUFFER_SIZE - NEEDLE_SIZE;
        char* pabyBuffer = (char*)CPLCalloc(1, BUFFER_SIZE+NEEDLE_SIZE);
        int nRead;
        int bEOGFound = FALSE;

        VSIFSeekL(fp, 0, SEEK_END);
        vsi_l_offset nEndPos = VSIFTellL(fp);
        if (nEndPos > BUFFER_SIZE)
            nEndPos -= BUFFER_SIZE;
        else
            nEndPos = 0;
        VSIFSeekL(fp, nEndPos, SEEK_SET);

#define GOTO_NEXT_CHAR() \
    i ++; \
    if (pabyBuffer[i] == 13 || pabyBuffer[i] == 10) \
    { \
        i++; \
        if (pabyBuffer[i] == 10) \
            i++; \
    } \

        while ((nRead = VSIFReadL(pabyBuffer, 1, nToRead, fp)) != 0)
        {
            int i;
            for(i = 0; i < nRead; i++)
            {
                if (pabyBuffer[i] == 'E')
                {
                    GOTO_NEXT_CHAR();
                    if (pabyBuffer[i] == 'O')
                    {
                        GOTO_NEXT_CHAR();
                        if (pabyBuffer[i] == 'G')
                        {
                            GOTO_NEXT_CHAR();
                            if (pabyBuffer[i] == '~')
                            {
                                GOTO_NEXT_CHAR();
                                if (pabyBuffer[i] == '}')
                                {
                                    bEOGFound = TRUE;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (bEOGFound)
            {
                VSIFSeekL(fp, VSIFTellL(fp) - nRead + i + 1, SEEK_SET);
                e00ReadPtr->iInBufPtr = 0;
                e00ReadPtr->szInBuf[0] = '\0';
                break;
            }

            if (nEndPos == 0)
                break;

            if ((unsigned int)nRead == nToRead)
            {
                memmove(pabyBuffer + nToRead, pabyBuffer, NEEDLE_SIZE);
                if (nEndPos >= (vsi_l_offset)nToRead)
                    nEndPos -= nToRead;
                else
                    nEndPos = 0;
                VSIFSeekL(fp, nEndPos, SEEK_SET);
            }
            else
                break;
        }
        CPLFree(pabyBuffer);
        if (!bEOGFound)
            return;
    }

    const char* pszLine;
    int bPRJFound = FALSE;
    int bStatsFound = FALSE;
    while((pszLine = ReadLine()) != NULL)
    {
        if (EQUALN(pszLine, "PRJ  2", 6))
        {
            bPRJFound = TRUE;
            while((pszLine = ReadLine()) != NULL)
            {
                if (EQUAL(pszLine, "EOP"))
                {
                    break;
                }
                papszPrj = CSLAddString(papszPrj, pszLine);
            }

            OGRSpatialReference oSRS;
            if( oSRS.importFromESRI( papszPrj ) != OGRERR_NONE )
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                            "Failed to parse PRJ section, ignoring." );
            }
            else
            {
                char* pszWKT = NULL;
                if (oSRS.exportToWkt(&pszWKT) == OGRERR_NONE && pszWKT != NULL)
                    osProjection = pszWKT;
                CPLFree(pszWKT);
            }
            if (bStatsFound)
                break;
        }
        else if (strcmp(pszLine, "STDV              8-1  254-1  15 3 60-1  -1  -1-1                   4-") == 0)
        {
            bStatsFound = TRUE;
            pszLine = ReadLine();
            if (pszLine)
            {
                CPLString osStats = pszLine;
                pszLine = ReadLine();
                if (pszLine)
                {
                    osStats += pszLine;
                    char** papszTokens = CSLTokenizeString(osStats);
                    if (CSLCount(papszTokens) == 4)
                    {
                        dfMin = CPLAtof(papszTokens[0]);
                        dfMax = CPLAtof(papszTokens[1]);
                        dfMean = CPLAtof(papszTokens[2]);
                        dfStddev = CPLAtof(papszTokens[3]);
                        bHasStats = TRUE;
                    }
                    CSLDestroy(papszTokens);
                }
            }
            if (bPRJFound)
                break;
        }
    }
}
예제 #11
0
static int OGR2GML3GeometryAppend( OGRGeometry *poGeometry,
                                   const OGRSpatialReference* poParentSRS,
                                   char **ppszText, int *pnLength,
                                   int *pnMaxLength,
                                   int bIsSubGeometry,
                                   int bLongSRS,
                                   int bLineStringAsCurve,
                                   const char* pszGMLId,
                                   int nSRSDimensionLocFlags )

{

/* -------------------------------------------------------------------- */
/*      Check for Spatial Reference System attached to given geometry   */
/* -------------------------------------------------------------------- */

    // Buffer for srsName, srsDimension and gml:id attributes (srsName="..." gml:id="...")
    char szAttributes[256];
    int nAttrsLength = 0;

    szAttributes[0] = 0;

    const OGRSpatialReference* poSRS = NULL;
    if (poParentSRS)
        poSRS = poParentSRS;
    else
        poParentSRS = poSRS = poGeometry->getSpatialReference();

    int bCoordSwap = FALSE;

    if( NULL != poSRS )
    {
        const char* pszAuthName = NULL;
        const char* pszAuthCode = NULL;
        const char* pszTarget = NULL;

        if (poSRS->IsProjected())
            pszTarget = "PROJCS";
        else
            pszTarget = "GEOGCS";

        pszAuthName = poSRS->GetAuthorityName( pszTarget );
        if( NULL != pszAuthName )
        {
            if( EQUAL( pszAuthName, "EPSG" ) )
            {
                pszAuthCode = poSRS->GetAuthorityCode( pszTarget );
                if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 )
                {
                    if (bLongSRS && !(((OGRSpatialReference*)poSRS)->EPSGTreatsAsLatLong() ||
                                      ((OGRSpatialReference*)poSRS)->EPSGTreatsAsNorthingEasting()))
                    {
                        OGRSpatialReference oSRS;
                        if (oSRS.importFromEPSGA(atoi(pszAuthCode)) == OGRERR_NONE)
                        {
                            if (oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting())
                                bCoordSwap = TRUE;
                        }
                    }

                    if (!bIsSubGeometry)
                    {
                        if (bLongSRS)
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"urn:ogc:def:crs:%s::%s\"",
                                      pszAuthName, pszAuthCode );
                        }
                        else
                        {
                            snprintf( szAttributes, sizeof(szAttributes),
                                      " srsName=\"%s:%s\"",
                                      pszAuthName, pszAuthCode );
                        }

                        nAttrsLength = strlen(szAttributes);
                    }
                }
            }
        }
    }

    if( (nSRSDimensionLocFlags & SRSDIM_LOC_GEOMETRY) != 0 &&
        (poGeometry->getGeometryType() & wkb25DBit) != 0 )
    {
        strcat(szAttributes, " srsDimension=\"3\"");
        nAttrsLength = strlen(szAttributes);

        nSRSDimensionLocFlags &= ~SRSDIM_LOC_GEOMETRY;
    }

    if (pszGMLId != NULL && nAttrsLength + 9 + strlen(pszGMLId) + 1 < sizeof(szAttributes))
    {
        strcat(szAttributes, " gml:id=\"");
        strcat(szAttributes, pszGMLId);
        strcat(szAttributes, "\"");
        nAttrsLength = strlen(szAttributes);
    }

/* -------------------------------------------------------------------- */
/*      2D Point                                                        */
/* -------------------------------------------------------------------- */
    if( poGeometry->getGeometryType() == wkbPoint )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), 0.0, 2 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), 0.0, 2 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }
/* -------------------------------------------------------------------- */
/*      3D Point                                                        */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPoint25D )
    {
        char    szCoordinate[256];
        OGRPoint *poPoint = (OGRPoint *) poGeometry;

        if (bCoordSwap)
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getY(), poPoint->getX(), poPoint->getZ(), 3 );
        else
            OGRMakeWktCoordinate( szCoordinate,
                           poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3 );

        _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength,
                     ppszText, pnMaxLength );

        sprintf( *ppszText + *pnLength,
                "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>",
                 szAttributes, szCoordinate );

        *pnLength += strlen( *ppszText + *pnLength );
    }

/* -------------------------------------------------------------------- */
/*      LineString and LinearRing                                       */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbLineString
             || poGeometry->getGeometryType() == wkbLineString25D )
    {
        int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");
        if (!bRing && bLineStringAsCurve)
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:Curve" );
            AppendString( ppszText, pnLength, pnMaxLength,
                            szAttributes );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "><gml:segments><gml:LineStringSegment>" );
            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );
            AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineStringSegment></gml:segments></gml:Curve>" );
        }
        else
        {
            // Buffer for tag name + srsName attribute if set
            const size_t nLineTagLength = 16;
            char* pszLineTagName = NULL;
            pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 );

            if( bRing )
            {
                /* LinearRing isn't supposed to have srsName attribute according to GML3 SF-0 */
                AppendString( ppszText, pnLength, pnMaxLength,
                            "<gml:LinearRing>" );
            }
            else
            {
                sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes );

                AppendString( ppszText, pnLength, pnMaxLength,
                            pszLineTagName );
            }

            // FREE TAG BUFFER
            CPLFree( pszLineTagName );

            AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap,
                                ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags );

            if( bRing )
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LinearRing>" );
            else
                AppendString( ppszText, pnLength, pnMaxLength,
                            "</gml:LineString>" );
        }
    }

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
    else if( poGeometry->getGeometryType() == wkbPolygon
             || poGeometry->getGeometryType() == wkbPolygon25D )
    {
        OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;

        // Buffer for polygon tag name + srsName attribute if set
        const size_t nPolyTagLength = 13;
        char* pszPolyTagName = NULL;
        pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 );

        // Compose Polygon tag with or without srsName attribute
        sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes );

        AppendString( ppszText, pnLength, pnMaxLength,
                      pszPolyTagName );

        // FREE TAG BUFFER
        CPLFree( pszPolyTagName );

        // Don't add srsName to polygon rings

        if( poPolygon->getExteriorRing() != NULL )
        {
            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:exterior>" );

            if( !OGR2GML3GeometryAppend( poPolygon->getExteriorRing(), poSRS,
                                         ppszText, pnLength, pnMaxLength,
                                         TRUE, bLongSRS, bLineStringAsCurve,
                                         NULL, nSRSDimensionLocFlags) )
            {
                return FALSE;
            }

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:exterior>" );
        }

        for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
        {
            OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);

            AppendString( ppszText, pnLength, pnMaxLength,
                          "<gml:interior>" );

            if( !OGR2GML3GeometryAppend( poRing, poSRS, ppszText, pnLength,
                                         pnMaxLength, TRUE, bLongSRS,
                                         bLineStringAsCurve,
                                         NULL, nSRSDimensionLocFlags) )
                return FALSE;

            AppendString( ppszText, pnLength, pnMaxLength,
                          "</gml:interior>" );
        }

        AppendString( ppszText, pnLength, pnMaxLength,
                      "</gml:Polygon>" );
    }

/* -------------------------------------------------------------------- */
/*      MultiPolygon, MultiLineString, MultiPoint, MultiGeometry        */
/* -------------------------------------------------------------------- */
    else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
             || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
             || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
        int             iMember;
        const char *pszElemClose = NULL;
        const char *pszMemberElem = NULL;

        // Buffer for opening tag + srsName attribute
        char* pszElemOpen = NULL;

        if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
        {
            pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiSurface%s>", szAttributes );

            pszElemClose = "MultiSurface>";
            pszMemberElem = "surfaceMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
        {
            pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiCurve%s>", szAttributes );

            pszElemClose = "MultiCurve>";
            pszMemberElem = "curveMember>";
        }
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
        {
            pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiPoint%s>", szAttributes );

            pszElemClose = "MultiPoint>";
            pszMemberElem = "pointMember>";
        }
        else
        {
            pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 );
            sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes );

            pszElemClose = "MultiGeometry>";
            pszMemberElem = "geometryMember>";
        }

        AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen );

        for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
        {
            OGRGeometry *poMember = poGC->getGeometryRef( iMember );

            AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );

            char* pszGMLIdSub = NULL;
            if (pszGMLId != NULL)
                pszGMLIdSub = CPLStrdup(CPLSPrintf("%s.%d", pszGMLId, iMember));

            if( !OGR2GML3GeometryAppend( poMember, poSRS,
                                         ppszText, pnLength, pnMaxLength,
                                         TRUE, bLongSRS, bLineStringAsCurve,
                                         pszGMLIdSub, nSRSDimensionLocFlags ) )
            {
                CPLFree(pszGMLIdSub);
                return FALSE;
            }

            CPLFree(pszGMLIdSub);

            AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
            AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
        }

        AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
        AppendString( ppszText, pnLength, pnMaxLength, pszElemClose );

        // FREE TAG BUFFER
        CPLFree( pszElemOpen );
    }
    else
    {
        return FALSE;
    }

    return TRUE;
}
예제 #12
0
void LevelTerrainCallback::loaded(osgTerrain::TerrainTile *tile, const osgDB::ReaderWriter::Options *options) const
{
    //Change TerrainTechnique
    tile->setTerrainTechnique(new DecoratedGeometryTechnique(voidBoundingAreaVector, treeStateSet.get(), buildingStateSet.get(), shapeFileVector));
    std::stringstream nameStream;
    nameStream << "tile_L" << tile->getTileID().level << "_X" << tile->getTileID().x << "_Y" << tile->getTileID().y;
    tile->setName(nameStream.str());

    /*tile->setName("TerrainTile");

   osg::Vec3d model;
   tile->getLocator()->convertLocalToModel(osg::Vec3d(0.0,0.0,0.0), model);
   char name[1000];
   sprintf(name,"X%f_Y%f_Z%f", model.x(), model.y(), model.z());
   tile->setName(name);*/

    //MTRand mt(10101);
    osgTerrain::HeightFieldLayer *hflayer = dynamic_cast<osgTerrain::HeightFieldLayer *>(tile->getElevationLayer());
    osg::HeightField *field = NULL;
    if (hflayer)
    {
        field = hflayer->getHeightField();
    }
    else
    {
        return;
    }

    double tileXInterval = field->getXInterval();
    double tileYInterval = field->getYInterval();
    double tileElementArea = tileXInterval * tileYInterval;
    double tileXMin = offset.x() + field->getOrigin().x();
    double tileXMax = tileXMin + tileXInterval * (double)field->getNumColumns();
    double tileYMin = offset.y() + field->getOrigin().y();
    double tileYMax = tileYMin + tileYInterval * (double)field->getNumRows();
    //osg::BoundingBox tileBB(tileXMin, tileYMin, -10.000, tileXMax, tileYMax, 10.000);

    if (tileXInterval > 10.0 && tileYInterval > 10.0)
    {
        return;
    }

    for (int i = 0; i < RoadSystem::Instance()->getNumRoads(); ++i)
    {
        Road *road = RoadSystem::Instance()->getRoad(i);
        double roadLength = road->getLength();

        const osg::BoundingBox &roadBB = road->getRoadGeode()->getBoundingBox();
        //if(roadBB.intersects(tileBB)) {
        if (((roadBB.xMax() >= tileXMin && roadBB.xMax() <= tileXMax) || (roadBB.xMin() >= tileXMin && roadBB.xMin() <= tileXMax) || (roadBB.xMin() <= tileXMin && roadBB.xMax() >= tileXMax)) && (roadBB.yMax() >= tileYMin && roadBB.yMin() <= tileYMax))
        {
            //double h = sqrt(tileXInterval*tileXInterval + tileYInterval*tileYInterval);
            double h = 20.0;
            std::deque<RoadPoint> pointDeque(4);
            double widthRight, widthLeft;
            road->getRoadSideWidths(0.0, widthRight, widthLeft);
            pointDeque.pop_front();
            pointDeque.pop_front();
            pointDeque.push_back(road->getRoadPoint(0.0, widthLeft + 10.0));
            pointDeque.push_back(road->getRoadPoint(0.0, widthRight - 10.0));

            std::map<std::pair<int, int>, double> coordHeightMap;

            for (double s_ = h; s_ < roadLength + h; s_ = s_ + h)
            {
                double s = s_;
                if (s > roadLength)
                    s = roadLength;

                road->getRoadSideWidths(s, widthRight, widthLeft);
                pointDeque.pop_front();
                pointDeque.pop_front();
                pointDeque.push_back(road->getRoadPoint(s, widthLeft + 10.0));
                pointDeque.push_back(road->getRoadPoint(s, widthRight - 10.0));

                //Bresenham
                //         y            x      z
                std::map<int, std::map<int, double> > fillBorderMap;
                //iteration over four lines
                for (int i = 0; i < 4; ++i)
                {
                    int j;
                    switch (i)
                    {
                    case 0:
                        j = 1;
                        break;
                    case 1:
                        j = 3;
                        break;
                    case 2:
                        j = 0;
                        break;
                    case 3:
                        j = 2;
                        break;
                    }

                    double fx0 = (pointDeque[i].x() - tileXMin) / tileXInterval;
                    double fy0 = (pointDeque[i].y() - tileYMin) / tileYInterval;
                    double fx1 = (pointDeque[j].x() - tileXMin) / tileXInterval;
                    double fy1 = (pointDeque[j].y() - tileYMin) / tileYInterval;

                    double dir_x = (fx0 - fx1) < 0.0 ? -1.0 : 1.0;
                    double dir_y = (fy0 - fy1) < 0.0 ? -1.0 : 1.0;

                    int x0 = (int)floor(fx0 + dir_x + 0.5);
                    //if(x0<0) x0=0; else if(x0>=field->getNumColumns()) x0=field->getNumColumns()-1;
                    int y0 = (int)floor(fy0 + dir_y + 0.5);
                    //if(y0<0) y0=0; else if(y0>=field->getNumRows()) y0=field->getNumRows()-1;
                    int x1 = (int)floor(fx1 - dir_x + 0.5);
                    //if(x1<0) x1=0; else if(x1>=field->getNumColumns()) x1=field->getNumColumns()-1;
                    int y1 = (int)floor(fy1 - dir_y + 0.5);
                    //if(y1<0) y1=0; else if(y1>=field->getNumRows()) y1=field->getNumRows()-1;

                    double z = 0.5 * (pointDeque[i].z() + pointDeque[j].z());

                    //wikipedia implementation
                    int dx = abs(x1 - x0);
                    int sx = x0 < x1 ? 1 : -1;
                    int dy = -abs(y1 - y0);
                    int sy = y0 < y1 ? 1 : -1;
                    int err = dx + dy;
                    int e2; /* error value e_xy */

                    do
                    { /* loop */
                        //setPixel(x0,y0);
                        fillBorderMap[y0][x0] = z;
                        //fillBorderMap[y0][x0] = 0.5;
                        //if (x0==x1 && y0==y1) break;
                        e2 = 2 * err;
                        if (e2 >= dy)
                        {
                            err += dy;
                            x0 += sx;
                        } /* e_xy+e_x > 0 */
                        if (e2 <= dx)
                        {
                            err += dx;
                            y0 += sy;
                        } /* e_xy+e_y < 0 */
                    } while (!(x0 == x1 && y0 == y1));
                }

                for (std::map<int, std::map<int, double> >::iterator yScanlineIt = fillBorderMap.begin();
                     yScanlineIt != fillBorderMap.end(); ++yScanlineIt)
                {
                    int x0 = (yScanlineIt->second.begin())->first;
                    double z0 = (yScanlineIt->second.begin())->second;
                    int x1 = (--(yScanlineIt->second.end()))->first;
                    double z1 = (--(yScanlineIt->second.end()))->second;
                    unsigned int y = yScanlineIt->first;
                    //if(y==field->getNumRows()-1) continue;

                    for (int x = x0; x <= x1; ++x)
                    {
                        if (x >= 0 && x < (int)field->getNumColumns() && y >= 0 && y < field->getNumRows())
                        {
                            //field->setHeight(x,y,0.5*(z0+z1)-0.5);
                            //double z = field->getHeight(x,y);
                            double rl_x = 0.5 * (pointDeque[0].x() + pointDeque[1].x());
                            double rl_y = 0.5 * (pointDeque[0].y() + pointDeque[1].y());
                            double ru_x = 0.5 * (pointDeque[2].x() + pointDeque[3].x());
                            double ru_y = 0.5 * (pointDeque[2].y() + pointDeque[3].y());
                            double t_x = ru_x - rl_x;
                            double t_y = ru_y - rl_y;
                            double mag_t = sqrt(t_x * t_x + t_y * t_y);
                            if (mag_t != mag_t)
                                continue;
                            t_x /= mag_t;
                            t_y /= mag_t;
                            double rp_x = tileXInterval * ((double)(x)) + tileXMin - rl_x;
                            double rp_y = tileYInterval * ((double)(y)) + tileYMin - rl_y;

                            double d_x = -t_y * t_x * rp_y + t_y * t_y * rp_x;
                            double d_y = t_x * t_x * rp_y - t_x * t_y * rp_x;
                            double d = sqrt(d_x * d_x + d_y * d_y);
                            //double mag_d = sqrt(d_x*d_x + d_y*d_y);
                            //double d = 0.0;
                            //if(mag_d==mag_d) {
                            //   d = (d_x*d_x+d_y*d_y)/mag_d;
                            //}
                            double s_x = rp_x - d_x;
                            double s_y = rp_y - d_y;
                            double s = sqrt(s_x * s_x + s_y * s_y);

                            double wl = sqrt(pow(pointDeque[0].x() - pointDeque[1].x(), 2) + pow(pointDeque[0].y() - pointDeque[1].y(), 2));
                            double wu = sqrt(pow(pointDeque[2].x() - pointDeque[3].x(), 2) + pow(pointDeque[2].y() - pointDeque[3].y(), 2));
                            double l = sqrt(pow(0.5 * (pointDeque[0].x() - pointDeque[2].x() + pointDeque[1].x() - pointDeque[3].x()), 2) + pow(0.5 * (pointDeque[0].y() - pointDeque[2].y() + pointDeque[1].y() - pointDeque[3].y()), 2));

                            double zt;
                            std::map<std::pair<int, int>, double>::iterator coordHeightMapIt = coordHeightMap.find(std::make_pair(x, y));
                            if (coordHeightMapIt == coordHeightMap.end())
                            {
                                zt = (double)field->getHeight(x, y);
                                coordHeightMap[std::make_pair(x, y)] = zt;
                            }
                            else
                            {
                                zt = coordHeightMapIt->second;
                            }

                            double zf0 = 7.0;
                            double zf = 0.5 * (z0 + z1) - zf0;
                            double kt0 = 50.0;
                            double kt = (d / (0.5 * (wl + (wu - wl) * s / l))) * kt0;
                            double kf0 = 10.0;
                            double kf = (1.0 - d / (0.5 * (wl + (wu - wl) * s / l))) * kf0;

                            double zl = (zt * kt + zf * kf) / (kt + kf);
                            double z_field = field->getHeight(x, y);
                            if (z_field > zl)
                            {
                                field->setHeight(x, y, zl);
                            }
                            //std::cout << "(x,y): (" << x << "," << y << "), zt: " << zt << ", zf: " << zf << ", kt: " << kt << ", kf: " << kf << std::endl;

                            //field->setHeight(x,y, std::min(zf, 0.5*(z0+z1) - 1.0*(1.0- d/(wl+(wu-wl)*s/l)) ) );
                            //std::cout << "(x,y): (" << x << "," << y << "), z0: " << z0 << ", z1: " << z1 << ", d: " << d << ", wl: " << wl << ", wu: " << wu << ", s: " << s << ", l: " << l << std::endl;
                        }
                    }
                }

                /*Vector3D roadCenterPoint = road->getCenterLinePoint(s);
            int x = floor((roadCenterPoint.x() - tileXMin)/tileXInterval + 0.5);
            int y = floor((roadCenterPoint.y() - tileYMin)/tileYInterval + 0.5);
            if(x>=0 && x<field->getNumColumns() && y>=0 && y<field->getNumRows()) {
               field->setHeight(x,y,0.0);
            }*/
            }
        }
    }

#if 0
   //osg::Group* treeGroup = new osg::Group();
   //tile->addChild(treeGroup);
   //treeGroup->setName("TreeGroup");
   
   osg::PositionAttitudeTransform* treeGeodeTransform = new osg::PositionAttitudeTransform;
   tile->addChild(treeGeodeTransform);
   treeGeodeTransform->setName("TreeGeodeTransform");
   osg::Vec3 tileMin(tileXMin, tileYMin, 0.0);
   treeGeodeTransform->setPosition(-offset + tileMin);
   osg::Geode* treeGeode = new osg::Geode();
   //tile->addChild(treeGeode);
   treeGeodeTransform->addChild(treeGeode);
   treeGeode->setName("TreeGeode");
   treeGeode->setStateSet(treeStateSet);

#endif

#if 0
   for(int layerIt = 0; layerIt < layers.size(); ++layerIt) {
      OGRLayer* layer = layers[layerIt];
      layer->ResetReading();

      OGRFeature* poFeature = NULL;
      while((poFeature = layer->GetNextFeature()) != NULL) {
         OGRGeometry *poGeometry = poFeature->GetGeometryRef();
         if(poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon)
         {
            OGRPolygon *poPolygon = dynamic_cast<OGRPolygon*>(poGeometry);
            //std::cout << "Geometry name: " << poPolygon->getGeometryName() << std::endl;
            //std::cout << "Polgon area: " << poPolygon->get_Area() << std::endl;

            OGRSpatialReference *poSource = layer->GetSpatialRef();
            OGRSpatialReference *poTarget = new OGRSpatialReference();
            poTarget->importFromProj4("+proj=utm +zone=32");
            OGRCoordinateTransformation* poCoordTrans = OGRCreateCoordinateTransformation(poSource, poTarget);

            poPolygon->transform(poCoordTrans);
            OGRLinearRing* poRing = poPolygon->getExteriorRing();
            /*for(int pointIt = 0; pointIt<poRing->getNumPoints(); ++pointIt) {
              std::cout << "Point " << pointIt << ": (" << poRing->getX(pointIt) + offset.x()
              << ", " << poRing->getY(pointIt) + offset.y()
              << ", " << poRing->getZ(pointIt) << ")" << std::endl;
              }*/
            /*double interval = 10.0*sqrt(tileXInterval*tileXInterval + tileYInterval*tileYInterval);
            OGRPoint point;
            poRing->Value(0, &point);
            OGRPoint point_next;
            for(double s = 0; s<poRing->get_Length(); s += interval*mt()) {
               double s_next = s+interval; if(s_next>poRing->get_Length()) s_next = poRing->get_Length();
               poRing->Value(s_next, &point_next);

               double ccw = poRing->isClockwise() ? -1.0 : 1.0;

               double t_x = point_next.getX() - point.getX();
               double t_y = point_next.getY() - point.getY();
               double n_x = -t_y*ccw;
               double n_y = t_x*ccw;
               double mag_n = sqrt(n_x*n_x+n_y*n_y);
               if(mag_n>1e-3) {
                  n_x /= mag_n; n_y /= mag_n;
               }
               
               double n_mt = mt();
               double x = point.getX()+offset.x() + 0.5*t_x + 10.0*n_mt*n_x;
               double y = point.getY()+offset.y() + 0.5*t_y + 10.0*n_mt*n_y;
               //std::cout << "t_x: " << t_x << ", t_y: " << t_y << ", n_x: " << 10.0*n_mt*n_x << ", n_y: " << 10.0*n_mt*n_y << std::endl;
               std::cout << "x: " << x << ", y: " << y << std::endl;

               point = point_next;
               //std::cout << "Boundary trace: s: " << s << ", x: " << x << ", y:"  << y << ", tile min: (" << tileXMin << ", " << tileYMin << "), max: (" << tileXMax << ", " << tileYMax << ")" << std::endl;

               osg::BoundingBox tileBB(tileXMin, tileYMin, -1.0, tileXMax, tileYMax, 1.0);
               if(tileBB.contains(osg::Vec3(x,y,0.0))) {
                  osg::PositionAttitudeTransform* treeTrans = new osg::PositionAttitudeTransform();
                  treeGroup->addChild(treeTrans);
                  //hflayer->getInterpolatedValue(x,y,z);
                  int x_int = floor((x-tileXMin)/tileXInterval+0.5);
                  if(x_int<0) x_int=0; else if(x_int>=field->getNumColumns()) x_int=field->getNumColumns()-1;
                  int y_int = floor((y-tileYMin)/tileYInterval+0.5);
                  if(y_int<0) y_int=0; else if(y_int>=field->getNumRows()) y_int=field->getNumRows()-1;
                  double z = field->getHeight(x_int,y_int);

                  //osg::Vec3 treePos(x,y,z);
                  osg::Vec3 treePos(point.getX(),point.getY(),z);
                  treeTrans->setPosition(treePos);
                  int treeIt = (int)floor(mt()*(double)treeNodeVector.size());
                  treeTrans->addChild(treeNodeVector[treeIt].get());
                  treeTrans->setName("TreeTransform");
               }
            }*/


            OGREnvelope psEnvelope;
            poPolygon->getEnvelope(&psEnvelope);
            int nTrees = (int)((psEnvelope.MaxX-psEnvelope.MinX)*(psEnvelope.MaxY-psEnvelope.MinY)*1e-5/tileElementArea);
            for(int i = 0; i<nTrees; ++i)
            {
               OGRPoint point;
               //point.setX(mt()*(psEnvelope.MaxX-psEnvelope.MinX) + psEnvelope.MinX);
               //point.setY(mt()*(psEnvelope.MaxY-psEnvelope.MinY) + psEnvelope.MinY);
               point.setX(mt()*(tileXMax-tileXMin) + tileXMin);
               point.setY(mt()*(tileYMax-tileYMin) + tileYMin);
               //if(poPolygon->Contains(&point)) {
                  osg::PositionAttitudeTransform* treeTrans = new osg::PositionAttitudeTransform();
                  treeGroup->addChild(treeTrans);
                  //hflayer->getInterpolatedValue(x,y,z);
                  double x = point.getX() + offset.x();
                  double y = point.getY() + offset.y();
                  int x_int = floor((x-tileXMin)/tileXInterval+0.5);
                  if(x_int<0) x_int=0; else if(x_int>=field->getNumColumns()) x_int=field->getNumColumns()-1;
                  int y_int = floor((y-tileYMin)/tileYInterval+0.5);
                  if(y_int<0) y_int=0; else if(y_int>=field->getNumRows()) y_int=field->getNumRows()-1;
                  double z = field->getHeight(x_int,y_int);
                  std::cout << "int x: " << x_int << ", x: " << x-tileXMin << ", y: " << y_int << ", y: " << y-tileYMin << std::endl;

                  //osg::Vec3 treePos(x,y,z);
                  osg::Vec3 treePos(x,y,z);
                  treeTrans->setPosition(treePos);
                  int treeIt = (int)floor(mt()*(double)treeNodeVector.size());
                  treeTrans->addChild(treeNodeVector[treeIt].get());
                  treeTrans->setName("TreeTransform");
               //}
            }
         }
      }
   }
#endif

#if 0
   typedef gaalet::algebra< gaalet::signature<3,0> > em;
   typedef em::mv<1, 2, 4>::type Vector;
   typedef em::mv<3, 5, 6>::type Bivector;
   typedef em::mv<0, 3, 5, 6>::type Rotor;

   static const em::mv<0>::type one(1.0);
   static const em::mv<1>::type e1(1.0);
   static const em::mv<2>::type e2(1.0);
   static const em::mv<4>::type e3(1.0);
   static const em::mv<7>::type e123(1.0);

   osgTerrain::Layer* colorLayer = tile->getColorLayer(0);
   if(colorLayer) {
      osg::Image* inputImage = colorLayer->getImage();

      /*static int tileLoadCounter = 0;
      osg::Image* outputImage = NULL;
      if(tileLoadCounter==0) {
         outputImage = new osg::Image();
         outputImage->allocateImage(inputImage->s(), inputImage->t(), 1, 0x1907, 0x1401);
      }
      tileLoadCounter += 1;*/


      em::mv<0,6>::type *fftwImag1 = (em::mv<0,6>::type*) fftw_malloc(sizeof(em::mv<0,6>::type)*inputImage->s()*inputImage->t());
      em::mv<0,3>::type *fftwImag2 = (em::mv<0,3>::type*) fftw_malloc(sizeof(em::mv<0,3>::type)*inputImage->s()*inputImage->t());

      em::mv<0,6>::type *fftwFreq1 = (em::mv<0,6>::type*) fftw_malloc(sizeof(em::mv<0,6>::type)*inputImage->s()*inputImage->t());
      em::mv<0,3>::type *fftwFreq2 = (em::mv<0,3>::type*) fftw_malloc(sizeof(em::mv<0,3>::type)*inputImage->s()*inputImage->t());


      fftw_plan fftwForward1 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwImag1), reinterpret_cast<fftw_complex*>(fftwFreq1), FFTW_FORWARD, FFTW_ESTIMATE);
      fftw_plan fftwForward2 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwImag2), reinterpret_cast<fftw_complex*>(fftwFreq2), FFTW_FORWARD, FFTW_ESTIMATE);

      fftw_plan fftwBackward1 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwFreq1), reinterpret_cast<fftw_complex*>(fftwImag1), FFTW_BACKWARD, FFTW_ESTIMATE);
      fftw_plan fftwBackward2 = fftw_plan_dft_2d(inputImage->s(), inputImage->t(), reinterpret_cast<fftw_complex*>(fftwFreq2), reinterpret_cast<fftw_complex*>(fftwImag2), FFTW_BACKWARD, FFTW_ESTIMATE);


      for(int x=0; x<inputImage->s(); ++x) {
         for(int y=0; y<inputImage->t(); ++y) {
            if(inputImage->getPixelFormat()==0x83f0) {   //COMPRESSED_RGB_S3TC_DXT1_EXT decompression
               unsigned int blocksize = 8;

               unsigned char* data = inputImage->data();
               unsigned char* block = data + (blocksize*(unsigned int)(ceil(double(inputImage->s()/4.0)*floor(y/4.0) + floor(x/4.0))));

               int rel_x = x % 4;
               int rel_y = y % 4;

               unsigned char& c0_lo = *(block+0);
               unsigned char& c0_hi = *(block+1);
               unsigned char& c1_lo = *(block+2);
               unsigned char& c1_hi = *(block+3);
               unsigned char& bits_0 = *(block+4);
               unsigned char& bits_1 = *(block+5);
               unsigned char& bits_2 = *(block+6);
               unsigned char& bits_3 = *(block+7);

               unsigned short color0 = c0_lo + c0_hi * 256;
               unsigned short color1 = c1_lo + c1_hi * 256;
               unsigned int bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3));

               unsigned int code_bits_pos = 2*(4*rel_y+rel_x);
               unsigned int code = (bits>>code_bits_pos) & 0x03;

               unsigned char r0 = ((color0>>11) & 0x1f);
               unsigned char g0 = ((color0>>5) & 0x3f);
               unsigned char b0 = ((color0>>0) & 0x1f);
               unsigned char r1 = ((color1>>11) & 0x1f);
               unsigned char g1 = ((color1>>5) & 0x3f);
               unsigned char b1 = ((color1>>0) & 0x1f);

               unsigned char r = 0;
               unsigned char g = 0;
               unsigned char b = 0;

               if(color0>color1) {
                  switch(code) {
                     case 0:
                        r = r0;
                        g = g0;
                        b = b0;
                        break;
                     case 1:
                        r = r1;
                        g = g1;
                        b = b1;
                        break;
                     case 2:
                        r = (2*r0+r1)/3;
                        g = (2*g0+g1)/3;
                        b = (2*b0+b1)/3;
                        break;
                     case 3:
                        r = (r0+2*r1)/3;
                        g = (g0+2*g1)/3;
                        b = (b0+2*b1)/3;
                        break;
                  };
               }
               else {
                  switch(code) {
                     case 0:
                        r = r0;
                        g = g0;
                        b = b0;
                        break;
                     case 1:
                        r = r1;
                        g = g1;
                        b = b1;
                        break;
                     case 2:
                        r = (r0+r1)/2;
                        g = (g0+g1)/2;
                        b = (b0+b1)/2;
                        break;
                     case 3:
                        r = 0;
                        g = 0;
                        b = 0;
                        break;
                  };
               }

               (*(fftwImag1+inputImage->t()*x+y)) = (0.0*one)+((double)r*(double)0xff/(double)0x1f*e2*e3);
               (*(fftwImag2+inputImage->t()*x+y)) = ((double)g*(double)0xff/(double)0x3f*e3*e1)*e3*e1 + ((double)b*(double)0xff/(double)0x1f*e1*e2);

               /*if(outputImage) {
                  *(outputImage->data(x,y)+0) = (unsigned int)((double)r*(double)0xff/(double)0x1f);
                  *(outputImage->data(x,y)+1) = (unsigned int)((double)g*(double)0xff/(double)0x3f);
                  *(outputImage->data(x,y)+2) = (unsigned int)((double)b*(double)0xff/(double)0x1f);
               }*/
            }
            else {
               unsigned char& r = *(inputImage->data(x,y)+0);
               unsigned char& g = *(inputImage->data(x,y)+1);
               unsigned char& b = *(inputImage->data(x,y)+2);

               (*(fftwImag1+inputImage->t()*x+y)) = (0.0*one)+((double)r*e2*e3);
               (*(fftwImag2+inputImage->t()*x+y)) = ((double)g*e3*e1)*e3*e1 + ((double)b*e1*e2);
               //if(x==0 && y==0) std::cout << "(0,0): r: " << (int)r << ", g: " << (int)g << ", b: " << (int)b << std::endl;
            }
         }
      }
예제 #13
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");

    double dfDPI = CPLAtof(CSLFetchNameValueDef(papszOptions, "DPI", "72"));
    if (dfDPI < 72.0)
        dfDPI = 72.0;

    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");
    int bWriteOGRAttributes = CSLFetchBoolean(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 == NULL )
    {
        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 = nWidth * dfRatio;
    }
    else
    {
        nHeight = 1024;
        nWidth = nHeight / dfRatio;
    }

    GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, NULL );

    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 = NULL;
        poSRS->exportToWkt(&pszWKT);
        poSrcDS->SetProjection(pszWKT);
        CPLFree(pszWKT);
    }

    oWriter.SetInfo(poSrcDS, papszOptions);

    oWriter.StartPage(poSrcDS,
                      dfDPI,
                      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;
}
예제 #14
0
GDALDataset *NDFDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      The user must select the header file (ie. .H1).                 */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    if( !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=2",14) 
        && !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=0",14) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Read and process the header into a local name/value             */
/*      stringlist.  We just take off the trailing semicolon.  The      */
/*      keyword is already seperated from the value by an equal         */
/*      sign.                                                           */
/* -------------------------------------------------------------------- */

    VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (fp == NULL)
        return NULL;

    const char *pszLine;
    const int nHeaderMax = 1000;
    int nHeaderLines = 0;
    char **papszHeader = (char **) CPLMalloc(sizeof(char *) * (nHeaderMax+1));

    while( nHeaderLines < nHeaderMax
           && (pszLine = CPLReadLineL( fp )) != NULL
           && !EQUAL(pszLine,"END_OF_HDR;") )
    {
        char *pszFixed;

        if( strstr(pszLine,"=") == NULL )
            break;

        pszFixed = CPLStrdup( pszLine );
        if( pszFixed[strlen(pszFixed)-1] == ';' )
            pszFixed[strlen(pszFixed)-1] = '\0';
        
        papszHeader[nHeaderLines++] = pszFixed;
        papszHeader[nHeaderLines] = NULL;
    }
    VSIFCloseL(fp);
    fp = NULL;
    
    if( CSLFetchNameValue( papszHeader, "PIXELS_PER_LINE" ) == NULL 
        || CSLFetchNameValue( papszHeader, "LINES_PER_DATA_FILE" ) == NULL 
        || CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL" ) == NULL 
        || CSLFetchNameValue( papszHeader, "PIXEL_FORMAT" ) == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
              "Dataset appears to be NDF but is missing a required field.");
        CSLDestroy( papszHeader );
        return NULL;
    }

    if( !EQUAL(CSLFetchNameValue( papszHeader, "PIXEL_FORMAT"),
               "BYTE" ) 
        || !EQUAL(CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL"),"8") )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Currently NDF driver supports only 8bit BYTE format." );
        CSLDestroy( papszHeader );
        return NULL;
    }
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CSLDestroy( papszHeader );
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The NDF driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    NDFDataset 	*poDS;

    poDS = new NDFDataset();
    poDS->papszHeader = papszHeader;

    poDS->nRasterXSize = atoi(poDS->Get("PIXELS_PER_LINE",""));
    poDS->nRasterYSize = atoi(poDS->Get("LINES_PER_DATA_FILE",""));

/* -------------------------------------------------------------------- */
/*      Create a raw raster band for each file.                         */
/* -------------------------------------------------------------------- */
    int iBand;
    const char* pszBand = CSLFetchNameValue(papszHeader, 
                                        "NUMBER_OF_BANDS_IN_VOLUME");
    if (pszBand == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find band count");
        delete poDS;
        return NULL;
    }
    int nBands = atoi(pszBand);

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBands, FALSE))
    {
        delete poDS;
        return NULL;
    }

    for( iBand = 0; iBand < nBands; iBand++ )
    {
        char szKey[100];
        CPLString osFilename;

        sprintf( szKey, "BAND%d_FILENAME", iBand+1 );
        osFilename = poDS->Get(szKey,"");

        // NDF1 file do not include the band filenames.
        if( osFilename.size() == 0 )
        {
            char szBandExtension[15];
            sprintf( szBandExtension, "I%d", iBand+1 );
            osFilename = CPLResetExtension( poOpenInfo->pszFilename, 
                                            szBandExtension );
        }
        else
        {      
            CPLString osBasePath = CPLGetPath(poOpenInfo->pszFilename);
            osFilename = CPLFormFilename( osBasePath, osFilename, NULL);
        }

        VSILFILE *fpRaw = VSIFOpenL( osFilename, "rb" );
        if( fpRaw == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Failed to open band file: %s", 
                      osFilename.c_str() );
            delete poDS;
            return NULL;
        }
        poDS->papszExtraFiles = 
            CSLAddString( poDS->papszExtraFiles, 
                          osFilename );

        RawRasterBand *poBand = 
            new RawRasterBand( poDS, iBand+1, fpRaw, 0, 1, poDS->nRasterXSize,
                               GDT_Byte, TRUE, TRUE );
        
        sprintf( szKey, "BAND%d_NAME", iBand+1 );
        poBand->SetDescription( poDS->Get(szKey, "") );

        sprintf( szKey, "BAND%d_WAVELENGTHS", iBand+1 );
        poBand->SetMetadataItem( "WAVELENGTHS", poDS->Get(szKey,"") );

        sprintf( szKey, "BAND%d_RADIOMETRIC_GAINS/BIAS", iBand+1 );
        poBand->SetMetadataItem( "RADIOMETRIC_GAINS_BIAS", 
                                 poDS->Get(szKey,"") );

        poDS->SetBand( iBand+1, poBand );
    }

/* -------------------------------------------------------------------- */
/*      Fetch and parse USGS projection parameters.                     */
/* -------------------------------------------------------------------- */
    double adfUSGSParms[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    char **papszParmTokens = 
        CSLTokenizeStringComplex( poDS->Get( "USGS_PROJECTION_NUMBER", "" ),
                                  ",", FALSE, TRUE );

    if( CSLCount( papszParmTokens ) >= 15 )
    {
        int i;
        for( i = 0; i < 15; i++ )
            adfUSGSParms[i] = atof(papszParmTokens[i]);
    }
    CSLDestroy(papszParmTokens);
    papszParmTokens = NULL;

/* -------------------------------------------------------------------- */
/*      Minimal georef support ... should add full USGS style           */
/*      support at some point.                                          */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;
    int nUSGSProjection = atoi(poDS->Get( "USGS_PROJECTION_NUMBER", "" ));
    int nZone = atoi(poDS->Get("USGS_MAP_ZONE","0"));

    oSRS.importFromUSGS( nUSGSProjection, nZone, adfUSGSParms, 12 );

    CPLString osDatum = poDS->Get( "HORIZONTAL_DATUM", "" );
    if( EQUAL(osDatum,"WGS84") || EQUAL(osDatum,"NAD83") 
        || EQUAL(osDatum,"NAD27") )
    {
        oSRS.SetWellKnownGeogCS( osDatum );
    }
    else if( EQUALN(osDatum,"NAD27",5) )
    {
        oSRS.SetWellKnownGeogCS( "NAD27" );
    }
    else
    {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unrecognised datum name in NLAPS/NDF file:%s, assuming WGS84.", 
                  osDatum.c_str() );
        oSRS.SetWellKnownGeogCS( "WGS84" );
    }

    if( oSRS.GetRoot() != NULL )
    {
        CPLFree( poDS->pszProjection );
        poDS->pszProjection = NULL;
        oSRS.exportToWkt( &(poDS->pszProjection) );
    }

/* -------------------------------------------------------------------- */
/*      Get geotransform.                                               */
/* -------------------------------------------------------------------- */
    char **papszUL = CSLTokenizeString2( 
        poDS->Get("UPPER_LEFT_CORNER",""), ",", 0 );
    char **papszUR = CSLTokenizeString2( 
        poDS->Get("UPPER_RIGHT_CORNER",""), ",", 0 );
    char **papszLL = CSLTokenizeString2( 
        poDS->Get("LOWER_LEFT_CORNER",""), ",", 0 );
    
    if( CSLCount(papszUL) == 4 
        && CSLCount(papszUR) == 4 
        && CSLCount(papszLL) == 4 )
    {
        poDS->adfGeoTransform[0] = atof(papszUL[2]);
        poDS->adfGeoTransform[1] = 
            (atof(papszUR[2]) - atof(papszUL[2])) / (poDS->nRasterXSize-1);
        poDS->adfGeoTransform[2] = 
            (atof(papszUR[3]) - atof(papszUL[3])) / (poDS->nRasterXSize-1);

        poDS->adfGeoTransform[3] = atof(papszUL[3]);
        poDS->adfGeoTransform[4] = 
            (atof(papszLL[2]) - atof(papszUL[2])) / (poDS->nRasterYSize-1);
        poDS->adfGeoTransform[5] = 
            (atof(papszLL[3]) - atof(papszUL[3])) / (poDS->nRasterYSize-1);

        // Move origin up-left half a pixel.
        poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5;
        poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[4] * 0.5;
        poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[2] * 0.5;
        poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5;
    }

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #15
0
/**
 * Captures Geolocation information from a COSMO-SKYMED
 * file.
 * The geoid will always be WGS84
 * The projection type may be UTM or UPS, depending on the
 * latitude from the center of the image.
 * @param iProductType type of CSK subproduct, see HDF5CSKProduct
 */
void HDF5ImageDataset::CaptureCSKGeolocation(int iProductType)
{
    // Set the ellipsoid to WGS84.
    oSRS.SetWellKnownGeogCS( "WGS84" );

    if(iProductType == PROD_CSK_L1C||iProductType == PROD_CSK_L1D)
    {
        double *dfProjFalseEastNorth = NULL;
        double *dfProjScaleFactor = NULL;
        double *dfCenterCoord = NULL;

        // Check if all the metadata attributes are present.
        if(HDF5ReadDoubleAttr("Map Projection False East-North", &dfProjFalseEastNorth) == CE_Failure||
                HDF5ReadDoubleAttr("Map Projection Scale Factor", &dfProjScaleFactor) == CE_Failure||
                HDF5ReadDoubleAttr("Map Projection Centre", &dfCenterCoord) == CE_Failure||
                GetMetadataItem("Projection_ID") == NULL)
        {
            pszProjection = CPLStrdup("");
            pszGCPProjection = CPLStrdup("");
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "The CSK hdf5 file geolocation information is "
                      "malformed\n" );
        }
        else
        {
            // Fetch projection Type.
            CPLString osProjectionID = GetMetadataItem("Projection_ID");

            //If the projection is UTM
            if(EQUAL(osProjectionID,"UTM"))
            {
                // @TODO: use SetUTM
                oSRS.SetProjCS(SRS_PT_TRANSVERSE_MERCATOR);
                oSRS.SetTM(dfCenterCoord[0],
                           dfCenterCoord[1],
                           dfProjScaleFactor[0],
                           dfProjFalseEastNorth[0],
                           dfProjFalseEastNorth[1]);
            }
            else
            {
                //TODO Test! I didn't had any UPS projected files to test!
                //If the projection is UPS
                if(EQUAL(osProjectionID,"UPS"))
                {
                    oSRS.SetProjCS(SRS_PT_POLAR_STEREOGRAPHIC);
                    oSRS.SetPS(dfCenterCoord[0],
                               dfCenterCoord[1],
                               dfProjScaleFactor[0],
                               dfProjFalseEastNorth[0],
                               dfProjFalseEastNorth[1]);
                }
            }

            //Export Projection to Wkt.
            //In case of error then clean the projection
            if (oSRS.exportToWkt(&pszProjection) != OGRERR_NONE)
                pszProjection = CPLStrdup("");

            CPLFree(dfCenterCoord);
            CPLFree(dfProjScaleFactor);
            CPLFree(dfProjFalseEastNorth);
        }
    }
    else
    {
        //Export GCPProjection to Wkt.
        //In case of error then clean the projection
        if(oSRS.exportToWkt(&pszGCPProjection) != OGRERR_NONE)
            pszGCPProjection = CPLStrdup("");
    }
}
예제 #16
0
GDALDataset *SDTSDataset::Open( GDALOpenInfo * poOpenInfo )

{
    int         i;
    
/* -------------------------------------------------------------------- */
/*      Before trying SDTSOpen() we first verify that the first         */
/*      record is in fact a SDTS file descriptor record.                */
/* -------------------------------------------------------------------- */
    char        *pachLeader = (char *) poOpenInfo->pabyHeader;
    
    if( poOpenInfo->nHeaderBytes < 24 )
        return NULL;

    if( pachLeader[5] != '1' && pachLeader[5] != '2' && pachLeader[5] != '3' )
        return NULL;

    if( pachLeader[6] != 'L' )
        return NULL;

    if( pachLeader[8] != '1' && pachLeader[8] != ' ' )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */
    SDTSTransfer        *poTransfer = new SDTSTransfer;
    
    if( !poTransfer->Open( poOpenInfo->pszFilename ) )
    {
        delete poTransfer;
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        delete poTransfer;
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The SDTS driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Find the first raster layer.  If there are none, abort          */
/*      returning an error.                                             */
/* -------------------------------------------------------------------- */
    SDTSRasterReader    *poRL = NULL;

    for( i = 0; i < poTransfer->GetLayerCount(); i++ )
    {
        if( poTransfer->GetLayerType( i ) == SLTRaster )
        {
            poRL = poTransfer->GetLayerRasterReader( i );
            break;
        }
    }

    if( poRL == NULL )
    {
        delete poTransfer;
        
        CPLError( CE_Warning, CPLE_AppDefined,
                  "%s is an SDTS transfer, but has no raster cell layers.\n"
                  "Perhaps it is a vector transfer?\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Initialize a corresponding GDALDataset.                         */
/* -------------------------------------------------------------------- */
    SDTSDataset *poDS = new SDTSDataset();

    poDS->poTransfer = poTransfer;
    poDS->poRL = poRL;
    
/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = poRL->GetXSize();
    poDS->nRasterYSize = poRL->GetYSize();
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    poDS->papoBands = (GDALRasterBand **)
        VSICalloc(sizeof(GDALRasterBand *),poDS->nBands);

    for( i = 0; i < poDS->nBands; i++ )
        poDS->SetBand( i+1, new SDTSRasterBand( poDS, i+1, poRL ) );

/* -------------------------------------------------------------------- */
/*      Try to establish the projection string.  For now we only        */
/*      support UTM and GEO.                                            */
/* -------------------------------------------------------------------- */
    OGRSpatialReference   oSRS;
    SDTS_XREF   *poXREF = poTransfer->GetXREF();

    if( EQUAL(poXREF->pszSystemName,"UTM") )
    {									
        oSRS.SetUTM( poXREF->nZone );
    }
    else if( EQUAL(poXREF->pszSystemName,"GEO") )
    {
        /* we set datum later */
    }
    else
        oSRS.SetLocalCS( poXREF->pszSystemName );

    if( oSRS.IsLocal() )
        /* don't try to set datum. */;
    else if( EQUAL(poXREF->pszDatum,"NAS") )
        oSRS.SetWellKnownGeogCS( "NAD27" );
    else if( EQUAL(poXREF->pszDatum, "NAX") )
        oSRS.SetWellKnownGeogCS( "NAD83" );
    else if( EQUAL(poXREF->pszDatum, "WGC") )
        oSRS.SetWellKnownGeogCS( "WGS72" );
    else if( EQUAL(poXREF->pszDatum, "WGE") )
        oSRS.SetWellKnownGeogCS( "WGS84" );
    else
        oSRS.SetWellKnownGeogCS( "WGS84" );

    oSRS.Fixup();

    poDS->pszProjection = NULL;
    if( oSRS.exportToWkt( &poDS->pszProjection ) != OGRERR_NONE )
        poDS->pszProjection = CPLStrdup("");


/* -------------------------------------------------------------------- */
/*      Get metadata from the IDEN file.                                */
/* -------------------------------------------------------------------- */
    const char* pszIDENFilePath = poTransfer->GetCATD()->GetModuleFilePath("IDEN");
    if (pszIDENFilePath)
    {
        DDFModule   oIDENFile;
        if( oIDENFile.Open( pszIDENFilePath ) )
        {
            DDFRecord* poRecord;

            while( (poRecord = oIDENFile.ReadRecord()) != NULL )
            {

                if( poRecord->GetStringSubfield( "IDEN", 0, "MODN", 0 ) == NULL )
                    continue;

                static const char* fields[][2] = { { "TITL", "TITLE" },
                                                   { "DAID", "DATASET_ID" },
                                                   { "DAST", "DATA_STRUCTURE" },
                                                   { "MPDT", "MAP_DATE" },
                                                   { "DCDT", "DATASET_CREATION_DATE" } };

                for (i = 0; i < (int)sizeof(fields) / (int)sizeof(fields[0]) ; i++)
                {
                    const char* pszFieldValue =
                            poRecord->GetStringSubfield( "IDEN", 0, fields[i][0], 0 );
                    if ( pszFieldValue )
                        poDS->SetMetadataItem(fields[i][1], pszFieldValue);
                }

                break;
            }
        }
    }

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

    return( poDS );
}
예제 #17
0
CPLErr HDF5ImageDataset::CreateProjections()
{
    switch(iSubdatasetType)
    {
    case CSK_PRODUCT:
    {
        const char *osMissionLevel = NULL;
        int productType = PROD_UNKNOWN;

        if(GetMetadataItem("Product_Type")!=NULL)
        {
            //Get the format's level
            osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type");

            if(STARTS_WITH_CI(osMissionLevel, "RAW"))
                productType  = PROD_CSK_L0;

            if(STARTS_WITH_CI(osMissionLevel, "SSC"))
                productType  = PROD_CSK_L1A;

            if(STARTS_WITH_CI(osMissionLevel, "DGM"))
                productType  = PROD_CSK_L1B;

            if(STARTS_WITH_CI(osMissionLevel, "GEC"))
                productType  = PROD_CSK_L1C;

            if(STARTS_WITH_CI(osMissionLevel, "GTC"))
                productType  = PROD_CSK_L1D;
        }

        CaptureCSKGeoTransform(productType);
        CaptureCSKGeolocation(productType);
        CaptureCSKGCPs(productType);

        break;
    }
    case UNKNOWN_PRODUCT:
    {
        static const int NBGCPLAT = 100;
        static const int NBGCPLON = 30;

        const int nDeltaLat = nRasterYSize / NBGCPLAT;
        const int nDeltaLon = nRasterXSize / NBGCPLON;

        if( nDeltaLat == 0 || nDeltaLon == 0 )
            return CE_None;

        /* -------------------------------------------------------------------- */
        /*      Create HDF5 Data Hierarchy in a link list                       */
        /* -------------------------------------------------------------------- */
        poH5Objects=HDF5FindDatasetObjects( poH5RootGroup,  "Latitude" );
        if( !poH5Objects ) {
            if( GetMetadataItem("where_projdef") != NULL )
                return CreateODIMH5Projection();
            return CE_None;
        }
        /* -------------------------------------------------------------------- */
        /*      The Latitude and Longitude arrays must have a rank of 2 to     */
        /*      retrieve GCPs.                                                  */
        /* -------------------------------------------------------------------- */
        if( poH5Objects->nRank != 2 ) {
            return CE_None;
        }

        /* -------------------------------------------------------------------- */
        /*      Retrieve HDF5 data information                                  */
        /* -------------------------------------------------------------------- */
        const hid_t LatitudeDatasetID   = H5Dopen( hHDF5,poH5Objects->pszPath );
        // LatitudeDataspaceID = H5Dget_space( dataset_id );

        poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" );
        const hid_t LongitudeDatasetID   = H5Dopen( hHDF5,poH5Objects->pszPath );
        // LongitudeDataspaceID = H5Dget_space( dataset_id );

        if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) {
            float * const Latitude = static_cast<float *>(
                                         CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) );
            float * const Longitude = static_cast<float *>(
                                          CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) );
            memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof(  float ) );
            memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) );

            H5Dread ( LatitudeDatasetID,
                      H5T_NATIVE_FLOAT,
                      H5S_ALL,
                      H5S_ALL,
                      H5P_DEFAULT,
                      Latitude );

            H5Dread ( LongitudeDatasetID,
                      H5T_NATIVE_FLOAT,
                      H5S_ALL,
                      H5S_ALL,
                      H5P_DEFAULT,
                      Longitude );

            oSRS.SetWellKnownGeogCS( "WGS84" );
            CPLFree(pszProjection);
            CPLFree(pszGCPProjection);
            oSRS.exportToWkt( &pszProjection );
            oSRS.exportToWkt( &pszGCPProjection );

            /* -------------------------------------------------------------------- */
            /*  Fill the GCPs list.                                                 */
            /* -------------------------------------------------------------------- */
            nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon;

            pasGCPList = static_cast<GDAL_GCP *>(
                             CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ) );

            GDALInitGCPs( nGCPCount, pasGCPList );
            int k=0;

            const int nYLimit = (static_cast<int>(nRasterYSize)/nDeltaLat) * nDeltaLat;
            const int nXLimit = (static_cast<int>(nRasterXSize)/nDeltaLon) * nDeltaLon;
            for( int j = 0; j < nYLimit; j+=nDeltaLat )
            {
                for( int i = 0; i < nXLimit; i+=nDeltaLon )
                {
                    const int iGCP =  j * nRasterXSize + i;
                    pasGCPList[k].dfGCPX = static_cast<double>(Longitude[iGCP])+180.0;
                    pasGCPList[k].dfGCPY = static_cast<double>(Latitude[iGCP]);

                    pasGCPList[k].dfGCPPixel = i + 0.5;
                    pasGCPList[k++].dfGCPLine =  j + 0.5;
                }
            }

            CPLFree( Latitude );
            CPLFree( Longitude );
        }

        if( LatitudeDatasetID > 0 )
            H5Dclose(LatitudeDatasetID);
        if( LongitudeDatasetID > 0 )
            H5Dclose(LongitudeDatasetID);

        break;
    }
    }

    return CE_None;
}
예제 #18
0
GDALDataset *BTDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Verify that this is some form of binterr file.                  */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->nHeaderBytes < 256)
        return NULL;

    if( strncmp( (const char *) poOpenInfo->pabyHeader, "binterr", 7 ) != 0 )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    BTDataset  *poDS;

    poDS = new BTDataset();
 
    memcpy( poDS->abyHeader, poOpenInfo->pabyHeader, 256 );

/* -------------------------------------------------------------------- */
/*      Get the version.                                                */
/* -------------------------------------------------------------------- */
    char szVersion[4];

    strncpy( szVersion, (char *) (poDS->abyHeader + 7), 3 );
    szVersion[3] = '\0';
    poDS->nVersionCode = (int) (atof(szVersion) * 10);

/* -------------------------------------------------------------------- */
/*      Extract core header information, being careful about the        */
/*      version.                                                        */
/* -------------------------------------------------------------------- */
    GInt32 nIntTemp;
    GInt16 nDataSize;
    GDALDataType eType;

    memcpy( &nIntTemp, poDS->abyHeader + 10, 4 );
    poDS->nRasterXSize = CPL_LSBWORD32( nIntTemp );
    
    memcpy( &nIntTemp, poDS->abyHeader + 14, 4 );
    poDS->nRasterYSize = CPL_LSBWORD32( nIntTemp );

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
    {
        delete poDS;
        return NULL;
    }

    memcpy( &nDataSize, poDS->abyHeader+18, 2 );
    nDataSize = CPL_LSBWORD16( nDataSize );

    if( poDS->abyHeader[20] != 0 && nDataSize == 4 )
        eType = GDT_Float32;
    else if( poDS->abyHeader[20] == 0 && nDataSize == 4 )
        eType = GDT_Int32;
    else if( poDS->abyHeader[20] == 0 && nDataSize == 2 )
        eType = GDT_Int16;
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  ".bt file data type unknown, got datasize=%d.", 
                  nDataSize );
        delete poDS;
        return NULL;
    }

    /*
        rcg, apr 7/06: read offset 62 for vert. units.
        If zero, assume 1.0 as per spec.

    */
    memcpy( &poDS->m_fVscale, poDS->abyHeader + 62, 4 );
    CPL_LSBPTR32(&poDS->m_fVscale);
    if(poDS->m_fVscale == 0.0f)
        poDS->m_fVscale = 1.0f; 

/* -------------------------------------------------------------------- */
/*      Try to read a .prj file if it is indicated.                     */
/* -------------------------------------------------------------------- */
    OGRSpatialReference oSRS;						

    if( poDS->nVersionCode >= 12 && poDS->abyHeader[60] != 0 )
    {
        const char  *pszPrjFile = CPLResetExtension( poOpenInfo->pszFilename, 
                                                     "prj" );
        VSILFILE *fp;

        fp = VSIFOpenL( pszPrjFile, "rt" );
        if( fp != NULL )
        {
            char *pszBuffer, *pszBufPtr;
            int  nBufMax = 10000;
            int nBytes;

            pszBuffer = (char *) CPLMalloc(nBufMax);
            nBytes = VSIFReadL( pszBuffer, 1, nBufMax-1, fp );
            VSIFCloseL( fp );

            pszBuffer[nBytes] = '\0';

            pszBufPtr = pszBuffer;
            if( oSRS.importFromWkt( &pszBufPtr ) != OGRERR_NONE )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Unable to parse .prj file, coordinate system missing." );
            }
            CPLFree( pszBuffer );
        }
    }

/* -------------------------------------------------------------------- */
/*      If we didn't find a .prj file, try to use internal info.        */
/* -------------------------------------------------------------------- */
    if( oSRS.GetRoot() == NULL )
    {
        GInt16 nUTMZone, nDatum, nHUnits;
        
        memcpy( &nUTMZone, poDS->abyHeader + 24, 2 );
        nUTMZone = CPL_LSBWORD16( nUTMZone );
        
        memcpy( &nDatum, poDS->abyHeader + 26, 2 );
        nDatum = CPL_LSBWORD16( nDatum );
        
        memcpy( &nHUnits, poDS->abyHeader + 22, 2 );
        nHUnits = CPL_LSBWORD16( nHUnits );

        if( nUTMZone != 0 )
            oSRS.SetUTM( ABS(nUTMZone), nUTMZone > 0 );
        else if( nHUnits != 0 )
            oSRS.SetLocalCS( "Unknown" );
        
        if( nHUnits == 1 )
            oSRS.SetLinearUnits( SRS_UL_METER, 1.0 );
        else if( nHUnits == 2 )
            oSRS.SetLinearUnits( SRS_UL_FOOT, atof(SRS_UL_FOOT_CONV) );
        else if( nHUnits == 3 )
            oSRS.SetLinearUnits( SRS_UL_US_FOOT, atof(SRS_UL_US_FOOT_CONV) );

        // Translate some of the more obvious old USGS datum codes 
        if( nDatum == 0 )
            nDatum = 6201;
        else if( nDatum == 1 )
            nDatum = 6209;
        else if( nDatum == 2 )
            nDatum = 6210;
        else if( nDatum == 3 )
            nDatum = 6202;
        else if( nDatum == 4 )
            nDatum = 6203;
        else if( nDatum == 6 )
            nDatum = 6222;
        else if( nDatum == 7 )
            nDatum = 6230;
        else if( nDatum == 13 )
            nDatum = 6267;
        else if( nDatum == 14 )
            nDatum = 6269;
        else if( nDatum == 17 )
            nDatum = 6277;
        else if( nDatum == 19 )
            nDatum = 6284;
        else if( nDatum == 21 )
            nDatum = 6301;
        else if( nDatum == 22 )
            nDatum = 6322;
        else if( nDatum == 23 )
            nDatum = 6326;

        if( !oSRS.IsLocal() )
        {
            if( nDatum >= 6000 )
            {
                char szName[32];
                sprintf( szName, "EPSG:%d", nDatum-2000 );
                oSRS.SetWellKnownGeogCS( szName );
            }
            else
                oSRS.SetWellKnownGeogCS( "WGS84" );
        }                
    }

/* -------------------------------------------------------------------- */
/*      Convert coordinate system back to WKT.                          */
/* -------------------------------------------------------------------- */
    if( oSRS.GetRoot() != NULL )
        oSRS.exportToWkt( &poDS->pszProjection );

/* -------------------------------------------------------------------- */
/*      Get georeferencing bounds.                                      */
/* -------------------------------------------------------------------- */
    if( poDS->nVersionCode >= 11 )
    {
        double dfLeft, dfRight, dfTop, dfBottom;

        memcpy( &dfLeft, poDS->abyHeader + 28, 8 );
        CPL_LSBPTR64( &dfLeft );
        
        memcpy( &dfRight, poDS->abyHeader + 36, 8 );
        CPL_LSBPTR64( &dfRight );
        
        memcpy( &dfBottom, poDS->abyHeader + 44, 8 );
        CPL_LSBPTR64( &dfBottom );
        
        memcpy( &dfTop, poDS->abyHeader + 52, 8 );
        CPL_LSBPTR64( &dfTop );

        poDS->adfGeoTransform[0] = dfLeft;
        poDS->adfGeoTransform[1] = (dfRight - dfLeft) / poDS->nRasterXSize;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfTop;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = (dfBottom - dfTop) / poDS->nRasterYSize;
        
        poDS->bGeoTransformValid = TRUE;
    }
    
/* -------------------------------------------------------------------- */
/*      Re-open the file with the desired access.                       */
/* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_Update )
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    else
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within BT driver.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }
    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Create band information objects                                 */
/* -------------------------------------------------------------------- */
    poDS->SetBand( 1, new BTRasterBand( poDS, poDS->fpImage, eType ) );

#ifdef notdef
    poDS->bGeoTransformValid = 
        GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", 
                           poDS->adfGeoTransform );
#endif

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #19
0
GDALDataset *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE dataset?                             */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the large file API.                         */
/* -------------------------------------------------------------------- */
    VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );

    if( fpQube == NULL )
        return NULL;

    ISIS3Dataset 	*poDS;

    poDS = new ISIS3Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return NULL;
    }
    
    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*	Assume user is pointing to label (ie .lbl) file for detached option */
/* -------------------------------------------------------------------- */
    //  Image can be inline or detached and point to an image name
    //  the Format can be Tiled or Raw
    //  Object = Core
    //      StartByte   = 65537
    //      Format      = Tile
    //      TileSamples = 128
    //      TileLines   = 128
    //OR-----
    //  Object = Core
    //      StartByte = 1
    //      ^Core     = r0200357_detatched.cub
    //      Format    = BandSequential
    //OR-----
    //  Object = Core
    //      StartByte = 1
    //      ^Core     = r0200357_detached_tiled.cub
    //      Format      = Tile
    //      TileSamples = 128
    //      TileLines   = 128
    
/* -------------------------------------------------------------------- */
/*      What file contains the actual data?                             */
/* -------------------------------------------------------------------- */
    const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" );
    CPLString osQubeFile;

    if( EQUAL(pszCore,"") )
        osQubeFile = poOpenInfo->pszFilename;
    else
    {
        CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
        osQubeFile = CPLFormFilename( osPath, pszCore, NULL );
        poDS->osExternalCube = osQubeFile;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS3 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType = GDT_Byte;
    OGRSpatialReference oSRS;

    int	nRows = -1;
    int nCols = -1;
    int nBands = 1;
    int nSkipBytes = 0;
    int tileSizeX = 0;
    int tileSizeY = 0;
    double dfULXMap=0.5;
    double dfULYMap = 0.5;
    double dfXDim = 1.0;
    double dfYDim = 1.0;
    double scaleFactor = 1.0;
    double dfNoData = 0.0;
    int	bNoDataSet = FALSE;
    char chByteOrder = 'M';  //default to MSB
    char szLayout[32] = "BandSequential"; //default to band seq.
    const char *target_name; //planet name
    //projection parameters
    const char *map_proj_name;
    int	bProjectionSet = TRUE;
    char proj_target_name[200]; 
    char geog_name[60];  
    char datum_name[60];  
    char sphere_name[60];
    char bIsGeographic = TRUE;
    double semi_major = 0.0;
    double semi_minor = 0.0;
    double iflattening = 0.0;
    double center_lat = 0.0;
    double center_lon = 0.0;
    double first_std_parallel = 0.0;
    double second_std_parallel = 0.0;
    double radLat, localRadius;
    VSILFILE	*fp;

    /*************   Skipbytes     *****************************/
    nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1;

    /*******   Grab format type (BandSequential, Tiled)  *******/
    const char *value;

    value = poDS->GetKeyword( "IsisCube.Core.Format", "" );
    if (EQUAL(value,"Tile") )  { //Todo
        strcpy(szLayout,"Tiled");
       /******* Get Tile Sizes *********/
       tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples",""));
       tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines",""));
       if (tileSizeX <= 0 || tileSizeY <= 0)
       {
           CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d",
                     tileSizeX, tileSizeY);
           delete poDS;
           return NULL;
       }
    }
    else if (EQUAL(value,"BandSequential") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    nCols = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Samples",""));
    nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines",""));
    nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands",""));
     
    /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/
    const char *itype;

    itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" );
    if (EQUAL(itype,"UnsignedByte") ) {
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"UnsignedWord") ) {
        eDataType = GDT_UInt16;
        dfNoData = NULL1;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"SignedWord") ) {
        eDataType = GDT_Int16;
        dfNoData = NULL2;
        bNoDataSet = TRUE;
    }
    else if (EQUAL(itype,"Real") || EQUAL(value,"") ) {
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = TRUE;
    }
    else {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "%s layout type not supported. Abort\n\n", itype);
        delete poDS;
        return NULL;
    }

    /***********   Grab samples lines band ************/
    value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder");
    if (EQUAL(value,"Lsb"))
        chByteOrder = 'I';
    
    /***********   Grab Cellsize ************/
    value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution");
    if (strlen(value) > 0 ) {
        dfXDim = CPLAtof(value); /* values are in meters */
        dfYDim = -CPLAtof(value);
    }
    
    /***********   Grab UpperLeftCornerY ************/
    value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY");
    if (strlen(value) > 0) {
        dfULYMap = CPLAtof(value);
    }
     
    /***********   Grab UpperLeftCornerX ************/
    value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX");
    if( strlen(value) > 0 ) {
        dfULXMap = CPLAtof(value);
    }
     
    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. Mars ***/
    target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName");
     
    /***********   Grab MAP_PROJECTION_TYPE ************/
    map_proj_name = 
        poDS->GetKeyword( "IsisCube.Mapping.ProjectionName");

    /***********   Grab SEMI-MAJOR ************/
    semi_major = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius"));

    /***********   Grab semi-minor ************/
    semi_minor = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius"));

    /***********   Grab CENTER_LAT ************/
    center_lat = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude"));

    /***********   Grab CENTER_LON ************/
    center_lon = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude"));

    /***********   Grab 1st std parallel ************/
    first_std_parallel = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel"));

    /***********   Grab 2nd std parallel ************/
    second_std_parallel = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel"));
     
    /***********   Grab scaleFactor ************/
    scaleFactor = 
        CPLAtof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor", "1.0"));
     
    /*** grab      LatitudeType = Planetographic ****/
    // Need to further study how ocentric/ographic will effect the gdal library
    // So far we will use this fact to define a sphere or ellipse for some 
    // projections

    // Frank - may need to talk this over
    value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType");
    if (EQUAL( value, "Planetocentric" ))
        bIsGeographic = FALSE; 
     
    //Set oSRS projection and parameters
    //############################################################
    //ISIS3 Projection types
    //  Equirectangular 
    //  LambertConformal 
    //  Mercator 
    //  ObliqueCylindrical //Todo
    //  Orthographic 
    //  PolarStereographic 
    //  SimpleCylindrical 
    //  Sinusoidal 
    //  TransverseMercator
    
#ifdef DEBUG
    CPLDebug( "ISIS3", "using projection %s", map_proj_name);
#endif

    if ((EQUAL( map_proj_name, "Equirectangular" )) ||
        (EQUAL( map_proj_name, "SimpleCylindrical" )) )  {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "Orthographic" )) {
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "Sinusoidal" )) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "Mercator" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "PolarStereographic" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "TransverseMercator" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 );
    } else if (EQUAL( map_proj_name, "LambertConformal" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else {
        CPLDebug( "ISIS3",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name );
        bProjectionSet = FALSE;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        strcpy(proj_target_name, map_proj_name);
        strcat(proj_target_name, " ");
        strcat(proj_target_name, target_name);
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     
        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        strcpy(geog_name, "GCS_");
        strcat(geog_name, target_name);
        
        //The datum name will be the same basic name as the planet
        strcpy(datum_name, "D_");
        strcat(datum_name, target_name);
     
        strcpy(sphere_name, target_name);
        //strcat(sphere_name, "_IAU_IAG");  //Might not be IAU defined so don't add
          
        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        if ((semi_major - semi_minor) < 0.0000001) 
           iflattening = 0;
        else
           iflattening = semi_major / (semi_major - semi_minor);
     
        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "Stereographic" ) && (fabs(center_lat) == 90)) ) || 
	           (EQUAL( map_proj_name, "PolarStereographic" )) )  
         {
            if (bIsGeographic) { 
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                               "Reference_Meridian", 0.0 );
            } else {
              //Geocentric, so force a sphere using the semi-minor axis. I hope... 
              strcat(sphere_name, "_polarRadius");
              oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                              semi_minor, 0.0, 
                              "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SimpleCylindrical" )) || 
  	               (EQUAL( map_proj_name, "Orthographic" )) || 
	               (EQUAL( map_proj_name, "Stereographic" )) || 
	               (EQUAL( map_proj_name, "Sinusoidal" )) ) {
            //isis uses the sphereical equation for these projections so force a sphere
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else if  (EQUAL( map_proj_name, "Equirectangular" )) { 
            //Calculate localRadius using ISIS3 simple elliptical method 
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            radLat = center_lat * PI / 180;  // in radians
            localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) 
                          + pow(semi_major*sin(radLat),2) );
            strcat(sphere_name, "_localRadius");
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            localRadius, 0.0, 
                            "Reference_Meridian", 0.0 );
        } 
        else { 
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening, 
                                "Reference_Meridian", 0.0 );
            } else { 
                //Geocentric, so force a sphere. I hope... 
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0, 
                                "Reference_Meridian", 0.0 );
            }
        }

        // translate back into a projection string.
        char *pszResult = NULL;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS3 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
    
/* -------------------------------------------------------------------- */
/*     Is the CUB detached - if so, reset name to binary file?          */
/* -------------------------------------------------------------------- */
#ifdef notdef
    // Frank - is this correct?
    //The extension already added on so don't add another. But is this needed?
    char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) );
    char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) );
    if (bIsDetached)
        pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" );
#endif

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( nRows < 1 || nCols < 1 || nBands < 1 )
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osQubeFile, "r" );
    else
        poDS->fpImage = VSIFOpenL( osQubeFile, "r+" );

    if( poDS->fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open %s with write permission.\n%s", 
                  osQubeFile.c_str(),
                  VSIStrerror( errno ) );
        delete poDS;
        return NULL;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
    int	    nLineOffset=0, nPixelOffset=0, nBandOffset=0;
    
    if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nLineOffset * nRows;
    }
    else /* Tiled */
    {
    }
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int i;

#ifdef CPL_LSB                               
    int bNativeOrder = !(chByteOrder == 'M');
#else
    int bNativeOrder = (chByteOrder == 'M');
#endif        


    for( i = 0; i < nBands; i++ )
    {
        GDALRasterBand	*poBand;

        if( EQUAL(szLayout,"Tiled") )
        {
            poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType,
                                        tileSizeX, tileSizeY, 
                                        nSkipBytes, 0, 0, 
                                        bNativeOrder );
        }
        else
        {
            poBand = 
                new RawRasterBand( poDS, i+1, poDS->fpImage,
                                   nSkipBytes + nBandOffset * i, 
                                   nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB                               
                                   chByteOrder == 'I' || chByteOrder == 'L',
#else
                                   chByteOrder == 'M',
#endif        
                                   TRUE );
        }

        poDS->SetBand( i+1, poBand );

        if( bNoDataSet )
            ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset( 
            CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0")));
        poBand->SetScale( 
          CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For ISIS3 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    CPLString osPath, osName;

    osPath = CPLGetPath( poOpenInfo->pszFilename );
    osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    fp = VSIFOpenL( pszPrjFile, "r" );
    if( fp != NULL )
    {
        char	**papszLines;
        OGRSpatialReference oSRS;

        VSIFCloseL( fp );
        
        papszLines = CSLLoad( pszPrjFile );

        if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = NULL;
            oSRS.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    
    if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }
    
    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform = 
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
                               poDS->adfGeoTransform );

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #20
0
int main( int argc, char ** argv )

{
    int            i;
    int            bGotSRS = FALSE;
    int            bPretty = FALSE;
    int            bOutputAll = FALSE;
    int            bValidate = FALSE;

    const char     *pszInput = NULL;
    const char     *pszOutputType = "all";
    char           *pszOutput = NULL;

    OGRSpatialReference  oSRS;

    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL;
    OGRDataSource *poOGRDS = NULL;
    OGRLayer      *poLayer = NULL;
    char           *pszProjection = NULL;
    int            bDebug = FALSE;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;

    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(argv[0]))
        exit(1);

    /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
    /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
    /* for the --format or --formats options */
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") )
        {
            CPLSetConfigOption( argv[i+1], argv[i+2] );

            i += 2;
        }
    }

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

    /* -------------------------------------------------------------------- */
    /*      Parse arguments.                                                */
    /* -------------------------------------------------------------------- */
    for( i = 1; i < argc; i++ )
    {
        CPLDebug( "gdalsrsinfo", "got arg #%d : [%s]", i, argv[i] );

        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i], "-h") )
            Usage();
        else if( EQUAL(argv[i], "-o") && i < argc - 1)
            pszOutputType = argv[++i];
        else if( EQUAL(argv[i], "-p") )
            bPretty = TRUE;
        else if( EQUAL(argv[i], "-V") )
            bValidate = TRUE;
        else if( argv[i][0] == '-' )
        {
            CSLDestroy( argv );
            Usage();
        }
        else
            pszInput = argv[i];
    }

    if ( pszInput == NULL ) {
        CSLDestroy( argv );
        Usage();
    }

    /* Register drivers */
    GDALAllRegister();
    OGRRegisterAll();

    /* Search for SRS */

    /* temporarily supress error messages we may get from xOpen() */
    bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF"));
    if ( ! bDebug )
        oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );

    /* If argument is a file, try to open it with GDALOpen() and get the projection */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {

        bIsFile = TRUE;
        VSIFCloseL( fp );

        /* try to open with GDAL */
        CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
        poGDALDS =  (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly );
        if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) {
            pszProjection = (char *) poGDALDS->GetProjectionRef( );
            if( oSRS.importFromWkt( &pszProjection ) == CE_None ) {
                CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
                bGotSRS = TRUE;
            }
            GDALClose( (GDALDatasetH) poGDALDS );
        }
        if ( ! bGotSRS )
            CPLDebug( "gdalsrsinfo", "did not open with GDAL" );

        /* if unsuccessful, try to open with OGR */
        if ( ! bGotSRS ) {
            CPLDebug( "gdalsrsinfo", "trying to open with OGR" );
            poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL );
            if( poOGRDS != NULL ) {
                poLayer = poOGRDS->GetLayer( 0 );
                if ( poLayer != NULL ) {
                    OGRSpatialReference *poSRS = poLayer->GetSpatialRef( );
                    if ( poSRS != NULL ) {
                        CPLDebug( "gdalsrsinfo", "got SRS from OGR" );
                        bGotSRS = TRUE;
                        OGRSpatialReference* poSRSClone = poSRS->Clone();
                        oSRS = *poSRSClone;
                        OGRSpatialReference::DestroySpatialReference( poSRSClone );
                    }
                }
                OGRDataSource::DestroyDataSource( poOGRDS );
                poOGRDS = NULL;
            }
            if ( ! bGotSRS )
                CPLDebug( "gdalsrsinfo", "did not open with OGR" );

            /* OGR_DS_Destroy( hOGRDS ); */
        }

    }

    /* If didn't get the projection from the file, try OSRSetFromUserInput() */
    /* File might not be a dataset, but contain projection info (e.g. .prf files) */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo",
                  "trying to get SRS from user input [%s]", pszInput );
        if( oSRS.SetFromUserInput( pszInput ) != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from user input" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from user input" );
            bGotSRS = TRUE;
        }
    }

    /* restore error messages */
    if ( ! bDebug )
        CPLSetErrorHandler ( oErrorHandler );

    CPLDebug( "gdalsrsinfo",
              "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d",
              bGotSRS, bValidate, pszOutputType, bPretty  );

    /* Make sure we got a SRS */
    if ( ! bGotSRS ) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ERROR - failed to load SRS definition from %s",
                  pszInput );
    }

    else {

        /* Validate - not well tested!*/
        if ( bValidate ) {
            OGRErr eErr = oSRS.Validate( );
            if ( eErr != OGRERR_NONE ) {
                printf( "\nValidate Fails" );
                if ( eErr == OGRERR_CORRUPT_DATA )
                    printf( " - SRS is not well formed");
                else if ( eErr == OGRERR_UNSUPPORTED_SRS )
                    printf(" - contains non-standard PROJECTION[] values");
                printf("\n");
            }
            else
                printf( "\nValidate Succeeds\n" );
        }

        /* Output */
        if ( EQUAL("all", pszOutputType ) ) {
            bOutputAll = TRUE;
            bPretty = TRUE;
        }

        printf("\n");

        if ( bOutputAll || EQUAL("proj4", pszOutputType ) ) {
            if ( bOutputAll ) printf("PROJ.4 : ");
            oSRS.exportToProj4( &pszOutput );
            printf("\'%s\'\n\n",pszOutput);
            CPLFree( pszOutput );
        }

        if ( bOutputAll || EQUAL("wkt", pszOutputType ) ) {
            if ( bOutputAll ) printf("OGC WKT :\n");
            if ( bPretty )
                oSRS.exportToPrettyWkt( &pszOutput, FALSE );
            else
                oSRS.exportToWkt( &pszOutput );
            printf("%s\n\n",pszOutput);
            CPLFree( pszOutput );
        }

        if ( bOutputAll || EQUAL("wkt_simple", pszOutputType ) ) {
            if ( bOutputAll ) printf("OGC WKT (simple) :\n");
            oSRS.exportToPrettyWkt( &pszOutput, TRUE );
            printf("%s\n\n",pszOutput);
            CPLFree( pszOutput );
        }

        if ( EQUAL("wkt_old", pszOutputType ) ) {
            if (  bOutputAll ) printf("OGC WKT (old) :\n");
            oSRS.StripCTParms( );
            if ( bPretty )
                oSRS.exportToPrettyWkt( &pszOutput, FALSE );
            else
                oSRS.exportToWkt( &pszOutput );
            printf("%s\n\n",pszOutput);
            CPLFree( pszOutput );
        }

        if ( bOutputAll || EQUAL("wkt_esri", pszOutputType ) ) {
            if ( bOutputAll ) printf("ESRI WKT :\n");
            OGRSpatialReference *poSRS = oSRS.Clone();
            poSRS->morphToESRI( );
            if ( bPretty )
                poSRS->exportToPrettyWkt( &pszOutput, FALSE );
            else
                poSRS->exportToWkt( &pszOutput );
            printf("%s\n\n",pszOutput);
            CPLFree( pszOutput );
            OGRSpatialReference::DestroySpatialReference( poSRS );
        }

        /* mapinfo and xml are not output with "all" */
        if ( EQUAL("mapinfo", pszOutputType ) ) {
            if ( bOutputAll ) printf("MAPINFO : ");
            oSRS.exportToMICoordSys( &pszOutput );
            printf("\'%s\'\n\n",pszOutput);
            CPLFree( pszOutput );
        }

        if ( EQUAL("xml", pszOutputType ) ) {
            if ( bOutputAll ) printf("XML :\n");
            oSRS.exportToXML( &pszOutput, NULL );
            printf("%s\n\n",pszOutput);
            CPLFree( pszOutput );
        }

    }

    /* cleanup anything left */
    GDALDestroyDriverManager();
    OGRCleanupAll();
    CSLDestroy( argv );

    return 0;

}
예제 #21
0
OGRLayer*  OGRVRTDataSource::InstanciateUnionLayer(
                                        CPLXMLNode *psLTree,
                                        const char *pszVRTDirectory,
                                        int bUpdate,
                                        int nRecLevel)
{
    CPLXMLNode *psSubNode;

    if( !EQUAL(psLTree->pszValue,"OGRVRTUnionLayer") )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get layer name.                                                 */
/* -------------------------------------------------------------------- */
    const char *pszLayerName = CPLGetXMLValue( psLTree, "name", NULL );

    if( pszLayerName == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Missing name attribute on OGRVRTUnionLayer" );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Do we have a fixed geometry type?  If not derive from the       */
/*      source layer.                                                   */
/* -------------------------------------------------------------------- */
    const char* pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL );
    int bGlobalGeomTypeSet = FALSE;
    OGRwkbGeometryType eGlobalGeomType = wkbUnknown;
    if( pszGType != NULL )
    {
        int bError;
        bGlobalGeomTypeSet = TRUE;
        eGlobalGeomType = OGRVRTGetGeometryType(pszGType, &bError);
        if( bError )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "GeometryType %s not recognised.",
                    pszGType );
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Apply a spatial reference system if provided                    */
/* -------------------------------------------------------------------- */
     const char* pszLayerSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL );
     OGRSpatialReference* poGlobalSRS = NULL;
     int bGlobalSRSSet = FALSE;
     if( pszLayerSRS != NULL )
     {
         bGlobalSRSSet = TRUE;
         if( !EQUAL(pszLayerSRS,"NULL") )
         {
             OGRSpatialReference oSRS;

             if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Failed to import LayerSRS `%s'.", pszLayerSRS );
                 return FALSE;
             }
             poGlobalSRS = oSRS.Clone();
         }
     }

/* -------------------------------------------------------------------- */
/*      Find field declarations.                                        */
/* -------------------------------------------------------------------- */
    OGRFieldDefn** papoFields = NULL;
    int nFields = 0;
    OGRUnionLayerGeomFieldDefn** papoGeomFields = NULL;
    int nGeomFields = 0;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
         if( psSubNode->eType != CXT_Element )
             continue;

         if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"Field") )
         {
/* -------------------------------------------------------------------- */
/*      Field name.                                                     */
/* -------------------------------------------------------------------- */
             const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL );
             if( pszName == NULL )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Unable to identify Field name." );
                 break;
             }

             OGRFieldDefn oFieldDefn( pszName, OFTString );

/* -------------------------------------------------------------------- */
/*      Type                                                            */
/* -------------------------------------------------------------------- */
             const char *pszArg = CPLGetXMLValue( psSubNode, "type", NULL );

             if( pszArg != NULL )
             {
                 int iType;

                 for( iType = 0; iType <= (int) OFTMaxType; iType++ )
                 {
                     if( EQUAL(pszArg,OGRFieldDefn::GetFieldTypeName(
                                   (OGRFieldType)iType)) )
                     {
                         oFieldDefn.SetType( (OGRFieldType) iType );
                         break;
                     }
                 }

                 if( iType > (int) OFTMaxType )
                 {
                     CPLError( CE_Failure, CPLE_AppDefined,
                               "Unable to identify Field type '%s'.",
                               pszArg );
                     break;
                 }
             }

/* -------------------------------------------------------------------- */
/*      Width and precision.                                            */
/* -------------------------------------------------------------------- */
             int nWidth = atoi(CPLGetXMLValue( psSubNode, "width", "0" ));
             if (nWidth < 0)
             {
                CPLError( CE_Failure, CPLE_IllegalArg,
                          "Invalid width for field %s.",
                          pszName );
                break;
             }
             oFieldDefn.SetWidth(nWidth);

             int nPrecision = atoi(CPLGetXMLValue( psSubNode, "precision", "0" ));
             if (nPrecision < 0 || nPrecision > 1024)
             {
                CPLError( CE_Failure, CPLE_IllegalArg,
                          "Invalid precision for field %s.",
                          pszName );
                break;
             }
             oFieldDefn.SetPrecision(nPrecision);

             papoFields = (OGRFieldDefn**) CPLRealloc(papoFields,
                                        sizeof(OGRFieldDefn*) * (nFields + 1));
             papoFields[nFields] = new OGRFieldDefn(&oFieldDefn);
             nFields ++;
         }

         else if( psSubNode->eType == CXT_Element &&
                  EQUAL(psSubNode->pszValue,"GeometryField") )
         {
             const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL );
             if( pszName == NULL )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Unable to identify GeometryField name." );
                 break;
             }

             pszGType = CPLGetXMLValue( psSubNode, "GeometryType", NULL );
             if( pszGType == NULL && nGeomFields == 0 )
                 pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL );
             OGRwkbGeometryType eGeomType = wkbUnknown;
             int bGeomTypeSet = FALSE;
             if( pszGType != NULL )
             {
                int bError;
                eGeomType = OGRVRTGetGeometryType(pszGType, &bError);
                bGeomTypeSet = TRUE;
                if( bError || eGeomType == wkbNone )
                {
                    CPLError( CE_Failure, CPLE_AppDefined,
                            "GeometryType %s not recognised.",
                            pszGType );
                    break;
                }
             }

             const char* pszSRS = CPLGetXMLValue( psSubNode, "SRS", NULL );
             if( pszSRS == NULL && nGeomFields == 0 )
                 pszSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL );
             OGRSpatialReference* poSRS = NULL;
             int bSRSSet = FALSE;
             if( pszSRS != NULL )
             {
                 bSRSSet = TRUE;
                 if( !EQUAL(pszSRS,"NULL") )
                 {
                    OGRSpatialReference oSRS;

                    if( oSRS.SetFromUserInput( pszSRS ) != OGRERR_NONE )
                    {
                        CPLError( CE_Failure, CPLE_AppDefined,
                                "Failed to import SRS `%s'.", pszSRS );
                        break;
                    }
                    poSRS = oSRS.Clone();
                }
             }

             OGRUnionLayerGeomFieldDefn* poFieldDefn =
                    new OGRUnionLayerGeomFieldDefn(pszName, eGeomType);
             if( poSRS != NULL )
             {
                poFieldDefn->SetSpatialRef(poSRS);
                poSRS->Dereference();
             }
             poFieldDefn->bGeomTypeSet = bGeomTypeSet;
             poFieldDefn->bSRSSet = bSRSSet;

             const char* pszExtentXMin = CPLGetXMLValue( psSubNode, "ExtentXMin", NULL );
             const char* pszExtentYMin = CPLGetXMLValue( psSubNode, "ExtentYMin", NULL );
             const char* pszExtentXMax = CPLGetXMLValue( psSubNode, "ExtentXMax", NULL );
             const char* pszExtentYMax = CPLGetXMLValue( psSubNode, "ExtentYMax", NULL );
             if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
                 pszExtentXMax != NULL && pszExtentYMax != NULL )
             {
                poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin);
                poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin);
                poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax);
                poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax);
             }

             papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields,
                                        sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1));
             papoGeomFields[nGeomFields] = poFieldDefn;
             nGeomFields ++;
         }
    }

/* -------------------------------------------------------------------- */
/*      Set Extent if provided                                          */
/* -------------------------------------------------------------------- */
    const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL );
    const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL );
    const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL );
    const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL );

    if( eGlobalGeomType != wkbNone && nGeomFields == 0 &&
        (bGlobalGeomTypeSet || bGlobalSRSSet ||
         (pszExtentXMin != NULL && pszExtentYMin != NULL &&
          pszExtentXMax != NULL && pszExtentYMax != NULL)) )
    {
        OGRUnionLayerGeomFieldDefn* poFieldDefn =
                new OGRUnionLayerGeomFieldDefn("", eGlobalGeomType);
        if( poGlobalSRS != NULL )
        {
            poFieldDefn->SetSpatialRef(poGlobalSRS);
            poGlobalSRS->Dereference();
            poGlobalSRS = NULL;
        }
        poFieldDefn->bGeomTypeSet = bGlobalGeomTypeSet;
        poFieldDefn->bSRSSet = bGlobalSRSSet;
        if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
            pszExtentXMax != NULL && pszExtentYMax != NULL )
        {
            poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin);
            poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin);
            poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax);
            poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax);
        }

        papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields,
                                sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1));
        papoGeomFields[nGeomFields] = poFieldDefn;
        nGeomFields ++;
    }
    else
    {
        delete poGlobalSRS;
        poGlobalSRS = NULL;
    }

/* -------------------------------------------------------------------- */
/*      Find source layers                                              */
/* -------------------------------------------------------------------- */

    int nSrcLayers = 0;
    OGRLayer** papoSrcLayers = NULL;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
        if( psSubNode->eType != CXT_Element )
            continue;

        OGRLayer* poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory,
                                           bUpdate, nRecLevel + 1);
        if( poSrcLayer != NULL )
        {
            papoSrcLayers = (OGRLayer**)
                CPLRealloc(papoSrcLayers, sizeof(OGRLayer*) * (nSrcLayers + 1));
            papoSrcLayers[nSrcLayers] = poSrcLayer;
            nSrcLayers ++;
        }
    }

    if( nSrcLayers == 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot find source layers" );
        int iField;
        for(iField = 0; iField < nFields; iField++)
            delete papoFields[iField];
        CPLFree(papoFields);
        for(iField = 0; iField < nGeomFields; iField++)
            delete papoGeomFields[iField];
        CPLFree(papoGeomFields);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Build the OGRUnionLayer.                                        */
/* -------------------------------------------------------------------- */
    OGRUnionLayer* poLayer = new OGRUnionLayer( pszLayerName,
                                                nSrcLayers,
                                                papoSrcLayers,
                                                TRUE );

/* -------------------------------------------------------------------- */
/*      Set the source layer field name attribute.                      */
/* -------------------------------------------------------------------- */
    const char* pszSourceLayerFieldName =
        CPLGetXMLValue( psLTree, "SourceLayerFieldName", NULL );
    poLayer->SetSourceLayerFieldName(pszSourceLayerFieldName);

/* -------------------------------------------------------------------- */
/*      Set the PreserveSrcFID attribute.                               */
/* -------------------------------------------------------------------- */
    int bPreserveSrcFID = FALSE;
    const char* pszPreserveFID = CPLGetXMLValue( psLTree, "PreserveSrcFID", NULL );
    if( pszPreserveFID != NULL )
        bPreserveSrcFID = CSLTestBoolean(pszPreserveFID);
    poLayer->SetPreserveSrcFID(bPreserveSrcFID);

/* -------------------------------------------------------------------- */
/*      Set fields                                                      */
/* -------------------------------------------------------------------- */
    FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS;
    const char* pszFieldStrategy = CPLGetXMLValue( psLTree, "FieldStrategy", NULL );
    if( pszFieldStrategy != NULL )
    {
        if( EQUAL(pszFieldStrategy, "FirstLayer") )
            eFieldStrategy = FIELD_FROM_FIRST_LAYER;
        else if( EQUAL(pszFieldStrategy, "Union") )
            eFieldStrategy = FIELD_UNION_ALL_LAYERS;
        else if( EQUAL(pszFieldStrategy, "Intersection") )
            eFieldStrategy = FIELD_INTERSECTION_ALL_LAYERS;
        else
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Unhandled value for FieldStrategy `%s'.", pszFieldStrategy );
        }
    }
    if( nFields != 0 || nGeomFields > 1 )
    {
        if( pszFieldStrategy != NULL )
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Ignoring FieldStrategy value, because explicit Field or GeometryField is provided") ;
        eFieldStrategy = FIELD_SPECIFIED;
    }

    poLayer->SetFields(eFieldStrategy, nFields, papoFields,
                       (nGeomFields == 0 && eGlobalGeomType == wkbNone) ? -1 : nGeomFields,
                       papoGeomFields);
    int iField;
    for(iField = 0; iField < nFields; iField++)
        delete papoFields[iField];
    CPLFree(papoFields);
    for(iField = 0; iField < nGeomFields; iField++)
        delete papoGeomFields[iField];
    CPLFree(papoGeomFields);

/* -------------------------------------------------------------------- */
/*      Set FeatureCount if provided                                    */
/* -------------------------------------------------------------------- */
    const char* pszFeatureCount = CPLGetXMLValue( psLTree, "FeatureCount", NULL );
    if( pszFeatureCount != NULL )
    {
        poLayer->SetFeatureCount(atoi(pszFeatureCount));
    }

    return poLayer;
}
예제 #22
0
GDALDataset *ROIPACDataset::Open( GDALOpenInfo *poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Confirm that the header is compatible with a ROIPAC dataset.    */
/* -------------------------------------------------------------------- */
    if ( !Identify(poOpenInfo) )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the .rsc file                                              */
/* -------------------------------------------------------------------- */
    CPLString osRscFilename = getRscFilename( poOpenInfo );
    if ( osRscFilename.empty() )
    {
        return NULL;
    }
    VSILFILE *fpRsc;
    if ( poOpenInfo->eAccess == GA_Update )
    {
        fpRsc = VSIFOpenL( osRscFilename, "r+" );
    }
    else
    {
        fpRsc = VSIFOpenL( osRscFilename, "r" );
    }
    if ( fpRsc == NULL )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Load the .rsc information.                                      */
/* -------------------------------------------------------------------- */
    char **papszRsc = NULL;
    while ( true )
    {
        const char *pszLine;
        char **papszTokens;

        pszLine = CPLReadLineL( fpRsc );
        if (pszLine == NULL)
        {
            break;
        }

        papszTokens = CSLTokenizeString2( pszLine, " \t",
                                          CSLT_STRIPLEADSPACES
                                            | CSLT_STRIPENDSPACES
                                            | CSLT_PRESERVEQUOTES
                                            | CSLT_PRESERVEESCAPES );
        if ( papszTokens == NULL 
             || papszTokens[0] == NULL || papszTokens[1] == NULL )
        {
            CSLDestroy ( papszTokens );
            break;
        }
        papszRsc = CSLSetNameValue( papszRsc,
                                       papszTokens[0], papszTokens[1] );

        CSLDestroy ( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Fetch required fields.                                          */
/* -------------------------------------------------------------------- */
    int nWidth = 0, nFileLength = 0;
    if ( CSLFetchNameValue( papszRsc, "WIDTH" ) == NULL
        || CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) == NULL )
    {
        CSLDestroy( papszRsc );
        VSIFCloseL( fpRsc );
        return NULL;
    }
    nWidth = atoi( CSLFetchNameValue( papszRsc, "WIDTH" ) ); 
    nFileLength = atoi( CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) );

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ROIPACDataset *poDS;
    poDS = new ROIPACDataset();
    poDS->nRasterXSize = nWidth;
    poDS->nRasterYSize = nFileLength;
    poDS->eAccess = poOpenInfo->eAccess;
    poDS->fpRsc = fpRsc;
    poDS->pszRscFilename = CPLStrdup( osRscFilename.c_str() );

/* -------------------------------------------------------------------- */
/*      Reopen file in update mode if necessary.                        */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" );
    }
    else
    {
        poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    }
    if( poDS->fpImage == NULL )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to re-open %s within ROI_PAC driver.\n",
                  poOpenInfo->pszFilename );
        CSLDestroy( papszRsc );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    GDALDataType eDataType;
    int nBands;
    enum Interleave { LINE, PIXEL } eInterleave;
    const char *pszExtension = CPLGetExtension(poOpenInfo->pszFilename);
    if ( strcmp( pszExtension, "raw" ) == 0 )
    {
        /* ------------------------------------------------------------ */
        /* TODO: ROI_PAC raw images are what would be GDT_CInt8 typed,  */
        /* but since that type do not exist, we will have to implement  */
        /* a specific case in the RasterBand to convert it to           */
        /* GDT_CInt16 for example                                       */
        /* ------------------------------------------------------------ */
#if 0
        eDataType = GDT_CInt8;
        nBands = 1;
        eInterleave = PIXEL;
#else
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Reading ROI_PAC raw files is not supported yet." );
        delete poDS;
        CSLDestroy( papszRsc );
        return NULL;
#endif
    }
    else if ( strcmp( pszExtension, "int" ) == 0
                || strcmp( pszExtension, "slc" ) == 0 )
    {
        eDataType = GDT_CFloat32;
        nBands = 1;
        eInterleave = PIXEL;
    }
    else if ( strcmp( pszExtension, "amp" ) == 0 )
    {
        eDataType = GDT_Float32;
        nBands = 2;
        eInterleave = PIXEL;
    }
    else if ( strcmp( pszExtension, "cor" ) == 0 
                || strcmp( pszExtension, "hgt" ) == 0 
                || strcmp( pszExtension, "unw" ) == 0 
                || strcmp( pszExtension, "msk" ) == 0 
                || strcmp( pszExtension, "trans" ) == 0 )
    {
        eDataType = GDT_Float32;
        nBands = 2;
        eInterleave = LINE;
    }
    else if ( strcmp( pszExtension, "dem" ) == 0 )
    {
        eDataType = GDT_Int16;
        nBands = 1;
        eInterleave = PIXEL;
    }
    else { /* Eeek */
        delete poDS;
        CSLDestroy( papszRsc );
        return NULL;
    }
    int nPixelOffset;
    int nLineOffset;
    int nBandOffset;
    if (eInterleave == LINE)
    {
        nPixelOffset = GDALGetDataTypeSize(eDataType)/8;
        nLineOffset = nPixelOffset * nWidth * nBands;
        nBandOffset = GDALGetDataTypeSize(eDataType)/8 * nWidth;
    }
    else { /* PIXEL */
        nPixelOffset = GDALGetDataTypeSize(eDataType)/8 * nBands;
        nLineOffset = nPixelOffset * nWidth * nBands;
        nBandOffset = GDALGetDataTypeSize(eDataType)/8;
    }
    poDS->nBands = nBands;
    for (int b = 0; b < nBands; b++)
    {
        poDS->SetBand( b + 1,
                       new ROIPACRasterBand( poDS, b + 1, poDS->fpImage,
                                             nBandOffset * b,
                                             nPixelOffset, nLineOffset,
                                             eDataType, TRUE,
                                             TRUE, FALSE ) );
    }

/* -------------------------------------------------------------------- */
/*      Interpret georeferencing, if present.                           */
/* -------------------------------------------------------------------- */
    if ( CSLFetchNameValue( papszRsc, "X_FIRST" ) != NULL
          && CSLFetchNameValue( papszRsc, "X_STEP" ) != NULL
          && CSLFetchNameValue( papszRsc, "Y_FIRST" ) != NULL
          && CSLFetchNameValue( papszRsc, "Y_STEP" ) != NULL )
    {
        poDS->adfGeoTransform[0] = CPLAtof( CSLFetchNameValue( papszRsc,
                                                               "X_FIRST" ) );
        poDS->adfGeoTransform[1] = CPLAtof( CSLFetchNameValue( papszRsc, 
                                                               "X_STEP" ) );
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = CPLAtof( CSLFetchNameValue( papszRsc, 
                                                               "Y_FIRST" ) );
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = CPLAtof( CSLFetchNameValue( papszRsc, 
                                                               "Y_STEP" ) );
        poDS->bValidGeoTransform = true;
    }
    if ( CSLFetchNameValue( papszRsc, "PROJECTION" ) != NULL )
    {
        /* ------------------------------------------------------------ */
        /* In ROI_PAC, images are georeferenced either with lat/long or */
        /* UTM projection. However, using UTM projection is dangerous   */
        /* because there is no North/South field, or use of latitude    */
        /* bands!                                                       */
        /* ------------------------------------------------------------ */
        OGRSpatialReference oSRS;
        if ( strcmp( CSLFetchNameValue( papszRsc, "PROJECTION" ),
                     "LL" ) == 0 )
        {
            if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL )
            {
                oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, 
                                                            "DATUM" ) );
            }
            else {
                oSRS.SetWellKnownGeogCS( "WGS84" );
            }
        }
        else if( strncmp( CSLFetchNameValue( papszRsc, "PROJECTION" ),
                          "UTM", 3 ) == 0 )
        {
            const char *pszZone = CSLFetchNameValue( papszRsc, 
                                                     "PROJECTION" ) + 3;
            oSRS.SetUTM( atoi( pszZone ), TRUE ); /* FIXME: north/south? */
            if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL )
            {
                oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, 
                                                            "DATUM" ) );
            }
            else {
                oSRS.SetWellKnownGeogCS( "NAD27" );
            }
        }
        oSRS.exportToWkt( &poDS->pszProjection );
    }


/* -------------------------------------------------------------------- */
/*      Set all the other header metadata into the ROI_PAC domain       */
/* -------------------------------------------------------------------- */
    for (int i = 0; i < CSLCount( papszRsc ); i++)
    {
        char **papszTokens;
        papszTokens = CSLTokenizeString2( papszRsc[i],
                                          "=",
                                          CSLT_STRIPLEADSPACES
                                            | CSLT_STRIPENDSPACES);
        if ( strcmp( papszTokens[0], "WIDTH" ) == 0
              || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0
              || strcmp( papszTokens[0], "X_FIRST" ) == 0
              || strcmp( papszTokens[0], "X_STEP" ) == 0
              || strcmp( papszTokens[0], "Y_FIRST" ) == 0
              || strcmp( papszTokens[0], "Y_STEP" ) == 0
              || strcmp( papszTokens[0], "PROJECTION" ) == 0 
              || strcmp( papszTokens[0], "DATUM" ) == 0 )
        {
            CSLDestroy( papszTokens );
            continue;
        }
        poDS->SetMetadataItem(papszTokens[0], papszTokens[1], "ROI_PAC");
        CSLDestroy( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Free papszRsc                                                   */
/* -------------------------------------------------------------------- */
    CSLDestroy( papszRsc );

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #23
0
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename,
                                     GDALDataset *poSrcDS, 
                                     int bStrict, char ** papszOptions, 
                                     GDALProgressFunc pfnProgress,
                                     void * pProgressData )
{
/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support source dataset with zero band.\n");
        return NULL;
    }

    if (nBands != 1)
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, 
                  "HF2 driver only uses the first band of the dataset.\n");
        if (bStrict)
            return NULL;
    }

    if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get source dataset info                                         */
/* -------------------------------------------------------------------- */

    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    double adfGeoTransform[6];
    poSrcDS->GetGeoTransform(adfGeoTransform);
    int bHasGeoTransform = !(adfGeoTransform[0] == 0 &&
                             adfGeoTransform[1] == 1 &&
                             adfGeoTransform[2] == 0 &&
                             adfGeoTransform[3] == 0 &&
                             adfGeoTransform[4] == 0 &&
                             adfGeoTransform[5] == 1);
    if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n");
        return NULL;
    }

    GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    GDALDataType eReqDT;
    float fVertPres = (float) 0.01;
    if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16)
    {
        fVertPres = 1;
        eReqDT = GDT_Int16;
    }
    else
        eReqDT = GDT_Float32;

/* -------------------------------------------------------------------- */
/*      Read creation options                                           */
/* -------------------------------------------------------------------- */
    const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS");
    int bCompress = FALSE;
    if (pszCompressed)
        bCompress = CSLTestBoolean(pszCompressed);
    
    const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION");
    if (pszVerticalPrecision)
    {
        fVertPres = (float) CPLAtofM(pszVerticalPrecision);
        if (fVertPres <= 0)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01");
            fVertPres = (float) 0.01;
        }
        if (eReqDT == GDT_Int16 && fVertPres > 1)
            eReqDT = GDT_Float32;
    }

    const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE");
    int nTileSize = 256;
    if (pszBlockSize)
    {
        nTileSize = atoi(pszBlockSize);
        if (nTileSize < 8 || nTileSize > 4096)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Unsupported value for BLOCKSIZE. Defaulting to 256");
            nTileSize = 256;
        }
    }

/* -------------------------------------------------------------------- */
/*      Parse source dataset georeferencing info                        */
/* -------------------------------------------------------------------- */

    int nExtendedHeaderLen = 0;
    if (bHasGeoTransform)
        nExtendedHeaderLen += 58;
    const char* pszProjectionRef = poSrcDS->GetProjectionRef();
    int nDatumCode = -2;
    int nUTMZone = 0;
    int bNorth = FALSE;
    int nEPSGCode = 0;
    int nExtentUnits = 1;
    if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0')
    {
        OGRSpatialReference oSRS;
        char* pszTemp = (char*) pszProjectionRef;
        if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE)
        {
            const char* pszValue = NULL;
            if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL
                && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") )
                nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" ));
            else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL)
            {
                if (strstr(pszValue, "WGS") && strstr(pszValue, "84"))
                    nDatumCode = 6326;
            }

            nUTMZone = oSRS.GetUTMZone(&bNorth);
        }
        if( oSRS.GetAuthorityName( "PROJCS" ) != NULL
            && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") )
            nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" ));

        if( oSRS.IsGeographic() )
        {
            nExtentUnits = 0;
        }
        else
        {
            double dfLinear = oSRS.GetLinearUnits();

            if( ABS(dfLinear - 0.3048) < 0.0000001 )
                nExtentUnits = 2;
            else if( ABS(dfLinear - atof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
                nExtentUnits = 3;
            else
                nExtentUnits = 1;
        }
    }
    if (nDatumCode != -2)
        nExtendedHeaderLen += 26;
    if (nUTMZone != 0)
        nExtendedHeaderLen += 26;
    if (nEPSGCode)
        nExtendedHeaderLen += 26;

/* -------------------------------------------------------------------- */
/*      Create target file                                              */
/* -------------------------------------------------------------------- */

    CPLString osFilename;
    if (bCompress)
    {
        osFilename = "/vsigzip/";
        osFilename += pszFilename;
    }
    else
        osFilename = pszFilename;
    VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb");
    if (fp == NULL)
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Cannot create %s", pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Write header                                                    */
/* -------------------------------------------------------------------- */

    VSIFWriteL("HF2\0", 4, 1, fp);
    WriteShort(fp, 0);
    WriteInt(fp, nXSize);
    WriteInt(fp, nYSize);
    WriteShort(fp, (GInt16) nTileSize);
    WriteFloat(fp, fVertPres);
    float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2);
    WriteFloat(fp, fHorizScale);
    WriteInt(fp, nExtendedHeaderLen);

/* -------------------------------------------------------------------- */
/*      Write extended header                                           */
/* -------------------------------------------------------------------- */

    char szBlockName[16 + 1];
    if (bHasGeoTransform)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-extents");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 34);
        WriteShort(fp, (GInt16) nExtentUnits);
        WriteDouble(fp, adfGeoTransform[0]);
        WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]);
        WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]);
        WriteDouble(fp, adfGeoTransform[3]);
    }
    if (nUTMZone != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-utm");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone));
    }
    if (nDatumCode != -2)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-datum");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nDatumCode);
    }
    if (nEPSGCode != 0)
    {
        VSIFWriteL("bin\0", 4, 1, fp);
        memset(szBlockName, 0, 16 + 1);
        strcpy(szBlockName, "georef-epsg-prj");
        VSIFWriteL(szBlockName, 16, 1, fp);
        WriteInt(fp, 2);
        WriteShort(fp, (GInt16) nEPSGCode);
    }

/* -------------------------------------------------------------------- */
/*      Copy imagery                                                    */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nTileSize - 1) / nTileSize;
    int nYBlocks = (nYSize + nTileSize - 1) / nTileSize;

    void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8));
    if (pTileBuffer == NULL)
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory");
        VSIFCloseL(fp);
        return NULL;
    }

    int i, j, k, l;
    CPLErr eErr = CE_None;
    for(j=0;j<nYBlocks && eErr == CE_None;j++)
    {
        for(i=0;i<nXBlocks && eErr == CE_None;i++)
        {
            int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize);
            int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize);
            eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read,
                                                i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize),
                                                nReqXSize, nReqYSize,
                                                pTileBuffer, nReqXSize, nReqYSize,
                                                eReqDT, 0, 0);
            if (eErr != CE_None)
                break;

            if (eReqDT == GDT_Int16)
            {
                WriteFloat(fp, 1); /* scale */
                WriteFloat(fp, 0); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        int nDiff = nVal - nLastVal;
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            char chDiff = (char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }
            else
            {
                float fMinVal = ((float*)pTileBuffer)[0];
                float fMaxVal = fMinVal;
                for(k=1;k<nReqYSize*nReqXSize;k++)
                {
                    float fVal = ((float*)pTileBuffer)[k];
                    if (fVal < fMinVal) fMinVal = fVal;
                    if (fVal > fMaxVal) fMaxVal = fVal;
                }

                float fIntRange = (fMaxVal - fMinVal) / fVertPres;
                float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange;
                float fOffset = fMinVal;
                WriteFloat(fp, fScale); /* scale */
                WriteFloat(fp, fOffset); /* offset */
                for(k=0;k<nReqYSize;k++)
                {
                    float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    float fIntLastVal = (fLastVal - fOffset) / fScale;
                    CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f);
                    int nLastVal = (int)fIntLastVal;
                    GByte nWordSize = 1;
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f);
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nDiff < -32768 || nDiff > 32767)
                        {
                            nWordSize = 4;
                            break;
                        }
                        if (nDiff < -128 || nDiff > 127)
                            nWordSize = 2;
                        nLastVal = nVal;
                    }

                    VSIFWriteL(&nWordSize, 1, 1, fp);
                    fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0];
                    fIntLastVal = (fLastVal - fOffset) / fScale;
                    nLastVal = (int)fIntLastVal;
                    WriteInt(fp, nLastVal);
                    for(l=1;l<nReqXSize;l++)
                    {
                        float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l];
                        float fIntVal = (fVal - fOffset) / fScale;
                        int nVal = (int)fIntVal;
                        int nDiff = nVal - nLastVal;
                        CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff);
                        if (nWordSize == 1)
                        {
                            CPLAssert(nDiff >= -128 && nDiff <= 127);
                            char chDiff = (char)nDiff;
                            VSIFWriteL(&chDiff, 1, 1, fp);
                        }
                        else if (nWordSize == 2)
                        {
                            CPLAssert(nDiff >= -32768 && nDiff <= 32767);
                            WriteShort(fp, (short)nDiff);
                        }
                        else
                        {
                            WriteInt(fp, nDiff);
                        }
                        nLastVal = nVal;
                    }
                }
            }

            if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) )
            {
                eErr = CE_Failure;
                break;
            }
        }
    }

    CPLFree(pTileBuffer);

    VSIFCloseL(fp);

    if (eErr != CE_None)
        return NULL;

    return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly);
}
예제 #24
0
void ROIPACDataset::FlushCache( void )
{
    RawDataset::FlushCache();

    GDALRasterBand *band = (GetRasterCount() > 0) ? GetRasterBand(1) : NULL;

    if ( eAccess == GA_ReadOnly || band == NULL )
        return;

    // If opening an existing file in Update mode (i.e. "r+") we need to make
    // sure any existing content is cleared, otherwise the file may contain
    // trailing content from the previous write.
    VSIFTruncateL( fpRsc, 0 );

    VSIFSeekL( fpRsc, 0, SEEK_SET );
/* -------------------------------------------------------------------- */
/*      Rewrite out the header.                                         */
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
/*      Raster dimensions.                                              */
/* -------------------------------------------------------------------- */
    VSIFPrintfL( fpRsc, "%-40s %d\n", "WIDTH", nRasterXSize );
    VSIFPrintfL( fpRsc, "%-40s %d\n", "FILE_LENGTH", nRasterYSize );

/* -------------------------------------------------------------------- */
/*      Georeferencing.                                                 */
/* -------------------------------------------------------------------- */
    if ( pszProjection != NULL )
    {
        char *pszProjectionTmp = pszProjection;
        OGRSpatialReference oSRS;
        if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE )
        {
            int bNorth;
            int iUTMZone;

            iUTMZone = oSRS.GetUTMZone( &bNorth );
            if ( iUTMZone != 0 )
            {
                VSIFPrintfL( fpRsc, "%-40s %s%d\n", "PROJECTION", "UTM", iUTMZone );
            }
            else if ( oSRS.IsGeographic() )
            {
                VSIFPrintfL( fpRsc, "%-40s %s\n", "PROJECTION", "LL" );
            }
            else
            {
                CPLError( CE_Warning, CPLE_AppDefined,
                          "ROI_PAC format only support Latitude/Longitude and "
                              "UTM projections, discarding projection.");
            }

            if ( oSRS.GetAttrValue( "DATUM" ) != NULL )
            {
                if ( strcmp( oSRS.GetAttrValue( "DATUM" ), "WGS_1984" ) == 0 )
                {
                    VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", "WGS84" );
                }
                else
                {
                    CPLError( CE_Warning, CPLE_AppDefined,
                              "Datum \"%s\" probably not supported in the "
                                  "ROI_PAC format, saving it anyway",
                                  oSRS.GetAttrValue( "DATUM" ) );
                    VSIFPrintfL( fpRsc, "%-40s %s\n", "DATUM", oSRS.GetAttrValue( "DATUM" ) );
                }
            }
            if ( oSRS.GetAttrValue( "UNIT" ) != NULL )
            {
                VSIFPrintfL( fpRsc, "%-40s %s\n", "X_UNIT", oSRS.GetAttrValue( "UNIT" ) );
                VSIFPrintfL( fpRsc, "%-40s %s\n", "Y_UNIT", oSRS.GetAttrValue( "UNIT" ) );
            }
        }
    }
    if( bValidGeoTransform )
    {
        if ( adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0 )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "ROI_PAC format do not support geotransform with "
                          "rotation, discarding info.");
        }
        else
        {
            VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_FIRST", adfGeoTransform[0] );
            VSIFPrintfL( fpRsc, "%-40s %.16g\n", "X_STEP", adfGeoTransform[1] );
            VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_FIRST", adfGeoTransform[3] );
            VSIFPrintfL( fpRsc, "%-40s %.16g\n", "Y_STEP", adfGeoTransform[5] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Metadata stored in the ROI_PAC domain.                          */
/* -------------------------------------------------------------------- */
    char** papszROIPACMetadata = GetMetadata( "ROI_PAC" );
    for (int i = 0; i < CSLCount( papszROIPACMetadata ); i++)
    {   
        char **papszTokens;

        /* Get the tokens from the metadata item */
        papszTokens = CSLTokenizeString2( papszROIPACMetadata[i], 
                                          "=", 
                                          CSLT_STRIPLEADSPACES 
                                            | CSLT_STRIPENDSPACES);
        if ( CSLCount( papszTokens ) != 2 )
        {   
            CPLDebug("ROI_PAC",
                     "Line of header file could not be split at = into two elements: %s",
                     papszROIPACMetadata[i]);
            CSLDestroy( papszTokens );
            continue;
        }

        /* Don't write it out if it is one of the bits of metadata that is
         * written out elsewhere in this routine */
        if ( strcmp( papszTokens[0], "WIDTH" ) == 0
              || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 )
        {   
            CSLDestroy( papszTokens );
            continue;
        }
        VSIFPrintfL( fpRsc, "%-40s %s\n", papszTokens[0], papszTokens[1] );
        CSLDestroy( papszTokens );
    }
}
OGRSpatialReference *OGRMySQLDataSource::FetchSRS( int nId )
{
    char         szCommand[1024];
    char           **papszRow;  
    MYSQL_RES       *hResult;
            
    if( nId < 0 )
        return NULL;

/* -------------------------------------------------------------------- */
/*      First, we look through our SRID cache, is it there?             */
/* -------------------------------------------------------------------- */
    int  i;

    for( i = 0; i < nKnownSRID; i++ )
    {
        if( panSRID[i] == nId )
            return papoSRS[i];
    }

    OGRSpatialReference *poSRS = NULL;
 
    // make sure to attempt to free any old results
    hResult = mysql_store_result( GetConn() );
    if( hResult != NULL )
        mysql_free_result( hResult );
    hResult = NULL;   
                        
    sprintf( szCommand,
         "SELECT srtext FROM spatial_ref_sys WHERE srid = %d",
         nId );
    
    if( !mysql_query( GetConn(), szCommand ) )
        hResult = mysql_store_result( GetConn() );
        
    char  *pszWKT = NULL;
    papszRow = NULL;
    

    if( hResult != NULL )
        papszRow = mysql_fetch_row( hResult );

    if( papszRow != NULL && papszRow[0] != NULL )
    {
        pszWKT = CPLStrdup(papszRow[0]);
    }

    if( hResult != NULL )
        mysql_free_result( hResult );
    hResult = NULL;

    poSRS = new OGRSpatialReference();
    char* pszWKTOri = pszWKT;
    if( pszWKT == NULL || poSRS->importFromWkt( &pszWKT ) != OGRERR_NONE )
    {
        delete poSRS;
        CPLFree(pszWKTOri);
        poSRS = NULL;
    }

    CPLFree(pszWKTOri);

/* -------------------------------------------------------------------- */
/*      Add to the cache.                                               */
/* -------------------------------------------------------------------- */
    panSRID = (int *) CPLRealloc(panSRID,sizeof(int) * (nKnownSRID+1) );
    papoSRS = (OGRSpatialReference **) 
        CPLRealloc(papoSRS, sizeof(void*) * (nKnownSRID + 1) );
    panSRID[nKnownSRID] = nId;
    papoSRS[nKnownSRID] = poSRS;
    nKnownSRID ++;

    return poSRS;
}
예제 #26
0
GDALDataset *ARGDataset::Open( GDALOpenInfo * poOpenInfo )
{
    json_object * pJSONObject;
    const char * pszJSONStr;
    char * pszLayer;
    /***** items from the json metadata *****/
    GDALDataType eType = GDT_Unknown;
    double fXmin = 0.0;
    double fYmin = 0.0;
    double fXmax = 0.0;
    double fYmax = 0.0;
    double fCellwidth = 1.0;
    double fCellheight = 1.0;
    double fXSkew = 0.0;
    double fYSkew = 0.0;
    int nRows = 0;
    int nCols = 0;
    int nSrs = 3857;
    /***** items from the json metadata *****/
    int nPixelOffset = 0;
    double fNoDataValue = NAN;

    char * pszWKT = NULL;
    OGRSpatialReference oSRS;
    OGRErr nErr = OGRERR_NONE;

    if ( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Check metadata settings in JSON.                                */
/* -------------------------------------------------------------------- */

    pJSONObject = GetJsonObject(poOpenInfo->pszFilename);

    if (pJSONObject == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined, "Error parsing JSON.");
        return NULL;
    }

    // get the type (always 'arg')
    pszJSONStr = GetJsonValueStr(pJSONObject, "type");
    if (pszJSONStr == NULL ) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    else if (!EQUAL(pszJSONStr, "arg")) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'type' is not recognized: '%s'.", pszJSONStr);
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the datatype
    pszJSONStr = GetJsonValueStr(pJSONObject, "datatype");
    if (pszJSONStr == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'datatype' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    else if (EQUAL(pszJSONStr, "int8")) {
        CPLDebug("ARGDataset", "Open(): "
            "int8 data is not supported in GDAL -- mapped to uint8");
        eType = GDT_Byte; 
        nPixelOffset = 1;
        fNoDataValue = 128;
    }
    else if (EQUAL(pszJSONStr, "int16")) {
        eType = GDT_Int16;
        nPixelOffset = 2;
        fNoDataValue = -32767;
    }
    else if (EQUAL(pszJSONStr, "int32")) {
        eType = GDT_Int32;
        nPixelOffset = 4;
        fNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "uint8")) {
        eType = GDT_Byte; 
        nPixelOffset = 1;
        fNoDataValue = 255;
    }
    else if (EQUAL(pszJSONStr, "uint16")) {
        eType = GDT_UInt16;
        nPixelOffset = 2;
        fNoDataValue = 65535;
    }
    else if (EQUAL(pszJSONStr, "uint32")) {
        eType = GDT_UInt32;
        nPixelOffset = 4;
        fNoDataValue = -2e31;
    }
    else if (EQUAL(pszJSONStr, "float32")) {
        eType = GDT_Float32;
        nPixelOffset = 4;
        fNoDataValue = NAN;
    }
    else if (EQUAL(pszJSONStr, "float64")) { 
        eType = GDT_Float64;
        nPixelOffset = 8;
        fNoDataValue = NAN;
    }
    else {
        if (EQUAL(pszJSONStr, "int64") ||
            EQUAL(pszJSONStr, "uint64")) {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unsupported in GDAL: '%s'.", pszJSONStr);
        }
        else {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The ARG 'datatype' is unknown: '%s'.", pszJSONStr);
        }
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the xmin of the bounding box
    fXmin = GetJsonValueDbl(pJSONObject, "xmin");
    if (CPLIsNan(fXmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }
    
    // get the ymin of the bounding box
    fYmin = GetJsonValueDbl(pJSONObject, "ymin");
    if (CPLIsNan(fYmin)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymin' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the xmax of the bounding box
    fXmax = GetJsonValueDbl(pJSONObject, "xmax");
    if (CPLIsNan(fXmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'xmax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the ymax of the bounding box
    fYmax = GetJsonValueDbl(pJSONObject, "ymax");
    if (CPLIsNan(fYmax)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'ymax' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the cell width
    fCellwidth = GetJsonValueDbl(pJSONObject, "cellwidth");
    if (CPLIsNan(fCellwidth)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellwidth' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the cell height
    fCellheight = GetJsonValueDbl(pJSONObject, "cellheight");
    if (CPLIsNan(fCellheight)) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cellheight' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    fXSkew = GetJsonValueDbl(pJSONObject, "xskew");
    if (CPLIsNan(fXSkew)) {
        // not an error -- default to 0.0
        fXSkew = 0.0f;
    }

    fYSkew = GetJsonValueDbl(pJSONObject, "yskew");
    if (CPLIsNan(fYSkew)) {
        // not an error -- default to 0.0
        fYSkew = 0.0f;
    }

    // get the rows
    nRows = GetJsonValueInt(pJSONObject, "rows");
    if (nRows < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'rows' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    // get the columns
    nCols = GetJsonValueInt(pJSONObject, "cols");
    if (nCols < 0) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'cols' is missing or invalid.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    nSrs = GetJsonValueInt(pJSONObject, "epsg");
    if (nSrs < 0) {
        // not an error -- default to web mercator
        nSrs = 3857;
    }

    nErr = oSRS.importFromEPSG(nSrs);
    if (nErr != OGRERR_NONE) {
        nErr = oSRS.importFromEPSG(3857);

        if (nErr == OGRERR_NONE) {
            CPLDebug("ARGDataset", "Open(): "
                "The EPSG provided did not import cleanly. Defaulting to EPSG:3857");
        }
        else {
            CPLError(CE_Failure, CPLE_AppDefined,
                "The 'epsg' value did not transate to a known spatial reference."
                " Please check the 'epsg' value and try again.");

            json_object_put(pJSONObject);
            pJSONObject = NULL;

            return NULL;
        }
    }

    nErr = oSRS.exportToWkt(&pszWKT);
    if (nErr != OGRERR_NONE) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The spatial reference is known, but could not be set on the "
            "dataset. Please check the 'epsg' value and try again.");

        json_object_put(pJSONObject);
        pJSONObject = NULL;

        return NULL;
    }

    // get the layer (always the file basename)
    pszJSONStr = GetJsonValueStr(pJSONObject, "layer");
    if (pszJSONStr == NULL) {
        CPLError(CE_Failure, CPLE_AppDefined,
            "The ARG 'layer' is missing from the JSON file.");
        json_object_put(pJSONObject);
        pJSONObject = NULL;
        return NULL;
    }

    pszLayer = CPLStrdup(pszJSONStr);

    // done with the json object now
    json_object_put(pJSONObject);
    pJSONObject = NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    ARGDataset *poDS;

    poDS = new ARGDataset();

    poDS->pszFilename = CPLStrdup(poOpenInfo->pszFilename);
    poDS->SetMetadataItem("LAYER",pszLayer,NULL);
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;
    poDS->SetProjection( pszWKT );

    // done with the projection string
    CPLFree(pszWKT);
    CPLFree(pszLayer);

/* -------------------------------------------------------------------- */
/*      Assume ownership of the file handled from the GDALOpenInfo.     */
/* -------------------------------------------------------------------- */
    poDS->fpImage = VSIFOpenL(poOpenInfo->pszFilename, "rb");
    if (poDS->fpImage == NULL)
    {
        delete poDS;
        CPLError(CE_Failure, CPLE_AppDefined,
            "Could not open dataset '%s'", poOpenInfo->pszFilename);
        return NULL;
    }

    poDS->adfGeoTransform[0] = fXmin;
    poDS->adfGeoTransform[1] = fCellwidth;
    poDS->adfGeoTransform[2] = fXSkew;
    poDS->adfGeoTransform[3] = fYmax;
    poDS->adfGeoTransform[4] = fYSkew;
    poDS->adfGeoTransform[5] = -fCellheight;
    
/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    RawRasterBand *poBand;

#ifdef CPL_LSB
    int bNative = FALSE;
#else
    int bNative = TRUE;
#endif

    poBand = new RawRasterBand( poDS, 1, poDS->fpImage,
                                0, nPixelOffset, nPixelOffset * nCols,
                                eType, bNative, TRUE );
    poDS->SetBand( 1, poBand );

    poBand->SetNoDataValue( fNoDataValue );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();
    
/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #27
0
CPLErr IDADataset::SetProjection( const char *pszWKTIn )

{
    OGRSpatialReference oSRS;

    oSRS.importFromWkt( (char **) &pszWKTIn );

    if( !oSRS.IsGeographic() && !oSRS.IsProjected() )
        GDALPamDataset::SetProjection( pszWKTIn );

/* -------------------------------------------------------------------- */
/*      Clear projection parameters.                                    */
/* -------------------------------------------------------------------- */
    dfParallel1 = 0.0;
    dfParallel2 = 0.0;
    dfLatCenter = 0.0;
    dfLongCenter = 0.0;

/* -------------------------------------------------------------------- */
/*      Geographic.                                                     */
/* -------------------------------------------------------------------- */
    if( oSRS.IsGeographic() )
    {
        // If no change, just return. 
        if( nProjection == 3 )
            return CE_None;

        nProjection = 3;
    }

/* -------------------------------------------------------------------- */
/*      Verify we don't have a false easting or northing as these       */
/*      will be ignored for the projections we do support.              */
/* -------------------------------------------------------------------- */
    if( oSRS.GetProjParm( SRS_PP_FALSE_EASTING ) != 0.0
        || oSRS.GetProjParm( SRS_PP_FALSE_NORTHING ) != 0.0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to set a projection on an IDA file with a non-zero\n"
                  "false easting and/or northing.  This is not supported." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Lambert Conformal Conic.  Note that we don't support false      */
/*      eastings or nothings.                                           */
/* -------------------------------------------------------------------- */
    const char *pszProjection = oSRS.GetAttrValue( "PROJECTION" );

    if( pszProjection == NULL )
    {
        /* do nothing - presumably geographic  */;
    }
    else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
    {
        nProjection = 4;
        dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
        dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
    {
        nProjection = 6;
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
    {
        nProjection = 8;
        dfParallel1 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
        dfParallel2 = oSRS.GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
        dfLatCenter = oSRS.GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else if( EQUAL(pszProjection,SRS_PT_GOODE_HOMOLOSINE) )
    {
        nProjection = 9;
        dfLongCenter = oSRS.GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    }
    else
    {
        return GDALPamDataset::SetProjection( pszWKTIn );
    }

/* -------------------------------------------------------------------- */
/*      Update header and mark it as dirty.                             */
/* -------------------------------------------------------------------- */
    bHeaderDirty = TRUE;

    abyHeader[23] = (GByte) nProjection;
    c2tp( dfLatCenter, abyHeader + 120 );
    c2tp( dfLongCenter, abyHeader + 126 );
    c2tp( dfParallel1, abyHeader + 156 );
    c2tp( dfParallel2, abyHeader + 162 );

    return CE_None;
}
예제 #28
0
GDALDataset * ARGDataset::CreateCopy( const char * pszFilename,
                                      GDALDataset * poSrcDS,
                                      CPL_UNUSED int bStrict,
                                      CPL_UNUSED char ** papszOptions,
                                      CPL_UNUSED GDALProgressFunc pfnProgress,
                                      CPL_UNUSED void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    int nXBlockSize, nYBlockSize, nPixelOffset = 0;
    GDALDataType eType;
    CPLString osJSONFilename;
    CPLString pszDataType;
    json_object * poJSONObject = NULL;
    double adfTransform[6];
    GDALRasterBand * poSrcBand = NULL;
    RawRasterBand * poDstBand = NULL;
    VSILFILE * fpImage = NULL;
    void * pabyData;
    OGRSpatialReference oSRS;
    char * pszWKT = NULL;
    char ** pszTokens = NULL;
    const char * pszLayer = NULL;
    int nSrs = 0;
    OGRErr nErr = OGRERR_NONE;
    CPLErr eErr;

    if( nBands != 1 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
              "ARG driver doesn't support %d bands.  Must be 1 band.", nBands );
        return NULL;
    }

    eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    if( eType == GDT_Unknown || 
        eType == GDT_CInt16 || 
        eType == GDT_CInt32 ||
        eType == GDT_CFloat32 || 
        eType == GDT_CFloat64 )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "ARG driver doesn't support data type %s.",
                  GDALGetDataTypeName(eType) );
        return NULL;
    }
    else if (eType == GDT_Int16) {
        pszDataType = "int16";
        nPixelOffset = 2;
    }
    else if (eType == GDT_Int32) {
        pszDataType = "int32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Byte) {
        pszDataType = "uint8";
        nPixelOffset = 1;
    }
    else if (eType == GDT_UInt16) {
        pszDataType = "uint16";
        nPixelOffset = 2;
    }
    else if (eType == GDT_UInt32) {
        pszDataType = "uint32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Float32) {
        pszDataType = "float32";
        nPixelOffset = 4;
    }
    else if (eType == GDT_Float64) {
        pszDataType = "float64";
        nPixelOffset = 8;
    }

    poSrcDS->GetGeoTransform( adfTransform );

    pszWKT = (char *)poSrcDS->GetProjectionRef();
    nErr = oSRS.importFromWkt(&pszWKT);
    if (nErr != OGRERR_NONE) {
        CPLError( CE_Failure, CPLE_NotSupported,
              "Cannot import spatial reference WKT from source dataset.");
        return NULL;
    }

    if (oSRS.GetAuthorityCode("PROJCS") != NULL) {
        nSrs = atoi(oSRS.GetAuthorityCode("PROJCS"));
    }
    else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) {
        nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS"));
    }
    else {
        // could not determine projected or geographic code
        // default to EPSG:3857 if no code could be found
        nSrs = 3857;
    }

    /********************************************************************/
    /* Create JSON companion file.                                      */
    /********************************************************************/
    osJSONFilename = GetJsonFilename(pszFilename);

    poJSONObject = json_object_new_object();

    pszTokens = poSrcDS->GetMetadata();
    pszLayer = CSLFetchNameValue(pszTokens, "LAYER");

    if ( pszLayer == NULL) {
        // Set the layer
        json_object_object_add(poJSONObject, "layer", json_object_new_string(
            CPLGetBasename(osJSONFilename)
        ));
    }
    else {
        // Set the layer
        json_object_object_add(poJSONObject, "layer", json_object_new_string(
            pszLayer
        ));
    }

    // Set the type
    json_object_object_add(poJSONObject, "type", json_object_new_string("arg"));
    // Set the datatype
    json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType));
    // Set the number of rows
    json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize));
    // Set the number of columns
    json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize));
    // Set the xmin
    json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0]));
    // Set the ymax
    json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3]));
    // Set the cellwidth
    json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1]));
    // Set the cellheight
    json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5]));
    // Set the xmax
    json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1]));
    // Set the ymin
    json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5]));
    // Set the xskew
    json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2]));
    // Set the yskew
    json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4]));
    if (nSrs > 0) {
        // Set the epsg
        json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs));
    }

    if (json_object_to_file((char *)osJSONFilename.c_str(), poJSONObject) < 0) {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "ARG driver can't write companion file.");

        json_object_put(poJSONObject);
        poJSONObject = NULL;

        return NULL;
    }

    json_object_put(poJSONObject);
    poJSONObject = NULL;

    fpImage = VSIFOpenL(pszFilename, "wb");
    if (fpImage == NULL)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
              "ARG driver can't create data file %s.", pszFilename);

        // remove JSON file
        VSIUnlink( osJSONFilename.c_str() );

        return NULL;
    }

    // only 1 raster band
    poSrcBand = poSrcDS->GetRasterBand( 1 );

#ifdef CPL_LSB
    int bNative = FALSE;
#else
    int bNative = TRUE;
#endif

    poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset,
                                   nPixelOffset * nXSize, eType, bNative,
                                   nXSize, nYSize, TRUE, FALSE);

    poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize);

    pabyData = CPLMalloc(nXBlockSize * nPixelOffset);

    // convert any blocks into scanlines
    for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) {
        for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) {
            if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) {
                continue;
            }

            for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) {
                int nXValid;

                if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() )
                    nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize;
                else
                    nXValid = nXBlockSize;

                eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize, 
                    nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 
                    1, eType, 0, 0, NULL);

                if (eErr != CE_None) {
                    CPLError(CE_Failure, CPLE_AppDefined, "Error reading.");

                    CPLFree( pabyData );
                    delete poDstBand;
                    VSIFCloseL( fpImage );

                    return NULL;
                }

                eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, 
                    nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 
                    1, eType, 0, 0, NULL);

                if (eErr != CE_None) {
                    CPLError(CE_Failure, CPLE_AppDefined, "Error writing.");

                    CPLFree( pabyData );
                    delete poDstBand;
                    VSIFCloseL( fpImage );

                    return NULL;
                }
            }
        }
    }

    CPLFree( pabyData );
    delete poDstBand;
    VSIFCloseL( fpImage );

    return (GDALDataset *)GDALOpen( pszFilename, GA_ReadOnly );
}
예제 #29
0
CPLErr GDALRasterizeLayers(GDALDatasetH hDS,
                           int nBandCount, int *panBandList,
                           int nLayerCount, OGRLayerH *pahLayers,
                           GDALTransformerFunc pfnTransformer,
                           void *pTransformArg,
                           double *padfLayerBurnValues,
                           char **papszOptions,
                           GDALProgressFunc pfnProgress,
                           void *pProgressArg)

{
#ifndef OGR_ENABLED
    CPLError(CE_Failure, CPLE_NotSupported, "GDALRasterizeLayers() unimplemented in a non OGR build");
    return CE_Failure;
#else
    GDALDataType  eType;
    unsigned char *pabyChunkBuf;
    GDALDataset   *poDS = (GDALDataset*) hDS;

    if (pfnProgress == NULL)
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if (nBandCount == 0 || nLayerCount == 0)
        return CE_None;

    // prototype band.
    GDALRasterBand *poBand = poDS->GetRasterBand(panBandList[0]);
    if (poBand == NULL)
        return CE_Failure;

    int              bAllTouched      = CSLFetchBoolean(papszOptions, "ALL_TOUCHED", FALSE);
    const char       *pszOpt          = CSLFetchNameValue(papszOptions, "BURN_VALUE_FROM");
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if (pszOpt)
    {
        if (EQUAL(pszOpt, "Z"))
            eBurnValueSource = GBV_Z;

        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    int        nYChunkSize, nScanlineBytes;
    const char *pszYChunkSize =
        CSLFetchNameValue(papszOptions, "CHUNKYSIZE");

    if (poBand->GetRasterDataType() == GDT_Byte)
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = nBandCount * poDS->GetRasterXSize()
                     * (GDALGetDataTypeSize(eType) / 8);

    if (pszYChunkSize && ((nYChunkSize = atoi(pszYChunkSize))) != 0)
        ;
    else
    {
        GIntBig nYChunkSize64 = GDALGetCacheMax64() / nScanlineBytes;
        if (nYChunkSize64 > INT_MAX)
            nYChunkSize = INT_MAX;
        else
            nYChunkSize = (int)nYChunkSize64;
    }

    if (nYChunkSize < 1)
        nYChunkSize = 1;

    if (nYChunkSize > poDS->GetRasterYSize())
        nYChunkSize = poDS->GetRasterYSize();

    pabyChunkBuf = (unsigned char*) VSIMalloc(nYChunkSize * nScanlineBytes);
    if (pabyChunkBuf == NULL)
    {
        CPLError(CE_Failure, CPLE_OutOfMemory,
                 "Unable to allocate rasterization buffer.");
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Read the image once for all layers if user requested to render  */
/*      the whole raster in single chunk.                               */
/* -------------------------------------------------------------------- */
    if (nYChunkSize == poDS->GetRasterYSize())
    {
        if (poDS->RasterIO(GF_Read, 0, 0, poDS->GetRasterXSize(),
                           nYChunkSize, pabyChunkBuf,
                           poDS->GetRasterXSize(), nYChunkSize,
                           eType, nBandCount, panBandList, 0, 0, 0)
            != CE_None)
        {
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Unable to read buffer.");
            CPLFree(pabyChunkBuf);
            return CE_Failure;
        }
    }

/* ==================================================================== */
/*      Read the specified layers transfoming and rasterizing           */
/*      geometries.                                                     */
/* ==================================================================== */
    CPLErr     eErr = CE_None;
    int        iLayer;
    const char *pszBurnAttribute =
        CSLFetchNameValue(papszOptions, "ATTRIBUTE");

    pfnProgress(0.0, NULL, pProgressArg);

    for (iLayer = 0; iLayer < nLayerCount; iLayer++)
    {
        int      iBurnField      = -1;
        double   *padfBurnValues = NULL;
        OGRLayer *poLayer        = (OGRLayer*) pahLayers[iLayer];

        if (!poLayer)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Layer element number %d is NULL, skipping.\n", iLayer);
            continue;
        }

/* -------------------------------------------------------------------- */
/*      If the layer does not contain any features just skip it.        */
/*      Do not force the feature count, so if driver doesn't know       */
/*      exact number of features, go down the normal way.               */
/* -------------------------------------------------------------------- */
        if (poLayer->GetFeatureCount(FALSE) == 0)
            continue;

        if (pszBurnAttribute)
        {
            iBurnField =
                poLayer->GetLayerDefn()->GetFieldIndex(pszBurnAttribute);
            if (iBurnField == -1)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Failed to find field %s on layer %s, skipping.\n",
                         pszBurnAttribute,
                         poLayer->GetLayerDefn()->GetName());
                continue;
            }
        }
        else
            padfBurnValues = padfLayerBurnValues + iLayer * nBandCount;

/* -------------------------------------------------------------------- */
/*      If we have no transformer, create the one from input file       */
/*      projection. Note that each layer can be georefernced            */
/*      separately.                                                     */
/* -------------------------------------------------------------------- */
        int bNeedToFreeTransformer = FALSE;

        if (pfnTransformer == NULL)
        {
            char *pszProjection = NULL;
            bNeedToFreeTransformer = TRUE;

            OGRSpatialReference *poSRS = poLayer->GetSpatialRef();
            if (!poSRS)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Failed to fetch spatial reference on layer %s "
                         "to build transformer, assuming matching coordinate systems.\n",
                         poLayer->GetLayerDefn()->GetName());
            }
            else
                poSRS->exportToWkt(&pszProjection);

            pTransformArg =
                GDALCreateGenImgProjTransformer(NULL, pszProjection,
                                                hDS, NULL, FALSE, 0.0, 0);
            pfnTransformer = GDALGenImgProjTransform;

            CPLFree(pszProjection);
        }

        OGRFeature *poFeat;

        poLayer->ResetReading();

/* -------------------------------------------------------------------- */
/*      Loop over image in designated chunks.                           */
/* -------------------------------------------------------------------- */
        int iY;

        for (iY = 0;
             iY < poDS->GetRasterYSize() && eErr == CE_None;
             iY += nYChunkSize)
        {
            int nThisYChunkSize;

            nThisYChunkSize = nYChunkSize;
            if (nThisYChunkSize + iY > poDS->GetRasterYSize())
                nThisYChunkSize = poDS->GetRasterYSize() - iY;

            // Only re-read image if not a single chunk is being rendered
            if (nYChunkSize < poDS->GetRasterYSize())
            {
                eErr =
                    poDS->RasterIO(GF_Read, 0, iY,
                                   poDS->GetRasterXSize(), nThisYChunkSize,
                                   pabyChunkBuf,
                                   poDS->GetRasterXSize(), nThisYChunkSize,
                                   eType, nBandCount, panBandList, 0, 0, 0);
                if (eErr != CE_None)
                    break;
            }

            double *padfAttrValues = (double*) VSIMalloc(sizeof(double) * nBandCount);

            while ((poFeat = poLayer->GetNextFeature()) != NULL)
            {
                OGRGeometry *poGeom = poFeat->GetGeometryRef();

                if (pszBurnAttribute)
                {
                    int    iBand;
                    double dfAttrValue;

                    dfAttrValue = poFeat->GetFieldAsDouble(iBurnField);

                    for (iBand = 0; iBand < nBandCount; iBand++)
                        padfAttrValues[iBand] = dfAttrValue;

                    padfBurnValues = padfAttrValues;
                }

                gv_rasterize_one_shape(pabyChunkBuf, iY,
                                       poDS->GetRasterXSize(),
                                       nThisYChunkSize,
                                       nBandCount, eType, bAllTouched, poGeom,
                                       padfBurnValues, eBurnValueSource,
                                       pfnTransformer, pTransformArg);

                delete poFeat;
            }

            VSIFree(padfAttrValues);

            // Only write image if not a single chunk is being rendered
            if (nYChunkSize < poDS->GetRasterYSize())
            {
                eErr =
                    poDS->RasterIO(GF_Write, 0, iY,
                                   poDS->GetRasterXSize(), nThisYChunkSize,
                                   pabyChunkBuf,
                                   poDS->GetRasterXSize(), nThisYChunkSize,
                                   eType, nBandCount, panBandList, 0, 0, 0);
            }

            poLayer->ResetReading();

            if (!pfnProgress((iY + nThisYChunkSize) / ((double)poDS->GetRasterYSize()),
                             "", pProgressArg))
            {
                CPLError(CE_Failure, CPLE_UserInterrupt, "User terminated");
                eErr = CE_Failure;
            }
        }

        if (bNeedToFreeTransformer)
        {
            GDALDestroyTransformer(pTransformArg);
            pTransformArg  = NULL;
            pfnTransformer = NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Write out the image once for all layers if user requested       */
/*      to render the whole raster in single chunk.                     */
/* -------------------------------------------------------------------- */
    if (nYChunkSize == poDS->GetRasterYSize())
    {
        poDS->RasterIO(GF_Write, 0, 0,
                       poDS->GetRasterXSize(), nYChunkSize,
                       pabyChunkBuf,
                       poDS->GetRasterXSize(), nYChunkSize,
                       eType, nBandCount, panBandList, 0, 0, 0);
    }

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFree(pabyChunkBuf);

    return eErr;
#endif /* def OGR_ENABLED */
}
예제 #30
0
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
{
/* -------------------------------------------------------------------- */
/*      Does this look like a CUBE or an IMAGE Primary Data Object?     */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) || poOpenInfo->fpL == nullptr )
        return nullptr;

    VSILFILE *fpQube = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    ISIS2Dataset *poDS = new ISIS2Dataset();

    if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
    {
        VSIFCloseL( fpQube );
        delete poDS;
        return nullptr;
    }

    VSIFCloseL( fpQube );

/* -------------------------------------------------------------------- */
/*      We assume the user is pointing to the label (i.e. .lab) file.   */
/* -------------------------------------------------------------------- */
    // QUBE can be inline or detached and point to an image name
    // ^QUBE = 76
    // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
    // ^QUBE = "ui31s015.img" - which implies no label or skip value

    const char *pszQube = poDS->GetKeyword( "^QUBE" );
    GUIntBig nQube = 0;
    int bByteLocation = FALSE;
    CPLString osTargetFile = poOpenInfo->pszFilename;

    if( pszQube[0] == '"' )
    {
        const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = pszQube;
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr );
        poDS->osExternalCube = osTargetFile;
    }
    else if( pszQube[0] == '(' )
    {
        const CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename);
        CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,"");
        poDS->CleanString( osFilename );
        osTargetFile = CPLFormCIFilename( osTPath, osFilename, nullptr );
        poDS->osExternalCube = osTargetFile;

        nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1"));
        if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != nullptr )
            bByteLocation = true;
    }
    else
    {
        nQube = atoi(pszQube);
        if( strstr(pszQube,"<BYTES>") != nullptr )
            bByteLocation = true;
    }

/* -------------------------------------------------------------------- */
/*      Check if file an ISIS2 header file?  Read a few lines of text   */
/*      searching for something starting with nrows or ncols.           */
/* -------------------------------------------------------------------- */

    /* -------------------------------------------------------------------- */
    /*      Checks to see if this is valid ISIS2 cube                       */
    /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
    /* -------------------------------------------------------------------- */
    const int s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
    const int s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
    const int s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));

    if( s_ix != 0 || s_iy != 0 || s_iz != 0 )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
                  "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
                  "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
        delete poDS;
        return nullptr;
    }

    /**************** end SUFFIX_ITEM check ***********************/

    /***********   Grab layout type (BSQ, BIP, BIL) ************/
    //  AXIS_NAME = (SAMPLE,LINE,BAND)
    /***********************************************************/

    char szLayout[10] = "BSQ"; //default to band seq.
    const char *value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
    if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
        strcpy(szLayout,"BSQ");
    else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
        strcpy(szLayout,"BIP");
    else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
        strcpy(szLayout,"BSQ");
    else {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "%s layout not supported. Abort\n\n", value);
        delete poDS;
        return nullptr;
    }

    /***********   Grab samples lines band ************/
    const int nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
    const int nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
    const int nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));

    /***********   Grab Qube record bytes  **********/
    const int record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));

    GUIntBig nSkipBytes = 0;
    if (nQube > 0 && bByteLocation )
        nSkipBytes = (nQube - 1);
    else if( nQube > 0 )
        nSkipBytes = (nQube - 1) * record_bytes;
    else
        nSkipBytes = 0;

    /***********   Grab samples lines band ************/
    char chByteOrder = 'M';  //default to MSB
    CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
    if( (EQUAL(osCoreItemType,"PC_INTEGER")) ||
        (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) ||
        (EQUAL(osCoreItemType,"PC_REAL")) ) {
        chByteOrder = 'I';
    }

    /********   Grab format type - isis2 only supports 8,16,32 *******/
    GDALDataType eDataType = GDT_Byte;
    bool bNoDataSet = false;
    double dfNoData = 0.0;

    int itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
    switch(itype) {
      case 1 :
        eDataType = GDT_Byte;
        dfNoData = NULL1;
        bNoDataSet = true;
        break;
      case 2 :
        if( strstr(osCoreItemType,"UNSIGNED") != nullptr )
        {
            dfNoData = 0;
            eDataType = GDT_UInt16;
        }
        else
        {
            dfNoData = NULL2;
            eDataType = GDT_Int16;
        }
        bNoDataSet = true;
        break;
      case 4 :
        eDataType = GDT_Float32;
        dfNoData = NULL3;
        bNoDataSet = true;
        break;
      case 8 :
        eDataType = GDT_Float64;
        dfNoData = NULL3;
        bNoDataSet = true;
        break;
      default :
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Itype of %d is not supported in ISIS 2.",
                  itype);
        delete poDS;
        return nullptr;
    }

    /***********   Grab Cellsize ************/
    double dfXDim = 1.0;
    double dfYDim = 1.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
    if (strlen(value) > 0 ) {
        // Convert km to m
        dfXDim = static_cast<float>( CPLAtof(value) * 1000.0 );
        dfYDim = static_cast<float>( CPLAtof(value) * 1000.0 * -1 );
    }

    /***********   Grab LINE_PROJECTION_OFFSET ************/
    double dfULYMap = 0.5;
    double yulcenter = 0.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
    if (strlen(value) > 0) {
        yulcenter = static_cast<float>( CPLAtof(value) );
        yulcenter = ((yulcenter) * dfYDim);
        dfULYMap = yulcenter - (dfYDim/2);
    }

    /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
    double dfULXMap = 0.5;
    double xulcenter = 0.0;

    value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
    if( strlen(value) > 0 ) {
        xulcenter= static_cast<float>( CPLAtof(value) );
        xulcenter = ((xulcenter) * dfXDim);
        dfULXMap = xulcenter - (dfXDim/2);
    }

    /***********  Grab TARGET_NAME  ************/
    /**** This is the planets name i.e. MARS ***/
    CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");

    /***********   Grab MAP_PROJECTION_TYPE ************/
    CPLString map_proj_name =
        poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
    poDS->CleanString( map_proj_name );

    /***********   Grab SEMI-MAJOR ************/
    const double semi_major =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;

    /***********   Grab semi-minor ************/
    const double semi_minor =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;

    /***********   Grab CENTER_LAT ************/
    const double center_lat =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));

    /***********   Grab CENTER_LON ************/
    const double center_lon =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));

    /***********   Grab 1st std parallel ************/
    const double first_std_parallel =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));

    /***********   Grab 2nd std parallel ************/
    const double second_std_parallel =
        CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));

    /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
    // Need to further study how ocentric/ographic will effect the gdal library.
    // So far we will use this fact to define a sphere or ellipse for some projections
    // Frank - may need to talk this over
    bool bIsGeographic = true;
    value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
    if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
        bIsGeographic = false;

    CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );

    OGRSpatialReference oSRS;
    bool bProjectionSet = true;

    //Set oSRS projection and parameters
    if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
        (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
        (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
        oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
    } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
    } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
               (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
        oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "MERCATOR" )) {
        oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
        oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
        oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
    } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
        oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
    } else if (EQUAL( map_proj_name, "") ) {
        /* no projection */
        bProjectionSet = false;
    } else {
        CPLDebug( "ISIS2",
                  "Dataset projection %s is not supported. Continuing...",
                  map_proj_name.c_str() );
        bProjectionSet = false;
    }

    if (bProjectionSet) {
        //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
        const CPLString proj_target_name = map_proj_name + " " + target_name;
        oSRS.SetProjCS(proj_target_name); //set ProjCS keyword

        //The geographic/geocentric name will be the same basic name as the body name
        //'GCS' = Geographic/Geocentric Coordinate System
        const CPLString geog_name = "GCS_" + target_name;

        //The datum and sphere names will be the same basic name aas the planet
        const CPLString datum_name = "D_" + target_name;
        // Might not be IAU defined so don't add.
        CPLString sphere_name = target_name; // + "_IAU_IAG");

        //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
        double iflattening = 0.0;
        if ((semi_major - semi_minor) < 0.0000001)
            iflattening = 0;
        else
            iflattening = semi_major / (semi_major - semi_minor);

        //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
        //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
        if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) ||
             (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))
        {
            if (bIsGeographic) {
                //Geograpraphic, so set an ellipse
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere using the semi-minor axis. I hope...
                sphere_name += "_polarRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_minor, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }
        else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
                  (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
            // ISIS uses the spherical equation for these projections so force
            // a sphere.
            oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                            semi_major, 0.0,
                            "Reference_Meridian", 0.0 );
        }
        else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
                  (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
            //Calculate localRadius using ISIS3 simple elliptical method
            //  not the more standard Radius of Curvature method
            //PI = 4 * atan(1);
            if (center_lon == 0) { //No need to calculate local radius
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            } else {
                const double radLat = center_lat * M_PI / 180;  // in radians
                const double localRadius
                    = semi_major * semi_minor
                    / sqrt(pow(semi_minor*cos(radLat),2)
                           + pow(semi_major*sin(radLat),2) );
                sphere_name += "_localRadius";
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                localRadius, 0.0,
                                "Reference_Meridian", 0.0 );
                CPLDebug( "ISIS2", "local radius: %f", localRadius);
            }
        }
        else {
            //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
            //Geographic, so set an ellipse
            if (bIsGeographic) {
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, iflattening,
                                "Reference_Meridian", 0.0 );
            } else {
                //Geocentric, so force a sphere. I hope...
                oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
                                semi_major, 0.0,
                                "Reference_Meridian", 0.0 );
            }
        }

        // translate back into a projection string.
        char *pszResult = nullptr;
        oSRS.exportToWkt( &pszResult );
        poDS->osProjection = pszResult;
        CPLFree( pszResult );
    }

/* END ISIS2 Label Read */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/* -------------------------------------------------------------------- */
/*      Did we get the required keywords?  If not we return with        */
/*      this never having been considered to be a match. This isn't     */
/*      an error!                                                       */
/* -------------------------------------------------------------------- */
    if( !GDALCheckDatasetDimensions(nCols, nRows) ||
        !GDALCheckBandCount(nBands, false) )
    {
        delete poDS;
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

/* -------------------------------------------------------------------- */
/*      Open target binary file.                                        */
/* -------------------------------------------------------------------- */

    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fpImage = VSIFOpenL( osTargetFile, "rb" );
    else
        poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" );

    if( poDS->fpImage == nullptr )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open %s with write permission.\n%s",
                  osTargetFile.c_str(), VSIStrerror( errno ) );
        delete poDS;
        return nullptr;
    }

    poDS->eAccess = poOpenInfo->eAccess;

/* -------------------------------------------------------------------- */
/*      Compute the line offset.                                        */
/* -------------------------------------------------------------------- */
    int nItemSize = GDALGetDataTypeSizeBytes(eDataType);
    int nLineOffset, nPixelOffset;
    vsi_l_offset nBandOffset;

    if( EQUAL(szLayout,"BIP") )
    {
        nPixelOffset = nItemSize * nBands;
        if( nPixelOffset > INT_MAX / nBands )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = nItemSize;
    }
    else if( EQUAL(szLayout,"BSQ") )
    {
        nPixelOffset = nItemSize;
        if( nPixelOffset > INT_MAX / nCols )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nPixelOffset * nCols;
        nBandOffset = static_cast<vsi_l_offset>(nLineOffset) * nRows;
    }
    else /* assume BIL */
    {
        nPixelOffset = nItemSize;
        if( nPixelOffset > INT_MAX / nBands ||
            nPixelOffset * nBands > INT_MAX / nCols )
        {
            delete poDS;
            return nullptr;
        }
        nLineOffset = nItemSize * nBands * nCols;
        nBandOffset = static_cast<vsi_l_offset>(nItemSize) * nCols;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = nBands;
    for( int i = 0; i < poDS->nBands; i++ )
    {
        RawRasterBand *poBand =
            new RawRasterBand( poDS, i+1, poDS->fpImage,
                               nSkipBytes + nBandOffset * i,
                               nPixelOffset, nLineOffset, eDataType,
#ifdef CPL_LSB
                               chByteOrder == 'I' || chByteOrder == 'L',
#else
                               chByteOrder == 'M',
#endif
                               TRUE );

        if( bNoDataSet )
            poBand->SetNoDataValue( dfNoData );

        poDS->SetBand( i+1, poBand );

        // Set offset/scale values at the PAM level.
        poBand->SetOffset(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
        poBand->SetScale(
            CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
    }

/* -------------------------------------------------------------------- */
/*      Check for a .prj file. For isis2 I would like to keep this in   */
/* -------------------------------------------------------------------- */
    const CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
    const CPLString osName = CPLGetBasename(poOpenInfo->pszFilename);
    const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );

    VSILFILE *fp = VSIFOpenL( pszPrjFile, "r" );
    if( fp != nullptr )
    {
        VSIFCloseL( fp );

        char **papszLines = CSLLoad( pszPrjFile );

        OGRSpatialReference oSRS2;
        if( oSRS2.importFromESRI( papszLines ) == OGRERR_NONE )
        {
            char *pszResult = nullptr;
            oSRS2.exportToWkt( &pszResult );
            poDS->osProjection = pszResult;
            CPLFree( pszResult );
        }

        CSLDestroy( papszLines );
    }

    if( dfULXMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
    {
        poDS->bGotTransform = TRUE;
        poDS->adfGeoTransform[0] = dfULXMap;
        poDS->adfGeoTransform[1] = dfXDim;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = dfULYMap;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = dfYDim;
    }

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "cbw",
                               poDS->adfGeoTransform );

    if( !poDS->bGotTransform )
        poDS->bGotTransform =
            GDALReadWorldFile( poOpenInfo->pszFilename, "wld",
                               poDS->adfGeoTransform );

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

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}