Exemplo n.º 1
0
std::string SpatialReference::getVerticalUnits() const
{
    std::string tmp("");

    std::string wkt = getWKT(eCompoundOK);
    const char* poWKT = wkt.c_str();
    OGRSpatialReference* poSRS =
        (OGRSpatialReference*)OSRNewSpatialReference(m_wkt.c_str());
    if (poSRS)
    {
        OGR_SRSNode* node = poSRS->GetAttrNode("VERT_CS");
        if (node)
        {
            char* units(0);
            double u = poSRS->GetLinearUnits(&units);
            tmp = units;
            CPLFree(units);

            Utils::trim(tmp);

        }
    }

    return tmp;
}
Exemplo n.º 2
0
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();
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}