예제 #1
0
void GDALGMLJP2Expr::ReportError( const char* pszOriStr,
                                  const char* pszStr,
                                  const char* pszIntroMessage )
{
    size_t nDist = static_cast<size_t>(pszStr - pszOriStr);
    if( nDist > 40 )
        nDist = 40;
    CPLString osErrMsg(pszIntroMessage);
    CPLString osInvalidExpr = CPLString(pszStr - nDist).substr(0, nDist + 20);
    for( int i = static_cast<int>(nDist) - 1; i >= 0; --i )
    {
        if( osInvalidExpr[i] == '\n' )
        {
            osInvalidExpr = osInvalidExpr.substr(i+1);
            nDist -= i + 1;
            break;
        }
    }
    for( size_t i = nDist; i < osInvalidExpr.size(); ++i )
    {
        if( osInvalidExpr[i] == '\n' )
        {
            osInvalidExpr.resize(i);
            break;
        }
    }
    osErrMsg += osInvalidExpr;
    osErrMsg += "\n";
    for( size_t i = 0; i < nDist; ++i )
        osErrMsg += " ";
    osErrMsg += "^";
    CPLError(CE_Failure, CPLE_AppDefined, "%s", osErrMsg.c_str());
}
예제 #2
0
OGRErr OGRSQLiteSelectLayerCommonBehaviour::GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce)
{
    if( iGeomField < 0 || iGeomField >= poLayer->GetLayerDefn()->GetGeomFieldCount() ||
        poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetType() == wkbNone )
    {
        if( iGeomField != 0 )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Invalid geometry field index : %d", iGeomField);
        }
        return OGRERR_FAILURE;
    }

    /* Caching of extent by SQL string is interesting to speed-up the */
    /* establishment of the WFS GetCapabilities document for a MapServer mapfile */
    /* which has several layers, only differing by scale rules */
    if( iGeomField == 0 )
    {
        const OGREnvelope* psCachedExtent = poDS->GetEnvelopeFromSQL(osSQLBase);
        if (psCachedExtent)
        {
            memcpy(psExtent, psCachedExtent, sizeof(*psCachedExtent));
            return OGRERR_NONE;
        }
    }

    CPLString osSQLCommand = osSQLBase;

    /* ORDER BY are costly to evaluate and are not necessary to establish */
    /* the layer extent. */
    size_t nOrderByPos = osSQLCommand.ifind(" ORDER BY ");
    if( osSQLCommand.ifind("SELECT ") == 0 &&
        osSQLCommand.ifind("SELECT ", 1) == std::string::npos && /* Ensure there's no sub SELECT that could confuse our heuristics */
        nOrderByPos != std::string::npos &&
        osSQLCommand.ifind(" LIMIT ") == std::string::npos &&
        osSQLCommand.ifind(" UNION ") == std::string::npos &&
        osSQLCommand.ifind(" INTERSECT ") == std::string::npos &&
        osSQLCommand.ifind(" EXCEPT ") == std::string::npos)
    {
        osSQLCommand.resize(nOrderByPos);

        OGRLayer* poTmpLayer = poDS->ExecuteSQL(osSQLCommand.c_str(), NULL, NULL);
        if (poTmpLayer)
        {
            OGRErr eErr = poTmpLayer->GetExtent(iGeomField, psExtent, bForce);
            poDS->ReleaseResultSet(poTmpLayer);
            return eErr;
        }
    }

    OGRErr eErr;
    if( iGeomField == 0 )
        eErr = poLayer->BaseGetExtent(psExtent, bForce);
    else
        eErr = poLayer->BaseGetExtent(iGeomField, psExtent, bForce);
    if (iGeomField == 0 && eErr == OGRERR_NONE && poDS->GetUpdate() == FALSE)
        poDS->SetEnvelopeForSQL(osSQLBase, *psExtent);
    return eErr;
}
예제 #3
0
const char *RDataset::ASCIIFGets()

{
    char chNextChar;

    osLastStringRead.resize(0);

    do 
    {
        chNextChar = '\n';
        VSIFReadL( &chNextChar, 1, 1, fp );
        if( chNextChar != '\n' )
            osLastStringRead += chNextChar;
    } while( chNextChar != '\n' && chNextChar != '\0' );

    return osLastStringRead;
}
예제 #4
0
OGRErr OGRSQLiteSelectLayer::GetExtent(OGREnvelope *psExtent, int bForce)
{
    if (GetGeomType() == wkbNone)
        return OGRERR_FAILURE;

    /* Caching of extent by SQL string is interesting to speed-up the */
    /* establishment of the WFS GetCapabilities document for a MapServer mapfile */
    /* which has several layers, only differing by scale rules */
    const OGREnvelope* psCachedExtent = poDS->GetEnvelopeFromSQL(osSQLBase);
    if (psCachedExtent)
    {
        memcpy(psExtent, psCachedExtent, sizeof(*psCachedExtent));
        return OGRERR_NONE;
    }

    CPLString osSQLCommand = osSQLBase;

    /* ORDER BY are costly to evaluate and are not necessary to establish */
    /* the layer extent. */
    size_t nOrderByPos = osSQLCommand.ifind(" ORDER BY ");
    if( osSQLCommand.ifind("SELECT ") == 0 &&
        nOrderByPos != std::string::npos &&
        osSQLCommand.ifind(" LIMIT ") == std::string::npos &&
        osSQLCommand.ifind(" UNION ") == std::string::npos &&
        osSQLCommand.ifind(" INTERSECT ") == std::string::npos &&
        osSQLCommand.ifind(" EXCEPT ") == std::string::npos)
    {
        osSQLCommand.resize(nOrderByPos);

        OGRLayer* poTmpLayer = poDS->ExecuteSQL(osSQLCommand.c_str(), NULL, NULL);
        if (poTmpLayer)
        {
            OGRErr eErr = poTmpLayer->GetExtent(psExtent, bForce);
            poDS->ReleaseResultSet(poTmpLayer);
            return eErr;
        }
    }

    OGRErr eErr = OGRSQLiteLayer::GetExtent(psExtent, bForce);
    if (eErr == OGRERR_NONE && poDS->GetUpdate() == FALSE)
        poDS->SetEnvelopeForSQL(osSQLBase, *psExtent);
    return eErr;
}
swq_expr_node *SWQCastEvaluator( swq_expr_node *node,
                                 swq_expr_node **sub_node_values )

{
    swq_expr_node *poRetNode = NULL;
    swq_expr_node *poSrcNode = sub_node_values[0];

    switch( node->field_type )
    {
        case SWQ_INTEGER:
        {
            poRetNode = new swq_expr_node( 0 );

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_BOOLEAN:
                    poRetNode->int_value = poSrcNode->int_value;
                    break;

                case SWQ_FLOAT:
                    poRetNode->int_value = (int) poSrcNode->float_value;
                    break;

                default:
                    poRetNode->int_value = atoi(poSrcNode->string_value);
                    break;
            }
        }
        break;

        case SWQ_FLOAT:
        {
            poRetNode = new swq_expr_node( 0.0 );

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_BOOLEAN:
                    poRetNode->float_value = poSrcNode->int_value;
                    break;

                case SWQ_FLOAT:
                    poRetNode->float_value = poSrcNode->float_value;
                    break;

                default:
                    poRetNode->float_value = atof(poSrcNode->string_value);
                    break;
            }
        }
        break;

        // everything else is a string.
        default:
        {
            CPLString osRet;

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_BOOLEAN:
                    osRet.Printf( "%d", poSrcNode->int_value );
                    break;

                case SWQ_FLOAT:
                    osRet.Printf( "%.15g", poSrcNode->float_value );
                    break;

                default:
                    osRet = poSrcNode->string_value;
                    break;
            }
         
            if( node->nSubExprCount > 2 )
            {
                int nWidth;

                nWidth = sub_node_values[2]->int_value;
                if( nWidth > 0 && (int) strlen(osRet) > nWidth )
                    osRet.resize(nWidth);
            }

            poRetNode = new swq_expr_node( osRet.c_str() );
        }
    }

    return poRetNode;
}
예제 #6
0
swq_expr_node *SWQGeneralEvaluator( swq_expr_node *node,
                                    swq_expr_node **sub_node_values )

