int FindEPSG( const OGRSpatialReference &oSRS )
{
    char *pszWKT = NULL;
    char *pszESRI = NULL;
    int nFound = -1;
    OGRSpatialReference *poSRS = NULL;
 
    poSRS = oSRS.Clone();
    poSRS->StripCTParms();
    poSRS->exportToWkt( &pszWKT );
    OGRSpatialReference::DestroySpatialReference( poSRS );

    poSRS = oSRS.Clone();
    poSRS->morphToESRI( );
    poSRS->exportToWkt( &pszESRI );
    OGRSpatialReference::DestroySpatialReference( poSRS );

    CPLDebug( "gdalsrsinfo", "FindEPSG()\nWKT (OGC)= %s\nWKT (ESRI)=%s",
              pszWKT,pszESRI );

    /* search for EPSG code in epsg_*.wkt.gz files */
    /* using ESRI WKT for now, as it seems to work best */
    nFound = SearchCSVForWKT( "epsg_esri.wkt.gz", pszESRI );
    if ( nFound == -1 )
        nFound = SearchCSVForWKT( "epsg_ogc_simple.wkt.gz", pszESRI );
    if ( nFound == -1 )
        nFound = SearchCSVForWKT( "epsg_ogc.wkt.gz", pszESRI );

    
    CPLFree( pszWKT );
    CPLFree( pszESRI );    
    
    return nFound;
}
Example #2
0
OGRLayer *
OGRMemDataSource::ICreateLayer( const char *pszLayerName,
                                OGRSpatialReference *poSRSIn,
                                OGRwkbGeometryType eType,
                                char **papszOptions )
{
    // Create the layer object.
    OGRSpatialReference* poSRS = poSRSIn;
    if( poSRS )
    {
        poSRS = poSRS->Clone();
        poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
    }
    OGRMemLayer *poLayer = new OGRMemLayer(pszLayerName, poSRS, eType);
    if( poSRS )
    {
        poSRS->Release();
    }

    if( CPLFetchBool(papszOptions, "ADVERTIZE_UTF8", false) )
        poLayer->SetAdvertizeUTF8(true);

    // Add layer to data source layer list.
    papoLayers = static_cast<OGRMemLayer **>(
        CPLRealloc(papoLayers, sizeof(OGRMemLayer *) * (nLayers + 1)));

    papoLayers[nLayers++] = poLayer;

    return poLayer;
}
OGRLayer   *OGRAmigoCloudDataSource::ICreateLayer( const char *pszNameIn,
                                           OGRSpatialReference *poSpatialRef,
                                           OGRwkbGeometryType eGType,
                                           char ** papszOptions )
{
    if( !bReadWrite )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode");
        return nullptr;
    }

    CPLString osName(pszNameIn);
    OGRAmigoCloudTableLayer* poLayer = new OGRAmigoCloudTableLayer(this, osName);
    const bool bGeomNullable =
        CPLFetchBool(papszOptions, "GEOMETRY_NULLABLE", true);
    OGRSpatialReference* poSRSClone = poSpatialRef;
    if( poSRSClone )
    {
        poSRSClone = poSRSClone->Clone();
        poSRSClone->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
    }
    poLayer->SetDeferredCreation(eGType, poSRSClone, bGeomNullable);
    if( poSRSClone )
        poSRSClone->Release();
    papoLayers = (OGRAmigoCloudTableLayer**) CPLRealloc(
                    papoLayers, (nLayers + 1) * sizeof(OGRAmigoCloudTableLayer*));
    papoLayers[nLayers ++] = poLayer;

    return poLayer;
}
	void CProjection::SetSpatialReference(const OGRSpatialReference& sr)
	{
		if (m_pSpatialReference)
		{
			OSRDestroySpatialReference(m_pSpatialReference);
			m_pSpatialReference = NULL;
		}

		m_pSpatialReference = sr.Clone();

	};
