?? ogr_srs_xml.cpp
字號:
/************************************************************************/
/* getNormalizedValue() */
/* */
/* Parse a node to get it's numerical value, and then normalize */
/* into meters of degrees depending on the measure type. */
/************************************************************************/
static double getNormalizedValue( CPLXMLNode *psNode, const char *pszPath,
const char * /*pszMeasure*/,
double dfDefault )
{
CPLXMLNode *psTargetNode;
CPLXMLNode *psValueNode;
if( pszPath == NULL || strlen(pszPath) == 0 )
psTargetNode = psNode;
else
psTargetNode = CPLGetXMLNode( psNode, pszPath );
if( psTargetNode == NULL )
return dfDefault;
for( psValueNode = psTargetNode->psChild;
psValueNode != NULL && psValueNode->eType != CXT_Text;
psValueNode = psValueNode->psNext ) {}
if( psValueNode == NULL )
return dfDefault;
// Add normalization later.
return atof(psValueNode->pszValue);
}
/************************************************************************/
/* importGeogCSFromXML() */
/************************************************************************/
static OGRErr importGeogCSFromXML( OGRSpatialReference *poSRS,
CPLXMLNode *psCRS )
{
const char *pszGeogName, *pszDatumName, *pszEllipsoidName, *pszPMName;
double dfSemiMajor, dfInvFlattening, dfPMOffset = 0.0;
/* -------------------------------------------------------------------- */
/* Set the GEOGCS name from the srsName. */
/* -------------------------------------------------------------------- */
pszGeogName =
CPLGetXMLValue( psCRS, "srsName", "Unnamed GeogCS" );
/* -------------------------------------------------------------------- */
/* If we don't seem to have a detailed coordinate system */
/* definition, check if we can define based on an EPSG code. */
/* -------------------------------------------------------------------- */
CPLXMLNode *psDatum;
psDatum = CPLGetXMLNode( psCRS, "usesGeodeticDatum.GeodeticDatum" );
if( psDatum == NULL )
{
OGRSpatialReference oIdSRS;
oIdSRS.SetLocalCS( "dummy" );
importXMLAuthority( psCRS, &oIdSRS, "srsID", "LOCAL_CS" );
if( oIdSRS.GetAuthorityCode( "LOCAL_CS" ) != NULL
&& oIdSRS.GetAuthorityName( "LOCAL_CS" ) != NULL
&& EQUAL(oIdSRS.GetAuthorityName("LOCAL_CS"),"EPSG") )
{
return poSRS->importFromEPSG(
atoi(oIdSRS.GetAuthorityCode("LOCAL_CS")) );
}
}
/* -------------------------------------------------------------------- */
/* Get datum name. */
/* -------------------------------------------------------------------- */
pszDatumName =
CPLGetXMLValue( psDatum, "datumName", "Unnamed Datum" );
/* -------------------------------------------------------------------- */
/* Get ellipsoid information. */
/* -------------------------------------------------------------------- */
CPLXMLNode *psE;
psE = CPLGetXMLNode( psDatum, "usesEllipsoid.Ellipsoid" );
pszEllipsoidName =
CPLGetXMLValue( psE, "ellipsoidName", "Unnamed Ellipsoid" );
dfSemiMajor = getNormalizedValue( psE, "semiMajorAxis", "Linear",
SRS_WGS84_SEMIMAJOR );
dfInvFlattening =
getNormalizedValue( psE, "secondDefiningParameter.inverseFlattening",
"Unitless", 0.0 );
if( dfInvFlattening == 0.0 )
{
CPLError( CE_Failure, CPLE_AppDefined,
"Ellipsoid inverseFlattening corrupt or missing." );
return OGRERR_CORRUPT_DATA;
}
/* -------------------------------------------------------------------- */
/* Get the prime meridian. */
/* -------------------------------------------------------------------- */
CPLXMLNode *psPM;
psPM = CPLGetXMLNode( psDatum, "usesPrimeMeridian.PrimeMeridian" );
if( psPM == NULL )
{
pszPMName = "Greenwich";
dfPMOffset = 0.0;
}
else
{
pszPMName = CPLGetXMLValue( psPM, "meridianName",
"Unnamed Prime Meridian");
dfPMOffset =
getNormalizedValue( psPM, "greenwichLongitude.angle",
"Angular", 0.0 );
}
/* -------------------------------------------------------------------- */
/* Set the geographic definition. */
/* -------------------------------------------------------------------- */
poSRS->SetGeogCS( pszGeogName, pszDatumName,
pszEllipsoidName, dfSemiMajor, dfInvFlattening,
pszPMName, dfPMOffset );
/* -------------------------------------------------------------------- */
/* Look for angular units. We don't check that all axes match */
/* at this time. */
/* -------------------------------------------------------------------- */
#ifdef notdef
CPLXMLNode *psAxis;
psAxis = CPLGetXMLNode( psGeo2DCRS,
"EllipsoidalCoordinateSystem.CoordinateAxis" );
importXMLUnits( psAxis, "AngularUnit", poSRS, "GEOGCS" );
#endif
/* -------------------------------------------------------------------- */
/* Can we set authorities for any of the levels? */
/* -------------------------------------------------------------------- */
importXMLAuthority( psCRS, poSRS, "srsID", "GEOGCS" );
importXMLAuthority( psDatum, poSRS, "datumID", "GEOGCS|DATUM" );
importXMLAuthority( psE, poSRS, "ellipsoidID",
"GEOGCS|DATUM|SPHEROID" );
importXMLAuthority( psDatum, poSRS,
"usesPrimeMeridian.PrimeMeridian.meridianID",
"GEOGCS|PRIMEM" );
poSRS->Fixup();
return OGRERR_NONE;
}
/************************************************************************/
/* importProjCSFromXML() */
/************************************************************************/
static OGRErr importProjCSFromXML( OGRSpatialReference *poSRS,
CPLXMLNode *psCRS )
{
CPLXMLNode *psSubXML;
OGRErr eErr;
/* -------------------------------------------------------------------- */
/* Setup the PROJCS node with a name. */
/* -------------------------------------------------------------------- */
poSRS->SetProjCS( CPLGetXMLValue( psCRS, "srsName", "Unnamed" ) );
/* -------------------------------------------------------------------- */
/* Get authority information if available. If we got it, and */
/* we seem to be lacking inline definition values, try and */
/* define according to the EPSG code for the PCS. */
/* -------------------------------------------------------------------- */
importXMLAuthority( psCRS, poSRS, "srsID", "PROJCS" );
if( poSRS->GetAuthorityCode( "PROJCS" ) != NULL
&& poSRS->GetAuthorityName( "PROJCS" ) != NULL
&& EQUAL(poSRS->GetAuthorityName("PROJCS"),"EPSG")
&& (CPLGetXMLNode( psCRS, "definedByConversion.Conversion" ) == NULL
|| CPLGetXMLNode( psCRS, "baseCRS.GeographicCRS" ) == NULL) )
{
return poSRS->importFromEPSG( atoi(poSRS->GetAuthorityCode("PROJCS")) );
}
/* -------------------------------------------------------------------- */
/* Try to set the GEOGCS info. */
/* -------------------------------------------------------------------- */
psSubXML = CPLGetXMLNode( psCRS, "baseCRS.GeographicCRS" );
if( psSubXML != NULL )
{
eErr = importGeogCSFromXML( poSRS, psSubXML );
if( eErr != OGRERR_NONE )
return eErr;
}
/* -------------------------------------------------------------------- */
/* Get the conversion node. It should be the only child of the */
/* definedByConversion node. */
/* -------------------------------------------------------------------- */
CPLXMLNode *psConv = NULL;
psConv = CPLGetXMLNode( psCRS, "definedByConversion.Conversion" );
if( psConv == NULL || psConv->eType != CXT_Element )
{
CPLError( CE_Failure, CPLE_AppDefined,
"Unable to find a conversion node under the definedByConversion\n"
"node of the ProjectedCRS." );
return OGRERR_CORRUPT_DATA;
}
/* -------------------------------------------------------------------- */
/* Determine the conversion method in effect. */
/* -------------------------------------------------------------------- */
int nMethod = getEPSGObjectCodeValue( CPLGetXMLNode( psConv, "usesMethod"),
"method", 0 );
/* -------------------------------------------------------------------- */
/* Transverse Mercator. */
/* -------------------------------------------------------------------- */
if( nMethod == 9807 )
{
poSRS->SetTM(
getProjectionParm( psConv, 8801, "Angular", 0.0 ),
getProjectionParm( psConv, 8802, "Angular", 0.0 ),
getProjectionParm( psConv, 8805, "Unitless", 1.0 ),
getProjectionParm( psConv, 8806, "Linear", 0.0 ),
getProjectionParm( psConv, 8807, "Linear", 0.0 ) );
}
/* -------------------------------------------------------------------- */
/* Didn't recognise? */
/* -------------------------------------------------------------------- */
else
{
CPLError( CE_Failure, CPLE_AppDefined,
"Conversion method %d not recognised.",
nMethod );
return OGRERR_CORRUPT_DATA;
}
/* -------------------------------------------------------------------- */
/* Cleanup and return. */
/* -------------------------------------------------------------------- */
poSRS->Fixup();
// Need to get linear units here!
return OGRERR_NONE;
}
/************************************************************************/
/* importFromXML() */
/************************************************************************/
OGRErr OGRSpatialReference::importFromXML( const char *pszXML )
{
CPLXMLNode *psTree;
OGRErr eErr = OGRERR_UNSUPPORTED_SRS;
this->Clear();
/* -------------------------------------------------------------------- */
/* Parse the XML. */
/* -------------------------------------------------------------------- */
psTree = CPLParseXMLString( pszXML );
if( psTree == NULL )
return OGRERR_CORRUPT_DATA;
CPLStripXMLNamespace( psTree, "gml", TRUE );
/* -------------------------------------------------------------------- */
/* Import according to the root node type. We walk through */
/* root elements as there is sometimes prefix stuff like */
/* <?xml>. */
/* -------------------------------------------------------------------- */
CPLXMLNode *psNode = psTree;
for( psNode = psTree; psNode != NULL; psNode = psNode->psNext )
{
if( EQUAL(psNode->pszValue,"GeographicCRS") )
{
eErr = importGeogCSFromXML( this, psNode );
break;
}
else if( EQUAL(psNode->pszValue,"ProjectedCRS") )
{
eErr = importProjCSFromXML( this, psNode );
break;
}
}
CPLDestroyXMLNode( psTree );
return eErr;
}
/************************************************************************/
/* OSRImportFromXML() */
/************************************************************************/
OGRErr OSRImportFromXML( OGRSpatialReferenceH hSRS, const char *pszXML )
{
return ((OGRSpatialReference *) hSRS)->importFromXML( pszXML );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -