Exemple #1
0
int ILI1Reader::ReadModel(ImdReader *poImdReader, const char *pszModelFilename, OGRILI1DataSource *poDS) {

  poImdReader->ReadModel(pszModelFilename);
  for (FeatureDefnInfos::const_iterator it = poImdReader->featureDefnInfos.begin(); it != poImdReader->featureDefnInfos.end(); ++it)
  {
    //CPLDebug( "OGR_ILI", "Adding OGRILI1Layer with table '%s'", it->poTableDefn->GetName() );
    OGRILI1Layer* layer = new OGRILI1Layer(it->poTableDefn, it->poGeomFieldInfos, poDS);
    AddLayer(layer);
    //Create additional layers for surface and area geometries
    for (GeomFieldInfos::const_iterator it2 = it->poGeomFieldInfos.begin(); it2 != it->poGeomFieldInfos.end(); ++it2)
    {
      if (it2->second.geomTable)
      {
        OGRFeatureDefn* poGeomTableDefn = it2->second.geomTable;
        OGRGeomFieldDefn* poOGRGeomFieldDefn = poGeomTableDefn->GetGeomFieldDefn(0);
        GeomFieldInfos oGeomFieldInfos;
        // We add iliGeomType to recognize Ili1 geom tables
        oGeomFieldInfos[poOGRGeomFieldDefn->GetNameRef()].iliGeomType = it2->second.iliGeomType;
        //CPLDebug( "OGR_ILI", "Adding OGRILI1Layer with geometry table '%s'", it2->second.geomTable->GetName() );
        OGRILI1Layer* geomlayer = new OGRILI1Layer(poGeomTableDefn, oGeomFieldInfos, poDS);
        AddLayer(geomlayer);
      }
    }
  }

  codeBlank = poImdReader->codeBlank;
  CPLDebug( "OGR_ILI", "Ili1Format blankCode '%c'", poImdReader->codeBlank );
  codeUndefined = poImdReader->codeUndefined;
  CPLDebug( "OGR_ILI", "Ili1Format undefinedCode '%c'", poImdReader->codeUndefined );
  codeContinue = poImdReader->codeContinue;
  CPLDebug( "OGR_ILI", "Ili1Format continueCode '%c'", poImdReader->codeContinue );
  return 0;
}
Exemple #2
0
void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer)
{
    if( !pabCheckIfAutoWrap[iLayer] )
    {
        pabCheckIfAutoWrap[iLayer] = TRUE;

        for(int i=0; i<GetLayerDefn()->GetGeomFieldCount();i++)
        {
            OGRSpatialReference* poSRS = GetLayerDefn()->GetGeomFieldDefn(i)->GetSpatialRef();
            if( poSRS != NULL )
                poSRS->Reference();

            OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn();
            int iSrcGeomField = poSrcFeatureDefn->GetGeomFieldIndex(
                    GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef());
            if( iSrcGeomField >= 0 )
            {
                OGRSpatialReference* poSRS2 =
                    poSrcFeatureDefn->GetGeomFieldDefn(iSrcGeomField)->GetSpatialRef();

                if( (poSRS == NULL && poSRS2 != NULL) ||
                    (poSRS != NULL && poSRS2 == NULL) )
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                            "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS",
                            GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(),
                            papoSrcLayers[iLayer]->GetName());
                }
                else if (poSRS != NULL && poSRS2 != NULL &&
                        poSRS != poSRS2 && !poSRS->IsSame(poSRS2))
                {
                    CPLDebug("VRT", "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS. "
                            "Trying auto warping",
                            GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(),
                            papoSrcLayers[iLayer]->GetName());
                    OGRCoordinateTransformation* poCT =
                        OGRCreateCoordinateTransformation( poSRS2, poSRS );
                    OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ?
                        OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : NULL;
                    if( poReversedCT != NULL )
                        papoSrcLayers[iLayer] = new OGRWarpedLayer(
                                    papoSrcLayers[iLayer], iSrcGeomField, TRUE, poCT, poReversedCT);
                    else
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "AutoWarpLayerIfNecessary failed to create "
                                 "poCT or poReversedCT.");
                        if ( poCT != NULL )
                            delete poCT;
                    }
                }
            }

            if( poSRS != NULL )
                poSRS->Release();
        }
    }
}
Exemple #3
0
OGRFeatureDefn *OGRTigerLayer::GetLayerDefn()