{
    swq_expr_node *poRet = NULL;

/* -------------------------------------------------------------------- */
/*      Floating point operations.                                      */
/* -------------------------------------------------------------------- */
    if( sub_node_values[0]->field_type == SWQ_FLOAT
        || (node->nSubExprCount > 1
            && sub_node_values[1]->field_type == SWQ_FLOAT) )
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        if( SWQ_IS_INTEGER(sub_node_values[0]->field_type) )
            sub_node_values[0]->float_value = (double) sub_node_values[0]->int_value;
        if( node->nSubExprCount > 1 &&
            SWQ_IS_INTEGER(sub_node_values[1]->field_type) )
            sub_node_values[1]->float_value = (double)sub_node_values[1]->int_value;

        if( node->nOperation != SWQ_ISNULL )
        {
            for( int i = 0; i < node->nSubExprCount; i++ )
            {
                if( sub_node_values[i]->is_null )
                {
                    if( poRet->field_type == SWQ_BOOLEAN )
                    {
                        poRet->int_value = FALSE;
                        return poRet;
                    }
                    else if( poRet->field_type == SWQ_FLOAT )
                    {
                        poRet->float_value = 0;
                        poRet->is_null = 1;
                        return poRet;
                    }
                    else if( SWQ_IS_INTEGER(poRet->field_type) ||
                             node->nOperation == SWQ_MODULUS )
                    {
                        poRet->field_type = SWQ_INTEGER;
                        poRet->int_value = 0;
                        poRet->is_null = 1;
                        return poRet;
                    }
                }
            }
        }

        switch( (swq_op) node->nOperation )
        {
          case SWQ_EQ:
            poRet->int_value = sub_node_values[0]->float_value
                == sub_node_values[1]->float_value;
            break;

          case SWQ_NE:
            poRet->int_value = sub_node_values[0]->float_value
                != sub_node_values[1]->float_value;
            break;

          case SWQ_GT:
            poRet->int_value = sub_node_values[0]->float_value
                > sub_node_values[1]->float_value;
            break;

          case SWQ_LT:
            poRet->int_value = sub_node_values[0]->float_value
                < sub_node_values[1]->float_value;
            break;

          case SWQ_GE:
            poRet->int_value = sub_node_values[0]->float_value
                >= sub_node_values[1]->float_value;
            break;

          case SWQ_LE:
            poRet->int_value = sub_node_values[0]->float_value
                <= sub_node_values[1]->float_value;
            break;

          case SWQ_IN:
          {
              poRet->int_value = 0;
              for( int i = 1; i < node->nSubExprCount; i++ )
              {
                  if( sub_node_values[0]->float_value
                      == sub_node_values[i]->float_value )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value = sub_node_values[0]->float_value
                                >= sub_node_values[1]->float_value &&
                               sub_node_values[0]->float_value
                                <= sub_node_values[2]->float_value;
            break;

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_ADD:
            poRet->float_value = sub_node_values[0]->float_value
                + sub_node_values[1]->float_value;
            break;

          case SWQ_SUBTRACT:
            poRet->float_value = sub_node_values[0]->float_value
                - sub_node_values[1]->float_value;
            break;

          case SWQ_MULTIPLY:
            poRet->float_value = sub_node_values[0]->float_value
                * sub_node_values[1]->float_value;
            break;

          case SWQ_DIVIDE:
            if( sub_node_values[1]->float_value == 0 )
                poRet->float_value = INT_MAX;
            else
                poRet->float_value = sub_node_values[0]->float_value
                    / sub_node_values[1]->float_value;
            break;

          case SWQ_MODULUS:
          {
            GIntBig nRight = (GIntBig) sub_node_values[1]->float_value;
            poRet->field_type = SWQ_INTEGER;
            if (nRight == 0)
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = ((GIntBig) sub_node_values[0]->float_value)
                    % nRight;
            break;
          }

          default:
            CPLAssert( false );
            delete poRet;
            poRet = NULL;
            break;
        }
    }
/* -------------------------------------------------------------------- */
/*      integer/boolean operations.                                     */
/* -------------------------------------------------------------------- */
    else if( SWQ_IS_INTEGER(sub_node_values[0]->field_type)
        || sub_node_values[0]->field_type == SWQ_BOOLEAN )
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        if( node->nOperation != SWQ_ISNULL )
        {
            for( int i = 0; i < node->nSubExprCount; i++ )
            {
                if( sub_node_values[i]->is_null )
                {
                    if( poRet->field_type == SWQ_BOOLEAN )
                    {
                        poRet->int_value = FALSE;
                        return poRet;
                    }
                    else if( SWQ_IS_INTEGER(poRet->field_type) )
                    {
                        poRet->int_value = 0;
                        poRet->is_null = 1;
                        return poRet;
                    }
                }
            }
        }

        switch( (swq_op) node->nOperation )
        {
          case SWQ_AND:
            poRet->int_value = sub_node_values[0]->int_value
                && sub_node_values[1]->int_value;
            break;

          case SWQ_OR:
            poRet->int_value = sub_node_values[0]->int_value
                || sub_node_values[1]->int_value;
            break;

          case SWQ_NOT:
            poRet->int_value = !sub_node_values[0]->int_value;
            break;

          case SWQ_EQ:
            poRet->int_value = sub_node_values[0]->int_value
                == sub_node_values[1]->int_value;
            break;

          case SWQ_NE:
            poRet->int_value = sub_node_values[0]->int_value
                != sub_node_values[1]->int_value;
            break;

          case SWQ_GT:
            poRet->int_value = sub_node_values[0]->int_value
                > sub_node_values[1]->int_value;
            break;

          case SWQ_LT:
            poRet->int_value = sub_node_values[0]->int_value
                < sub_node_values[1]->int_value;
            break;

          case SWQ_GE:
            poRet->int_value = sub_node_values[0]->int_value
                >= sub_node_values[1]->int_value;
            break;

          case SWQ_LE:
            poRet->int_value = sub_node_values[0]->int_value
                <= sub_node_values[1]->int_value;
            break;

          case SWQ_IN:
          {
              poRet->int_value = 0;
              for( int i = 1; i < node->nSubExprCount; i++ )
              {
                  if( sub_node_values[0]->int_value
                      == sub_node_values[i]->int_value )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value = sub_node_values[0]->int_value
                                >= sub_node_values[1]->int_value &&
                               sub_node_values[0]->int_value
                                <= sub_node_values[2]->int_value;
            break;

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_ADD:
            poRet->int_value = sub_node_values[0]->int_value
                + sub_node_values[1]->int_value;
            break;

          case SWQ_SUBTRACT:
            poRet->int_value = sub_node_values[0]->int_value
                - sub_node_values[1]->int_value;
            break;

          case SWQ_MULTIPLY:
            poRet->int_value = sub_node_values[0]->int_value
                * sub_node_values[1]->int_value;
            break;

          case SWQ_DIVIDE:
            if( sub_node_values[1]->int_value == 0 )
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = sub_node_values[0]->int_value
                    / sub_node_values[1]->int_value;
            break;

          case SWQ_MODULUS:
            if( sub_node_values[1]->int_value == 0 )
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = sub_node_values[0]->int_value
                    % sub_node_values[1]->int_value;
            break;

          default:
            CPLAssert( false );
            delete poRet;
            poRet = NULL;
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      String operations.                                              */
/* -------------------------------------------------------------------- */
    else
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        if( node->nOperation != SWQ_ISNULL )
        {
            for( int i = 0; i < node->nSubExprCount; i++ )
            {
                if( sub_node_values[i]->is_null )
                {
                    if( poRet->field_type == SWQ_BOOLEAN )
                    {
                        poRet->int_value = FALSE;
                        return poRet;
                    }
                    else if( poRet->field_type == SWQ_STRING )
                    {
                        poRet->string_value = CPLStrdup("");
                        poRet->is_null = 1;
                        return poRet;
                    }
                }
            }
        }

        switch( (swq_op) node->nOperation )
        {
          case SWQ_EQ:
          {
            /* When comparing timestamps, the +00 at the end might be discarded */
            /* if the other member has no explicit timezone */
            if( (sub_node_values[0]->field_type == SWQ_TIMESTAMP ||
                 sub_node_values[0]->field_type == SWQ_STRING) &&
                (sub_node_values[1]->field_type == SWQ_TIMESTAMP ||
                 sub_node_values[1]->field_type == SWQ_STRING) &&
                strlen(sub_node_values[0]->string_value) > 3 &&
                strlen(sub_node_values[1]->string_value) > 3 &&
                (strcmp(sub_node_values[0]->string_value + strlen(sub_node_values[0]->string_value)-3, "+00") == 0 &&
                 sub_node_values[1]->string_value[strlen(sub_node_values[1]->string_value)-3] == ':') )
            {
                poRet->int_value =
                    EQUALN(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value,
                           strlen(sub_node_values[1]->string_value));
            }
            else if( (sub_node_values[0]->field_type == SWQ_TIMESTAMP ||
                      sub_node_values[0]->field_type == SWQ_STRING) &&
                     (sub_node_values[1]->field_type == SWQ_TIMESTAMP ||
                      sub_node_values[1]->field_type == SWQ_STRING) &&
                     strlen(sub_node_values[0]->string_value) > 3 &&
                     strlen(sub_node_values[1]->string_value) > 3 &&
                     (sub_node_values[0]->string_value[strlen(sub_node_values[0]->string_value)-3] == ':')  &&
                      strcmp(sub_node_values[1]->string_value + strlen(sub_node_values[1]->string_value)-3, "+00") == 0)
            {
                poRet->int_value =
                    EQUALN(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value,
                           strlen(sub_node_values[0]->string_value));
            }
            else
            {
                poRet->int_value =
                    strcasecmp(sub_node_values[0]->string_value,
                            sub_node_values[1]->string_value) == 0;
            }
            break;
          }

          case SWQ_NE:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) != 0;
            break;

          case SWQ_GT:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) > 0;
            break;

          case SWQ_LT:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) < 0;
            break;

          case SWQ_GE:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) >= 0;
            break;

          case SWQ_LE:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) <= 0;
            break;

          case SWQ_IN:
          {
              poRet->int_value = 0;
              for( int i = 1; i < node->nSubExprCount; i++ )
              {
                  if( strcasecmp(sub_node_values[0]->string_value,
                                 sub_node_values[i]->string_value) == 0 )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) >= 0 &&
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[2]->string_value) <= 0;
            break;

          case SWQ_LIKE:
          {
            char chEscape = '\0';
            if( node->nSubExprCount == 3 )
                chEscape = sub_node_values[2]->string_value[0];
            poRet->int_value = swq_test_like(sub_node_values[0]->string_value,
                                             sub_node_values[1]->string_value,
                                             chEscape);
            break;
          }

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_CONCAT:
          case SWQ_ADD:
          {
              CPLString osResult = sub_node_values[0]->string_value;

              for( int i = 1; i < node->nSubExprCount; i++ )
                  osResult += sub_node_values[i]->string_value;

              poRet->string_value = CPLStrdup(osResult);
              poRet->is_null = sub_node_values[0]->is_null;
              break;
          }

          case SWQ_SUBSTR:
          {
              int nOffset, nSize;
              const char *pszSrcStr = sub_node_values[0]->string_value;

              if( SWQ_IS_INTEGER(sub_node_values[1]->field_type) )
                  nOffset = (int)sub_node_values[1]->int_value;
              else if( sub_node_values[1]->field_type == SWQ_FLOAT )
                  nOffset = (int) sub_node_values[1]->float_value;
              else
                  nOffset = 0;

              if( node->nSubExprCount < 3 )
                  nSize = 100000;
              else if( SWQ_IS_INTEGER(sub_node_values[2]->field_type) )
                  nSize = (int)sub_node_values[2]->int_value;
              else if( sub_node_values[2]->field_type == SWQ_FLOAT )
                  nSize = (int) sub_node_values[2]->float_value;
              else
                  nSize = 0;

              int nSrcStrLen = (int)strlen(pszSrcStr);


              /* In SQL, the first character is at offset 1 */
              /* And 0 is considered as 1 */
              if (nOffset > 0)
                  nOffset --;
              /* Some implementations allow negative offsets, to start */
              /* from the end of the string */
              else if( nOffset < 0 )
              {
                  if( nSrcStrLen + nOffset >= 0 )
                      nOffset = nSrcStrLen + nOffset;
                  else
                      nOffset = 0;
              }

              if( nSize < 0 || nOffset > nSrcStrLen )
              {
                  nOffset = 0;
                  nSize = 0;
              }
              else if( nOffset + nSize > nSrcStrLen )
                  nSize = nSrcStrLen - nOffset;

              CPLString osResult = pszSrcStr + nOffset;
              if( (int)osResult.size() > nSize )
                  osResult.resize( nSize );

              poRet->string_value = CPLStrdup(osResult);
              poRet->is_null = sub_node_values[0]->is_null;
              break;
          }

          case SWQ_HSTORE_GET_VALUE:
          {
              const char *pszHStore = sub_node_values[0]->string_value;
              const char *pszSearchedKey = sub_node_values[1]->string_value;
              char* pszRet = OGRHStoreGetValue(pszHStore, pszSearchedKey);
              poRet->string_value = pszRet ? pszRet : CPLStrdup("");
              poRet->is_null = (pszRet == NULL);
              break;
          }

          default:
            CPLAssert( false );
            delete poRet;
            poRet = NULL;
            break;
        }
    }

    return poRet;
}
예제 #7
0
swq_expr_node *SWQCastEvaluator( swq_expr_node *node,
                                 swq_expr_node **sub_node_values )

