OGR_SRSNode *OGR_SRSNode::Clone() const { OGR_SRSNode *poNew = new OGR_SRSNode( pszValue ); for( int i = 0; i < nChildren; i++ ) { poNew->AddChild( papoChildNodes[i]->Clone() ); } return poNew; }
/** * \brief Validate the current VERT_DATUM's arguments. * * @return OGRERR_NONE if the VERT_DATUM's arguments validate, an error code * otherwise */ OGRErr OGRSpatialReference::ValidateVertDatum(OGR_SRSNode *poRoot) { if ( !EQUAL(poRoot->GetValue(), "VERT_DATUM") ) return OGRERR_NONE; if (poRoot->GetChildCount() < 2 ) { CPLDebug( "OGRSpatialReference::Validate", "Invalid number of children : %d", poRoot->GetChildCount() ); return OGRERR_CORRUPT_DATA; } if (atoi(poRoot->GetChild(1)->GetValue()) == 0) { CPLDebug( "OGRSpatialReference::Validate", "Invalid value for datum type (%s) : must be a number\n", poRoot->GetChild(1)->GetValue()); return OGRERR_CORRUPT_DATA; } OGR_SRSNode *poNode; int i; for( i = 2; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"EXTENSION") ) { // We do not try to control the sub-organization of // EXTENSION nodes. } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for VERT_DATUM `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } return OGRERR_NONE; }
std::string CSpatialReference::GetProjName() const { if(!m_Handle) { return ""; } OGRSpatialReference* psr = (OGRSpatialReference*)m_Handle; //查找GEOGCS节点 OGR_SRSNode *pNode =psr->GetAttrNode("PROJCS"); if(!pNode) { return ""; } return pNode->GetChild(0)->GetValue(); }
std::string SpatialReference::getVertical() const { std::string tmp(""); OGRSpatialReference* poSRS = (OGRSpatialReference*)OSRNewSpatialReference(m_wkt.c_str()); char *pszWKT = NULL; OGR_SRSNode* node = poSRS->GetAttrNode("VERT_CS"); if (node && poSRS) { node->exportToWkt(&pszWKT); tmp = pszWKT; CPLFree(pszWKT); OSRDestroySpatialReference(poSRS); } return tmp; }
void ProjectionDlg::OnItemRightClick( wxListEvent &event ) { int item_clicked = event.GetIndex(); OGR_SRSNode *root = m_proj.GetRoot(); OGR_SRSNode *node, *par1, *par2; const char *value; int children = root->GetChildCount(); int i, item = 0; wxString str; for (i = 0; i < children; i++) { node = root->GetChild(i); value = node->GetValue(); if (strcmp(value, "PARAMETER")) continue; par1 = node->GetChild(0); par2 = node->GetChild(1); value = par2->GetValue(); if (item == item_clicked) { wxString caption = _("Value for "); str = wxString(par1->GetValue(), wxConvUTF8); caption += str; str = wxString(value, wxConvUTF8); wxString result = wxGetTextFromUser(caption, _("Enter new value"), str, this); if (result != _T("")) { // double newval = atof((const char *)result); par2->SetValue(result.mb_str(wxConvUTF8)); DisplayProjectionSpecificParams(); return; } } item++; } }
void ProjectionDlg::DisplayProjectionSpecificParams() { m_pParamCtrl->DeleteAllItems(); OGR_SRSNode *root = m_proj.GetRoot(); if (!root) { m_pParamCtrl->InsertItem(0, _("(Invalid projection)")); return; // bogus projection } OGR_SRSNode *node, *par1, *par2; const char *value; int children = root->GetChildCount(); int i, item = 0; wxString str; for (i = 0; i < children; i++) { node = root->GetChild(i); value = node->GetValue(); if (!strcmp(value, "PARAMETER")) { par1 = node->GetChild(0); value = par1->GetValue(); str = wxString(value, wxConvUTF8); item = m_pParamCtrl->InsertItem(item, str); par2 = node->GetChild(1); value = par2->GetValue(); str = wxString(value, wxConvUTF8); m_pParamCtrl->SetItem(item, 1, str); item++; } } }
/** * \brief Validate the current PROJECTION's arguments. * * @return OGRERR_NONE if the PROJECTION's arguments validate, an error code * otherwise */ OGRErr OGRSpatialReference::ValidateProjection(OGR_SRSNode *poRoot) { OGR_SRSNode *poPROJCS = poRoot->GetNode( "PROJCS" ); if( poPROJCS == NULL ) return OGRERR_NONE; if( poPROJCS->GetNode( "PROJECTION" ) == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "PROJCS does not have PROJECTION subnode." ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Find the matching group in the proj and parms table. */ /* -------------------------------------------------------------------- */ const char *pszProjection; int iOffset; pszProjection = poPROJCS->GetNode("PROJECTION")->GetChild(0)->GetValue(); for( iOffset = 0; papszProjWithParms[iOffset] != NULL && !EQUAL(papszProjWithParms[iOffset],pszProjection); ) { while( papszProjWithParms[iOffset] != NULL ) iOffset++; iOffset++; } if( papszProjWithParms[iOffset] == NULL ) return OGRERR_UNSUPPORTED_SRS; iOffset++; /* -------------------------------------------------------------------- */ /* Check all parameters, and verify they are in the permitted */ /* list. */ /* -------------------------------------------------------------------- */ int iNode; for( iNode = 0; iNode < poPROJCS->GetChildCount(); iNode++ ) { OGR_SRSNode *poParm = poPROJCS->GetChild(iNode); int i; const char *pszParmName; if( !EQUAL(poParm->GetValue(),"PARAMETER") ) continue; pszParmName = poParm->GetChild(0)->GetValue(); for( i = iOffset; papszProjWithParms[i] != NULL; i++ ) { if( EQUAL(papszProjWithParms[i],pszParmName) ) break; } /* This parameter is not an exact match, is it an alias? */ if( papszProjWithParms[i] == NULL ) { for( i = iOffset; papszProjWithParms[i] != NULL; i++ ) { if( IsAliasFor(papszProjWithParms[i],pszParmName) ) break; } if( papszProjWithParms[i] == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER %s for PROJECTION %s is not permitted.", pszParmName, pszProjection ); return OGRERR_CORRUPT_DATA; } else { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER %s for PROJECTION %s is an alias for %s.", pszParmName, pszProjection, papszProjWithParms[i] ); return OGRERR_CORRUPT_DATA; } } } return OGRERR_NONE; }
OGRBoolean CheckCitationKeyForStatePlaneUTM(GTIF* hGTIF, GTIFDefn* psDefn, OGRSpatialReference* poSRS, OGRBoolean* pLinearUnitIsSet) { if( !hGTIF || !psDefn || !poSRS ) return FALSE; /* -------------------------------------------------------------------- */ /* For ESRI builds we are interested in maximizing PE */ /* compatability, but generally we prefer to use EPSG */ /* definitions of the coordinate system if PCS is defined. */ /* -------------------------------------------------------------------- */ #if !defined(ESRI_BUILD) if( psDefn->PCS != KvUserDefined ) return FALSE; #endif char szCTString[512]; szCTString[0] = '\0'; /* Check units */ char units[32]; units[0] = '\0'; OGRBoolean hasUnits = FALSE; if( GTIFKeyGet( hGTIF, GTCitationGeoKey, szCTString, 0, sizeof(szCTString) ) ) { CPLString osLCCT = szCTString; osLCCT.tolower(); if( strstr(osLCCT,"us") && strstr(osLCCT,"survey") && (strstr(osLCCT,"feet") || strstr(osLCCT,"foot")) ) strcpy(units, "us_survey_feet"); else if(strstr(osLCCT, "linear_feet") || strstr(osLCCT, "linear_foot") || strstr(osLCCT, "international")) strcpy(units, "international_feet"); else if( strstr(osLCCT,"meter") ) strcpy(units, "meters"); if (strlen(units) > 0) hasUnits = TRUE; if( strstr( szCTString, "Projection Name = ") && strstr( szCTString, "_StatePlane_")) { const char *pStr = strstr( szCTString, "Projection Name = ") + strlen("Projection Name = "); const char* pReturn = strchr( pStr, '\n'); char CSName[128]; strncpy(CSName, pStr, pReturn-pStr); CSName[pReturn-pStr] = '\0'; if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, NULL, 32767, CSName) == OGRERR_NONE ) { // for some erdas citation keys, the state plane CS name is incomplete, the unit check is necessary. OGRBoolean done = FALSE; if (hasUnits) { OGR_SRSNode *poUnit = poSRS->GetAttrNode( "PROJCS|UNIT" ); if( poUnit != NULL && poUnit->GetChildCount() >= 2 ) { CPLString unitName = poUnit->GetChild(0)->GetValue(); unitName.tolower(); if (strstr(units, "us_survey_feet")) { if (strstr(unitName, "us_survey_feet") || strstr(unitName, "foot_us") ) done = TRUE; } else if (strstr(units, "international_feet")) { if (strstr(unitName, "feet") || strstr(unitName, "foot")) done = TRUE; } else if (strstr(units, "meters")) { if (strstr(unitName, "meter") ) done = TRUE; } } } if (done) return TRUE; } } } if( !hasUnits ) { char *pszUnitsName = NULL; GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszUnitsName, NULL ); if( pszUnitsName && strlen(pszUnitsName) > 0 ) { CPLString osLCCT = pszUnitsName; GTIFFreeMemory( pszUnitsName ); osLCCT.tolower(); if( strstr(osLCCT, "us") && strstr(osLCCT, "survey") && (strstr(osLCCT, "feet") || strstr(osLCCT, "foot"))) strcpy(units, "us_survey_feet"); else if(strstr(osLCCT, "feet") || strstr(osLCCT, "foot")) strcpy(units, "international_feet"); else if(strstr(osLCCT, "meter")) strcpy(units, "meters"); hasUnits = TRUE; } } if (strlen(units) == 0) strcpy(units, "meters"); /* check PCSCitationGeoKey if it exists */ szCTString[0] = '\0'; if( hGTIF && GTIFKeyGet( hGTIF, PCSCitationGeoKey, szCTString, 0, sizeof(szCTString)) ) { /* For tif created by LEICA(ERDAS), ESRI state plane pe string was used and */ /* the state plane zone is given in PCSCitation. Therefore try Esri pe string first. */ SetCitationToSRS(hGTIF, szCTString, strlen(szCTString), PCSCitationGeoKey, poSRS, pLinearUnitIsSet); const char *pcsName = poSRS->GetAttrValue("PROJCS"); const char *pStr = NULL; if( (pcsName && (pStr = strstr(pcsName, "State Plane Zone ")) != NULL) || (pStr = strstr(szCTString, "State Plane Zone ")) != NULL ) { pStr += strlen("State Plane Zone "); int statePlaneZone = abs(atoi(pStr)); char nad[32]; strcpy(nad, "HARN"); if( strstr(szCTString, "NAD83") || strstr(szCTString, "NAD = 83") ) strcpy(nad, "NAD83"); else if( strstr(szCTString, "NAD27") || strstr(szCTString, "NAD = 27") ) strcpy(nad, "NAD27"); if( poSRS->ImportFromESRIStatePlaneWKT(statePlaneZone, (const char*)nad, (const char*)units, psDefn->PCS) == OGRERR_NONE ) return TRUE; } else if( pcsName && (pStr = strstr(pcsName, "UTM Zone ")) != NULL ) CheckUTM( psDefn, szCTString ); } /* check state plane again to see if a pe string is available */ if( psDefn->PCS != KvUserDefined ) { if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, (const char*)units, psDefn->PCS) == OGRERR_NONE ) return TRUE; } return FALSE; }
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn, OGRSpatialReference * poTargetIn ) { if( poSourceIn == NULL || poTargetIn == NULL ) return FALSE; poSRSSource = poSourceIn->Clone(); poSRSTarget = poTargetIn->Clone(); bSourceLatLong = poSRSSource->IsGeographic(); bTargetLatLong = poSRSTarget->IsGeographic(); /* -------------------------------------------------------------------- */ /* Setup source and target translations to radians for lat/long */ /* systems. */ /* -------------------------------------------------------------------- */ dfSourceToRadians = DEG_TO_RAD; bSourceWrap = FALSE; dfSourceWrapLong = 0.0; if( bSourceLatLong ) { OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { dfSourceToRadians = atof(poUNITS->GetChild(1)->GetValue()); if( dfSourceToRadians == 0.0 ) dfSourceToRadians = DEG_TO_RAD; } } dfTargetFromRadians = RAD_TO_DEG; bTargetWrap = FALSE; dfTargetWrapLong = 0.0; if( bTargetLatLong ) { OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { double dfTargetToRadians = atof(poUNITS->GetChild(1)->GetValue()); if( dfTargetToRadians != 0.0 ) dfTargetFromRadians = 1 / dfTargetToRadians; } } /* -------------------------------------------------------------------- */ /* Preliminary logic to setup wrapping. */ /* -------------------------------------------------------------------- */ const char *pszCENTER_LONG; if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL ) { bSourceWrap = bTargetWrap = TRUE; dfSourceWrapLong = dfTargetWrapLong = atof(CPLGetConfigOption( "CENTER_LONG", "" )); CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong ); } pszCENTER_LONG = poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfSourceWrapLong = atof(pszCENTER_LONG); bSourceWrap = TRUE; CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong ); } pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfTargetWrapLong = atof(pszCENTER_LONG); bTargetWrap = TRUE; CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong ); } bCheckWithInvertProj = CSLTestBoolean(CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", "NO" )); /* The threshold is rather experimental... Works well with the cases of ticket #2305 */ if (bSourceLatLong) dfThreshold = atof(CPLGetConfigOption( "THRESHOLD", ".1" )); else /* 1 works well for most projections, except for +proj=aeqd that requires */ /* a tolerance of 10000 */ dfThreshold = atof(CPLGetConfigOption( "THRESHOLD", "10000" )); /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for source if projection. */ /* -------------------------------------------------------------------- */ // OGRThreadSafety: The following variable is not a thread safety issue // since the only issue is incrementing while accessing which at worse // means debug output could be one "increment" late. static int nDebugReportCount = 0; char *pszSrcProj4Defn = NULL; if( poSRSSource->exportToProj4( &pszSrcProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); return FALSE; } if( strlen(pszSrcProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for source SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } if (pjctx) psPJSource = pfn_pj_init_plus_ctx( pjctx, pszSrcProj4Defn ); else psPJSource = pfn_pj_init_plus( pszSrcProj4Defn ); if( psPJSource == NULL ) { if( pjctx != NULL) { int pj_errno = pfn_pj_ctx_get_errno(pjctx); /* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */ CPLMutexHolderD(&hPROJMutex); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(pj_errno) ); } else if( pfn_pj_get_errno_ref != NULL && pfn_pj_strerrno != NULL ) { int *p_pj_errno = pfn_pj_get_errno_ref(); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(*p_pj_errno) ); } else { CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n", pszSrcProj4Defn ); } } if( nDebugReportCount < 10 ) CPLDebug( "OGRCT", "Source: %s", pszSrcProj4Defn ); if( psPJSource == NULL ) { CPLFree( pszSrcProj4Defn ); return FALSE; } /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for target if projection. */ /* -------------------------------------------------------------------- */ char *pszDstProj4Defn = NULL; if( poSRSTarget->exportToProj4( &pszDstProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } if( strlen(pszDstProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for destination SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } if (pjctx) psPJTarget = pfn_pj_init_plus_ctx( pjctx, pszDstProj4Defn ); else psPJTarget = pfn_pj_init_plus( pszDstProj4Defn ); if( psPJTarget == NULL ) CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.", pszDstProj4Defn ); if( nDebugReportCount < 10 ) { CPLDebug( "OGRCT", "Target: %s", pszDstProj4Defn ); nDebugReportCount++; } if( psPJTarget == NULL ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } /* Determine if we really have a transformation to do */ bIdentityTransform = (strcmp(pszSrcProj4Defn, pszDstProj4Defn) == 0); /* In case of identity transform, under the following conditions, */ /* we can also avoid transforming from deegrees <--> radians. */ if( bIdentityTransform && bSourceLatLong && !bSourceWrap && bTargetLatLong && !bTargetWrap && abs(dfSourceToRadians * dfTargetFromRadians - 1.0) < 1e-10 ) { /*bSourceLatLong = FALSE; bTargetLatLong = FALSE;*/ } CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return TRUE; }
bool rspfOgcWktTranslator::toOssimKwl( const rspfString& wktString, rspfKeywordlist &kwl, const char *prefix)const { static const char MODULE[] = "rspfOgcWktTranslator::toOssimKwl"; if(traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << MODULE << " entered...\n"; } const char* wkt = wktString.c_str(); OGRSpatialReferenceH hSRS = NULL; rspfDpt falseEastingNorthing; hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, (char **) &wkt ) != OGRERR_NONE ) { OSRDestroySpatialReference( hSRS ); return false; } rspfString rspfProj = ""; const char* epsg_code = OSRGetAttrValue( hSRS, "AUTHORITY", 1 ); if(traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << "epsg_code: " << (epsg_code?epsg_code:"null") << "\n"; } const char* units = NULL; OGR_SRSNode* node = ((OGRSpatialReference *)hSRS)->GetRoot(); int nbChild = node->GetChildCount(); for (int i = 0; i < nbChild; i++) { OGR_SRSNode* curChild = node->GetChild(i); if (strcmp(curChild->GetValue(), "UNIT") == 0) { units = curChild->GetChild(0)->GetValue(); } } if(traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << "units: " << (units?units:"null") << "\n"; } rspfString rspf_units; bool bGeog = OSRIsGeographic(hSRS); if ( bGeog == false ) { rspf_units = "meters"; if ( units != NULL ) { rspfString s = units; s.downcase(); if( ( s == rspfString("us survey foot") ) || ( s == rspfString("u.s. foot") ) || ( s == rspfString("foot_us") ) ) { rspf_units = "us_survey_feet"; } else if( s == rspfString("degree") ) { rspf_units = "degrees"; } else if( ( s == rspfString("meter") ) || ( s == rspfString("metre") ) ) { rspf_units = "meters"; } } } else { rspf_units = "degrees"; } if(traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << "rspf_units: " << rspf_units << "\n"; } if (epsg_code) { rspfString epsg_spec ("EPSG:"); epsg_spec += rspfString::toString(epsg_code); rspfProjection* proj = rspfEpsgProjectionFactory::instance()->createProjection(epsg_spec); if (proj) rspfProj = proj->getClassName(); delete proj; } if(rspfProj == "") { const char* pszProjection = OSRGetAttrValue( hSRS, "PROJECTION", 0 ); if(pszProjection) { rspfProj = wktToOssimProjection(pszProjection); } else { rspfString localCs = OSRGetAttrValue( hSRS, "LOCAL_CS", 0 ); localCs = localCs.upcase(); if(localCs == "GREATBRITAIN_GRID") { rspfProj = "rspfBngProjection"; } else if (rspf_units.contains("degree")) { rspfProj = "rspfEquDistCylProjection"; } } } if(rspfProj == "rspfEquDistCylProjection" ) rspf_units = "degrees"; kwl.add(prefix, rspfKeywordNames::UNITS_KW, rspf_units, true); if (traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << MODULE << "DEBUG:" << "\nrspfProj = " << rspfProj << endl; } kwl.add(prefix, rspfKeywordNames::TYPE_KW, rspfProj.c_str(), true); falseEastingNorthing.x = OSRGetProjParm(hSRS, SRS_PP_FALSE_EASTING, 0.0, NULL); falseEastingNorthing.y = OSRGetProjParm(hSRS, SRS_PP_FALSE_NORTHING, 0.0, NULL); if (epsg_code) { kwl.add(prefix, rspfKeywordNames::PCS_CODE_KW, epsg_code, true); } if(rspfProj == "rspfBngProjection") { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfBngProjection", true); } else if(rspfProj == "rspfCylEquAreaProjection") { kwl.add(prefix, rspfKeywordNames::STD_PARALLEL_1_KW, OSRGetProjParm(hSRS, SRS_PP_STANDARD_PARALLEL_1, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW, OSRGetProjParm(hSRS, SRS_PP_STANDARD_PARALLEL_1, 0.0, NULL), true); rspfUnitType units = static_cast<rspfUnitType>(rspfUnitTypeLut::instance()-> getEntryNumber(rspf_units.c_str())); if ( units == RSPF_METERS || units == RSPF_FEET || units == RSPF_US_SURVEY_FEET ) { kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); } } else if(rspfProj == "rspfEquDistCylProjection") { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfEquDistCylProjection", true); rspfUnitType units = static_cast<rspfUnitType>(rspfUnitTypeLut::instance()-> getEntryNumber(rspf_units.c_str())); if ( units == RSPF_METERS || units == RSPF_FEET || units == RSPF_US_SURVEY_FEET ) { kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); } kwl.add(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW, OSRGetProjParm(hSRS, SRS_PP_LATITUDE_OF_ORIGIN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW, OSRGetProjParm(hSRS, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL), true); } else if( (rspfProj == "rspfLambertConformalConicProjection") || (rspfProj == "rspfAlbersProjection") ) { kwl.add(prefix, rspfKeywordNames::TYPE_KW, rspfProj.c_str(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); kwl.add(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW, OSRGetProjParm(hSRS, SRS_PP_LATITUDE_OF_ORIGIN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW, OSRGetProjParm(hSRS, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::STD_PARALLEL_1_KW, OSRGetProjParm(hSRS, SRS_PP_STANDARD_PARALLEL_1, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::STD_PARALLEL_2_KW, OSRGetProjParm(hSRS, SRS_PP_STANDARD_PARALLEL_2, 0.0, NULL), true); } else if(rspfProj == "rspfMercatorProjection") { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfMercatorProjection", true); kwl.add(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW, OSRGetProjParm(hSRS, SRS_PP_LATITUDE_OF_ORIGIN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW, OSRGetProjParm(hSRS, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); } else if(rspfProj == "rspfSinusoidalProjection") { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfSinusoidalProjection", true); kwl.add(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW, OSRGetProjParm(hSRS, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); } else if(rspfProj == "rspfTransMercatorProjection") { int bNorth; int nZone = OSRGetUTMZone( hSRS, &bNorth ); if( nZone != 0 ) { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfUtmProjection", true); kwl.add(prefix, rspfKeywordNames::ZONE_KW, nZone, true); if( bNorth ) { kwl.add(prefix, rspfKeywordNames::HEMISPHERE_KW, "N", true); } else { kwl.add(prefix, rspfKeywordNames::HEMISPHERE_KW, "S", true); } } else { kwl.add(prefix, rspfKeywordNames::TYPE_KW, "rspfTransMercatorProjection", true); kwl.add(prefix, rspfKeywordNames::SCALE_FACTOR_KW, OSRGetProjParm(hSRS, SRS_PP_SCALE_FACTOR, 1.0, NULL), true); kwl.add(prefix, rspfKeywordNames::ORIGIN_LATITUDE_KW, OSRGetProjParm(hSRS, SRS_PP_LATITUDE_OF_ORIGIN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::CENTRAL_MERIDIAN_KW, OSRGetProjParm(hSRS, SRS_PP_CENTRAL_MERIDIAN, 0.0, NULL), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_KW, falseEastingNorthing.toString(), true); kwl.add(prefix, rspfKeywordNames::FALSE_EASTING_NORTHING_UNITS_KW, rspf_units, true); } } else { if (traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << "rspfOgcWktTranslator::toOssimKwl DEBUG:\n" << "Projection conversion to RSPF not supported !!!!!!!!!\n" << "Please send the following string to the development staff\n" << "to be added to the transaltion to RSPF\n" << wkt << endl; } return false; } const char *datum = OSRGetAttrValue( hSRS, "DATUM", 0 ); rspfString oDatum = "WGE"; if( datum ) { oDatum = wktToOssimDatum(datum); if(oDatum == "") { oDatum = "WGE"; } } kwl.add(prefix, rspfKeywordNames::DATUM_KW, oDatum, true); OSRDestroySpatialReference( hSRS ); if (traceDebug()) { rspfNotify(rspfNotifyLevel_DEBUG) << MODULE << " exit status = true" << std::endl; } return true; }
static int WFS_ExprDumpAsOGCFilter(CPLString& osFilter, const swq_expr_node* poExpr, int bExpectBinary, ExprDumpFilterOptions* psOptions) { if( poExpr->eNodeType == SNT_COLUMN ) { if (bExpectBinary) return FALSE; /* Special fields not understood by server */ if (EQUAL(poExpr->string_value, "gml_id") || EQUAL(poExpr->string_value, "FID") || EQUAL(poExpr->string_value, "OGR_GEOMETRY") || EQUAL(poExpr->string_value, "OGR_GEOM_WKT") || EQUAL(poExpr->string_value, "OGR_GEOM_AREA") || EQUAL(poExpr->string_value, "OGR_STYLE")) { CPLDebug("WFS", "Attribute refers to a OGR special field. Cannot use server-side filtering"); return FALSE; } const char* pszFieldname = NULL; int nIndex; int bSameTable = psOptions->poFDefn != NULL && ( poExpr->table_name == NULL || EQUAL(poExpr->table_name, psOptions->poFDefn->GetName()) ); if( bSameTable ) { if( (nIndex = psOptions->poFDefn->GetFieldIndex(poExpr->string_value)) >= 0 ) { pszFieldname = psOptions->poFDefn->GetFieldDefn(nIndex)->GetNameRef(); } else if( (nIndex = psOptions->poFDefn->GetGeomFieldIndex(poExpr->string_value)) >= 0 ) { pszFieldname = psOptions->poFDefn->GetGeomFieldDefn(nIndex)->GetNameRef(); } } else if( psOptions->poDS != NULL ) { OGRLayer* poLayer = psOptions->poDS->GetLayerByName(poExpr->table_name); if( poLayer ) { OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn(); if( (nIndex = poFDefn->GetFieldIndex(poExpr->string_value)) >= 0 ) { pszFieldname = CPLSPrintf("%s/%s", poLayer->GetName(), poFDefn->GetFieldDefn(nIndex)->GetNameRef()); } else if( (nIndex = poFDefn->GetGeomFieldIndex(poExpr->string_value)) >= 0 ) { pszFieldname = CPLSPrintf("%s/%s", poLayer->GetName(), poFDefn->GetGeomFieldDefn(nIndex)->GetNameRef()); } } } if( psOptions->poFDefn == NULL && psOptions->poDS == NULL ) pszFieldname = poExpr->string_value; if( pszFieldname == NULL ) { if( poExpr->table_name != NULL ) CPLDebug("WFS", "Field \"%s\".\"%s\" unknown. Cannot use server-side filtering", poExpr->table_name, poExpr->string_value); else CPLDebug("WFS", "Field \"%s\" unknown. Cannot use server-side filtering", poExpr->string_value); return FALSE; } if (psOptions->nVersion >= 200) osFilter += CPLSPrintf("<%sValueReference>", psOptions->pszNSPrefix); else osFilter += CPLSPrintf("<%sPropertyName>", psOptions->pszNSPrefix); char* pszFieldnameXML = CPLEscapeString(pszFieldname, -1, CPLES_XML); osFilter += pszFieldnameXML; CPLFree(pszFieldnameXML); if (psOptions->nVersion >= 200) osFilter += CPLSPrintf("</%sValueReference>", psOptions->pszNSPrefix); else osFilter += CPLSPrintf("</%sPropertyName>", psOptions->pszNSPrefix); return TRUE; } if( poExpr->eNodeType == SNT_CONSTANT ) { if (bExpectBinary) return FALSE; osFilter += CPLSPrintf("<%sLiteral>", psOptions->pszNSPrefix); if( !WFS_ExprDumpRawLitteral(osFilter, poExpr) ) return FALSE; osFilter += CPLSPrintf("</%sLiteral>", psOptions->pszNSPrefix); return TRUE; } if( poExpr->eNodeType != SNT_OPERATION ) return FALSE; /* shouldn't happen */ if( poExpr->nOperation == SWQ_NOT ) { osFilter += CPLSPrintf("<%sNot>", psOptions->pszNSPrefix); if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], TRUE, psOptions)) return FALSE; osFilter += CPLSPrintf("</%sNot>", psOptions->pszNSPrefix); return TRUE; } if( poExpr->nOperation == SWQ_LIKE ) { CPLString osVal; char ch; char firstCh = 0; int i; if (psOptions->nVersion == 100) osFilter += CPLSPrintf("<%sPropertyIsLike wildCard='*' singleChar='_' escape='!'>", psOptions->pszNSPrefix); else osFilter += CPLSPrintf("<%sPropertyIsLike wildCard='*' singleChar='_' escapeChar='!'>", psOptions->pszNSPrefix); if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions)) return FALSE; if (poExpr->papoSubExpr[1]->eNodeType != SNT_CONSTANT && poExpr->papoSubExpr[1]->field_type != SWQ_STRING) return FALSE; osFilter += CPLSPrintf("<%sLiteral>", psOptions->pszNSPrefix); /* Escape value according to above special characters */ /* For URL compatibility reason, we remap the OGR SQL '%' wildchard into '*' */ i = 0; ch = poExpr->papoSubExpr[1]->string_value[i]; if (ch == '\'' || ch == '"') { firstCh = ch; i ++; } for(;(ch = poExpr->papoSubExpr[1]->string_value[i]) != '\0';i++) { if (ch == '%') osVal += "*"; else if (ch == '!') osVal += "!!"; else if (ch == '*') osVal += "!*"; else if (ch == firstCh && poExpr->papoSubExpr[1]->string_value[i + 1] == 0) break; else { char ach[2]; ach[0] = ch; ach[1] = 0; osVal += ach; } } char* pszXML = CPLEscapeString(osVal, -1, CPLES_XML); osFilter += pszXML; CPLFree(pszXML); osFilter += CPLSPrintf("</%sLiteral>", psOptions->pszNSPrefix); osFilter += CPLSPrintf("</%sPropertyIsLike>", psOptions->pszNSPrefix); return TRUE; } if( poExpr->nOperation == SWQ_ISNULL ) { osFilter += CPLSPrintf("<%sPropertyIsNull>", psOptions->pszNSPrefix); if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions)) return FALSE; osFilter += CPLSPrintf("</%sPropertyIsNull>", psOptions->pszNSPrefix); psOptions->bOutNeedsNullCheck = TRUE; return TRUE; } if( poExpr->nOperation == SWQ_EQ || poExpr->nOperation == SWQ_NE || poExpr->nOperation == SWQ_LE || poExpr->nOperation == SWQ_LT || poExpr->nOperation == SWQ_GE || poExpr->nOperation == SWQ_GT ) { int nOperation = poExpr->nOperation; int bAddClosingNot = FALSE; if (!psOptions->bPropertyIsNotEqualToSupported && nOperation == SWQ_NE) { osFilter += CPLSPrintf("<%sNot>", psOptions->pszNSPrefix); nOperation = SWQ_EQ; bAddClosingNot = TRUE; } const char* pszName = NULL; switch(nOperation) { case SWQ_EQ: pszName = "PropertyIsEqualTo"; break; case SWQ_NE: pszName = "PropertyIsNotEqualTo"; break; case SWQ_LE: pszName = "PropertyIsLessThanOrEqualTo"; break; case SWQ_LT: pszName = "PropertyIsLessThan"; break; case SWQ_GE: pszName = "PropertyIsGreaterThanOrEqualTo"; break; case SWQ_GT: pszName = "PropertyIsGreaterThan"; break; default: break; } osFilter += "<"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions)) return FALSE; if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[1], FALSE, psOptions)) return FALSE; osFilter += "</"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; if (bAddClosingNot) osFilter += CPLSPrintf("</%sNot>", psOptions->pszNSPrefix); return TRUE; } if( poExpr->nOperation == SWQ_AND || poExpr->nOperation == SWQ_OR ) { const char* pszName = (poExpr->nOperation == SWQ_AND) ? "And" : "Or"; osFilter += "<"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], TRUE, psOptions)) return FALSE; if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[1], TRUE, psOptions)) return FALSE; osFilter += "</"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; return TRUE; } if( poExpr->nOperation == SWQ_CUSTOM_FUNC && EQUAL(poExpr->string_value, "ST_MakeEnvelope") ) { OGRSpatialReference oSRS; const char* pszSRSName = WFS_ExprGetSRSName( poExpr, 4, psOptions, oSRS ); int bAxisSwap = FALSE; osFilter += "<gml:Envelope"; if( pszSRSName ) { osFilter += " srsName=\""; osFilter += pszSRSName; osFilter += "\""; if( oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting() ) bAxisSwap = TRUE; } osFilter += ">"; osFilter += "<gml:lowerCorner>"; if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 1 : 0])) return FALSE; osFilter += " "; if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 0 : 1])) return FALSE; osFilter += "</gml:lowerCorner>"; osFilter += "<gml:upperCorner>"; if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 3 : 2])) return FALSE; osFilter += " "; if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 2 : 3])) return FALSE; osFilter += "</gml:upperCorner>"; osFilter += "</gml:Envelope>"; return TRUE; } if( poExpr->nOperation == SWQ_CUSTOM_FUNC && EQUAL(poExpr->string_value, "ST_GeomFromText") ) { OGRSpatialReference oSRS; const char* pszSRSName = WFS_ExprGetSRSName( poExpr, 1, psOptions, oSRS ); OGRGeometry* poGeom = NULL; char* pszWKT = (char*)poExpr->papoSubExpr[0]->string_value; OGRGeometryFactory::createFromWkt(&pszWKT, NULL, &poGeom); char** papszOptions = NULL; papszOptions = CSLSetNameValue(papszOptions, "FORMAT", "GML3"); if( pszSRSName != NULL ) { if( oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting() ) { OGR_SRSNode *poGEOGCS = oSRS.GetAttrNode( "GEOGCS" ); if( poGEOGCS != NULL ) poGEOGCS->StripNodes( "AXIS" ); OGR_SRSNode *poPROJCS = oSRS.GetAttrNode( "PROJCS" ); if (poPROJCS != NULL && oSRS.EPSGTreatsAsNorthingEasting()) poPROJCS->StripNodes( "AXIS" ); } if( EQUALN(pszSRSName, "urn:ogc:def:crs:EPSG::", strlen("urn:ogc:def:crs:EPSG::")) ) papszOptions = CSLSetNameValue(papszOptions, "GML3_LONGSRS", "YES"); else papszOptions = CSLSetNameValue(papszOptions, "GML3_LONGSRS", "NO"); poGeom->assignSpatialReference(&oSRS); } papszOptions = CSLSetNameValue(papszOptions, "GMLID", CPLSPrintf("id%d", psOptions->nUniqueGeomGMLId ++)); char* pszGML = OGR_G_ExportToGMLEx( (OGRGeometryH)poGeom, papszOptions ); osFilter += pszGML; CSLDestroy(papszOptions); delete poGeom; CPLFree(pszGML); return TRUE; } if( poExpr->nOperation == SWQ_CUSTOM_FUNC ) { const char* pszName = EQUAL(poExpr->string_value, "ST_Equals") ? "Equals" : EQUAL(poExpr->string_value, "ST_Disjoint") ? "Disjoint" : EQUAL(poExpr->string_value, "ST_Touches") ? "Touches" : EQUAL(poExpr->string_value, "ST_Contains") ? "Contains" : EQUAL(poExpr->string_value, "ST_Intersects") ? "Intersects" : EQUAL(poExpr->string_value, "ST_Within") ? "Within" : EQUAL(poExpr->string_value, "ST_Crosses") ? "Crosses" : EQUAL(poExpr->string_value, "ST_Overlaps") ? "Overlaps" : EQUAL(poExpr->string_value, "ST_DWithin") ? "DWithin" : EQUAL(poExpr->string_value, "ST_Beyond") ? "Beyond" : NULL; if( pszName == NULL ) return FALSE; osFilter += "<"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; for(int i=0;i<2;i++) { if( i == 1 && poExpr->papoSubExpr[0]->eNodeType == SNT_COLUMN && poExpr->papoSubExpr[1]->eNodeType == SNT_OPERATION && poExpr->papoSubExpr[1]->nOperation == SWQ_CUSTOM_FUNC && (EQUAL(poExpr->papoSubExpr[1]->string_value, "ST_GeomFromText") || EQUAL(poExpr->papoSubExpr[1]->string_value, "ST_MakeEnvelope")) ) { int bSameTable = psOptions->poFDefn != NULL && ( poExpr->papoSubExpr[0]->table_name == NULL || EQUAL(poExpr->papoSubExpr[0]->table_name, psOptions->poFDefn->GetName()) ); if( bSameTable ) { int nIndex; if( (nIndex = psOptions->poFDefn->GetGeomFieldIndex(poExpr->papoSubExpr[0]->string_value)) >= 0 ) { psOptions->poSRS = psOptions->poFDefn->GetGeomFieldDefn(nIndex)->GetSpatialRef(); } } else if( psOptions->poDS != NULL ) { OGRLayer* poLayer = psOptions->poDS->GetLayerByName(poExpr->papoSubExpr[0]->table_name); if( poLayer ) { OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn(); int nIndex; if( (nIndex = poFDefn->GetGeomFieldIndex(poExpr->papoSubExpr[0]->string_value)) >= 0 ) { psOptions->poSRS = poFDefn->GetGeomFieldDefn(nIndex)->GetSpatialRef(); } } } } int bRet = WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[i], FALSE, psOptions); psOptions->poSRS = NULL; if( !bRet ) return FALSE; } if( poExpr->nSubExprCount > 2 ) { osFilter += CPLSPrintf("<%sDistance unit=\"m\">", psOptions->pszNSPrefix); if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[2]) ) return FALSE; osFilter += CPLSPrintf("</%sDistance>", psOptions->pszNSPrefix); } osFilter += "</"; osFilter += psOptions->pszNSPrefix; osFilter += pszName; osFilter += ">"; return TRUE; } return FALSE; }
void ProjectionDlg::SetUIFromProjection() { if (m_proj.IsDymaxion()) SetProjectionUI(PT_DYMAX); else if (m_proj.IsGeographic()) SetProjectionUI(PT_GEO); else { const char *proj_string = m_proj.GetProjectionName(); if (!strcmp(proj_string, SRS_PT_TRANSVERSE_MERCATOR)) { if (m_proj.GetUTMZone() != 0) SetProjectionUI(PT_UTM); else SetProjectionUI(PT_TM); } // Supposedly, Gauss-Kruger is just a form of Transverse Mercator else if (!strcmp(proj_string, "Gauss_Kruger")) SetProjectionUI(PT_TM); else if (!strcmp(proj_string, SRS_PT_ALBERS_CONIC_EQUAL_AREA)) SetProjectionUI(PT_ALBERS); else if (!strcmp(proj_string, SRS_PT_MERCATOR_1SP)) SetProjectionUI(PT_MERC); else if (!strcmp(proj_string, SRS_PT_HOTINE_OBLIQUE_MERCATOR)) SetProjectionUI(PT_HOM); else if (!strcmp(proj_string, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP)) SetProjectionUI(PT_LCC1SP); else if (!strcmp(proj_string, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP)) SetProjectionUI(PT_LCC); else if (!strcmp(proj_string, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA)) SetProjectionUI(PT_LAEA); else if (!strcmp(proj_string, SRS_PT_NEW_ZEALAND_MAP_GRID)) SetProjectionUI(PT_NZMG); else if (!strcmp(proj_string, SRS_PT_SINUSOIDAL)) SetProjectionUI(PT_SINUS); else if (!strcmp(proj_string, SRS_PT_STEREOGRAPHIC)) SetProjectionUI(PT_STEREO); else if (!strcmp(proj_string, SRS_PT_OBLIQUE_STEREOGRAPHIC)) SetProjectionUI(PT_OS); else if (!strcmp(proj_string, SRS_PT_POLAR_STEREOGRAPHIC)) SetProjectionUI(PT_PS); else if (!strcmp(proj_string, SRS_PT_KROVAK)) SetProjectionUI(PT_KROVAK); // I've seen a .prj file for Stereo70 which refers to the projection // as "Double_Stereographic", but this is unknown by OGR. We do know // about Oblique Stereographic, which is what i believe is meant. else if (!strcmp(proj_string, "Double_Stereographic")) { OGR_SRSNode *node = m_proj.GetAttrNode("PROJECTION"); node = node->GetChild(0); node->SetValue(SRS_PT_OBLIQUE_STEREOGRAPHIC); SetProjectionUI(PT_OS); } else { wxString str = _("Unknown projection: "); str += wxString(proj_string, wxConvUTF8); wxMessageBox(str); } } }
OGRErr OGR_SRSNode::importFromWkt( char ** ppszInput ) { const char *pszInput = *ppszInput; int bInQuotedString = FALSE; /* -------------------------------------------------------------------- */ /* Clear any existing children of this node. */ /* -------------------------------------------------------------------- */ ClearChildren(); /* -------------------------------------------------------------------- */ /* Read the ``value'' for this node. */ /* -------------------------------------------------------------------- */ char szToken[512]; int nTokenLen = 0; while( *pszInput != '\0' && nTokenLen < (int) sizeof(szToken)-1 ) { if( *pszInput == '"' ) { bInQuotedString = !bInQuotedString; } else if( !bInQuotedString && (*pszInput == '[' || *pszInput == ']' || *pszInput == ',' || *pszInput == '(' || *pszInput == ')' ) ) { break; } else { szToken[nTokenLen++] = *pszInput; } pszInput++; } if( *pszInput == '\0' || nTokenLen == sizeof(szToken) - 1 ) return OGRERR_CORRUPT_DATA; szToken[nTokenLen++] = '\0'; SetValue( szToken ); /* -------------------------------------------------------------------- */ /* Read children, if we have a sublist. */ /* -------------------------------------------------------------------- */ if( *pszInput == '[' || *pszInput == '(' ) { do { OGR_SRSNode *poNewChild; OGRErr eErr; pszInput++; // Skip bracket or comma. poNewChild = new OGR_SRSNode(); eErr = poNewChild->importFromWkt( (char **) &pszInput ); if( eErr != OGRERR_NONE ) return eErr; AddChild( poNewChild ); } while( *pszInput == ',' ); if( *pszInput != ')' && *pszInput != ']' ) return OGRERR_CORRUPT_DATA; pszInput++; } *ppszInput = (char *) pszInput; return OGRERR_NONE; }
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn, OGRSpatialReference * poTargetIn ) { if( poSourceIn == NULL || poTargetIn == NULL ) return FALSE; poSRSSource = poSourceIn->Clone(); poSRSTarget = poTargetIn->Clone(); bSourceLatLong = CPL_TO_BOOL(poSRSSource->IsGeographic()); bTargetLatLong = CPL_TO_BOOL(poSRSTarget->IsGeographic()); /* -------------------------------------------------------------------- */ /* Setup source and target translations to radians for lat/long */ /* systems. */ /* -------------------------------------------------------------------- */ dfSourceToRadians = DEG_TO_RAD; bSourceWrap = false; dfSourceWrapLong = 0.0; if( bSourceLatLong ) { OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { dfSourceToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue()); if( dfSourceToRadians == 0.0 ) dfSourceToRadians = DEG_TO_RAD; } } dfTargetFromRadians = RAD_TO_DEG; bTargetWrap = false; dfTargetWrapLong = 0.0; if( bTargetLatLong ) { OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { double dfTargetToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue()); if( dfTargetToRadians != 0.0 ) dfTargetFromRadians = 1 / dfTargetToRadians; } } /* -------------------------------------------------------------------- */ /* Preliminary logic to setup wrapping. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL ) { bSourceWrap = true; bTargetWrap = true; dfSourceWrapLong = dfTargetWrapLong = CPLAtof(CPLGetConfigOption( "CENTER_LONG", "" )); CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong ); } const char *pszCENTER_LONG = poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfSourceWrapLong = CPLAtof(pszCENTER_LONG); bSourceWrap = true; CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong ); } pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfTargetWrapLong = CPLAtof(pszCENTER_LONG); bTargetWrap = true; CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong ); } bCheckWithInvertProj = CPLTestBool(CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", "NO" )); // The threshold is experimental. Works well with the cases of ticket #2305. if( bSourceLatLong ) dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", ".1" )); else // 1 works well for most projections, except for +proj=aeqd that // requires a tolerance of 10000. dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", "10000" )); // OGRThreadSafety: The following variable is not a thread safety issue // since the only issue is incrementing while accessing which at worse // means debug output could be one "increment" late. static int nDebugReportCount = 0; char *pszSrcProj4Defn = NULL; if( poSRSSource->exportToProj4( &pszSrcProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); return FALSE; } if( strlen(pszSrcProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for source SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } char *pszDstProj4Defn = NULL; if( poSRSTarget->exportToProj4( &pszDstProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } if( strlen(pszDstProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for destination SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Optimization to avoid useless nadgrids evaluation. */ /* For example when converting between WGS84 and WebMercator */ /* -------------------------------------------------------------------- */ if( pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] == ' ' ) pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] = 0; if( pszDstProj4Defn[strlen(pszDstProj4Defn)-1] == ' ' ) pszDstProj4Defn[strlen(pszDstProj4Defn)-1] = 0; char* pszNeedle = strstr(pszSrcProj4Defn, " "); if( pszNeedle ) memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1); pszNeedle = strstr(pszDstProj4Defn, " "); if( pszNeedle ) memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1); if( (strstr(pszSrcProj4Defn, "+datum=WGS84") != NULL || strstr(pszSrcProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) && strstr(pszDstProj4Defn, "+nadgrids=@null ") != NULL && strstr(pszDstProj4Defn, "+towgs84") == NULL ) { char* pszDst = strstr(pszSrcProj4Defn, "+towgs84=0,0,0,0,0,0,0 "); if( pszDst != NULL ) { char *pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } else { memcpy(strstr(pszSrcProj4Defn, "+datum=WGS84"), "+ellps", 6); } pszDst = strstr(pszDstProj4Defn, "+nadgrids=@null "); char *pszSrc = pszDst + strlen("+nadgrids=@null "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); pszDst = strstr(pszDstProj4Defn, "+wktext "); if( pszDst ) { pszSrc = pszDst + strlen("+wktext "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } //bWGS84ToWebMercator = // strcmp(pszSrcProj4Defn, "+proj=longlat +ellps=WGS84 +no_defs") == 0 && // strcmp(pszDstProj4Defn, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0; } else if( (strstr(pszDstProj4Defn, "+datum=WGS84") != NULL || strstr(pszDstProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) && strstr(pszSrcProj4Defn, "+nadgrids=@null ") != NULL && strstr(pszSrcProj4Defn, "+towgs84") == NULL ) { char* pszDst = strstr(pszDstProj4Defn, "+towgs84=0,0,0,0,0,0,0 "); if( pszDst != NULL) { char* pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } else memcpy(strstr(pszDstProj4Defn, "+datum=WGS84"), "+ellps", 6); pszDst = strstr(pszSrcProj4Defn, "+nadgrids=@null "); char* pszSrc = pszDst + strlen("+nadgrids=@null "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); pszDst = strstr(pszSrcProj4Defn, "+wktext "); if( pszDst ) { pszSrc = pszDst + strlen("+wktext "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } bWebMercatorToWGS84 = strcmp(pszDstProj4Defn, "+proj=longlat +ellps=WGS84 +no_defs") == 0 && strcmp(pszSrcProj4Defn, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 " "+x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0; } /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for source if projection. */ /* -------------------------------------------------------------------- */ if( !bWebMercatorToWGS84 ) { if (pjctx) psPJSource = pfn_pj_init_plus_ctx( pjctx, pszSrcProj4Defn ); else psPJSource = pfn_pj_init_plus( pszSrcProj4Defn ); if( psPJSource == NULL ) { if( pjctx != NULL) { int l_pj_errno = pfn_pj_ctx_get_errno(pjctx); /* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */ CPLMutexHolderD(&hPROJMutex); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(l_pj_errno) ); } else if( pfn_pj_get_errno_ref != NULL && pfn_pj_strerrno != NULL ) { int *p_pj_errno = pfn_pj_get_errno_ref(); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(*p_pj_errno) ); } else { CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n", pszSrcProj4Defn ); } } } if( nDebugReportCount < 10 ) CPLDebug( "OGRCT", "Source: %s", pszSrcProj4Defn ); if( !bWebMercatorToWGS84 && psPJSource == NULL ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for target if projection. */ /* -------------------------------------------------------------------- */ if( !bWebMercatorToWGS84 ) { if (pjctx) psPJTarget = pfn_pj_init_plus_ctx( pjctx, pszDstProj4Defn ); else psPJTarget = pfn_pj_init_plus( pszDstProj4Defn ); if( psPJTarget == NULL ) CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.", pszDstProj4Defn ); } if( nDebugReportCount < 10 ) { CPLDebug( "OGRCT", "Target: %s", pszDstProj4Defn ); nDebugReportCount++; } if( !bWebMercatorToWGS84 && psPJTarget == NULL ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } /* Determine if we really have a transformation to do */ bIdentityTransform = strcmp(pszSrcProj4Defn, pszDstProj4Defn) == 0; #if 0 /* In case of identity transform, under the following conditions, */ /* we can also avoid transforming from degrees <--> radians. */ if( bIdentityTransform && bSourceLatLong && !bSourceWrap && bTargetLatLong && !bTargetWrap && fabs(dfSourceToRadians * dfTargetFromRadians - 1.0) < 1e-10 ) { // bSourceLatLong = false; // bTargetLatLong = false; } #endif CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return TRUE; }
static void importXMLUnits(CPLXMLNode *psSrcXML, const char *pszClass, OGRSpatialReference *poSRS, const char *pszTarget) { const char *pszUnitName, *pszUnitsPer; OGR_SRSNode *poNode = poSRS->GetAttrNode(pszTarget); OGR_SRSNode *poUnits; CPLAssert(EQUAL(pszClass, "AngularUnit") || EQUAL(pszClass, "LinearUnit")); psSrcXML = CPLGetXMLNode(psSrcXML, pszClass); if (psSrcXML == NULL) goto DefaultTarget; pszUnitName = CPLGetXMLValue(psSrcXML, "NameSet.name", "unnamed"); if (EQUAL(pszClass, "AngularUnit")) pszUnitsPer = CPLGetXMLValue(psSrcXML, "radiansPerUnit", NULL); else pszUnitsPer = CPLGetXMLValue(psSrcXML, "metresPerUnit", NULL); if (pszUnitsPer == NULL) { CPLDebug("OGR_SRS_XML", "Missing PerUnit value for %s.", pszClass); goto DefaultTarget; } if (poNode == NULL) { CPLDebug("OGR_SRS_XML", "Can't find %s in importXMLUnits.", pszTarget); goto DefaultTarget; } if (poNode->FindChild("UNIT") != -1) { poUnits = poNode->GetChild(poNode->FindChild("UNIT")); poUnits->GetChild(0)->SetValue(pszUnitName); poUnits->GetChild(1)->SetValue(pszUnitsPer); } else { poUnits = new OGR_SRSNode("UNIT"); poUnits->AddChild(new OGR_SRSNode(pszUnitName)); poUnits->AddChild(new OGR_SRSNode(pszUnitsPer)); poNode->AddChild(poUnits); } return; DefaultTarget: poUnits = new OGR_SRSNode("UNIT"); if (EQUAL(pszClass, "AngularUnit")) { poUnits->AddChild(new OGR_SRSNode(SRS_UA_DEGREE)); poUnits->AddChild(new OGR_SRSNode(SRS_UA_DEGREE_CONV)); } else { poUnits->AddChild(new OGR_SRSNode(SRS_UL_METER)); poUnits->AddChild(new OGR_SRSNode("1.0")); } poNode->AddChild(poUnits); }
OGRErr OGRSpatialReference::Validate(OGR_SRSNode *poRoot) { if( !EQUAL(poRoot->GetValue(),"GEOGCS") && !EQUAL(poRoot->GetValue(),"PROJCS") && !EQUAL(poRoot->GetValue(),"LOCAL_CS") && !EQUAL(poRoot->GetValue(),"GEOCCS") && !EQUAL(poRoot->GetValue(),"VERT_CS") && !EQUAL(poRoot->GetValue(),"COMPD_CS")) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised root node `%s'\n", poRoot->GetValue() ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* For a COMPD_CS, validate subparameters and head & tail cs */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"COMPD_CS") ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"GEOGCS") || EQUAL(poNode->GetValue(),"PROJCS") || EQUAL(poNode->GetValue(),"LOCAL_CS") || EQUAL(poNode->GetValue(),"GEOCCS") || EQUAL(poNode->GetValue(),"VERT_CS") || EQUAL(poNode->GetValue(),"COMPD_CS") ) { OGRErr eErr = Validate(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for COMPD_CS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Validate VERT_CS */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"VERT_CS") ) { OGR_SRSNode *poNode; int i; int bGotVertDatum = FALSE; int bGotUnit = FALSE; int nCountAxis = 0; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"VERT_DATUM") ) { OGRErr eErr = ValidateVertDatum(poNode); if (eErr != OGRERR_NONE) return eErr; bGotVertDatum = TRUE; } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; bGotUnit = TRUE; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; nCountAxis ++; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for VERT_CS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if (!bGotVertDatum) { CPLDebug( "OGRSpatialReference::Validate", "No VERT_DATUM child in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } if (!bGotUnit) { CPLDebug( "OGRSpatialReference::Validate", "No UNIT child in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } if (nCountAxis > 1) { CPLDebug( "OGRSpatialReference::Validate", "Too many AXIS children in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* For a PROJCS, validate subparameters (other than GEOGCS). */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"PROJCS") ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"GEOGCS") ) { /* validated elsewhere */ } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"PARAMETER") ) { if( poNode->GetChildCount() != 2 ) { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER has wrong number of children (%d)," "not 2 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CSLFindString( (char **)papszParameters, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised PARAMETER `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } } else if( EQUAL(poNode->GetValue(),"PROJECTION") ) { if( poNode->GetChildCount() != 1 && poNode->GetChildCount() != 2 ) { CPLDebug( "OGRSpatialReference::Validate", "PROJECTION has wrong number of children (%d)," "not 1 or 2 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CSLFindString( (char **)papszProjectionSupported, poNode->GetChild(0)->GetValue()) == -1 && CSLFindString( (char **)papszProjectionUnsupported, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised PROJECTION `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } else if( CSLFindString( (char **)papszProjectionSupported, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unsupported, but recognised PROJECTION `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } if (poNode->GetChildCount() == 2) { poNode = poNode->GetChild(1); if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for PROJECTION `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"EXTENSION") ) { // We do not try to control the sub-organization of // EXTENSION nodes. } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for PROJCS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } } /* -------------------------------------------------------------------- */ /* Validate GEOGCS if found. */ /* -------------------------------------------------------------------- */ OGR_SRSNode *poGEOGCS = poRoot->GetNode( "GEOGCS" ); if( poGEOGCS != NULL ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poGEOGCS->GetChildCount(); i++ ) { poNode = poGEOGCS->GetChild(i); if( EQUAL(poNode->GetValue(),"DATUM") ) { /* validated elsewhere */ } else if( EQUAL(poNode->GetValue(),"PRIMEM") ) { if( poNode->GetChildCount() < 2 || poNode->GetChildCount() > 3 ) { CPLDebug( "OGRSpatialReference::Validate", "PRIMEM has wrong number of children (%d)," "not 2 or 3 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for GEOGCS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if( poGEOGCS->GetNode("DATUM") == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "No DATUM child in GEOGCS.\n" ); return OGRERR_CORRUPT_DATA; } } /* -------------------------------------------------------------------- */ /* Validate DATUM/SPHEROID. */ /* -------------------------------------------------------------------- */ OGR_SRSNode *poDATUM = poRoot->GetNode( "DATUM" ); if( poDATUM != NULL ) { OGR_SRSNode *poSPHEROID; int bGotSpheroid = FALSE; int i; if( poDATUM->GetChildCount() == 0 ) { CPLDebug( "OGRSpatialReference::Validate", "DATUM has no children." ); return OGRERR_CORRUPT_DATA; } for( i = 1; i < poDATUM->GetChildCount(); i++ ) { OGR_SRSNode *poNode; poNode = poDATUM->GetChild(i); if( EQUAL(poNode->GetValue(),"SPHEROID") ) { poSPHEROID = poDATUM->GetChild(1); bGotSpheroid = TRUE; if( poSPHEROID->GetChildCount() != 3 && poSPHEROID->GetChildCount() != 4 ) { CPLDebug( "OGRSpatialReference::Validate", "SPHEROID has wrong number of children (%d)," "not 3 or 4 as expected.\n", poSPHEROID->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CPLAtof(poSPHEROID->GetChild(1)->GetValue()) == 0.0 ) { CPLDebug( "OGRSpatialReference::Validate", "SPHEROID semi-major axis is zero (%s)!\n", poSPHEROID->GetChild(1)->GetValue() ); return OGRERR_CORRUPT_DATA; } } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"TOWGS84") ) { if( poNode->GetChildCount() != 3 && poNode->GetChildCount() != 7) { CPLDebug( "OGRSpatialReference::Validate", "TOWGS84 has wrong number of children (%d), not 3 or 7.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for DATUM `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if( !bGotSpheroid ) { CPLDebug( "OGRSpatialReference::Validate", "No SPHEROID child in DATUM.\n" ); return OGRERR_CORRUPT_DATA; } } /* -------------------------------------------------------------------- */ /* If this is projected, try to validate the detailed set of */ /* parameters used for the projection. */ /* -------------------------------------------------------------------- */ OGRErr eErr; eErr = ValidateProjection(poRoot); if( eErr != OGRERR_NONE ) return eErr; /* -------------------------------------------------------------------- */ /* Final check. */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"GEOCCS") ) return OGRERR_UNSUPPORTED_SRS; return OGRERR_NONE; }
OGRErr OGR_SRSNode::importFromWkt( char ** ppszInput, int nRecLevel, int* pnNodes ) { const char *pszInput = *ppszInput; int bInQuotedString = FALSE; /* Sanity checks */ if( nRecLevel == 10 ) { return OGRERR_CORRUPT_DATA; } if( *pnNodes == 1000 ) { return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Clear any existing children of this node. */ /* -------------------------------------------------------------------- */ ClearChildren(); /* -------------------------------------------------------------------- */ /* Read the ``value'' for this node. */ /* -------------------------------------------------------------------- */ char szToken[512]; int nTokenLen = 0; while( *pszInput != '\0' && nTokenLen < (int) sizeof(szToken)-1 ) { if( *pszInput == '"' ) { bInQuotedString = !bInQuotedString; } else if( !bInQuotedString && (*pszInput == '[' || *pszInput == ']' || *pszInput == ',' || *pszInput == '(' || *pszInput == ')' ) ) { break; } else if( !bInQuotedString && (*pszInput == ' ' || *pszInput == '\t' || *pszInput == 10 || *pszInput == 13) ) { /* just skip over whitespace */ } else { szToken[nTokenLen++] = *pszInput; } pszInput++; } if( *pszInput == '\0' || nTokenLen == sizeof(szToken) - 1 ) return OGRERR_CORRUPT_DATA; szToken[nTokenLen++] = '\0'; SetValue( szToken ); /* -------------------------------------------------------------------- */ /* Read children, if we have a sublist. */ /* -------------------------------------------------------------------- */ if( *pszInput == '[' || *pszInput == '(' ) { do { OGR_SRSNode *poNewChild; OGRErr eErr; pszInput++; // Skip bracket or comma. poNewChild = new OGR_SRSNode(); (*pnNodes) ++; eErr = poNewChild->importFromWkt( (char **) &pszInput, nRecLevel + 1, pnNodes ); if( eErr != OGRERR_NONE ) { delete poNewChild; return eErr; } AddChild( poNewChild ); // swallow whitespace while( isspace(*pszInput) ) pszInput++; } while( *pszInput == ',' ); if( *pszInput != ')' && *pszInput != ']' ) return OGRERR_CORRUPT_DATA; pszInput++; } *ppszInput = (char *) pszInput; return OGRERR_NONE; }
/** Apply a vertical shift grid to a source (DEM typically) dataset. * * hGridDataset will typically use WGS84 as horizontal datum (but this is * not a requirement) and its values are the values to add to go from geoid * elevations to WGS84 ellipsoidal heights. * * hGridDataset will be on-the-fly reprojected and resampled to the projection * and resolution of hSrcDataset, using bilinear resampling by default. * * Both hSrcDataset and hGridDataset must be single band datasets, and have * a valid geotransform and projection. * * On success, a reference will be taken on hSrcDataset and hGridDataset. * Reference counting semantics on the source and grid datasets should be * honoured. That is, don't just GDALClose() it, unless it was opened with * GDALOpenShared(), but rather use GDALReleaseDataset() if wanting to * immediately release the reference(s) and make the returned dataset the * owner of them. * * Valid use cases: * * \code * hSrcDataset = GDALOpen(...) * hGridDataset = GDALOpen(...) * hDstDataset = GDALApplyVerticalShiftGrid(hSrcDataset, hGridDataset, ...) * GDALReleaseDataset(hSrcDataset); * GDALReleaseDataset(hGridDataset); * if( hDstDataset ) * { * // Do things with hDstDataset * GDALClose(hDstDataset) // will close hSrcDataset and hGridDataset * } * \endcode * * @param hSrcDataset source (DEM) dataset. Must not be NULL. * @param hGridDataset vertical grid shift dataset. Must not be NULL. * @param bInverse if set to FALSE, hGridDataset values will be added to * hSrcDataset. If set to TRUE, they will be subtracted. * @param dfSrcUnitToMeter the factor to convert values from hSrcDataset to * meters (1.0 if source values are in meter). * @param dfDstUnitToMeter the factor to convert shifted values from meter * (1.0 if output values must be in meter). * @param papszOptions list of options, or NULL. Supported options are: * <ul> * <li>RESAMPLING=NEAREST/BILINEAR/CUBIC. Defaults to BILINEAR.</li> * <li>MAX_ERROR=val. Maximum error measured in input pixels that is allowed in * approximating the transformation (0.0 for exact calculations). Defaults * to 0.125</li> * <li>DATATYPE=Byte/UInt16/Int16/Float32/Float64. Output data type. If not * specified will be the same as the one of hSrcDataset. * <li>ERROR_ON_MISSING_VERT_SHIFT=YES/NO. Whether a missing/nodata value in * hGridDataset should cause I/O requests to fail. Default is NO (in which case * 0 will be used) * <li>SRC_SRS=srs_def. Override projection on hSrcDataset; * </ul> * * @return a new dataset corresponding to hSrcDataset adjusted with * hGridDataset, or NULL. If not NULL, it must be closed with GDALClose(). * * @since GDAL 2.2 */ GDALDatasetH GDALApplyVerticalShiftGrid( GDALDatasetH hSrcDataset, GDALDatasetH hGridDataset, int bInverse, double dfSrcUnitToMeter, double dfDstUnitToMeter, const char* const* papszOptions ) { VALIDATE_POINTER1( hSrcDataset, "GDALApplyVerticalShiftGrid", nullptr ); VALIDATE_POINTER1( hGridDataset, "GDALApplyVerticalShiftGrid", nullptr ); double adfSrcGT[6]; if( GDALGetGeoTransform(hSrcDataset, adfSrcGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no geotransform."); return nullptr; } const char* pszSrcProjection = CSLFetchNameValueDef(papszOptions, "SRC_SRS", GDALGetProjectionRef(hSrcDataset)); if( pszSrcProjection == nullptr || pszSrcProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hSrcDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band source dataset is supported."); return nullptr; } double adfGridGT[6]; if( GDALGetGeoTransform(hGridDataset, adfGridGT) != CE_None ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no geotransform."); return nullptr; } const char* pszGridProjection = GDALGetProjectionRef(hGridDataset); if( pszGridProjection == nullptr || pszGridProjection[0] == '\0' ) { CPLError(CE_Failure, CPLE_NotSupported, "Grid dataset has no projection."); return nullptr; } if( GDALGetRasterCount(hGridDataset) != 1 ) { CPLError(CE_Failure, CPLE_NotSupported, "Only single band grid dataset is supported."); return nullptr; } GDALDataType eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDataset,1)); const char* pszDataType = CSLFetchNameValue(papszOptions, "DATATYPE"); if( pszDataType ) eDT = GDALGetDataTypeByName(pszDataType); if( eDT == GDT_Unknown ) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid DATATYPE=%s", pszDataType); return nullptr; } const int nSrcXSize = GDALGetRasterXSize(hSrcDataset); const int nSrcYSize = GDALGetRasterYSize(hSrcDataset); OGRSpatialReference oSRS; CPLString osSrcProjection(pszSrcProjection); oSRS.SetFromUserInput(osSrcProjection); if( oSRS.IsCompound() ) { OGR_SRSNode* poNode = oSRS.GetRoot()->GetChild(1); if( poNode != nullptr ) { char* pszWKT = nullptr; poNode->exportToWkt(&pszWKT); osSrcProjection = pszWKT; CPLFree(pszWKT); } } void* hTransform = GDALCreateGenImgProjTransformer3( pszGridProjection, adfGridGT, osSrcProjection, adfSrcGT ); if( hTransform == nullptr ) return nullptr; GDALWarpOptions* psWO = GDALCreateWarpOptions(); psWO->hSrcDS = hGridDataset; psWO->eResampleAlg = GRA_Bilinear; const char* pszResampling = CSLFetchNameValue(papszOptions, "RESAMPLING"); if( pszResampling ) { if( EQUAL(pszResampling, "NEAREST") ) psWO->eResampleAlg = GRA_NearestNeighbour; else if( EQUAL(pszResampling, "BILINEAR") ) psWO->eResampleAlg = GRA_Bilinear; else if( EQUAL(pszResampling, "CUBIC") ) psWO->eResampleAlg = GRA_Cubic; } psWO->eWorkingDataType = GDT_Float32; int bHasNoData = FALSE; const double dfSrcNoData = GDALGetRasterNoDataValue( GDALGetRasterBand(hGridDataset, 1), &bHasNoData ); if( bHasNoData ) { psWO->padfSrcNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); psWO->padfSrcNoDataReal[0] = dfSrcNoData; } psWO->padfDstNoDataReal = static_cast<double*>(CPLMalloc(sizeof(double))); const bool bErrorOnMissingShift = CPLFetchBool( papszOptions, "ERROR_ON_MISSING_VERT_SHIFT", false ); psWO->padfDstNoDataReal[0] = (bErrorOnMissingShift) ? -std::numeric_limits<float>::infinity() : 0.0; psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions, "INIT_DEST", "NO_DATA"); psWO->pfnTransformer = GDALGenImgProjTransform; psWO->pTransformerArg = hTransform; const double dfMaxError = CPLAtof(CSLFetchNameValueDef(papszOptions, "MAX_ERROR", "0.125")); if( dfMaxError > 0.0 ) { psWO->pTransformerArg = GDALCreateApproxTransformer( psWO->pfnTransformer, psWO->pTransformerArg, dfMaxError ); psWO->pfnTransformer = GDALApproxTransform; GDALApproxTransformerOwnsSubtransformer(psWO->pTransformerArg, TRUE); } psWO->nBandCount = 1; psWO->panSrcBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panSrcBands[0] = 1; psWO->panDstBands = static_cast<int *>(CPLMalloc(sizeof(int))); psWO->panDstBands[0] = 1; VRTWarpedDataset* poReprojectedGrid = new VRTWarpedDataset(nSrcXSize, nSrcYSize); // This takes a reference on hGridDataset CPLErr eErr = poReprojectedGrid->Initialize(psWO); CPLAssert(eErr == CE_None); CPL_IGNORE_RET_VAL(eErr); GDALDestroyWarpOptions(psWO); poReprojectedGrid->SetGeoTransform(adfSrcGT); poReprojectedGrid->AddBand(GDT_Float32, nullptr); GDALApplyVSGDataset* poOutDS = new GDALApplyVSGDataset( reinterpret_cast<GDALDataset*>(hSrcDataset), poReprojectedGrid, eDT, CPL_TO_BOOL(bInverse), dfSrcUnitToMeter, dfDstUnitToMeter, // Undocumented option. For testing only atoi(CSLFetchNameValueDef(papszOptions, "BLOCKSIZE", "256")) ); poReprojectedGrid->ReleaseRef(); if( !poOutDS->IsInitOK() ) { delete poOutDS; return nullptr; } poOutDS->SetDescription( GDALGetDescription( hSrcDataset ) ); return reinterpret_cast<GDALDatasetH>(poOutDS); }