CPLString OGRPLScenesLayer::BuildFilter(swq_expr_node* poNode) { if( poNode->eNodeType == SNT_OPERATION ) { if( poNode->nOperation == SWQ_AND && poNode->nSubExprCount == 2 ) { // For AND, we can deal with a failure in one of the branch // since client-side will do that extra filtering CPLString osFilter1 = BuildFilter(poNode->papoSubExpr[0]); CPLString osFilter2 = BuildFilter(poNode->papoSubExpr[1]); if( osFilter1.size() && osFilter2.size() ) return osFilter1 + "&" + osFilter2; else if( osFilter1.size() ) return osFilter1; else return osFilter2; } else if( (poNode->nOperation == SWQ_EQ || poNode->nOperation == SWQ_NE || poNode->nOperation == SWQ_LT || poNode->nOperation == SWQ_LE || poNode->nOperation == SWQ_GT || poNode->nOperation == SWQ_GE) && poNode->nSubExprCount == 2 && poNode->papoSubExpr[0]->eNodeType == SNT_COLUMN && poNode->papoSubExpr[1]->eNodeType == SNT_CONSTANT && poNode->papoSubExpr[0]->field_index != poFeatureDefn->GetFieldIndex("id") && poNode->papoSubExpr[0]->field_index < poFeatureDefn->GetFieldCount() ) { OGRFieldDefn *poFieldDefn; poFieldDefn = poFeatureDefn->GetFieldDefn(poNode->papoSubExpr[0]->field_index); CPLString osFilter(poFieldDefn->GetNameRef()); int bDateTimeParsed = FALSE; int nYear = 0, nMonth = 0, nDay = 0, nHour = 0, nMinute = 0, nSecond = 0; if( poNode->papoSubExpr[1]->field_type == SWQ_TIMESTAMP ) { if( sscanf(poNode->papoSubExpr[1]->string_value,"%04d/%02d/%02d %02d:%02d:%02d", &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond) >= 3 || sscanf(poNode->papoSubExpr[1]->string_value,"%04d-%02d-%02dT%02d:%02d:%02d", &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond) >= 3 ) bDateTimeParsed = TRUE; } osFilter += "."; if( poNode->nOperation == SWQ_EQ ) { if( bDateTimeParsed ) osFilter += "gte"; else osFilter += "eq"; } else if( poNode->nOperation == SWQ_NE ) osFilter += "neq"; else if( poNode->nOperation == SWQ_LT ) osFilter += "lt"; else if( poNode->nOperation == SWQ_LE ) osFilter += "lte"; else if( poNode->nOperation == SWQ_GT ) osFilter += "gt"; else if( poNode->nOperation == SWQ_GE ) osFilter += "gte"; osFilter += "="; if (poNode->papoSubExpr[1]->field_type == SWQ_FLOAT) osFilter += CPLSPrintf("%.8f", poNode->papoSubExpr[1]->float_value); else if (poNode->papoSubExpr[1]->field_type == SWQ_INTEGER) osFilter += CPLSPrintf(CPL_FRMT_GIB, poNode->papoSubExpr[1]->int_value); else if (poNode->papoSubExpr[1]->field_type == SWQ_STRING) osFilter += poNode->papoSubExpr[1]->string_value; else if (poNode->papoSubExpr[1]->field_type == SWQ_TIMESTAMP) { if( bDateTimeParsed ) { osFilter += CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond); if( poNode->nOperation == SWQ_EQ ) { osFilter += "&"; osFilter += poFieldDefn->GetNameRef(); osFilter += ".lt="; nSecond ++; if( nSecond == 60 ) { nSecond = 0; nMinute ++; } if( nMinute == 60 ) { nMinute = 0; nHour ++; } if( nHour == 24 ) { nHour = 0; nDay ++; } osFilter += CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond); } } else osFilter += poNode->papoSubExpr[1]->string_value; } return osFilter; } } if( !bFilterMustBeClientSideEvaluated ) { bFilterMustBeClientSideEvaluated = TRUE; CPLDebug("PLSCENES", "Part or full filter will have to be evaluated on client side."); } return ""; }
CPLString OGRPLScenesLayer::BuildFilter(swq_expr_node* poNode) { if( poNode->eNodeType == SNT_OPERATION ) { if( poNode->nOperation == SWQ_AND && poNode->nSubExprCount == 2 ) { // For AND, we can deal with a failure in one of the branch // since client-side will do that extra filtering CPLString osFilter1 = BuildFilter(poNode->papoSubExpr[0]); CPLString osFilter2 = BuildFilter(poNode->papoSubExpr[1]); if( osFilter1.size() && osFilter2.size() ) return osFilter1 + "&" + osFilter2; else if( osFilter1.size() ) return osFilter1; else return osFilter2; } else if( (poNode->nOperation == SWQ_EQ || poNode->nOperation == SWQ_NE || poNode->nOperation == SWQ_LT || poNode->nOperation == SWQ_LE || poNode->nOperation == SWQ_GT || poNode->nOperation == SWQ_GE) && poNode->nSubExprCount == 2 && poNode->papoSubExpr[0]->eNodeType == SNT_COLUMN && poNode->papoSubExpr[1]->eNodeType == SNT_CONSTANT && poNode->papoSubExpr[0]->field_index != poFeatureDefn->GetFieldIndex("id") && poNode->papoSubExpr[0]->field_index < poFeatureDefn->GetFieldCount() ) { OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn(poNode->papoSubExpr[0]->field_index); int nOperation = poNode->nOperation; // image_quality supports only gte filters // (https://www.planet.com/docs-v0/v0/scenes/planetscope/#metadata) if( poNode->papoSubExpr[0]->field_index == poFeatureDefn->GetFieldIndex("image_statistics.image_quality") && nOperation != SWQ_GE ) { // == target can be safely turned as >= target if( poNode->nOperation == SWQ_EQ && poNode->papoSubExpr[1]->field_type == SWQ_STRING && strcmp(poNode->papoSubExpr[1]->string_value, "target") == 0 ) { nOperation = SWQ_GE; } else { if( !bFilterMustBeClientSideEvaluated ) { bFilterMustBeClientSideEvaluated = true; CPLDebug("PLSCENES", "Part or full filter will have to be " "evaluated on client side."); } return ""; } } CPLString osFilter(poFieldDefn->GetNameRef()); bool bDateTimeParsed = false; int nYear = 0; int nMonth = 0; int nDay = 0; int nHour = 0; int nMinute = 0; int nSecond = 0; if( poNode->papoSubExpr[1]->field_type == SWQ_TIMESTAMP ) { if( sscanf(poNode->papoSubExpr[1]->string_value,"%04d/%02d/%02d %02d:%02d:%02d", &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond) >= 3 || sscanf(poNode->papoSubExpr[1]->string_value,"%04d-%02d-%02dT%02d:%02d:%02d", &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond) >= 3 ) bDateTimeParsed = true; } osFilter += "."; if( nOperation == SWQ_EQ ) { if( bDateTimeParsed ) osFilter += "gte"; else osFilter += "eq"; } else if( nOperation == SWQ_NE ) osFilter += "neq"; else if( nOperation == SWQ_LT ) osFilter += "lt"; else if( nOperation == SWQ_LE ) osFilter += "lte"; else if( nOperation == SWQ_GT ) osFilter += "gt"; else if( nOperation == SWQ_GE ) osFilter += "gte"; osFilter += "="; if (poNode->papoSubExpr[1]->field_type == SWQ_FLOAT) osFilter += CPLSPrintf("%.8f", poNode->papoSubExpr[1]->float_value); else if (poNode->papoSubExpr[1]->field_type == SWQ_INTEGER) osFilter += CPLSPrintf(CPL_FRMT_GIB, poNode->papoSubExpr[1]->int_value); else if (poNode->papoSubExpr[1]->field_type == SWQ_STRING) osFilter += poNode->papoSubExpr[1]->string_value; else if (poNode->papoSubExpr[1]->field_type == SWQ_TIMESTAMP) { if( bDateTimeParsed ) { osFilter += CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond); if( nOperation == SWQ_EQ ) { osFilter += "&"; osFilter += poFieldDefn->GetNameRef(); osFilter += ".lt="; nSecond ++; if( nSecond == 60 ) { nSecond = 0; nMinute ++; } if( nMinute == 60 ) { nMinute = 0; nHour ++; } if( nHour == 24 ) { nHour = 0; nDay ++; } osFilter += CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond); } } else osFilter += poNode->papoSubExpr[1]->string_value; } return osFilter; } } if( !bFilterMustBeClientSideEvaluated ) { bFilterMustBeClientSideEvaluated = true; CPLDebug("PLSCENES", "Part or full filter will have to be evaluated on client side."); } return ""; }