{
    swq_expr_node *poRetNode = NULL;
    swq_expr_node *poSrcNode = sub_node_values[0];

    switch( node->field_type )
    {
        case SWQ_INTEGER:
        {
            poRetNode = new swq_expr_node( 0 );
            poRetNode->is_null = poSrcNode->is_null;

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_BOOLEAN:
                    poRetNode->int_value = poSrcNode->int_value;
                    break;

                case SWQ_INTEGER64:
                    // TODO: warn in case of overflow ?
                    poRetNode->int_value = (int) poSrcNode->int_value;
                    break;

                case SWQ_FLOAT:
                    poRetNode->int_value = (int) poSrcNode->float_value;
                    break;

                default:
                    poRetNode->int_value = atoi(poSrcNode->string_value);
                    break;
            }
        }
        break;

        case SWQ_INTEGER64:
        {
            poRetNode = new swq_expr_node( 0 );
            poRetNode->is_null = poSrcNode->is_null;
            poRetNode->field_type = SWQ_INTEGER64;

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_INTEGER64:
                case SWQ_BOOLEAN:
                    poRetNode->int_value = poSrcNode->int_value;
                    break;

                case SWQ_FLOAT:
                    poRetNode->int_value = (GIntBig) poSrcNode->float_value;
                    break;

                default:
                    poRetNode->int_value = CPLAtoGIntBig(poSrcNode->string_value);
                    break;
            }
        }
        break;

        case SWQ_FLOAT:
        {
            poRetNode = new swq_expr_node( 0.0 );
            poRetNode->is_null = poSrcNode->is_null;

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_INTEGER64:
                case SWQ_BOOLEAN:
                    poRetNode->float_value = (double) poSrcNode->int_value;
                    break;

                case SWQ_FLOAT:
                    poRetNode->float_value = poSrcNode->float_value;
                    break;

                default:
                    poRetNode->float_value = CPLAtof(poSrcNode->string_value);
                    break;
            }
        }
        break;

        case SWQ_GEOMETRY:
        {
            poRetNode = new swq_expr_node( (OGRGeometry*) NULL );
            if( !poSrcNode->is_null )
            {
                switch( poSrcNode->field_type )
                {
                    case SWQ_GEOMETRY:
                    {
                        poRetNode->geometry_value =
                            poSrcNode->geometry_value->clone();
                        poRetNode->is_null = FALSE;
                        break;
                    }

                    case SWQ_STRING:
                    {
                        char* pszTmp = poSrcNode->string_value;
                        OGRGeometryFactory::createFromWkt(&pszTmp, NULL,
                            &(poRetNode->geometry_value));
                        if( poRetNode->geometry_value != NULL )
                            poRetNode->is_null = FALSE;
                        break;
                    }

                    default:
                        break;
                }
            }
            break;
        }

        // everything else is a string.
        default:
        {
            CPLString osRet;

            switch( poSrcNode->field_type )
            {
                case SWQ_INTEGER:
                case SWQ_BOOLEAN:
                case SWQ_INTEGER64:
                    osRet.Printf( CPL_FRMT_GIB, poSrcNode->int_value );
                    break;

                case SWQ_FLOAT:
                    osRet.Printf( "%.15g", poSrcNode->float_value );
                    break;

                case SWQ_GEOMETRY:
                {
                    if( poSrcNode->geometry_value != NULL )
                    {
                        char* pszWKT = NULL;
                        poSrcNode->geometry_value->exportToWkt(&pszWKT);
                        osRet = pszWKT;
                        CPLFree(pszWKT);
                    }
                    else
                        osRet = "";
                    break;
                }

                default:
                    osRet = poSrcNode->string_value;
                    break;
            }

            if( node->nSubExprCount > 2 )
            {
                int nWidth;

                nWidth = (int) sub_node_values[2]->int_value;
                if( nWidth > 0 && (int) strlen(osRet) > nWidth )
                    osRet.resize(nWidth);
            }

            poRetNode = new swq_expr_node( osRet.c_str() );
            poRetNode->is_null = poSrcNode->is_null;
        }
    }

    return poRetNode;
}
예제 #8
0
void OGROSMLayer::AddComputedAttribute(const char* pszName,
                                       OGRFieldType eType,
                                       const char* pszSQL)
{
    if( poDS->hDBForComputedAttributes == NULL )
    {
        int rc;
#ifdef HAVE_SQLITE_VFS
        rc = sqlite3_open_v2( ":memory:", &(poDS->hDBForComputedAttributes),
                              SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL );
#else
        rc = sqlite3_open( ":memory:", &(poDS->hDBForComputedAttributes) );
#endif
        if( rc != SQLITE_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Cannot open temporary sqlite DB" );
            return;
        }
    }

    if( poFeatureDefn->GetFieldIndex(pszName) >= 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "A field with same name %s already exists", pszName );
        return;
    }

    CPLString osSQL(pszSQL);
    std::vector<CPLString> aosAttrToBind;
    std::vector<int> anIndexToBind;
    size_t nStartSearch = 0;
    while(TRUE)
    {
        size_t nPos = osSQL.find("[", nStartSearch);
        if( nPos == std::string::npos )
            break;
        nStartSearch = nPos + 1;
        if( nPos > 0 && osSQL[nPos-1] != '\\' )
        {
            CPLString osAttr = osSQL.substr(nPos + 1);
            size_t nPos2 = osAttr.find("]");
            if( nPos2 == std::string::npos )
                break;
            osAttr.resize(nPos2);

            osSQL = osSQL.substr(0, nPos) + "?" + osSQL.substr(nPos + 1 + nPos2+1);

            aosAttrToBind.push_back(osAttr);
            anIndexToBind.push_back(poFeatureDefn->GetFieldIndex(osAttr));
        }
    }
    while(TRUE)
    {
        size_t nPos = osSQL.find("\\");
        if( nPos == std::string::npos || nPos == osSQL.size() - 1 )
            break;
        osSQL = osSQL.substr(0, nPos) + osSQL.substr(nPos + 1);
    }

    CPLDebug("OSM", "SQL : \"%s\"", osSQL.c_str());

    sqlite3_stmt  *hStmt;
    int rc = sqlite3_prepare( poDS->hDBForComputedAttributes, osSQL, -1,
                              &hStmt, NULL );
    if( rc != SQLITE_OK )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "sqlite3_prepare() failed :  %s",
                  sqlite3_errmsg(poDS->hDBForComputedAttributes) );
        return;
    }

    OGRFieldDefn oField(pszName, eType);
    poFeatureDefn->AddFieldDefn(&oField);
    oComputedAttributes.push_back(OGROSMComputedAttribute(pszName));
    oComputedAttributes[oComputedAttributes.size()-1].eType = eType;
    oComputedAttributes[oComputedAttributes.size()-1].nIndex = poFeatureDefn->GetFieldCount() - 1;
    oComputedAttributes[oComputedAttributes.size()-1].osSQL = pszSQL;
    oComputedAttributes[oComputedAttributes.size()-1].hStmt = hStmt;
    oComputedAttributes[oComputedAttributes.size()-1].aosAttrToBind = aosAttrToBind;
    oComputedAttributes[oComputedAttributes.size()-1].anIndexToBind = anIndexToBind;
}
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"))
        {
            CPLDebug("WFS", "Attribute refers to a OGR special field. Cannot use server-side filtering");
            return FALSE;
        }

        const char* pszFieldname;
        CPLString osVal;
        if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"')
        {
            osVal = expr->pszVal + 1;
            osVal.resize(osVal.size() - 1);
            pszFieldname = osVal.c_str();
        }
        else
            pszFieldname = expr->pszVal;

        if (psOptions->poFDefn->GetFieldIndex(pszFieldname) == -1)
        {
            CPLDebug("WFS", "Field '%s' unknown. Cannot use server-side filtering",
                     pszFieldname);
            return FALSE;
        }

        if (psOptions->nVersion >= 200)
            osFilter += "<ValueReference>";
        else
            osFilter += "<PropertyName>";
        char* pszFieldnameXML = CPLEscapeString(pszFieldname, -1, CPLES_XML);
        osFilter += pszFieldnameXML;
        CPLFree(pszFieldnameXML);
        if (psOptions->nVersion >= 200)
            osFilter += "</ValueReference>";
        else
            osFilter += "</PropertyName>";
        break;
    }

    case TOKEN_LITERAL:
    {
        if (bExpectBinary)
            return FALSE;

        const char* pszLiteral;
        CPLString osVal;
        if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"')
        {
            osVal = expr->pszVal + 1;
            osVal.resize(osVal.size() - 1);
            pszLiteral = osVal.c_str();
        }
        else
            pszLiteral = expr->pszVal;

        osFilter += "<Literal>";
        char* pszLiteralXML = CPLEscapeString(pszLiteral, -1, CPLES_XML);
        osFilter += pszLiteralXML;
        CPLFree(pszLiteralXML);
        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;
}
예제 #10
0
bool VSIDIRAz::AnalyseAzureFileList(
    const CPLString& osBaseURL,
    const char* pszXML)
{
#if DEBUG_VERBOSE
    CPLDebug("AZURE", "%s", pszXML);
#endif

    CPLXMLNode* psTree = CPLParseXMLString(pszXML);
    if( psTree == nullptr )
        return false;
    CPLXMLNode* psEnumerationResults = CPLGetXMLNode(psTree, "=EnumerationResults");

    bool bNonEmpty = false;
    if( psEnumerationResults )
    {
        CPLString osPrefix = CPLGetXMLValue(psEnumerationResults, "Prefix", "");
        CPLXMLNode* psBlobs = CPLGetXMLNode(psEnumerationResults, "Blobs");
        if( psBlobs == nullptr )
        {
            psBlobs = CPLGetXMLNode(psEnumerationResults, "Containers");
            if( psBlobs != nullptr )
                bNonEmpty = true;
        }

        // Count the number of occurrences of a path. Can be 1 or 2. 2 in the case
        // that both a filename and directory exist
        std::map<CPLString, int> aoNameCount;
        for(CPLXMLNode* psIter = psBlobs ? psBlobs->psChild : nullptr;
            psIter != nullptr; psIter = psIter->psNext )
        {
            if( psIter->eType != CXT_Element )
                continue;
            if( strcmp(psIter->pszValue, "Blob") == 0 )
            {
                const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr);
                if( pszKey && strstr(pszKey, GDAL_MARKER_FOR_DIR) != nullptr )
                {
                    bNonEmpty = true;
                }
                else if( pszKey && strlen(pszKey) > osPrefix.size() )
                {
                    bNonEmpty = true;
                    aoNameCount[pszKey + osPrefix.size()] ++;
                }
            }
            else if( strcmp(psIter->pszValue, "BlobPrefix") == 0 ||
                     strcmp(psIter->pszValue, "Container") == 0 )
            {
                bNonEmpty = true;

                const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr);
                if( pszKey && strncmp(pszKey, osPrefix, osPrefix.size()) == 0 )
                {
                    CPLString osKey = pszKey;
                    if( !osKey.empty() && osKey.back() == '/' )
                        osKey.resize(osKey.size()-1);
                    if( osKey.size() > osPrefix.size() )
                    {
                        aoNameCount[osKey.c_str() + osPrefix.size()] ++;
                    }
                }
            }
        }

        for(CPLXMLNode* psIter = psBlobs ? psBlobs->psChild : nullptr;
            psIter != nullptr; psIter = psIter->psNext )
        {
            if( psIter->eType != CXT_Element )
                continue;
            if( strcmp(psIter->pszValue, "Blob") == 0 )
            {
                const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr);
                if( pszKey && strstr(pszKey, GDAL_MARKER_FOR_DIR) != nullptr )
                {
                    if( nRecurseDepth < 0 )
                    {
                        aoEntries.push_back(
                            std::unique_ptr<VSIDIREntry>(new VSIDIREntry()));
                        auto& entry = aoEntries.back();
                        entry->pszName = CPLStrdup(pszKey + osPrefix.size());
                        char* pszMarker = strstr(entry->pszName, GDAL_MARKER_FOR_DIR);
                        if( pszMarker )
                            *pszMarker = '\0';
                        entry->nMode = S_IFDIR;
                        entry->bModeKnown = true;
                    }
                }
                else if( pszKey && strlen(pszKey) > osPrefix.size() )
                {
                    aoEntries.push_back(
                        std::unique_ptr<VSIDIREntry>(new VSIDIREntry()));
                    auto& entry = aoEntries.back();
                    entry->pszName = CPLStrdup(pszKey + osPrefix.size());
                    entry->nSize = static_cast<GUIntBig>(
                        CPLAtoGIntBig(CPLGetXMLValue(psIter, "Properties.Content-Length", "0")));
                    entry->bSizeKnown = true;
                    entry->nMode = S_IFDIR;
                    entry->bModeKnown = true;

                    CPLString ETag = CPLGetXMLValue(psIter, "Etag", "");
                    if( !ETag.empty() )
                    {
                        entry->papszExtra = CSLSetNameValue(
                            entry->papszExtra, "ETag", ETag.c_str());
                    }

                    int nYear, nMonth, nDay, nHour, nMinute, nSecond;
                    if( CPLParseRFC822DateTime(
                        CPLGetXMLValue(psIter, "Properties.Last-Modified", ""),
                                                    &nYear,
                                                    &nMonth,
                                                    &nDay,
                                                    &nHour,
                                                    &nMinute,
                                                    &nSecond,
                                                    nullptr,
                                                    nullptr ) )
                    {
                        struct tm brokendowntime;
                        brokendowntime.tm_year = nYear - 1900;
                        brokendowntime.tm_mon = nMonth - 1;
                        brokendowntime.tm_mday = nDay;
                        brokendowntime.tm_hour = nHour;
                        brokendowntime.tm_min = nMinute;
                        brokendowntime.tm_sec = nSecond < 0 ? 0 : nSecond;
                        entry->nMTime =
                                CPLYMDHMSToUnixTime(&brokendowntime);
                        entry->bMTimeKnown = true;
                    }

                    if( bCacheResults )
                    {
                        FileProp prop;
                        prop.eExists = EXIST_YES;
                        prop.bHasComputedFileSize = true;
                        prop.fileSize = entry->nSize;
                        prop.bIsDirectory = false;
                        prop.mTime = static_cast<time_t>(entry->nMTime);
                        prop.ETag = ETag;

                        CPLString osCachedFilename =
                            osBaseURL + "/" + osPrefix + entry->pszName;
#if DEBUG_VERBOSE
                        CPLDebug("AZURE", "Cache %s", osCachedFilename.c_str());
#endif
                        poFS->SetCachedFileProp(osCachedFilename, prop);
                    }
                }
            }
            else if( strcmp(psIter->pszValue, "BlobPrefix") == 0 ||
                     strcmp(psIter->pszValue, "Container") == 0 )
            {
                const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr);
                if( pszKey && strncmp(pszKey, osPrefix, osPrefix.size()) == 0 )
                {
                    CPLString osKey = pszKey;
                    if( !osKey.empty() && osKey.back() == '/' )
                        osKey.resize(osKey.size()-1);
                    if( osKey.size() > osPrefix.size() )
                    {
                        aoEntries.push_back(
                            std::unique_ptr<VSIDIREntry>(new VSIDIREntry()));
                        auto& entry = aoEntries.back();
                        entry->pszName = CPLStrdup(osKey.c_str() + osPrefix.size());
                        if( aoNameCount[entry->pszName] == 2 )
                        {
                            // Add a / suffix to disambiguish the situation
                            // Normally we don't suffix directories with /, but
                            // we have no alternative here
                            CPLString osTemp(entry->pszName);
                            osTemp += '/';
                            CPLFree(entry->pszName);
                            entry->pszName = CPLStrdup(osTemp);
                        }
                        entry->nMode = S_IFDIR;
                        entry->bModeKnown = true;

                        if( bCacheResults )
                        {
                            FileProp prop;
                            prop.eExists = EXIST_YES;
                            prop.bIsDirectory = true;
                            prop.bHasComputedFileSize = true;
                            prop.fileSize = 0;
                            prop.mTime = 0;

                            CPLString osCachedFilename =
                                osBaseURL + "/" + osPrefix + entry->pszName;
#if DEBUG_VERBOSE
                            CPLDebug("AZURE", "Cache %s", osCachedFilename.c_str());
#endif
                            poFS->SetCachedFileProp(osCachedFilename, prop);
                        }
                    }
                }
            }

            if( nMaxFiles > 0 && aoEntries.size() > static_cast<unsigned>(nMaxFiles) )
                break;
        }

        osNextMarker = CPLGetXMLValue(psEnumerationResults, "NextMarker", "");
    }
    CPLDestroyXMLNode(psTree);

    return bNonEmpty;
}
예제 #11
0
static CPLString GetProj4Filename(const char* pszFilename)
{
    CPLString osFilename;

    /* or fixed path: /name, ./name or ../name */
    if ( !CPLIsFilenameRelative(pszFilename) || *pszFilename == '.' )
    {
        return pszFilename;
    }

#if defined(PROJ_STATIC) && PROJ_VERSION >= 5
    PJ_GRID_INFO info = proj_grid_info(pszFilename);
    if( info.filename[0] )
    {
        osFilename = info.filename;
    }
#elif defined(PROJ_STATIC) && PJ_VERSION > 493
    osFilename.resize(2048);
    projCtx ctx = pj_ctx_alloc();
    if( pj_find_file(ctx, pszFilename, &osFilename[0], osFilename.size()) )
    {
        osFilename.resize( strlen(osFilename) );
    }
    else
    {
        osFilename.clear();
    }
    pj_ctx_free(ctx);
#else
    // Transpose some of the proj.4 pj_open_lib() logic...

    /* check if ~/name */
    char* pszSysname;
    if (*pszFilename == '~' &&
        (pszFilename[1] == '/' || pszFilename[1] == '\\') )
    {
        if ((pszSysname = getenv("HOME")) != nullptr)
        {
            osFilename = CPLFormFilename(pszSysname, pszFilename + 1, nullptr);
        }
        return osFilename;
    }

    /* or is environment PROJ_LIB defined */
    else if ((pszSysname = getenv("PROJ_LIB")) != nullptr)
    {
        osFilename = CPLFormFilename(pszSysname, pszFilename, nullptr);
        VSIStatBufL sStat;
        if( VSIStatL(osFilename, &sStat) == 0 )
            return osFilename;
        osFilename.clear();
    }


#if defined(PROJ_STATIC) && PJ_VERSION >= 490
    // Super messy. proj.4 up to 4.9.3 had no public API to return the full
    // path to a resource file, so we rely on the fact that it emits a log
    // message with it...
    // Basically this is needed in the case where the file is in the
    // resource installation directory of proj.4, which we have no way to
    // know otherwise.
    CPLString osMsg;
    projCtx ctx = pj_ctx_alloc();
    pj_ctx_set_app_data(ctx, &osMsg);
    pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR);
    pj_ctx_set_logger(ctx, my_proj4_logger);
    PAFile f = pj_open_lib(ctx, pszFilename, "rb");
    if( f )
    {
        pj_ctx_fclose(ctx, f);
        size_t nPos = osMsg.find("fopen(");
        if( nPos != std::string::npos )
        {
            osFilename = osMsg.substr(nPos + strlen("fopen("));
            nPos = osFilename.find(")");
            if( nPos != std::string::npos )
                osFilename = osFilename.substr(0, nPos);
        }
    }
    pj_ctx_free(ctx);
