Example #1
0
void OgrWriter::_addFeature(OGRLayer* layer, shared_ptr<Feature> f, shared_ptr<Geometry> g)
{
  OGRFeature* poFeature = OGRFeature::CreateFeature( layer->GetLayerDefn() );

  // set all the column values.
  const QVariantMap& vm = f->getValues();

  for (QVariantMap::const_iterator it = vm.constBegin(); it != vm.constEnd(); ++it)
  {
    const QVariant& v = it.value();
    QByteArray ba = it.key().toUtf8();

    // If the field DOESN'T exist in the output layer, skip it.
    if (poFeature->GetFieldIndex(ba.constData()) == -1)
    {
      continue;
    }

    switch (v.type())
    {
    case QVariant::Invalid:
      poFeature->UnsetField(poFeature->GetFieldIndex(ba.constData()));
      break;
    case QVariant::Int:
      poFeature->SetField(ba.constData(), v.toInt());
      break;
    case QVariant::Double:
      poFeature->SetField(ba.constData(), v.toDouble());
      break;
    case QVariant::String:
    {
      QByteArray vba = v.toString().toUtf8();
      poFeature->SetField(ba.constData(), vba.constData());
      break;
    }
    default:
      strictError("Can't convert the provided value into an OGR value. (" + v.toString() + ")");
      return;
    }
  }

  // convert the geometry.
  shared_ptr<GeometryCollection> gc = dynamic_pointer_cast<GeometryCollection>(g);
  if (gc.get() != 0)
  {
    for (size_t i = 0; i < gc->getNumGeometries(); i++)
    {
      const Geometry* child = gc->getGeometryN(i);
      _addFeatureToLayer(layer, f, child, poFeature);
    }
  }
  else
  {
    _addFeatureToLayer(layer, f, g.get(), poFeature);
  }

  OGRFeature::DestroyFeature(poFeature);
}
Example #2
0
void OGRGeoJSONLayer::AddFeature( OGRFeature* poFeature )
{
    CPLAssert( NULL != poFeature );

    // NOTE - mloskot:
    // Features may not be sorted according to FID values.

    // TODO: Should we check if feature already exists?
    // TODO: Think about sync operation, upload, etc.

    OGRFeature* poNewFeature = NULL;
    poNewFeature = poFeature->Clone();


    if( -1 == poNewFeature->GetFID() )
    {
        int nFID = static_cast<int>(seqFeatures_.size());
        poNewFeature->SetFID( nFID );

        // TODO - mlokot: We need to redesign creation of FID column
        int nField = poNewFeature->GetFieldIndex( DefaultFIDColumn );
        if( -1 != nField && GetLayerDefn()->GetFieldDefn(nField)->GetType() == OFTInteger )
        {
            poNewFeature->SetField( nField, nFID );
        }
    }

    seqFeatures_.push_back( poNewFeature );
}
Example #3
0
int ILI2Reader::AddFeature(DOMElement *elem) {
  bool newLayer = true;
  OGRLayer *curLayer = NULL;
  char *pszName = tr_strdup(elem->getTagName());
  //CPLDebug( "OGR_ILI", "Reading layer: %s", pszName );

  // test if this layer exist
  curLayer = GetLayer(pszName);
  newLayer = (curLayer == NULL);

  // add a layer
  if (newLayer) {
    CPLDebug( "OGR_ILI", "Adding layer: %s", pszName );
    OGRFeatureDefn* poFeatureDefn = new OGRFeatureDefn(pszName);
    poFeatureDefn->SetGeomType( wkbUnknown );
    GeomFieldInfos oGeomFieldInfos;
    curLayer = new OGRILI2Layer(poFeatureDefn, oGeomFieldInfos, NULL);
    m_listLayer.push_back(curLayer);
  }

  // the feature and field definition
  OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
  if (newLayer) {
    // add TID field
    OGRFieldDefn ofieldDefn (ILI2_TID, OFTString);
    featureDef->AddFieldDefn(&ofieldDefn);

    setFieldDefn(featureDef, elem);
  }

  // add the features
  OGRFeature *feature = new OGRFeature(featureDef);

  // assign TID
  int fIndex = feature->GetFieldIndex(ILI2_TID);
  if (fIndex != -1) {
      XMLCh *pszIli2_tid = XMLString::transcode(ILI2_TID);
      char *fChVal = tr_strdup(elem->getAttribute(pszIli2_tid));
      feature->SetField(fIndex, fChVal);
      XMLString::release(&pszIli2_tid);
      CPLFree(fChVal);
  } else {
      CPLDebug( "OGR_ILI","'%s' not found", ILI2_TID);
  }

  SetFieldValues(feature, elem);
  CPL_IGNORE_RET_VAL(curLayer->SetFeature(feature));

  CPLFree(pszName);

  return 0;
}
Example #4
0
static void ParseObject(const char* pszId,
                        json_object* poObj, OGRGeoJSONLayer* poLayer,
                        json_object* poArcsDB, ScalingParams* psParams)
{
    json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type");
    if( poType == NULL || json_object_get_type(poType) != json_type_string )
        return;
    const char* pszType = json_object_get_string(poType);

    json_object* poArcsObj = OGRGeoJSONFindMemberByName(poObj, "arcs");
    json_object* poCoordinatesObj = OGRGeoJSONFindMemberByName(poObj, "coordinates");
    if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 )
    {
        if( poCoordinatesObj == NULL || json_type_array != json_object_get_type(poCoordinatesObj) )
            return;
    }
    else
    {
        if( poArcsObj == NULL || json_type_array != json_object_get_type(poArcsObj) )
            return;
    }

    if( pszId == NULL )
    {
        json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id");
        if( poId != NULL &&
            (json_type_string == json_object_get_type(poId) ||
             json_type_int == json_object_get_type(poId)) )
        {
            pszId = json_object_get_string(poId);
        }
    }

    OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn());
    if( pszId != NULL )
        poFeature->SetField("id", pszId);

    json_object* poProperties = OGRGeoJSONFindMemberByName(poObj, "properties");
    if( poProperties != NULL && json_type_object == json_object_get_type(poProperties) )
    {
        json_object_iter it;
        it.key = NULL;
        it.val = NULL;
        it.entry = NULL;
        json_object_object_foreachC( poProperties, it )
        {
            const int nField
                = poFeature->GetFieldIndex(it.key);
            OGRGeoJSONReaderSetField(poLayer, poFeature, nField, it.key, it.val, false, 0);
        }
    }
