GIntBig OGRDODSSequenceLayer::GetFeatureCount( int bForce )

{
    if( !bDataLoaded && !bForce )
        return -1;

    ProvideDataDDS();

    return nRecordCount;
}
OGRFeature *OGRDODSSequenceLayer::GetFeature( GIntBig nFeatureId )

{
/* -------------------------------------------------------------------- */
/*      Ensure we have the dataset.                                     */
/* -------------------------------------------------------------------- */
    if( !ProvideDataDDS() )
        return NULL;

    Sequence *seq = dynamic_cast<Sequence *>(poTargetVar);

/* -------------------------------------------------------------------- */
/*      Figure out what the super and subsequence number this           */
/*      feature will be, and validate it.  If there is not super        */
/*      sequence the feature id is the subsequence number.              */
/* -------------------------------------------------------------------- */
    int iSubSeq = -1;

    if( nFeatureId < 0 || nFeatureId >= nRecordCount )
        return NULL;

    if( poSuperSeq == NULL )
        iSubSeq = nFeatureId;
    else
    {
        int nSeqOffset = 0, iSuperSeq;

        // for now we just scan through till find find out what
        // super sequence this in.  In the long term we need a better (cached)
        // approach that doesn't involve this quadratic cost.
        for( iSuperSeq = 0; 
             iSuperSeq < nSuperSeqCount; 
             iSuperSeq++ )
        {
            if( nSeqOffset + panSubSeqSize[iSuperSeq] > nFeatureId )
            {
                iSubSeq = nFeatureId - nSeqOffset;
                break;
            }
            nSeqOffset += panSubSeqSize[iSuperSeq];
        }

        CPLAssert( iSubSeq != -1 );

        // Make sure we have the right target var ... the one 
        // corresponding to our current super sequence. 
        if( iSuperSeq != iLastSuperSeq )
        {
            iLastSuperSeq = iSuperSeq;
            poTargetVar = poSuperSeq->var_value( iSuperSeq, pszSubSeqPath );
            seq = dynamic_cast<Sequence *>(poTargetVar);
        }
    }

/* -------------------------------------------------------------------- */
/*      Create the feature being read.                                  */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeature;

    poFeature = new OGRFeature( poFeatureDefn );
    poFeature->SetFID( nFeatureId );
    m_nFeaturesRead++;

/* -------------------------------------------------------------------- */
/*      Process all the regular data fields.                            */
/* -------------------------------------------------------------------- */
    int      iField;

    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {
        if( papoFields[iField]->pszPathToSequence )
            continue;

        BaseType *poFieldVar = GetFieldValue( papoFields[iField], iSubSeq,
                                              NULL );

        if( poFieldVar == NULL )
            continue;

        switch( poFieldVar->type() )
        {
          case dods_byte_c:
          {
              signed char byVal;
              void *pValPtr = &byVal;
              
              poFieldVar->buf2val( &pValPtr );
              poFeature->SetField( iField, byVal );
          }
          break;

          case dods_int16_c:
          {
              GInt16 nIntVal;
              void *pValPtr = &nIntVal;
              
              poFieldVar->buf2val( &pValPtr );
              poFeature->SetField( iField, nIntVal );
          }
          break;

          case dods_uint16_c:
          {
              GUInt16 nIntVal;
              void *pValPtr = &nIntVal;
              
              poFieldVar->buf2val( &pValPtr );
              poFeature->SetField( iField, nIntVal );
          }
          break;

          case dods_int32_c:
          {
              GInt32 nIntVal;
              void *pValPtr = &nIntVal;
              
              poFieldVar->buf2val( &pValPtr );
              poFeature->SetField( iField, nIntVal );
          }
          break;

          case dods_uint32_c:
          {
              GUInt32 nIntVal;
              void *pValPtr = &nIntVal;
              
              poFieldVar->buf2val( &pValPtr );
              poFeature->SetField( iField, (int) nIntVal );
          }
          break;

          case dods_float32_c:
            poFeature->SetField( iField, 
                                 dynamic_cast<Float32 *>(poFieldVar)->value());
            break;

          case dods_float64_c:
            poFeature->SetField( iField, 
                                 dynamic_cast<Float64 *>(poFieldVar)->value());
            break;

          case dods_str_c:
          case dods_url_c:
          {
              string *poStrVal = NULL;
              poFieldVar->buf2val( (void **) &poStrVal );
              poFeature->SetField( iField, poStrVal->c_str() );
              delete poStrVal;
          }
          break;

          default:
            break;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Handle data nested in sequences.                                */
/* -------------------------------------------------------------------- */
    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    {
        OGRDODSFieldDefn *poFD = papoFields[iField];
        const char *pszPathFromSubSeq;

        if( poFD->pszPathToSequence == NULL )
            continue;

        CPLAssert( strlen(poFD->pszPathToSequence) 
                   < strlen(poFD->pszFieldName)-1 );

        if( strstr(poFD->pszFieldName,poFD->pszPathToSequence) != NULL )
            pszPathFromSubSeq = 
                strstr(poFD->pszFieldName,poFD->pszPathToSequence)
                + strlen(poFD->pszPathToSequence) + 1;
        else
            continue;

/* -------------------------------------------------------------------- */
/*      Get the sequence out of which this variable will be collected.  */
/* -------------------------------------------------------------------- */
        BaseType *poFieldVar = seq->var_value( iSubSeq, 
                                               poFD->pszPathToSequence );
        Sequence *poSubSeq;
        int nSubSeqCount;

        if( poFieldVar == NULL )
            continue;

        poSubSeq = dynamic_cast<Sequence *>( poFieldVar );
        if( poSubSeq == NULL )
            continue;

        nSubSeqCount = poSubSeq->number_of_rows();
            
/* -------------------------------------------------------------------- */
/*      Allocate array to put values into.                              */
/* -------------------------------------------------------------------- */
        OGRFieldDefn *poOFD = poFeature->GetFieldDefnRef( iField );
        int *panIntList = NULL;
        double *padfDblList = NULL;
        char **papszStrList = NULL;

        if( poOFD->GetType() == OFTIntegerList )
        {
            panIntList = (int *) CPLCalloc(sizeof(int),nSubSeqCount);
        }
        else if( poOFD->GetType() == OFTRealList )
        {
            padfDblList = (double *) CPLCalloc(sizeof(double),nSubSeqCount);
        }
        else if( poOFD->GetType() == OFTStringList )
        {
            papszStrList = (char **) CPLCalloc(sizeof(char*),nSubSeqCount+1);
        }
        else
            continue;

/* -------------------------------------------------------------------- */
/*      Loop, fetching subsequence values.                              */
/* -------------------------------------------------------------------- */
        int iSubIndex;
        for( iSubIndex = 0; iSubIndex < nSubSeqCount; iSubIndex++ )
        {
            poFieldVar = poSubSeq->var_value( iSubIndex, pszPathFromSubSeq );

            if( poFieldVar == NULL )
                continue;

            switch( poFieldVar->type() )
            {
              case dods_byte_c:
              {
                  signed char byVal;
                  void *pValPtr = &byVal;
                  
                  poFieldVar->buf2val( &pValPtr );
                  panIntList[iSubIndex] = byVal;
              }
              break;
              
              case dods_int16_c:
              {
                  GInt16 nIntVal;
                  void *pValPtr = &nIntVal;
                  
                  poFieldVar->buf2val( &pValPtr );
                  panIntList[iSubIndex] = nIntVal;
              }
              break;
              
              case dods_uint16_c:
              {
                  GUInt16 nIntVal;
                  void *pValPtr = &nIntVal;
                  
                  poFieldVar->buf2val( &pValPtr );
                  panIntList[iSubIndex] = nIntVal;
              }
              break;
              
              case dods_int32_c:
              {
                  GInt32 nIntVal;
                  void *pValPtr = &nIntVal;
                  
                  poFieldVar->buf2val( &pValPtr );
                  panIntList[iSubIndex] = nIntVal;
              }
              break;

              case dods_uint32_c:
              {
                  GUInt32 nIntVal;
                  void *pValPtr = &nIntVal;
              
                  poFieldVar->buf2val( &pValPtr );
                  panIntList[iSubIndex] = nIntVal;
              }
              break;

              case dods_float32_c:
                padfDblList[iSubIndex] = 
                    dynamic_cast<Float32 *>(poFieldVar)->value();
                break;

              case dods_float64_c:
                padfDblList[iSubIndex] = 
                    dynamic_cast<Float64 *>(poFieldVar)->value();
                break;

              case dods_str_c:
              case dods_url_c:
              {
                  string *poStrVal = NULL;
                  poFieldVar->buf2val( (void **) &poStrVal );
                  papszStrList[iSubIndex] = CPLStrdup( poStrVal->c_str() );
                  delete poStrVal;
              }
              break;

              default:
                break;
            }
        }

/* -------------------------------------------------------------------- */
/*      Apply back to feature.                                          */
/* -------------------------------------------------------------------- */
        if( poOFD->GetType() == OFTIntegerList )
        {
            poFeature->SetField( iField, nSubSeqCount, panIntList );
            CPLFree(panIntList);
        }
        else if( poOFD->GetType() == OFTRealList )
        {
            poFeature->SetField( iField, nSubSeqCount, padfDblList );
            CPLFree(padfDblList);
        }
        else if( poOFD->GetType() == OFTStringList )
        {
            poFeature->SetField( iField, papszStrList );
            CSLDestroy( papszStrList );
        }
    }
    
/* ==================================================================== */
/*      Fetch the geometry.                                             */
/* ==================================================================== */
    if( oXField.bValid && oYField.bValid )
    {
        int iXField = poFeature->GetFieldIndex( oXField.pszFieldName );
        int iYField = poFeature->GetFieldIndex( oYField.pszFieldName );
        int iZField = -1;

        if( oZField.bValid )
            iZField = poFeature->GetFieldIndex(oZField.pszFieldName);

/* -------------------------------------------------------------------- */
/*      If we can't find the values in attributes then use the more     */
/*      general mechanism to fetch the value.                           */
/* -------------------------------------------------------------------- */
        
        if( iXField == -1 || iYField == -1 
            || (oZField.bValid && iZField == -1) )
        {
            poFeature->SetGeometryDirectly( 
                new OGRPoint( GetFieldValueAsDouble( &oXField, iSubSeq ),
                              GetFieldValueAsDouble( &oYField, iSubSeq ),
                              GetFieldValueAsDouble( &oZField, iSubSeq ) ) );
        }
/* -------------------------------------------------------------------- */
/*      If the fields are list values, then build a linestring.         */
/* -------------------------------------------------------------------- */
        else if( poFeature->GetFieldDefnRef(iXField)->GetType() == OFTRealList
            && poFeature->GetFieldDefnRef(iYField)->GetType() == OFTRealList )
        {
            const double *padfX, *padfY, *padfZ = NULL;
            int nPointCount, i;
            OGRLineString *poLS = new OGRLineString();
            
            padfX = poFeature->GetFieldAsDoubleList( iXField, &nPointCount );
            padfY = poFeature->GetFieldAsDoubleList( iYField, &nPointCount );
            if( iZField != -1 )
                padfZ = poFeature->GetFieldAsDoubleList(iZField,&nPointCount);

            poLS->setPoints( nPointCount, (double *) padfX, (double *) padfY,
                             (double *) padfZ );

            // Make a pass clearing out NaN or Inf values. 
            for( i = 0; i < nPointCount; i++ )
            {
                double dfX = poLS->getX(i);
                double dfY = poLS->getY(i);
                double dfZ = poLS->getZ(i);
                int bReset = FALSE;

                if( OGRDODSIsDoubleInvalid( &dfX ) )
                {
                    dfX = 0.0;
                    bReset = TRUE;
                }
                if( OGRDODSIsDoubleInvalid( &dfY ) )
                {
                    dfY = 0.0;
                    bReset = TRUE;
                }
                if( OGRDODSIsDoubleInvalid( &dfZ ) )
                {
                    dfZ = 0.0;
                    bReset = TRUE;
                }

                if( bReset )
                    poLS->setPoint( i, dfX, dfY, dfZ );
            }

            poFeature->SetGeometryDirectly( poLS );
        }

/* -------------------------------------------------------------------- */
/*      Otherwise build a point.                                        */
/* -------------------------------------------------------------------- */
        else
        {
            poFeature->SetGeometryDirectly( 
                new OGRPoint( 
                    poFeature->GetFieldAsDouble( iXField ),
                    poFeature->GetFieldAsDouble( iYField ),
                    poFeature->GetFieldAsDouble( iZField ) ) );
        }
    }

    return poFeature;
}
Example #3
0
OGRFeature *OGRDODSGridLayer::GetFeature( GIntBig nFeatureId )

{
    if( nFeatureId < 0 || nFeatureId >= nMaxRawIndex )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Ensure we have the dataset.                                     */
/* -------------------------------------------------------------------- */
    if( !ProvideDataDDS() )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the feature being read.                                  */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    poFeature->SetFID( nFeatureId );
    m_nFeaturesRead++;

/* -------------------------------------------------------------------- */
/*      Establish the values for the various dimension indices.         */
/* -------------------------------------------------------------------- */
    int iDim;
    int nRemainder = static_cast<int>(nFeatureId);

    for( iDim = nDimCount-1; iDim >= 0; iDim-- )
    {
        paoDimensions[iDim].iLastValue =
            (nRemainder % paoDimensions[iDim].nDimEntries)
            * paoDimensions[iDim].nDimStride
            + paoDimensions[iDim].nDimStart;
        nRemainder = nRemainder / paoDimensions[iDim].nDimEntries;

        if( poTargetGrid == NULL )
            poFeature->SetField( iDim, paoDimensions[iDim].iLastValue );
    }
    CPLAssert( nRemainder == 0 );

/* -------------------------------------------------------------------- */
/*      For grids, we need to apply the values of the dimensions        */
/*      looked up in the corresponding map.                             */
/* -------------------------------------------------------------------- */
    if( poTargetGrid != NULL )
    {
        for( iDim = 0; iDim < nDimCount; iDim++ )
        {
            ArrayEntryToField( paoDimensions[iDim].poMap,
                               paoDimensions[iDim].pRawData,
                               paoDimensions[iDim].iLastValue,
                               poFeature, iDim );
        }
    }

/* -------------------------------------------------------------------- */
/*      Process all the regular data fields.                            */
/* -------------------------------------------------------------------- */
    int iArray;
    for( iArray = 0; iArray < nArrayRefCount; iArray++ )
    {
        OGRDODSArrayRef *poRef = paoArrayRefs + iArray;

        ArrayEntryToField( poRef->poArray, poRef->pRawData,
                           static_cast<int>(nFeatureId),
                           poFeature, poRef->iFieldIndex );
    }

/* -------------------------------------------------------------------- */
/*      Do we have geometry information?                                */
/* -------------------------------------------------------------------- */
    if( oXField.iFieldIndex >= 0 && oYField.iFieldIndex >= 0 )
    {
        OGRPoint *poPoint = new OGRPoint();

        poPoint->setX( poFeature->GetFieldAsDouble( oXField.iFieldIndex ) );
        poPoint->setY( poFeature->GetFieldAsDouble( oYField.iFieldIndex ) );

        if( oZField.iFieldIndex >= 0 )
            poPoint->setZ( poFeature->GetFieldAsDouble(oZField.iFieldIndex) );

        poFeature->SetGeometryDirectly( poPoint );
    }

    return poFeature;
}