#endif
#endif
    return osFilename;
}
예제 #12
0
/*!
  \brief VFKReaderSQLite constructor
*/
VFKReaderSQLite::VFKReaderSQLite(const char *pszFilename) : VFKReader(pszFilename)
{
    const char *pszDbNameConf;
    CPLString   osDbName;
    CPLString   osCommand;
    VSIStatBufL sStatBufDb, sStatBufVfk;

    /* open tmp SQLite DB (re-use DB file if already exists) */
    pszDbNameConf = CPLGetConfigOption("OGR_VFK_DB_NAME", NULL);
    if (pszDbNameConf) {
	osDbName = pszDbNameConf;
    }
    else {
	osDbName = CPLResetExtension(m_pszFilename, "db");
    }
    size_t nLen = osDbName.length();
    if( nLen > 2048 )
    {
        nLen = 2048;
        osDbName.resize(nLen);
    }
    m_pszDBname = new char [nLen+1];
    std::strncpy(m_pszDBname, osDbName.c_str(), nLen);
    m_pszDBname[nLen] = 0;
    CPLDebug("OGR-VFK", "Using internal DB: %s",
             m_pszDBname);

    if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_SPATIAL", "YES")))
	m_bSpatial = TRUE;    /* build geometry from DB */
    else
	m_bSpatial = FALSE;   /* store also geometry in DB */

    m_bNewDb = TRUE;
    if (VSIStatL(osDbName, &sStatBufDb) == 0) {
	if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_OVERWRITE", "NO"))) {
	    m_bNewDb = TRUE;     /* overwrite existing DB */
            CPLDebug("OGR-VFK", "Internal DB (%s) already exists and will be overwritten",
                     m_pszDBname);
	    VSIUnlink(osDbName);
        }
        else {
            if (VSIStatL(pszFilename, &sStatBufVfk) == 0 &&
                sStatBufVfk.st_mtime > sStatBufDb.st_mtime) {
                CPLDebug("OGR-VFK",
                         "Found %s but ignoring because it appears\n"
                         "be older than the associated VFK file.",
                         osDbName.c_str());
                m_bNewDb = TRUE;
                VSIUnlink(osDbName);
            }
            else {
                m_bNewDb = FALSE;    /* re-use existing DB */
            }
        }
    }

    /*
    if (m_bNewDb) {
      CPLError(CE_Warning, CPLE_AppDefined,
               "INFO: No internal SQLite DB found. Reading VFK data may take some time...");
    }
    */

    CPLDebug("OGR-VFK", "New DB: %s Spatial: %s",
	     m_bNewDb ? "yes" : "no", m_bSpatial ? "yes" : "no");

    if (SQLITE_OK != sqlite3_open(osDbName, &m_poDB)) {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Creating SQLite DB failed");
    }
    else {
        char* pszErrMsg = NULL;
        CPL_IGNORE_RET_VAL(sqlite3_exec(m_poDB, "PRAGMA synchronous = OFF", NULL, NULL, &pszErrMsg));
        sqlite3_free(pszErrMsg);
    }

    if (m_bNewDb) {
        /* new DB, create support metadata tables */
        osCommand.Printf("CREATE TABLE %s (file_name text, table_name text, num_records integer, "
                         "num_features integer, num_geometries integer, table_defn text)",
                         VFK_DB_TABLE);
        ExecuteSQL(osCommand.c_str());

        /* header table */
        osCommand.Printf("CREATE TABLE %s (key text, value text)", VFK_DB_HEADER);
        ExecuteSQL(osCommand.c_str());
    }
}
swq_expr_node *SWQGeneralEvaluator( swq_expr_node *node,
                                    swq_expr_node **sub_node_values )