{
    OGRFeatureDefn* poFDefn = poReader->GetFeatureDefn();
    if( poFDefn != NULL )
    {
        if( poFDefn->GetGeomFieldCount() > 0 )
            poFDefn->GetGeomFieldDefn(0)->SetSpatialRef(poDS->GetSpatialRef());
    }
    return poFDefn;
}
OGRESRIFeatureServiceLayer::OGRESRIFeatureServiceLayer(OGRESRIFeatureServiceDataset* poDS)
{
    this->poDS = poDS;
    OGRFeatureDefn* poSrcFeatDefn = poDS->GetUnderlyingLayer()->GetLayerDefn();
    poFeatureDefn = new OGRFeatureDefn(poSrcFeatDefn->GetName());
    SetDescription(poFeatureDefn->GetName());
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType(wkbNone);
    for(int i=0;i<poSrcFeatDefn->GetFieldCount();i++)
        poFeatureDefn->AddFieldDefn(poSrcFeatDefn->GetFieldDefn(i));
    for(int i=0;i<poSrcFeatDefn->GetGeomFieldCount();i++)
        poFeatureDefn->AddGeomFieldDefn(poSrcFeatDefn->GetGeomFieldDefn(i));
    nFeaturesRead = 0;
    nLastFID = 0;
    bOtherPage = FALSE;
    bUseSequentialFID = FALSE;
}
OGRESRIFeatureServiceLayer::OGRESRIFeatureServiceLayer(
    OGRESRIFeatureServiceDataset* poDSIn) :
    poDS(poDSIn),
    nFeaturesRead(0),
    nLastFID(0),
    bOtherPage(false),
    bUseSequentialFID(false)
{
    OGRFeatureDefn* poSrcFeatDefn = poDS->GetUnderlyingLayer()->GetLayerDefn();
    poFeatureDefn = new OGRFeatureDefn(poSrcFeatDefn->GetName());
    SetDescription(poFeatureDefn->GetName());
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType(wkbNone);
    for(int i=0;i<poSrcFeatDefn->GetFieldCount();i++)
        poFeatureDefn->AddFieldDefn(poSrcFeatDefn->GetFieldDefn(i));
    for(int i=0;i<poSrcFeatDefn->GetGeomFieldCount();i++)
        poFeatureDefn->AddGeomFieldDefn(poSrcFeatDefn->GetGeomFieldDefn(i));
}
Exemple #6
0
void OGRUnionLayer::ConfigureActiveLayer()
{
    AutoWarpLayerIfNecessary(iCurLayer);
    ApplyAttributeFilterToSrcLayer(iCurLayer);
    SetSpatialFilterToSourceLayer(papoSrcLayers[iCurLayer]);
    papoSrcLayers[iCurLayer]->ResetReading();

    /* Establish map */
    GetLayerDefn();
    OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iCurLayer]->GetLayerDefn();
    CPLFree(panMap);
    panMap = (int*) CPLMalloc(poSrcFeatureDefn->GetFieldCount() * sizeof(int));
    for(int i=0; i < poSrcFeatureDefn->GetFieldCount(); i++)
    {
        OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
        if( CSLFindString(papszIgnoredFields,
                          poSrcFieldDefn->GetNameRef() ) == -1 )
        {
            panMap[i] =
                poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
        }
        else
        {
            panMap[i] = -1;
        }
    }

    if( papoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields) )
    {
        char** papszIter = papszIgnoredFields;
        char** papszFieldsSrc = NULL;
        while ( papszIter != NULL && *papszIter != NULL )
        {
            const char* pszFieldName = *papszIter;
            if ( EQUAL(pszFieldName, "OGR_GEOMETRY") ||
                 EQUAL(pszFieldName, "OGR_STYLE") ||
                 poSrcFeatureDefn->GetFieldIndex(pszFieldName) >= 0 ||
                 poSrcFeatureDefn->GetGeomFieldIndex(pszFieldName) >= 0 )
            {
                papszFieldsSrc = CSLAddString(papszFieldsSrc, pszFieldName);
            }
            papszIter++;
        }

        /* Attribute fields */
        int* panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int),
                                          poSrcFeatureDefn->GetFieldCount());
        for(int iField = 0;
                iField < poFeatureDefn->GetFieldCount(); iField++)
        {
            OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iField);
            int iSrcField =
                    poSrcFeatureDefn->GetFieldIndex(poFieldDefn->GetNameRef());
            if (iSrcField >= 0)
                panSrcFieldsUsed[iSrcField] = TRUE;
        }
        for(int iSrcField = 0;
                iSrcField < poSrcFeatureDefn->GetFieldCount(); iSrcField ++)
        {
            if( !panSrcFieldsUsed[iSrcField] )
            {
                OGRFieldDefn *poSrcDefn =
                        poSrcFeatureDefn->GetFieldDefn( iSrcField );
                papszFieldsSrc =
                        CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
            }
        }
        CPLFree(panSrcFieldsUsed);

        /* geometry fields now */
        panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int),
                                          poSrcFeatureDefn->GetGeomFieldCount());
        for(int iField = 0;
                iField < poFeatureDefn->GetGeomFieldCount(); iField++)
        {
            OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iField);
            int iSrcField =
                    poSrcFeatureDefn->GetGeomFieldIndex(poFieldDefn->GetNameRef());
            if (iSrcField >= 0)
                panSrcFieldsUsed[iSrcField] = TRUE;
        }
        for(int iSrcField = 0;
                iSrcField < poSrcFeatureDefn->GetGeomFieldCount(); iSrcField ++)
        {
            if( !panSrcFieldsUsed[iSrcField] )
            {
                OGRGeomFieldDefn *poSrcDefn =
                        poSrcFeatureDefn->GetGeomFieldDefn( iSrcField );
                papszFieldsSrc =
                        CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
            }
        }
        CPLFree(panSrcFieldsUsed);

        papoSrcLayers[iCurLayer]->SetIgnoredFields((const char**)papszFieldsSrc);

        CSLDestroy(papszFieldsSrc);
    }
}
Exemple #7
0
OGRFeatureDefn *OGRUnionLayer::GetLayerDefn()
{
    if( poFeatureDefn != NULL )
        return poFeatureDefn;

    poFeatureDefn = new OGRFeatureDefn( osName );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType(wkbNone);

    int iCompareFirstIndex = 0;
    if( osSourceLayerFieldName.size() )
    {
        OGRFieldDefn oField(osSourceLayerFieldName, OFTString);
        poFeatureDefn->AddFieldDefn(&oField);
        iCompareFirstIndex = 1;
    }

    if( eFieldStrategy == FIELD_SPECIFIED )
    {
        int i;
        for(i = 0; i < nFields; i++)
            poFeatureDefn->AddFieldDefn(papoFields[i]);
        for(i = 0; i < nGeomFields; i++)
        {
            poFeatureDefn->AddGeomFieldDefn(new OGRUnionLayerGeomFieldDefn(papoGeomFields[i]), FALSE);
            OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
                (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(i);

            if( poGeomFieldDefn->bGeomTypeSet == FALSE ||
                poGeomFieldDefn->bSRSSet == FALSE )
            {
                for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
                {
                    OGRFeatureDefn* poSrcFeatureDefn =
                                papoSrcLayers[iLayer]->GetLayerDefn();
                    int nIndex =
                        poSrcFeatureDefn->GetGeomFieldIndex(poGeomFieldDefn->GetNameRef());
                    if( nIndex >= 0 )
                    {
                        OGRGeomFieldDefn* poSrcGeomFieldDefn =
                            poSrcFeatureDefn->GetGeomFieldDefn(nIndex);
                        if( poGeomFieldDefn->bGeomTypeSet == FALSE )
                        {
                            poGeomFieldDefn->bGeomTypeSet = TRUE;
                            poGeomFieldDefn->SetType(poSrcGeomFieldDefn->GetType());
                        }
                        if( poGeomFieldDefn->bSRSSet == FALSE )
                        {
                            poGeomFieldDefn->bSRSSet = TRUE;
                            poGeomFieldDefn->SetSpatialRef(poSrcGeomFieldDefn->GetSpatialRef());
                            if( i == 0 && poGlobalSRS == NULL )
                            {
                                poGlobalSRS = poSrcGeomFieldDefn->GetSpatialRef();
                                if( poGlobalSRS != NULL )
                                    poGlobalSRS->Reference();
                            }
                        }
                        break;
                    }
                }
            }
        }
    }
    else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER )
    {
        OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
        int i;
        for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
            poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
        for(i = 0;  nGeomFields != - 1 && i < poSrcFeatureDefn->GetGeomFieldCount(); i++)
        {
            OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
            poFeatureDefn->AddGeomFieldDefn(
                new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE);
        }
    }
    else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS )
    {
        if( nGeomFields == 1 )
        {
            poFeatureDefn->AddGeomFieldDefn(
                        new OGRUnionLayerGeomFieldDefn(papoGeomFields[0]), FALSE);
        }

        for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
        {
            OGRFeatureDefn* poSrcFeatureDefn =
                                papoSrcLayers[iLayer]->GetLayerDefn();

            /* Add any field that is found in the source layers */
            int i;
            for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
            {
                OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
                int nIndex =
                    poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
                if( nIndex < 0 )
                    poFeatureDefn->AddFieldDefn(poSrcFieldDefn);
                else
                {
                    OGRFieldDefn* poFieldDefn =
                                        poFeatureDefn->GetFieldDefn(nIndex);
                    MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
                }
            }

            for(i = 0; nGeomFields != - 1 && i < poSrcFeatureDefn->GetGeomFieldCount(); i++)
            {
                OGRGeomFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
                int nIndex =
                    poFeatureDefn->GetGeomFieldIndex(poSrcFieldDefn->GetNameRef());
                if( nIndex < 0 )
                {
                    poFeatureDefn->AddGeomFieldDefn(
                        new OGRUnionLayerGeomFieldDefn(poSrcFieldDefn), FALSE);
                    if( poFeatureDefn->GetGeomFieldCount() == 1 && nGeomFields == 0 &&
                        GetSpatialRef() != NULL )
                    {
                        OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
                            (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(0);
                        poGeomFieldDefn->bSRSSet = TRUE;
                        poGeomFieldDefn->SetSpatialRef(GetSpatialRef());
                    }
                }
                else
                {
                    if( nIndex == 0 && nGeomFields == 1 )
                    {
                        OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
                            (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(0);
                        if( poGeomFieldDefn->bGeomTypeSet == FALSE )
                        {
                            poGeomFieldDefn->bGeomTypeSet = TRUE;
                            poGeomFieldDefn->SetType(poSrcFieldDefn->GetType());
                        }
                        if( poGeomFieldDefn->bSRSSet == FALSE )
                        {
                            poGeomFieldDefn->bSRSSet = TRUE;
                            poGeomFieldDefn->SetSpatialRef(poSrcFieldDefn->GetSpatialRef());
                        }
                    }
                    /* TODO: merge type, SRS, extent ? */
                }
            }
        }
    }
    else if (eFieldStrategy == FIELD_INTERSECTION_ALL_LAYERS )
    {
        OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
        int i;
        for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
            poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
        for(i = 0; i < poSrcFeatureDefn->GetGeomFieldCount(); i++)
        {
            OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
            poFeatureDefn->AddGeomFieldDefn(
                new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE);
        }

        /* Remove any field that is not found in the source layers */
        for(int iLayer = 1; iLayer < nSrcLayers; iLayer++)
        {
            OGRFeatureDefn* l_poSrcFeatureDefn =
                                        papoSrcLayers[iLayer]->GetLayerDefn();
            for(i = iCompareFirstIndex; i < poFeatureDefn->GetFieldCount();)
            {
                OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
                int nSrcIndex = l_poSrcFeatureDefn->GetFieldIndex(
                                                    poFieldDefn->GetNameRef());
                if( nSrcIndex < 0 )
                {
                    poFeatureDefn->DeleteFieldDefn(i);
                }
                else
                {
                    OGRFieldDefn* poSrcFieldDefn =
                        l_poSrcFeatureDefn->GetFieldDefn(nSrcIndex);
                    MergeFieldDefn(poFieldDefn, poSrcFieldDefn);

                    i ++;
                }
            }
            for(i = 0; i < poFeatureDefn->GetGeomFieldCount();)
            {
                OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(i);
                int nSrcIndex = l_poSrcFeatureDefn->GetGeomFieldIndex(
                                                    poFieldDefn->GetNameRef());
                if( nSrcIndex < 0 )
                {
                    poFeatureDefn->DeleteGeomFieldDefn(i);
                }
                else
                {
                    /* TODO: merge type, SRS, extent ? */

                    i ++;
                }
            }
        }
    }

    return poFeatureDefn;
}
Exemple #8
0
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) {
    char **tokens = NULL;
    int ret = TRUE;
    int warned = FALSE;
    int geomIdx = -1;

    OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
    OGRFeature *feature = NULL;
    bool bFeatureAdded = false;

    while (ret && (tokens = ReadParseLine()) != NULL)
    {
      const char *firsttok = CSLGetField(tokens, 0);
      if (EQUAL(firsttok, "OBJE"))
      {
        if (featureDef->GetFieldCount() == 0 && curLayer->GetFeatureCount() == 0)
        {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "No field definition found for table: %s",
                    featureDef->GetName() );
          // Model not read - use heuristics.
          for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ )
          {
            char szFieldName[32];
            snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex);
            OGRFieldDefn oFieldDefn(szFieldName, OFTString);
            featureDef->AddFieldDefn(&oFieldDefn);
          }
        }
        //start new feature
        if( !bFeatureAdded )
            delete feature;
        feature = new OGRFeature(featureDef);

        for( int fIndex=1, fieldno = 0;
             fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount();
             fIndex++, fieldno++ )
        {
          if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) {
#ifdef DEBUG_VERBOSE
            CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s",
                      fieldno, featureDef->GetFieldDefn(fieldno)->GetType(),
                      tokens[fIndex] );