Example #5
0
void SaveGeometry(const CPLString &path, const OGRPolygon &polygon, const OGRSpatialReference &spaRef)
{
    const char *pszDriverName = "ESRI Shapefile";
    GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName );
    if( poDriver == NULL )
    {
        printf( "%s driver not available.\n", pszDriverName );
        exit( 1 );
    }

    GDALDataset *poDS = poDriver->Create( path, 0, 0, 0, GDT_Unknown, NULL );
    if( poDS == NULL )
    {
        printf( "Creation of output file failed.\n" );
        exit( 1 );
    }

    const char* pszLayerName = CPLGetBasename(path);

    OGRLayer *poLayer = poDS->CreateLayer( pszLayerName, spaRef.Clone(), wkbPolygon, NULL );
    if( poLayer == NULL )
    {
        printf( "Layer creation failed.\n" );
        exit( 1 );
    }

    OGRFieldDefn oField( "Name", OFTString );
    oField.SetWidth(32);
    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
        printf( "Creating Name field failed.\n" );
        exit( 1 );
    }

    OGRFeature *poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
    //poFeature->SetField( "Name", szName );

    poFeature->SetGeometry( polygon.clone() );
    if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
    {
        printf( "Failed to create feature in shapefile.\n" );
        exit( 1 );
    }
    OGRFeature::DestroyFeature( poFeature );
    GDALClose( poDS );
}
Example #6
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.           */
/* -------------------------------------------------------------------- */
    OGRDataSource *poDstDS;
    OGRLayer *poDstLayer = NULL;

    poDstDS = OGRSFDriverRegistrar::Open( pszOutputName, TRUE );

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

        for( iDriver = 0;
             iDriver < poR->GetDriverCount() && poDriver == NULL;
             iDriver++ )
        {
            if( EQUAL(poR->GetDriver(iDriver)->GetName(),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)->GetName() );
            }
            exit( 1 );
        }

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

/* -------------------------------------------------------------------- */
/*      Now create it.                                                  */
/* -------------------------------------------------------------------- */
        
        poDstDS = poDriver->CreateDataSource( pszOutputName, 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)
            {
                OGRDataSource* poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], 
                                           FALSE );
                                           
                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;
                    }
                }
                
                OGRDataSource::DestroyDataSource( 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)
            {
                OGRDataSource       *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 = OGRSFDriverRegistrar::Open(filename, 
                                                    FALSE );
                    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();
                        }
                        OGRDataSource::DestroyDataSource( 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;
        OGRDataSource       *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 = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], 
                                           FALSE );

        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." );
                OGRDataSource::DestroyDataSource( poDstDS );
                exit( 1 );
            }
        }

/* -------------------------------------------------------------------- */
/*      Cleanup this data source.                                       */
/* -------------------------------------------------------------------- */
        CPLFree(fileNameToWrite);
        OGRDataSource::DestroyDataSource( poDS );
    }

/* -------------------------------------------------------------------- */
/*      Close tile index and clear buffers.                             */
/* -------------------------------------------------------------------- */
    OGRDataSource::DestroyDataSource( 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);
    }

    return 0;
}
Example #7
0
int main( int nArgc, char ** papszArgv )