{
    swq_expr_node *poRet = NULL;

/* -------------------------------------------------------------------- */
/*      Floating point operations.                                      */
/* -------------------------------------------------------------------- */
    if( sub_node_values[0]->field_type == SWQ_FLOAT 
        || (node->nSubExprCount > 1 
            && sub_node_values[1]->field_type == SWQ_FLOAT) )
            
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        if( sub_node_values[0]->field_type == SWQ_INTEGER )
            sub_node_values[0]->float_value = sub_node_values[0]->int_value;
        if( node->nSubExprCount > 1 &&
            sub_node_values[1]->field_type == SWQ_INTEGER )
            sub_node_values[1]->float_value = sub_node_values[1]->int_value;

        switch( (swq_op) node->nOperation )
        {
          case SWQ_EQ:
            poRet->int_value = sub_node_values[0]->float_value 
                == sub_node_values[1]->float_value;
            break;

          case SWQ_NE:
            poRet->int_value = sub_node_values[0]->float_value 
                != sub_node_values[1]->float_value;
            break;

          case SWQ_GT:
            poRet->int_value = sub_node_values[0]->float_value 
                > sub_node_values[1]->float_value;
            break;

          case SWQ_LT:
            poRet->int_value = sub_node_values[0]->float_value 
                < sub_node_values[1]->float_value;
            break;

          case SWQ_GE:
            poRet->int_value = sub_node_values[0]->float_value 
                >= sub_node_values[1]->float_value;
            break;

          case SWQ_LE:
            poRet->int_value = sub_node_values[0]->float_value 
                <= sub_node_values[1]->float_value;
            break;

          case SWQ_IN:
          {
              int i;
              poRet->int_value = 0;
              for( i = 1; i < node->nSubExprCount; i++ )
              {
                  if( sub_node_values[0]->float_value 
                      == sub_node_values[i]->float_value )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value = sub_node_values[0]->float_value
                                >= sub_node_values[1]->float_value &&
                               sub_node_values[0]->float_value
                                <= sub_node_values[2]->float_value;
            break;

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_ADD:
            poRet->float_value = sub_node_values[0]->float_value 
                + sub_node_values[1]->float_value;
            break;
            
          case SWQ_SUBTRACT:
            poRet->float_value = sub_node_values[0]->float_value 
                - sub_node_values[1]->float_value;
            break;
            
          case SWQ_MULTIPLY:
            poRet->float_value = sub_node_values[0]->float_value 
                * sub_node_values[1]->float_value;
            break;
            
          case SWQ_DIVIDE:
            if( sub_node_values[1]->float_value == 0 )
                poRet->float_value = INT_MAX;
            else
                poRet->float_value = sub_node_values[0]->float_value 
                    / sub_node_values[1]->float_value;
            break;
            
          case SWQ_MODULUS:
          {
            int nRight = (int) sub_node_values[1]->float_value;
            poRet->field_type = SWQ_INTEGER;
            if (nRight == 0)
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = ((int) sub_node_values[0]->float_value)
                    % nRight;
            break;
          }

          default:
            CPLAssert( FALSE );
            delete poRet;
            poRet = NULL;
            break;
        }
    }
/* -------------------------------------------------------------------- */
/*      integer/boolean operations.                                     */
/* -------------------------------------------------------------------- */
    else if( sub_node_values[0]->field_type == SWQ_INTEGER
        || sub_node_values[0]->field_type == SWQ_BOOLEAN )
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        switch( (swq_op) node->nOperation )
        {
          case SWQ_AND:
            poRet->int_value = sub_node_values[0]->int_value 
                && sub_node_values[1]->int_value;
            break;
            
          case SWQ_OR:
            poRet->int_value = sub_node_values[0]->int_value 
                || sub_node_values[1]->int_value;
            break;
            
          case SWQ_NOT:
            poRet->int_value = !sub_node_values[0]->int_value;
            break;
            
          case SWQ_EQ:
            poRet->int_value = sub_node_values[0]->int_value 
                == sub_node_values[1]->int_value;
            break;

          case SWQ_NE:
            poRet->int_value = sub_node_values[0]->int_value 
                != sub_node_values[1]->int_value;
            break;

          case SWQ_GT:
            poRet->int_value = sub_node_values[0]->int_value 
                > sub_node_values[1]->int_value;
            break;

          case SWQ_LT:
            poRet->int_value = sub_node_values[0]->int_value 
                < sub_node_values[1]->int_value;
            break;

          case SWQ_GE:
            poRet->int_value = sub_node_values[0]->int_value 
                >= sub_node_values[1]->int_value;
            break;

          case SWQ_LE:
            poRet->int_value = sub_node_values[0]->int_value 
                <= sub_node_values[1]->int_value;
            break;

          case SWQ_IN:
          {
              int i;
              poRet->int_value = 0;
              for( i = 1; i < node->nSubExprCount; i++ )
              {
                  if( sub_node_values[0]->int_value 
                      == sub_node_values[i]->int_value )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value = sub_node_values[0]->int_value
                                >= sub_node_values[1]->int_value &&
                               sub_node_values[0]->int_value
                                <= sub_node_values[2]->int_value;
            break;

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_ADD:
            poRet->int_value = sub_node_values[0]->int_value 
                + sub_node_values[1]->int_value;
            break;
            
          case SWQ_SUBTRACT:
            poRet->int_value = sub_node_values[0]->int_value 
                - sub_node_values[1]->int_value;
            break;
            
          case SWQ_MULTIPLY:
            poRet->int_value = sub_node_values[0]->int_value 
                * sub_node_values[1]->int_value;
            break;
            
          case SWQ_DIVIDE:
            if( sub_node_values[1]->int_value == 0 )
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = sub_node_values[0]->int_value 
                    / sub_node_values[1]->int_value;
            break;
            
          case SWQ_MODULUS:
            if( sub_node_values[1]->int_value == 0 )
                poRet->int_value = INT_MAX;
            else
                poRet->int_value = sub_node_values[0]->int_value
                    % sub_node_values[1]->int_value;
            break;
            
          default:
            CPLAssert( FALSE );
            delete poRet;
            poRet = NULL;
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      String operations.                                              */
/* -------------------------------------------------------------------- */
    else
    {
        poRet = new swq_expr_node(0);
        poRet->field_type = node->field_type;

        switch( (swq_op) node->nOperation )
        {
          case SWQ_EQ:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) == 0;
            break;

          case SWQ_NE:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) != 0;
            break;

          case SWQ_GT:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) > 0;
            break;

          case SWQ_LT:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) < 0;
            break;

          case SWQ_GE:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) >= 0;
            break;

          case SWQ_LE:
            poRet->int_value = 
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) <= 0;
            break;

          case SWQ_IN:
          {
              int i;
              poRet->int_value = 0;
              for( i = 1; i < node->nSubExprCount; i++ )
              {
                  if( strcasecmp(sub_node_values[0]->string_value,
                                 sub_node_values[i]->string_value) == 0 )
                  {
                      poRet->int_value = 1;
                      break;
                  }
              }
          }
          break;

          case SWQ_BETWEEN:
            poRet->int_value =
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[1]->string_value) >= 0 &&
                strcasecmp(sub_node_values[0]->string_value,
                           sub_node_values[2]->string_value) <= 0;
            break;

          case SWQ_LIKE:
            poRet->int_value = swq_test_like(sub_node_values[0]->string_value,
                                             sub_node_values[1]->string_value);
            break;

          case SWQ_ISNULL:
            poRet->int_value = sub_node_values[0]->is_null;
            break;

          case SWQ_CONCAT:
          case SWQ_ADD:
          {
              CPLString osResult = sub_node_values[0]->string_value;
              int i;

              for( i = 1; i < node->nSubExprCount; i++ )
                  osResult += sub_node_values[i]->string_value;
              
              poRet->string_value = CPLStrdup(osResult);
              break;
          }
            
          case SWQ_SUBSTR:
          {
              int nOffset, nSize;
              const char *pszSrcStr = sub_node_values[0]->string_value;

              if( sub_node_values[1]->field_type == SWQ_INTEGER )
                  nOffset = sub_node_values[1]->int_value;
              else if( sub_node_values[1]->field_type == SWQ_FLOAT )
                  nOffset = (int) sub_node_values[1]->float_value; 
              else
                  nOffset = 0;

              if( node->nSubExprCount < 3 )
                  nSize = 100000;
              else if( sub_node_values[2]->field_type == SWQ_INTEGER )
                  nSize = sub_node_values[2]->int_value;
              else if( sub_node_values[2]->field_type == SWQ_FLOAT )
                  nSize = (int) sub_node_values[2]->float_value; 
              else
                  nSize = 0;

              int nSrcStrLen = (int)strlen(pszSrcStr);
              if( nOffset < 0 || nSize < 0 || nOffset > nSrcStrLen )
              {
                  nOffset = 0;
                  nSize = 0;
              }
              else if( nOffset + nSize > nSrcStrLen )
                  nSize = nSrcStrLen - nOffset;

              CPLString osResult = pszSrcStr + nOffset;
              if( (int)osResult.size() > nSize )
                  osResult.resize( nSize );
              
              poRet->string_value = CPLStrdup(osResult);
              break;
          }

          default:
            CPLAssert( FALSE );
            delete poRet;
            poRet = NULL;
            break;
        }
    }

    return poRet;
}
예제 #14
0
static
CPLXMLNode * GDALWMSDatasetGetConfigFromURL(GDALOpenInfo *poOpenInfo)
{
    const char* pszBaseURL = poOpenInfo->pszFilename;
    if (EQUALN(pszBaseURL, "WMS:", 4))
        pszBaseURL += 4;

    CPLString osLayer = CPLURLGetValue(pszBaseURL, "LAYERS");
    CPLString osVersion = CPLURLGetValue(pszBaseURL, "VERSION");
    CPLString osSRS = CPLURLGetValue(pszBaseURL, "SRS");
    CPLString osCRS = CPLURLGetValue(pszBaseURL, "CRS");
    CPLString osBBOX = CPLURLGetValue(pszBaseURL, "BBOX");
    CPLString osFormat = CPLURLGetValue(pszBaseURL, "FORMAT");
    CPLString osTransparent = CPLURLGetValue(pszBaseURL, "TRANSPARENT");

    /* GDAL specific extensions to alter the default settings */
    CPLString osOverviewCount = CPLURLGetValue(pszBaseURL, "OVERVIEWCOUNT");
    CPLString osTileSize = CPLURLGetValue(pszBaseURL, "TILESIZE");
    CPLString osMinResolution = CPLURLGetValue(pszBaseURL, "MINRESOLUTION");
    CPLString osBBOXOrder = CPLURLGetValue(pszBaseURL, "BBOXORDER");

    CPLString osBaseURL = pszBaseURL;
    /* Remove all keywords to get base URL */

    osBaseURL = CPLURLAddKVP(osBaseURL, "VERSION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "REQUEST", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "LAYERS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "SRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "CRS", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOX", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "FORMAT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TRANSPARENT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "STYLES", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "WIDTH", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "HEIGHT", NULL);

    osBaseURL = CPLURLAddKVP(osBaseURL, "OVERVIEWCOUNT", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "TILESIZE", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "MINRESOLUTION", NULL);
    osBaseURL = CPLURLAddKVP(osBaseURL, "BBOXORDER", NULL);

    if (osBaseURL.size() > 0 && osBaseURL[osBaseURL.size() - 1] == '&')
        osBaseURL.resize(osBaseURL.size() - 1);

    if (osVersion.size() == 0)
        osVersion = "1.1.1";

    CPLString osSRSTag;
    CPLString osSRSValue;
    if(VersionStringToInt(osVersion.c_str())>= VersionStringToInt("1.3.0"))
    {
        if (osSRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.3 and above expects CRS however SRS was set instead.");
        }
        osSRSValue = osCRS;
        osSRSTag = "CRS";
    }
    else
    {
        if (osCRS.size())
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "WMS version 1.1.1 and below expects SRS however CRS was set instead.");
        }
        osSRSValue = osSRS;
        osSRSTag = "SRS";
    }

    if (osSRSValue.size() == 0)
        osSRSValue = "EPSG:4326";
    
    if (osBBOX.size() == 0)
    {
        if (osBBOXOrder.compare("yxYX") == 0)
            osBBOX = "-90,-180,90,180";
        else
            osBBOX = "-180,-90,180,90";
    }

    char** papszTokens = CSLTokenizeStringComplex(osBBOX, ",", 0, 0);
    if (CSLCount(papszTokens) != 4)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }
    const char* pszMinX = papszTokens[0];
    const char* pszMinY = papszTokens[1];
    const char* pszMaxX = papszTokens[2];
    const char* pszMaxY = papszTokens[3];

    if (osBBOXOrder.compare("yxYX") == 0)
    {
        std::swap(pszMinX, pszMinY);
        std::swap(pszMaxX, pszMaxY);
    }

    double dfMinX = CPLAtofM(pszMinX);
    double dfMinY = CPLAtofM(pszMinY);
    double dfMaxX = CPLAtofM(pszMaxX);
    double dfMaxY = CPLAtofM(pszMaxY);

    if (dfMaxY <= dfMinY || dfMaxX <= dfMinX)
    {
        CSLDestroy(papszTokens);
        return NULL;
    }

    int nTileSize = atoi(osTileSize);
    if (nTileSize <= 128 || nTileSize > 2048)
        nTileSize = 1024;

    int nXSize, nYSize;

    int nOverviewCount = (osOverviewCount.size()) ? atoi(osOverviewCount) : 20;

    if (osMinResolution.size() != 0)
    {
        double dfMinResolution = CPLAtofM(osMinResolution);

        while (nOverviewCount > 20)
        {
            nOverviewCount --;
            dfMinResolution *= 2;
        }

        nXSize = (int) ((dfMaxX - dfMinX) / dfMinResolution + 0.5);
        nYSize = (int) ((dfMaxY - dfMinY) / dfMinResolution + 0.5);
    }
    else
    {
        double dfRatio = (dfMaxX - dfMinX) / (dfMaxY - dfMinY);
        if (dfRatio > 1)
        {
            nXSize = nTileSize;
            nYSize = (int) (nXSize / dfRatio);
        }
        else
        {
            nYSize = nTileSize;
            nXSize = (int) (nYSize * dfRatio);
        }

        if (nOverviewCount < 0 || nOverviewCount > 20)
            nOverviewCount = 20;

        nXSize = nXSize * (1 << nOverviewCount);
        nYSize = nYSize * (1 << nOverviewCount);
    }

    int bTransparent = osTransparent.size() ? CSLTestBoolean(osTransparent) : FALSE;

    if (osFormat.size() == 0)
    {
        if (!bTransparent)
        {
            osFormat = "image/jpeg";
        }
        else
        {
            osFormat = "image/png";
        }
    }

    char* pszEscapedURL = CPLEscapeString(osBaseURL.c_str(), -1, CPLES_XML);
    char* pszEscapedLayerURL = CPLEscapeString(osLayer.c_str(), -1, CPLES_URL);
    char* pszEscapedLayerXML = CPLEscapeString(pszEscapedLayerURL, -1, CPLES_XML);

    CPLString osXML = CPLSPrintf(
            "<GDAL_WMS>\n"
            "  <Service name=\"WMS\">\n"
            "    <Version>%s</Version>\n"
            "    <ServerUrl>%s</ServerUrl>\n"
            "    <Layers>%s</Layers>\n"
            "    <%s>%s</%s>\n"
            "    <ImageFormat>%s</ImageFormat>\n"
            "    <Transparent>%s</Transparent>\n"
            "    <BBoxOrder>%s</BBoxOrder>\n"
            "  </Service>\n"
            "  <DataWindow>\n"
            "    <UpperLeftX>%s</UpperLeftX>\n"
            "    <UpperLeftY>%s</UpperLeftY>\n"
            "    <LowerRightX>%s</LowerRightX>\n"
            "    <LowerRightY>%s</LowerRightY>\n"
            "    <SizeX>%d</SizeX>\n"
            "    <SizeY>%d</SizeY>\n"
            "  </DataWindow>\n"
            "  <BandsCount>%d</BandsCount>\n"
            "  <BlockSizeX>%d</BlockSizeX>\n"
            "  <BlockSizeY>%d</BlockSizeY>\n"
            "  <OverviewCount>%d</OverviewCount>\n"
            "</GDAL_WMS>\n",
            osVersion.c_str(),
            pszEscapedURL,
            pszEscapedLayerXML,
            osSRSTag.c_str(),
            osSRSValue.c_str(),
            osSRSTag.c_str(),
            osFormat.c_str(),
            (bTransparent) ? "TRUE" : "FALSE",
            (osBBOXOrder.size()) ? osBBOXOrder.c_str() : "xyXY",
            pszMinX, pszMaxY, pszMaxX, pszMinY,
            nXSize, nYSize,
            (bTransparent) ? 4 : 3,
            nTileSize, nTileSize,
            nOverviewCount);

    CPLFree(pszEscapedURL);
    CPLFree(pszEscapedLayerURL);
    CPLFree(pszEscapedLayerXML);

    CSLDestroy(papszTokens);

    CPLDebug("WMS", "Opening WMS :\n%s", osXML.c_str());

    return CPLParseXMLString(osXML);
}
예제 #15
0
static
CPLXMLNode * GDALWMSDatasetGetConfigFromTileMap(CPLXMLNode* psXML)
{
    CPLXMLNode* psRoot = CPLGetXMLNode( psXML, "=TileMap" );
    if (psRoot == NULL)
        return NULL;

    CPLXMLNode* psTileSets = CPLGetXMLNode(psRoot, "TileSets");
    if (psTileSets == NULL)
        return NULL;

    const char* pszURL = CPLGetXMLValue(psRoot, "tilemapservice", NULL);

    int bCanChangeURL = TRUE;

    CPLString osURL;
    if (pszURL)
    {
        osURL = pszURL;
        /* Special hack for http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/ */
        if (strlen(pszURL) > 10 &&
            strncmp(pszURL, "http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/",
                            strlen("http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/")) == 0 &&
            strcmp(pszURL + strlen(pszURL) - strlen("1.0.0/"), "1.0.0/") == 0)
        {
            osURL.resize(strlen(pszURL) - strlen("1.0.0/"));
            bCanChangeURL = FALSE;
        }
        osURL += "${z}/${x}/${y}.${format}";
    }

    const char* pszSRS = CPLGetXMLValue(psRoot, "SRS", NULL);
    if (pszSRS == NULL)
        return NULL;

    CPLXMLNode* psBoundingBox = CPLGetXMLNode( psRoot, "BoundingBox" );
    if (psBoundingBox == NULL)
        return NULL;

    const char* pszMinX = CPLGetXMLValue(psBoundingBox, "minx", NULL);
    const char* pszMinY = CPLGetXMLValue(psBoundingBox, "miny", NULL);
    const char* pszMaxX = CPLGetXMLValue(psBoundingBox, "maxx", NULL);
    const char* pszMaxY = CPLGetXMLValue(psBoundingBox, "maxy", NULL);
    if (pszMinX == NULL || pszMinY == NULL || pszMaxX == NULL || pszMaxY == NULL)
        return NULL;

    double dfMinX = CPLAtofM(pszMinX);
    double dfMinY = CPLAtofM(pszMinY);
    double dfMaxX = CPLAtofM(pszMaxX);
    double dfMaxY = CPLAtofM(pszMaxY);
    if (dfMaxY <= dfMinY || dfMaxX <= dfMinX)
        return NULL;

    CPLXMLNode* psTileFormat = CPLGetXMLNode( psRoot, "TileFormat" );
    if (psTileFormat == NULL)
        return NULL;

    const char* pszTileWidth = CPLGetXMLValue(psTileFormat, "width", NULL);
    const char* pszTileHeight = CPLGetXMLValue(psTileFormat, "height", NULL);
    const char* pszTileFormat = CPLGetXMLValue(psTileFormat, "extension", NULL);
    if (pszTileWidth == NULL || pszTileHeight == NULL || pszTileFormat == NULL)
        return NULL;

    int nTileWidth = atoi(pszTileWidth);
    int nTileHeight = atoi(pszTileHeight);
    if (nTileWidth < 128 || nTileHeight < 128)
        return NULL;

    CPLXMLNode* psIter = psTileSets->psChild;
    int nLevelCount = 0;
    double dfPixelSize = 0;
    for(; psIter != NULL; psIter = psIter->psNext)
    {
        if (psIter->eType == CXT_Element &&
            EQUAL(psIter->pszValue, "TileSet"))
        {
            const char* pszOrder =
                CPLGetXMLValue(psIter, "order", NULL);
            if (pszOrder == NULL)
            {
                CPLDebug("WMS", "Cannot find order attribute");
                return NULL;
            }
            if (atoi(pszOrder) != nLevelCount)
            {
                CPLDebug("WMS", "Expected order=%d, got %s", nLevelCount, pszOrder);
                return NULL;
            }

            const char* pszHref =
                CPLGetXMLValue(psIter, "href", NULL);
            if (nLevelCount == 0 && pszHref != NULL)
            {
                if (bCanChangeURL && strlen(pszHref) > 10 &&
                    strcmp(pszHref + strlen(pszHref) - strlen("/0"), "/0") == 0)
                {
                    osURL = pszHref;
                    osURL.resize(strlen(pszHref) - strlen("/0"));
                    osURL += "/${z}/${x}/${y}.${format}";
                }
            }
            const char* pszUnitsPerPixel =
                CPLGetXMLValue(psIter, "units-per-pixel", NULL);
            if (pszUnitsPerPixel == NULL)
                return NULL;
            dfPixelSize = CPLAtofM(pszUnitsPerPixel);

            nLevelCount++;
        }
    }

    if (nLevelCount == 0 || osURL.size() == 0)
        return NULL;

    int nXSize = 0;
    int nYSize = 0;

    while(nLevelCount > 0)
    {
        GIntBig nXSizeBig = (GIntBig)((dfMaxX - dfMinX) / dfPixelSize + 0.5);
        GIntBig nYSizeBig = (GIntBig)((dfMaxY - dfMinY) / dfPixelSize + 0.5);
        if (nXSizeBig < INT_MAX && nYSizeBig < INT_MAX)
        {
            nXSize = (int)nXSizeBig;
            nYSize = (int)nYSizeBig;
            break;
        }
        CPLDebug("WMS", "Dropping one overview level so raster size fits into 32bit...");
        dfPixelSize *= 2;
        nLevelCount --;
    }

    char* pszEscapedURL = CPLEscapeString(osURL.c_str(), -1, CPLES_XML);
    
    CPLString osXML = CPLSPrintf(
            "<GDAL_WMS>\n"
            "  <Service name=\"TMS\">\n"
            "    <ServerUrl>%s</ServerUrl>\n"
            "    <Format>%s</Format>\n"
            "  </Service>\n"
            "  <DataWindow>\n"
            "    <UpperLeftX>%s</UpperLeftX>\n"
            "    <UpperLeftY>%s</UpperLeftY>\n"
            "    <LowerRightX>%s</LowerRightX>\n"
            "    <LowerRightY>%s</LowerRightY>\n"
            "    <TileLevel>%d</TileLevel>\n"
            "    <SizeX>%d</SizeX>\n"
            "    <SizeY>%d</SizeY>\n"
            "  </DataWindow>\n"
            "  <Projection>%s</Projection>\n"
            "  <BlockSizeX>%d</BlockSizeX>\n"
            "  <BlockSizeY>%d</BlockSizeY>\n"
            "  <BandsCount>%d</BandsCount>\n"
            "</GDAL_WMS>\n",
            pszEscapedURL,
            pszTileFormat,
            pszMinX, pszMaxY, pszMaxX, pszMinY,
            nLevelCount - 1,
            nXSize, nYSize,
            pszSRS,
            nTileWidth, nTileHeight, 3);
    CPLDebug("WMS", "Opening TMS :\n%s", osXML.c_str());

    CPLFree(pszEscapedURL);

    return CPLParseXMLString(osXML);
}
예제 #16
0
char **CPL_STDCALL GDALLoadRPBFile( const char *pszFilename,
                                    char **papszSiblingFiles )

