void QgsSpatiaLiteFeatureIterator::getFeatureGeometry( sqlite3_stmt* stmt, int ic, QgsFeature& feature )
{
  if ( sqlite3_column_type( stmt, ic ) == SQLITE_BLOB )
  {
    unsigned char *featureGeom = NULL;
    size_t geom_size = 0;
    const void *blob = sqlite3_column_blob( stmt, ic );
    size_t blob_size = sqlite3_column_bytes( stmt, ic );
    QgsSpatiaLiteProvider::convertToGeosWKB(( const unsigned char * )blob, blob_size,
                                            &featureGeom, &geom_size );
    if ( featureGeom )
    {
      QgsGeometry *g = new QgsGeometry();
      g->fromWkb( featureGeom, geom_size );
      feature.setGeometry( g );
    }
    else
      feature.setGeometry( 0 );
  }
  else
  {
    // NULL geometry
    feature.setGeometry( 0 );
  }
}
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
{
  feature.setFeatureId( OGR_F_GetFID( fet ) );
  feature.initAttributes( mSource->mFields.count() );
  feature.setFields( &mSource->mFields ); // allow name-based attribute lookups

  bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect;
  bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown;
  if ( mFetchGeometry || useIntersect || geometryTypeFilter )
  {
    OGRGeometryH geom = OGR_F_GetGeometryRef( fet );

    if ( geom )
    {
      if ( mGeometrySimplifier )
        mGeometrySimplifier->simplifyGeometry( geom );

      // get the wkb representation
      int memorySize = OGR_G_WkbSize( geom );
      unsigned char *wkb = new unsigned char[memorySize];
      OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );

      QgsGeometry* geometry = feature.geometry();
      if ( !geometry ) feature.setGeometryAndOwnership( wkb, memorySize ); else geometry->fromWkb( wkb, memorySize );
    }
    if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) )
        || ( geometryTypeFilter && ( !feature.geometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
    {
      OGR_F_Destroy( fet );
      return false;
    }
  }

  if ( !mFetchGeometry )
  {
    feature.setGeometry( 0 );
  }

  // fetch attributes
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    const QgsAttributeList& attrs = mRequest.subsetOfAttributes();
    for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it )
    {
      getFeatureAttribute( fet, feature, *it );
    }
  }
  else
  {
    // all attributes
    for ( int idx = 0; idx < mSource->mFields.count(); ++idx )
    {
      getFeatureAttribute( fet, feature, idx );
    }
  }

  return true;
}
 // TODO: make this a QgsGeometry member...
 QgsGeometry geomFromHexWKB( const char *hexwkb )
 {
   int wkbsize;
   unsigned char *wkb = hex2bytes( hexwkb, &wkbsize );
   QgsGeometry geom;
   // NOTE: QgsGeometry takes ownership of wkb
   geom.fromWkb( wkb, wkbsize );
   return geom;
 }