Example #5
0
int ILI2Reader::AddFeature(DOMElement *elem) {
  bool newLayer = true;
  OGRLayer *curLayer = 0;
  char *pszName = XMLString::transcode(elem->getTagName());

  // test if this layer exist
  for (list<OGRLayer *>::reverse_iterator layerIt = m_listLayer.rbegin();
       layerIt != m_listLayer.rend();
       ++layerIt) {
    OGRFeatureDefn *fDef = (*layerIt)->GetLayerDefn();
    if (cmpStr(fDef->GetName(), pszName) == 0) {
      newLayer = false;
      curLayer = *layerIt;
      break;
    }
  }

  // add a layer
  if (newLayer) { // FIXME in Layer: SRS Writer Type datasource
    CPLDebug( "OGR_ILI", "Adding layer: %s", pszName );
    // new layer data
    OGRSpatialReference *poSRSIn = NULL; // FIXME fix values for initial layer
    int bWriterIn = 0;
    OGRwkbGeometryType eReqType = wkbUnknown;
    OGRILI2DataSource *poDSIn = NULL;
    curLayer = new OGRILI2Layer(pszName, poSRSIn, bWriterIn, eReqType, poDSIn);
    m_listLayer.push_back(curLayer);
  }

  // the feature and field definition
  OGRFeatureDefn *featureDef = curLayer->GetLayerDefn();
  if (newLayer) {
    // add TID field
    OGRFieldDefn ofieldDefn (ILI2_TID, OFTString);
    featureDef->AddFieldDefn(&ofieldDefn);

    setFieldDefn(featureDef, elem);
  }

  // add the features
  OGRFeature *feature = new OGRFeature(featureDef);

  // assign TID
  int fIndex = feature->GetFieldIndex(ILI2_TID);
  if (fIndex != -1) {
      XMLCh *pszIli2_tid = XMLString::transcode(ILI2_TID);
      char *fChVal = XMLString::transcode(elem->getAttribute(pszIli2_tid));
      feature->SetField(fIndex, fChVal);
      XMLString::release (&pszIli2_tid);
      XMLString::release (&fChVal);
  } else {
      CPLDebug( "OGR_ILI","'%s' not found", ILI2_TID);
  }

  SetFieldValues(feature, elem);
  curLayer->SetFeature(feature);
  
  XMLString::release (&pszName);

  return 0;
}
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 #7
0
OGRFeature* OGRPLScenesLayer::GetNextRawFeature()
{
    if( bEOF ||
        (!bFilterMustBeClientSideEvaluated && nFeatureCount >= 0 && nNextFID > nFeatureCount) )
        return NULL;

    if( poGeoJSONLayer == NULL )
    {
        if( !GetNextPage() )
            return NULL;
    }

#ifdef notdef
    if( CSLTestBoolean(CPLGetConfigOption("OGR_LIMIT_TOO_MANY_FEATURES", "FALSE")) &&
        nFeatureCount > nPageSize )
    {
        bEOF = TRUE;
        OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
        OGRGeometry* poGeom;
        const char* pszWKT = "MULTIPOLYGON(((-180 90,180 90,180 -90,-180 -90,-180 90)))";
        OGRGeometryFactory::createFromWkt((char**)&pszWKT, poSRS, &poGeom);
        poFeature->SetGeometryDirectly(poGeom);
        return poFeature;
    }
#endif

    OGRFeature* poGeoJSONFeature = poGeoJSONLayer->GetNextFeature();
    if( poGeoJSONFeature == NULL )
    {
        osRequestURL = osNextURL;
        bStillInFirstPage = FALSE;
        if( !GetNextPage() )
            return NULL;
        poGeoJSONFeature = poGeoJSONLayer->GetNextFeature();
        if( poGeoJSONFeature == NULL )
        {
            bEOF = TRUE;
            return NULL;
        }
    }
    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    poFeature->SetFID(nNextFID++);

    OGRGeometry* poGeom = poGeoJSONFeature->StealGeometry();
    if( poGeom != NULL )
    {
        if( poGeom->getGeometryType() == wkbPolygon )
        {
            OGRMultiPolygon* poMP = new OGRMultiPolygon();
            poMP->addGeometryDirectly(poGeom);
            poGeom = poMP;
        }
        poGeom->assignSpatialReference(poSRS);
        poFeature->SetGeometryDirectly(poGeom);
    }
    
    for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
    {
        OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
        OGRFieldType eType = poFieldDefn->GetType();
        int iSrcField = poGeoJSONFeature->GetFieldIndex(poFieldDefn->GetNameRef());
        if( iSrcField >= 0 && poGeoJSONFeature->IsFieldSet(iSrcField) )
        {
            if( eType == OFTInteger )
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsInteger(iSrcField));
            else if( eType == OFTReal )
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsDouble(iSrcField));
            else
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsString(iSrcField));
        }
    }

    delete poGeoJSONFeature;

    return poFeature;
}
Example #8
0
void
NIImporter_ArcView::load() {
#ifdef HAVE_GDAL
    PROGRESS_BEGIN_MESSAGE("Loading data from '" + mySHPName + "'");
#if GDAL_VERSION_MAJOR < 2
    OGRRegisterAll();
    OGRDataSource* poDS = OGRSFDriverRegistrar::Open(mySHPName.c_str(), FALSE);
#else
    GDALAllRegister();
    GDALDataset* poDS = (GDALDataset*)GDALOpenEx(mySHPName.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL);
#endif
    if (poDS == NULL) {
        WRITE_ERROR("Could not open shape description '" + mySHPName + "'.");
        return;
    }

    // begin file parsing
    OGRLayer*  poLayer = poDS->GetLayer(0);
    poLayer->ResetReading();

    // build coordinate transformation
    OGRSpatialReference* origTransf = poLayer->GetSpatialRef();
    OGRSpatialReference destTransf;
    // use wgs84 as destination
    destTransf.SetWellKnownGeogCS("WGS84");
    OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf);
    if (poCT == NULL) {
        if (myOptions.isSet("shapefile.guess-projection")) {
            OGRSpatialReference origTransf2;
            origTransf2.SetWellKnownGeogCS("WGS84");
            poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf);
        }
        if (poCT == 0) {
            WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed.");
        }
    }

    OGRFeature* poFeature;
    poLayer->ResetReading();
    while ((poFeature = poLayer->GetNextFeature()) != NULL) {
        // read in edge attributes
        std::string id, name, from_node, to_node;
        if (!getStringEntry(poFeature, "shapefile.street-id", "LINK_ID", true, id)) {
            WRITE_ERROR("Needed field '" + id + "' (from node id) is missing.");
        }
        if (id == "") {
            WRITE_ERROR("Could not obtain edge id.");
            return;
        }

        getStringEntry(poFeature, "shapefile.street-id", "ST_NAME", true, name);
        name = StringUtils::replace(name, "&", "&amp;");

        if (!getStringEntry(poFeature, "shapefile.from-id", "REF_IN_ID", true, from_node)) {
            WRITE_ERROR("Needed field '" + from_node + "' (from node id) is missing.");
        }
        if (!getStringEntry(poFeature, "shapefile.to-id", "NREF_IN_ID", true, to_node)) {
            WRITE_ERROR("Needed field '" + to_node + "' (to node id) is missing.");
        }

        if (from_node == "" || to_node == "") {
            from_node = toString(myRunningNodeID++);
            to_node = toString(myRunningNodeID++);
        }

        std::string type;
        if (myOptions.isSet("shapefile.type-id") && poFeature->GetFieldIndex(myOptions.getString("shapefile.type-id").c_str()) >= 0) {
            type = poFeature->GetFieldAsString(myOptions.getString("shapefile.type-id").c_str());
        } else if (poFeature->GetFieldIndex("ST_TYP_AFT") >= 0) {
            type = poFeature->GetFieldAsString("ST_TYP_AFT");
        }
        SUMOReal width = myTypeCont.getWidth(type);
        SUMOReal speed = getSpeed(*poFeature, id);
        int nolanes = getLaneNo(*poFeature, id, speed);
        int priority = getPriority(*poFeature, id);
        if (nolanes == 0 || speed == 0) {
            if (myOptions.getBool("shapefile.use-defaults-on-failure")) {
                nolanes = myTypeCont.getNumLanes("");
                speed = myTypeCont.getSpeed("");
            } else {
                OGRFeature::DestroyFeature(poFeature);
                WRITE_ERROR("The description seems to be invalid. Please recheck usage of types.");
                return;
            }
        }
        if (mySpeedInKMH) {
            speed = speed / (SUMOReal) 3.6;
        }


        // read in the geometry
        OGRGeometry* poGeometry = poFeature->GetGeometryRef();
        OGRwkbGeometryType gtype = poGeometry->getGeometryType();
        assert(gtype == wkbLineString);
        UNUSED_PARAMETER(gtype); // ony used for assertion
        OGRLineString* cgeom = (OGRLineString*) poGeometry;
        if (poCT != 0) {
            // try transform to wgs84
            cgeom->transform(poCT);
        }

        PositionVector shape;
        for (int j = 0; j < cgeom->getNumPoints(); j++) {
            Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j));
            if (!NBNetBuilder::transformCoordinate(pos)) {
                WRITE_WARNING("Unable to project coordinates for edge '" + id + "'.");
            }
            shape.push_back_noDoublePos(pos);
        }

        // build from-node
        NBNode* from = myNodeCont.retrieve(from_node);
        if (from == 0) {
            Position from_pos = shape[0];
            from = myNodeCont.retrieve(from_pos);
            if (from == 0) {
                from = new NBNode(from_node, from_pos);
                if (!myNodeCont.insert(from)) {
                    WRITE_ERROR("Node '" + from_node + "' could not be added");
                    delete from;
                    continue;
                }
            }
        }
        // build to-node
        NBNode* to = myNodeCont.retrieve(to_node);
        if (to == 0) {
            Position to_pos = shape[-1];
            to = myNodeCont.retrieve(to_pos);
            if (to == 0) {
                to = new NBNode(to_node, to_pos);
                if (!myNodeCont.insert(to)) {
                    WRITE_ERROR("Node '" + to_node + "' could not be added");
                    delete to;
                    continue;
                }
            }
        }

        if (from == to) {
            WRITE_WARNING("Edge '" + id + "' connects identical nodes, skipping.");
            continue;
        }

        // retrieve the information whether the street is bi-directional
        std::string dir;
        int index = poFeature->GetDefnRef()->GetFieldIndex("DIR_TRAVEL");
        if (index >= 0 && poFeature->IsFieldSet(index)) {
            dir = poFeature->GetFieldAsString(index);
        }
        // add positive direction if wanted
        if (dir == "B" || dir == "F" || dir == "" || myOptions.getBool("shapefile.all-bidirectional")) {
            if (myEdgeCont.retrieve(id) == 0) {
                LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LANESPREAD_RIGHT : LANESPREAD_CENTER;
                NBEdge* edge = new NBEdge(id, from, to, type, speed, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape, name, id, spread);
                myEdgeCont.insert(edge);
                checkSpread(edge);
            }
        }
        // add negative direction if wanted
        if (dir == "B" || dir == "T" || myOptions.getBool("shapefile.all-bidirectional")) {
            if (myEdgeCont.retrieve("-" + id) == 0) {
                LaneSpreadFunction spread = dir == "B" || dir == "FALSE" ? LANESPREAD_RIGHT : LANESPREAD_CENTER;
                NBEdge* edge = new NBEdge("-" + id, to, from, type, speed, nolanes, priority, width, NBEdge::UNSPECIFIED_OFFSET, shape.reverse(), name, id, spread);
                myEdgeCont.insert(edge);
                checkSpread(edge);
            }
        }
        //
        OGRFeature::DestroyFeature(poFeature);
    }