#endif
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) {
                // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8
                char* pszRecoded = CPLRecode(
                    tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
                // Replace space marks
                for( char* pszString = pszRecoded;
                     *pszString != '\0';
                     pszString++ ) {
                    if (*pszString == codeBlank) *pszString = ' ';
                }
                feature->SetField(fieldno, pszRecoded);
                CPLFree(pszRecoded);
            } else {
              feature->SetField(fieldno, tokens[fIndex]);
            }
            if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal
                && fieldno > 0
                && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) {
              // Check for Point geometry (Coord type).
              // If there is no ili model read,
              // we have no chance to detect the
              // geometry column.
              CPLString geomfldname
                  = featureDef->GetFieldDefn(fieldno)->GetNameRef();
              // Check if name ends with _1.
              if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2]
                  == '_') {
                geomfldname = geomfldname.substr(0, geomfldname.size()-2);
                geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str());
                if (geomIdx == -1)
                {
                  CPLError( CE_Warning, CPLE_AppDefined,
                            "No matching definition for field '%s' of "
                            "table %s found",
                            geomfldname.c_str(), featureDef->GetName() );
                }
              } else {
                geomIdx = -1;
              }
              if (geomIdx >= 0) {
                if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                    wkbPoint) {
                  // Add Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]));
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() ==
                           wkbPoint25D && fieldno > 1 &&
                           featureDef->GetFieldDefn(fieldno-2)->GetType() ==
                           OFTReal) {
                  // Add 3D Point geometry.
                  OGRPoint *ogrPoint = new OGRPoint(
                      CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]),
                      CPLAtof(tokens[fIndex]) );
                  feature->SetGeomFieldDirectly(geomIdx, ogrPoint);
                }
              }
            }
          }
        }
        if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) {
          CPLError( CE_Warning, CPLE_AppDefined,
                    "Field count of table %s doesn't match. %d declared, "
                    "%d found (e.g. ignored LINEATTR)",
                    featureDef->GetName(), featureDef->GetFieldCount(),
                    CSLCount(tokens) - 1 );
          warned = TRUE;
        }
        if (feature->GetFieldCount() > 0) {
          // USE _TID as FID. TODO: respect IDENT field from model.
          feature->SetFID(feature->GetFieldAsInteger64(0));
        }
        curLayer->AddFeature(feature);
        bFeatureAdded = true;
        geomIdx = -1; //Reset
      }
      else if (EQUAL(firsttok, "STPT") && feature != NULL)
      {
        //Find next non-Point geometry
        if (geomIdx < 0) geomIdx = 0;
        while (geomIdx < featureDef->GetGeomFieldCount() &&
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) {
            geomIdx++;
        }
        OGRwkbGeometryType geomType
            = (geomIdx < featureDef->GetGeomFieldCount()) ?
               featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone;
        if( CSLCount(tokens) >= 3 )
            ReadGeom(tokens, geomIdx, geomType, feature);
      }
      else if (EQUAL(firsttok, "ELIN"))
      {
        // Empty geom.
      }
      else if (EQUAL(firsttok, "EDGE") && feature != NULL)
      {
        CSLDestroy(tokens);
        tokens = ReadParseLine(); //STPT
        //Find next non-Point geometry
        do {
            geomIdx++;
        } while (geomIdx < featureDef->GetGeomFieldCount() &&
                 featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint);
        if( CSLCount(tokens) >= 3 )
            ReadGeom(tokens, geomIdx, wkbMultiLineString, feature);
      }
      else if (EQUAL(firsttok, "PERI"))
      {
      }
      else if (EQUAL(firsttok, "ETAB"))
      {
        CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB,
                  curLayer->GetFeatureCount() );
        CSLDestroy(tokens);
        if( !bFeatureAdded )
            delete feature;
        return TRUE;
      }
      else
      {
        CPLError( CE_Warning, CPLE_AppDefined,
                  "Unexpected token: %s", firsttok );
      }

      CSLDestroy(tokens);
    }

    if( !bFeatureAdded )
        delete feature;

    return ret;
}
Exemple #9
0
OGRErr OGRCSVEditableLayerSynchronizer::EditableSyncToDisk(OGRLayer* poEditableLayer,
                                                           OGRLayer** ppoDecoratedLayer)
{
    CPLAssert( m_poCSVLayer == *ppoDecoratedLayer );

    CPLString osLayerName(m_poCSVLayer->GetName());
    CPLString osFilename(m_poCSVLayer->GetFilename());
    const bool bCreateCSVT = m_poCSVLayer->GetCreateCSVT();
    CPLString osCSVTFilename(CPLResetExtension(osFilename, "csvt"));
    VSIStatBufL sStatBuf;
    const bool bHasCSVT = VSIStatL(osCSVTFilename, &sStatBuf) == 0;
    CPLString osTmpFilename(osFilename);
    CPLString osTmpCSVTFilename(osFilename);
    if( VSIStatL(osFilename, &sStatBuf) == 0 )
    {
        osTmpFilename += "_ogr_tmp.csv";
        osTmpCSVTFilename += "_ogr_tmp.csvt";
    }
    const char chDelimiter = m_poCSVLayer->GetDelimiter();
    OGRCSVLayer* poCSVTmpLayer = new OGRCSVLayer( osLayerName, NULL,
                                                  osTmpFilename,
                                                  true, true, chDelimiter );
    poCSVTmpLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions);
    poCSVTmpLayer->SetCRLF( m_poCSVLayer->GetCRLF() );
    poCSVTmpLayer->SetCreateCSVT( bCreateCSVT || bHasCSVT );
    poCSVTmpLayer->SetWriteBOM( m_poCSVLayer->GetWriteBOM() );

    if( m_poCSVLayer->GetGeometryFormat() == OGR_CSV_GEOM_AS_WKT )
        poCSVTmpLayer->SetWriteGeometry( wkbNone, OGR_CSV_GEOM_AS_WKT, NULL );

    OGRErr eErr = OGRERR_NONE;
    OGRFeatureDefn* poEditableFDefn =  poEditableLayer->GetLayerDefn();
    for( int i=0; eErr == OGRERR_NONE &&
                  i < poEditableFDefn->GetFieldCount(); i++ )
    {
        OGRFieldDefn oFieldDefn(poEditableFDefn->GetFieldDefn(i));
        int iGeomFieldIdx = 0;
        if( (EQUAL(oFieldDefn.GetNameRef(), "WKT") &&
             (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex("")) >= 0) ||
            (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex(oFieldDefn.GetNameRef())) >= 0 )
        {
            OGRGeomFieldDefn oGeomFieldDefn(
                poEditableFDefn->GetGeomFieldDefn(iGeomFieldIdx) );
            eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn );
        }
        else
        {
            eErr = poCSVTmpLayer->CreateField( &oFieldDefn );
        }
    }

    const bool bHasXY = ( !m_poCSVLayer->GetXField().empty() &&
                          !m_poCSVLayer->GetYField().empty() );
    const bool bHasZ = ( !m_poCSVLayer->GetZField().empty() );
    if( bHasXY && !CPLFetchBool(m_papszOpenOptions, "KEEP_GEOM_COLUMNS", true) )
    {
        if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetXField()) < 0 )
        {
            OGRFieldDefn oFieldDefn(m_poCSVLayer->GetXField(), OFTReal);
            if( eErr == OGRERR_NONE )
                eErr = poCSVTmpLayer->CreateField( &oFieldDefn );
        }
        if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetYField()) < 0 )
        {
            OGRFieldDefn oFieldDefn(m_poCSVLayer->GetYField(), OFTReal);
            if( eErr == OGRERR_NONE )
                eErr = poCSVTmpLayer->CreateField( &oFieldDefn );
        }
        if( bHasZ && poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetZField()) < 0 )
        {
            OGRFieldDefn oFieldDefn(m_poCSVLayer->GetZField(), OFTReal);
            if( eErr == OGRERR_NONE )
                eErr = poCSVTmpLayer->CreateField( &oFieldDefn );
        }
    }

    int nFirstGeomColIdx = 0;
    if( m_poCSVLayer->HasHiddenWKTColumn() )
    {
        poCSVTmpLayer->SetWriteGeometry(
            poEditableFDefn->GetGeomFieldDefn(0)->GetType(),
            OGR_CSV_GEOM_AS_WKT,
            poEditableFDefn->GetGeomFieldDefn(0)->GetNameRef());
        nFirstGeomColIdx = 1;
    }

    if( !(poEditableFDefn->GetGeomFieldCount() == 1 && bHasXY) )
    {
        for( int i=nFirstGeomColIdx; eErr == OGRERR_NONE &&
                i < poEditableFDefn->GetGeomFieldCount(); i++ )
        {
            OGRGeomFieldDefn oGeomFieldDefn( poEditableFDefn->GetGeomFieldDefn(i) );
            if( poCSVTmpLayer->GetLayerDefn()->GetGeomFieldIndex(oGeomFieldDefn.GetNameRef()) >= 0 )
                continue;
            eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn );
        }
    }

    OGRFeature* poFeature = NULL;
    poEditableLayer->ResetReading();
    while( eErr == OGRERR_NONE &&
           (poFeature = poEditableLayer->GetNextFeature()) != NULL )
    {
        OGRFeature* poNewFeature = new OGRFeature( poCSVTmpLayer->GetLayerDefn() );
        poNewFeature->SetFrom(poFeature);
        if( bHasXY )
        {
            OGRGeometry* poGeom = poFeature->GetGeometryRef();
            if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
            {
                poNewFeature->SetField( m_poCSVLayer->GetXField(),
                                        static_cast<OGRPoint*>(poGeom)->getX());
                poNewFeature->SetField( m_poCSVLayer->GetYField(),
                                        static_cast<OGRPoint*>(poGeom)->getY());
                if( bHasZ )
                {
                    poNewFeature->SetField( m_poCSVLayer->GetZField(),
                                        static_cast<OGRPoint*>(poGeom)->getZ());
                }
            }
        }
        eErr = poCSVTmpLayer->CreateFeature(poNewFeature);
        delete poFeature;
        delete poNewFeature;
    }
    delete poCSVTmpLayer;

    if( eErr != OGRERR_NONE )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Error while creating %s",
                 osTmpFilename.c_str());
        VSIUnlink( osTmpFilename );
        VSIUnlink( CPLResetExtension(osTmpFilename, "csvt") );
        return eErr;
    }

    delete m_poCSVLayer;

    if( osFilename != osTmpFilename )
    {
        CPLString osTmpOriFilename(osFilename + ".ogr_bak");
        CPLString osTmpOriCSVTFilename(osCSVTFilename + ".ogr_bak");
        if( VSIRename( osFilename, osTmpOriFilename ) != 0 ||
            (bHasCSVT && VSIRename( osCSVTFilename, osTmpOriCSVTFilename ) != 0 ) ||
            VSIRename( osTmpFilename, osFilename) != 0 ||
            (bHasCSVT && VSIRename( osTmpCSVTFilename, osCSVTFilename ) != 0) )
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Cannot rename files");
            *ppoDecoratedLayer = NULL;
            m_poCSVLayer = NULL;
            return OGRERR_FAILURE;
        }
        VSIUnlink( osTmpOriFilename );
        if( bHasCSVT )
            VSIUnlink( osTmpOriCSVTFilename );
    }

    VSILFILE* fp = VSIFOpenL( osFilename, "rb+" );
    if( fp == NULL )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot reopen updated %s",
                 osFilename.c_str());
        *ppoDecoratedLayer = NULL;
        m_poCSVLayer = NULL;
        return OGRERR_FAILURE;
    }

    m_poCSVLayer = new OGRCSVLayer( osLayerName, fp,
                                    osFilename,
                                    false, /* new */
                                    true, /* update */
                                    chDelimiter );
    m_poCSVLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions);
    *ppoDecoratedLayer = m_poCSVLayer;

    return OGRERR_NONE;
}
Exemple #10
0
static int WFS_ExprDumpAsOGCFilter(CPLString& osFilter,
                                   const swq_expr_node* poExpr,
                                   int bExpectBinary,
                                   ExprDumpFilterOptions* psOptions)
{
    if( poExpr->eNodeType == SNT_COLUMN )
    {
        if (bExpectBinary)
            return FALSE;

        /* Special fields not understood by server */
        if (EQUAL(poExpr->string_value, "gml_id") ||
            EQUAL(poExpr->string_value, "FID") ||
            EQUAL(poExpr->string_value, "OGR_GEOMETRY") ||
            EQUAL(poExpr->string_value, "OGR_GEOM_WKT") ||
            EQUAL(poExpr->string_value, "OGR_GEOM_AREA") ||
            EQUAL(poExpr->string_value, "OGR_STYLE"))
        {
            CPLDebug("WFS", "Attribute refers to a OGR special field. Cannot use server-side filtering");
            return FALSE;
        }

        const char* pszFieldname = NULL;
        int nIndex;
        int bSameTable = psOptions->poFDefn != NULL &&
                         ( poExpr->table_name == NULL ||
                           EQUAL(poExpr->table_name, psOptions->poFDefn->GetName()) );
        if( bSameTable )
        {
            if( (nIndex = psOptions->poFDefn->GetFieldIndex(poExpr->string_value)) >= 0 )
            {
                pszFieldname = psOptions->poFDefn->GetFieldDefn(nIndex)->GetNameRef();
            }
            else if( (nIndex = psOptions->poFDefn->GetGeomFieldIndex(poExpr->string_value)) >= 0 )
            {
                pszFieldname = psOptions->poFDefn->GetGeomFieldDefn(nIndex)->GetNameRef();
            }
        }
        else if( psOptions->poDS != NULL )
        {
            OGRLayer* poLayer = psOptions->poDS->GetLayerByName(poExpr->table_name);
            if( poLayer )
            {
                OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
                if( (nIndex = poFDefn->GetFieldIndex(poExpr->string_value)) >= 0 )
                {
                    pszFieldname = CPLSPrintf("%s/%s",
                                              poLayer->GetName(),
                                              poFDefn->GetFieldDefn(nIndex)->GetNameRef());
                }
                else if( (nIndex = poFDefn->GetGeomFieldIndex(poExpr->string_value)) >= 0 )
                {
                    pszFieldname = CPLSPrintf("%s/%s",
                                              poLayer->GetName(),
                                              poFDefn->GetGeomFieldDefn(nIndex)->GetNameRef());
                }
            }
        }
        
        if( psOptions->poFDefn == NULL && psOptions->poDS == NULL )
            pszFieldname = poExpr->string_value;

        if( pszFieldname == NULL )
        {
            if( poExpr->table_name != NULL )
                CPLDebug("WFS", "Field \"%s\".\"%s\" unknown. Cannot use server-side filtering",
                         poExpr->table_name, poExpr->string_value);
            else
                CPLDebug("WFS", "Field \"%s\" unknown. Cannot use server-side filtering",
                         poExpr->string_value);
            return FALSE;
        }

        if (psOptions->nVersion >= 200)
            osFilter += CPLSPrintf("<%sValueReference>", psOptions->pszNSPrefix);
        else
            osFilter += CPLSPrintf("<%sPropertyName>", psOptions->pszNSPrefix);
        char* pszFieldnameXML = CPLEscapeString(pszFieldname, -1, CPLES_XML);
        osFilter += pszFieldnameXML;
        CPLFree(pszFieldnameXML);
        if (psOptions->nVersion >= 200)
            osFilter += CPLSPrintf("</%sValueReference>", psOptions->pszNSPrefix);
        else
            osFilter += CPLSPrintf("</%sPropertyName>", psOptions->pszNSPrefix);

        return TRUE;
    }

    if( poExpr->eNodeType == SNT_CONSTANT )
    {
        if (bExpectBinary)
            return FALSE;

        osFilter += CPLSPrintf("<%sLiteral>", psOptions->pszNSPrefix);
        if( !WFS_ExprDumpRawLitteral(osFilter, poExpr) )
            return FALSE;
        osFilter += CPLSPrintf("</%sLiteral>", psOptions->pszNSPrefix);

        return TRUE;
    }
    
    if( poExpr->eNodeType != SNT_OPERATION )
        return FALSE; /* shouldn't happen */

    if( poExpr->nOperation == SWQ_NOT )
    {
        osFilter +=  CPLSPrintf("<%sNot>", psOptions->pszNSPrefix);
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], TRUE, psOptions))
            return FALSE;
        osFilter +=  CPLSPrintf("</%sNot>", psOptions->pszNSPrefix);
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_LIKE )
    {
        CPLString osVal;
        char ch;
        char firstCh = 0;
        int i;
        if (psOptions->nVersion == 100)
            osFilter += CPLSPrintf("<%sPropertyIsLike wildCard='*' singleChar='_' escape='!'>", psOptions->pszNSPrefix);
        else
            osFilter += CPLSPrintf("<%sPropertyIsLike wildCard='*' singleChar='_' escapeChar='!'>", psOptions->pszNSPrefix);
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions))
            return FALSE;
        if (poExpr->papoSubExpr[1]->eNodeType != SNT_CONSTANT &&
            poExpr->papoSubExpr[1]->field_type != SWQ_STRING)
            return FALSE;
        osFilter += CPLSPrintf("<%sLiteral>", psOptions->pszNSPrefix);

        /* Escape value according to above special characters */
        /* For URL compatibility reason, we remap the OGR SQL '%' wildchard into '*' */
        i = 0;
        ch = poExpr->papoSubExpr[1]->string_value[i];
        if (ch == '\'' || ch == '"')
        {
            firstCh = ch;
            i ++;
        }
        for(;(ch = poExpr->papoSubExpr[1]->string_value[i]) != '\0';i++)
        {
            if (ch == '%')
                osVal += "*";
            else if (ch == '!')
                osVal += "!!";
            else if (ch == '*')
                osVal += "!*";
            else if (ch == firstCh && poExpr->papoSubExpr[1]->string_value[i + 1] == 0)
                break;
            else
            {
                char ach[2];
                ach[0] = ch;
                ach[1] = 0;
                osVal += ach;
            }
        }
        char* pszXML = CPLEscapeString(osVal, -1, CPLES_XML);
        osFilter += pszXML;
        CPLFree(pszXML);
        osFilter += CPLSPrintf("</%sLiteral>", psOptions->pszNSPrefix);
        osFilter += CPLSPrintf("</%sPropertyIsLike>", psOptions->pszNSPrefix);
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_ISNULL )
    {
        osFilter += CPLSPrintf("<%sPropertyIsNull>", psOptions->pszNSPrefix);
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions))
            return FALSE;
        osFilter += CPLSPrintf("</%sPropertyIsNull>", psOptions->pszNSPrefix);
        psOptions->bOutNeedsNullCheck = TRUE;
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_EQ ||
        poExpr->nOperation == SWQ_NE ||
        poExpr->nOperation == SWQ_LE ||
        poExpr->nOperation == SWQ_LT ||
        poExpr->nOperation == SWQ_GE ||
        poExpr->nOperation == SWQ_GT )
    {
        int nOperation = poExpr->nOperation;
        int bAddClosingNot = FALSE;
        if (!psOptions->bPropertyIsNotEqualToSupported && nOperation == SWQ_NE)
        {
            osFilter += CPLSPrintf("<%sNot>", psOptions->pszNSPrefix);
            nOperation = SWQ_EQ;
            bAddClosingNot = TRUE;
        }

        const char* pszName = NULL;
        switch(nOperation)
        {
            case SWQ_EQ:  pszName = "PropertyIsEqualTo"; break;
            case SWQ_NE:  pszName = "PropertyIsNotEqualTo"; break;
            case SWQ_LE:  pszName = "PropertyIsLessThanOrEqualTo"; break;
            case SWQ_LT:  pszName = "PropertyIsLessThan"; break;
            case SWQ_GE:  pszName = "PropertyIsGreaterThanOrEqualTo"; break;
            case SWQ_GT:  pszName = "PropertyIsGreaterThan"; break;
            default: break;
        }
        osFilter += "<";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], FALSE, psOptions))
            return FALSE;
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[1], FALSE, psOptions))
            return FALSE;
        osFilter += "</";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        if (bAddClosingNot)
            osFilter += CPLSPrintf("</%sNot>", psOptions->pszNSPrefix);
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_AND ||
        poExpr->nOperation == SWQ_OR )
    {
        const char* pszName = (poExpr->nOperation == SWQ_AND) ? "And" : "Or";
        osFilter += "<";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[0], TRUE, psOptions))
            return FALSE;
        if (!WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[1], TRUE, psOptions))
            return FALSE;
        osFilter += "</";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        return TRUE;
    }
    
    if( poExpr->nOperation == SWQ_CUSTOM_FUNC &&
        EQUAL(poExpr->string_value, "ST_MakeEnvelope") )
    {
        OGRSpatialReference oSRS;
        const char* pszSRSName = WFS_ExprGetSRSName( poExpr, 4, psOptions, oSRS );
        int bAxisSwap = FALSE;

        osFilter += "<gml:Envelope";
        if( pszSRSName )
        {
            osFilter += " srsName=\"";
            osFilter += pszSRSName;
            osFilter += "\"";
            if( oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting() )
                bAxisSwap = TRUE;
        }
        osFilter += ">";
        osFilter += "<gml:lowerCorner>";
        if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 1 : 0]))
            return FALSE;
        osFilter += " ";
        if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 0 : 1]))
            return FALSE;
        osFilter += "</gml:lowerCorner>";
        osFilter += "<gml:upperCorner>";
        if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 3 : 2]))
            return FALSE;
        osFilter += " ";
        if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[(bAxisSwap) ? 2 : 3]))
            return FALSE;
        osFilter += "</gml:upperCorner>";
        osFilter += "</gml:Envelope>";
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_CUSTOM_FUNC &&
        EQUAL(poExpr->string_value, "ST_GeomFromText") )
    {
        OGRSpatialReference oSRS;
        const char* pszSRSName = WFS_ExprGetSRSName( poExpr, 1, psOptions, oSRS );
        OGRGeometry* poGeom = NULL;
        char* pszWKT = (char*)poExpr->papoSubExpr[0]->string_value;
        OGRGeometryFactory::createFromWkt(&pszWKT, NULL, &poGeom);
        char** papszOptions = NULL;
        papszOptions = CSLSetNameValue(papszOptions, "FORMAT", "GML3");
        if( pszSRSName != NULL )
        {
            if( oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting() )
            {
                OGR_SRSNode *poGEOGCS = oSRS.GetAttrNode( "GEOGCS" );
                if( poGEOGCS != NULL )
                    poGEOGCS->StripNodes( "AXIS" );

                OGR_SRSNode *poPROJCS = oSRS.GetAttrNode( "PROJCS" );
                if (poPROJCS != NULL && oSRS.EPSGTreatsAsNorthingEasting())
                    poPROJCS->StripNodes( "AXIS" );
            }

            if( EQUALN(pszSRSName, "urn:ogc:def:crs:EPSG::", strlen("urn:ogc:def:crs:EPSG::")) )
                papszOptions = CSLSetNameValue(papszOptions, "GML3_LONGSRS", "YES");
            else
                papszOptions = CSLSetNameValue(papszOptions, "GML3_LONGSRS", "NO");

            poGeom->assignSpatialReference(&oSRS);
        }
        papszOptions = CSLSetNameValue(papszOptions, "GMLID",
                                       CPLSPrintf("id%d", psOptions->nUniqueGeomGMLId ++));
        char* pszGML = OGR_G_ExportToGMLEx( (OGRGeometryH)poGeom, papszOptions );
        osFilter += pszGML;
        CSLDestroy(papszOptions);
        delete poGeom;
        CPLFree(pszGML);
        return TRUE;
    }

    if( poExpr->nOperation == SWQ_CUSTOM_FUNC )
    {
        const char* pszName =
            EQUAL(poExpr->string_value, "ST_Equals") ? "Equals" :
            EQUAL(poExpr->string_value, "ST_Disjoint") ? "Disjoint" :
            EQUAL(poExpr->string_value, "ST_Touches") ? "Touches" :
            EQUAL(poExpr->string_value, "ST_Contains") ? "Contains" :
            EQUAL(poExpr->string_value, "ST_Intersects") ? "Intersects" :
            EQUAL(poExpr->string_value, "ST_Within") ? "Within" :
            EQUAL(poExpr->string_value, "ST_Crosses") ? "Crosses" :
            EQUAL(poExpr->string_value, "ST_Overlaps") ? "Overlaps" :
            EQUAL(poExpr->string_value, "ST_DWithin") ? "DWithin" :
            EQUAL(poExpr->string_value, "ST_Beyond") ? "Beyond" :
            NULL;
        if( pszName == NULL )
            return FALSE;
        osFilter += "<";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        for(int i=0;i<2;i++)
        {
            if( i == 1 && poExpr->papoSubExpr[0]->eNodeType == SNT_COLUMN &&
                poExpr->papoSubExpr[1]->eNodeType == SNT_OPERATION &&
                poExpr->papoSubExpr[1]->nOperation == SWQ_CUSTOM_FUNC &&
                (EQUAL(poExpr->papoSubExpr[1]->string_value, "ST_GeomFromText") ||
                 EQUAL(poExpr->papoSubExpr[1]->string_value, "ST_MakeEnvelope")) )
            {
                int bSameTable = psOptions->poFDefn != NULL &&
                                ( poExpr->papoSubExpr[0]->table_name == NULL ||
                                EQUAL(poExpr->papoSubExpr[0]->table_name, psOptions->poFDefn->GetName()) );
                if( bSameTable )
                {
                    int nIndex;
                    if( (nIndex = psOptions->poFDefn->GetGeomFieldIndex(poExpr->papoSubExpr[0]->string_value)) >= 0 )
                    {
                        psOptions->poSRS = psOptions->poFDefn->GetGeomFieldDefn(nIndex)->GetSpatialRef();
                    }
                }
                else if( psOptions->poDS != NULL )
                {
                    OGRLayer* poLayer = psOptions->poDS->GetLayerByName(poExpr->papoSubExpr[0]->table_name);
                    if( poLayer )
                    {
                        OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
                        int nIndex;
                        if( (nIndex = poFDefn->GetGeomFieldIndex(poExpr->papoSubExpr[0]->string_value)) >= 0 )
                        {
                            psOptions->poSRS = poFDefn->GetGeomFieldDefn(nIndex)->GetSpatialRef();
                        }
                    }
                }
            }
            int bRet = WFS_ExprDumpAsOGCFilter(osFilter, poExpr->papoSubExpr[i], FALSE, psOptions);
            psOptions->poSRS = NULL;
            if( !bRet )
                return FALSE;
        }
        if( poExpr->nSubExprCount > 2 )
        {
            osFilter += CPLSPrintf("<%sDistance unit=\"m\">", psOptions->pszNSPrefix);
            if (!WFS_ExprDumpRawLitteral(osFilter, poExpr->papoSubExpr[2]) )
                return FALSE;
            osFilter += CPLSPrintf("</%sDistance>", psOptions->pszNSPrefix);
        }
        osFilter += "</";
        osFilter += psOptions->pszNSPrefix;
        osFilter += pszName;
        osFilter += ">";
        return TRUE;
    }

    return FALSE;
}
Exemple #11
0
OGRFeatureDefn *OGRMySQLResultLayer::ReadResultDefinition()

