/* ** Replace the default value srs value in the url with a utm zone. ** ** Steps: ** Check for default SRS key/value ** Erase it from the string ** Add a new token with the EPSG code provided. ** ** The result should be freed using CPLFree(); */ const char * LandfireClient::ReplaceSRS( int nEpsgCode, const char *pszUrl ) { int i, n; int nUrlSize = CPLStrnlen( pszUrl, 8192 ); const char *pszEpsg = CPLSPrintf( "&prj=%d", nEpsgCode ); int nEpsgSize = CPLStrnlen( pszEpsg, 8192 ); char **papszBadTokens = CSLTokenizeString2( LF_DEFAULT_SRS_TOKENS, ",", 0 ); int nBadTokenSize = 0; char *p, *q; char *pszNewUrl = CPLStrdup( pszUrl ); i = 0; do { p = strstr( pszNewUrl, papszBadTokens[i] ); nBadTokenSize = strlen( papszBadTokens[i] ); i++; } while( i < CSLCount( papszBadTokens ) && !p ); i--; if( p ) { if( nBadTokenSize < nEpsgSize ) { n = nUrlSize + nEpsgSize - nBadTokenSize + 1; CPLAssert( n > strlen( pszNewUrl ) ); pszNewUrl = (char*)CPLRealloc( pszNewUrl, sizeof( char ) * n ); /* reset p after realloc */ p = strstr( pszNewUrl, papszBadTokens[i] ); } q = p + nBadTokenSize; while( *q != '\0' ) { *(p++) = *(q++); } *p = '\0'; } else { n = nUrlSize + nEpsgSize + 1; pszNewUrl = (char*)CPLRealloc( pszNewUrl, sizeof( char ) * n ); } strcat( pszNewUrl, pszEpsg ); CSLDestroy( papszBadTokens ); return pszNewUrl; }
CPLErr GNMGenericNetwork::LoadMetadataLayer(GDALDataset * const pDS) { // read version, description, SRS, classes, rules m_poMetadataLayer = pDS->GetLayerByName(GNM_SYSLAYER_META); if(NULL == m_poMetadataLayer) { CPLError( CE_Failure, CPLE_AppDefined, "Loading of '%s' layer failed", GNM_SYSLAYER_META ); return CE_Failure; } std::map<int, GNMRule> moRules; int nRulePrefixLen = static_cast<int>(CPLStrnlen(GNM_MD_RULE, 255)); OGRFeature *poFeature; m_poMetadataLayer->ResetReading(); while ((poFeature = m_poMetadataLayer->GetNextFeature()) != NULL) { const char *pKey = poFeature->GetFieldAsString(GNM_SYSFIELD_PARAMNAME); const char *pValue = poFeature->GetFieldAsString(GNM_SYSFIELD_PARAMVALUE); CPLDebug("GNM", "Load metadata. Key: %s, value %s", pKey, pValue); if(EQUAL(pKey, GNM_MD_NAME)) { m_soName = pValue; } else if(EQUAL(pKey, GNM_MD_DESCR)) { sDescription = pValue; } else if(EQUAL(pKey, GNM_MD_SRS)) { m_soSRS = pValue; } else if(EQUAL(pKey, GNM_MD_VERSION)) { m_nVersion = atoi(pValue); } else if(EQUALN(pKey, GNM_MD_RULE, nRulePrefixLen)) { moRules[atoi(pKey + nRulePrefixLen)] = GNMRule(pValue); } OGRFeature::DestroyFeature(poFeature); } for(std::map<int, GNMRule>::iterator it = moRules.begin(); it != moRules.end(); ++it) { if(it->second.IsValid()) m_asRules.push_back(it->second); } if(m_soSRS.empty()) { // cppcheck-suppress knownConditionTrueFalse if(LoadNetworkSrs() != CE_None) return CE_Failure; } return CE_None; }
static CPLErr Resolve( CPLXMLNode * psNode, CPLXMLNode *** ppapsRoot, char *** ppapszResourceHREF, char ** papszSkip, const int bStrict ) { //for each sibling CPLXMLNode *psSibling = NULL; CPLXMLNode *psResource = NULL; CPLXMLNode *psTarget = NULL; CPLErr eReturn = CE_None, eReturned; for( psSibling = psNode; psSibling != NULL; psSibling = psSibling->psNext ) { if( psSibling->eType != CXT_Element ) continue; CPLXMLNode *psChild = psSibling->psChild; while( psChild != NULL && !( psChild->eType == CXT_Attribute && EQUAL( psChild->pszValue, "xlink:href" ) ) ) psChild = psChild->psNext; //if a child has a "xlink:href" attribute if( psChild != NULL && psChild->psChild != NULL ) { if( CSLFindString( papszSkip, psSibling->pszValue ) >= 0 ) {//Skipping a specified element eReturn = CE_Warning; continue; } static int i = 0; if( i-- == 0 ) {//a way to track progress i = 256; CPLDebug( "GML", "Resolving xlinks... (currently %s)", psChild->psChild->pszValue ); } char **papszTokens; papszTokens = CSLTokenizeString2( psChild->psChild->pszValue, "#", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if( CSLCount( papszTokens ) != 2 || strlen(papszTokens[1]) <= 0 ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_NotSupported, "Error parsing the href %s.%s", psChild->psChild->pszValue, bStrict ? "" : " Skipping..." ); CSLDestroy( papszTokens ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; continue; } //look for the resource with that URL psResource = FindTreeByURL( ppapsRoot, ppapszResourceHREF, papszTokens[0] ); if( psResource == NULL ) { CSLDestroy( papszTokens ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; continue; } //look for the element with the ID psTarget = FindElementByID( psResource, papszTokens[1] ); if( psTarget != NULL ) { //remove the xlink:href attribute CPLRemoveXMLChild( psSibling, psChild ); CPLDestroyXMLNode( psChild ); //make a copy of psTarget CPLXMLNode *psCopy = CPLCreateXMLNode( NULL, CXT_Element, psTarget->pszValue ); psCopy->psChild = CPLCloneXMLTree( psTarget->psChild ); RemoveIDs( psCopy ); //correct empty URLs in URL#id pairs if( CPLStrnlen( papszTokens[0], 1 ) > 0 ) { CorrectURLs( psCopy, papszTokens[0] ); } CPLAddXMLChild( psSibling, psCopy ); CSLDestroy( papszTokens ); } else { //element not found CSLDestroy( papszTokens ); CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_ObjectNull, "Couldn't find the element with id %s.", psChild->psChild->pszValue ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; } } //Recurse with the first child eReturned=Resolve( psSibling->psChild, ppapsRoot, ppapszResourceHREF, papszSkip, bStrict ); if( eReturned == CE_Failure ) return CE_Failure; if( eReturned == CE_Warning ) eReturn = CE_Warning; } return eReturn; }
static void CorrectURLs( CPLXMLNode * psRoot, const char *pszURL ) { if( psRoot == NULL || pszURL == NULL ) return; if( pszURL[0] == '\0' ) return; CPLXMLNode *psChild = psRoot->psChild; // check for xlink:href attribute while( psChild != NULL && !( ( psChild->eType == CXT_Attribute ) && ( EQUAL(psChild->pszValue, "xlink:href") )) ) psChild = psChild->psNext; if( psChild != NULL && !( strstr( psChild->psChild->pszValue, pszURL ) == psChild->psChild->pszValue && psChild->psChild->pszValue[strlen(pszURL)] == '#' ) ) { //href has a different url size_t nLen; char *pszNew; if( psChild->psChild->pszValue[0] == '#' ) { //empty URL: prepend the given URL nLen = CPLStrnlen( pszURL, 1024 ) + CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1; pszNew = (char *)CPLMalloc( nLen * sizeof(char)); CPLStrlcpy( pszNew, pszURL, nLen ); CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen ); CPLSetXMLValue( psRoot, "#xlink:href", pszNew ); CPLFree( pszNew ); } else { size_t nPathLen; for( nPathLen = strlen(pszURL); nPathLen > 0 && pszURL[nPathLen - 1] != '/' && pszURL[nPathLen - 1] != '\\'; nPathLen--); if( strncmp( pszURL, psChild->psChild->pszValue, nPathLen ) != 0 ) { //different path int nURLLen = strchr( psChild->psChild->pszValue, '#' ) - psChild->psChild->pszValue; char *pszURLWithoutID = (char *)CPLMalloc( (nURLLen+1) * sizeof(char)); strncpy( pszURLWithoutID, psChild->psChild->pszValue, nURLLen ); pszURLWithoutID[nURLLen] = '\0'; if( CPLIsFilenameRelative( pszURLWithoutID ) && strstr( pszURLWithoutID, ":" ) == NULL ) { //relative URL: prepend the path of pszURL nLen = nPathLen + CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1; pszNew = (char *)CPLMalloc( nLen * sizeof(char)); size_t i; for( i = 0; i < nPathLen; i++ ) pszNew[i] = pszURL[i]; pszNew[nPathLen] = '\0'; CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen ); CPLSetXMLValue( psRoot, "#xlink:href", pszNew ); CPLFree( pszNew ); } CPLFree( pszURLWithoutID ); } } } // search the child elements of psRoot for( psChild = psRoot->psChild; psChild != NULL; psChild = psChild->psNext) if( psChild->eType == CXT_Element ) CorrectURLs( psChild, pszURL ); }
SEXP ogrReadColumn(OGRLayer *poLayer, SEXP FIDs, int iField, int int64, int ENC_DEBUG) { // read feature data and return something according to the type OGRFeatureDefn *poDefn; OGRFieldDefn *poField; OGRFeature *poFeature; int iRow,nRows; SEXP ans = R_NilValue; nRows=length(FIDs); // get field data from layer installErrorHandler(); poDefn = poLayer->GetLayerDefn(); poField = poDefn->GetFieldDefn(iField); uninstallErrorHandlerAndTriggerError(); if(poField == NULL) { error("Error getting field %d ",iField); } // allocate an object for the result depending on the feature type: installErrorHandler(); switch(poField->GetType()) { case OFTInteger: PROTECT(ans=allocVector(INTSXP,nRows)); break; #ifdef GDALV2 case OFTInteger64: if (int64 ==3) { PROTECT(ans=allocVector(STRSXP,nRows)); } else { PROTECT(ans=allocVector(INTSXP,nRows)); } break; #endif case OFTReal: PROTECT(ans=allocVector(REALSXP,nRows)); break; case OFTString: PROTECT(ans=allocVector(STRSXP,nRows)); break; case OFTDate: PROTECT(ans=allocVector(STRSXP,nRows)); break; case OFTDateTime: PROTECT(ans=allocVector(STRSXP,nRows)); break; case OFTTime: PROTECT(ans=allocVector(STRSXP,nRows)); break; default: const char *desc = poField->GetFieldTypeName(poField->GetType()); uninstallErrorHandlerAndTriggerError(); error("unsupported field type: %s", desc); break; } uninstallErrorHandlerAndTriggerError(); // now go over each row and retrieve data. iRow is an index in a // vector of FIDs /*#ifndef EJP installErrorHandler(); for(iRow=0;iRow<nRows;iRow++){ poFeature=poLayer->GetFeature(INTEGER(FIDs)[iRow]); if(poFeature == NULL){ error("Error getting feature FID: %d",(INTEGER(FIDs)[iRow])); } } uninstallErrorHandlerAndTriggerError(); #else*/ // EJP, changed into: installErrorHandler(); poLayer->ResetReading(); iRow = 0; while((poFeature = poLayer->GetNextFeature()) != NULL) { //#endif // now get the value using the right type: switch(poField->GetType()) { case OFTInteger: if (poFeature->IsFieldSet(iField)) INTEGER(ans)[iRow]=poFeature->GetFieldAsInteger(iField); else INTEGER(ans)[iRow]=NA_INTEGER; break; #ifdef GDALV2 case OFTInteger64: if (poFeature->IsFieldSet(iField)) { if (int64 == 3) { SET_STRING_ELT(ans, iRow, mkChar(poFeature->GetFieldAsString(iField))); } else { GIntBig nVal64 = poFeature->GetFieldAsInteger64(iField); int nVal = (nVal64 > INT_MAX) ? INT_MAX : (nVal64 < INT_MIN) ? INT_MIN : (int) nVal64; INTEGER(ans)[iRow]=nVal; if (((GIntBig)nVal != nVal64) && int64 == 2) { warning("Integer64 value clamped: feature %d", iRow); } } } else { if (int64 == 3) { SET_STRING_ELT(ans, iRow, NA_STRING); } else { INTEGER(ans)[iRow]=NA_INTEGER; } } break; #endif case OFTReal: if (poFeature->IsFieldSet(iField)) REAL(ans)[iRow]=poFeature->GetFieldAsDouble(iField); else REAL(ans)[iRow]=NA_REAL; break; case OFTString: // ENC char str[4096]; size_t stln; if (poFeature->IsFieldSet(iField)) { stln = CPLStrnlen(poFeature->GetFieldAsString(iField), 4096); CPLStrlcpy(str, (const char *) poFeature->GetFieldAsString(iField), 4096); SET_STRING_ELT(ans, iRow, mkChar(str)); } else SET_STRING_ELT(ans, iRow, NA_STRING); if (ENC_DEBUG) { Rprintf("iField: %d, iRow: %d stln %u Enc %s ", iField, iRow, stln, CPLIsUTF8(str, (int) stln)?"UTF-8":"other"); for (int si=0; si < (int) stln; si++) Rprintf("%x ", (unsigned char) str[si]); Rprintf("\n"); } /* FIXME */ break; case OFTDate: if (poFeature->IsFieldSet(iField)) SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField))); else SET_STRING_ELT(ans, iRow, NA_STRING); break; case OFTDateTime: if (poFeature->IsFieldSet(iField)) SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField))); else SET_STRING_ELT(ans, iRow, NA_STRING); break; case OFTTime: if (poFeature->IsFieldSet(iField)) SET_STRING_ELT(ans,iRow,mkChar(poFeature->GetFieldAsString(iField))); else SET_STRING_ELT(ans, iRow, NA_STRING); break; default: OGRFeature::DestroyFeature( poFeature ); // delete poFeature; uninstallErrorHandlerAndTriggerError(); error("Unsupported field type. should have been caught before"); } OGRFeature::DestroyFeature( poFeature ); // delete poFeature; //#ifdef EJP // according to tutorial: OGRFeature::DestroyFeature(poFeature); // see comment FW in OGR tutorial: We could just "delete" it, // but this can cause problems in windows builds where the GDAL DLL // has a different "heap" from the main program. To be on the safe // side we use a GDAL function to delete the feature. iRow++; //#endif } uninstallErrorHandlerAndTriggerError(); UNPROTECT(1); return(ans); }
OGRErr OGRKMLLayer::ICreateFeature( OGRFeature* poFeature ) { CPLAssert( NULL != poFeature ); CPLAssert( NULL != poDS_ ); if( !bWriter_ ) return OGRERR_FAILURE; if( bClosedForWriting ) { CPLError(CE_Failure, CPLE_NotSupported, "Interleaved feature adding to different layers is not supported"); return OGRERR_FAILURE; } VSILFILE *fp = poDS_->GetOutputFP(); CPLAssert( NULL != fp ); if( poDS_->GetLayerCount() == 1 && nWroteFeatureCount_ == 0 ) { CPLString osRet = WriteSchema(); if( osRet.size() ) VSIFPrintfL( fp, "%s", osRet.c_str() ); bSchemaWritten_ = TRUE; VSIFPrintfL( fp, "<Folder><name>%s</name>\n", pszName_); } VSIFPrintfL( fp, " <Placemark>\n" ); if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( iNextKMLId_++ ); // Find and write the name element if (NULL != poDS_->GetNameField()) { for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && EQUAL(poField->GetNameRef(), poDS_->GetNameField()) ) { const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); VSIFPrintfL( fp, "\t<name>%s</name>\n", pszEscaped); CPLFree( pszEscaped ); } } } if (NULL != poDS_->GetDescriptionField()) { for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && EQUAL(poField->GetNameRef(), poDS_->GetDescriptionField()) ) { const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); VSIFPrintfL( fp, "\t<description>%s</description>\n", pszEscaped); CPLFree( pszEscaped ); } } } OGRwkbGeometryType eGeomType = wkbNone; if (poFeature->GetGeometryRef() != NULL) eGeomType = wkbFlatten(poFeature->GetGeometryRef()->getGeometryType()); if ( wkbPolygon == eGeomType || wkbMultiPolygon == eGeomType || wkbLineString == eGeomType || wkbMultiLineString == eGeomType ) { OGRStylePen *poPen = NULL; OGRStyleMgr oSM; if( poFeature->GetStyleString() != NULL ) { oSM.InitFromFeature( poFeature ); int i; for(i=0; i<oSM.GetPartCount();i++) { OGRStyleTool *poTool = oSM.GetPart(i); if (poTool && poTool->GetType() == OGRSTCPen ) { poPen = (OGRStylePen*) poTool; break; } delete poTool; } } VSIFPrintfL( fp, "\t<Style>"); if( poPen != NULL ) { GBool bDefault; int bHasWidth = FALSE; /* Require width to be returned in pixel */ poPen->SetUnit(OGRSTUPixel); double fW = poPen->Width(bDefault); if( bDefault ) fW = 1; else bHasWidth = TRUE; const char* pszColor = poPen->Color(bDefault); int nColorLen = static_cast<int>(CPLStrnlen(pszColor, 10)); if( pszColor != NULL && pszColor[0] == '#' && !bDefault && nColorLen >= 7) { char acColor[9] = {0}; /* Order of KML color is aabbggrr, whereas OGR color is #rrggbb[aa] ! */ if(nColorLen == 9) { acColor[0] = pszColor[7]; /* A */ acColor[1] = pszColor[8]; } else { acColor[0] = 'F'; acColor[1] = 'F'; } acColor[2] = pszColor[5]; /* B */ acColor[3] = pszColor[6]; acColor[4] = pszColor[3]; /* G */ acColor[5] = pszColor[4]; acColor[6] = pszColor[1]; /* R */ acColor[7] = pszColor[2]; VSIFPrintfL( fp, "<LineStyle><color>%s</color>", acColor); if (bHasWidth) VSIFPrintfL( fp, "<width>%g</width>", fW); VSIFPrintfL( fp, "</LineStyle>"); } else VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>"); } else VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>"); delete poPen; //If we're dealing with a polygon, add a line style that will stand out a bit VSIFPrintfL( fp, "<PolyStyle><fill>0</fill></PolyStyle></Style>\n" ); } int bHasFoundOtherField = FALSE; // Write all fields as SchemaData for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ ) { OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField )) { if (NULL != poDS_->GetNameField() && EQUAL(poField->GetNameRef(), poDS_->GetNameField()) ) continue; if (NULL != poDS_->GetDescriptionField() && EQUAL(poField->GetNameRef(), poDS_->GetDescriptionField()) ) continue; if (!bHasFoundOtherField) { VSIFPrintfL( fp, "\t<ExtendedData><SchemaData schemaUrl=\"#%s\">\n", pszName_ ); bHasFoundOtherField = TRUE; } const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped; if (poFeatureDefn_->GetFieldDefn(iField)->GetType() == OFTReal) { pszEscaped = CPLStrdup( pszRaw ); } else { pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); } VSIFPrintfL( fp, "\t\t<SimpleData name=\"%s\">%s</SimpleData>\n", poField->GetNameRef(), pszEscaped); CPLFree( pszEscaped ); } } if (bHasFoundOtherField) { VSIFPrintfL( fp, "\t</SchemaData></ExtendedData>\n" ); } // Write out Geometry - for now it isn't indented properly. if( poFeature->GetGeometryRef() != NULL ) { char* pszGeometry = NULL; OGREnvelope sGeomBounds; OGRGeometry* poWGS84Geom; if (NULL != poCT_) { poWGS84Geom = poFeature->GetGeometryRef()->clone(); poWGS84Geom->transform( poCT_ ); } else { poWGS84Geom = poFeature->GetGeometryRef(); } // TODO - porting // pszGeometry = poFeature->GetGeometryRef()->exportToKML(); pszGeometry = OGR_G_ExportToKML( (OGRGeometryH)poWGS84Geom, poDS_->GetAltitudeMode()); VSIFPrintfL( fp, " %s\n", pszGeometry ); CPLFree( pszGeometry ); poWGS84Geom->getEnvelope( &sGeomBounds ); poDS_->GrowExtents( &sGeomBounds ); if (NULL != poCT_) { delete poWGS84Geom; } } VSIFPrintfL( fp, " </Placemark>\n" ); nWroteFeatureCount_++; return OGRERR_NONE; }