{
    OGRSpatialReference oSRS;
    int i;
    int bReportXML = FALSE;

    /* -------------------------------------------------------------------- */
    /*      Processing command line arguments.                              */
    /* -------------------------------------------------------------------- */
    nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );

    if( nArgc < 2 )
        Usage();

    for( i = 1; i < nArgc; i++ )
    {
        if( EQUAL(papszArgv[i],"-xml") )
            bReportXML = TRUE;

        else if( EQUAL(papszArgv[i],"-t") && i < nArgc - 4 )
        {
            OGRSpatialReference oSourceSRS, oTargetSRS;
            OGRCoordinateTransformation *poCT;
            double                      x, y, z_orig, z;
            int                         nArgsUsed = 4;

            if( oSourceSRS.SetFromUserInput(papszArgv[i+1]) != OGRERR_NONE )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "SetFromUserInput(%s) failed.",
                          papszArgv[i+1] );
                continue;
            }
            if( oTargetSRS.SetFromUserInput(papszArgv[i+2]) != OGRERR_NONE )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "SetFromUserInput(%s) failed.",
                          papszArgv[i+2] );
                continue;
            }

            poCT = OGRCreateCoordinateTransformation( &oSourceSRS,
                    &oTargetSRS );
            x = CPLAtof( papszArgv[i+3] );
            y = CPLAtof( papszArgv[i+4] );
            if( i < nArgc - 5
                    && (CPLAtof(papszArgv[i+5]) > 0.0 || papszArgv[i+5][0] == '0') )
            {
                z_orig = z = CPLAtof(papszArgv[i+5]);
                nArgsUsed++;
            }
            else
                z_orig = z = 0;

            if( poCT == NULL || !poCT->Transform( 1, &x, &y, &z ) )
                printf( "Transformation failed.\n" );
            else
                printf( "(%f,%f,%f) -> (%f,%f,%f)\n",
                        CPLAtof( papszArgv[i+3] ),
                        CPLAtof( papszArgv[i+4] ),
                        z_orig,
                        x, y, z );

            i += nArgsUsed;
        }
        else
        {
            /* coverity[tainted_data] */
            if( oSRS.SetFromUserInput(papszArgv[i]) != OGRERR_NONE )
                CPLError( CE_Failure, CPLE_AppDefined,
                          "Error occurred translating %s.\n",
                          papszArgv[i] );
            else
            {
                char  *pszWKT = NULL;

                if( oSRS.Validate() != OGRERR_NONE )
                    printf( "Validate Fails.\n" );
                else
                    printf( "Validate Succeeds.\n" );

                oSRS.exportToPrettyWkt( &pszWKT, FALSE );
                printf( "WKT[%s] =\n%s\n",
                        papszArgv[i], pszWKT );
                CPLFree( pszWKT );

                printf( "\n" );

                oSRS.exportToPrettyWkt( &pszWKT, TRUE );
                printf( "Simplified WKT[%s] =\n%s\n",
                        papszArgv[i], pszWKT );
                CPLFree( pszWKT );

                printf( "\n" );

                OGRSpatialReference *poSRS2;

                poSRS2 = oSRS.Clone();
                poSRS2->StripCTParms();
                poSRS2->exportToWkt( &pszWKT );
                printf( "Old Style WKT[%s] = %s\n",
                        papszArgv[i], pszWKT );
                CPLFree( pszWKT );
                OGRSpatialReference::DestroySpatialReference( poSRS2 );

                poSRS2 = oSRS.Clone();
                poSRS2->morphToESRI();
                poSRS2->exportToPrettyWkt( &pszWKT, FALSE );
                printf( "ESRI'ified WKT[%s] = \n%s\n",
                        papszArgv[i], pszWKT );
                CPLFree( pszWKT );
                OGRSpatialReference::DestroySpatialReference( poSRS2 );

                oSRS.exportToProj4( &pszWKT );
                printf( "PROJ.4 rendering of [%s] = %s\n",
                        papszArgv[i], pszWKT );
                CPLFree( pszWKT );


                if( bReportXML )
                {
                    char       *pszRawXML;
                    if( oSRS.exportToXML(&pszRawXML) == OGRERR_NONE )
                    {
                        printf( "XML[%s] =\n%s\n",
                                papszArgv[i], pszRawXML );
                        CPLFree( pszRawXML );
                    }
                    else
                    {
                        printf( "XML translation failed\n" );
                    }
                }

                printf( "\n" );
            }
        }
    }

    CSLDestroy( papszArgv );
    OSRCleanup();
    CPLFinderClean();
    CPLCleanupTLS();

    return 0;
}
Example #8
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;
}
Example #9
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;
}
CPLErr PrintSRS( const OGRSpatialReference &oSRS, 
                 const char * pszOutputType, 
                 int bPretty, int bPrintSep )