{
/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" );
    SetDescription( poDefn->GetName() );

    poDefn->Reference();

    mysql_field_seek( hResultSet, 0 );
    for( int iRawField = 0;
         iRawField < (int) mysql_num_fields(hResultSet);
         iRawField++ )
    {
        MYSQL_FIELD *psMSField = mysql_fetch_field( hResultSet );
        OGRFieldDefn oField( psMSField->name, OFTString);

        switch( psMSField->type )
        {
          case FIELD_TYPE_TINY:
          case FIELD_TYPE_SHORT:
          case FIELD_TYPE_LONG:
          case FIELD_TYPE_INT24:
          case FIELD_TYPE_LONGLONG:
          {
            oField.SetType( OFTInteger );
            const int width = (int)psMSField->length;
            oField.SetWidth(width);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_DECIMAL:
#ifdef FIELD_TYPE_NEWDECIMAL
          case FIELD_TYPE_NEWDECIMAL:
#endif
          {
            oField.SetType( OFTReal );

            // a bunch of hackery to munge the widths that MySQL gives
            // us into corresponding widths and precisions for OGR
            const int precision = (int)psMSField->decimals;
            int width = (int)psMSField->length;
            if (!precision)
                width = width - 1;
            width = width - precision;

            oField.SetWidth(width);
            oField.SetPrecision(precision);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_FLOAT:
          case FIELD_TYPE_DOUBLE:
         /* MYSQL_FIELD is always reporting ->length = 22 and ->decimals = 31
            for double type regardless of the data it returned. In an example,
            the data it returned had only 5 or 6 decimal places which were
            exactly as entered into the database but reported the decimals
            as 31. */
         /* Assuming that a length of 22 means no particular width and 31
            decimals means no particular precision. */
          {
            const int width = (int)psMSField->length;
            const int precision = (int)psMSField->decimals;
            oField.SetType( OFTReal );
            if( width != 22 )
                oField.SetWidth(width);
            if( precision != 31 )
                oField.SetPrecision(precision);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_DATE:
          {
            oField.SetType( OFTDate );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TIME:
          {
            oField.SetType( OFTTime );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TIMESTAMP:
          case FIELD_TYPE_DATETIME:
          {
            oField.SetType( OFTDateTime );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_YEAR:
          case FIELD_TYPE_STRING:
          case FIELD_TYPE_VAR_STRING:
          {
            oField.SetType( OFTString );
            oField.SetWidth((int)psMSField->length);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TINY_BLOB:
          case FIELD_TYPE_MEDIUM_BLOB:
          case FIELD_TYPE_LONG_BLOB:
          case FIELD_TYPE_BLOB:
          {
            if( psMSField->charsetnr == 63 )
                oField.SetType( OFTBinary );
            else
                oField.SetType( OFTString );
            oField.SetWidth((int)psMSField->max_length);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_GEOMETRY:
          {
            if (pszGeomColumn == nullptr)
            {
                pszGeomColumnTable = CPLStrdup( psMSField->table);
                pszGeomColumn = CPLStrdup( psMSField->name);
            }
            break;
          }
          default:
            // any other field we ignore.
            break;
        }

        // assume a FID name first, and if it isn't there
        // take a field that is not null, a primary key,
        // and is an integer-like field
        if( EQUAL(psMSField->name,"ogc_fid") )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            continue;
        } else
        if (IS_NOT_NULL(psMSField->flags)
            && IS_PRI_KEY(psMSField->flags)
            &&
                (
                    psMSField->type == FIELD_TYPE_TINY
                    || psMSField->type == FIELD_TYPE_SHORT
                    || psMSField->type == FIELD_TYPE_LONG
                    || psMSField->type == FIELD_TYPE_INT24
                    || psMSField->type == FIELD_TYPE_LONGLONG
                )
            )
        {
           bHasFid = TRUE;
           pszFIDColumn = CPLStrdup(oField.GetNameRef());
           continue;
        }
    }

    poDefn->SetGeomType( wkbNone );

    if (pszGeomColumn)
    {
        char*        pszType=nullptr;
        CPLString    osCommand;
        char           **papszRow;

        // set to unknown first
        poDefn->SetGeomType( wkbUnknown );
        poDefn->GetGeomFieldDefn(0)->SetName( pszGeomColumn );

        osCommand.Printf(
                "SELECT type FROM geometry_columns WHERE f_table_name='%s'",
                pszGeomColumnTable );

        if( hResultSet != nullptr )
            mysql_free_result( hResultSet );
        hResultSet = nullptr;

        if( !mysql_query( poDS->GetConn(), osCommand ) )
            hResultSet = mysql_store_result( poDS->GetConn() );

        papszRow = nullptr;
        if( hResultSet != nullptr )
            papszRow = mysql_fetch_row( hResultSet );

        if( papszRow != nullptr && papszRow[0] != nullptr )
        {
            pszType = papszRow[0];

            OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType);

            poDefn->SetGeomType( l_nGeomType );
        }

        nSRSId = FetchSRSId();
    }

    return poDefn;
}
OGRFeatureDefn *OGRMySQLTableLayer::ReadTableDefinition( const char *pszTable )

{
    MYSQL_RES    *hResult;
    CPLString     osCommand;

/* -------------------------------------------------------------------- */
/*      Fire off commands to get back the schema of the table.          */
/* -------------------------------------------------------------------- */
    osCommand.Printf("DESCRIBE `%s`", pszTable );
    pszGeomColumnTable = CPLStrdup(pszTable);
    if( mysql_query( poDS->GetConn(), osCommand ) )
    {
        poDS->ReportError( "DESCRIBE Failed" );
        return NULL;
    }

    hResult = mysql_store_result( poDS->GetConn() );
    if( hResult == NULL )
    {
        poDS->ReportError( "mysql_store_result() failed on DESCRIBE result." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable );
    char           **papszRow;
    OGRwkbGeometryType eForcedGeomType = wkbUnknown;
    int bGeomColumnNotNullable = FALSE;

    poDefn->Reference();

    while( (papszRow = mysql_fetch_row( hResult )) != NULL )
    {
        const char      *pszType;
        OGRFieldDefn    oField( papszRow[0], OFTString);
        int             nLenType;

        pszType = papszRow[1];

        if( pszType == NULL )
            continue;

        nLenType = (int)strlen(pszType);

        if( EQUAL(pszType,"varbinary")
            || (nLenType>=4 && EQUAL(pszType+nLenType-4,"blob")))
        {
            oField.SetType( OFTBinary );
        }
        else if( EQUAL(pszType,"varchar")
                 || (nLenType>=4 && EQUAL(pszType+nLenType-4,"enum"))
                 || (nLenType>=3 && EQUAL(pszType+nLenType-3,"set")) )
        {
            oField.SetType( OFTString );

        }
        else if( STARTS_WITH_CI(pszType, "char")  )
        {
            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 2)
            {
                /* width is the second */
                oField.SetWidth(atoi(papszTokens[1]));
            }

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );

        }

        if(nLenType>=4 && EQUAL(pszType+nLenType-4,"text"))
        {
            oField.SetType( OFTString );
        }
        else if( STARTS_WITH_CI(pszType,"varchar")  )
        {
            /*
               pszType is usually in the form "varchar(15)"
               so we'll split it up and get the width and precision
            */

            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 2)
            {
                /* width is the second */
                oField.SetWidth(atoi(papszTokens[1]));
            }

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );
        }
        else if( STARTS_WITH_CI(pszType, "int") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "tinyint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "smallint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "mediumint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "bigint") )
        {
            oField.SetType( OFTInteger64 );
        }
        else if( STARTS_WITH_CI(pszType, "decimal") )
        {
            /*
               pszType is usually in the form "decimal(15,2)"
               so we'll split it up and get the width and precision
            */
            oField.SetType( OFTReal );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 3)
            {
                /* width is the second and precision is the third */
                oField.SetWidth(atoi(papszTokens[1]));
                oField.SetPrecision(atoi(papszTokens[2]));
            }
            CSLDestroy( papszTokens );


        }
        else if( STARTS_WITH_CI(pszType, "float") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"double") )
        {
            oField.SetType( OFTReal );
        }
        else if( STARTS_WITH_CI(pszType, "double") )
        {
            // double can also be double(15,2)
            // so we'll handle this case here after
            // we check for just a regular double
            // without a width and precision specified

            char ** papszTokens=NULL;
            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 3)
            {
                /* width is the second and precision is the third */
                oField.SetWidth(atoi(papszTokens[1]));
                oField.SetPrecision(atoi(papszTokens[2]));
            }
            CSLDestroy( papszTokens );

            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"decimal") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType, "date") )
        {
            oField.SetType( OFTDate );
        }
        else if( EQUAL(pszType, "time") )
        {
            oField.SetType( OFTTime );
        }
        else if( EQUAL(pszType, "datetime")
                 || EQUAL(pszType, "timestamp") )
        {
            oField.SetType( OFTDateTime );
        }
        else if( EQUAL(pszType, "year") )
        {
            oField.SetType( OFTString );
            oField.SetWidth( 10 );
        }
        else if( EQUAL(pszType, "geometry") ||
                 OGRFromOGCGeomType(pszType) != wkbUnknown)
        {
            if (pszGeomColumn == NULL)
            {
                pszGeomColumn = CPLStrdup(papszRow[0]);
                eForcedGeomType = OGRFromOGCGeomType(pszType);
                bGeomColumnNotNullable = ( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") );
            }
            else
            {
                CPLDebug("MYSQL",
                         "Ignoring %s as geometry column. Another one(%s) has already been found before",
                         papszRow[0], pszGeomColumn);
            }
            continue;
        }
        // Is this an integer primary key field?
        if( !bHasFid && papszRow[3] != NULL && EQUAL(papszRow[3],"PRI")
            && (oField.GetType() == OFTInteger || oField.GetType() == OFTInteger64) )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            if( oField.GetType() == OFTInteger64 )
                SetMetadataItem(OLMD_FID64, "YES");
            continue;
        }

        // Is not nullable ?
        if( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") )
            oField.SetNullable(FALSE);

        // Has default ?
        const char* pszDefault = papszRow[4];
        if( pszDefault != NULL )
        {
            if( !EQUAL(pszDefault, "NULL") &&
                !STARTS_WITH_CI(pszDefault, "CURRENT_") &&
                pszDefault[0] != '(' &&
                pszDefault[0] != '\'' &&
                CPLGetValueType(pszDefault) == CPL_VALUE_STRING )
            {
                int nYear, nMonth, nDay, nHour, nMinute;
                float fSecond;
                if( oField.GetType() == OFTDateTime &&
                    sscanf(pszDefault, "%d-%d-%d %d:%d:%f", &nYear, &nMonth, &nDay,
                                &nHour, &nMinute, &fSecond) == 6 )
                {
                    oField.SetDefault(CPLSPrintf("'%04d/%02d/%02d %02d:%02d:%02d'",
                                            nYear, nMonth, nDay, nHour, nMinute, (int)(fSecond+0.5)));
                }
                else
                {
                    CPLString osDefault("'");
                    char* pszTmp = CPLEscapeString(pszDefault, -1, CPLES_SQL);
                    osDefault += pszTmp;
                    CPLFree(pszTmp);
                    osDefault += "'";
                    oField.SetDefault(osDefault);
                }
            }
            else
            {
                oField.SetDefault(pszDefault);
            }
        }

        poDefn->AddFieldDefn( &oField );
    }

    // set to none for now... if we have a geometry column it will be set layer.
    poDefn->SetGeomType( wkbNone );

    if( hResult != NULL )
    {
        mysql_free_result( hResult );
        hResultSet = NULL;
    }

    if( bHasFid )
        CPLDebug( "MySQL", "table %s has FID column %s.",
                  pszTable, pszFIDColumn );
    else
        CPLDebug( "MySQL",
                  "table %s has no FID column, FIDs will not be reliable!",
                  pszTable );

    if (pszGeomColumn)
    {
        char*        pszType=NULL;

        // set to unknown first
        poDefn->SetGeomType( wkbUnknown );

        osCommand = "SELECT type, coord_dimension FROM geometry_columns WHERE f_table_name='";
        osCommand += pszTable;
        osCommand += "'";

        hResult = NULL;
        if( !mysql_query( poDS->GetConn(), osCommand ) )
            hResult = mysql_store_result( poDS->GetConn() );

        papszRow = NULL;
        if( hResult != NULL )
            papszRow = mysql_fetch_row( hResult );

        if( papszRow != NULL && papszRow[0] != NULL )
        {

            pszType = papszRow[0];

            OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType);

            if( papszRow[1] != NULL && atoi(papszRow[1]) == 3 )
                l_nGeomType = wkbSetZ(l_nGeomType);

            poDefn->SetGeomType( l_nGeomType );

        }
        else if (eForcedGeomType != wkbUnknown)
            poDefn->SetGeomType(eForcedGeomType);

        if( bGeomColumnNotNullable )
            poDefn->GetGeomFieldDefn(0)->SetNullable(FALSE);

        if( hResult != NULL )
            mysql_free_result( hResult );   //Free our query results for finding type.
			hResult = NULL;
    }

    // Fetch the SRID for this table now
    nSRSId = FetchSRSId();
    return poDefn;
}