static int WFS_ExprDumpGmlObjectIdFilter(CPLString& osFilter,
        const Expr* expr,
        int bUseFeatureId,
        int bGmlObjectIdNeedsGMLPrefix,
        int nVersion)
{
    if (expr->eType == TOKEN_EQUAL &&
            expr->expr1->eType == TOKEN_VAR_NAME &&
            EQUAL(expr->expr1->pszVal, "gml_id") &&
            expr->expr2->eType == TOKEN_LITERAL)
    {
        if (bUseFeatureId)
            osFilter += "<FeatureId fid=\"";
        else if (nVersion >= 200)
            osFilter += "<ResourceId rid=\"";
        else if (!bGmlObjectIdNeedsGMLPrefix)
            osFilter += "<GmlObjectId id=\"";
        else
            osFilter += "<GmlObjectId gml:id=\"";
        if (expr->expr2->pszVal[0] == '\'' || expr->expr2->pszVal[0] == '"')
        {
            CPLString osVal(expr->expr2->pszVal + 1);
            osVal.resize(osVal.size() - 1);
            osFilter += osVal;
        }
        else
            osFilter += expr->expr2->pszVal;
        osFilter += "\"/>";
        return TRUE;
    }
    else if (expr->eType == TOKEN_OR)
    {
        return WFS_ExprDumpGmlObjectIdFilter(osFilter, expr->expr1,
                                             bUseFeatureId, bGmlObjectIdNeedsGMLPrefix, nVersion) &&
               WFS_ExprDumpGmlObjectIdFilter(osFilter, expr->expr2,
                                             bUseFeatureId, bGmlObjectIdNeedsGMLPrefix, nVersion);
    }
    return FALSE;
}
示例#2
0
static int WFS_ExprDumpAsOGCFilter(CPLString& osFilter,
                          const Expr* expr,
                          int bExpectBinary,
                          ExprDumpFilterOptions* psOptions)
{
    switch(expr->eType)
    {
        case TOKEN_VAR_NAME:
            if (bExpectBinary)
                return FALSE;

            /* Special fields not understood by server */
            if (EQUAL(expr->pszVal, "gml_id") ||
                EQUAL(expr->pszVal, "FID") ||
                EQUAL(expr->pszVal, "OGR_GEOMETRY") ||
                EQUAL(expr->pszVal, "OGR_GEOM_WKT") ||
                EQUAL(expr->pszVal, "OGR_GEOM_AREA") ||
                EQUAL(expr->pszVal, "OGR_STYLE"))
                return FALSE;

            if (psOptions->nVersion >= 200)
                osFilter += "<ValueReference>";
            else
                osFilter += "<PropertyName>";
            if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"')
            {
                CPLString osVal(expr->pszVal + 1);
                osVal.resize(osVal.size() - 1);
                osFilter += osVal;
            }
            else
                osFilter += expr->pszVal;
            if (psOptions->nVersion >= 200)
                osFilter += "</ValueReference>";
            else
                osFilter += "</PropertyName>";
            break;

        case TOKEN_LITERAL:
            if (bExpectBinary)
                return FALSE;
            osFilter += "<Literal>";
            if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"')
            {
                CPLString osVal(expr->pszVal + 1);
                osVal.resize(osVal.size() - 1);
                osFilter += osVal;
            }
            else
                osFilter += expr->pszVal;
            osFilter += "</Literal>";
            break;

        case TOKEN_NOT:
            osFilter += "<Not>";
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, TRUE, psOptions))
                return FALSE;
            osFilter += "</Not>";
            break;

        case TOKEN_LIKE:
        {
            CPLString osVal;
            char ch;
            char firstCh = 0;
            int i;
            if (psOptions->nVersion == 100)
                osFilter += "<PropertyIsLike wildCard='*' singleChar='_' escape='!'>";
            else
                osFilter += "<PropertyIsLike wildCard='*' singleChar='_' escapeChar='!'>";
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions))
                return FALSE;
            if (expr->expr2->eType != TOKEN_LITERAL)
                return FALSE;
            osFilter += "<Literal>";

            /* Escape value according to above special characters */
            /* For URL compatibility reason, we remap the OGR SQL '%' wildchard into '*' */
            i = 0;
            ch = expr->expr2->pszVal[i];
            if (ch == '\'' || ch == '"')
            {
                firstCh = ch;
                i ++;
            }
            for(;(ch = expr->expr2->pszVal[i]) != '\0';i++)
            {
                if (ch == '%')
                    osVal += "*";
                else if (ch == '!')
                    osVal += "!!";
                else if (ch == '*')
                    osVal += "!*";
                else if (ch == firstCh && expr->expr2->pszVal[i + 1] == 0)
                    break;
                else
                {
                    char ach[2];
                    ach[0] = ch;
                    ach[1] = 0;
                    osVal += ach;
                }
            }
            osFilter += osVal;
            osFilter += "</Literal>";
            osFilter += "</PropertyIsLike>";
            break;
        }

        case TOKEN_EQUAL:
        case TOKEN_NOT_EQUAL:
        case TOKEN_LESSER_OR_EQUAL:
        case TOKEN_LESSER:
        case TOKEN_GREATER_OR_EQUAL:
        case TOKEN_GREATER:
        {
            if (expr->eType == TOKEN_EQUAL && expr->expr2->eType == TOKEN_LITERAL &&
                EQUAL(expr->expr2->pszVal, "NULL"))
            {
                osFilter += "<PropertyIsNull>";
                if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions))
                    return FALSE;
                osFilter += "</PropertyIsNull>";
                psOptions->bOutNeedsNullCheck = TRUE;
                break;
            }
            if (expr->eType == TOKEN_NOT_EQUAL && expr->expr2->eType == TOKEN_LITERAL &&
                EQUAL(expr->expr2->pszVal, "NULL"))
            {
                osFilter += "<Not><PropertyIsNull>";
                if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions))
                    return FALSE;
                osFilter += "</PropertyIsNull></Not>";
                psOptions->bOutNeedsNullCheck = TRUE;
                break;
            }
            TokenType eType = expr->eType;
            int bAddClosingNot = FALSE;
            if (!psOptions->bPropertyIsNotEqualToSupported && eType == TOKEN_NOT_EQUAL)
            {
                osFilter += "<Not>";
                eType = TOKEN_EQUAL;
                bAddClosingNot = TRUE;
            }

            const char* pszName = NULL;
            switch(eType)
            {
                case TOKEN_EQUAL:           pszName = "PropertyIsEqualTo"; break;
                case TOKEN_NOT_EQUAL:       pszName = "PropertyIsNotEqualTo"; break;
                case TOKEN_LESSER_OR_EQUAL: pszName = "PropertyIsLessThanOrEqualTo"; break;
                case TOKEN_LESSER:          pszName = "PropertyIsLessThan"; break;
                case TOKEN_GREATER_OR_EQUAL:pszName = "PropertyIsGreaterThanOrEqualTo"; break;
                case TOKEN_GREATER:         pszName = "PropertyIsGreaterThan"; break;
                default: break;
            }
            osFilter += "<";
            osFilter += pszName;
            osFilter += ">";
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions))
                return FALSE;
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr2, FALSE, psOptions))
                return FALSE;
            osFilter += "</";
            osFilter += pszName;
            osFilter += ">";
            if (bAddClosingNot)
                osFilter += "</Not>";
            break;
        }

        case TOKEN_AND:
        case TOKEN_OR:
        {
            const char* pszName = (expr->eType == TOKEN_AND) ? "And" : "Or";
            osFilter += "<";
            osFilter += pszName;
            osFilter += ">";
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, TRUE, psOptions))
                return FALSE;
            if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr2, TRUE, psOptions))
                return FALSE;
            osFilter += "</";
            osFilter += pszName;
            osFilter += ">";

            break;
        }

        default:
            return FALSE;
    }

    return TRUE;
}