{
    if ( ! pszOutputType || EQUAL(pszOutputType,""))
        return CE_None;

    CPLDebug( "gdalsrsinfo", "PrintSRS( oSRS, %s, %d, %d )\n",
              pszOutputType, bPretty, bPrintSep );
    
    char *pszOutput = NULL;

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

    else if ( EQUAL("wkt", pszOutputType ) ) {
        if ( bPrintSep ) printf("OGC WKT :\n");
        if ( bPretty ) 
            oSRS.exportToPrettyWkt( &pszOutput, FALSE );
        else
            oSRS.exportToWkt( &pszOutput );
        printf("%s\n",pszOutput);
    }
        
    else if (  EQUAL("wkt_simple", pszOutputType ) ) {
        if ( bPrintSep ) printf("OGC WKT (simple) :\n");
        oSRS.exportToPrettyWkt( &pszOutput, TRUE );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("wkt_noct", pszOutputType ) ) {
        if (  bPrintSep ) printf("OGC WKT (no CT) :\n");
        OGRSpatialReference *poSRS = oSRS.Clone();
        poSRS->StripCTParms( );
        if ( bPretty ) 
            poSRS->exportToPrettyWkt( &pszOutput, FALSE );
        else
            poSRS->exportToWkt( &pszOutput );
        OGRSpatialReference::DestroySpatialReference( poSRS );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("wkt_esri", pszOutputType ) ) {
        if ( bPrintSep ) printf("ESRI WKT :\n");
        OGRSpatialReference *poSRS = oSRS.Clone();
        poSRS->morphToESRI( );
        if ( bPretty ) 
            poSRS->exportToPrettyWkt( &pszOutput, FALSE );
        else
            poSRS->exportToWkt( &pszOutput );
        OGRSpatialReference::DestroySpatialReference( poSRS );
        printf("%s\n",pszOutput);
    }
        
    else if ( EQUAL("mapinfo", pszOutputType ) ) {
        if ( bPrintSep ) printf("MAPINFO : ");
        oSRS.exportToMICoordSys( &pszOutput );
        printf("\'%s\'\n",pszOutput);
    }
        
    else if ( EQUAL("xml", pszOutputType ) ) {
        if ( bPrintSep ) printf("XML :\n");
        oSRS.exportToXML( &pszOutput, NULL );
        printf("%s\n",pszOutput);
    }

    else {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "ERROR - %s output not supported",
                  pszOutputType );
        return CE_Failure;
    }

    CPLFree( pszOutput );
    
    return CE_None;
}
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS, int bDebug )

{
    int            bGotSRS = FALSE;
    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL; 
    OGRDataSource *poOGRDS = NULL;
    OGRLayer      *poLayer = NULL;
    char           *pszProjection = NULL;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;
    OGRErr eErr = CE_None;
      
    /* temporarily supress error messages we may get from xOpen() */
    if ( ! bDebug )
        oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );

    /* Test if argument is a file */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {
        bIsFile = TRUE;
        VSIFCloseL( fp );
        CPLDebug( "gdalsrsinfo", "argument is a file" );
    } 
       
    /* 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" );
    }    
    
#ifdef OGR_ENABLED
    /* 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" );
    }
#endif // OGR_ENABLED
    
    /* Try ESRI file */
    if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from ESRI .prj file [%s]", pszInput );

        char **pszTemp;
        if ( strstr(pszInput,"ESRI::") != NULL )
            pszTemp = CSLLoad( pszInput+6 );
        else 
            pszTemp = CSLLoad( pszInput );

        if( pszTemp ) {
            eErr = oSRS.importFromESRI( pszTemp );
            CSLDestroy( pszTemp );
        }
        else 
            eErr = OGRERR_UNSUPPORTED_SRS;

        if( eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
            bGotSRS = TRUE;
        }
    }

    /* Last resort, try OSRSetFromUserInput() */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from user input [%s]", pszInput );

        eErr = oSRS.SetFromUserInput( pszInput );
 
       if(  eErr != 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 );	


    return bGotSRS;
}
Example #12
0
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS )

{
    int            bGotSRS = FALSE;
    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL; 
    OGRLayer      *poLayer = NULL;
    const char    *pszProjection = NULL;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;
    OGRErr eErr = OGRERR_NONE;
    int bDebug  = FALSE;

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

    /* Test if argument is a file */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {
        bIsFile = TRUE;
        VSIFCloseL( fp );
        CPLDebug( "gdalsrsinfo", "argument is a file" );
    } 
       
    /* try to open with GDAL */
    if( strncmp(pszInput, "http://spatialreference.org/",
                strlen("http://spatialreference.org/")) != 0 )
    {
        CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
        poGDALDS = (GDALDataset *) GDALOpenEx( pszInput, 0, NULL, NULL, NULL );
    }
    if ( poGDALDS != NULL ) {
        pszProjection = poGDALDS->GetProjectionRef( );
        if( pszProjection != NULL && pszProjection[0] != '\0' )
        {
            char* pszProjectionTmp = (char*) pszProjection;
            if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) {
                CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
                bGotSRS = TRUE;
            }
        }
        else if( poGDALDS->GetLayerCount() > 0 )
        {
            poLayer = poGDALDS->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 );
                }
            }
        }
        GDALClose( (GDALDatasetH) poGDALDS );
        if ( ! bGotSRS ) 
            CPLDebug( "gdalsrsinfo", "did not open with GDAL" );
    }    
    
    /* Try ESRI file */
    if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from ESRI .prj file [%s]", pszInput );

        char **pszTemp;
        if ( strstr(pszInput,"ESRI::") != NULL )
            pszTemp = CSLLoad( pszInput+6 );
        else 
            pszTemp = CSLLoad( pszInput );

        if( pszTemp ) {
            eErr = oSRS.importFromESRI( pszTemp );
            CSLDestroy( pszTemp );
        }
        else 
            eErr = OGRERR_UNSUPPORTED_SRS;

        if( eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
            bGotSRS = TRUE;
        }
    }

    /* Last resort, try OSRSetFromUserInput() */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from user input [%s]", pszInput );

        eErr = oSRS.SetFromUserInput( pszInput );
 
       if(  eErr != 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 );	


    return bGotSRS;
}
Example #13
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;

}
Example #14
0
OGRSpatialReference *
WCTSImportCoordinateReferenceSystem( CPLXMLNode *psXMLCRS )