{
/* -------------------------------------------------------------------- */
/*      Try to identify the RPB file in upper or lower case.            */
/* -------------------------------------------------------------------- */
    CPLString osTarget = CPLResetExtension( pszFilename, "RPB" );

    /* Is this already a RPB file ? */
    if (EQUAL(CPLGetExtension(pszFilename), "RPB"))
        osTarget = pszFilename;
    else if( papszSiblingFiles == NULL )
    {
        VSIStatBufL sStatBuf;
        
        if( VSIStatL( osTarget, &sStatBuf ) != 0 )
        {
            osTarget = CPLResetExtension( pszFilename, "rpb" );

            if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                return NULL;
        }
    }
    else
    {
        int iSibling = CSLFindString( papszSiblingFiles, 
                                      CPLGetFilename(osTarget) );
        if( iSibling < 0 )
            return NULL;

        osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
        osTarget += papszSiblingFiles[iSibling];
    }

/* -------------------------------------------------------------------- */
/*      Read file and parse.                                            */
/* -------------------------------------------------------------------- */
    CPLKeywordParser oParser;

    VSILFILE *fp = VSIFOpenL( osTarget, "r" );

    if( fp == NULL )
        return NULL;
    
    if( !oParser.Ingest( fp ) )
    {
        VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

/* -------------------------------------------------------------------- */
/*      Extract RPC information, in a GDAL "standard" metadata format.  */
/* -------------------------------------------------------------------- */
    int i;
    char **papszMD = NULL;
    for( i = 0; apszRPBMap[i] != NULL; i += 2 )
    {
        const char *pszRPBVal = oParser.GetKeyword( apszRPBMap[i+1] );
        CPLString osAdjVal;

        if( pszRPBVal == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "%s file found, but missing %s field (and possibly others).",
                      osTarget.c_str(), apszRPBMap[i+1] );
            CSLDestroy( papszMD );
            return NULL;
        }

        if( strchr(pszRPBVal,',') == NULL )
            osAdjVal = pszRPBVal;
        else
        {
            // strip out commas and turn newlines into spaces.
            int j;

            for( j = 0; pszRPBVal[j] != '\0'; j++ )
            {
                switch( pszRPBVal[j] ) 
                {
                  case ',':
                  case '\n':
                  case '\r':
                    osAdjVal += ' ';
                    break;
                    
                  case '(':
                  case ')':
                    break;

                  default:
                    osAdjVal += pszRPBVal[j];
                }
            }
        }

        papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], osAdjVal );
    }

    return papszMD;
}
예제 #17
0
char ** CPL_STDCALL GDALLoadIMDFile( const char *pszFilename,
                                     char **papszSiblingFiles )

{
/* -------------------------------------------------------------------- */
/*      Try to identify the IMD file in upper or lower case.            */
/* -------------------------------------------------------------------- */
    CPLString osTarget = CPLResetExtension( pszFilename, "IMD" );

    /* Is this already a IMD file ? */
    if (EQUAL(CPLGetExtension(pszFilename), "IMD"))
        osTarget = pszFilename;
    else if( papszSiblingFiles == NULL )
    {
        VSIStatBufL sStatBuf;
        
        if( VSIStatL( osTarget, &sStatBuf ) != 0 )
        {
            osTarget = CPLResetExtension( pszFilename, "imd" );

            if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                return NULL;
        }
    }
    else
    {
        int iSibling = CSLFindString( papszSiblingFiles, 
                                      CPLGetFilename(osTarget) );
        if( iSibling < 0 )
            return NULL;

        osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
        osTarget += papszSiblingFiles[iSibling];
    }

/* -------------------------------------------------------------------- */
/*      Read file and parse.                                            */
/* -------------------------------------------------------------------- */
    CPLKeywordParser oParser;

    VSILFILE *fp = VSIFOpenL( osTarget, "r" );

    if( fp == NULL )
        return NULL;
    
    if( !oParser.Ingest( fp ) )
    {
        VSIFCloseL( fp );
        return NULL;
    }

    VSIFCloseL( fp );

/* -------------------------------------------------------------------- */
/*      Consider version changing.                                      */
/* -------------------------------------------------------------------- */
    char **papszIMD = CSLDuplicate( oParser.GetAllKeywords() );
    const char *pszVersion = CSLFetchNameValue( papszIMD, "version" );

    if( pszVersion == NULL )
    {
        /* ? */;
    }
    else if( EQUAL(pszVersion,"\"AA\"") )
    {
        GDAL_IMD_AA2R( &papszIMD );
    }

    return papszIMD;
}
예제 #18
0
char **CPL_STDCALL GDALLoadRPCFile( const char *pszFilename,
                                    char **papszSiblingFiles )

{
/* -------------------------------------------------------------------- */
/*      Try to identify the RPC file in upper or lower case.            */
/* -------------------------------------------------------------------- */
    CPLString osTarget; 

    /* Is this already a _RPC.TXT file ? */
    if (strlen(pszFilename) > 8 && EQUAL(pszFilename + strlen(pszFilename) - 8, "_RPC.TXT"))
        osTarget = pszFilename;
    else
    {
        CPLString osSrcPath = pszFilename;
        CPLString soPt(".");
        size_t found = osSrcPath.rfind(soPt);
        if (found == CPLString::npos)
            return NULL;
        osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt");
        CPLString osTarget = osSrcPath; 

        if( papszSiblingFiles == NULL )
        {
            VSIStatBufL sStatBuf;

            if( VSIStatL( osTarget, &sStatBuf ) != 0 )
            {
                osSrcPath = pszFilename;
                osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT");
                osTarget = osSrcPath; 

                if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                {
                    osSrcPath = pszFilename;
                    osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT");
                    osTarget = osSrcPath; 

                    if( VSIStatL( osTarget, &sStatBuf ) != 0 )
                    {
                        return NULL;
                    }
                }
            }
        }
        else
        {
            int iSibling = CSLFindString( papszSiblingFiles, 
                                        CPLGetFilename(osTarget) );
            if( iSibling < 0 )
                return NULL;

            osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
            osTarget += papszSiblingFiles[iSibling];
        }
    }

/* -------------------------------------------------------------------- */
/*      Read file and parse.                                            */
/* -------------------------------------------------------------------- */
    char **papszLines = CSLLoad2( osTarget, 100, 100, NULL );
    if(!papszLines)
        return NULL;

    char **papszMD = NULL;

    /* From LINE_OFF to HEIGHT_SCALE */
    for(size_t i = 0; i < 19; i += 2 )
    {
        const char *pszRPBVal = CSLFetchNameValue(papszLines, apszRPBMap[i] );
        if( pszRPBVal == NULL )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                "%s file found, but missing %s field (and possibly others).",
                osTarget.c_str(), apszRPBMap[i]);
            CSLDestroy( papszMD );
            CSLDestroy( papszLines );
            return NULL;
        }
        else
        {
            papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], pszRPBVal );
        }
    }
       
    /* For LINE_NUM_COEFF, LINE_DEN_COEFF, SAMP_NUM_COEFF, SAMP_DEN_COEFF */
    /* parameters that have 20 values each */
    for(size_t i = 20; apszRPBMap[i] != NULL; i += 2 )
    {
        CPLString soVal;
        for(int j = 1; j <= 20; j++)
        {
            CPLString soRPBMapItem;
            soRPBMapItem.Printf("%s_%d", apszRPBMap[i], j);
            const char *pszRPBVal = CSLFetchNameValue(papszLines, soRPBMapItem.c_str() );
            if( pszRPBVal == NULL )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                    "%s file found, but missing %s field (and possibly others).",
                    osTarget.c_str(), soRPBMapItem.c_str() );
                CSLDestroy( papszMD );
                CSLDestroy( papszLines );
                return NULL;
            }
            else
            {
                soVal += pszRPBVal;
                soVal += " ";
            }
        }
        papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], soVal.c_str() );
    }

    CSLDestroy( papszLines );
    return papszMD;
}
예제 #19
0
GDALDataset *SAFEDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Is this a SENTINEL-1 manifest.safe definition?                  */
/* -------------------------------------------------------------------- */
    if ( !SAFEDataset::Identify( poOpenInfo ) ) {
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*        Get subdataset information, if relevant                       */
/* -------------------------------------------------------------------- */
    CPLString osMDFilename;

    //Subdataset 1st level selection (ex: for swath selection)
    CPLString osSelectedSubDS1;
    //Subdataset 2nd level selection (ex: for polarisation selection)
    CPLString osSelectedSubDS2;

    if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SENTINEL1_DS:"))
    {
      osMDFilename = poOpenInfo->pszFilename + strlen("SENTINEL1_DS:");
      const char* pszSelection1 = strrchr(osMDFilename.c_str(), ':');
      if (pszSelection1 == nullptr || pszSelection1 == osMDFilename.c_str() )
      {
          CPLError(CE_Failure, CPLE_AppDefined, "Invalid syntax for SENTINEL1_DS:");
          return nullptr;
      }
      osMDFilename.resize( pszSelection1 - osMDFilename.c_str() );
      osSelectedSubDS1 = pszSelection1 + strlen(":");

      const char* pszSelection2 = strchr(osSelectedSubDS1.c_str(), '_');
      if (pszSelection2 != nullptr && pszSelection2 != pszSelection1 )
      {
          osSelectedSubDS1.resize( pszSelection2 - osSelectedSubDS1.c_str() );
          osSelectedSubDS2 = pszSelection2 + strlen("_");
      }

      //update directory check:
      VSIStatBufL  sStat;
      if( VSIStatL( osMDFilename.c_str(), &sStat ) == 0 )
          poOpenInfo->bIsDirectory = VSI_ISDIR( sStat.st_mode );
    }
    else
    {
      osMDFilename = poOpenInfo->pszFilename;
    }

    if( poOpenInfo->bIsDirectory )
    {
        osMDFilename =
            CPLFormCIFilename( osMDFilename.c_str(), "manifest.safe", nullptr );
    }

/* -------------------------------------------------------------------- */
/*      Ingest the manifest.safe file.                                  */
/* -------------------------------------------------------------------- */
    //TODO REMOVE CPLXMLNode *psImageAttributes, *psImageGenerationParameters;
    CPLXMLNode *psManifest = CPLParseXMLFile( osMDFilename );
    if( psManifest == nullptr )
        return nullptr;

    CPLString osPath(CPLGetPath( osMDFilename ));

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLDestroyXMLNode( psManifest );
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The SAFE driver does not support update access to existing"
                  " datasets.\n" );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Get contentUnit parent element.                                 */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psContentUnits = CPLGetXMLNode(
            psManifest,
            "=xfdu:XFDU.informationPackageMap.xfdu:contentUnit" );
    if( psContentUnits == nullptr )
    {
        CPLDestroyXMLNode( psManifest );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to find <xfdu:XFDU><informationPackageMap>"
                  "<xfdu:contentUnit> in manifest file." );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Get Metadata Objects element.                                   */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psMetaDataObjects
        = CPLGetXMLNode( psManifest, "=xfdu:XFDU.metadataSection" );
    if( psMetaDataObjects == nullptr )
    {
        CPLDestroyXMLNode( psManifest );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to find <xfdu:XFDU><metadataSection>"
                  "in manifest file." );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Get Data Objects element.                                       */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psDataObjects
        = CPLGetXMLNode( psManifest, "=xfdu:XFDU.dataObjectSection" );
    if( psDataObjects == nullptr )
    {
        CPLDestroyXMLNode( psManifest );
        CPLError( CE_Failure, CPLE_OpenFailed,
                "Failed to find <xfdu:XFDU><dataObjectSection> in document." );
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    SAFEDataset *poDS = new SAFEDataset();

    poDS->psManifest = psManifest;

/* -------------------------------------------------------------------- */
/*      Look for "Measurement Data Unit" contentUnit elements.          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAnnotation = nullptr;
    //Map with all measures aggregated by swath
    std::map<CPLString, std::set<CPLString> > oMapSwaths2Pols;

    for( CPLXMLNode *psContentUnit = psContentUnits->psChild;
         psContentUnit != nullptr;
         psContentUnit = psContentUnit->psNext )
    {
        if( psContentUnit->eType != CXT_Element
            || !(EQUAL(psContentUnit->pszValue,"xfdu:contentUnit")) ) {
            continue;
        }

        const char *pszUnitType = CPLGetXMLValue( psContentUnit,
                "unitType", "" );

        const char *pszAnnotation  = nullptr;
        const char *pszCalibration = nullptr;
        const char *pszMeasurement = nullptr;

        if ( EQUAL(pszUnitType, "Measurement Data Unit") ) {
            /* Get dmdID and dataObjectID */
            const char *pszDmdID = CPLGetXMLValue(psContentUnit, "dmdID", "");

            const char *pszDataObjectID = CPLGetXMLValue(
                psContentUnit,
                "dataObjectPointer.dataObjectID", "" );
            if( *pszDataObjectID == '\0' || *pszDmdID == '\0' ) {
                continue;
            }

            CPLXMLNode *psDataObject = SAFEDataset::GetDataObject(
                    psDataObjects, pszDataObjectID);

            const char *pszRepId = CPLGetXMLValue( psDataObject, "repID", "" );
            if ( !EQUAL(pszRepId, "s1Level1MeasurementSchema") ) {
                continue;
            }
            pszMeasurement = CPLGetXMLValue(
                    psDataObject, "byteStream.fileLocation.href", "");
            if( *pszMeasurement == '\0' ) {
                continue;
            }

            char** papszTokens = CSLTokenizeString2( pszDmdID, " ",
                CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES
                | CSLT_STRIPENDSPACES );

            for( int j = 0; j < CSLCount( papszTokens ); j++ ) {
                const char* pszId = papszTokens[j];
                if( *pszId == '\0' ) {
                    continue;
                }

                //Map the metadata ID to the object element
                CPLXMLNode *psDO = SAFEDataset::GetDataObject(
                        psMetaDataObjects, psDataObjects, pszId);

                if (psDO == nullptr) {
                    continue;
                }

                //check object type
                pszRepId = CPLGetXMLValue( psDO, "repID", "" );

                if( EQUAL(pszRepId, "s1Level1ProductSchema") )
                {
                    /* Get annotation filename */
                    pszAnnotation = CPLGetXMLValue(
                            psDO, "byteStream.fileLocation.href", "");
                    if( *pszAnnotation == '\0' )
                    {
                        continue;
                    }
                }
                else if( EQUAL(pszRepId, "s1Level1CalibrationSchema") )
                {
                    pszCalibration = CPLGetXMLValue(
                            psDO, "byteStream.fileLocation.href", "");
                    if( *pszCalibration == '\0' ) {
                        continue;
                    }
                }
                else
                {
                    continue;
                }
            }

            CSLDestroy(papszTokens);

            if (pszAnnotation == nullptr || pszCalibration == nullptr ) {
                continue;
            }

            //open Annotation XML file
            CPLString osAnnotationFilePath = CPLFormFilename( osPath,
                                                       pszAnnotation, nullptr );
            if( psAnnotation )
                CPLDestroyXMLNode(psAnnotation);
            psAnnotation = CPLParseXMLFile( osAnnotationFilePath );
            if( psAnnotation == nullptr )
                continue;

/* -------------------------------------------------------------------- */
/*      Get overall image information.                                  */
/* -------------------------------------------------------------------- */
            poDS->nRasterXSize =
                atoi(CPLGetXMLValue( psAnnotation,
                    "=product.imageAnnotation.imageInformation.numberOfSamples",
                    "-1" ));
            poDS->nRasterYSize =
                atoi(CPLGetXMLValue( psAnnotation,
                    "=product.imageAnnotation.imageInformation.numberOfLines",
                    "-1" ));
            if (poDS->nRasterXSize <= 1 || poDS->nRasterYSize <= 1) {
                CPLError( CE_Failure, CPLE_OpenFailed,
                    "Non-sane raster dimensions provided in manifest.safe. "
                    "If this is a valid SENTINEL-1 scene, please contact your "
                    "data provider for a corrected dataset." );
                delete poDS;
                CPLDestroyXMLNode(psAnnotation);
                return nullptr;
            }

            CPLString osProductType = CPLGetXMLValue(
                psAnnotation, "=product.adsHeader.productType", "UNK" );
            CPLString osMissionId = CPLGetXMLValue(
                psAnnotation, "=product.adsHeader.missionId", "UNK" );
            CPLString osPolarisation = CPLGetXMLValue(
                psAnnotation, "=product.adsHeader.polarisation", "UNK" );
            CPLString osMode = CPLGetXMLValue(
                psAnnotation, "=product.adsHeader.mode", "UNK" );
            CPLString osSwath = CPLGetXMLValue(
                psAnnotation, "=product.adsHeader.swath", "UNK" );

            oMapSwaths2Pols[osSwath].insert(osPolarisation);

            if (osSelectedSubDS1.empty()) {
              // If not subdataset was selected,
              // open the first one we can find.
              osSelectedSubDS1 = osSwath;
            }

            if (!EQUAL(osSelectedSubDS1.c_str(), osSwath.c_str())) {
              //do not mix swath, otherwise it does not work for SLC products
              continue;
            }

            if (!osSelectedSubDS2.empty()
              && (osSelectedSubDS2.find(osPolarisation)== std::string::npos)) {
              // Add only selected polarisations.
              continue;
            }

            poDS->SetMetadataItem("PRODUCT_TYPE", osProductType.c_str());
            poDS->SetMetadataItem("MISSION_ID", osMissionId.c_str());
            poDS->SetMetadataItem("MODE", osMode.c_str());
            poDS->SetMetadataItem("SWATH", osSwath.c_str());

/* -------------------------------------------------------------------- */
/*      Get dataType (so we can recognize complex data), and the        */
/*      bitsPerSample.                                                  */
/* -------------------------------------------------------------------- */

            const char *pszDataType = CPLGetXMLValue(
                psAnnotation,
                "=product.imageAnnotation.imageInformation.outputPixels",
                "" );

            GDALDataType eDataType;
            if( EQUAL(pszDataType,"16 bit Signed Integer") )
                eDataType = GDT_CInt16;
            else if( EQUAL(pszDataType,"16 bit Unsigned Integer") )
                eDataType = GDT_UInt16;
            else
            {
                delete poDS;
                CPLError( CE_Failure, CPLE_AppDefined,
                          "dataType=%s: not a supported configuration.",
                          pszDataType );
                CPLDestroyXMLNode(psAnnotation);
                return nullptr;
            }

            /* Extract pixel spacing information */
            const char *pszPixelSpacing = CPLGetXMLValue(
                psAnnotation,
                "=product.imageAnnotation.imageInformation.rangePixelSpacing",
                "UNK" );
            poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing );

            const char *pszLineSpacing = CPLGetXMLValue(
                psAnnotation,
                "=product.imageAnnotation.imageInformation.azimuthPixelSpacing",
                "UNK" );
            poDS->SetMetadataItem( "LINE_SPACING", pszLineSpacing );