Beispiel #4
0
//! Returns a simplified version the specified geometry (Removing duplicated points) when is applied the specified map2pixel context
QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
{
    QgsGeometry* g = new QgsGeometry();

    size_t wkbSize = geometry->wkbSize();
    unsigned char* wkb = ( unsigned char* )malloc( wkbSize );
    memcpy( wkb, geometry->asWkb(), wkbSize );
    g->fromWkb( wkb, wkbSize );
    simplifyGeometry( g, mSimplifyFlags, mTolerance );

    return g;
}
QgsGeometry* QgsGPXFeatureIterator::readWaypointGeometry( const QgsWaypoint& wpt )
{
  char* geo = new char[21];
  std::memset( geo, 0, 21 );
  geo[0] = QgsApplication::endian();
  geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBPoint;
  std::memcpy( geo + 5, &wpt.lon, sizeof( double ) );
  std::memcpy( geo + 13, &wpt.lat, sizeof( double ) );
  QgsGeometry *g = new QgsGeometry();
  g->fromWkb(( unsigned char * )geo, 21 );
  return g;
}
Beispiel #6
0
QgsGeometry *QgsGPXFeatureIterator::readWaypointGeometry( const QgsWaypoint &wpt )
{
  int size = 1 + sizeof( int ) + 2 * sizeof( double );
  unsigned char *geo = new unsigned char[size];

  QgsWkbPtr wkbPtr( geo, size );
  wkbPtr << ( char ) QgsApplication::endian() << QgsWkbTypes::Point << wpt.lon << wpt.lat;

  QgsGeometry *g = new QgsGeometry();
  g->fromWkb( geo, size );
  return g;
}
Beispiel #7
0
QgsGeometry spatialiteBlobToQgsGeometry( const char *blob, size_t size )
{
  const int header_size = SpatialiteBlobHeader::LENGTH;
  const int wkb_size = static_cast< const int >( size - header_size );
  char *wkb = new char[wkb_size];

  uint32_t osize = 0;
  copySpatialiteCollectionWkbToQgsGeometry( blob + header_size - 1, wkb, osize, /*endianness*/blob[1] );

  QgsGeometry geom;
  geom.fromWkb( reinterpret_cast< unsigned char * >( wkb ), wkb_size );
  return geom;
}
Beispiel #8
0
QgsGeometry QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom )
{
  if ( !geom )
    return QgsGeometry();

  // get the wkb representation
  int memorySize = OGR_G_WkbSize( geom );
  unsigned char *wkb = new unsigned char[memorySize];
  OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );

  QgsGeometry g;
  g.fromWkb( wkb, memorySize );
  return g;
}
QgsGeometry* QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack& trk )
{
  // TODO: support multi line string for segments

  if ( trk.segments.size() == 0 )
    return 0;

  // A track consists of several segments. Add all those segments into one.
  int totalPoints = 0;;
  for ( int i = 0; i < trk.segments.size(); i ++ )
  {
    totalPoints += trk.segments[i].points.size();
  }
  if ( totalPoints == 0 )
    return 0;
  //QgsDebugMsg( "GPX feature track total points: " + QString::number( totalPoints ) );

  // some wkb voodoo
  char* geo = new char[9 + 16 * totalPoints];
  if ( !geo )
  {
    QgsDebugMsg( "Too large track!!!" );
    return 0;
  }
  std::memset( geo, 0, 9 + 16 * totalPoints );
  geo[0] = QgsApplication::endian();
  geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;
  std::memcpy( geo + 5, &totalPoints, 4 );

  int thisPoint = 0;
  for ( int k = 0; k < trk.segments.size(); k++ )
  {
    int nPoints = trk.segments[k].points.size();
    for ( int i = 0; i < nPoints; ++i )
    {
      std::memcpy( geo + 9 + 16 * thisPoint,     &trk.segments[k].points[i].lon, sizeof( double ) );
      std::memcpy( geo + 9 + 16 * thisPoint + 8, &trk.segments[k].points[i].lat, sizeof( double ) );
      thisPoint++;
    }
  }

  //create QgsGeometry and use it for intersection test
  //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
  QgsGeometry* theGeometry = new QgsGeometry();
  theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * totalPoints );
  return theGeometry;
}
Beispiel #10
0
QgsGeometry *QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack &trk )
{
  // TODO: support multi line string for segments
  if ( trk.segments.isEmpty() )
    return nullptr;

  // A track consists of several segments. Add all those segments into one.
  int totalPoints = 0;
  for ( int i = 0; i < trk.segments.size(); i ++ )
  {
    totalPoints += trk.segments[i].points.size();
  }

  if ( totalPoints == 0 )
    return nullptr;

  //QgsDebugMsg( "GPX feature track total points: " + QString::number( totalPoints ) );

  // some wkb voodoo
  int size = 1 + 2 * sizeof( int ) + 2 * sizeof( double ) * totalPoints;
  unsigned char *geo = new unsigned char[size];
  if ( !geo )
  {
    QgsDebugMsg( "Track too large!" );
    return nullptr;
  }

  QgsWkbPtr wkbPtr( geo, size );
  wkbPtr << ( char ) QgsApplication::endian() << QgsWkbTypes::LineString << totalPoints;

  for ( int k = 0; k < trk.segments.size(); k++ )
  {
    int nPoints = trk.segments[k].points.size();
    for ( int i = 0; i < nPoints; ++i )
    {
      wkbPtr << trk.segments[k].points[i].lon << trk.segments[k].points[i].lat;
    }
  }

  //create QgsGeometry and use it for intersection test
  //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
  QgsGeometry *g = new QgsGeometry();
  g->fromWkb( geo, size );
  return g;
}
void QgsWFSFeatureIterator::copyFeature( const QgsFeature* f, QgsFeature& feature, bool fetchGeometry )
{
  Q_UNUSED( fetchGeometry );

  if ( !f )
  {
    return;
  }

  //copy the geometry
  const QgsGeometry* geometry = f->constGeometry();
  if ( geometry && fetchGeometry )
  {
    const unsigned char *geom = geometry->asWkb();
    int geomSize = geometry->wkbSize();
    unsigned char* copiedGeom = new unsigned char[geomSize];
    memcpy( copiedGeom, geom, geomSize );

    QgsGeometry *g = new QgsGeometry();
    g->fromWkb( copiedGeom, geomSize );
    feature.setGeometry( g );
  }
  else
  {
    feature.setGeometry( nullptr );
  }

  //and the attributes
  feature.initAttributes( mSource->mFields.size() );
  for ( int i = 0; i < mSource->mFields.size(); i++ )
  {
    const QVariant &v = f->attributes().value( i );
    if ( v.type() != mSource->mFields.at( i ).type() )
      feature.setAttribute( i, QgsVectorDataProvider::convertValue( mSource->mFields.at( i ).type(), v.toString() ) );
    else
      feature.setAttribute( i, v );
  }

  //id and valid
  feature.setValid( true );
  feature.setFeatureId( f->id() );
  feature.setFields( mSource->mFields ); // allow name-based attribute lookups
}
Beispiel #12
0
QgsGeometry *QgsGPXFeatureIterator::readRouteGeometry( const QgsRoute &rte )
{
  // some wkb voodoo
  int size = 1 + 2 * sizeof( int ) + 2 * sizeof( double ) * rte.points.size();
  unsigned char *geo = new unsigned char[size];

  QgsWkbPtr wkbPtr( geo, size );
  wkbPtr << ( char ) QgsApplication::endian() << QgsWkbTypes::LineString << rte.points.size();

  for ( int i = 0; i < rte.points.size(); ++i )
  {
    wkbPtr << rte.points[i].lon << rte.points[i].lat;
  }

  //create QgsGeometry and use it for intersection test
  //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
  QgsGeometry *g = new QgsGeometry();
  g->fromWkb( geo, size );
  return g;
}
Beispiel #13
0
QgsGeometry* QgsGPXFeatureIterator::readRouteGeometry( const QgsRoute& rte )
{
  // some wkb voodoo
  int nPoints = rte.points.size();
  char* geo = new char[9 + 16 * nPoints];
  std::memset( geo, 0, 9 + 16 * nPoints );
  geo[0] = QgsApplication::endian();
  geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;
  std::memcpy( geo + 5, &nPoints, 4 );
  for ( int i = 0; i < rte.points.size(); ++i )
  {
    std::memcpy( geo + 9 + 16 * i, &rte.points[i].lon, sizeof( double ) );
    std::memcpy( geo + 9 + 16 * i + 8, &rte.points[i].lat, sizeof( double ) );
  }

  //create QgsGeometry and use it for intersection test
  //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
  QgsGeometry* theGeometry = new QgsGeometry();
  theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * nPoints );
  return theGeometry;
}
Beispiel #14
0
bool QgsGPXProvider::nextFeature( QgsFeature& feature )
{
  feature.setValid( false );
  bool result = false;

  QgsAttributeList::const_iterator iter;

  if ( mFeatureType == WaypointType )
  {
    // go through the list of waypoints and return the first one that is in
    // the bounds rectangle
    for ( ; mWptIter != data->waypointsEnd(); ++mWptIter )
    {
      const QgsWaypoint* wpt;
      wpt = &( *mWptIter );
      if ( boundsCheck( wpt->lon, wpt->lat ) )
      {
        feature.setFeatureId( wpt->id );
        result = true;

        // some wkb voodoo
        if ( mFetchGeom )
        {
          char* geo = new char[21];
          std::memset( geo, 0, 21 );
          geo[0] = QgsApplication::endian();
          geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBPoint;
          std::memcpy( geo + 5, &wpt->lon, sizeof( double ) );
          std::memcpy( geo + 13, &wpt->lat, sizeof( double ) );
          feature.setGeometryAndOwnership(( unsigned char * )geo, sizeof( wkbPoint ) );
        }
        feature.setValid( true );

        // add attributes if they are wanted
        for ( iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter )
        {
          switch ( *iter )
          {
            case NameAttr:
              feature.addAttribute( NameAttr, QVariant( wpt->name ) );
              break;
            case EleAttr:
              if ( wpt->ele != -std::numeric_limits<double>::max() )
                feature.addAttribute( EleAttr, QVariant( wpt->ele ) );
              break;
            case SymAttr:
              feature.addAttribute( SymAttr, QVariant( wpt->sym ) );
              break;
            case CmtAttr:
              feature.addAttribute( CmtAttr, QVariant( wpt->cmt ) );
              break;
            case DscAttr:
              feature.addAttribute( DscAttr, QVariant( wpt->desc ) );
              break;
            case SrcAttr:
              feature.addAttribute( SrcAttr, QVariant( wpt->src ) );
              break;
            case URLAttr:
              feature.addAttribute( URLAttr, QVariant( wpt->url ) );
              break;
            case URLNameAttr:
              feature.addAttribute( URLNameAttr, QVariant( wpt->urlname ) );
              break;
          }
        }

        ++mWptIter;
        break;
      }
    }
  }

  else if ( mFeatureType == RouteType )
  {
    // go through the routes and return the first one that is in the bounds
    // rectangle
    for ( ; mRteIter != data->routesEnd(); ++mRteIter )
    {
      const QgsRoute* rte;
      rte = &( *mRteIter );

      if ( rte->points.size() == 0 )
        continue;
      const QgsRectangle& b( *mSelectionRectangle );
      if (( rte->xMax >= b.xMinimum() ) && ( rte->xMin <= b.xMaximum() ) &&
          ( rte->yMax >= b.yMinimum() ) && ( rte->yMin <= b.yMaximum() ) )
      {
        // some wkb voodoo
        int nPoints = rte->points.size();
        char* geo = new char[9 + 16 * nPoints];
        std::memset( geo, 0, 9 + 16 * nPoints );
        geo[0] = QgsApplication::endian();
        geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;
        std::memcpy( geo + 5, &nPoints, 4 );
        for ( uint i = 0; i < rte->points.size(); ++i )
        {
          std::memcpy( geo + 9 + 16 * i, &rte->points[i].lon, sizeof( double ) );
          std::memcpy( geo + 9 + 16 * i + 8, &rte->points[i].lat, sizeof( double ) );
        }

        //create QgsGeometry and use it for intersection test
        //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
        QgsGeometry* theGeometry = new QgsGeometry();
        theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * nPoints );
        bool intersection = theGeometry->intersects( b );//use geos for precise intersection test

        if ( !intersection )
        {
          delete theGeometry;
        }
        else
        {
          if ( mFetchGeom )
          {
            feature.setGeometry( theGeometry );
          }
          else
          {
            delete theGeometry;
          }
          feature.setFeatureId( rte->id );
          result = true;
          feature.setValid( true );

          // add attributes if they are wanted
          for ( iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter )
          {
            switch ( *iter )
            {
              case NameAttr:
                feature.addAttribute( NameAttr, QVariant( rte->name ) );
                break;
              case NumAttr:
                if ( rte->number != std::numeric_limits<int>::max() )
                  feature.addAttribute( NumAttr, QVariant( rte->number ) );
                break;
              case CmtAttr:
                feature.addAttribute( CmtAttr, QVariant( rte->cmt ) );
                break;
              case DscAttr:
                feature.addAttribute( DscAttr, QVariant( rte->desc ) );
                break;
              case SrcAttr:
                feature.addAttribute( SrcAttr, QVariant( rte->src ) );
                break;
              case URLAttr:
                feature.addAttribute( URLAttr, QVariant( rte->url ) );
                break;
              case URLNameAttr:
                feature.addAttribute( URLNameAttr, QVariant( rte->urlname ) );
                break;
            }
          }

          ++mRteIter;
          break;

        }

        //++mRteIter;
        //xbreak;
      }
    }
  }

  else if ( mFeatureType == TrackType )
  {
    // go through the tracks and return the first one that is in the bounds
    // rectangle
    for ( ; mTrkIter != data->tracksEnd(); ++mTrkIter )
    {
      const QgsTrack* trk;
      trk = &( *mTrkIter );

      QgsDebugMsg( QString( "GPX feature track segments: %1" ).arg( trk->segments.size() ) );
      if ( trk->segments.size() == 0 )
        continue;

      // A track consists of several segments. Add all those segments into one.
      int totalPoints = 0;;
      for ( std::vector<QgsTrackSegment>::size_type i = 0; i < trk->segments.size(); i ++ )
      {
        totalPoints += trk->segments[i].points.size();
      }
      if ( totalPoints == 0 )
        continue;
      QgsDebugMsg( "GPX feature track total points: " + QString::number( totalPoints ) );
      const QgsRectangle& b( *mSelectionRectangle );
      if (( trk->xMax >= b.xMinimum() ) && ( trk->xMin <= b.xMaximum() ) &&
          ( trk->yMax >= b.yMinimum() ) && ( trk->yMin <= b.yMaximum() ) )
      {
        // some wkb voodoo
        char* geo = new char[9 + 16 * totalPoints];
        if ( !geo )
        {
          QgsDebugMsg( "Too large track!!!" );
          return false;
        }
        std::memset( geo, 0, 9 + 16 * totalPoints );
        geo[0] = QgsApplication::endian();
        geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;
        std::memcpy( geo + 5, &totalPoints, 4 );

        int thisPoint = 0;
        for ( std::vector<QgsTrackSegment>::size_type k = 0; k < trk->segments.size(); k++ )
        {
          int nPoints = trk->segments[k].points.size();
          for ( int i = 0; i < nPoints; ++i )
          {
            std::memcpy( geo + 9 + 16 * thisPoint,     &trk->segments[k].points[i].lon, sizeof( double ) );
            std::memcpy( geo + 9 + 16 * thisPoint + 8, &trk->segments[k].points[i].lat, sizeof( double ) );
            thisPoint++;
          }
        }

        //create QgsGeometry and use it for intersection test
        //if geometry is to be fetched, it is attached to the feature, otherwise we delete it
        QgsGeometry* theGeometry = new QgsGeometry();
        theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * totalPoints );
        bool intersection = theGeometry->intersects( b );//use geos for precise intersection test

        if ( !intersection ) //no intersection, delete geometry and move on
        {
          delete theGeometry;
        }
        else //intersection
        {
          if ( mFetchGeom )
          {
            feature.setGeometry( theGeometry );
          }
          else
          {
            delete theGeometry;
          }
          feature.setFeatureId( trk->id );
          result = true;

          feature.setValid( true );

          // add attributes if they are wanted
          for ( iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter )
          {
            switch ( *iter )
            {
              case NameAttr:
                feature.addAttribute( NameAttr, QVariant( trk->name ) );
                break;
              case NumAttr:
                if ( trk->number != std::numeric_limits<int>::max() )
                  feature.addAttribute( NumAttr, QVariant( trk->number ) );
                break;
              case CmtAttr:
                feature.addAttribute( CmtAttr, QVariant( trk->cmt ) );
                break;
              case DscAttr:
                feature.addAttribute( DscAttr, QVariant( trk->desc ) );
                break;
              case SrcAttr:
                feature.addAttribute( SrcAttr, QVariant( trk->src ) );
                break;
              case URLAttr:
                feature.addAttribute( URLAttr, QVariant( trk->url ) );
                break;
              case URLNameAttr:
                feature.addAttribute( URLNameAttr, QVariant( trk->urlname ) );
                break;
            }
          }

          ++mTrkIter;
          break;
        }
      }

    }
  }
  if ( result )
  {
    feature.setValid( true );
  }
  return result;
}
Beispiel #15
0
void QgsGml::endElement( const XML_Char* el )
{
    QString elementName( QString::fromUtf8( el ) );
    ParseMode theParseMode( mParseModeStack.isEmpty() ? none : mParseModeStack.top() );
    QStringList splitName =  elementName.split( NS_SEPARATOR );
    QString localName = splitName.last();
    QString ns = splitName.size() > 1 ? splitName.first() : "";

    if (( theParseMode == coordinate && elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates" )
            || ( theParseMode == posList && (
                     elementName == GML_NAMESPACE + NS_SEPARATOR + "pos"
                     || elementName == GML_NAMESPACE + NS_SEPARATOR + "posList" ) ) )
    {
        mParseModeStack.pop();
    }
    else if ( theParseMode == attribute && localName == mAttributeName ) //add a thematic attribute to the feature
    {
        mParseModeStack.pop();

        setAttribute( mAttributeName, mStringCash );
    }
    else if ( theParseMode == geometry && localName == mGeometryAttribute )
    {
        mParseModeStack.pop();
    }
    else if ( theParseMode == boundingBox && elementName == GML_NAMESPACE + NS_SEPARATOR + "boundedBy" )
    {
        //create bounding box from mStringCash
        if ( createBBoxFromCoordinateString( mCurrentExtent, mStringCash ) != 0 )
        {
            QgsDebugMsg( "creation of bounding box failed" );
        }

        mParseModeStack.pop();
    }
    else if ( theParseMode == feature && localName == mTypeName )
    {
        Q_ASSERT( mCurrentFeature );
        if ( mCurrentWKBSize > 0 )
        {
            QgsGeometry *g = new QgsGeometry();
            g->fromWkb( mCurrentWKB, mCurrentWKBSize );
            mCurrentFeature->setGeometry( g );
            mCurrentWKB = QgsWkbPtr( nullptr, 0 );
        }
        else if ( !mCurrentExtent.isEmpty() )
        {
            mCurrentFeature->setGeometry( QgsGeometry::fromRect( mCurrentExtent ) );
        }
        else
        {
            mCurrentFeature->setGeometry( nullptr );
        }
        mCurrentFeature->setValid( true );

        mFeatures.insert( mCurrentFeature->id(), mCurrentFeature );
        if ( !mCurrentFeatureId.isEmpty() )
        {
            mIdMap.insert( mCurrentFeature->id(), mCurrentFeatureId );
        }
        mCurrentFeature = nullptr;
        ++mFeatureCount;
        mParseModeStack.pop();
    }
    else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Point" )
    {
        QList<QgsPoint> pointList;
        if ( pointsFromString( pointList, mStringCash ) != 0 )
        {
            //error
        }

        if ( pointList.isEmpty() )
            return;  // error

        if ( theParseMode == QgsGml::geometry )
        {
            //directly add WKB point to the feature
            if ( getPointWKB( mCurrentWKB, *( pointList.constBegin() ) ) != 0 )
            {
                //error
            }

            if ( *mWkbType != QGis::WKBMultiPoint ) //keep multitype in case of geometry type mix
            {
                *mWkbType = QGis::WKBPoint;
            }
        }
        else //multipoint, add WKB as fragment
        {
            QgsWkbPtr wkbPtr( nullptr, 0 );
            if ( getPointWKB( wkbPtr, *( pointList.constBegin() ) ) != 0 )
            {
                //error
            }
            if ( !mCurrentWKBFragments.isEmpty() )
            {
                mCurrentWKBFragments.last().push_back( wkbPtr );
            }
            else
            {
                QgsDebugMsg( "No wkb fragments" );
                delete [] wkbPtr;
            }
        }
    }
    else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "LineString" )
    {
        //add WKB point to the feature

        QList<QgsPoint> pointList;
        if ( pointsFromString( pointList, mStringCash ) != 0 )
        {
            //error
        }
        if ( theParseMode == QgsGml::geometry )
        {
            if ( getLineWKB( mCurrentWKB, pointList ) != 0 )
            {
                //error
            }

            if ( *mWkbType != QGis::WKBMultiLineString )//keep multitype in case of geometry type mix
            {
                *mWkbType = QGis::WKBLineString;
            }
        }
        else //multiline, add WKB as fragment
        {
            QgsWkbPtr wkbPtr( nullptr, 0 );
            if ( getLineWKB( wkbPtr, pointList ) != 0 )
            {
                //error
            }
            if ( !mCurrentWKBFragments.isEmpty() )
            {
                mCurrentWKBFragments.last().push_back( wkbPtr );
            }
            else
            {
                QgsDebugMsg( "no wkb fragments" );
                delete [] wkbPtr;
            }
        }
    }
    else if (( theParseMode == geometry || theParseMode == multiPolygon ) && elementName == GML_NAMESPACE + NS_SEPARATOR + "LinearRing" )
    {
        QList<QgsPoint> pointList;
        if ( pointsFromString( pointList, mStringCash ) != 0 )
        {
            //error
        }

        QgsWkbPtr wkbPtr( nullptr, 0 );
        if ( getRingWKB( wkbPtr, pointList ) != 0 )
        {
            //error
        }

        if ( !mCurrentWKBFragments.isEmpty() )
        {
            mCurrentWKBFragments.last().push_back( wkbPtr );
        }
        else
        {
            delete[] wkbPtr;
            QgsDebugMsg( "no wkb fragments" );
        }
    }
    else if (( theParseMode == geometry || theParseMode == multiPolygon ) && elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon" )
    {
        if ( *mWkbType != QGis::WKBMultiPolygon )//keep multitype in case of geometry type mix
        {
            *mWkbType = QGis::WKBPolygon;
        }

        if ( theParseMode == geometry )
        {
            createPolygonFromFragments();
        }
    }
    else if ( theParseMode == multiPoint && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint" )
    {
        *mWkbType = QGis::WKBMultiPoint;
        mParseModeStack.pop();
        createMultiPointFromFragments();
    }
    else if ( theParseMode == multiLine && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString" )
    {
        *mWkbType = QGis::WKBMultiLineString;
        mParseModeStack.pop();
        createMultiLineFromFragments();
    }
    else if ( theParseMode == multiPolygon && elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon" )
    {
        *mWkbType = QGis::WKBMultiPolygon;
        mParseModeStack.pop();
        createMultiPolygonFromFragments();
    }
}
Beispiel #16
0
QgsGeometry QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom )
{
  if ( !geom )
    return QgsGeometry();

  // get the wkb representation
  int memorySize = OGR_G_WkbSize( geom );
  unsigned char *wkb = new unsigned char[memorySize];
  OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );

  // Read original geometry type
  uint32_t origGeomType;
  memcpy( &origGeomType, wkb + 1, sizeof( uint32_t ) );
  bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
  bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );

  // PolyhedralSurface and TINs are not supported, map them to multipolygons...
  if ( origGeomType % 1000 == 16 ) // is TIN, TINZ, TINM or TINZM
  {
    // TIN has the same wkb layout as a multipolygon, just need to overwrite the geom types...
    int nDims = 2 + hasZ + hasM;
    uint32_t newMultiType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::MultiPolygon, hasZ, hasM ) );
    uint32_t newSingleType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::Polygon, hasZ, hasM ) );
    unsigned char *wkbptr = wkb;

    // Endianness
    wkbptr += 1;

    // Overwrite geom type
    memcpy( wkbptr, &newMultiType, sizeof( uint32_t ) );
    wkbptr += 4;

    // Geom count
    uint32_t numGeoms;
    memcpy( &numGeoms, wkb + 5, sizeof( uint32_t ) );
    wkbptr += 4;

    // For each part, overwrite the geometry type to polygon (Z|M)
    for ( uint32_t i = 0; i < numGeoms; ++i )
    {
      // Endianness
      wkbptr += 1;

      // Overwrite geom type
      memcpy( wkbptr, &newSingleType, sizeof( uint32_t ) );
      wkbptr += sizeof( uint32_t );

      // skip coordinates
      uint32_t nRings;
      memcpy( &nRings, wkbptr, sizeof( uint32_t ) );
      wkbptr += sizeof( uint32_t );

      for ( uint32_t j = 0; j < nRings; ++j )
      {
        uint32_t nPoints;
        memcpy( &nPoints, wkbptr, sizeof( uint32_t ) );
        wkbptr += sizeof( uint32_t ) + sizeof( double ) * nDims * nPoints;
      }
    }
  }
  else if ( origGeomType % 1000 == 15 ) // PolyhedralSurface, PolyhedralSurfaceZ, PolyhedralSurfaceM or PolyhedralSurfaceZM
  {
    // PolyhedralSurface has the same wkb layout as a MultiPolygon, just need to overwrite the geom type...
    uint32_t newType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::MultiPolygon, hasZ, hasM ) );
    // Overwrite geom type
    memcpy( wkb + 1, &newType, sizeof( uint32_t ) );
  }

  QgsGeometry g;
  g.fromWkb( wkb, memorySize );
  return g;
}
Beispiel #17
0
/** Set the pointer to the feature geometry
*/
void QgsFeature::setGeometryAndOwnership( unsigned char *geom, size_t length )
{
  QgsGeometry *g = new QgsGeometry();
  g->fromWkb( geom, length );
  setGeometry( g );
}