{
    CPLStripXMLNamespace( psXMLCRS->psChild, NULL, TRUE );

/* ==================================================================== */
/*      Try to find a direct crsID as per old specification.            */
/* ==================================================================== */
    const char *pszCode = CPLGetXMLValue( psXMLCRS, "crsID.code", NULL );
    const char *pszCodeSpace = CPLGetXMLValue( psXMLCRS, "crsID.codeSpace", 
                                               NULL );

    if( pszCode != NULL && pszCodeSpace != NULL )
    {
/* -------------------------------------------------------------------- */
/*      Get the EPSG code, and verify that it is in the EPSG            */
/*      codeSpace.                                                      */
/* -------------------------------------------------------------------- */
        OGRSpatialReference oSRS;

        if( EQUAL(pszCodeSpace,"EPSG") )
        {
            int nEPSGCode = atoi(pszCode);
            
            if( nEPSGCode == 0 )
            {
                WCTSEmitServiceException( "Failed to decode CoordinateReferenceSystem with missing,\n"
                                          "or zero crsID.code" );
            }								

            CPLErrorReset();
            if( oSRS.importFromEPSG( nEPSGCode ) != OGRERR_NONE )
            {
                if( strlen(CPLGetLastErrorMsg()) > 0 )
                    WCTSEmitServiceException( CPLGetLastErrorMsg() );
                else
                    WCTSEmitServiceException( 
                        CPLSPrintf( "OGRSpatialReference::importFromEPSG(%d) "
                                    "failed.  Is this a defined EPSG code?", 
                                    nEPSGCode ) );
            }
        }

/* -------------------------------------------------------------------- */
/*      Handle AUTO case.                                               */
/* -------------------------------------------------------------------- */
        else if( EQUAL(pszCodeSpace,"AUTO") )
        {
            if( oSRS.importFromWMSAUTO( pszCode ) != OGRERR_NONE )
            {
                if( strlen(CPLGetLastErrorMsg()) > 0 )
                    WCTSEmitServiceException( CPLGetLastErrorMsg() );
                else
                    WCTSEmitServiceException( 
                        CPLSPrintf( "OGRSpatialReference::importFromWMSAUTO(%s) "
                                    "failed.  Is this a defined EPSG code?", 
                                    pszCode  ) );
            }
        }

/* -------------------------------------------------------------------- */
/*      Otherwise blow a gasket.                                        */
/* -------------------------------------------------------------------- */
        else
        {
            WCTSEmitServiceException( "Failed to decode CoordinateReferenceSystem with missing,\n"
                                      "or non-EPSG crsID.codeSpace" );
        }	
        
/* -------------------------------------------------------------------- */
/*      Translate into an OGRSpatialReference from EPSG code.           */
/* -------------------------------------------------------------------- */

        return oSRS.Clone();
    }

/* ==================================================================== */
/*      Try to import a projectedCRS or geographicCRS.                  */
/* ==================================================================== */
    if( CPLGetXMLNode( psXMLCRS, "ProjectedCRS" ) != NULL 
        || CPLGetXMLNode( psXMLCRS, "GeographicCRS" ) != NULL )
    {
#ifdef DISABLE_USER_DEFINED_CRS
        WCTSEmitServiceException( 
            "User defined ProjectedCRS and GeographicCRS support\n"
            "disabled for security reasons." );
#else
        char *pszSerializedForm;
        OGRSpatialReference oSRS;

        pszSerializedForm = CPLSerializeXMLTree( psXMLCRS->psChild );
        if( oSRS.importFromXML( pszSerializedForm ) != OGRERR_NONE )
        {
            CPLFree( pszSerializedForm );
            if( strlen(CPLGetLastErrorMsg()) > 0 )
                WCTSEmitServiceException( CPLGetLastErrorMsg() );
            else
                WCTSEmitServiceException( "Failed to import CRS" );
        }

        CPLFree( pszSerializedForm );
        return oSRS.Clone();
#endif
    }
    
/* -------------------------------------------------------------------- */
/*      We don't seem to recognise a CRS here.                          */
/* -------------------------------------------------------------------- */
    WCTSEmitServiceException( "Unable to identify CRS in one of SourceCRS or TargetCRS elements" );

    return NULL;
}
int OGRFMELayerCached::InitializeFromXML( CPLXMLNode *psLayer )