/* -------------------------------------------------------------------- */
/*      Form full filename (path of manifest.safe + measurement file).  */
/* -------------------------------------------------------------------- */
            char *pszFullname =
                CPLStrdup(CPLFormFilename( osPath, pszMeasurement, nullptr ));

/* -------------------------------------------------------------------- */
/*      Try and open the file.                                          */
/* -------------------------------------------------------------------- */
            GDALDataset *poBandFile = reinterpret_cast<GDALDataset *>(
                GDALOpen( pszFullname, GA_ReadOnly ) );
            if( poBandFile == nullptr )
            {
                // NOP
            }
            else
            if (poBandFile->GetRasterCount() == 0)
            {
                GDALClose( (GDALRasterBandH) poBandFile );
             }
            else {
                poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles,
                                                  osAnnotationFilePath );
                poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles,
                                                  pszFullname );

/* -------------------------------------------------------------------- */
/*      Create the band.                                                */
/* -------------------------------------------------------------------- */
                SAFERasterBand *poBand
                    = new SAFERasterBand( poDS, eDataType,
                                          osSwath.c_str(),
                                          osPolarisation.c_str(),
                                          poBandFile );

                poDS->SetBand( poDS->GetRasterCount() + 1, poBand );
            }

            CPLFree( pszFullname );
        }
    }

    //loop through all Swath/pols to add subdatasets
    int iSubDS = 1;
    for (std::map<CPLString, std::set<CPLString> >::iterator iterSwath=oMapSwaths2Pols.begin();
         iterSwath!=oMapSwaths2Pols.end(); ++iterSwath)
    {
        CPLString osSubDS1 = iterSwath->first;
        CPLString osSubDS2;

        for (std::set<CPLString>::iterator iterPol=iterSwath->second.begin();
            iterPol!=iterSwath->second.end(); ++iterPol)
        {
            if (!osSubDS2.empty()) {
                osSubDS2 += "+";
            }
            osSubDS2 += *iterPol;

            //Create single band SubDataset
            SAFEDataset::AddSubDataset(poDS, iSubDS,
                CPLSPrintf("SENTINEL1_DS:%s:%s_%s",
                    osPath.c_str(),
                    osSubDS1.c_str(),
                    (*iterPol).c_str()),
                CPLSPrintf("Single band with %s swath and %s polarisation",
                    osSubDS1.c_str(),
                    (*iterPol).c_str())
            );
            iSubDS++;
        }

        if (iterSwath->second.size()>1) {
            //Create single band SubDataset with all polarisations
            SAFEDataset::AddSubDataset(poDS, iSubDS,
                CPLSPrintf("SENTINEL1_DS:%s:%s",
                    osPath.c_str(),
                    osSubDS1.c_str()),
                CPLSPrintf("%s swath with all polarisations as bands",
                    osSubDS1.c_str())
            );
            iSubDS++;
        }
    }

    if (poDS->GetRasterCount() == 0) {
        CPLError( CE_Failure, CPLE_OpenFailed, "Measurement bands not found." );
        delete poDS;
        if( psAnnotation )
            CPLDestroyXMLNode(psAnnotation);
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      Collect more metadata elements                                  */
/* -------------------------------------------------------------------- */

/* -------------------------------------------------------------------- */
/*      Platform information                                            */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psPlatformAttrs = SAFEDataset::GetMetaDataObject(
        psMetaDataObjects, "platform");

    if (psPlatformAttrs != nullptr) {
        const char *pszItem = CPLGetXMLValue(
                psPlatformAttrs,
                "metadataWrap.xmlData.safe:platform"
                ".safe:familyName", "" );
        poDS->SetMetadataItem( "SATELLITE_IDENTIFIER", pszItem );

        pszItem = CPLGetXMLValue(
                psPlatformAttrs,
                "metadataWrap.xmlData.safe:platform"
                ".safe:instrument.safe:familyName.abbreviation", "" );
        poDS->SetMetadataItem( "SENSOR_IDENTIFIER", pszItem );

        pszItem = CPLGetXMLValue(
                psPlatformAttrs,
                "metadataWrap.xmlData.safe:platform"
                ".safe:instrument.safe:extension"
                ".s1sarl1:instrumentMode.s1sarl1:mode", "UNK" );
        poDS->SetMetadataItem( "BEAM_MODE", pszItem );

        pszItem = CPLGetXMLValue(
                psPlatformAttrs,
                "metadataWrap.xmlData.safe:platform"
                ".safe:instrument.safe:extension"
                ".s1sarl1:instrumentMode.s1sarl1:swath", "UNK" );
        poDS->SetMetadataItem( "BEAM_SWATH", pszItem );
    }

/* -------------------------------------------------------------------- */
/*      Acquisition Period information                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAcquisitionAttrs = SAFEDataset::GetMetaDataObject(
        psMetaDataObjects, "acquisitionPeriod");

    if (psAcquisitionAttrs != nullptr) {
            const char *pszItem = CPLGetXMLValue(
            psAcquisitionAttrs,
            "metadataWrap.xmlData.safe:acquisitionPeriod"
            ".safe:startTime", "UNK" );
        poDS->SetMetadataItem( "ACQUISITION_START_TIME", pszItem );
        pszItem = CPLGetXMLValue(
            psAcquisitionAttrs,
            "metadataWrap.xmlData.safe:acquisitionPeriod"
            ".safe:stopTime", "UNK" );
        poDS->SetMetadataItem( "ACQUISITION_STOP_TIME", pszItem );
    }

/* -------------------------------------------------------------------- */
/*      Processing information                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psProcessingAttrs = SAFEDataset::GetMetaDataObject(
        psMetaDataObjects, "processing");

    if (psProcessingAttrs != nullptr) {
        const char *pszItem = CPLGetXMLValue(
            psProcessingAttrs,
            "metadataWrap.xmlData.safe:processing.safe:facility.name", "UNK" );
        poDS->SetMetadataItem( "FACILITY_IDENTIFIER", pszItem );
    }

/* -------------------------------------------------------------------- */
/*      Measurement Orbit Reference information                         */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psOrbitAttrs = SAFEDataset::GetMetaDataObject(
        psMetaDataObjects, "measurementOrbitReference");

    if (psOrbitAttrs != nullptr) {
        const char *pszItem = CPLGetXMLValue( psOrbitAttrs,
            "metadataWrap.xmlData.safe:orbitReference"
            ".safe:orbitNumber", "UNK" );
        poDS->SetMetadataItem( "ORBIT_NUMBER", pszItem );
        pszItem = CPLGetXMLValue( psOrbitAttrs,
            "metadataWrap.xmlData.safe:orbitReference"
            ".safe:extension.s1:orbitProperties.s1:pass", "UNK" );
        poDS->SetMetadataItem( "ORBIT_DIRECTION", pszItem );
    }

/* -------------------------------------------------------------------- */
/*      Collect Annotation Processing Information                       */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psProcessingInfo =
        CPLGetXMLNode( psAnnotation,
                       "=product.imageAnnotation.processingInformation" );

    if ( psProcessingInfo != nullptr ) {
        OGRSpatialReference oLL, oPrj;

        const char *pszEllipsoidName = CPLGetXMLValue(
            psProcessingInfo, "ellipsoidName", "" );
        const double minor_axis = CPLAtof(CPLGetXMLValue(
            psProcessingInfo, "ellipsoidSemiMinorAxis", "0.0" ));
        const double major_axis = CPLAtof(CPLGetXMLValue(
            psProcessingInfo, "ellipsoidSemiMajorAxis", "0.0" ));

        if ( EQUAL(pszEllipsoidName, "") || ( minor_axis == 0.0 ) ||
             ( major_axis == 0.0 ) )
        {
            CPLError(CE_Warning,CPLE_AppDefined,"Warning- incomplete"
                     " ellipsoid information.  Using wgs-84 parameters.\n");
            oLL.SetWellKnownGeogCS( "WGS84" );
            oPrj.SetWellKnownGeogCS( "WGS84" );
        }
        else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) {
            oLL.SetWellKnownGeogCS( "WGS84" );
            oPrj.SetWellKnownGeogCS( "WGS84" );
        }
        else {
            const double inv_flattening = major_axis/(major_axis - minor_axis);
            oLL.SetGeogCS( "","",pszEllipsoidName, major_axis,
                           inv_flattening);
            oPrj.SetGeogCS( "","",pszEllipsoidName, major_axis,
                            inv_flattening);
        }

        CPLFree( poDS->pszGCPProjection );
        poDS->pszGCPProjection = nullptr;
        oLL.exportToWkt( &(poDS->pszGCPProjection) );
    }

