📄 ogr_srs_xml.cpp
字号:
if( pszValue != NULL ) return atof(pszValue); else return dfDefault; } } return dfDefault;}/************************************************************************//* 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 + -