{
/* -------------------------------------------------------------------- */
/*      Create the feature definition.                                  */
/* -------------------------------------------------------------------- */
    poFeatureDefn = new OGRFeatureDefn( CPLGetXMLValue(psLayer,"Name","X") );
    poFeatureDefn->Reference();
    
/* -------------------------------------------------------------------- */
/*      Set the geometry type, if available.                            */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psLayer, "GeomType" ) != NULL )
        poFeatureDefn->SetGeomType( (OGRwkbGeometryType) 
                     atoi(CPLGetXMLValue( psLayer, "GeomType", "0" )) );

/* -------------------------------------------------------------------- */
/*      If we can extract extents, apply them to the layer.             */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psLayer, "Extent" ) != NULL )
    {
        if( sscanf( CPLGetXMLValue( psLayer, "Extent", "" ), 
                    "%lf,%lf,%lf,%lf", 
                    &sExtents.MinX, 
                    &sExtents.MaxX, 
                    &sExtents.MinY, 
                    &sExtents.MaxY ) != 4 )
        {
            memset( &sExtents, 0, sizeof(sExtents) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Apply a SRS if found in the XML.                                */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psLayer, "SRS" ) != NULL )
    {
        char *pszSRS = (char *) CPLGetXMLValue( psLayer, "SRS", "" );
        OGRSpatialReference oSRS;

        if( oSRS.importFromWkt( &pszSRS ) == OGRERR_NONE )
        {
            if( poSpatialRef != NULL )
                delete poSpatialRef;

            poSpatialRef = oSRS.Clone();
        }
    }

/* -------------------------------------------------------------------- */
/*      Apply the Schema.                                               */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psFieldDef;

    for( psFieldDef = CPLGetXMLNode( psLayer, "Schema.OGRFieldDefn" );
         psFieldDef != NULL; psFieldDef = psFieldDef->psNext )
    {
        const char *pszType;
        OGRFieldType eType;

        if( !EQUAL(psFieldDef->pszValue,"OGRFieldDefn") )
            continue;

        pszType = CPLGetXMLValue( psFieldDef, "type", "String" );
        if( EQUAL(pszType,"String") )
            eType = OFTString;
        else if( EQUAL(pszType,"StringList") )
            eType = OFTStringList;
        else if( EQUAL(pszType,"Integer") )
            eType = OFTInteger;
        else if( EQUAL(pszType,"IntegerList") )
            eType = OFTIntegerList;
        else if( EQUAL(pszType,"Real") )
            eType = OFTReal;
        else if( EQUAL(pszType,"RealList") )
            eType = OFTRealList;
        else if( EQUAL(pszType,"Binary") )
            eType = OFTBinary;
        else
            eType = OFTString;

        OGRFieldDefn oField( CPLGetXMLValue( psFieldDef, "name", "default" ),
                             eType );

        oField.SetWidth( atoi(CPLGetXMLValue(psFieldDef,"width","0")) );
        oField.SetPrecision( atoi(CPLGetXMLValue(psFieldDef,"precision","0")));

        poFeatureDefn->AddFieldDefn( &oField );
    }

/* -------------------------------------------------------------------- */
/*      Ensure we have a working string and feature object              */
/* -------------------------------------------------------------------- */
    poFMEFeature = poDS->GetFMESession()->createFeature();

    return TRUE;
}