#if GDAL_VERSION_MAJOR < 2
    OGRDataSource::DestroyDataSource(poDS);
#else
    GDALClose(poDS);
#endif
    PROGRESS_DONE_MESSAGE();
#else
    WRITE_ERROR("SUMO was compiled without GDAL support.");
#endif
}
Example #9
0
void writePolygons(RegionMap* regionMap)
{
    char* driverName = (char *)ogrDriver->c_str();
    char* outFilePath =  (char *)outFile->c_str();

    cout << "Creating output file \"" << outFilePath << "\" (\"" << driverName << "\" format)...";
    OGRSFDriver* driver = (OGRSFDriver*)OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(ogrDriver->c_str());
    if (driver == NULL) {
        localExit(new string(string("FATAL: OGR driver \"") + string(driverName) +  string("\" is not available.\n")), 1);
    }
    
    char* dataSourceName = NULL;
    bool cleanupDataSource = false;
    if (ogrDriver->compare("KML") == 0 && kmlStyleFile != NULL) {
        dataSourceName = tmpnam(NULL);
        //mkstemp(dataSourceName);
        cleanupDataSource = true;
    }
    else if (ogrDriver->compare("ESRI Shapefile") == 0) {
        string* dsStr = removeFromLastOccurrence(outFilePath, '/');
        dsStr = removeFromLastOccurrence((char *)dsStr->c_str(), '\\');
        dataSourceName = (char *)dsStr->c_str();
    } else {
        dataSourceName = outFilePath;
    }
    
    OGRDataSource* ds = driver->CreateDataSource(dataSourceName);
    if(ds == NULL) {
        localExit(new string(string("FATAL: Unable to create output file \"") + string(outFilePath) + string("\"\n")), 1);
    }
    
    cout << "[ok]\n";

    OGRCoordinateTransformation* transform = NULL;
    const string* rmSpatialRefStr = regionMap->getSpatialRef();
    if (rmSpatialRefStr != NULL && rmSpatialRefStr->compare("") != 0) {
        OGRSpatialReference* spatialRef = new OGRSpatialReference(rmSpatialRefStr->c_str());
        transform = OGRCreateCoordinateTransformation(spatialRef, outSpatialRef);
    }

    char* layerName = (char *)pointToFilename(outFilePath, true)->c_str();
    OGRLayer* layer = ds->CreateLayer(layerName, outSpatialRef, wkbPolygon);
    layer->CreateField(new OGRFieldDefn("RegionID", OFTInteger), 0);
    layer->CreateField(new OGRFieldDefn("Category", OFTString), 0);
    layer->CreateField(new OGRFieldDefn("Threshold", OFTReal), 0);

    cout << "Writing polygon data to file...";
    int count = 0;
    int currRegionID = 0;
    int numRegions =  regionMap->getNumRegions();
    while (currRegionID < numRegions) {

        Region *currRegion = regionMap->getRegion(currRegionID);
        Polygon* poly = currRegion->toPolygon();
        if(poly == NULL) {
            currRegionID += 1;
            continue;
        }
        count++;

        OGRFeature* feature = new OGRFeature(layer->GetLayerDefn());
        feature->SetField(feature->GetFieldIndex("RegionID"), currRegionID);
        feature->SetField(feature->GetFieldIndex("Category"), currRegion->getCategory()->getName()->c_str());
        feature->SetField(feature->GetFieldIndex("Threshold"), currRegion->getCategory()->minThreshold());

        OGRGeometry* geom = BuildOgrPolygon(poly, transform);
        feature->SetGeometry(geom);

        if (layer->CreateFeature(feature) != OGRERR_NONE)
            localExit(new string("ERROR: Unable to create feature for region #\n"), 2);

        //OGRFeature::DestroyFeature(feature);
        currRegionID += 1;

        if (currRegionID % 100 == 0)
            cout << ".";
    }
    //CPLFree(transform);
    //CPLFree(layer);
    OGRDataSource::DestroyDataSource(ds);
    cout << "[ok] Wrote "<< count << " polygons\n";

    if(kmlStyleFile != NULL) {
#ifdef USE_XALAN
        XALAN_USING_XERCES(XMLPlatformUtils)
        XALAN_USING_XALAN(XalanTransformer)
        XMLPlatformUtils::Initialize();
        XalanTransformer::initialize();
        XalanTransformer theXalanTransformer;
        cout << "Transforing KML file ..." << outFile->c_str();
        if(theXalanTransformer.transform(dataSourceName, kmlStyleFile->c_str(), outFile->c_str()) != 0) {
            cout << "[!!]\n";
            cout << "ERROR doing XSLT transform using " << kmlStyleFile->c_str() << "\n";
        } else {
            cout << "...[ok]\n";
        }
#endif /* USE_XALAN */
#ifdef USE_LIBXSLT
        xsltStylesheetPtr cur = NULL;
        xmlDocPtr doc, res;
        const char *params[16 + 1];
        params[0] = NULL;
        xmlSubstituteEntitiesDefault(1);
        xmlLoadExtDtdDefaultValue = 1;
        cur = xsltParseStylesheetFile((const xmlChar *) kmlStyleFile->c_str());
        doc = xmlParseFile(dataSourceName);
        res = xsltApplyStylesheet(cur, doc, params);
        FILE* f = fopen(outFile->c_str(), "w");
        xsltSaveResultToFile(f, res, cur);
        fclose(f);

        xsltFreeStylesheet(cur);
        xmlFreeDoc(res);
        xmlFreeDoc(doc);

        xsltCleanupGlobals();
        xmlCleanupParser();
#endif /* USE_LIBXSLT */
    }
    if(cleanupDataSource) {
        if(!remove(dataSourceName)) {
            fprintf(stderr, "Error deleting temporary file: %s\n", dataSourceName);
        }
    }
}
bool DataProcessingWorker::loadDataFromSources(int Step)
{
  emit stepEntered(tr("Loading and checking data from sources..."));


  GDALAllRegister_COMPAT();

  for (int i=0; i<m_SourcesInfos.size();i++)
  {

    QString RealURI = m_SourcesInfos[i].SourceURI;
    if (!m_SourcesInfos[i].CachedSourceURI.isEmpty())
      RealURI = m_SourcesInfos[i].CachedSourceURI;


    GDALDataset_COMPAT* DS = GDALOpenRO_COMPAT(RealURI.toStdString().c_str());

    if (DS == nullptr)
    {
      emit stepCompleted(Step,getStyledText(tr("[Error] Unable to open datasource for layer \"%1\"")
                                            .arg(m_SourcesInfos[i].LayerName),"red"));
      return false;
    }

    OGRLayer *Layer;
    OGRFeature *Feature;

    Layer = DS->GetLayerByName(m_SourcesInfos[i].LayerName.toStdString().c_str());

    // For cached layers as GeoJSON files
    // TODO do better for that!
    if (Layer == nullptr)
    {
      Layer = DS->GetLayer(0);
    }

    Layer->ResetReading();
    while((Feature = Layer->GetNextFeature()) != nullptr )
    {
      SourceUnit CurrentUnit;
      int CurrentUnitID;

      int FieldIndex = 0;
      QString FieldValue;

      // === Unit ID ===

      FieldIndex = Feature->GetFieldIndex(OGRGDAL_UNITID_FIELD);

      if (FieldIndex < 0)
      {
        GDALClose_COMPAT(DS);
        emit stepCompleted(Step,getStyledText(tr("[Error] Field for unit ID not found in layer \"%1\"")
                                              .arg(m_SourcesInfos[i].LayerName),"red"));
        return false;
      }

      CurrentUnitID = Feature->GetFieldAsInteger(FieldIndex);

      if (CurrentUnitID <= 0)
      {
        GDALClose_COMPAT(DS);
        emit stepCompleted(Step,getStyledText(tr("[Error] Wrong field format for unit ID in layer \"%1\"")
                                              .arg(m_SourcesInfos[i].LayerName),"red"));
        return false;
      }

      if (m_SourcesData[i].isUnitExists(CurrentUnitID))
      {
        GDALClose_COMPAT(DS);
        emit stepCompleted(Step,getStyledText(tr("[Error] Unit ID %2 already exist in layer \"%1\"")
                                                 .arg(m_SourcesInfos[i].LayerName)
                                                 .arg(CurrentUnitID),
                                              "red"));
        return false;
      }


      // === Process order ===

      if (m_SourcesInfos[i].UnitsPcsOrdField.isEmpty())
      {
        CurrentUnit.ProcessOrder = 1;
      }
      else
      {
        FieldIndex = Feature->GetFieldIndex(m_SourcesInfos[i].UnitsPcsOrdField.toStdString().c_str());

        if (FieldIndex < 0)
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Field for process order not found in layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName),
                                                "red"));
          return false;
        }

        int PcsOrd = Feature->GetFieldAsInteger(FieldIndex);

        if (PcsOrd <= 0)
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Wrong field format for process order in layer \"%1\"")
                                                 .arg(m_SourcesInfos[i].LayerName),
                                                "red"));
          return false;
        }

        CurrentUnit.ProcessOrder = PcsOrd;
      }


      // === To connections ===

      if (!m_SourcesInfos[i].ToConnectionsField.isEmpty())
      {
        FieldIndex = Feature->GetFieldIndex(m_SourcesInfos[i].ToConnectionsField.toStdString().c_str());

        if (FieldIndex < 0)
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Field for \"To\" connections not found in layer \"%1\"")
                                                .arg(m_SourcesInfos[i].LayerName),"red"));
          return false;
        }

        CurrentUnit.ToConnStr = QString(Feature->GetFieldAsString(FieldIndex));

        if (!OGRGDALHelpers::convertConnectionsStringToList(CurrentUnit.ToConnStr,CurrentUnit.ToConn))
        {
          emit stepCompleted(Step,getStyledText(tr("[Error] Wrong field \"%2\" format for \"To\" connections "
                                                   "in layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].ToConnectionsField),
                                                "red"));
          return false;
        }
      }


      // === Childof connections ===

      if (!m_SourcesInfos[i].ChildofConnectionsField.isEmpty())
      {
        FieldIndex = Feature->GetFieldIndex(m_SourcesInfos[i].ChildofConnectionsField.toStdString().c_str());

        if (FieldIndex < 0)
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,
                             getStyledText(tr("[Error] Field for \"Child Of\" connections not found in layer \"%1\"")
                                           .arg(m_SourcesInfos[i].LayerName),"red"));
          return false;
        }

        CurrentUnit.ChildofConnStr = QString(Feature->GetFieldAsString(FieldIndex));

        if (!OGRGDALHelpers::convertConnectionsStringToList(CurrentUnit.ChildofConnStr,CurrentUnit.ChildofConn))
        {
          emit stepCompleted(Step,getStyledText(tr("[Error] Wrong field \"%2\" format for \"Child Of\" connections "
                                                   "in layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].ChildofConnectionsField),
                                                "red"));
          return false;
        }
      }


      // === Attributes ===

      for (int j=0;j<m_SourcesInfos[i].ImportedFields.size(); j++)
      {
        FieldIndex = Feature->GetFieldIndex(m_SourcesInfos[i].ImportedFields[j].toStdString().c_str());

        if (FieldIndex <0)
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Field for attribute \"%2\" not found in layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].ImportedFields[j]),
                                                "red"));
          return false;
        }

        // replacing unwanted chars (space, tab) by underscore
        QString Attr;

        if (!OGRGDALHelpers::convertFieldToAttribute(Feature,FieldIndex,Attr))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Wrong field format for attribute \"%2\" in layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].ImportedFields[j]),
                                                "red"));
          return false;
        }

        CurrentUnit.Attributes[m_SourcesInfos[i].ImportedFields[j]] = Attr.replace(" ","_")
                                                                          .replace("\t","_");
      }


      // === Area computed attribute ===

      if (m_SourcesInfos[i].IsAreaCompute)
      {
        if (m_SourcesInfos[i].ImportedFields.contains(m_SourcesInfos[i].AreaComputeAttribute))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Attribute \"%2\" for computed area attribute "
                                                   "is already imported from layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].AreaComputeAttribute),
                                                "red"));
          return false;
        }
        else
        {
          double Area = ((OGRPolygon*)(Feature->GetGeometryRef()))->get_Area();
          CurrentUnit.Attributes[m_SourcesInfos[i].AreaComputeAttribute] = QString::number(Area,'g');
        }
      }


      // === Length computed attribute ===

      if (m_SourcesInfos[i].IsLengthCompute)
      {
        if (m_SourcesInfos[i].ImportedFields.contains(m_SourcesInfos[i].LengthComputeAttribute))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Attribute \"%2\" for computed length attribute "
                                                   "is already imported from layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].LengthComputeAttribute),
                                                "red"));
          return false;
        }
        else
        {
          double Length = ((OGRLineString*)(Feature->GetGeometryRef()))->get_Length();
          CurrentUnit.Attributes[m_SourcesInfos[i].LengthComputeAttribute] = QString::number(Length,'g');
        }
      }


      // === Preprocess for computed centroid

      OGRPoint Centroid;

      if (Feature->GetGeometryRef()->Centroid(&Centroid) != OGRERR_NONE)
      {
        GDALClose_COMPAT(DS);
        emit stepCompleted(Step,
                           getStyledText(tr("[Error] Unable to compute centroid coordinates "
                                            "for geometries in layer \"%1\"."
                                            "Computing centroid coordinates should be unchecked "
                                            "in computed attributes.")
                                         .arg(m_SourcesInfos[i].LayerName),"red"));
        return false;
      }


      // === XCentroid computed attribute ===

      if (m_SourcesInfos[i].IsXCentroidCompute)
      {
        if (m_SourcesInfos[i].ImportedFields.contains(m_SourcesInfos[i].XCentroidComputeAttribute))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Attribute \"%2\" for computed centroid X attribute "
                                                   "is already imported from layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].XCentroidComputeAttribute),
                                                "red"));
          return false;
        }
        else
        {
          CurrentUnit.Attributes[m_SourcesInfos[i].XCentroidComputeAttribute] = QString::number(Centroid.getX(),'g');
        }
      }


      // === YCentroid computed attribute ===

      if (m_SourcesInfos[i].IsYCentroidCompute)
      {
        if (m_SourcesInfos[i].ImportedFields.contains(m_SourcesInfos[i].YCentroidComputeAttribute))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Attribute \"%2\" for computed centroid Y attribute "
                                                   "is already imported from layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].YCentroidComputeAttribute),
                                                "red"));
          return false;
        }
        else
        {
          CurrentUnit.Attributes[m_SourcesInfos[i].YCentroidComputeAttribute] = QString::number(Centroid.getY(),'g');
        }
      }


      // === ZCentroid computed attribute ===

      if (m_SourcesInfos[i].IsZCentroidCompute)
      {
        if (m_SourcesInfos[i].ImportedFields.contains(m_SourcesInfos[i].ZCentroidComputeAttribute))
        {
          GDALClose_COMPAT(DS);
          emit stepCompleted(Step,getStyledText(tr("[Error] Attribute \"%2\" for computed centroid Z attribute "
                                                   "is already imported from layer \"%1\"")
                                                   .arg(m_SourcesInfos[i].LayerName)
                                                   .arg(m_SourcesInfos[i].ZCentroidComputeAttribute),
                                                "red"));
          return false;
        }
        else
        {
          CurrentUnit.Attributes[m_SourcesInfos[i].ZCentroidComputeAttribute] = QString::number(Centroid.getZ(),'g');
        }
      }


      m_SourcesData[i].Units[CurrentUnitID] = CurrentUnit;
    }

    GDALClose_COMPAT(DS);
    DS = nullptr;
  }

  emit stepCompleted(Step,getStyledText(tr("[OK]"),"green"));
  return true;
}