static void importXMLAuthority(CPLXMLNode *psSrcXML, OGRSpatialReference *poSRS, const char *pszSourceKey, const char *pszTargetKey) { CPLXMLNode *psIDNode = CPLGetXMLNode(psSrcXML, pszSourceKey); CPLXMLNode *psNameNode = CPLGetXMLNode(psIDNode, "name"); CPLXMLNode *psCodeSpace = CPLGetXMLNode(psNameNode, "codeSpace"); const char *pszAuthority, *pszCode; char *pszURN; int nCode = 0; if (psIDNode == NULL || psNameNode == NULL || psCodeSpace == NULL) return; pszURN = CPLStrdup(CPLGetXMLValue(psCodeSpace, "", "")); if (!parseURN(pszURN, NULL, &pszAuthority, &pszCode)) { CPLFree(pszURN); return; } if (strlen(pszCode) == 0) pszCode = (char*) CPLGetXMLValue(psNameNode, "", ""); if (pszCode != NULL) nCode = atoi(pszCode); if (nCode != 0) poSRS->SetAuthority(pszTargetKey, pszAuthority, nCode); CPLFree(pszURN); }
void WCTSIsTransformable( CPLXMLNode *psOperation ) { OGRSpatialReference *poSrcCRS, *poDstCRS; CPLXMLNode *psSrcXMLCRS, *psDstXMLCRS; /* -------------------------------------------------------------------- */ /* Translate the source CRS. */ /* -------------------------------------------------------------------- */ psSrcXMLCRS = CPLGetXMLNode( psOperation, "SourceCRS" ); if( psSrcXMLCRS == NULL ) WCTSEmitServiceException( "Unable to identify SourceCRS.CoordinateReferenceSystem" ); poSrcCRS = WCTSImportCoordinateReferenceSystem( psSrcXMLCRS ); /* -------------------------------------------------------------------- */ /* Translate the destination CRS. */ /* -------------------------------------------------------------------- */ psDstXMLCRS = CPLGetXMLNode( psOperation, "TargetCRS" ); if( psDstXMLCRS == NULL ) WCTSEmitServiceException( "Unable to identify DestinationCRS.CoordinateReferenceSystem" ); poDstCRS = WCTSImportCoordinateReferenceSystem( psDstXMLCRS ); /* -------------------------------------------------------------------- */ /* Create a transformation object between the coordinate */ /* systems as an added step of verification that they are */ /* supported. */ /* -------------------------------------------------------------------- */ OGRCoordinateTransformation *poCT; const char *pszResult; poCT = OGRCreateCoordinateTransformation( poSrcCRS, poDstCRS ); if( poCT == NULL ) pszResult = "false"; else { delete poCT; pszResult = "true"; } delete poSrcCRS; delete poDstCRS; /* -------------------------------------------------------------------- */ /* Return the answer. */ /* -------------------------------------------------------------------- */ printf( "Content-type: text/xml%c%c", 10, 10 ); printf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); printf( "<TransformableResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.deegree.org/xml/schemas/wcts/transformableResponse.xsd\" transformable=\"%s\"/>\n", pszResult ); exit( 0 ); }
static double getProjectionParm(CPLXMLNode *psRootNode, int nParameterCode, const char* /*pszMeasureType */, double dfDefault) { CPLXMLNode *psUsesParameter; for (psUsesParameter = psRootNode->psChild; psUsesParameter != NULL; psUsesParameter = psUsesParameter->psNext) { if (psUsesParameter->eType != CXT_Element) continue; if (!EQUAL(psUsesParameter->pszValue, "usesParameterValue") && !EQUAL(psUsesParameter->pszValue, "usesValue")) continue; if (getEPSGObjectCodeValue(CPLGetXMLNode(psUsesParameter, "valueOfParameter"), "parameter", 0) == nParameterCode) { const char *pszValue = CPLGetXMLValue(psUsesParameter, "value", NULL); if (pszValue != NULL) return atof(pszValue); else return dfDefault; } } return dfDefault; }
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); }
CPLErr GDALWMSRasterBand::ReportWMSException(const char *file_name) { CPLErr ret = CE_None; int reported_errors_count = 0; CPLXMLNode *orig_root = CPLParseXMLFile(file_name); CPLXMLNode *root = orig_root; if (root != NULL) { root = CPLGetXMLNode(root, "=ServiceExceptionReport"); } if (root != NULL) { CPLXMLNode *n = CPLGetXMLNode(root, "ServiceException"); while (n != NULL) { const char *exception = CPLGetXMLValue(n, "=ServiceException", ""); const char *exception_code = CPLGetXMLValue(n, "=ServiceException.code", ""); if (exception[0] != '\0') { if (exception_code[0] != '\0') { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception code '%s': %s", exception_code, exception); ++reported_errors_count; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception: %s", exception); ++reported_errors_count; } } else if (exception_code[0] != '\0') { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception code '%s'.", exception_code); ++reported_errors_count; } n = n->psNext; if (n != NULL) { n = CPLGetXMLNode(n, "=ServiceException"); } } } else { ret = CE_Failure; } if (orig_root != NULL) { CPLDestroyXMLNode(orig_root); } if (reported_errors_count == 0) { ret = CE_Failure; } return ret; }
void *GDALDeserializeGCPTransformer( CPLXMLNode *psTree ) { GDAL_GCP *pasGCPList = 0; int nGCPCount = 0; void *pResult = NULL; int nReqOrder = 0; int bReversed = 0; int bRefine = 0; int nMinimumGcps = 0; double dfTolerance = 0.0; /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { GDALDeserializeGCPListFromXML( psGCPList, &pasGCPList, &nGCPCount, NULL ); } /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ nReqOrder = atoi(CPLGetXMLValue(psTree,"Order","3")); bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); bRefine = atoi(CPLGetXMLValue(psTree,"Refine","0")); nMinimumGcps = atoi(CPLGetXMLValue(psTree,"MinimumGcps","6")); dfTolerance = CPLAtof(CPLGetXMLValue(psTree,"Tolerance","1.0")); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ if(bRefine) { pResult = GDALCreateGCPRefineTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed, dfTolerance, nMinimumGcps ); } else { pResult = GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed ); } /* -------------------------------------------------------------------- */ /* Cleanup GCP copy. */ /* -------------------------------------------------------------------- */ GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); return pResult; }
static void CPLMoveImportAtBeginning(CPLXMLNode* psXML) { CPLXMLNode* psSchema = CPLGetXMLNode(psXML, "=schema"); if (psSchema == NULL) psSchema = CPLGetXMLNode(psXML, "=xs:schema"); if (psSchema == NULL) psSchema = CPLGetXMLNode(psXML, "=xsd:schema"); if (psSchema == NULL) return; CPLXMLNode* psPrev = NULL; CPLXMLNode* psIter = psSchema->psChild; while(psIter) { if (psPrev != NULL && psIter->eType == CXT_Element && (strcmp(psIter->pszValue, "import") == 0 || strcmp(psIter->pszValue, "xs:import") == 0 || strcmp(psIter->pszValue, "xsd:import") == 0)) { /* Reorder at the beginning */ CPLXMLNode* psNext = psIter->psNext; psPrev->psNext = psNext; CPLXMLNode* psFirstChild = psSchema->psChild; psSchema->psChild = psIter; psIter->psNext = psFirstChild; psIter = psNext; continue; } psPrev = psIter; psIter = psIter->psNext; } }
// ************************************************************ // ParseServerException() // ************************************************************ void BaseProvider::ParseServerException(CString s) { CPLXMLNode* node = CPLParseXMLString(s); if (node) { while (node) { CPLXMLNode* nodeException = CPLGetXMLNode(node, "ServiceException"); if (nodeException) { CString msg = CPLGetXMLValue(nodeException, "", ""); CallbackHelper::ErrorMsg(Debug::Format("WMS Server exception (%s): %s", Name, msg)); } node = node->psNext; } CPLDestroyXMLNode(node); } }
CPLXMLNode *OGRFMECacheIndex::FindMatch( const char *pszDriver, const char *pszDataset, IFMEStringArray &oUserDirectives ) { CPLXMLNode *psCDS; if( psTree == NULL ) return NULL; for( psCDS = psTree->psChild; psCDS != NULL; psCDS = psCDS->psNext ) { if( !EQUAL(pszDriver,CPLGetXMLValue(psCDS,"Driver","")) ) continue; if( !EQUAL(pszDataset,CPLGetXMLValue(psCDS,"DSName","")) ) continue; CPLXMLNode *psDirective; int bMatch = TRUE; int iDir; psDirective = CPLGetXMLNode( psCDS, "UserDirectives.Directive" ); for( iDir = 0; iDir < (int)oUserDirectives.entries() && bMatch; iDir++ ) { if( psDirective == NULL || psDirective->psChild == NULL ) bMatch = FALSE; else if( !EQUAL(psDirective->psChild->pszValue, oUserDirectives(iDir)) ) bMatch = FALSE; else psDirective = psDirective->psNext; } if( iDir < (int) oUserDirectives.entries() || !bMatch || (psDirective != NULL && psDirective->psNext != NULL) ) continue; return psCDS; } return NULL; }
void OGRFMECacheIndex::Dereference( CPLXMLNode *psDSNode ) { if( psDSNode == NULL || !EQUAL(psDSNode->pszValue,"DataSource") || CPLGetXMLNode(psDSNode,"RefCount") == NULL ) return; char szNewRefCount[32]; int nRefCount = atoi(CPLGetXMLValue(psDSNode, "RefCount", "1")); if( nRefCount < 1 ) nRefCount = 1; sprintf( szNewRefCount, "%d", nRefCount-1 ); CPLSetXMLValue( psDSNode, "RefCount", szNewRefCount ); Touch( psDSNode ); }
void *GDALDeserializeTPSTransformer( CPLXMLNode *psTree ) { GDAL_GCP *pasGCPList = 0; int nGCPCount = 0; void *pResult; int bReversed; /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { GDALDeserializeGCPListFromXML( psGCPList, &pasGCPList, &nGCPCount, NULL ); } /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ pResult = GDALCreateTPSTransformer( nGCPCount, pasGCPList, bReversed ); /* -------------------------------------------------------------------- */ /* Cleanup GCP copy. */ /* -------------------------------------------------------------------- */ GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); return pResult; }
bool GMLRegistry::Parse() { if( osRegistryPath.empty() ) { const char *pszFilename = CPLFindFile("gdal", "gml_registry.xml"); if( pszFilename ) osRegistryPath = pszFilename; } if( osRegistryPath.empty() ) return false; CPLXMLNode *psRootNode = CPLParseXMLFile(osRegistryPath); if( psRootNode == NULL ) return false; CPLXMLNode *psRegistryNode = CPLGetXMLNode(psRootNode, "=gml_registry"); if( psRegistryNode == NULL ) { CPLDestroyXMLNode(psRootNode); return false; } CPLXMLNode *psIter = psRegistryNode->psChild; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "namespace") == 0 ) { GMLRegistryNamespace oNameSpace; if( oNameSpace.Parse(osRegistryPath, psIter) ) { aoNamespaces.push_back(oNameSpace); } } psIter = psIter->psNext; } CPLDestroyXMLNode(psRootNode); return true; }
CPLErr VRTDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath ) { if( pszVRTPath != NULL ) this->pszVRTPath = CPLStrdup(pszVRTPath); /* -------------------------------------------------------------------- */ /* Check for an SRS node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "SRS", "")) > 0 ) { OGRSpatialReference oSRS; CPLFree( pszProjection ); pszProjection = NULL; if( oSRS.SetFromUserInput( CPLGetXMLValue(psTree, "SRS", "") ) == OGRERR_NONE ) oSRS.exportToWkt( &pszProjection ); } /* -------------------------------------------------------------------- */ /* Check for a GeoTransform node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "GeoTransform", "")) > 0 ) { const char *pszGT = CPLGetXMLValue(psTree, "GeoTransform", ""); char **papszTokens; papszTokens = CSLTokenizeStringComplex( pszGT, ",", FALSE, FALSE ); if( CSLCount(papszTokens) != 6 ) { CPLError( CE_Warning, CPLE_AppDefined, "GeoTransform node does not have expected six values."); } else { for( int iTA = 0; iTA < 6; iTA++ ) adfGeoTransform[iTA] = atof(papszTokens[iTA]); bGeoTransformSet = TRUE; } CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { CPLXMLNode *psXMLGCP; OGRSpatialReference oSRS; const char *pszRawProj = CPLGetXMLValue(psGCPList, "Projection", ""); CPLFree( pszGCPProjection ); if( strlen(pszRawProj) > 0 && oSRS.SetFromUserInput( pszRawProj ) == OGRERR_NONE ) oSRS.exportToWkt( &pszGCPProjection ); else pszGCPProjection = CPLStrdup(""); // Count GCPs. int nGCPMax = 0; for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Create dataset mask band. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psChild; /* Parse dataset mask band first */ CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand"); if (psMaskBandNode) psChild = psMaskBandNode->psChild; else psChild = NULL; for( ; psChild != NULL; psChild=psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(psChild->pszValue,"VRTRasterBand") ) { VRTRasterBand *poBand = NULL; const char *pszSubclass = CPLGetXMLValue( psChild, "subclass", "VRTSourcedRasterBand" ); if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( this, 0 ); else CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); if( poBand != NULL && poBand->XMLInit( psChild, pszVRTPath ) == CE_None ) { SetMaskBand(poBand); break; } else { if( poBand ) delete poBand; return CE_Failure; } } } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int nBands = 0; for( psChild=psTree->psChild; psChild != NULL; psChild=psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(psChild->pszValue,"VRTRasterBand") ) { VRTRasterBand *poBand = NULL; const char *pszSubclass = CPLGetXMLValue( psChild, "subclass", "VRTSourcedRasterBand" ); if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( this, nBands+1 ); else CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); if( poBand != NULL && poBand->XMLInit( psChild, pszVRTPath ) == CE_None ) { SetBand( ++nBands, poBand ); } else { if( poBand ) delete poBand; return CE_Failure; } } } return CE_None; }
static GMLFeatureClass* GMLParseFeatureType(CPLXMLNode *psSchemaNode, const char* pszName, CPLXMLNode *psComplexType) { /* -------------------------------------------------------------------- */ /* Grab the sequence of extensions greatgrandchild. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAttrSeq = CPLGetXMLNode( psComplexType, "complexContent.extension.sequence" ); if( psAttrSeq == NULL ) { return NULL; } /* -------------------------------------------------------------------- */ /* We are pretty sure this going to be a valid Feature class */ /* now, so create it. */ /* -------------------------------------------------------------------- */ GMLFeatureClass *poClass = new GMLFeatureClass( pszName ); /* -------------------------------------------------------------------- */ /* Loop over each of the attribute elements being defined for */ /* this feature class. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAttrDef; int nAttributeIndex = 0; int bGotUnrecognizedType = FALSE; for( psAttrDef = psAttrSeq->psChild; psAttrDef != NULL; psAttrDef = psAttrDef->psNext ) { if( strcmp(psAttrDef->pszValue,"group") == 0 ) { /* Too complex schema for us. Aborts parsing */ delete poClass; return NULL; } if( !EQUAL(psAttrDef->pszValue,"element") ) continue; /* MapServer WFS writes element type as an attribute of element */ /* not as a simpleType definition */ const char* pszType = CPLGetXMLValue( psAttrDef, "type", NULL ); const char* pszElementName = CPLGetXMLValue( psAttrDef, "name", NULL ); if (pszType != NULL) { const char* pszStrippedNSType = StripNS(pszType); int nWidth = 0, nPrecision = 0; GMLPropertyType gmlType = GMLPT_Untyped; if (EQUAL(pszStrippedNSType, "string") || EQUAL(pszStrippedNSType, "Character")) gmlType = GMLPT_String; /* TODO: Would be nice to have a proper date type */ else if (EQUAL(pszStrippedNSType, "date") || EQUAL(pszStrippedNSType, "dateTime")) gmlType = GMLPT_String; else if (EQUAL(pszStrippedNSType, "real") || EQUAL(pszStrippedNSType, "double") || EQUAL(pszStrippedNSType, "float") || EQUAL(pszStrippedNSType, "decimal")) gmlType = GMLPT_Real; else if (EQUAL(pszStrippedNSType, "short") || EQUAL(pszStrippedNSType, "int") || EQUAL(pszStrippedNSType, "integer") || EQUAL(pszStrippedNSType, "long")) gmlType = GMLPT_Integer; else if (strncmp(pszType, "gml:", 4) == 0) { const AssocNameType* psIter = apsPropertyTypes; while(psIter->pszName) { if (strncmp(pszType + 4, psIter->pszName, strlen(psIter->pszName)) == 0) { if (poClass->GetGeometryAttributeIndex() != -1) { CPLDebug("GML", "Geometry field already found ! Ignoring the following ones"); } else { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(psIter->eType); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; } break; } psIter ++; } if (psIter->pszName == NULL) { /* Can be a non geometry gml type */ /* Too complex schema for us. Aborts parsing */ delete poClass; return NULL; } if (poClass->GetGeometryAttributeIndex() == -1) bGotUnrecognizedType = TRUE; continue; } /* Integraph stuff */ else if (strcmp(pszType, "G:Point_MultiPointPropertyType") == 0 || strcmp(pszType, "gmgml:Point_MultiPointPropertyType") == 0) { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(wkbMultiPoint); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; continue; } else if (strcmp(pszType, "G:LineString_MultiLineStringPropertyType") == 0 || strcmp(pszType, "gmgml:LineString_MultiLineStringPropertyType") == 0) { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(wkbMultiLineString); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; continue; } else if (strcmp(pszType, "G:Polygon_MultiPolygonPropertyType") == 0 || strcmp(pszType, "gmgml:Polygon_MultiPolygonPropertyType") == 0 || strcmp(pszType, "gmgml:Polygon_Surface_MultiSurface_CompositeSurfacePropertyType") == 0) { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(wkbMultiPolygon); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; continue; } /* ERDAS Apollo stuff (like in http://apollo.erdas.com/erdas-apollo/vector/WORLDWIDE?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=wfs:cntry98) */ else if (strcmp(pszType, "wfs:MixedPolygonPropertyType") == 0) { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(wkbMultiPolygon); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; continue; } else { gmlType = GMLPT_Untyped; if ( ! LookForSimpleType(psSchemaNode, pszStrippedNSType, &gmlType, &nWidth, &nPrecision) ) { /* Too complex schema for us. Aborts parsing */ delete poClass; return NULL; } } if (pszElementName == NULL) pszElementName = "unnamed"; GMLPropertyDefn *poProp = new GMLPropertyDefn( pszElementName, pszElementName ); poProp->SetType( gmlType ); poProp->SetAttributeIndex( nAttributeIndex ); poProp->SetWidth( nWidth ); poProp->SetPrecision( nPrecision ); if (poClass->AddProperty( poProp ) < 0) delete poProp; else nAttributeIndex ++; continue; } // For now we skip geometries .. fixup later. CPLXMLNode* psSimpleType = CPLGetXMLNode( psAttrDef, "simpleType" ); if( psSimpleType == NULL ) { const char* pszRef = CPLGetXMLValue( psAttrDef, "ref", NULL ); /* FME .xsd */ if (pszRef != NULL && strncmp(pszRef, "gml:", 4) == 0) { const AssocNameType* psIter = apsRefTypes; while(psIter->pszName) { if (strncmp(pszRef + 4, psIter->pszName, strlen(psIter->pszName)) == 0) { if (poClass->GetGeometryAttributeIndex() != -1) { OGRwkbGeometryType eNewType = psIter->eType; OGRwkbGeometryType eOldType = (OGRwkbGeometryType)poClass->GetGeometryType(); if ((eNewType == wkbMultiPoint && eOldType == wkbPoint) || (eNewType == wkbMultiLineString && eOldType == wkbLineString) || (eNewType == wkbMultiPolygon && eOldType == wkbPolygon)) { poClass->SetGeometryType(eNewType); } else { CPLDebug("GML", "Geometry field already found ! Ignoring the following ones"); } } else { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(psIter->eType); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; } break; } psIter ++; } if (psIter->pszName == NULL) { /* Can be a non geometry gml type */ /* Too complex schema for us. Aborts parsing */ delete poClass; return NULL; } if (poClass->GetGeometryAttributeIndex() == -1) bGotUnrecognizedType = TRUE; continue; } /* Parse stuff like the following found in http://199.29.1.81:8181/miwfs/GetFeature.ashx?REQUEST=GetFeature&MAXFEATURES=1&SERVICE=WFS&VERSION=1.0.0&TYPENAME=miwfs:World : <xs:element name="Obj" minOccurs="0" maxOccurs="1"> <xs:complexType> <xs:sequence> <xs:element ref="gml:_Geometry"/> </xs:sequence> </xs:complexType> </xs:element> */ CPLXMLNode* psComplexType = GetSingleChildElement( psAttrDef, "complexType" ); CPLXMLNode* psComplexTypeSequence = GetSingleChildElement( psComplexType, "sequence" ); CPLXMLNode* psComplexTypeSequenceElement = GetSingleChildElement( psComplexTypeSequence, "element" ); if( pszElementName != NULL && CheckMinMaxOccursCardinality(psAttrDef) && psComplexTypeSequenceElement != NULL && CheckMinMaxOccursCardinality(psComplexTypeSequence) && strcmp(CPLGetXMLValue( psComplexTypeSequenceElement, "ref", "" ), "gml:_Geometry") == 0 ) { poClass->SetGeometryElement(pszElementName); poClass->SetGeometryType(wkbUnknown); poClass->SetGeometryAttributeIndex( nAttributeIndex ); nAttributeIndex ++; continue; } else { /* Too complex schema for us. Aborts parsing */ delete poClass; return NULL; } } if (pszElementName == NULL) pszElementName = "unnamed"; GMLPropertyDefn *poProp = new GMLPropertyDefn( pszElementName, pszElementName ); GMLPropertyType eType = GMLPT_Untyped; int nWidth = 0, nPrecision = 0; GetSimpleTypeProperties(psSimpleType, &eType, &nWidth, &nPrecision); poProp->SetType( eType ); poProp->SetWidth( nWidth ); poProp->SetPrecision( nPrecision ); poProp->SetAttributeIndex( nAttributeIndex ); if (poClass->AddProperty( poProp ) < 0) delete poProp; else nAttributeIndex ++; } /* Only report wkbNone if we didn't find a known geometry type */ /* and there were not any unknown types (in case this unknown type */ /* would be a geometry type) */ if (poClass->GetGeometryAttributeIndex() == -1 && !bGotUnrecognizedType) { poClass->SetGeometryType(wkbNone); } /* -------------------------------------------------------------------- */ /* Class complete, add to reader class list. */ /* -------------------------------------------------------------------- */ poClass->SetSchemaLocked( TRUE ); return poClass; }
int GMLParseXSD( const char *pszFile, std::vector<GMLFeatureClass*> & aosClasses) { if( pszFile == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Load the raw XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXSDTree = CPLParseXMLFile( pszFile ); if( psXSDTree == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Strip off any namespace qualifiers. */ /* -------------------------------------------------------------------- */ CPLStripXMLNamespace( psXSDTree, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Find <schema> root element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" ); if( psSchemaNode == NULL ) { CPLDestroyXMLNode( psXSDTree ); return FALSE; } /* ==================================================================== */ /* Process each feature class definition. */ /* ==================================================================== */ CPLXMLNode *psThis; for( psThis = psSchemaNode->psChild; psThis != NULL; psThis = psThis->psNext ) { /* -------------------------------------------------------------------- */ /* Check for <xs:element> node. */ /* -------------------------------------------------------------------- */ if( psThis->eType != CXT_Element || !EQUAL(psThis->pszValue,"element") ) continue; /* -------------------------------------------------------------------- */ /* Check the substitution group. */ /* -------------------------------------------------------------------- */ const char *pszSubGroup = StripNS(CPLGetXMLValue(psThis,"substitutionGroup","")); // Old OGR produced elements for the feature collection. if( EQUAL(pszSubGroup, "_FeatureCollection") ) continue; if( !EQUAL(pszSubGroup, "_Feature") && !EQUAL(pszSubGroup, "AbstractFeature") /* AbstractFeature used by GML 3.2 */ ) { continue; } /* -------------------------------------------------------------------- */ /* Get name */ /* -------------------------------------------------------------------- */ const char *pszName; pszName = CPLGetXMLValue( psThis, "name", NULL ); if( pszName == NULL ) { continue; } /* -------------------------------------------------------------------- */ /* Get type and verify relationship with name. */ /* -------------------------------------------------------------------- */ const char *pszType; pszType = CPLGetXMLValue( psThis, "type", NULL ); if (pszType == NULL) { CPLXMLNode *psComplexType = CPLGetXMLNode( psThis, "complexType" ); if (psComplexType) { GMLFeatureClass* poClass = GMLParseFeatureType(psSchemaNode, pszName, psComplexType); if (poClass) aosClasses.push_back(poClass); } continue; } if( strstr( pszType, ":" ) != NULL ) pszType = strstr( pszType, ":" ) + 1; if( EQUAL(pszType, pszName) ) { /* A few WFS servers return a type name which is the element name */ /* without any _Type or Type suffix */ /* e.g. : http://apollo.erdas.com/erdas-apollo/vector/Cherokee?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=iwfs:Air */ } else if( !EQUALN(pszType,pszName,strlen(pszName)) || !(EQUAL(pszType+strlen(pszName),"_Type") || EQUAL(pszType+strlen(pszName),"Type")) ) { continue; } /* CanVec .xsd contains weird types that are not used in the related GML */ if (strncmp(pszName, "XyZz", 4) == 0 || strncmp(pszName, "XyZ1", 4) == 0 || strncmp(pszName, "XyZ2", 4) == 0) continue; GMLFeatureClass* poClass = GMLParseFeatureType(psSchemaNode, pszName, pszType); if (poClass) aosClasses.push_back(poClass); } CPLDestroyXMLNode( psXSDTree ); if( aosClasses.size() > 0 ) { return TRUE; } else return FALSE; }
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a TerraSAR-X product file? */ /* -------------------------------------------------------------------- */ if (!TSXDataset::Identify( poOpenInfo )) { return NULL; /* nope */ } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The TSX driver does not support update access to existing" " datasets.\n" ); return NULL; } CPLString osFilename; if( poOpenInfo->bIsDirectory ) { osFilename = CPLFormCIFilename( poOpenInfo->pszFilename, CPLGetFilename( poOpenInfo->pszFilename ), "xml" ); } else osFilename = poOpenInfo->pszFilename; /* Ingest the XML */ CPLXMLNode *psData = CPLParseXMLFile( osFilename ); if (psData == NULL) return NULL; /* find the product components */ CPLXMLNode *psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productComponents> tag in file.\n" ); CPLDestroyXMLNode(psData); return NULL; } /* find the product info tag */ CPLXMLNode *psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" ); if (psProductInfo == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productInfo> tag in file.\n" ); CPLDestroyXMLNode(psData); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ TSXDataset *poDS = new TSXDataset(); /* -------------------------------------------------------------------- */ /* Read in product info. */ /* -------------------------------------------------------------------- */ poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo, "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) ); poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, "generationInfo.groundOperationsType", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo, "missionInfo.orbitCycle", "unknown" ) ); poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo, "missionInfo.absOrbit", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo, "missionInfo.orbitDirection", "unknown" ) ); poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo, "acquisitionInfo.imagingMode", "unknown" ) ); poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ) ); char *pszDataType = CPLStrdup( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageDataType", "unknown" ) ); poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); /* Get raster information */ int nRows = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfRows", "" ) ); int nCols = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfColumns", "" ) ); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rowSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) ); /* Get equivalent number of looks */ poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) ); poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rangeLooks", "unknown" ) ); const char *pszProductVariant = CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ); poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant ); /* Determine what product variant this is */ if (STARTS_WITH_CI(pszProductVariant, "SSC")) poDS->nProduct = eSSC; else if (STARTS_WITH_CI(pszProductVariant, "MGD")) poDS->nProduct = eMGD; else if (STARTS_WITH_CI(pszProductVariant, "EEC")) poDS->nProduct = eEEC; else if (STARTS_WITH_CI(pszProductVariant, "GEC")) poDS->nProduct = eGEC; else poDS->nProduct = eUnknown; /* Start reading in the product components */ char *pszGeorefFile = NULL; CPLErr geoTransformErr=CE_Failure; for ( CPLXMLNode *psComponent = psComponents->psChild; psComponent != NULL; psComponent = psComponent->psNext) { const char *pszType = NULL; const char *pszPath = CPLFormFilename( CPLGetDirname( osFilename ), GetFilePath(psComponent, &pszType), "" ); const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " "); if ( !STARTS_WITH_CI(pszType, " ") ) { if (STARTS_WITH_CI(pszType, "MAPPING_GRID") ) { /* the mapping grid... save as a metadata item this path */ poDS->SetMetadataItem( "MAPPING_GRID", pszPath ); } else if (STARTS_WITH_CI(pszType, "GEOREF")) { /* save the path to the georef data for later use */ CPLFree( pszGeorefFile ); pszGeorefFile = CPLStrdup( pszPath ); } } else if( !STARTS_WITH_CI(pszPolLayer, " ") && STARTS_WITH_CI(psComponent->pszValue, "imageData") ) { /* determine the polarization of this band */ ePolarization ePol; if ( STARTS_WITH_CI(pszPolLayer, "HH") ) { ePol = HH; } else if ( STARTS_WITH_CI(pszPolLayer, "HV") ) { ePol = HV; } else if ( STARTS_WITH_CI(pszPolLayer, "VH") ) { ePol = VH; } else { ePol = VV; } GDALDataType eDataType = STARTS_WITH_CI(pszDataType, "COMPLEX") ? GDT_CInt16 : GDT_UInt16; /* try opening the file that represents that band */ GDALDataset *poBandData = reinterpret_cast<GDALDataset *>( GDALOpen( pszPath, GA_ReadOnly ) ); if ( poBandData != NULL ) { TSXRasterBand *poBand = new TSXRasterBand( poDS, eDataType, ePol, poBandData ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); //copy georeferencing info from the band //need error checking?? //it will just save the info from the last band CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(poBandData->GetProjectionRef()); geoTransformErr = poBandData->GetGeoTransform(poDS->adfGeoTransform); } } } //now check if there is a geotransform if ( strcmp(poDS->pszProjection, "") && geoTransformErr==CE_None) { poDS->bHaveGeoTransform = TRUE; } else { poDS->bHaveGeoTransform = FALSE; CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(""); poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; } CPLFree(pszDataType); /* -------------------------------------------------------------------- */ /* Check and set matrix representation. */ /* -------------------------------------------------------------------- */ if (poDS->GetRasterCount() == 4) { poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } /* -------------------------------------------------------------------- */ /* Read the four corners and centre GCPs in */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, "=level1Product.productInfo.sceneInfo" ); if (psSceneInfo != NULL) { /* extract the GCPs from the provided file */ bool success = false; if (pszGeorefFile != NULL) success = poDS->getGCPsFromGEOREF_XML(pszGeorefFile); //if the gcp's cannot be extracted from the georef file, try to get the corner coordinates //for now just SSC because the others don't have refColumn and refRow if (!success && poDS->nProduct == eSSC) { int nGCP = 0; double dfAvgHeight = CPLAtof(CPLGetXMLValue(psSceneInfo, "sceneAverageHeight", "0.0")); //count and allocate gcps - there should be five - 4 corners and a centre poDS->nGCPCount = 0; CPLXMLNode *psNode = psSceneInfo->psChild; for ( ; psNode != NULL; psNode = psNode->psNext ) { if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; poDS->nGCPCount++; } if (poDS->nGCPCount > 0) { poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount); /* iterate over GCPs */ for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + nGCP; if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode, "refColumn", "0.0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode, "refRow", "0.0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode, "lon", "0.0")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode, "lat", "0.0")); psGCP->dfGCPZ = dfAvgHeight; psGCP->pszId = CPLStrdup( CPLSPrintf( "%d", nGCP ) ); psGCP->pszInfo = CPLStrdup(""); nGCP++; } //set the projection string - the fields are lat/long - seems to be WGS84 datum OGRSpatialReference osr; osr.SetWellKnownGeogCS( "WGS84" ); CPLFree(poDS->pszGCPProjection); osr.exportToWkt( &(poDS->pszGCPProjection) ); } } //gcps override geotransform - does it make sense to have both?? if (poDS->nGCPCount>0) { poDS->bHaveGeoTransform = FALSE; CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(""); poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; } } else { CPLError(CE_Warning, CPLE_AppDefined, "Unable to find sceneInfo tag in XML document. " "Proceeding with caution."); } CPLFree(pszGeorefFile); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); CPLDestroyXMLNode(psData); return poDS; }
void *GDALDeserializeGCPTransformer( CPLXMLNode *psTree ) { GDAL_GCP *pasGCPList = 0; int nGCPCount = 0; void *pResult; int nReqOrder; int bReversed; int bRefine; int nMinimumGcps; double dfTolerance; /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { int nGCPMax = 0; CPLXMLNode *psXMLGCP; // Count GCPs. for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ nReqOrder = atoi(CPLGetXMLValue(psTree,"Order","3")); bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); bRefine = atoi(CPLGetXMLValue(psTree,"Refine","0")); nMinimumGcps = atoi(CPLGetXMLValue(psTree,"MinimumGcps","6")); dfTolerance = atof(CPLGetXMLValue(psTree,"Tolerance","1.0")); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ if(bRefine) { pResult = GDALCreateGCPRefineTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed, dfTolerance, nMinimumGcps ); } else { pResult = GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed ); } /* -------------------------------------------------------------------- */ /* Cleanup GCP copy. */ /* -------------------------------------------------------------------- */ GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); return pResult; }
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a TerraSAR-X product file? */ /* -------------------------------------------------------------------- */ if (!TSXDataset::Identify( poOpenInfo )) { return NULL; /* nope */ } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The TSX driver does not support update access to existing" " datasets.\n" ); return NULL; } /* Ingest the XML */ CPLXMLNode *psData, *psComponents, *psProductInfo; psData = CPLParseXMLFile( poOpenInfo->pszFilename ); /* find the product components */ psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productComponents> tag in file.\n" ); return NULL; } /* find the product info tag */ psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productInfo> tag in file.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ TSXDataset *poDS = new TSXDataset(); poDS->fp = poOpenInfo->fp; poOpenInfo->fp = NULL; /* -------------------------------------------------------------------- */ /* Read in product info. */ /* -------------------------------------------------------------------- */ poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo, "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) ); poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, "generationInfo.groundOperationsType", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo, "missionInfo.orbitCycle", "unknown" ) ); poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo, "missionInfo.absOrbit", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo, "missionInfo.orbitDirection", "unknown" ) ); poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo, "acquisitionInfo.imagingMode", "unknown" ) ); poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ) ); char *pszDataType = strdup( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageDataType", "unknown" ) ); poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); /* Get raster information */ int nRows = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfRows", "" ) ); int nCols = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfColumns", "" ) ); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rowSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) ); /* Get equivalent number of looks */ poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) ); poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rangeLooks", "unknown" ) ); const char *pszProductVariant; pszProductVariant = CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ); poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant ); /* Determine what product variant this is */ if (EQUALN(pszProductVariant,"SSC",3)) poDS->nProduct = eSSC; else if (EQUALN(pszProductVariant,"MGD",3)) poDS->nProduct = eMGD; else if (EQUALN(pszProductVariant,"EEC",3)) poDS->nProduct = eEEC; else if (EQUALN(pszProductVariant,"GEC",3)) poDS->nProduct = eGEC; else poDS->nProduct = eUnknown; /* Start reading in the product components */ const char *pszPath; char *pszGeorefFile = NULL; CPLXMLNode *psComponent; for (psComponent = psComponents->psChild; psComponent != NULL; psComponent = psComponent->psNext) { char *pszType; pszPath = CPLFormFilename( CPLGetDirname( poOpenInfo->pszFilename ), GetFilePath(psComponent, &pszType), "" ); const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " "); if ( !EQUALN(pszType," ",1) ) { if (EQUALN(pszType, "MAPPING_GRID", 12) ) { /* the mapping grid... save as a metadata item this path */ poDS->SetMetadataItem( "MAPPING_GRID", pszPath ); } else if (EQUALN(pszType, "GEOREF", 6)) { /* save the path to the georef data for later use */ pszGeorefFile = strdup( pszPath ); } CPLFree(pszType); } else if( !EQUALN(pszPolLayer, " ", 1) && EQUALN(psComponent->pszValue, "imageData", 9) ) { /* determine the polarization of this band */ ePolarization ePol; if ( EQUALN(pszPolLayer, "HH", 2) ) { ePol = HH; } else if ( EQUALN(pszPolLayer, "HV" , 2) ) { ePol = HV; } else if ( EQUALN(pszPolLayer, "VH", 2) ) { ePol = VH; } else { ePol = VV; } GDALDataType eDataType = EQUALN(pszDataType, "COMPLEX", 7) ? GDT_CInt16 : GDT_UInt16; /* try opening the file that represents that band */ TSXRasterBand *poBand; GDALDataset *poBandData; poBandData = (GDALDataset *) GDALOpen( pszPath, GA_ReadOnly ); if ( poBandData != NULL ) { poBand = new TSXRasterBand( poDS, eDataType, ePol, poBandData ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); } } } CPLFree(pszDataType); /* -------------------------------------------------------------------- */ /* Check and set matrix representation. */ /* -------------------------------------------------------------------- */ if (poDS->GetRasterCount() == 4) { poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } /* -------------------------------------------------------------------- */ /* Read the four corners and centre GCPs in */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, "=level1Product.productInfo.sceneInfo" ); /* for SSC products */ if (poDS->nProduct == eSSC && psSceneInfo != NULL) { CPLXMLNode *psNode; int nGCP = 0; double dfAvgHeight = atof(CPLGetXMLValue(psSceneInfo, "sceneAverageHeight", "0.0")); char szID[3]; poDS->nGCPCount = 5; /* 5 GCPs provided */ poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount); /* iterate over GCPs */ for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + nGCP; if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; CPLSPrintf( szID, "%d", nGCP ); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psNode, "refColumn", "0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psNode, "refRow", "0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psNode, "lon", "0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psNode, "lat", "0.0")); psGCP->dfGCPZ = dfAvgHeight; psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); nGCP++; } } else if (psSceneInfo != NULL) { /* extract the GCPs from the provided file */ /* TODO */ } else { CPLError(CE_Warning, CPLE_AppDefined, "Unable to find sceneInfo tag in XML document. " "Proceeding with caution."); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); CPLDestroyXMLNode(psData); return poDS; }
bool TSXDataset::getGCPsFromGEOREF_XML(char *pszGeorefFilename) { //open GEOREF.xml CPLXMLNode *psGeorefData = CPLParseXMLFile( pszGeorefFilename ); if (psGeorefData==NULL) return false; //get the ellipsoid and semi-major, semi-minor axes OGRSpatialReference osr; CPLXMLNode *psSphere = CPLGetXMLNode( psGeorefData, "=geoReference.referenceFrames.sphere" ); if (psSphere!=NULL) { const char *pszEllipsoidName = CPLGetXMLValue( psSphere, "ellipsoidID", "" ); const double minor_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMinorAxis", "0.0" )); const double major_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMajorAxis", "0.0" )); //save datum parameters to the spatial reference if ( EQUAL(pszEllipsoidName, "") || minor_axis==0.0 || major_axis==0.0 ) { CPLError(CE_Warning,CPLE_AppDefined,"Warning- incomplete" " ellipsoid information. Using wgs-84 parameters.\n"); osr.SetWellKnownGeogCS( "WGS84" ); } else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) { osr.SetWellKnownGeogCS( "WGS84" ); } else { const double inv_flattening = major_axis/(major_axis - minor_axis); osr.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); } } //get gcps CPLXMLNode *psGeolocationGrid = CPLGetXMLNode( psGeorefData, "=geoReference.geolocationGrid" ); if (psGeolocationGrid==NULL) { CPLDestroyXMLNode( psGeorefData ); return false; } nGCPCount = atoi(CPLGetXMLValue( psGeolocationGrid, "numberOfGridPoints.total", "0" )); //count the gcps if the given count value is invalid CPLXMLNode *psNode; if (nGCPCount<=0) { for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) if( EQUAL(psNode->pszValue,"gridPoint") ) nGCPCount++ ; } //if there are no gcps, fail if(nGCPCount<=0) { CPLDestroyXMLNode( psGeorefData ); return false; } //put some reasonable limits of the number of gcps if (nGCPCount>MAX_GCPS ) nGCPCount=MAX_GCPS; //allocate memory for the gcps pasGCPList = reinterpret_cast<GDAL_GCP *>( CPLCalloc(sizeof(GDAL_GCP), nGCPCount) ); //loop through all gcps and set info //save the number allocated to ensure it does not run off the end of the array const int gcps_allocated = nGCPCount; nGCPCount=0; //reset to zero and count //do a check on the grid point to make sure it has lat,long row, and column //it seems that only SSC products contain row, col - how to map lat long otherwise?? //for now fail if row and col are not present - just check the first and assume the rest are the same for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { if( !EQUAL(psNode->pszValue,"gridPoint") ) continue; if ( !strcmp(CPLGetXMLValue(psNode,"col","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"row","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"lon","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"lat","error"), "error")) { CPLDestroyXMLNode( psGeorefData ); return false; } } for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { //break out if the end of the array has been reached if (nGCPCount >= gcps_allocated) { CPLError(CE_Warning, CPLE_AppDefined, "GDAL TSX driver: Truncating the number of GCPs."); break; } GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psNode->pszValue,"gridPoint") ) continue; nGCPCount++ ; char szID[32]; snprintf( szID, sizeof(szID), "%d", nGCPCount ); psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"col","0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"row","0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"lon","")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"lat","")); //looks like height is in meters - should it be converted so xyz are all on the same scale?? psGCP->dfGCPZ = 0; //CPLAtof(CPLGetXMLValue(psNode,"height","")); } CPLFree(pszGCPProjection); osr.exportToWkt( &(pszGCPProjection) ); CPLDestroyXMLNode( psGeorefData ); return true; }
static OGRGeometry* ParseKMLGeometry(/* const */ CPLXMLNode* psXML) { OGRGeometry* poGeom = nullptr; const char* pszGeomType = psXML->pszValue; if (strcmp(pszGeomType, "Point") == 0) { const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr); if (pszCoordinates) { char** papszTokens = CSLTokenizeString2(pszCoordinates, ",", 0); if (CSLCount(papszTokens) == 2) poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1])); else if (CSLCount(papszTokens) == 3) poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2])); CSLDestroy(papszTokens); } } else if (strcmp(pszGeomType, "LineString") == 0) { const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr); if (pszCoordinates) { OGRLineString* poLS = new OGRLineString(); ParseLineString(poLS, pszCoordinates); poGeom = poLS; } } else if (strcmp(pszGeomType, "Polygon") == 0) { OGRPolygon* poPoly = nullptr; CPLXMLNode* psOuterBoundary = CPLGetXMLNode(psXML, "outerBoundaryIs"); if (psOuterBoundary) { CPLXMLNode* psLinearRing = CPLGetXMLNode(psOuterBoundary, "LinearRing"); const char* pszCoordinates = CPLGetXMLValue( psLinearRing ? psLinearRing : psOuterBoundary, "coordinates", nullptr); if (pszCoordinates) { OGRLinearRing* poLS = new OGRLinearRing(); ParseLineString(poLS, pszCoordinates); poPoly = new OGRPolygon(); poPoly->addRingDirectly(poLS); poGeom = poPoly; } if (poPoly) { CPLXMLNode* psIter = psXML->psChild; while(psIter) { if (psIter->eType == CXT_Element && strcmp(psIter->pszValue, "innerBoundaryIs") == 0) { psLinearRing = CPLGetXMLNode(psIter, "LinearRing"); pszCoordinates = CPLGetXMLValue( psLinearRing ? psLinearRing : psIter, "coordinates", nullptr); if (pszCoordinates) { OGRLinearRing* poLS = new OGRLinearRing(); ParseLineString(poLS, pszCoordinates); poPoly->addRingDirectly(poLS); } } psIter = psIter->psNext; } } } } else if (strcmp(pszGeomType, "MultiGeometry") == 0) { CPLXMLNode* psIter = nullptr; OGRwkbGeometryType eType = wkbUnknown; for(psIter = psXML->psChild; psIter; psIter = psIter->psNext) { if (psIter->eType == CXT_Element) { OGRwkbGeometryType eNewType = wkbUnknown; if (strcmp(psIter->pszValue, "Point") == 0) { eNewType = wkbPoint; } else if (strcmp(psIter->pszValue, "LineString") == 0) { eNewType = wkbLineString; } else if (strcmp(psIter->pszValue, "Polygon") == 0) { eNewType = wkbPolygon; } else break; if (eType == wkbUnknown) eType = eNewType; else if (eType != eNewType) break; } } OGRGeometryCollection* poColl = nullptr; if (psIter != nullptr) poColl = new OGRGeometryCollection(); else if (eType == wkbPoint) poColl = new OGRMultiPoint(); else if (eType == wkbLineString) poColl = new OGRMultiLineString(); else if (eType == wkbPolygon) poColl = new OGRMultiPolygon(); else { CPLAssert(false); } for(psIter = psXML->psChild; psIter; psIter = psIter->psNext) { if (psIter->eType == CXT_Element) { OGRGeometry* poSubGeom = ParseKMLGeometry(psIter); if (poSubGeom) poColl->addGeometryDirectly(poSubGeom); } } poGeom = poColl; } return poGeom; }
void GDALJP2AbstractDataset::LoadVectorLayers(int bOpenRemoteResources) { char** papszGMLJP2 = GetMetadata("xml:gml.root-instance"); if( papszGMLJP2 == NULL ) return; GDALDriver* poMemDriver = (GDALDriver*)GDALGetDriverByName("Memory"); if( poMemDriver == NULL ) return; CPLXMLNode* psRoot = CPLParseXMLString(papszGMLJP2[0]); if( psRoot == NULL ) return; CPLXMLNode* psCC = CPLGetXMLNode(psRoot, "=gmljp2:GMLJP2CoverageCollection"); if( psCC == NULL ) { CPLDestroyXMLNode(psRoot); return; } // Find feature collections CPLXMLNode* psCCChildIter = psCC->psChild; int nLayersAtCC = 0; int nLayersAtGC = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:feature") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL ) continue; CPLXMLNode* psFC = NULL; int bFreeFC = FALSE; CPLString osGMLTmpFile; CPLXMLNode* psChild = psGCorGMLJP2FeaturesChildIter->psChild; if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && strncmp(psChild->psChild->pszValue, "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = psChild->psChild->pszValue + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { psFC = CPLParseXMLString(papszBoxData[0]); bFreeFC = TRUE; } else { CPLDebug("GMLJP2", "gmljp2:feature references %s, but no corresponding box found", psChild->psChild->pszValue); } } if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && (strncmp(psChild->psChild->pszValue, "http://", strlen("http://")) == 0 || strncmp(psChild->psChild->pszValue, "https://", strlen("https://")) == 0) ) { if( !bOpenRemoteResources ) CPLDebug("GMLJP2", "Remote feature collection %s mentionned in GMLJP2 box", psChild->psChild->pszValue); else osGMLTmpFile = "/vsicurl/" + CPLString(psChild->psChild->pszValue); } else if( psChild->eType == CXT_Element && strstr(psChild->pszValue, "FeatureCollection") != NULL ) { psFC = psChild; } if( psFC == NULL && osGMLTmpFile.size() == 0 ) continue; if( psFC != NULL ) { osGMLTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.gml", this); // Create temporary .gml file CPLSerializeXMLTreeToFile(psFC, osGMLTmpFile); } CPLDebug("GMLJP2", "Found a FeatureCollection at %s level", (bIsGC) ? "GridCoverage" : "CoverageCollection"); CPLString osXSDTmpFile; if( psFC ) { // Try to localize its .xsd schema in a GMLJP2 auxiliary box const char* pszSchemaLocation = CPLGetXMLValue(psFC, "xsi:schemaLocation", NULL); if( pszSchemaLocation ) { char **papszTokens = CSLTokenizeString2( pszSchemaLocation, " \t\n", CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if( (CSLCount(papszTokens) % 2) == 0 ) { for(char** papszIter = papszTokens; *papszIter; papszIter += 2 ) { if( strncmp(papszIter[1], "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = papszIter[1] + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { osXSDTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.xsd", this); VSIFCloseL(VSIFileFromMemBuffer(osXSDTmpFile, (GByte*)papszBoxData[0], strlen(papszBoxData[0]), FALSE)); } else { CPLDebug("GMLJP2", "Feature collection references %s, but no corresponding box found", papszIter[1]); } break; } } } CSLDestroy(papszTokens); } if( bFreeFC ) { CPLDestroyXMLNode(psFC); psFC = NULL; } } GDALDriverH hDrv = GDALIdentifyDriver(osGMLTmpFile, NULL); GDALDriverH hGMLDrv = GDALGetDriverByName("GML"); if( hDrv != NULL && hDrv == hGMLDrv ) { char* apszOpenOptions[2]; apszOpenOptions[0] = (char*) "FORCE_SRS_DETECTION=YES"; apszOpenOptions[1] = NULL; GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osGMLTmpFile, GDAL_OF_VECTOR, NULL, apszOpenOptions, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; if( bIsGC ) pszLayerName = CPLSPrintf("FC_GridCoverage_%d_%s", ++nLayersAtGC, poSrcLyr->GetName()); else pszLayerName = CPLSPrintf("FC_CoverageCollection_%d_%s", ++nLayersAtCC, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); // In case we don't have a schema, a .gfs might have been generated VSIUnlink(CPLSPrintf("/vsimem/gmljp2/%p/my.gfs", this)); } } else { CPLDebug("GMLJP2", "No GML driver found to read feature collection"); } if( strncmp(osGMLTmpFile, "/vsicurl/", strlen("/vsicurl/")) != 0 ) VSIUnlink(osGMLTmpFile); if( osXSDTmpFile.size() ) VSIUnlink(osXSDTmpFile); } } // Find annotations psCCChildIter = psCC->psChild; int nAnnotations = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); if( !bIsGC ) continue; CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:annotation") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL || psGCorGMLJP2FeaturesChildIter->psChild->eType != CXT_Element || strstr(psGCorGMLJP2FeaturesChildIter->psChild->pszValue, "kml") == NULL ) continue; CPLDebug("GMLJP2", "Found a KML annotation"); // Create temporary .kml file CPLXMLNode* psKML = psGCorGMLJP2FeaturesChildIter->psChild; CPLString osKMLTmpFile(CPLSPrintf("/vsimem/gmljp2/%p/my.kml", this)); CPLSerializeXMLTreeToFile(psKML, osKMLTmpFile); GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osKMLTmpFile, GDAL_OF_VECTOR, NULL, NULL, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; pszLayerName = CPLSPrintf("Annotation_%d_%s", ++nAnnotations, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); } else { CPLDebug("GMLJP2", "No KML/LIBKML driver found to read annotation"); } VSIUnlink(osKMLTmpFile); } } CPLDestroyXMLNode(psRoot); }
GDALDataset *VRTDataset::OpenXML( const char *pszXML, const char *pszVRTPath, GDALAccess eAccess) { /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psTree; psTree = CPLParseXMLString( pszXML ); if( psTree == NULL ) return NULL; CPLXMLNode *psRoot = CPLGetXMLNode( psTree, "=VRTDataset" ); if (psRoot == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Missing VRTDataset element." ); CPLDestroyXMLNode( psTree ); return NULL; } if( CPLGetXMLNode( psRoot, "rasterXSize" ) == NULL || CPLGetXMLNode( psRoot, "rasterYSize" ) == NULL || CPLGetXMLNode( psRoot, "VRTRasterBand" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing one of rasterXSize, rasterYSize or bands on" " VRTDataset." ); CPLDestroyXMLNode( psTree ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the new virtual dataset object. */ /* -------------------------------------------------------------------- */ VRTDataset *poDS; int nXSize = atoi(CPLGetXMLValue(psRoot,"rasterXSize","0")); int nYSize = atoi(CPLGetXMLValue(psRoot,"rasterYSize","0")); if ( !GDALCheckDatasetDimensions(nXSize, nYSize) ) { CPLDestroyXMLNode( psTree ); return NULL; } if( strstr(pszXML,"VRTWarpedDataset") != NULL ) poDS = new VRTWarpedDataset( nXSize, nYSize ); else { poDS = new VRTDataset( nXSize, nYSize ); poDS->eAccess = eAccess; } if( poDS->XMLInit( psRoot, pszVRTPath ) != CE_None ) { delete poDS; poDS = NULL; } /* -------------------------------------------------------------------- */ /* Try to return a regular handle on the file. */ /* -------------------------------------------------------------------- */ CPLDestroyXMLNode( psTree ); return poDS; }
GDALDataset* ECRGTOCDataset::Build(const char* pszTOCFilename, CPLXMLNode* psXML, CPLString osProduct, CPLString osDiscId, const char* pszOpenInfoFilename) { CPLXMLNode* psTOC = CPLGetXMLNode(psXML, "=Table_of_Contents"); if (psTOC == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find Table_of_Contents element"); return NULL; } double dfGlobalMinX = 0, dfGlobalMinY = 0, dfGlobalMaxX = 0, dfGlobalMaxY= 0; double dfGlobalPixelXSize = 0, dfGlobalPixelYSize = 0; int bGlobalExtentValid = FALSE; ECRGTOCDataset* poDS = new ECRGTOCDataset(); int nSubDatasets = 0; int bLookForSubDataset = osProduct.size() != 0 && osDiscId.size() != 0; int nCountSubDataset = 0; poDS->SetDescription( pszOpenInfoFilename ); poDS->papszFileList = poDS->GDALDataset::GetFileList(); for(CPLXMLNode* psIter1 = psTOC->psChild; psIter1 != NULL; psIter1 = psIter1->psNext) { if (!(psIter1->eType == CXT_Element && psIter1->pszValue != NULL && strcmp(psIter1->pszValue, "product") == 0)) continue; const char* pszProductTitle = CPLGetXMLValue(psIter1, "product_title", NULL); if (pszProductTitle == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find product_title attribute"); continue; } if (bLookForSubDataset && strcmp(pszProductTitle, osProduct.c_str()) != 0) continue; for(CPLXMLNode* psIter2 = psIter1->psChild; psIter2 != NULL; psIter2 = psIter2->psNext) { if (!(psIter2->eType == CXT_Element && psIter2->pszValue != NULL && strcmp(psIter2->pszValue, "disc") == 0)) continue; const char* pszDiscId = CPLGetXMLValue(psIter2, "id", NULL); if (pszDiscId == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find id attribute"); continue; } if (bLookForSubDataset && strcmp(pszDiscId, osDiscId.c_str()) != 0) continue; nCountSubDataset ++; CPLXMLNode* psFrameList = CPLGetXMLNode(psIter2, "frame_list"); if (psFrameList == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_list element"); continue; } int nValidFrames = 0; std::vector<FrameDesc> aosFrameDesc; int nSubDatasetScale = -1; for(CPLXMLNode* psIter3 = psFrameList->psChild; psIter3 != NULL; psIter3 = psIter3->psNext) { if (!(psIter3->eType == CXT_Element && psIter3->pszValue != NULL && strcmp(psIter3->pszValue, "scale") == 0)) continue; const char* pszSize = CPLGetXMLValue(psIter3, "size", NULL); if (pszSize == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find size attribute"); continue; } int nScale = GetScaleFromString(pszSize); if (nScale <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid scale %s", pszSize); continue; } if (nValidFrames == 0) nSubDatasetScale = nScale; else nSubDatasetScale = -1; for(CPLXMLNode* psIter4 = psIter3->psChild; psIter4 != NULL; psIter4 = psIter4->psNext) { if (!(psIter4->eType == CXT_Element && psIter4->pszValue != NULL && strcmp(psIter4->pszValue, "frame") == 0)) continue; const char* pszFrameName = CPLGetXMLValue(psIter4, "name", NULL); if (pszFrameName == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find name element"); continue; } if (strlen(pszFrameName) != 18) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for name element : %s", pszFrameName); continue; } const char* pszFramePath = CPLGetXMLValue(psIter4, "frame_path", NULL); if (pszFramePath == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_path element"); continue; } const char* pszFrameZone = CPLGetXMLValue(psIter4, "frame_zone", NULL); if (pszFrameZone == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_zone element"); continue; } if (strlen(pszFrameZone) != 1) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for frame_zone element : %s", pszFrameZone); continue; } char chZone = pszFrameZone[0]; int nZone = 0; if (chZone >= '1' && chZone <= '9') nZone = chZone - '0'; else if (chZone >= 'a' && chZone <= 'h') nZone = -(chZone - 'a' + 1); else if (chZone >= 'A' && chZone <= 'H') nZone = -(chZone - 'A' + 1); else if (chZone == 'j' || chZone == 'J') nZone = -9; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for frame_zone element : %s", pszFrameZone); continue; } if (nZone == 9 || nZone == -9) { CPLError(CE_Warning, CPLE_AppDefined, "Polar zones unhandled by current implementation"); continue; } double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0, dfPixelXSize = 0, dfPixelYSize = 0; if (!GetExtent(pszFrameName, nScale, nZone, dfMinX, dfMaxX, dfMinY, dfMaxY, dfPixelXSize, dfPixelYSize)) { continue; } nValidFrames ++; const char* pszFullName = BuildFullName(pszTOCFilename, pszFramePath, pszFrameName); poDS->papszFileList = CSLAddString(poDS->papszFileList, pszFullName); if (!bGlobalExtentValid) { dfGlobalMinX = dfMinX; dfGlobalMinY = dfMinY; dfGlobalMaxX = dfMaxX; dfGlobalMaxY = dfMaxY; dfGlobalPixelXSize = dfPixelXSize; dfGlobalPixelYSize = dfPixelYSize; bGlobalExtentValid = TRUE; } else { if (dfMinX < dfGlobalMinX) dfGlobalMinX = dfMinX; if (dfMinY < dfGlobalMinY) dfGlobalMinY = dfMinY; if (dfMaxX > dfGlobalMaxX) dfGlobalMaxX = dfMaxX; if (dfMaxY > dfGlobalMaxY) dfGlobalMaxY = dfMaxY; if (dfPixelXSize < dfGlobalPixelXSize) dfGlobalPixelXSize = dfPixelXSize; if (dfPixelYSize < dfGlobalPixelYSize) dfGlobalPixelYSize = dfPixelYSize; } if (bLookForSubDataset) { FrameDesc frameDesc; frameDesc.pszName = pszFrameName; frameDesc.pszPath = pszFramePath; frameDesc.nScale = nScale; frameDesc.nZone = nZone; aosFrameDesc.push_back(frameDesc); } } } if (bLookForSubDataset) { delete poDS; if (nValidFrames == 0) return NULL; return ECRGTOCSubDataset::Build(pszProductTitle, pszDiscId, nSubDatasetScale, nCountSubDataset, pszTOCFilename, aosFrameDesc, dfGlobalMinX, dfGlobalMinY, dfGlobalMaxX, dfGlobalMaxY, dfGlobalPixelXSize, dfGlobalPixelYSize); } if (nValidFrames) { poDS->AddSubDataset(pszOpenInfoFilename, pszProductTitle, pszDiscId); nSubDatasets ++; } } } if (!bGlobalExtentValid) { delete poDS; return NULL; } if (nSubDatasets == 1) { const char* pszSubDatasetName = CSLFetchNameValue( poDS->GetMetadata("SUBDATASETS"), "SUBDATASET_1_NAME"); GDALOpenInfo oOpenInfo(pszSubDatasetName, GA_ReadOnly); delete poDS; GDALDataset* poRetDS = Open(&oOpenInfo); if (poRetDS) poRetDS->SetDescription(pszOpenInfoFilename); return poRetDS; } poDS->adfGeoTransform[0] = dfGlobalMinX; poDS->adfGeoTransform[1] = dfGlobalPixelXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfGlobalMaxY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = - dfGlobalPixelYSize; poDS->nRasterXSize = (int)(0.5 + (dfGlobalMaxX - dfGlobalMinX) / dfGlobalPixelXSize); poDS->nRasterYSize = (int)(0.5 + (dfGlobalMaxY - dfGlobalMinY) / dfGlobalPixelYSize); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); return poDS; }
int GDALJP2Metadata::ParseGMLCoverageDesc() { /* -------------------------------------------------------------------- */ /* Do we have an XML doc that is apparently a coverage */ /* description? */ /* -------------------------------------------------------------------- */ const char *pszCoverage = CSLFetchNameValue( papszGMLMetadata, "gml.root-instance" ); if( pszCoverage == NULL ) return FALSE; CPLDebug( "GDALJP2Metadata", "Found GML Box:\n%s", pszCoverage ); /* -------------------------------------------------------------------- */ /* Try parsing the XML. Wipe any namespace prefixes. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXML = CPLParseXMLString( pszCoverage ); if( psXML == NULL ) return FALSE; CPLStripXMLNamespace( psXML, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Isolate RectifiedGrid. Eventually we will need to support */ /* other georeferencing objects. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRG = CPLSearchXMLNode( psXML, "=RectifiedGrid" ); CPLXMLNode *psOriginPoint = NULL; const char *pszOffset1=NULL, *pszOffset2=NULL; if( psRG != NULL ) { psOriginPoint = CPLGetXMLNode( psRG, "origin.Point" ); CPLXMLNode *psOffset1 = CPLGetXMLNode( psRG, "offsetVector" ); if( psOffset1 != NULL ) { pszOffset1 = CPLGetXMLValue( psOffset1, "", NULL ); pszOffset2 = CPLGetXMLValue( psOffset1->psNext, "=offsetVector", NULL ); } } /* -------------------------------------------------------------------- */ /* If we are missing any of the origin or 2 offsets then give up. */ /* -------------------------------------------------------------------- */ if( psOriginPoint == NULL || pszOffset1 == NULL || pszOffset2 == NULL ) { CPLDestroyXMLNode( psXML ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract origin location. */ /* -------------------------------------------------------------------- */ OGRPoint *poOriginGeometry = NULL; const char *pszSRSName = NULL; if( psOriginPoint != NULL ) { poOriginGeometry = (OGRPoint *) OGR_G_CreateFromGMLTree( psOriginPoint ); if( poOriginGeometry != NULL && wkbFlatten(poOriginGeometry->getGeometryType()) != wkbPoint ) { delete poOriginGeometry; poOriginGeometry = NULL; } // SRS? pszSRSName = CPLGetXMLValue( psOriginPoint, "srsName", NULL ); } /* -------------------------------------------------------------------- */ /* Extract offset(s) */ /* -------------------------------------------------------------------- */ char **papszOffset1Tokens = NULL; char **papszOffset2Tokens = NULL; int bSuccess = FALSE; papszOffset1Tokens = CSLTokenizeStringComplex( pszOffset1, " ,", FALSE, FALSE ); papszOffset2Tokens = CSLTokenizeStringComplex( pszOffset2, " ,", FALSE, FALSE ); if( CSLCount(papszOffset1Tokens) >= 2 && CSLCount(papszOffset2Tokens) >= 2 && poOriginGeometry != NULL ) { adfGeoTransform[0] = poOriginGeometry->getX(); adfGeoTransform[1] = atof(papszOffset1Tokens[0]); adfGeoTransform[2] = atof(papszOffset2Tokens[0]); adfGeoTransform[3] = poOriginGeometry->getY(); adfGeoTransform[4] = atof(papszOffset1Tokens[1]); adfGeoTransform[5] = atof(papszOffset2Tokens[1]); // offset from center of pixel. adfGeoTransform[0] -= adfGeoTransform[1]*0.5; adfGeoTransform[0] -= adfGeoTransform[2]*0.5; adfGeoTransform[3] -= adfGeoTransform[4]*0.5; adfGeoTransform[3] -= adfGeoTransform[5]*0.5; bSuccess = TRUE; bHaveGeoTransform = TRUE; } CSLDestroy( papszOffset1Tokens ); CSLDestroy( papszOffset2Tokens ); if( poOriginGeometry != NULL ) delete poOriginGeometry; /* -------------------------------------------------------------------- */ /* If we still don't have an srsName, check for it on the */ /* boundedBy Envelope. Some products */ /* (ie. EuropeRasterTile23.jpx) use this as the only srsName */ /* delivery vehicle. */ /* -------------------------------------------------------------------- */ if( pszSRSName == NULL ) { pszSRSName = CPLGetXMLValue( psXML, "=FeatureCollection.boundedBy.Envelope.srsName", NULL ); } /* -------------------------------------------------------------------- */ /* If we have gotten a geotransform, then try to interprete the */ /* srsName. */ /* -------------------------------------------------------------------- */ int bNeedAxisFlip = FALSE; if( bSuccess && pszSRSName != NULL && (pszProjection == NULL || strlen(pszProjection) == 0) ) { OGRSpatialReference oSRS; if( EQUALN(pszSRSName,"epsg:",5) ) { if( oSRS.SetFromUserInput( pszSRSName ) == OGRERR_NONE ) oSRS.exportToWkt( &pszProjection ); } else if( EQUALN(pszSRSName,"urn:",4) && strstr(pszSRSName,":def:") != NULL && oSRS.importFromURN(pszSRSName) == OGRERR_NONE ) { const char *pszCode = strrchr(pszSRSName,':') + 1; oSRS.exportToWkt( &pszProjection ); // Per #2131 if( atoi(pszCode) >= 4000 && atoi(pszCode) <= 4999 ) { CPLDebug( "GMLJP2", "Request axis flip for SRS=%s", pszSRSName ); bNeedAxisFlip = TRUE; } } else if( !GMLSRSLookup( pszSRSName ) ) { CPLDebug( "GDALJP2Metadata", "Unable to evaluate SRSName=%s", pszSRSName ); } } if( pszProjection ) CPLDebug( "GDALJP2Metadata", "Got projection from GML box: %s", pszProjection ); CPLDestroyXMLNode( psXML ); psXML = NULL; /* -------------------------------------------------------------------- */ /* Do we need to flip the axes? */ /* -------------------------------------------------------------------- */ if( bNeedAxisFlip && CSLTestBoolean( CPLGetConfigOption( "GDAL_IGNORE_AXIS_ORIENTATION", "FALSE" ) ) ) { bNeedAxisFlip = FALSE; CPLDebug( "GMLJP2", "Supressed axis flipping based on GDAL_IGNORE_AXIS_ORIENTATION." ); } if( bNeedAxisFlip ) { double dfTemp; CPLDebug( "GMLJP2", "Flipping axis orientation in GMLJP2 coverage description." ); dfTemp = adfGeoTransform[0]; adfGeoTransform[0] = adfGeoTransform[3]; adfGeoTransform[3] = dfTemp; dfTemp = adfGeoTransform[1]; adfGeoTransform[1] = adfGeoTransform[4]; adfGeoTransform[4] = dfTemp; dfTemp = adfGeoTransform[2]; adfGeoTransform[2] = adfGeoTransform[5]; adfGeoTransform[5] = dfTemp; } return pszProjection != NULL && bSuccess; }
CPLErr VRTWarpedDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath ) { CPLErr eErr; /* -------------------------------------------------------------------- */ /* Initialize blocksize before calling sub-init so that the */ /* band initializers can get it from the dataset object when */ /* they are created. */ /* -------------------------------------------------------------------- */ nBlockXSize = atoi(CPLGetXMLValue(psTree,"BlockXSize","512")); nBlockYSize = atoi(CPLGetXMLValue(psTree,"BlockYSize","128")); /* -------------------------------------------------------------------- */ /* Initialize all the general VRT stuff. This will even */ /* create the VRTWarpedRasterBands and initialize them. */ /* -------------------------------------------------------------------- */ eErr = VRTDataset::XMLInit( psTree, pszVRTPath ); if( eErr != CE_None ) return eErr; /* -------------------------------------------------------------------- */ /* Find the GDALWarpOptions XML tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psOptionsTree; psOptionsTree = CPLGetXMLNode( psTree, "GDALWarpOptions" ); if( psOptionsTree == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Count not find required GDALWarpOptions in XML." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Adjust the SourceDataset in the warp options to take into */ /* account that it is relative to the VRT if appropriate. */ /* -------------------------------------------------------------------- */ int bRelativeToVRT = atoi(CPLGetXMLValue(psOptionsTree, "SourceDataset.relativeToVRT", "0" )); const char *pszRelativePath = CPLGetXMLValue(psOptionsTree, "SourceDataset", "" ); char *pszAbsolutePath; if( bRelativeToVRT ) pszAbsolutePath = CPLStrdup(CPLProjectRelativeFilename( pszVRTPath, pszRelativePath ) ); else pszAbsolutePath = CPLStrdup(pszRelativePath); CPLSetXMLValue( psOptionsTree, "SourceDataset", pszAbsolutePath ); CPLFree( pszAbsolutePath ); /* -------------------------------------------------------------------- */ /* And instantiate the warp options, and corresponding warp */ /* operation. */ /* -------------------------------------------------------------------- */ GDALWarpOptions *psWO; psWO = GDALDeserializeWarpOptions( psOptionsTree ); if( psWO == NULL ) return CE_Failure; this->eAccess = GA_Update; psWO->hDstDS = this; /* -------------------------------------------------------------------- */ /* Instantiate the warp operation. */ /* -------------------------------------------------------------------- */ poWarper = new GDALWarpOperation(); eErr = poWarper->Initialize( psWO ); if( eErr != CE_None) { /* -------------------------------------------------------------------- */ /* We are responsible for cleaning up the transformer outselves. */ /* -------------------------------------------------------------------- */ if( psWO->pTransformerArg != NULL ) GDALDestroyTransformer( psWO->pTransformerArg ); } GDALDestroyWarpOptions( psWO ); if( eErr != CE_None ) { delete poWarper; poWarper = NULL; } /* -------------------------------------------------------------------- */ /* Generate overviews, if appropriate. */ /* -------------------------------------------------------------------- */ char **papszTokens = CSLTokenizeString( CPLGetXMLValue( psTree, "OverviewList", "" )); int iOverview; for( iOverview = 0; papszTokens != NULL && papszTokens[iOverview] != NULL; iOverview++ ) { int nOvFactor = atoi(papszTokens[iOverview]); if (nOvFactor > 0) BuildOverviews( "NEAREST", 1, &nOvFactor, 0, NULL, NULL, NULL ); else CPLError(CE_Failure, CPLE_AppDefined, "Bad value for overview factor : %s", papszTokens[iOverview]); } CSLDestroy( papszTokens ); return eErr; }
CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" ); /* -------------------------------------------------------------------- */ /* Various kinds of metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; CPLSetXMLValue( psTree, "#dataType", GDALGetDataTypeName( GetRasterDataType() ) ); if( nBand > 0 ) CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) ); psMD = oMDMD.Serialize(); if( psMD != NULL ) CPLAddXMLChild( psTree, psMD ); if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( bNoDataValueSet ) { if (CPLIsNan(dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan"); else CPLSetXMLValue( psTree, "NoDataValue", CPLSPrintf( "%.14E", dfNoDataValue ) ); } if( bHideNoDataValue ) CPLSetXMLValue( psTree, "HideNoDataValue", CPLSPrintf( "%d", bHideNoDataValue ) ); if( pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", pszUnitType ); if( dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", CPLSPrintf( "%.16g", dfOffset ) ); if( dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", CPLSPrintf( "%.16g", dfScale ) ); if( eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( eColorInterp ) ); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ ) { CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category", papszCategoryNames[iEntry] ); if( psLastChild == NULL ) psCT_XML->psChild = psNode; else psLastChild->psNext = psNode; psLastChild = psNode; } } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element, "Entry" ); if( psLastChild == NULL ) psCT_XML->psChild = psEntry_XML; else psLastChild->psNext = psEntry_XML; psLastChild = psEntry_XML; poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) ); } } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ for( int iOvr = 0; iOvr < (int)apoOverviews.size(); iOvr ++ ) { CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element, "Overview" ); int bRelativeToVRT; const char *pszRelativePath; VSIStatBufL sStat; if( VSIStatExL( apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 ) { pszRelativePath = apoOverviews[iOvr].osFilename; bRelativeToVRT = FALSE; } else { pszRelativePath = CPLExtractRelativePath( pszVRTPath, apoOverviews[iOvr].osFilename, &bRelativeToVRT ); } CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath ); CPLCreateXMLNode( CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ), CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); CPLSetXMLValue( psOVR_XML, "SourceBand", CPLSPrintf("%d",apoOverviews[iOvr].nBand) ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ if( poMaskBand != NULL ) { CPLXMLNode *psBandTree = poMaskBand->SerializeToXML(pszVRTPath); if( psBandTree != NULL ) { CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element, "MaskBand" ); CPLAddXMLChild( psMaskBandElement, psBandTree ); } } return psTree; }
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath ) { /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == NULL || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue,"VRTRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char* pszBand = CPLGetXMLValue( psTree, "band", NULL); if( pszBand != NULL ) { nBand = atoi(pszBand); } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL); if( pszDataType != NULL ) { eDataType = GDALGetDataTypeByName(pszDataType); } /* -------------------------------------------------------------------- */ /* Apply any band level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL ) SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL ) bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) ); SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) ); SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL ); SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL ) { CPLXMLNode *psEntry; CSLDestroy( papszCategoryNames ); papszCategoryNames = NULL; CPLStringList oCategoryNames; for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) ) continue; oCategoryNames.AddString( (psEntry->psChild) ? psEntry->psChild->pszValue : ""); } papszCategoryNames = oCategoryNames.StealList(); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL ) { CPLXMLNode *psEntry; GDALColorTable oTable; int iEntry = 0; for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { GDALColorEntry sCEntry; sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" )); sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" )); sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" )); sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" )); oTable.SetColorEntry( iEntry++, &sCEntry ); } SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != NULL ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = NULL; psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ CPLXMLNode *psNode; for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"Overview") ) continue; /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ char *pszSrcDSName = NULL; CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename"); const char *pszFilename = psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL; if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in Overview." ); return CE_Failure; } if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL && !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO"))) { CPLError( CE_Failure, CPLE_AppDefined, "<SourceFilename> points to a MEM dataset, which is rather suspect! " "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" ); return CE_Failure; } if( pszVRTPath != NULL && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) ) { pszSrcDSName = CPLStrdup( CPLProjectRelativeFilename( pszVRTPath, pszFilename ) ); } else pszSrcDSName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Get the raster band. */ /* -------------------------------------------------------------------- */ int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1")); apoOverviews.resize( apoOverviews.size() + 1 ); apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName; apoOverviews[apoOverviews.size()-1].nBand = nSrcBand; CPLFree( pszSrcDSName ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand"); if (psMaskBandNode) psNode = psMaskBandNode->psChild; else psNode = NULL; for( ; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"VRTRasterBand") ) continue; if( ((VRTDataset*)poDS)->poMaskBand != NULL) { CPLError( CE_Warning, CPLE_AppDefined, "Illegal mask band at raster band level when a dataset mask band already exists." ); break; } const char *pszSubclass = CPLGetXMLValue( psNode, "subclass", "VRTSourcedRasterBand" ); VRTRasterBand *poBand = NULL; if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( GetDataset(), 0 ); else { CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); break; } if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None ) { SetMaskBand(poBand); } break; } return CE_None; }
CPLXMLNode *VRTWarpedDataset::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = VRTDataset::SerializeToXML( pszVRTPath ); if( psTree == NULL ) return psTree; /* -------------------------------------------------------------------- */ /* Set subclass. */ /* -------------------------------------------------------------------- */ CPLCreateXMLNode( CPLCreateXMLNode( psTree, CXT_Attribute, "subClass" ), CXT_Text, "VRTWarpedDataset" ); /* -------------------------------------------------------------------- */ /* Serialize the block size. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "BlockXSize", CPLSPrintf( "%d", nBlockXSize ) ); CPLCreateXMLElementAndValue( psTree, "BlockYSize", CPLSPrintf( "%d", nBlockYSize ) ); /* -------------------------------------------------------------------- */ /* Serialize the overview list. */ /* -------------------------------------------------------------------- */ if( nOverviewCount > 0 ) { char *pszOverviewList; int iOverview; pszOverviewList = (char *) CPLMalloc(nOverviewCount*8 + 10); pszOverviewList[0] = '\0'; for( iOverview = 0; iOverview < nOverviewCount; iOverview++ ) { int nOvFactor; nOvFactor = (int) (0.5+GetRasterXSize() / (double) papoOverviews[iOverview]->GetRasterXSize()); sprintf( pszOverviewList + strlen(pszOverviewList), "%d ", nOvFactor ); } CPLCreateXMLElementAndValue( psTree, "OverviewList", pszOverviewList ); CPLFree( pszOverviewList ); } /* ==================================================================== */ /* Serialize the warp options. */ /* ==================================================================== */ CPLXMLNode *psWOTree; if( poWarper != NULL ) { /* -------------------------------------------------------------------- */ /* We reset the destination dataset name so it doesn't get */ /* written out in the serialize warp options. */ /* -------------------------------------------------------------------- */ char *pszSavedName = CPLStrdup(GetDescription()); SetDescription(""); psWOTree = GDALSerializeWarpOptions( poWarper->GetOptions() ); CPLAddXMLChild( psTree, psWOTree ); SetDescription( pszSavedName ); CPLFree( pszSavedName ); /* -------------------------------------------------------------------- */ /* We need to consider making the source dataset relative to */ /* the VRT file if possible. Adjust accordingly. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSDS = CPLGetXMLNode( psWOTree, "SourceDataset" ); int bRelativeToVRT; char *pszRelativePath; pszRelativePath = CPLStrdup( CPLExtractRelativePath( pszVRTPath, psSDS->psChild->pszValue, &bRelativeToVRT ) ); CPLFree( psSDS->psChild->pszValue ); psSDS->psChild->pszValue = pszRelativePath; CPLCreateXMLNode( CPLCreateXMLNode( psSDS, CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); } return psTree; }
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree, const char *pszUnused ) { PamInitialize(); /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ GDALMajorObject::SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL ) { const char *pszLEHex = CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", NULL ); if( pszLEHex != NULL ) { int nBytes; GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes ); if( nBytes == 8 ) { CPL_LSBPTR64( pabyBin ); GDALPamRasterBand::SetNoDataValue( *((double *) pabyBin) ); } else { GDALPamRasterBand::SetNoDataValue( atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } CPLFree( pabyBin ); } else { GDALPamRasterBand::SetNoDataValue( atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } } GDALPamRasterBand::SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); GDALPamRasterBand::SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL)); if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL ); GDALPamRasterBand::SetColorInterpretation( GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL ) { CPLXMLNode *psEntry; char **papszCategoryNames = NULL; for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { /* Don't skeep <Category> tag with empty content */ if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) ) continue; papszCategoryNames = CSLAddString( papszCategoryNames, (psEntry->psChild) ? psEntry->psChild->pszValue : "" ); } GDALPamRasterBand::SetCategoryNames( papszCategoryNames ); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL ) { CPLXMLNode *psEntry; GDALColorTable oTable; int iEntry = 0; for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { GDALColorEntry sCEntry; sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" )); sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" )); sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" )); sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" )); oTable.SetColorEntry( iEntry++, &sCEntry ); } GDALPamRasterBand::SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Do we have a complete set of stats? */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "Minimum" ) != NULL && CPLGetXMLNode( psTree, "Maximum" ) != NULL ) { psPam->bHaveMinMax = TRUE; psPam->dfMin = atof(CPLGetXMLValue(psTree, "Minimum","0")); psPam->dfMax = atof(CPLGetXMLValue(psTree, "Maximum","0")); } if( CPLGetXMLNode( psTree, "Mean" ) != NULL && CPLGetXMLNode( psTree, "StandardDeviation" ) != NULL ) { psPam->bHaveStats = TRUE; psPam->dfMean = atof(CPLGetXMLValue(psTree, "Mean","0")); psPam->dfStdDev = atof(CPLGetXMLValue(psTree,"StandardDeviation","0")); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != NULL ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = NULL; psPam->psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* -------------------------------------------------------------------- */ /* Raster Attribute Table */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" ); if( psRAT != NULL ) { psPam->poDefaultRAT = new GDALRasterAttributeTable(); psPam->poDefaultRAT->XMLInit( psRAT, "" ); } return CE_None; }
int OGRVRTDataSource::Initialize( CPLXMLNode *psTree, const char *pszNewName, int bUpdate ) { CPLAssert( nLayers == 0 ); this->psTree = psTree; /* -------------------------------------------------------------------- */ /* Set name, and capture the directory path so we can use it */ /* for relative datasources. */ /* -------------------------------------------------------------------- */ CPLString osVRTDirectory = CPLGetPath( pszNewName ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Look for the OGRVRTDataSource node, it might be after an */ /* <xml> node. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psVRTDSXML = CPLGetXMLNode( psTree, "=OGRVRTDataSource" ); if( psVRTDSXML == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Did not find the <OGRVRTDataSource> node in the root of the document,\n" "this is not really an OGR VRT." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Determine if we must proxy layers. */ /* -------------------------------------------------------------------- */ int nOGRVRTLayerCount = CountOGRVRTLayers(psVRTDSXML); int nMaxSimultaneouslyOpened = atoi(CPLGetConfigOption("OGR_VRT_MAX_OPENED", "100")); if( nMaxSimultaneouslyOpened < 1 ) nMaxSimultaneouslyOpened = 1; if( nOGRVRTLayerCount > nMaxSimultaneouslyOpened ) poLayerPool = new OGRLayerPool(nMaxSimultaneouslyOpened); /* -------------------------------------------------------------------- */ /* Look for layers. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psLTree; for( psLTree=psVRTDSXML->psChild; psLTree != NULL; psLTree=psLTree->psNext ) { if( psLTree->eType != CXT_Element ) continue; /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRLayer *poLayer = InstanciateLayer(psLTree, osVRTDirectory, bUpdate); if( poLayer == NULL ) continue; /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRLayer **) CPLRealloc( papoLayers, sizeof(OGRLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; } return TRUE; }