/* -------------------------------------------------------------------- */
/*      Collect GCPs.                                                   */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psGeoGrid =
        CPLGetXMLNode( psAnnotation,
                       "=product.geolocationGrid.geolocationGridPointList" );

    if( psGeoGrid != nullptr ) {
        /* count GCPs */
        poDS->nGCPCount = 0;

        for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != nullptr;
             psNode = psNode->psNext )
        {
            if( EQUAL(psNode->pszValue,"geolocationGridPoint") )
                poDS->nGCPCount++ ;
        }

        poDS->pasGCPList = reinterpret_cast<GDAL_GCP *>(
            CPLCalloc( sizeof(GDAL_GCP), poDS->nGCPCount ) );

        poDS->nGCPCount = 0;

        for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != nullptr;
             psNode = psNode->psNext )
        {
            GDAL_GCP *psGCP = poDS->pasGCPList + poDS->nGCPCount;

            if( !EQUAL(psNode->pszValue,"geolocationGridPoint") )
                continue;

            poDS->nGCPCount++ ;

            char szID[32];
            snprintf( szID, sizeof(szID), "%d", poDS->nGCPCount );
            psGCP->pszId = CPLStrdup( szID );
            psGCP->pszInfo = CPLStrdup("");
            psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"pixel","0"));
            psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"line","0"));
            psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"longitude",""));
            psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"latitude",""));
            psGCP->dfGCPZ = CPLAtof(CPLGetXMLValue(psNode,"height",""));
        }
    }

    CPLDestroyXMLNode(psAnnotation);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    const CPLString osDescription = osMDFilename;

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( osDescription );

    poDS->SetPhysicalFilename( osMDFilename );
    poDS->SetSubdatasetName( osDescription );

    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );

    return poDS;
}
예제 #20
0
OGRLayer * OGRGeoPackageDataSource::ExecuteSQL( const char *pszSQLCommand,
                                          OGRGeometry *poSpatialFilter,
                                          const char *pszDialect )

{
    if( EQUALN(pszSQLCommand, "SELECT ", 7) ||
        (pszDialect != NULL && EQUAL(pszDialect,"OGRSQL")) )
        return OGRDataSource::ExecuteSQL( pszSQLCommand, 
                                          poSpatialFilter, 
                                          pszDialect );

/* -------------------------------------------------------------------- */
/*      Prepare statement.                                              */
/* -------------------------------------------------------------------- */
    int rc;
    sqlite3_stmt *hSQLStmt = NULL;

    CPLString osSQLCommand = pszSQLCommand;

#if 0
    /* This will speed-up layer creation */
    /* ORDER BY are costly to evaluate and are not necessary to establish */
    /* the layer definition. */
    int bUseStatementForGetNextFeature = TRUE;
    int bEmptyLayer = FALSE;

    if( osSQLCommand.ifind("SELECT ") == 0 &&
        osSQLCommand.ifind(" UNION ") == std::string::npos &&
        osSQLCommand.ifind(" INTERSECT ") == std::string::npos &&
        osSQLCommand.ifind(" EXCEPT ") == std::string::npos )
    {
        size_t nOrderByPos = osSQLCommand.ifind(" ORDER BY ");
        if( nOrderByPos != std::string::npos )
        {
            osSQLCommand.resize(nOrderByPos);
            bUseStatementForGetNextFeature = FALSE;
        }
    }
#endif

    rc = sqlite3_prepare( m_poDb, osSQLCommand.c_str(), osSQLCommand.size(),
                          &hSQLStmt, NULL );

    if( rc != SQLITE_OK )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                "In ExecuteSQL(): sqlite3_prepare(%s):\n  %s", 
                pszSQLCommand, sqlite3_errmsg(m_poDb) );

        if( hSQLStmt != NULL )
        {
            sqlite3_finalize( hSQLStmt );
        }

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Do we get a resultset?                                          */
/* -------------------------------------------------------------------- */
    rc = sqlite3_step( hSQLStmt );
    if( rc != SQLITE_ROW )
    {
        if ( rc != SQLITE_DONE )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                  "In ExecuteSQL(): sqlite3_step(%s):\n  %s", 
                  pszSQLCommand, sqlite3_errmsg(m_poDb) );

            sqlite3_finalize( hSQLStmt );
            return NULL;
        }
        
        if( EQUAL(pszSQLCommand, "VACUUM") )
        {
            sqlite3_finalize( hSQLStmt );
            /* VACUUM rewrites the DB, so we need to reset the application id */
            SetApplicationId();
            return NULL;
        }
        
        if( EQUALN(pszSQLCommand, "ALTER TABLE ", strlen("ALTER TABLE ")) )
        {
            char **papszTokens = CSLTokenizeString( pszSQLCommand );
            /* ALTER TABLE src_table RENAME TO dst_table */
            if( CSLCount(papszTokens) == 6 && EQUAL(papszTokens[3], "RENAME") &&
                EQUAL(papszTokens[4], "TO") )
            {
                const char* pszSrcTableName = papszTokens[2];
                const char* pszDstTableName = papszTokens[5];
                OGRLayer* poSrcLayer = GetLayerByName(pszSrcTableName);
                if( poSrcLayer )
                {
                    /* We also need to update GeoPackage metadata tables */
                    char* pszSQL;
                    pszSQL = sqlite3_mprintf(
                            "UPDATE gpkg_geometry_columns SET table_name = '%s' WHERE table_name = '%s'",
                            pszDstTableName, pszSrcTableName);
                    
                    SQLCommand(m_poDb, pszSQL);
                    sqlite3_free(pszSQL);
                    
                    pszSQL = sqlite3_mprintf(
                            "UPDATE gpkg_contents SET table_name = '%s' WHERE table_name = '%s'",
                            pszDstTableName, pszSrcTableName);

                    SQLCommand(m_poDb, pszSQL);
                    sqlite3_free(pszSQL);
                }
            }
            CSLDestroy(papszTokens);
        }

        if( !EQUALN(pszSQLCommand, "SELECT ", 7) )
        {
            sqlite3_finalize( hSQLStmt );
            return NULL;
        }
#if 0
        bUseStatementForGetNextFeature = FALSE;
        bEmptyLayer = TRUE;
#endif
    }

/* -------------------------------------------------------------------- */
/*      Create layer.                                                   */
/* -------------------------------------------------------------------- */
#if 0
    OGRSQLiteSelectLayer *poLayer = NULL;
        
    CPLString osSQL = pszSQLCommand;
    poLayer = new OGRGeopackageSelectLayer( this, osSQL, hSQLStmt,
                                        bUseStatementForGetNextFeature, bEmptyLayer, TRUE );

    if( poSpatialFilter != NULL )
        poLayer->SetSpatialFilter( 0, poSpatialFilter );
    
    return poLayer;
#else
    return OGRDataSource::ExecuteSQL( pszSQLCommand, 
                                          poSpatialFilter, 
                                          pszDialect );
#endif
}
예제 #21
0
OGRLayer * OGRCouchDBDataSource::ExecuteSQL( const char *pszSQLCommand,
                                          OGRGeometry *poSpatialFilter,
                                          const char *pszDialect )

{
/* -------------------------------------------------------------------- */
/*      Use generic implementation for recognized dialects              */
/* -------------------------------------------------------------------- */
    if( IsGenericSQLDialect(pszDialect) )
        return OGRDataSource::ExecuteSQL( pszSQLCommand,
                                          poSpatialFilter,
                                          pszDialect );

/* -------------------------------------------------------------------- */
/*      Special case DELLAYER: command.                                 */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "DELLAYER:") )
    {
        const char *pszLayerName = pszSQLCommand + 9;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        DeleteLayer( pszLayerName );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Special case 'COMPACT ON ' command.                             */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "COMPACT ON ") )
    {
        const char *pszLayerName = pszSQLCommand + 11;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        CPLString osURI("/");
        osURI += pszLayerName;
        osURI += "/_compact";

        json_object* poAnswerObj = POST(osURI, NULL);
        IsError(poAnswerObj, "Database compaction failed");
        json_object_put(poAnswerObj);

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Special case 'VIEW CLEANUP ON ' command.                        */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "VIEW CLEANUP ON ") )
    {
        const char *pszLayerName = pszSQLCommand + 16;

        while( *pszLayerName == ' ' )
            pszLayerName++;

        CPLString osURI("/");
        osURI += pszLayerName;
        osURI += "/_view_cleanup";

        json_object* poAnswerObj = POST(osURI, NULL);
        IsError(poAnswerObj, "View cleanup failed");
        json_object_put(poAnswerObj);

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Deal with "DELETE FROM layer_name WHERE expression" statement   */
/* -------------------------------------------------------------------- */
    if( STARTS_WITH_CI(pszSQLCommand, "DELETE FROM ") )
    {
        const char* pszIter = pszSQLCommand + 12;
        while(*pszIter && *pszIter != ' ')
            pszIter ++;
        if (*pszIter == 0)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Invalid statement");
            return NULL;
        }

        CPLString osName = pszSQLCommand + 12;
        osName.resize(pszIter - (pszSQLCommand + 12));
        OGRCouchDBLayer* poLayer = (OGRCouchDBLayer*)GetLayerByName(osName);
        if (poLayer == NULL)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Unknown layer : %s", osName.c_str());
            return NULL;
        }
        if (poLayer->GetLayerType() != COUCHDB_TABLE_LAYER)
            return NULL;
        OGRCouchDBTableLayer* poTableLayer = (OGRCouchDBTableLayer*)poLayer;

        while( *pszIter == ' ' )
            pszIter ++;
        if (!STARTS_WITH_CI(pszIter, "WHERE "))
        {
            CPLError(CE_Failure, CPLE_AppDefined, "WHERE clause missing");
            return NULL;
        }
        pszIter += 5;

        const char* pszQuery = pszIter;

        /* Check with the generic SQL engine that this is a valid WHERE clause */
        OGRFeatureQuery oQuery;
        OGRErr eErr = oQuery.Compile( poLayer->GetLayerDefn(), pszQuery );
        if( eErr != OGRERR_NONE )
        {
            return NULL;
        }

        swq_expr_node * pNode = (swq_expr_node *) oQuery.GetSWQExpr();
        if (pNode->eNodeType == SNT_OPERATION &&
            pNode->nOperation == SWQ_EQ &&
            pNode->nSubExprCount == 2 &&
            pNode->papoSubExpr[0]->eNodeType == SNT_COLUMN &&
            pNode->papoSubExpr[1]->eNodeType == SNT_CONSTANT &&
            pNode->papoSubExpr[0]->field_index == COUCHDB_ID_FIELD &&
            pNode->papoSubExpr[1]->field_type == SWQ_STRING)
        {
            poTableLayer->DeleteFeature(pNode->papoSubExpr[1]->string_value);
        }
        else
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Invalid WHERE clause. Expecting '_id' = 'a_value'");
            return NULL;
        }

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Try an optimized implementation when doing only stats           */
/* -------------------------------------------------------------------- */
    if (poSpatialFilter == NULL && STARTS_WITH_CI(pszSQLCommand, "SELECT"))
    {
        OGRLayer* poRet = ExecuteSQLStats(pszSQLCommand);
        if (poRet)
            return poRet;
    }

    return OGRDataSource::ExecuteSQL( pszSQLCommand,
                                        poSpatialFilter,
                                        pszDialect );
}
예제 #22
0
OGRFeature *OGRAeronavFAARouteLayer::GetNextRawFeature()
{
    OGRFeature* poFeature = nullptr;
    OGRLineString* poLS = nullptr;

    while( true )
    {
        const char* pszLine = nullptr;
        if (!osLastReadLine.empty())
            pszLine = osLastReadLine.c_str();
        else
            pszLine = CPLReadLine2L(fpAeronavFAA, 87, nullptr);
        osLastReadLine = "";

        if (pszLine == nullptr)
        {
            bEOF = true;
            break;
        }
        if (strlen(pszLine) != 85)
            continue;

        if (bIsDPOrSTARS && STARTS_WITH(pszLine, "===") && pszLine[3] != '=')
        {
            osAPTName = pszLine + 3;
            const char* pszComma = strchr(pszLine + 3, ',');
            if (pszComma)
            {
                osAPTName.resize(pszComma - (pszLine + 3));
                osStateName = pszComma + 2;
                const char* pszEqual = strchr(pszComma + 2, '=');
                if (pszEqual)
                    osStateName.resize(pszEqual - (pszComma + 2));
            }
            else
            {
                const char* pszEqual = strchr(pszLine + 3, '=');
                if (pszEqual)
                    osAPTName.resize(pszEqual - (pszLine + 3));
                osStateName = "";
            }
        }

        if (STARTS_WITH(pszLine + 2, "FACILITY OR"))
            continue;
        if (STARTS_WITH(pszLine + 2, "INTERSECTION"))
            continue;

        if (strcmp(pszLine, "================================DELETIONS LIST=================================198326") == 0)
        {
            bEOF = true;
            break;
        }

        if (poFeature == nullptr)
        {
            if (pszLine[2] == ' ' || pszLine[2] == '-' )
            {
                continue;
            }

            if (STARTS_WITH(pszLine + 29, "                    ") ||
                strchr(pszLine, '(') != nullptr)
            {
                CPLString osName = pszLine + 2;
                osName.resize(60);
                while(!osName.empty() && osName.back() == ' ')
                {
                    osName.resize(osName.size()-1);
                }

                if (strcmp(osName.c_str(), "(DELETIONS LIST)") == 0)
                {
                    bEOF = true;
                    return nullptr;
                }

                poFeature = new OGRFeature(poFeatureDefn);
                poFeature->SetFID(nNextFID ++);
                if (bIsDPOrSTARS)
                {
                    poFeature->SetField(0, osAPTName);
                    poFeature->SetField(1, osStateName);
                    poFeature->SetField(2, osName);
                }
                else
                    poFeature->SetField(0, osName);
                poLS = new OGRLineString();
            }
            continue;
        }

        if (STARTS_WITH(pszLine, "                                                                                    0"))
        {
            if (poLS->getNumPoints() == 0)
                continue;
            else
                break;
        }

        if (pszLine[29 - 1] == ' ' && pszLine[42 - 1] == ' ')
            continue;
        if (strstr(pszLine, "RWY") || strchr(pszLine, '('))
        {
            osLastReadLine = pszLine;
            break;
        }

        double dfLat = 0.0;
        double dfLon = 0.0;
        GetLatLon(pszLine + 29 - 1,
                  pszLine + 42 - 1,
                  dfLat,
                  dfLon);
        poLS->addPoint(dfLon, dfLat);
    }

    if( poFeature != nullptr )
        poFeature->SetGeometryDirectly(poLS);
    return poFeature;
}