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; }
//! 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; }
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; }
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; }
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; }
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 }
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; }
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; }
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; }
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(); } }
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; }
/** 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 ); }