mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
port more WKB parsing to Qgs(Const)WkbPtr including bounds checking
This commit is contained in:
parent
ded1ebb33b
commit
2ea3d7744d
@ -324,3 +324,4 @@
|
||||
%Include geometry/qgspolygonv2.sip
|
||||
%Include geometry/qgssurfacev2.sip
|
||||
%Include geometry/qgswkbtypes.sip
|
||||
%Include geometry/qgswkbptr.sip
|
||||
|
@ -127,7 +127,7 @@ class QgsAbstractGeometryV2
|
||||
/** Sets the geometry from a WKB string.
|
||||
* @see fromWkt
|
||||
*/
|
||||
virtual bool fromWkb( const unsigned char * wkb ) = 0;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) = 0;
|
||||
|
||||
/** Sets the geometry from a WKT string.
|
||||
* @see fromWkb
|
||||
@ -368,15 +368,4 @@ class QgsAbstractGeometryV2
|
||||
/** Updates the geometry type based on whether sub geometries contain z or m values.
|
||||
*/
|
||||
void setZMTypeFromSubGeometry( const QgsAbstractGeometryV2* subggeom, QgsWKBTypes::Type baseGeomType );
|
||||
|
||||
/** Reads a WKB header and tests its validity.
|
||||
* @param wkbPtr
|
||||
* @param wkbType destination for WKB type from header
|
||||
* @param endianSwap will be set to true if endian from WKB must be swapped to match QGIS platform endianness
|
||||
* @param expectedType expected WKB type
|
||||
* @returns true if header is valid and matches expected type
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
//static bool readWkbHeader( QgsConstWkbPtr& wkbPtr, QgsWKBTypes::Type& wkbType, bool& endianSwap, QgsWKBTypes::Type expectedType );
|
||||
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ class QgsCircularStringV2: public QgsCurveV2
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
virtual bool fromWkb( const unsigned char * wkb );
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
int wkbSize() const;
|
||||
|
@ -20,7 +20,7 @@ class QgsCompoundCurveV2: public QgsCurveV2
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb );
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
int wkbSize() const;
|
||||
|
@ -17,7 +17,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual bool fromWkb( const unsigned char* wkb );
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
int wkbSize() const;
|
||||
|
@ -57,7 +57,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
|
||||
virtual void draw( QPainter& p ) const;
|
||||
|
||||
bool fromWkb( const unsigned char * wkb );
|
||||
bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
int wkbSize() const;
|
||||
unsigned char* asWkb( int& binarySize ) const;
|
||||
|
@ -112,7 +112,8 @@ class QgsLineStringV2: public QgsCurveV2
|
||||
virtual int dimension() const;
|
||||
virtual QgsLineStringV2* clone() const /Factory/;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb );
|
||||
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
int wkbSize() const;
|
||||
|
@ -143,7 +143,7 @@ class QgsPointV2: public QgsAbstractGeometryV2
|
||||
virtual int dimension() const;
|
||||
virtual QgsPointV2* clone() const /Factory/;
|
||||
void clear();
|
||||
virtual bool fromWkb( const unsigned char* wkb );
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
int wkbSize() const;
|
||||
unsigned char* asWkb( int& binarySize ) const;
|
||||
|
@ -13,7 +13,7 @@ class QgsPolygonV2: public QgsCurvePolygonV2
|
||||
virtual QString geometryType() const;
|
||||
virtual QgsPolygonV2* clone() const;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb );
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
|
||||
// inherited: bool fromWkt( const QString &wkt );
|
||||
|
||||
|
21
python/core/geometry/qgswkbptr.sip
Normal file
21
python/core/geometry/qgswkbptr.sip
Normal file
@ -0,0 +1,21 @@
|
||||
class QgsWkbPtr
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgswkbptr.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
QgsWkbPtr( unsigned char *wkb /Array/, int size /ArraySize/ );
|
||||
|
||||
};
|
||||
|
||||
class QgsConstWkbPtr
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgswkbptr.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
QgsConstWkbPtr( unsigned char *wkb /Array/, int size /ArraySize/ );
|
||||
|
||||
};
|
@ -56,5 +56,5 @@ class QgsClipper
|
||||
@param wkb pointer to the start of the line wkb
|
||||
@param clipExtent clipping bounds
|
||||
@param line out: clipped line coordinates*/
|
||||
static const unsigned char* clippedLineWKB( const unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line );
|
||||
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr wkb, const QgsRectangle& clipExtent, QPolygonF& line );
|
||||
};
|
||||
|
@ -374,9 +374,9 @@ class QgsFeatureRendererV2
|
||||
//! render editing vertex marker for a polygon
|
||||
void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context );
|
||||
|
||||
static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb );
|
||||
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr wkb );
|
||||
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );
|
||||
|
||||
|
@ -226,13 +226,13 @@ class QgsSymbolV2
|
||||
* Creates a line string in screen coordinates from a wkb string in map
|
||||
* coordinates
|
||||
*/
|
||||
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
/**
|
||||
* Creates a polygon in screen coordinates from a wkb string in map
|
||||
* coordinates
|
||||
*/
|
||||
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
/**
|
||||
* Retrieve a cloned list of all layers that make up this symbol.
|
||||
|
@ -108,7 +108,8 @@ int QgsInterpolator::addVerticesToCache( const QgsGeometry *geom, bool zCoord, d
|
||||
return 1;
|
||||
|
||||
bool hasZValue = false;
|
||||
QgsConstWkbPtr currentWkbPtr( geom->asWkb() + 1 + sizeof( int ) );
|
||||
QgsConstWkbPtr currentWkbPtr( geom->asWkb(), geom->wkbSize() );
|
||||
currentWkbPtr.readHeader();
|
||||
vertexData theVertex; //the current vertex
|
||||
|
||||
QGis::WkbType wkbType = geom->wkbType();
|
||||
|
@ -199,7 +199,8 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
|
||||
//parse WKB. It is ugly, but we cannot use the methods with QgsPoint because they don't contain z-values for 25D types
|
||||
bool hasZValue = false;
|
||||
double x, y, z;
|
||||
QgsConstWkbPtr currentWkbPtr( g->asWkb() + 1 + sizeof( int ) );
|
||||
QgsConstWkbPtr currentWkbPtr( g->asWkb(), g->wkbSize() );
|
||||
currentWkbPtr.readHeader();
|
||||
//maybe a structure or break line
|
||||
Line3D* line = nullptr;
|
||||
|
||||
@ -236,7 +237,7 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
|
||||
currentWkbPtr >> nPoints;
|
||||
for ( int index = 0; index < nPoints; ++index )
|
||||
{
|
||||
currentWkbPtr += 1 + sizeof( int );
|
||||
currentWkbPtr.readHeader();
|
||||
currentWkbPtr >> x >> y;
|
||||
if ( hasZValue ) //skip z-coordinate for 25D geometries
|
||||
{
|
||||
@ -388,7 +389,7 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
|
||||
currentWkbPtr >> nPolys;
|
||||
for ( int index = 0; index < nPolys; ++index )
|
||||
{
|
||||
currentWkbPtr += 1 + sizeof( int );
|
||||
currentWkbPtr.readHeader();
|
||||
int nRings;
|
||||
currentWkbPtr >> nRings;
|
||||
for ( int index2 = 0; index2 < nRings; ++index2 )
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgis.h"
|
||||
|
||||
#include <QProgressDialog>
|
||||
|
||||
bool QgsGeometryAnalyzer::simplify( QgsVectorLayer* layer,
|
||||
@ -1178,13 +1180,10 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou
|
||||
QgsMultiPolyline resultGeom;
|
||||
|
||||
//need to go with WKB and z coordinate until QgsGeometry supports M values
|
||||
const unsigned char* lineWkb = lineGeom->asWkb();
|
||||
|
||||
const unsigned char* ptr = lineWkb + 1;
|
||||
QGis::WkbType wkbType;
|
||||
memcpy( &wkbType, ptr, sizeof( wkbType ) );
|
||||
ptr += sizeof( wkbType );
|
||||
QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
QGis::WkbType wkbType = lineGeom->wkbType();
|
||||
if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
|
||||
{
|
||||
return nullptr;
|
||||
@ -1192,16 +1191,16 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou
|
||||
|
||||
if ( wkbType == QGis::WKBLineString25D )
|
||||
{
|
||||
locateBetweenWkbString( ptr, resultGeom, fromMeasure, toMeasure );
|
||||
locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
|
||||
}
|
||||
else if ( wkbType == QGis::WKBMultiLineString25D )
|
||||
{
|
||||
int* nLines = ( int* )ptr;
|
||||
ptr += sizeof( int );
|
||||
for ( int i = 0; i < *nLines; ++i )
|
||||
int nLines;
|
||||
wkbPtr >> nLines;
|
||||
for ( int i = 0; i < nLines; ++i )
|
||||
{
|
||||
ptr += ( 1 + sizeof( wkbType ) );
|
||||
ptr = locateBetweenWkbString( ptr, resultGeom, fromMeasure, toMeasure );
|
||||
wkbPtr.readHeader();
|
||||
wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1222,12 +1221,8 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
|
||||
QgsMultiPoint resultGeom;
|
||||
|
||||
//need to go with WKB and z coordinate until QgsGeometry supports M values
|
||||
const unsigned char* lineWkb = lineGeom->asWkb();
|
||||
|
||||
const unsigned char* ptr = lineWkb + 1;
|
||||
QGis::WkbType wkbType;
|
||||
memcpy( &wkbType, ptr, sizeof( wkbType ) );
|
||||
ptr += sizeof( wkbType );
|
||||
QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
|
||||
QGis::WkbType wkbType = lineGeom->wkbType();
|
||||
|
||||
if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
|
||||
{
|
||||
@ -1236,16 +1231,16 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
|
||||
|
||||
if ( wkbType == QGis::WKBLineString25D )
|
||||
{
|
||||
locateAlongWkbString( ptr, resultGeom, measure );
|
||||
locateAlongWkbString( wkbPtr, resultGeom, measure );
|
||||
}
|
||||
else if ( wkbType == QGis::WKBMultiLineString25D )
|
||||
{
|
||||
int* nLines = ( int* )ptr;
|
||||
ptr += sizeof( int );
|
||||
for ( int i = 0; i < *nLines; ++i )
|
||||
int nLines;
|
||||
wkbPtr >> nLines;
|
||||
for ( int i = 0; i < nLines; ++i )
|
||||
{
|
||||
ptr += ( 1 + sizeof( wkbType ) );
|
||||
ptr = locateAlongWkbString( ptr, resultGeom, measure );
|
||||
wkbPtr.readHeader();
|
||||
wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1253,34 +1248,27 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return QgsGeometry::fromMultiPoint( resultGeom );
|
||||
}
|
||||
|
||||
const unsigned char* QgsGeometryAnalyzer::locateBetweenWkbString( const unsigned char* ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure )
|
||||
QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPolyline& result, double fromMeasure, double toMeasure )
|
||||
{
|
||||
int* nPoints = ( int* ) ptr;
|
||||
ptr += sizeof( int );
|
||||
double prevx = 0.0, prevy = 0.0, prevz = 0.0;
|
||||
double *x, *y, *z;
|
||||
int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
QgsPolyline currentLine;
|
||||
|
||||
QgsPoint pt1, pt2;
|
||||
bool measureInSegment; //true if measure is contained in the segment
|
||||
bool secondPointClipped; //true if second point is != segment endpoint
|
||||
|
||||
|
||||
for ( int i = 0; i < *nPoints; ++i )
|
||||
double prevx = 0.0, prevy = 0.0, prevz = 0.0;
|
||||
for ( int i = 0; i < nPoints; ++i )
|
||||
{
|
||||
x = ( double* )ptr;
|
||||
ptr += sizeof( double );
|
||||
y = ( double* )ptr;
|
||||
ptr += sizeof( double );
|
||||
z = ( double* ) ptr;
|
||||
ptr += sizeof( double );
|
||||
double x, y, z;
|
||||
wkbPtr >> x >> y >> z;
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
measureInSegment = clipSegmentByRange( prevx, prevy, prevz, *x, *y, *z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
|
||||
QgsPoint pt1, pt2;
|
||||
bool secondPointClipped; //true if second point is != segment endpoint
|
||||
bool measureInSegment = clipSegmentByRange( prevx, prevy, prevz, x, y, z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
|
||||
if ( measureInSegment )
|
||||
{
|
||||
if ( currentLine.size() < 1 ) //no points collected yet, so the first point needs to be added to the line
|
||||
@ -1293,7 +1281,7 @@ const unsigned char* QgsGeometryAnalyzer::locateBetweenWkbString( const unsigned
|
||||
currentLine.append( pt2 );
|
||||
}
|
||||
|
||||
if ( secondPointClipped || i == *nPoints - 1 ) //close current segment
|
||||
if ( secondPointClipped || i == nPoints - 1 ) //close current segment
|
||||
{
|
||||
if ( currentLine.size() > 1 )
|
||||
{
|
||||
@ -1303,49 +1291,45 @@ const unsigned char* QgsGeometryAnalyzer::locateBetweenWkbString( const unsigned
|
||||
}
|
||||
}
|
||||
}
|
||||
prevx = *x;
|
||||
prevy = *y;
|
||||
prevz = *z;
|
||||
prevx = x;
|
||||
prevy = y;
|
||||
prevz = z;
|
||||
}
|
||||
return ptr;
|
||||
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
const unsigned char* QgsGeometryAnalyzer::locateAlongWkbString( const unsigned char* ptr, QgsMultiPoint& result, double measure )
|
||||
QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPoint& result, double measure )
|
||||
{
|
||||
int* nPoints = ( int* ) ptr;
|
||||
ptr += sizeof( int );
|
||||
int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
double x, y, z;
|
||||
double prevx = 0.0, prevy = 0.0, prevz = 0.0;
|
||||
double *x, *y, *z;
|
||||
|
||||
QgsPoint pt1, pt2;
|
||||
bool pt1Ok, pt2Ok;
|
||||
|
||||
for ( int i = 0; i < *nPoints; ++i )
|
||||
for ( int i = 0; i < nPoints; ++i )
|
||||
{
|
||||
x = ( double* )ptr;
|
||||
ptr += sizeof( double );
|
||||
y = ( double* )ptr;
|
||||
ptr += sizeof( double );
|
||||
z = ( double* ) ptr;
|
||||
ptr += sizeof( double );
|
||||
wkbPtr >> x >> y >> z;
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
locateAlongSegment( prevx, prevy, prevz, *x, *y, *z, measure, pt1Ok, pt1, pt2Ok, pt2 );
|
||||
QgsPoint pt1, pt2;
|
||||
bool pt1Ok, pt2Ok;
|
||||
locateAlongSegment( prevx, prevy, prevz, x, y, z, measure, pt1Ok, pt1, pt2Ok, pt2 );
|
||||
if ( pt1Ok )
|
||||
{
|
||||
result.append( pt1 );
|
||||
}
|
||||
if ( pt2Ok && ( i == ( *nPoints - 1 ) ) )
|
||||
if ( pt2Ok && i == nPoints - 1 )
|
||||
{
|
||||
result.append( pt2 );
|
||||
}
|
||||
}
|
||||
prevx = *x;
|
||||
prevy = *y;
|
||||
prevz = *z;
|
||||
prevx = x;
|
||||
prevy = y;
|
||||
prevz = z;
|
||||
}
|
||||
return ptr;
|
||||
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
bool QgsGeometryAnalyzer::clipSegmentByRange( double x1, double y1, double m1, double x2, double y2, double m2, double range1, double range2, QgsPoint& pt1,
|
||||
|
@ -151,8 +151,8 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
|
||||
@param offset the offset value in layer unit. Negative values mean offset towards left, positive values offset to the right side*/
|
||||
bool createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset );
|
||||
QgsPoint createPointOffset( double x, double y, double dist, QgsGeometry* lineGeom ) const;
|
||||
const unsigned char* locateBetweenWkbString( const unsigned char* ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
|
||||
const unsigned char* locateAlongWkbString( const unsigned char* ptr, QgsMultiPoint& result, double measure );
|
||||
QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
|
||||
QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure );
|
||||
static bool clipSegmentByRange( double x1, double y1, double m1, double x2, double y2, double m2, double range1, double range2, QgsPoint& pt1, QgsPoint& pt2, bool& secondPointClipped );
|
||||
static void locateAlongSegment( double x1, double y1, double m1, double x2, double y2, double m2, double measure, bool& pt1Ok, QgsPoint& pt1, bool& pt2Ok, QgsPoint& pt2 );
|
||||
};
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "qgsrubberband.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
|
||||
// QWT Charting widget
|
||||
@ -817,8 +818,6 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked()
|
||||
QgsFeature* f = new QgsFeature( 0 );
|
||||
|
||||
int size = 0;
|
||||
char end = QgsApplication::endian();
|
||||
unsigned char *wkb = nullptr;
|
||||
int wkbtype = 0;
|
||||
|
||||
QgsCoordinateTransform t( mWgs84CRS, vlayer->crs() );
|
||||
@ -827,15 +826,13 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked()
|
||||
double y = myPoint.y();
|
||||
|
||||
size = 1 + sizeof( int ) + 2 * sizeof( double );
|
||||
wkb = new unsigned char[size];
|
||||
wkbtype = QGis::WKBPoint;
|
||||
memcpy( &wkb[0], &end, 1 );
|
||||
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
|
||||
memcpy( &wkb[5], &x, sizeof( double ) );
|
||||
memcpy( &wkb[5] + sizeof( double ), &y, sizeof( double ) );
|
||||
unsigned char *buf = new unsigned char[size];
|
||||
|
||||
QgsWkbPtr wkbPtr( buf, size );
|
||||
wkbPtr << ( char ) QgsApplication::endian() << wkbtype << x << y;
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( &wkb[0], size );
|
||||
g->fromWkb( buf, size );
|
||||
f->setGeometry( g );
|
||||
|
||||
QgsFeatureAction action( tr( "Feature added" ), *f, vlayer, -1, -1, this );
|
||||
@ -865,54 +862,37 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked()
|
||||
|
||||
//create QgsFeature with wkb representation
|
||||
QgsFeature* f = new QgsFeature( 0 );
|
||||
unsigned char* wkb;
|
||||
int size;
|
||||
char end = QgsApplication::endian();
|
||||
|
||||
if ( layerWKBType == QGis::WKBLineString )
|
||||
{
|
||||
size = 1 + 2 * sizeof( int ) + 2 * mCaptureList.size() * sizeof( double );
|
||||
wkb = new unsigned char[size];
|
||||
int wkbtype = QGis::WKBLineString;
|
||||
int length = mCaptureList.size();
|
||||
memcpy( &wkb[0], &end, 1 );
|
||||
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
|
||||
memcpy( &wkb[1+sizeof( int )], &length, sizeof( int ) );
|
||||
int position = 1 + 2 * sizeof( int );
|
||||
double x, y;
|
||||
int size = 1 + 2 * sizeof( int ) + 2 * mCaptureList.size() * sizeof( double );
|
||||
unsigned char *buf = new unsigned char[size];
|
||||
|
||||
QgsWkbPtr wkbPtr( buf, size );
|
||||
wkbPtr << ( char ) QgsApplication::endian() << QGis::WKBLineString << mCaptureList.size();
|
||||
|
||||
for ( QList<QgsPoint>::const_iterator it = mCaptureList.constBegin(); it != mCaptureList.constEnd(); ++it )
|
||||
{
|
||||
QgsPoint savePoint = *it;
|
||||
// transform the gps point into the layer crs
|
||||
QgsCoordinateTransform t( mWgs84CRS, vlayer->crs() );
|
||||
QgsPoint myPoint = t.transform( savePoint );
|
||||
x = myPoint.x();
|
||||
y = myPoint.y();
|
||||
|
||||
memcpy( &wkb[position], &x, sizeof( double ) );
|
||||
position += sizeof( double );
|
||||
|
||||
memcpy( &wkb[position], &y, sizeof( double ) );
|
||||
position += sizeof( double );
|
||||
wkbPtr << myPoint.x() << myPoint.y();
|
||||
}
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( &wkb[0], size );
|
||||
g->fromWkb( buf, size );
|
||||
f->setGeometry( g );
|
||||
}
|
||||
else if ( layerWKBType == QGis::WKBPolygon )
|
||||
{
|
||||
size = 1 + 3 * sizeof( int ) + 2 * ( mCaptureList.size() + 1 ) * sizeof( double );
|
||||
wkb = new unsigned char[size];
|
||||
int wkbtype = QGis::WKBPolygon;
|
||||
int length = mCaptureList.size() + 1;//+1 because the first point is needed twice
|
||||
int numrings = 1;
|
||||
memcpy( &wkb[0], &end, 1 );
|
||||
memcpy( &wkb[1], &wkbtype, sizeof( int ) );
|
||||
memcpy( &wkb[1+sizeof( int )], &numrings, sizeof( int ) );
|
||||
memcpy( &wkb[1+2*sizeof( int )], &length, sizeof( int ) );
|
||||
int position = 1 + 3 * sizeof( int );
|
||||
double x, y;
|
||||
int size = 1 + 3 * sizeof( int ) + 2 * ( mCaptureList.size() + 1 ) * sizeof( double );
|
||||
unsigned char *buf = new unsigned char[size];
|
||||
|
||||
QgsWkbPtr wkbPtr( buf, size );
|
||||
wkbPtr << ( char ) QgsApplication::endian() << QGis::WKBPolygon << 1 << mCaptureList.size() + 1;
|
||||
|
||||
QList<QgsPoint>::iterator it;
|
||||
for ( it = mCaptureList.begin(); it != mCaptureList.end(); ++it )
|
||||
{
|
||||
@ -920,28 +900,16 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked()
|
||||
// transform the gps point into the layer crs
|
||||
QgsCoordinateTransform t( mWgs84CRS, vlayer->crs() );
|
||||
QgsPoint myPoint = t.transform( savePoint );
|
||||
x = myPoint.x();
|
||||
y = myPoint.y();
|
||||
|
||||
memcpy( &wkb[position], &x, sizeof( double ) );
|
||||
position += sizeof( double );
|
||||
|
||||
memcpy( &wkb[position], &y, sizeof( double ) );
|
||||
position += sizeof( double );
|
||||
wkbPtr << myPoint.x() << myPoint.y();
|
||||
}
|
||||
// close the polygon
|
||||
it = mCaptureList.begin();
|
||||
QgsPoint savePoint = *it;
|
||||
x = savePoint.x();
|
||||
y = savePoint.y();
|
||||
|
||||
memcpy( &wkb[position], &x, sizeof( double ) );
|
||||
position += sizeof( double );
|
||||
|
||||
memcpy( &wkb[position], &y, sizeof( double ) );
|
||||
wkbPtr << savePoint.x() << savePoint.y();
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( &wkb[0], size );
|
||||
g->fromWkb( buf, size );
|
||||
f->setGeometry( g );
|
||||
|
||||
int avoidIntersectionsReturn = f->geometry()->avoidIntersections();
|
||||
|
@ -18,6 +18,7 @@ email : marco.hugentobler at sourcepole dot com
|
||||
#include "qgswkbptr.h"
|
||||
#include "qgsgeos.h"
|
||||
#include "qgsmaptopixel.h"
|
||||
|
||||
#include <limits>
|
||||
#include <QTransform>
|
||||
|
||||
@ -173,29 +174,6 @@ QString QgsAbstractGeometryV2::wktTypeStr() const
|
||||
return wkt;
|
||||
}
|
||||
|
||||
bool QgsAbstractGeometryV2::readWkbHeader( QgsConstWkbPtr& wkbPtr, QgsWKBTypes::Type& wkbType, bool& endianSwap, QgsWKBTypes::Type expectedType )
|
||||
{
|
||||
if ( !static_cast<const unsigned char*>( wkbPtr ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char wkbEndian;
|
||||
wkbPtr >> wkbEndian;
|
||||
endianSwap = wkbEndian != QgsApplication::endian();
|
||||
|
||||
wkbPtr >> wkbType;
|
||||
if ( endianSwap )
|
||||
QgsApplication::endian_swap( wkbType );
|
||||
|
||||
if ( QgsWKBTypes::flatType( wkbType ) != expectedType )
|
||||
{
|
||||
wkbType = QgsWKBTypes::Unknown;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsPointV2 QgsAbstractGeometryV2::centroid() const
|
||||
{
|
||||
// http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
|
||||
|
@ -19,6 +19,8 @@ email : marco.hugentobler at sourcepole dot com
|
||||
#include "qgscoordinatetransform.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgswkbtypes.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QgsCoordinateTransform;
|
||||
@ -27,9 +29,7 @@ class QgsCurveV2;
|
||||
class QgsMultiCurveV2;
|
||||
class QgsMultiPointV2;
|
||||
class QgsPointV2;
|
||||
class QgsConstWkbPtr;
|
||||
struct QgsVertexId;
|
||||
class QgsWkbPtr;
|
||||
class QPainter;
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
||||
/** Sets the geometry from a WKB string.
|
||||
* @see fromWkt
|
||||
*/
|
||||
virtual bool fromWkb( const unsigned char * wkb ) = 0;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) = 0;
|
||||
|
||||
/** Sets the geometry from a WKT string.
|
||||
* @see fromWkb
|
||||
@ -205,7 +205,7 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
||||
* in this variable if found.
|
||||
* @param vertex container for found node
|
||||
* @return false if at end
|
||||
*/
|
||||
*/
|
||||
virtual bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const = 0;
|
||||
|
||||
/** Retrieves the sequence of geometries, rings and nodes.
|
||||
@ -358,17 +358,6 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
||||
/** Updates the geometry type based on whether sub geometries contain z or m values.
|
||||
*/
|
||||
void setZMTypeFromSubGeometry( const QgsAbstractGeometryV2* subggeom, QgsWKBTypes::Type baseGeomType );
|
||||
|
||||
/** Reads a WKB header and tests its validity.
|
||||
* @param wkbPtr
|
||||
* @param wkbType destination for WKB type from header
|
||||
* @param endianSwap will be set to true if endian from WKB must be swapped to match QGIS platform endianness
|
||||
* @param expectedType expected WKB type
|
||||
* @returns true if header is valid and matches expected type
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
static bool readWkbHeader( QgsConstWkbPtr& wkbPtr, QgsWKBTypes::Type& wkbType, bool& endianSwap, QgsWKBTypes::Type expectedType );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -206,14 +206,11 @@ QList<QgsPointV2> QgsCircularStringV2::compassPointsOnSegment( double p1Angle, d
|
||||
return pointList;
|
||||
}
|
||||
|
||||
bool QgsCircularStringV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsCircularStringV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
if ( !wkb )
|
||||
{
|
||||
if ( !wkbPtr )
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::CircularString )
|
||||
{
|
||||
@ -272,7 +269,7 @@ unsigned char* QgsCircularStringV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
QList<QgsPointV2> pts;
|
||||
|
@ -43,7 +43,7 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
virtual bool fromWkb( const unsigned char * wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
int wkbSize() const override;
|
||||
@ -87,6 +87,7 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
||||
virtual QgsLineStringV2* curveToLine() const override;
|
||||
|
||||
void draw( QPainter& p ) const override;
|
||||
|
||||
/** Transforms the geometry using a coordinate transform
|
||||
* @param ct coordinate transform
|
||||
* @param d transformation direction
|
||||
|
@ -98,15 +98,14 @@ QgsRectangle QgsCompoundCurveV2::calculateBoundingBox() const
|
||||
return bbox;
|
||||
}
|
||||
|
||||
bool QgsCompoundCurveV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsCompoundCurveV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
clear();
|
||||
if ( !wkb )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::CompoundCurve )
|
||||
{
|
||||
@ -120,10 +119,8 @@ bool QgsCompoundCurveV2::fromWkb( const unsigned char* wkb )
|
||||
int currentCurveSize = 0;
|
||||
for ( int i = 0; i < nCurves; ++i )
|
||||
{
|
||||
wkbPtr += 1; //skip endian
|
||||
QgsWKBTypes::Type curveType;
|
||||
wkbPtr >> curveType;
|
||||
wkbPtr -= ( 1 + sizeof( int ) );
|
||||
QgsWKBTypes::Type curveType = wkbPtr.readHeader();
|
||||
wkbPtr -= 1 + sizeof( int );
|
||||
if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::LineString )
|
||||
{
|
||||
currentCurve = new QgsLineStringV2();
|
||||
@ -209,7 +206,7 @@ unsigned char* QgsCompoundCurveV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
wkb << static_cast<quint32>( mCurves.size() );
|
||||
|
@ -44,7 +44,7 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
int wkbSize() const override;
|
||||
|
@ -82,14 +82,14 @@ void QgsCurvePolygonV2::clear()
|
||||
}
|
||||
|
||||
|
||||
bool QgsCurvePolygonV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsCurvePolygonV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
clear();
|
||||
if ( !wkb )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::CurvePolygon )
|
||||
{
|
||||
@ -103,10 +103,8 @@ bool QgsCurvePolygonV2::fromWkb( const unsigned char* wkb )
|
||||
int currentCurveSize = 0;
|
||||
for ( int i = 0; i < nRings; ++i )
|
||||
{
|
||||
wkbPtr += 1; //skip endian
|
||||
QgsWKBTypes::Type curveType;
|
||||
wkbPtr >> curveType;
|
||||
wkbPtr -= ( 1 + sizeof( int ) );
|
||||
QgsWKBTypes::Type curveType = wkbPtr.readHeader();
|
||||
wkbPtr -= 1 + sizeof( int );
|
||||
if ( curveType == QgsWKBTypes::LineString || curveType == QgsWKBTypes::LineStringZ || curveType == QgsWKBTypes::LineStringM ||
|
||||
curveType == QgsWKBTypes::LineStringZM || curveType == QgsWKBTypes::LineString25D )
|
||||
{
|
||||
@ -149,6 +147,7 @@ bool QgsCurvePolygonV2::fromWkt( const QString& wkt )
|
||||
|
||||
if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::parseType( geometryType() ) )
|
||||
return false;
|
||||
|
||||
mWkbType = parts.first;
|
||||
|
||||
QString defaultChildWkbType = QString( "LineString%1%2" ).arg( is3D() ? "Z" : "", isMeasure() ? "M" : "" );
|
||||
@ -233,23 +232,23 @@ unsigned char* QgsCurvePolygonV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
wkb << static_cast<quint32>(( nullptr != mExteriorRing ) + mInteriorRings.size() );
|
||||
QgsWkbPtr wkbPtr( geomPtr, binarySize );
|
||||
wkbPtr << static_cast<char>( QgsApplication::endian() );
|
||||
wkbPtr << static_cast<quint32>( wkbType() );
|
||||
wkbPtr << static_cast<quint32>(( nullptr != mExteriorRing ) + mInteriorRings.size() );
|
||||
if ( mExteriorRing )
|
||||
{
|
||||
int curveWkbLen = 0;
|
||||
unsigned char* ringWkb = mExteriorRing->asWkb( curveWkbLen );
|
||||
memcpy( wkb, ringWkb, curveWkbLen );
|
||||
wkb += curveWkbLen;
|
||||
unsigned char *ringWkb = mExteriorRing->asWkb( curveWkbLen );
|
||||
memcpy( wkbPtr, ringWkb, curveWkbLen );
|
||||
wkbPtr += curveWkbLen;
|
||||
}
|
||||
Q_FOREACH ( const QgsCurveV2* curve, mInteriorRings )
|
||||
{
|
||||
int curveWkbLen = 0;
|
||||
unsigned char* ringWkb = curve->asWkb( curveWkbLen );
|
||||
memcpy( wkb, ringWkb, curveWkbLen );
|
||||
wkb += curveWkbLen;
|
||||
unsigned char *ringWkb = curve->asWkb( curveWkbLen );
|
||||
memcpy( wkbPtr, ringWkb, curveWkbLen );
|
||||
wkbPtr += curveWkbLen;
|
||||
}
|
||||
return geomPtr;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
virtual bool fromWkb( const unsigned char* wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
int wkbSize() const override;
|
||||
|
@ -244,7 +244,7 @@ void QgsGeometry::fromWkb( unsigned char *wkb, int length )
|
||||
delete d->geometry;
|
||||
removeWkbGeos();
|
||||
}
|
||||
d->geometry = QgsGeometryFactory::geomFromWkb( wkb );
|
||||
d->geometry = QgsGeometryFactory::geomFromWkb( QgsConstWkbPtr( wkb, length ) );
|
||||
d->mWkb = wkb;
|
||||
d->mWkbSize = length;
|
||||
}
|
||||
|
@ -138,11 +138,12 @@ class CORE_EXPORT QgsGeometry
|
||||
@note not available in python bindings
|
||||
*/
|
||||
void fromGeos( GEOSGeometry* geos );
|
||||
|
||||
/**
|
||||
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
|
||||
This class will take ownership of the buffer.
|
||||
*/
|
||||
void fromWkb( unsigned char * wkb, int length );
|
||||
void fromWkb( unsigned char *wkb, int length );
|
||||
|
||||
/**
|
||||
Returns the buffer containing this geometry in WKB format.
|
||||
|
@ -179,15 +179,15 @@ void QgsGeometryCollectionV2::draw( QPainter& p ) const
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsGeometryCollectionV2::fromWkb( const unsigned char * wkb )
|
||||
bool QgsGeometryCollectionV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
if ( !wkb )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
//type
|
||||
wkbPtr >> mWkbType;
|
||||
|
||||
mWkbType = wkbPtr.readHeader();
|
||||
|
||||
int nGeometries = 0;
|
||||
wkbPtr >> nGeometries;
|
||||
|
||||
@ -237,7 +237,7 @@ unsigned char* QgsGeometryCollectionV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
wkb << static_cast<quint32>( mGeometries.size() );
|
||||
|
@ -81,7 +81,7 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
#endif
|
||||
virtual void draw( QPainter& p ) const override;
|
||||
|
||||
bool fromWkb( const unsigned char * wkb ) override;
|
||||
bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
int wkbSize() const override;
|
||||
unsigned char* asWkb( int& binarySize ) const override;
|
||||
|
@ -29,24 +29,22 @@
|
||||
#include "qgsmultisurfacev2.h"
|
||||
#include "qgswkbtypes.h"
|
||||
|
||||
QgsAbstractGeometryV2* QgsGeometryFactory::geomFromWkb( const unsigned char* wkb )
|
||||
QgsAbstractGeometryV2* QgsGeometryFactory::geomFromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
if ( !wkb )
|
||||
{
|
||||
if ( !wkbPtr )
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//find out type (bytes 2-5)
|
||||
int type;
|
||||
memcpy( &type, wkb + 1, sizeof( int ) );
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
wkbPtr -= 1 + sizeof( int );
|
||||
|
||||
QgsAbstractGeometryV2* geom = nullptr;
|
||||
|
||||
geom = geomFromWkbType( QgsWKBTypes::Type( type ) );
|
||||
geom = geomFromWkbType( type );
|
||||
|
||||
if ( geom )
|
||||
{
|
||||
geom->fromWkb( wkb );
|
||||
}
|
||||
geom->fromWkb( wkbPtr );
|
||||
|
||||
return geom;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgswkbtypes.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QgsAbstractGeometryV2;
|
||||
@ -45,7 +47,7 @@ class CORE_EXPORT QgsGeometryFactory
|
||||
public:
|
||||
/** Construct geometry from a WKB string.
|
||||
*/
|
||||
static QgsAbstractGeometryV2* geomFromWkb( const unsigned char* wkb );
|
||||
static QgsAbstractGeometryV2* geomFromWkb( QgsConstWkbPtr wkb );
|
||||
|
||||
/** Construct geometry from a WKT string.
|
||||
*/
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "qgsgeometryutils.h"
|
||||
#include "qgsmaptopixel.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <limits>
|
||||
#include <QDomDocument>
|
||||
@ -89,13 +90,13 @@ void QgsLineStringV2::clear()
|
||||
mBoundingBox = QgsRectangle();
|
||||
}
|
||||
|
||||
bool QgsLineStringV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsLineStringV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
if ( !wkb )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::LineString )
|
||||
{
|
||||
@ -143,7 +144,7 @@ unsigned char* QgsLineStringV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
QList<QgsPointV2> pts;
|
||||
|
@ -139,7 +139,7 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
|
||||
virtual QgsLineStringV2* clone() const override;
|
||||
virtual void clear() override;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
int wkbSize() const override;
|
||||
|
@ -96,9 +96,8 @@ QgsPointV2 *QgsPointV2::clone() const
|
||||
return new QgsPointV2( *this );
|
||||
}
|
||||
|
||||
bool QgsPointV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsPointV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::Point )
|
||||
{
|
||||
@ -183,7 +182,7 @@ unsigned char* QgsPointV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
wkb << mX << mY;
|
||||
|
@ -155,7 +155,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
virtual int dimension() const override { return 0; }
|
||||
virtual QgsPointV2* clone() const override;
|
||||
void clear() override;
|
||||
virtual bool fromWkb( const unsigned char* wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
int wkbSize() const override;
|
||||
unsigned char* asWkb( int& binarySize ) const override;
|
||||
|
@ -52,7 +52,8 @@ bool QgsPolygonV2::operator==( const QgsPolygonV2& other ) const
|
||||
( mInteriorRings.at( i ) && !other.mInteriorRings.at( i ) ) )
|
||||
return false;
|
||||
|
||||
if ( mInteriorRings.at( i ) && other.mInteriorRings.at( i ) && *mInteriorRings.at( i ) != *other.mInteriorRings.at( i ) )
|
||||
if ( mInteriorRings.at( i ) && other.mInteriorRings.at( i ) &&
|
||||
*mInteriorRings.at( i ) != *other.mInteriorRings.at( i ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -69,15 +70,14 @@ QgsPolygonV2* QgsPolygonV2::clone() const
|
||||
return new QgsPolygonV2( *this );
|
||||
}
|
||||
|
||||
bool QgsPolygonV2::fromWkb( const unsigned char* wkb )
|
||||
bool QgsPolygonV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
clear();
|
||||
if ( !wkb )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( wkb );
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::Polygon )
|
||||
{
|
||||
@ -149,7 +149,7 @@ unsigned char* QgsPolygonV2::asWkb( int& binarySize ) const
|
||||
{
|
||||
binarySize = wkbSize();
|
||||
unsigned char* geomPtr = new unsigned char[binarySize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, binarySize );
|
||||
wkb << static_cast<char>( QgsApplication::endian() );
|
||||
wkb << static_cast<quint32>( wkbType() );
|
||||
wkb << static_cast<quint32>(( nullptr != mExteriorRing ) + mInteriorRings.size() );
|
||||
|
@ -37,7 +37,7 @@ class CORE_EXPORT QgsPolygonV2: public QgsCurvePolygonV2
|
||||
virtual QString geometryType() const override { return "Polygon"; }
|
||||
virtual QgsPolygonV2* clone() const override;
|
||||
|
||||
virtual bool fromWkb( const unsigned char* wkb ) override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
|
||||
int wkbSize() const override;
|
||||
unsigned char* asWkb( int& binarySize ) const override;
|
||||
|
@ -14,27 +14,33 @@
|
||||
***************************************************************************/
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
QgsConstWkbPtr::QgsConstWkbPtr( const unsigned char *p ): mEndianSwap( false )
|
||||
QgsWkbPtr::QgsWkbPtr( unsigned char *p, int size )
|
||||
{
|
||||
mP = p;
|
||||
mStart = mP;
|
||||
mEnd = mP + size;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr::QgsConstWkbPtr( const unsigned char *p, int size )
|
||||
{
|
||||
mP = const_cast< unsigned char * >( p );
|
||||
mEnd = mP + size;
|
||||
mEndianSwap = false;
|
||||
}
|
||||
|
||||
QgsWKBTypes::Type QgsConstWkbPtr::readHeader() const
|
||||
{
|
||||
if ( !mP )
|
||||
{
|
||||
return QgsWKBTypes::Unknown;
|
||||
}
|
||||
|
||||
char wkbEndian;
|
||||
( *this ) >> wkbEndian;
|
||||
*this >> wkbEndian;
|
||||
mEndianSwap = ( wkbEndian != QgsApplication::endian() );
|
||||
|
||||
QgsWKBTypes::Type wkbType;
|
||||
( *this ) >> wkbType;
|
||||
int wkbType;
|
||||
*this >> wkbType;
|
||||
if ( mEndianSwap )
|
||||
{
|
||||
QgsApplication::endian_swap( wkbType );
|
||||
}
|
||||
return wkbType;
|
||||
|
||||
return static_cast<QgsWKBTypes::Type>( wkbType );
|
||||
}
|
||||
|
@ -18,6 +18,17 @@
|
||||
#include "qgswkbtypes.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgis.h"
|
||||
#include "qgsexception.h"
|
||||
|
||||
/** \ingroup core
|
||||
* * Custom exception class for Wkb related exceptions.
|
||||
* */
|
||||
class CORE_EXPORT QgsWkbException : public QgsException
|
||||
{
|
||||
public:
|
||||
QgsWkbException( QString const &what ) : QgsException( what ) {}
|
||||
};
|
||||
|
||||
|
||||
/** \class QgsWkbPtr
|
||||
* \note not available in Python bindings
|
||||
@ -26,33 +37,50 @@
|
||||
class CORE_EXPORT QgsWkbPtr
|
||||
{
|
||||
mutable unsigned char *mP;
|
||||
unsigned char *mStart;
|
||||
unsigned char *mEnd;
|
||||
|
||||
void verify( int size ) const { Q_ASSERT( mP && mP + size <= mEnd ); if ( !mP || mP + size > mEnd ) throw QgsWkbException( "wkb access out of bounds" ); }
|
||||
|
||||
template<typename T> void read( T& v ) const
|
||||
{
|
||||
verify( sizeof v );
|
||||
memcpy( &v, mP, sizeof v );
|
||||
mP += sizeof v;
|
||||
}
|
||||
|
||||
template<typename T> void write( T& v ) const
|
||||
{
|
||||
verify( sizeof v );
|
||||
memcpy( mP, &v, sizeof v );
|
||||
mP += sizeof v;
|
||||
}
|
||||
|
||||
public:
|
||||
QgsWkbPtr( unsigned char *p ): mP( p ) {}
|
||||
QgsWkbPtr( unsigned char *p, int size );
|
||||
|
||||
inline const QgsWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( QgsWKBTypes::Type &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
#ifdef QT_ARCH_ARM
|
||||
inline const QgsWkbPtr &operator>>( qreal &r ) const { double v; memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); r = v; return *this; }
|
||||
#endif
|
||||
inline const QgsWkbPtr &operator>>( double &v ) const { read( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( float &r ) const { double v; read( v ); r = v; return *this; }
|
||||
inline const QgsWkbPtr &operator>>( int &v ) const { read( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( char &v ) const { read( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( QgsWKBTypes::Type &v ) const { read( v ); return *this; }
|
||||
inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { read( v ); return *this; }
|
||||
|
||||
inline QgsWkbPtr &operator<<( const double &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const unsigned int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const char &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const QgsWKBTypes::Type &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const QGis::WkbType &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
#ifdef QT_ARCH_ARM
|
||||
inline QgsWkbPtr &operator<<( const qreal &r ) { double v = r; memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
|
||||
#endif
|
||||
inline QgsWkbPtr &operator<<( const double &v ) { write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const float &r ) { double v = r; write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const int &v ) { write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const unsigned int &v ) { write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const char &v ) { write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const QgsWKBTypes::Type &v ) { write( v ); return *this; }
|
||||
inline QgsWkbPtr &operator<<( const QGis::WkbType &v ) { write( v ); return *this; }
|
||||
|
||||
inline void operator+=( int n ) { mP += n; }
|
||||
inline void operator+=( int n ) { verify( n ); mP += n; }
|
||||
|
||||
inline operator unsigned char *() const { return mP; }
|
||||
inline int size() const { return mEnd -mStart; }
|
||||
inline int remaining() const { return mEnd -mP; }
|
||||
inline int writtenSize() const { return mP -mStart; }
|
||||
};
|
||||
|
||||
/** \class QgsConstWkbPtr
|
||||
@ -62,10 +90,22 @@ class CORE_EXPORT QgsWkbPtr
|
||||
class CORE_EXPORT QgsConstWkbPtr
|
||||
{
|
||||
mutable unsigned char *mP;
|
||||
unsigned char *mEnd;
|
||||
mutable bool mEndianSwap;
|
||||
|
||||
void verify( int size ) const { Q_ASSERT( mP && mP + size <= mEnd ); if ( !mP || mP + size > mEnd ) throw QgsWkbException( "wkb access out of bounds" ); }
|
||||
|
||||
template<typename T> void read( T& v ) const
|
||||
{
|
||||
verify( sizeof v );
|
||||
memcpy( &v, mP, sizeof( v ) );
|
||||
mP += sizeof( v );
|
||||
if ( mEndianSwap )
|
||||
QgsApplication::endian_swap( v );
|
||||
}
|
||||
|
||||
public:
|
||||
QgsConstWkbPtr( const unsigned char *p );
|
||||
QgsConstWkbPtr( const unsigned char *p, int size );
|
||||
QgsWKBTypes::Type readHeader() const;
|
||||
|
||||
inline const QgsConstWkbPtr &operator>>( double &v ) const { read( v ); return *this; }
|
||||
@ -73,23 +113,12 @@ class CORE_EXPORT QgsConstWkbPtr
|
||||
inline const QgsConstWkbPtr &operator>>( int &v ) const { read( v ); return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( char &v ) const { read( v ); return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( QGis::WkbType &v ) const { read( v ); return *this; }
|
||||
inline const QgsConstWkbPtr &operator>>( QgsWKBTypes::Type &v ) const { read( v ); return *this; }
|
||||
|
||||
inline void operator+=( int n ) { mP += n; }
|
||||
inline void operator+=( int n ) { verify( n ); mP += n; }
|
||||
inline void operator-=( int n ) { mP -= n; }
|
||||
|
||||
inline operator const unsigned char *() const { return mP; }
|
||||
|
||||
template<typename T> void read( T& v ) const
|
||||
{
|
||||
memcpy( &v, mP, sizeof( v ) );
|
||||
mP += sizeof( v );
|
||||
if ( mEndianSwap )
|
||||
{
|
||||
QgsApplication::endian_swap( v );
|
||||
}
|
||||
}
|
||||
inline int remaining() const { return mEnd -mP; }
|
||||
};
|
||||
|
||||
#endif // QGSWKBPTR_H
|
||||
|
@ -98,14 +98,14 @@ class CORE_EXPORT QGis
|
||||
static bool isMultiType( WkbType type );
|
||||
|
||||
// get dimension of points
|
||||
// @deprecated use QgsWKBTypes::hasZ() and QgsWKBTypes::hasM()
|
||||
// @deprecated use QgsWKBTypes::coordDimensions()
|
||||
/* Q_DECL_DEPRECATED */
|
||||
static int wkbDimensions( WkbType type );
|
||||
|
||||
//! Converts from old (pre 2.10) WKB type to new WKB type
|
||||
//! Converts from old (pre 2.10) WKB type (OGR) to new WKB type
|
||||
static QgsWKBTypes::Type fromOldWkbType( QGis::WkbType type );
|
||||
|
||||
//! Converts from new (post 2.10) WKB type to old WKB type
|
||||
//! Converts from new (post 2.10) WKB type (OGC) to old WKB type
|
||||
static QGis::WkbType fromNewWkbType( QgsWKBTypes::Type type );
|
||||
|
||||
enum GeometryType
|
||||
|
@ -37,17 +37,14 @@ const double QgsClipper::MIN_Y = -16000;
|
||||
|
||||
const double QgsClipper::SMALL_NUM = 1e-12;
|
||||
|
||||
const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line )
|
||||
QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr wkbPtr, const QgsRectangle& clipExtent, QPolygonF& line )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();
|
||||
|
||||
unsigned int wkbType, nPoints;
|
||||
|
||||
wkbPtr >> wkbType >> nPoints;
|
||||
|
||||
bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
|
||||
double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
|
||||
double p1x_c, p1y_c; //clipped end coordinates
|
||||
@ -56,16 +53,12 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const
|
||||
line.clear();
|
||||
line.reserve( nPoints + 1 );
|
||||
|
||||
for ( unsigned int i = 0; i < nPoints; ++i )
|
||||
for ( int i = 0; i < nPoints; ++i )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
wkbPtr >> p1x >> p1y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
|
||||
wkbPtr += skipZM;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@ -74,10 +67,7 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const
|
||||
p0y = p1y;
|
||||
|
||||
wkbPtr >> p1x >> p1y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
wkbPtr += skipZM;
|
||||
|
||||
p1x_c = p1x;
|
||||
p1y_c = p1y;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "qgis.h"
|
||||
#include "qgspoint.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <QPolygonF>
|
||||
@ -86,7 +87,7 @@ class CORE_EXPORT QgsClipper
|
||||
@param wkb pointer to the start of the line wkb
|
||||
@param clipExtent clipping bounds
|
||||
@param line out: clipped line coordinates*/
|
||||
static const unsigned char* clippedLineWKB( const unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line );
|
||||
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr wkb, const QgsRectangle& clipExtent, QPolygonF& line );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -539,15 +539,15 @@ QGis::UnitType QgsDistanceArea::lengthUnits() const
|
||||
return willUseEllipsoid() ? QGis::Meters : mCoordTransform->sourceCrs().mapUnits();
|
||||
}
|
||||
|
||||
const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr ) const
|
||||
QgsConstWkbPtr QgsDistanceArea::measurePolygon( QgsConstWkbPtr wkbPtr, double* area, double* perimeter, bool hasZptr ) const
|
||||
{
|
||||
if ( !feature )
|
||||
if ( !wkbPtr )
|
||||
{
|
||||
QgsDebugMsg( "no feature to measure" );
|
||||
return nullptr;
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
// get number of rings in the polygon
|
||||
int numRings;
|
||||
@ -556,7 +556,7 @@ const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* featu
|
||||
if ( numRings == 0 )
|
||||
{
|
||||
QgsDebugMsg( "no rings to measure" );
|
||||
return nullptr;
|
||||
return QgsConstWkbPtr( nullptr, 0 );
|
||||
}
|
||||
|
||||
// Set pointer to the first ring
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <QList>
|
||||
#include "qgscoordinatetransform.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
class QgsGeometry;
|
||||
class QgsAbstractGeometryV2;
|
||||
@ -220,7 +221,7 @@ class CORE_EXPORT QgsDistanceArea
|
||||
protected:
|
||||
//! measures polygon area and perimeter, vertices are extracted from WKB
|
||||
// @note not available in python bindings
|
||||
const unsigned char* measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr = false ) const;
|
||||
QgsConstWkbPtr measurePolygon( QgsConstWkbPtr feature, double* area, double* perimeter, bool hasZptr = false ) const;
|
||||
|
||||
/**
|
||||
calculates distance from two points on ellipsoid
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QList>
|
||||
#include <QNetworkRequest>
|
||||
@ -45,8 +47,7 @@ QgsGml::QgsGml(
|
||||
, mFinished( false )
|
||||
, mCurrentFeature( nullptr )
|
||||
, mFeatureCount( 0 )
|
||||
, mCurrentWKB( nullptr )
|
||||
, mCurrentWKBSize( 0 )
|
||||
, mCurrentWKB( nullptr, 0 )
|
||||
, mDimension( 2 )
|
||||
, mCoorMode( QgsGml::coordinate )
|
||||
, mEpsg( 0 )
|
||||
@ -286,22 +287,19 @@ void QgsGml::startElement( const XML_Char* el, const XML_Char** attr )
|
||||
}
|
||||
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon" )
|
||||
{
|
||||
mCurrentWKBFragments.push_back( QList<unsigned char*>() );
|
||||
mCurrentWKBFragmentSizes.push_back( QList<int>() );
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
}
|
||||
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint" )
|
||||
{
|
||||
mParseModeStack.push( QgsGml::multiPoint );
|
||||
//we need one nested list for intermediate WKB
|
||||
mCurrentWKBFragments.push_back( QList<unsigned char*>() );
|
||||
mCurrentWKBFragmentSizes.push_back( QList<int>() );
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
}
|
||||
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString" )
|
||||
{
|
||||
mParseModeStack.push( QgsGml::multiLine );
|
||||
//we need one nested list for intermediate WKB
|
||||
mCurrentWKBFragments.push_back( QList<unsigned char*>() );
|
||||
mCurrentWKBFragmentSizes.push_back( QList<int>() );
|
||||
mCurrentWKBFragments.push_back( QList<QgsWkbPtr>() );
|
||||
}
|
||||
else if ( elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon" )
|
||||
{
|
||||
@ -384,7 +382,7 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( mCurrentWKB, mCurrentWKBSize );
|
||||
mCurrentFeature->setGeometry( g );
|
||||
mCurrentWKB = nullptr;
|
||||
mCurrentWKB = QgsWkbPtr( nullptr, 0 );
|
||||
}
|
||||
else if ( !mCurrentExtent.isEmpty() )
|
||||
{
|
||||
@ -419,7 +417,7 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
if ( theParseMode == QgsGml::geometry )
|
||||
{
|
||||
//directly add WKB point to the feature
|
||||
if ( getPointWKB( &mCurrentWKB, &mCurrentWKBSize, *( pointList.begin() ) ) != 0 )
|
||||
if ( getPointWKB( mCurrentWKB, *( pointList.begin() ) ) != 0 )
|
||||
{
|
||||
//error
|
||||
}
|
||||
@ -431,23 +429,19 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
}
|
||||
else //multipoint, add WKB as fragment
|
||||
{
|
||||
unsigned char* wkb = nullptr;
|
||||
int wkbSize = 0;
|
||||
QList<unsigned char*> wkbList;
|
||||
QList<int> wkbSizeList;
|
||||
if ( getPointWKB( &wkb, &wkbSize, *( pointList.begin() ) ) != 0 )
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
if ( getPointWKB( wkbPtr, *( pointList.begin() ) ) != 0 )
|
||||
{
|
||||
//error
|
||||
}
|
||||
if ( !mCurrentWKBFragments.isEmpty() )
|
||||
{
|
||||
mCurrentWKBFragments.last().push_back( wkb );
|
||||
mCurrentWKBFragmentSizes.last().push_back( wkbSize );
|
||||
mCurrentWKBFragments.last().push_back( wkbPtr );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "No wkb fragments" );
|
||||
delete [] wkb;
|
||||
delete [] wkbPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -462,7 +456,7 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
}
|
||||
if ( theParseMode == QgsGml::geometry )
|
||||
{
|
||||
if ( getLineWKB( &mCurrentWKB, &mCurrentWKBSize, pointList ) != 0 )
|
||||
if ( getLineWKB( mCurrentWKB, pointList ) != 0 )
|
||||
{
|
||||
//error
|
||||
}
|
||||
@ -474,23 +468,19 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
}
|
||||
else //multiline, add WKB as fragment
|
||||
{
|
||||
unsigned char* wkb = nullptr;
|
||||
int wkbSize = 0;
|
||||
QList<unsigned char*> wkbList;
|
||||
QList<int> wkbSizeList;
|
||||
if ( getLineWKB( &wkb, &wkbSize, pointList ) != 0 )
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
if ( getLineWKB( wkbPtr, pointList ) != 0 )
|
||||
{
|
||||
//error
|
||||
}
|
||||
if ( !mCurrentWKBFragments.isEmpty() )
|
||||
{
|
||||
mCurrentWKBFragments.last().push_back( wkb );
|
||||
mCurrentWKBFragmentSizes.last().push_back( wkbSize );
|
||||
mCurrentWKBFragments.last().push_back( wkbPtr );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( "no wkb fragments" );
|
||||
delete [] wkb;
|
||||
delete [] wkbPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -501,20 +491,20 @@ void QgsGml::endElement( const XML_Char* el )
|
||||
{
|
||||
//error
|
||||
}
|
||||
unsigned char* wkb = nullptr;
|
||||
int wkbSize = 0;
|
||||
if ( getRingWKB( &wkb, &wkbSize, pointList ) != 0 )
|
||||
|
||||
QgsWkbPtr wkbPtr( nullptr, 0 );
|
||||
if ( getRingWKB( wkbPtr, pointList ) != 0 )
|
||||
{
|
||||
//error
|
||||
}
|
||||
|
||||
if ( !mCurrentWKBFragments.isEmpty() )
|
||||
{
|
||||
mCurrentWKBFragments.last().push_back( wkb );
|
||||
mCurrentWKBFragmentSizes.last().push_back( wkbSize );
|
||||
mCurrentWKBFragments.last().push_back( wkbPtr );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] wkb;
|
||||
delete[] wkbPtr;
|
||||
QgsDebugMsg( "no wkb fragments" );
|
||||
}
|
||||
}
|
||||
@ -728,145 +718,94 @@ int QgsGml::pointsFromString( QList<QgsPoint>& points, const QString& coordStrin
|
||||
return 1;
|
||||
}
|
||||
|
||||
int QgsGml::getPointWKB( unsigned char** wkb, int* size, const QgsPoint& point ) const
|
||||
int QgsGml::getPointWKB( QgsWkbPtr &wkbPtr, const QgsPoint& point ) const
|
||||
{
|
||||
int wkbSize = 1 + sizeof( int ) + 2 * sizeof( double );
|
||||
*size = wkbSize;
|
||||
*wkb = new unsigned char[wkbSize];
|
||||
QGis::WkbType type = QGis::WKBPoint;
|
||||
double x = point.x();
|
||||
double y = point.y();
|
||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
fillPtr << mEndian << QGis::WKBPoint << point.x() << point.y();
|
||||
|
||||
memcpy( &( *wkb )[wkbPosition], &mEndian, 1 );
|
||||
wkbPosition += 1;
|
||||
memcpy( &( *wkb )[wkbPosition], &type, sizeof( int ) );
|
||||
wkbPosition += sizeof( int );
|
||||
memcpy( &( *wkb )[wkbPosition], &x, sizeof( double ) );
|
||||
wkbPosition += sizeof( double );
|
||||
memcpy( &( *wkb )[wkbPosition], &y, sizeof( double ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGml::getLineWKB( unsigned char** wkb, int* size, const QList<QgsPoint>& lineCoordinates ) const
|
||||
int QgsGml::getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPoint>& lineCoordinates ) const
|
||||
{
|
||||
int wkbSize = 1 + 2 * sizeof( int ) + lineCoordinates.size() * 2 * sizeof( double );
|
||||
*size = wkbSize;
|
||||
*wkb = new unsigned char[wkbSize];
|
||||
QGis::WkbType type = QGis::WKBLineString;
|
||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||
double x, y;
|
||||
int nPoints = lineCoordinates.size();
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
|
||||
//fill the contents into *wkb
|
||||
memcpy( &( *wkb )[wkbPosition], &mEndian, 1 );
|
||||
wkbPosition += 1;
|
||||
memcpy( &( *wkb )[wkbPosition], &type, sizeof( int ) );
|
||||
wkbPosition += sizeof( int );
|
||||
memcpy( &( *wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
||||
wkbPosition += sizeof( int );
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
|
||||
fillPtr << mEndian << QGis::WKBLineString << lineCoordinates.size();
|
||||
|
||||
QList<QgsPoint>::const_iterator iter;
|
||||
for ( iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter )
|
||||
{
|
||||
x = iter->x();
|
||||
y = iter->y();
|
||||
memcpy( &( *wkb )[wkbPosition], &x, sizeof( double ) );
|
||||
wkbPosition += sizeof( double );
|
||||
memcpy( &( *wkb )[wkbPosition], &y, sizeof( double ) );
|
||||
wkbPosition += sizeof( double );
|
||||
fillPtr << iter->x() << iter->y();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGml::getRingWKB( unsigned char** wkb, int* size, const QList<QgsPoint>& ringCoordinates ) const
|
||||
int QgsGml::getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPoint>& ringCoordinates ) const
|
||||
{
|
||||
int wkbSize = sizeof( int ) + ringCoordinates.size() * 2 * sizeof( double );
|
||||
*size = wkbSize;
|
||||
*wkb = new unsigned char[wkbSize];
|
||||
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
|
||||
double x, y;
|
||||
int nPoints = ringCoordinates.size();
|
||||
memcpy( &( *wkb )[wkbPosition], &nPoints, sizeof( int ) );
|
||||
wkbPosition += sizeof( int );
|
||||
wkbPtr = QgsWkbPtr( new unsigned char[wkbSize], wkbSize );
|
||||
|
||||
QgsWkbPtr fillPtr( wkbPtr );
|
||||
|
||||
fillPtr << ringCoordinates.size();
|
||||
|
||||
QList<QgsPoint>::const_iterator iter;
|
||||
for ( iter = ringCoordinates.begin(); iter != ringCoordinates.end(); ++iter )
|
||||
{
|
||||
x = iter->x();
|
||||
y = iter->y();
|
||||
memcpy( &( *wkb )[wkbPosition], &x, sizeof( double ) );
|
||||
wkbPosition += sizeof( double );
|
||||
memcpy( &( *wkb )[wkbPosition], &y, sizeof( double ) );
|
||||
wkbPosition += sizeof( double );
|
||||
fillPtr << iter->x() << iter->y();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGml::createMultiLineFromFragments()
|
||||
{
|
||||
mCurrentWKBSize = 0;
|
||||
mCurrentWKBSize += 1 + 2 * sizeof( int );
|
||||
mCurrentWKBSize += totalWKBFragmentSize();
|
||||
mCurrentWKBSize = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[mCurrentWKBSize], mCurrentWKBSize );
|
||||
|
||||
mCurrentWKB = new unsigned char[mCurrentWKBSize];
|
||||
int pos = 0;
|
||||
QGis::WkbType type = QGis::WKBMultiLineString;
|
||||
int numLines = mCurrentWKBFragments.begin()->size();
|
||||
//add endian
|
||||
memcpy( &( mCurrentWKB[pos] ), &mEndian, 1 );
|
||||
pos += 1;
|
||||
memcpy( &( mCurrentWKB[pos] ), &type, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
memcpy( &( mCurrentWKB[pos] ), &numLines, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
QList<unsigned char*>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
QList<int>::iterator sizeIt = mCurrentWKBFragmentSizes.begin()->begin();
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB, mCurrentWKBSize );
|
||||
|
||||
wkbPtr << mEndian << QGis::WKBMultiLineString << mCurrentWKBFragments.begin()->size();
|
||||
|
||||
QList<QgsWkbPtr>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
|
||||
//copy (and delete) all the wkb fragments
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt, ++sizeIt )
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt )
|
||||
{
|
||||
memcpy( &( mCurrentWKB[pos] ), *wkbIt, *sizeIt );
|
||||
pos += *sizeIt;
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
mCurrentWKBFragmentSizes.clear();
|
||||
*mWkbType = QGis::WKBMultiLineString;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsGml::createMultiPointFromFragments()
|
||||
{
|
||||
mCurrentWKBSize = 0;
|
||||
mCurrentWKBSize += 1 + 2 * sizeof( int );
|
||||
mCurrentWKBSize += totalWKBFragmentSize();
|
||||
mCurrentWKB = new unsigned char[mCurrentWKBSize];
|
||||
mCurrentWKBSize = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[mCurrentWKBSize], mCurrentWKBSize );
|
||||
|
||||
int pos = 0;
|
||||
QGis::WkbType type = QGis::WKBMultiPoint;
|
||||
int numPoints = mCurrentWKBFragments.begin()->size();
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << mEndian << QGis::WKBMultiPoint << mCurrentWKBFragments.begin()->size();
|
||||
|
||||
memcpy( &( mCurrentWKB[pos] ), &mEndian, 1 );
|
||||
pos += 1;
|
||||
memcpy( &( mCurrentWKB[pos] ), &type, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
memcpy( &( mCurrentWKB[pos] ), &numPoints, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
|
||||
QList<unsigned char*>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
QList<int>::iterator sizeIt = mCurrentWKBFragmentSizes.begin()->begin();
|
||||
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt, ++sizeIt )
|
||||
QList<QgsWkbPtr>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt )
|
||||
{
|
||||
memcpy( &( mCurrentWKB[pos] ), *wkbIt, *sizeIt );
|
||||
pos += *sizeIt;
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
mCurrentWKBFragmentSizes.clear();
|
||||
*mWkbType = QGis::WKBMultiPoint;
|
||||
return 0;
|
||||
}
|
||||
@ -874,32 +813,21 @@ int QgsGml::createMultiPointFromFragments()
|
||||
|
||||
int QgsGml::createPolygonFromFragments()
|
||||
{
|
||||
mCurrentWKBSize = 0;
|
||||
mCurrentWKBSize += 1 + 2 * sizeof( int );
|
||||
mCurrentWKBSize += totalWKBFragmentSize();
|
||||
mCurrentWKBSize = 1 + 2 * sizeof( int ) + totalWKBFragmentSize();
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[mCurrentWKBSize], mCurrentWKBSize );
|
||||
|
||||
mCurrentWKB = new unsigned char[mCurrentWKBSize];
|
||||
int pos = 0;
|
||||
QGis::WkbType type = QGis::WKBPolygon;
|
||||
int numRings = mCurrentWKBFragments.begin()->size();
|
||||
memcpy( &( mCurrentWKB[pos] ), &mEndian, 1 );
|
||||
pos += 1;
|
||||
memcpy( &( mCurrentWKB[pos] ), &type, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
memcpy( &( mCurrentWKB[pos] ), &numRings, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << mEndian << QGis::WKBPolygon << mCurrentWKBFragments.begin()->size();
|
||||
|
||||
QList<unsigned char*>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
QList<int>::iterator sizeIt = mCurrentWKBFragmentSizes.begin()->begin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt, ++sizeIt )
|
||||
QList<QgsWkbPtr>::iterator wkbIt = mCurrentWKBFragments.begin()->begin();
|
||||
for ( ; wkbIt != mCurrentWKBFragments.begin()->end(); ++wkbIt )
|
||||
{
|
||||
memcpy( &( mCurrentWKB[pos] ), *wkbIt, *sizeIt );
|
||||
pos += *sizeIt;
|
||||
memcpy( wkbPtr, *wkbIt, wkbIt->size() );
|
||||
wkbPtr += wkbIt->size();
|
||||
delete[] *wkbIt;
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
mCurrentWKBFragmentSizes.clear();
|
||||
*mWkbType = QGis::WKBPolygon;
|
||||
return 0;
|
||||
}
|
||||
@ -911,51 +839,29 @@ int QgsGml::createMultiPolygonFromFragments()
|
||||
mCurrentWKBSize += totalWKBFragmentSize();
|
||||
mCurrentWKBSize += mCurrentWKBFragments.size() * ( 1 + 2 * sizeof( int ) ); //fragments are just the rings
|
||||
|
||||
mCurrentWKB = new unsigned char[mCurrentWKBSize];
|
||||
int pos = 0;
|
||||
QGis::WkbType type = QGis::WKBMultiPolygon;
|
||||
QGis::WkbType polygonType = QGis::WKBPolygon;
|
||||
int numPolys = mCurrentWKBFragments.size();
|
||||
int numRings;
|
||||
memcpy( &( mCurrentWKB[pos] ), &mEndian, 1 );
|
||||
pos += 1;
|
||||
memcpy( &( mCurrentWKB[pos] ), &type, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
memcpy( &( mCurrentWKB[pos] ), &numPolys, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
mCurrentWKB = QgsWkbPtr( new unsigned char[mCurrentWKBSize], mCurrentWKBSize );
|
||||
|
||||
QgsWkbPtr wkbPtr( mCurrentWKB );
|
||||
wkbPtr << ( char ) mEndian << QGis::WKBMultiPolygon << mCurrentWKBFragments.size();
|
||||
|
||||
//have outer and inner iterators
|
||||
QList< QList<unsigned char*> >::iterator outerWkbIt;
|
||||
QList< QList<int> >::iterator outerSizeIt;
|
||||
QList< unsigned char* >::iterator innerWkbIt;
|
||||
QList< int >::iterator innerSizeIt;
|
||||
QList< QList<QgsWkbPtr> >::iterator outerWkbIt = mCurrentWKBFragments.begin();
|
||||
|
||||
outerWkbIt = mCurrentWKBFragments.begin();
|
||||
outerSizeIt = mCurrentWKBFragmentSizes.begin();
|
||||
|
||||
for ( ; outerWkbIt != mCurrentWKBFragments.end(); ++outerWkbIt, ++outerSizeIt )
|
||||
for ( ; outerWkbIt != mCurrentWKBFragments.end(); ++outerWkbIt )
|
||||
{
|
||||
//new polygon
|
||||
memcpy( &( mCurrentWKB[pos] ), &mEndian, 1 );
|
||||
pos += 1;
|
||||
memcpy( &( mCurrentWKB[pos] ), &polygonType, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
numRings = outerWkbIt->size();
|
||||
memcpy( &( mCurrentWKB[pos] ), &numRings, sizeof( int ) );
|
||||
pos += sizeof( int );
|
||||
wkbPtr << ( char ) mEndian << QGis::WKBPolygon << outerWkbIt->size();
|
||||
|
||||
innerWkbIt = outerWkbIt->begin();
|
||||
innerSizeIt = outerSizeIt->begin();
|
||||
for ( ; innerWkbIt != outerWkbIt->end(); ++innerWkbIt, ++innerSizeIt )
|
||||
QList<QgsWkbPtr>::iterator innerWkbIt = outerWkbIt->begin();
|
||||
for ( ; innerWkbIt != outerWkbIt->end(); ++innerWkbIt )
|
||||
{
|
||||
memcpy( &( mCurrentWKB[pos] ), *innerWkbIt, *innerSizeIt );
|
||||
pos += *innerSizeIt;
|
||||
memcpy( wkbPtr, *innerWkbIt, innerWkbIt->size() );
|
||||
wkbPtr += innerWkbIt->size();
|
||||
delete[] *innerWkbIt;
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentWKBFragments.clear();
|
||||
mCurrentWKBFragmentSizes.clear();
|
||||
*mWkbType = QGis::WKBMultiPolygon;
|
||||
return 0;
|
||||
}
|
||||
@ -963,11 +869,11 @@ int QgsGml::createMultiPolygonFromFragments()
|
||||
int QgsGml::totalWKBFragmentSize() const
|
||||
{
|
||||
int result = 0;
|
||||
Q_FOREACH ( const QList<int> &list, mCurrentWKBFragmentSizes )
|
||||
Q_FOREACH ( const QList<QgsWkbPtr> &list, mCurrentWKBFragments )
|
||||
{
|
||||
Q_FOREACH ( int i, list )
|
||||
Q_FOREACH ( const QgsWkbPtr &i, list )
|
||||
{
|
||||
result += i;
|
||||
result += i.size();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgspoint.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
@ -164,9 +165,9 @@ class CORE_EXPORT QgsGml : public QObject
|
||||
int pointsFromPosListString( QList<QgsPoint>& points, const QString& coordString, int dimension ) const;
|
||||
|
||||
int pointsFromString( QList<QgsPoint>& points, const QString& coordString ) const;
|
||||
int getPointWKB( unsigned char** wkb, int* size, const QgsPoint& ) const;
|
||||
int getLineWKB( unsigned char** wkb, int* size, const QList<QgsPoint>& lineCoordinates ) const;
|
||||
int getRingWKB( unsigned char** wkb, int* size, const QList<QgsPoint>& ringCoordinates ) const;
|
||||
int getPointWKB( QgsWkbPtr &wkbPtr, const QgsPoint& ) const;
|
||||
int getLineWKB( QgsWkbPtr &wkbPtr, const QList<QgsPoint>& lineCoordinates ) const;
|
||||
int getRingWKB( QgsWkbPtr &wkbPtr, const QList<QgsPoint>& ringCoordinates ) const;
|
||||
/** Creates a multiline from the information in mCurrentWKBFragments and
|
||||
* mCurrentWKBFragmentSizes. Assign the result. The multiline is in
|
||||
* mCurrentWKB and mCurrentWKBSize. The function deletes the memory in
|
||||
@ -224,7 +225,7 @@ class CORE_EXPORT QgsGml : public QObject
|
||||
QString mCurrentFeatureId;
|
||||
int mFeatureCount;
|
||||
/** The total WKB for a feature*/
|
||||
unsigned char* mCurrentWKB;
|
||||
QgsWkbPtr mCurrentWKB;
|
||||
/** The total WKB size for a feature*/
|
||||
int mCurrentWKBSize;
|
||||
QgsRectangle mCurrentExtent;
|
||||
@ -232,9 +233,7 @@ class CORE_EXPORT QgsGml : public QObject
|
||||
* intermediate WKB is stored at all. For multipoints and multilines and
|
||||
* polygons, only one nested list is used. For multipolygons, both nested lists
|
||||
* are used*/
|
||||
QList< QList<unsigned char*> > mCurrentWKBFragments;
|
||||
/** Similar to mCurrentWKB, but only the size*/
|
||||
QList< QList<int> > mCurrentWKBFragmentSizes;
|
||||
QList< QList<QgsWkbPtr> > mCurrentWKBFragments;
|
||||
QString mAttributeName;
|
||||
QgsApplication::endian_t mEndian;
|
||||
/** Coordinate separator for coordinate strings. Usually "," */
|
||||
|
@ -15,26 +15,11 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "qgsmaptopixelgeometrysimplifier.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
class QgsParserException: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
QgsParserException( const QString &msg )
|
||||
: std::runtime_error( msg.toStdString() )
|
||||
{}
|
||||
};
|
||||
|
||||
class QgsShortWkbException: public QgsParserException
|
||||
{
|
||||
public:
|
||||
QgsShortWkbException( const QString &msg )
|
||||
: QgsParserException( QString( "Premature end of WKB: " ) + msg )
|
||||
{}
|
||||
};
|
||||
|
||||
QgsMapToPixelSimplifier::QgsMapToPixelSimplifier( int simplifyFlags, double tolerance )
|
||||
: mSimplifyFlags( simplifyFlags )
|
||||
@ -59,21 +44,19 @@ float QgsMapToPixelSimplifier::calculateLengthSquared2D( double x1, double y1, d
|
||||
}
|
||||
|
||||
//! Returns the BBOX of the specified WKB-point stream
|
||||
inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, const unsigned char* wkb, int numPoints )
|
||||
inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, QgsConstWkbPtr wkbPtr, int numPoints )
|
||||
{
|
||||
double x, y;
|
||||
QgsRectangle r;
|
||||
r.setMinimal();
|
||||
|
||||
int sizeOfDoubleX = sizeof( double );
|
||||
int sizeOfDoubleY = ( QGis::wkbDimensions( wkbType ) - 1 ) * sizeof( double );
|
||||
int skipZM = ( QGis::wkbDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
Q_ASSERT( skipZM >= 0 );
|
||||
|
||||
for ( int i = 0; i < numPoints; ++i )
|
||||
{
|
||||
memcpy( &x, wkb, sizeof( double ) );
|
||||
wkb += sizeOfDoubleX;
|
||||
memcpy( &y, wkb, sizeof( double ) );
|
||||
wkb += sizeOfDoubleY;
|
||||
double x, y;
|
||||
wkbPtr >> x >> y;
|
||||
wkbPtr += skipZM;
|
||||
r.combineExtentWith( x, y );
|
||||
}
|
||||
|
||||
@ -83,24 +66,24 @@ inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, const un
|
||||
//! Generalize the WKB-geometry using the BBOX of the original geometry
|
||||
static bool generalizeWkbGeometryByBoundingBox(
|
||||
QGis::WkbType wkbType,
|
||||
const unsigned char *sourceWkb, int sourceWkbSize,
|
||||
unsigned char *targetWkb, int &targetWkbSize,
|
||||
QgsConstWkbPtr sourceWkbPtr,
|
||||
QgsWkbPtr targetWkbPtr,
|
||||
int &targetWkbSize,
|
||||
const QgsRectangle &envelope, bool writeHeader )
|
||||
{
|
||||
Q_UNUSED( sourceWkb );
|
||||
unsigned char* wkb2 = targetWkb;
|
||||
QgsWkbPtr savedTargetWkb( targetWkbPtr );
|
||||
unsigned int geometryType = QGis::singleType( QGis::flatType( wkbType ) );
|
||||
|
||||
int sizeOfDoubleX = sizeof( double );
|
||||
int sizeOfDoubleY = sizeof( double ) * ( QGis::wkbDimensions( wkbType ) - 1 );
|
||||
int skipZM = ( QGis::wkbDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
Q_ASSERT( skipZM >= 0 );
|
||||
|
||||
// If the geometry is already minimal skip the generalization
|
||||
int minimumSize = geometryType == QGis::WKBLineString ? 4 + 2 * ( sizeOfDoubleX + sizeOfDoubleY ) : 8 + 5 * ( sizeOfDoubleX + sizeOfDoubleY );
|
||||
int minimumSize = geometryType == QGis::WKBLineString ? 4 + 2 * ( 2 * sizeof( double ) + skipZM ) : 8 + 5 * ( 2 * sizeof( double ) + skipZM );
|
||||
|
||||
if ( writeHeader )
|
||||
minimumSize += 5;
|
||||
|
||||
if ( sourceWkbSize <= minimumSize )
|
||||
if ( sourceWkbPtr.remaining() <= minimumSize )
|
||||
{
|
||||
targetWkbSize = 0;
|
||||
return false;
|
||||
@ -114,70 +97,25 @@ static bool generalizeWkbGeometryByBoundingBox(
|
||||
// Write the main header of the geometry
|
||||
if ( writeHeader )
|
||||
{
|
||||
char byteOrder = QgsApplication::endian(); // byteOrder
|
||||
memcpy( targetWkb, &byteOrder, 1 );
|
||||
targetWkb += 1;
|
||||
|
||||
memcpy( targetWkb, &geometryType, 4 ); // type
|
||||
targetWkb += 4;
|
||||
targetWkbPtr << ( char ) QgsApplication::endian() << geometryType;
|
||||
|
||||
if ( geometryType == QGis::WKBPolygon ) // numRings
|
||||
{
|
||||
int numRings = 1;
|
||||
memcpy( targetWkb, &numRings, 4 );
|
||||
targetWkb += 4;
|
||||
targetWkbPtr << 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the generalized geometry
|
||||
if ( geometryType == QGis::WKBLineString )
|
||||
{
|
||||
int numPoints = 2;
|
||||
memcpy( targetWkb, &numPoints, 4 ); // numPoints;
|
||||
targetWkb += 4;
|
||||
|
||||
memcpy( targetWkb, &x1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
|
||||
memcpy( targetWkb, &x2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
targetWkbPtr << 2 << x1 << y1 << x2 << y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numPoints = 5;
|
||||
memcpy( targetWkb, &numPoints, 4 ); // numPoints;
|
||||
targetWkb += 4;
|
||||
|
||||
memcpy( targetWkb, &x1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
|
||||
memcpy( targetWkb, &x2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
|
||||
memcpy( targetWkb, &x2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
|
||||
memcpy( targetWkb, &x1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y2, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
|
||||
memcpy( targetWkb, &x1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
memcpy( targetWkb, &y1, sizeof( double ) );
|
||||
targetWkb += sizeof( double );
|
||||
targetWkbPtr << 5 << x1 << y1 << x2 << y1 << x2 << y2 << x1 << y2 << x1 << y1;
|
||||
}
|
||||
targetWkbSize += targetWkb - wkb2;
|
||||
|
||||
targetWkbSize += targetWkbPtr - savedTargetWkb;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -185,8 +123,9 @@ static bool generalizeWkbGeometryByBoundingBox(
|
||||
//! Simplify the WKB-geometry using the specified tolerance
|
||||
bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
int simplifyFlags, QGis::WkbType wkbType,
|
||||
const unsigned char *sourceWkb, int sourceWkbSize,
|
||||
unsigned char *targetWkb, int &targetWkbSize,
|
||||
QgsConstWkbPtr sourceWkbPtr,
|
||||
QgsWkbPtr targetWkbPtr,
|
||||
int &targetWkbSize,
|
||||
const QgsRectangle &envelope, double map2pixelTol,
|
||||
bool writeHeader, bool isaLinearRing )
|
||||
{
|
||||
@ -194,17 +133,15 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
bool result = false;
|
||||
|
||||
// Save initial WKB settings to use when the simplification creates invalid geometries
|
||||
const unsigned char* sourcePrevWkb = sourceWkb;
|
||||
unsigned char* targetPrevWkb = targetWkb;
|
||||
QgsConstWkbPtr sourcePrevWkbPtr( sourceWkbPtr );
|
||||
QgsWkbPtr targetPrevWkbPtr( targetWkbPtr );
|
||||
int targetWkbPrevSize = targetWkbSize;
|
||||
|
||||
const unsigned char* endOfSourceWkb = sourceWkb + sourceWkbSize;
|
||||
|
||||
// Can replace the geometry by its BBOX ?
|
||||
if (( simplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) &&
|
||||
isGeneralizableByMapBoundingBox( envelope, map2pixelTol ) )
|
||||
{
|
||||
isGeneralizable = generalizeWkbGeometryByBoundingBox( wkbType, sourceWkb, sourceWkbSize, targetWkb, targetWkbSize, envelope, writeHeader );
|
||||
isGeneralizable = generalizeWkbGeometryByBoundingBox( wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize, envelope, writeHeader );
|
||||
if ( isGeneralizable )
|
||||
return true;
|
||||
}
|
||||
@ -215,52 +152,38 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
// Write the main header of the geometry
|
||||
if ( writeHeader )
|
||||
{
|
||||
if ( sourceWkbSize < 5 )
|
||||
throw QgsParserException( QString( "Premature end of WKB reading header " ) );
|
||||
QgsWKBTypes::Type geometryType = sourceWkbPtr.readHeader();
|
||||
|
||||
targetWkb[0] = sourceWkb[0]; // byteOrder
|
||||
sourceWkb += 1;
|
||||
targetWkb += 1;
|
||||
targetWkbPtr << ( char ) QgsApplication::endian() << QgsWKBTypes::flatType( geometryType );
|
||||
|
||||
int geometryType;
|
||||
memcpy( &geometryType, sourceWkb, 4 );
|
||||
int flatType = QGis::flatType( static_cast< QGis::WkbType >( geometryType ) );
|
||||
memcpy( targetWkb, &flatType, 4 ); // type
|
||||
sourceWkb += 4;
|
||||
targetWkb += 4;
|
||||
|
||||
targetWkbSize += 5;
|
||||
targetWkbSize += targetWkbPtr - targetPrevWkbPtr;
|
||||
}
|
||||
|
||||
const unsigned char* wkb1 = sourceWkb;
|
||||
unsigned char* wkb2 = targetWkb;
|
||||
unsigned int flatType = QGis::flatType( wkbType );
|
||||
|
||||
// Write the geometry
|
||||
if ( flatType == QGis::WKBLineString || isaLinearRing )
|
||||
{
|
||||
QgsWkbPtr savedTargetWkbPtr( targetWkbPtr );
|
||||
double x, y, lastX = 0, lastY = 0;
|
||||
QgsRectangle r;
|
||||
r.setMinimal();
|
||||
|
||||
int sizeOfDoubleX = sizeof( double );
|
||||
int sizeOfDoubleY = ( QGis::wkbDimensions( wkbType ) - 1 ) * sizeof( double );
|
||||
|
||||
if ( sourceWkb + 4 >= endOfSourceWkb )
|
||||
throw QgsShortWkbException( "reading numPoints" );
|
||||
int skipZM = ( QGis::wkbDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
Q_ASSERT( skipZM >= 0 );
|
||||
|
||||
int numPoints;
|
||||
memcpy( &numPoints, sourceWkb, 4 );
|
||||
sourceWkb += 4;
|
||||
sourceWkbPtr >> numPoints;
|
||||
|
||||
if ( numPoints <= ( isaLinearRing ? 5 : 2 ) )
|
||||
isGeneralizable = false;
|
||||
|
||||
QgsWkbPtr numPtr( targetWkbPtr );
|
||||
|
||||
int numTargetPoints = 0;
|
||||
memcpy( targetWkb, &numTargetPoints, 4 );
|
||||
targetWkb += 4;
|
||||
targetWkbPtr << numTargetPoints;
|
||||
targetWkbSize += 4;
|
||||
|
||||
double* ptr = reinterpret_cast< double* >( targetWkb );
|
||||
map2pixelTol *= map2pixelTol; //-> Use mappixelTol for 'LengthSquare' calculations.
|
||||
|
||||
bool isLongSegment;
|
||||
@ -269,21 +192,13 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
// Check whether the LinearRing is really closed.
|
||||
if ( isaLinearRing )
|
||||
{
|
||||
QgsConstWkbPtr checkPtr( sourceWkbPtr );
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
const unsigned char* startWkbX = sourceWkb;
|
||||
const unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
|
||||
const unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
|
||||
const unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
|
||||
|
||||
if ( finalWkbY + sizeof( double ) > endOfSourceWkb )
|
||||
throw QgsShortWkbException( "reading last point" );
|
||||
|
||||
|
||||
memcpy( &x1, startWkbX, sizeof( double ) );
|
||||
memcpy( &y1, startWkbY, sizeof( double ) );
|
||||
memcpy( &x2, finalWkbX, sizeof( double ) );
|
||||
memcpy( &y2, finalWkbY, sizeof( double ) );
|
||||
checkPtr >> x1 >> y1;
|
||||
checkPtr += skipZM + ( numPoints - 1 ) * ( 2 * sizeof( double ) + skipZM );
|
||||
checkPtr >> x2 >> y2;
|
||||
|
||||
isaLinearRing = qgsDoubleNear( x1, x2 ) && qgsDoubleNear( y1, y2 );
|
||||
}
|
||||
@ -291,15 +206,8 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
// Process each vertex...
|
||||
for ( int i = 0; i < numPoints; ++i )
|
||||
{
|
||||
if ( sourceWkb + sizeOfDoubleX + sizeOfDoubleY > endOfSourceWkb )
|
||||
{
|
||||
throw QgsParserException( QString( "Premature end of WKB reading point %1/%2" ) .arg( i + 1 ) .arg( numPoints ) );
|
||||
}
|
||||
|
||||
memcpy( &x, sourceWkb, sizeof( double ) );
|
||||
sourceWkb += sizeOfDoubleX;
|
||||
memcpy( &y, sourceWkb, sizeof( double ) );
|
||||
sourceWkb += sizeOfDoubleY;
|
||||
sourceWkbPtr >> x >> y;
|
||||
sourceWkbPtr += skipZM;
|
||||
|
||||
isLongSegment = false;
|
||||
|
||||
@ -308,12 +216,9 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
( isLongSegment = ( calculateLengthSquared2D( x, y, lastX, lastY ) > map2pixelTol ) ) ||
|
||||
( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
|
||||
{
|
||||
memcpy( ptr, &x, sizeof( double ) );
|
||||
targetWkbPtr << x << y;
|
||||
lastX = x;
|
||||
ptr++;
|
||||
memcpy( ptr, &y, sizeof( double ) );
|
||||
lastY = y;
|
||||
ptr++;
|
||||
numTargetPoints++;
|
||||
|
||||
hasLongSegments |= isLongSegment;
|
||||
@ -321,7 +226,11 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
|
||||
r.combineExtentWith( x, y );
|
||||
}
|
||||
targetWkb = wkb2 + 4;
|
||||
|
||||
QgsWkbPtr nextPointPtr( targetWkbPtr );
|
||||
|
||||
targetWkbPtr = savedTargetWkbPtr;
|
||||
targetWkbPtr += sizeof( int );
|
||||
|
||||
if ( numTargetPoints < ( isaLinearRing ? 4 : 2 ) )
|
||||
{
|
||||
@ -330,16 +239,16 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
{
|
||||
// approximate the geometry's shape by its bounding box
|
||||
// (rect for linear ring / one segment for line string)
|
||||
unsigned char* targetTempWkb = targetWkb;
|
||||
QgsWkbPtr tempWkbPtr( targetWkbPtr );
|
||||
int targetWkbTempSize = targetWkbSize;
|
||||
|
||||
sourceWkb = sourcePrevWkb;
|
||||
targetWkb = targetPrevWkb;
|
||||
sourceWkbPtr = sourcePrevWkbPtr;
|
||||
targetWkbPtr = targetPrevWkbPtr;
|
||||
targetWkbSize = targetWkbPrevSize;
|
||||
if ( generalizeWkbGeometryByBoundingBox( wkbType, sourceWkb, sourceWkbSize, targetWkb, targetWkbSize, r, writeHeader ) )
|
||||
if ( generalizeWkbGeometryByBoundingBox( wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize, r, writeHeader ) )
|
||||
return true;
|
||||
|
||||
targetWkb = targetTempWkb;
|
||||
targetWkbPtr = tempWkbPtr;
|
||||
targetWkbSize = targetWkbTempSize;
|
||||
}
|
||||
else
|
||||
@ -351,48 +260,45 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
// other pieces of QGIS will survive that :-/
|
||||
}
|
||||
}
|
||||
|
||||
if ( isaLinearRing )
|
||||
{
|
||||
// make sure we keep the linear ring closed
|
||||
memcpy( &x, targetWkb + 0, sizeof( double ) );
|
||||
memcpy( &y, targetWkb + sizeof( double ), sizeof( double ) );
|
||||
targetWkbPtr << x << y;
|
||||
if ( !qgsDoubleNear( lastX, x ) || !qgsDoubleNear( lastY, y ) )
|
||||
{
|
||||
memcpy( ptr, &x, sizeof( double ) );
|
||||
ptr++;
|
||||
memcpy( ptr, &y, sizeof( double ) );
|
||||
ptr++;
|
||||
nextPointPtr << x << y;
|
||||
numTargetPoints++;
|
||||
}
|
||||
}
|
||||
targetWkbSize += numTargetPoints * sizeof( double ) * 2;
|
||||
targetWkb = wkb2;
|
||||
|
||||
memcpy( targetWkb, &numTargetPoints, 4 );
|
||||
numPtr << numTargetPoints;
|
||||
targetWkbSize += numTargetPoints * sizeof( double ) * 2;
|
||||
|
||||
result = numPoints != numTargetPoints;
|
||||
}
|
||||
else if ( flatType == QGis::WKBPolygon )
|
||||
{
|
||||
int numRings;
|
||||
memcpy( &numRings, sourceWkb, 4 );
|
||||
sourceWkb += 4;
|
||||
|
||||
memcpy( targetWkb, &numRings, 4 );
|
||||
targetWkb += 4;
|
||||
sourceWkbPtr >> numRings;
|
||||
targetWkbPtr << numRings;
|
||||
targetWkbSize += 4;
|
||||
|
||||
for ( int i = 0; i < numRings; ++i )
|
||||
{
|
||||
int numPoints_i;
|
||||
memcpy( &numPoints_i, sourceWkb, 4 );
|
||||
QgsRectangle envelope_i = numRings == 1 ? envelope : calculateBoundingBox( wkbType, sourceWkb + 4, numPoints_i );
|
||||
sourceWkbPtr >> numPoints_i;
|
||||
|
||||
int sourceWkbSize_i = 4 + numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
QgsRectangle envelope_i = numRings == 1 ? envelope : calculateBoundingBox( wkbType, sourceWkbPtr, numPoints_i );
|
||||
|
||||
sourceWkbPtr -= sizeof( int );
|
||||
|
||||
int sourceWkbSize_i = sizeof( int ) + numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
int targetWkbSize_i = 0;
|
||||
|
||||
result |= simplifyWkbGeometry( simplifyFlags, wkbType, sourceWkb, sourceWkbSize_i, targetWkb, targetWkbSize_i, envelope_i, map2pixelTol, false, true );
|
||||
sourceWkb += sourceWkbSize_i;
|
||||
targetWkb += targetWkbSize_i;
|
||||
result |= simplifyWkbGeometry( simplifyFlags, wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope_i, map2pixelTol, false, true );
|
||||
sourceWkbPtr += sourceWkbSize_i;
|
||||
targetWkbPtr += targetWkbSize_i;
|
||||
|
||||
targetWkbSize += targetWkbSize_i;
|
||||
}
|
||||
@ -400,53 +306,55 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
else if ( flatType == QGis::WKBMultiLineString || flatType == QGis::WKBMultiPolygon )
|
||||
{
|
||||
int numGeoms;
|
||||
memcpy( &numGeoms, sourceWkb, 4 );
|
||||
sourceWkb += 4;
|
||||
wkb1 += 4;
|
||||
|
||||
memcpy( targetWkb, &numGeoms, 4 );
|
||||
targetWkb += 4;
|
||||
sourceWkbPtr >> numGeoms;
|
||||
targetWkbPtr << numGeoms;
|
||||
targetWkbSize += 4;
|
||||
|
||||
QgsConstWkbPtr sourceWkbPtr2( sourceWkbPtr );
|
||||
|
||||
for ( int i = 0; i < numGeoms; ++i )
|
||||
{
|
||||
int sourceWkbSize_i = 0;
|
||||
int targetWkbSize_i = 0;
|
||||
|
||||
sourceWkbPtr2.readHeader();
|
||||
|
||||
// ... calculate the wkb-size of the current child complex geometry
|
||||
if ( flatType == QGis::WKBMultiLineString )
|
||||
{
|
||||
int numPoints_i;
|
||||
memcpy( &numPoints_i, wkb1 + 5, 4 );
|
||||
int wkbSize_i = 4 + numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
sourceWkbPtr2 >> numPoints_i;
|
||||
|
||||
sourceWkbSize_i += 5 + wkbSize_i;
|
||||
wkb1 += 5 + wkbSize_i;
|
||||
int wkbSize_i = numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
|
||||
sourceWkbSize_i += 9 + wkbSize_i;
|
||||
sourceWkbPtr2 += wkbSize_i;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numPrings_i;
|
||||
memcpy( &numPrings_i, wkb1 + 5, 4 );
|
||||
sourceWkbSize_i = 9;
|
||||
wkb1 += 9;
|
||||
sourceWkbPtr2 >> numPrings_i;
|
||||
sourceWkbSize_i = 1 + 2 * sizeof( int );
|
||||
|
||||
for ( int j = 0; j < numPrings_i; ++j )
|
||||
{
|
||||
int numPoints_i;
|
||||
memcpy( &numPoints_i, wkb1, 4 );
|
||||
int wkbSize_i = 4 + numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
sourceWkbPtr2 >> numPoints_i;
|
||||
|
||||
sourceWkbSize_i += wkbSize_i;
|
||||
wkb1 += wkbSize_i;
|
||||
int wkbSize_i = numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
|
||||
sourceWkbSize_i += 4 + wkbSize_i;
|
||||
sourceWkbPtr2 += wkbSize_i;
|
||||
}
|
||||
}
|
||||
result |= simplifyWkbGeometry( simplifyFlags, QGis::singleType( wkbType ), sourceWkb, endOfSourceWkb - sourceWkb, targetWkb, targetWkbSize_i, envelope, map2pixelTol, true, false );
|
||||
sourceWkb += sourceWkbSize_i;
|
||||
targetWkb += targetWkbSize_i;
|
||||
result |= simplifyWkbGeometry( simplifyFlags, QGis::singleType( wkbType ), sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope, map2pixelTol, true, false );
|
||||
sourceWkbPtr += sourceWkbSize_i;
|
||||
targetWkbPtr += targetWkbSize_i;
|
||||
|
||||
targetWkbSize += targetWkbSize_i;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -465,7 +373,7 @@ QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
|
||||
QgsGeometry* g = new QgsGeometry();
|
||||
|
||||
int wkbSize = geometry->wkbSize();
|
||||
unsigned char* wkb = reinterpret_cast< unsigned char* >( malloc( wkbSize ) );
|
||||
unsigned char* wkb = new unsigned char[ wkbSize ];
|
||||
memcpy( wkb, geometry->asWkb(), wkbSize );
|
||||
g->fromWkb( wkb, wkbSize );
|
||||
simplifyGeometry( g, mSimplifyFlags, mTolerance );
|
||||
@ -474,7 +382,7 @@ QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
|
||||
}
|
||||
|
||||
//! Simplifies the geometry (Removing duplicated points) when is applied the specified map2pixel context
|
||||
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance )
|
||||
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry *geometry, int simplifyFlags, double tolerance )
|
||||
{
|
||||
int finalWkbSize = 0;
|
||||
|
||||
@ -486,24 +394,24 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simpl
|
||||
QgsRectangle envelope = geometry->boundingBox();
|
||||
QGis::WkbType wkbType = geometry->wkbType();
|
||||
|
||||
const unsigned char* wkb = geometry->asWkb();
|
||||
int wkbSize = geometry->wkbSize();
|
||||
QgsConstWkbPtr wkbPtr( geometry->asWkb(), geometry->wkbSize() );
|
||||
|
||||
unsigned char* targetWkb = new unsigned char[wkbSize];
|
||||
memcpy( targetWkb, wkb, wkbSize );
|
||||
unsigned char* targetWkb = new unsigned char[wkbPtr.remaining()];
|
||||
memcpy( targetWkb, wkbPtr, wkbPtr.remaining() );
|
||||
QgsWkbPtr targetWkbPtr( targetWkb, wkbPtr.remaining() );
|
||||
|
||||
try
|
||||
{
|
||||
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, targetWkb, finalWkbSize, envelope, tolerance ) )
|
||||
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkbPtr, targetWkbPtr, finalWkbSize, envelope, tolerance ) )
|
||||
{
|
||||
unsigned char* finalWkb = new unsigned char[finalWkbSize];
|
||||
unsigned char *finalWkb = new unsigned char[finalWkbSize];
|
||||
memcpy( finalWkb, targetWkb, finalWkbSize );
|
||||
geometry->fromWkb( finalWkb, finalWkbSize );
|
||||
delete [] targetWkb;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch ( const QgsParserException &e )
|
||||
catch ( const QgsWkbException &e )
|
||||
{
|
||||
QgsDebugMsg( QString( "Exception thrown by simplifier: %1" ) .arg( e.what() ) );
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
|
||||
|
||||
private:
|
||||
//! Simplify the WKB-geometry using the specified tolerance
|
||||
static bool simplifyWkbGeometry( int simplifyFlags, QGis::WkbType wkbType, const unsigned char* sourceWkb, int sourceWkbSize, unsigned char* targetWkb, int &targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
|
||||
static bool simplifyWkbGeometry( int simplifyFlags, QGis::WkbType wkbType, QgsConstWkbPtr sourceWkbPtr, QgsWkbPtr targetWkbPtr, int &targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
|
||||
|
||||
protected:
|
||||
//! Current simplification flags
|
||||
|
@ -1080,7 +1080,8 @@ QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry* geometry, QDomDocumen
|
||||
|
||||
bool hasZValue = false;
|
||||
|
||||
QgsConstWkbPtr wkbPtr( geometry->asWkb() + 1 + sizeof( int ) );
|
||||
QgsConstWkbPtr wkbPtr( geometry->asWkb(), geometry->wkbSize() );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
if ( format == "GML3" )
|
||||
{
|
||||
@ -1135,11 +1136,12 @@ QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry* geometry, QDomDocumen
|
||||
|
||||
for ( int idx = 0; idx < nPoints; ++idx )
|
||||
{
|
||||
wkbPtr += 1 + sizeof( int );
|
||||
QDomElement pointMemberElem = doc.createElement( "gml:pointMember" );
|
||||
QDomElement pointElem = doc.createElement( "gml:Point" );
|
||||
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
|
||||
|
||||
wkbPtr.readHeader();
|
||||
|
||||
double x, y;
|
||||
wkbPtr >> x >> y;
|
||||
QDomText coordText = doc.createTextNode( qgsDoubleToString( x, precision ) + cs + qgsDoubleToString( y, precision ) );
|
||||
@ -1206,7 +1208,8 @@ QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry* geometry, QDomDocumen
|
||||
{
|
||||
QDomElement lineStringMemberElem = doc.createElement( "gml:lineStringMember" );
|
||||
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
|
||||
wkbPtr += 1 + sizeof( int ); // skip type since we know its 2
|
||||
|
||||
wkbPtr.readHeader();
|
||||
|
||||
int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
@ -1312,7 +1315,7 @@ QDomElement QgsOgcUtils::geometryToGML( const QgsGeometry* geometry, QDomDocumen
|
||||
QDomElement polygonMemberElem = doc.createElement( "gml:polygonMember" );
|
||||
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
|
||||
|
||||
wkbPtr += 1 + sizeof( int );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
int numRings;
|
||||
wkbPtr >> numRings;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgswkbptr.h"
|
||||
#include "qgis.h"
|
||||
|
||||
#include <spatialindex/SpatialIndex.h>
|
||||
|
||||
@ -301,7 +302,7 @@ struct _CohenSutherland
|
||||
};
|
||||
|
||||
|
||||
static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry* geom, const QgsRectangle& rect, QgsVectorLayer* vl, QgsFeatureId fid )
|
||||
static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry *geom, const QgsRectangle& rect, QgsVectorLayer *vl, QgsFeatureId fid )
|
||||
{
|
||||
// this code is stupidly based on QgsGeometry::closestSegmentWithContext
|
||||
// we need iterator for segments...
|
||||
@ -313,9 +314,10 @@ static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry* geom, co
|
||||
|
||||
_CohenSutherland cs( rect );
|
||||
|
||||
QgsWkbPtr wkbPtr( wkb + 1 );
|
||||
QGis::WkbType wkbType;
|
||||
wkbPtr >> wkbType;
|
||||
QgsConstWkbPtr wkbPtr( wkb, geom->wkbSize() );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
QGis::WkbType wkbType = geom->wkbType();
|
||||
|
||||
bool hasZValue = false;
|
||||
switch ( wkbType )
|
||||
@ -373,7 +375,7 @@ static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry* geom, co
|
||||
wkbPtr >> nLines;
|
||||
for ( int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
|
||||
{
|
||||
wkbPtr += 1 + sizeof( int );
|
||||
wkbPtr.readHeader();
|
||||
int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
@ -455,7 +457,7 @@ static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry* geom, co
|
||||
wkbPtr >> nPolygons;
|
||||
for ( int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
|
||||
{
|
||||
wkbPtr += 1 + sizeof( int );
|
||||
wkbPtr.readHeader();
|
||||
int nRings;
|
||||
wkbPtr >> nRings;
|
||||
for ( int ringnr = 0; ringnr < nRings; ++ringnr )
|
||||
|
@ -242,14 +242,14 @@ QgsSpatialIndex& QgsSpatialIndex::operator=( const QgsSpatialIndex & other )
|
||||
return *this;
|
||||
}
|
||||
|
||||
Region QgsSpatialIndex::rectToRegion( const QgsRectangle& rect )
|
||||
SpatialIndex::Region QgsSpatialIndex::rectToRegion( const QgsRectangle& rect )
|
||||
{
|
||||
double pt1[2], pt2[2];
|
||||
pt1[0] = rect.xMinimum();
|
||||
pt1[1] = rect.yMinimum();
|
||||
pt2[0] = rect.xMaximum();
|
||||
pt2[1] = rect.yMaximum();
|
||||
return Region( pt1, pt2, 2 );
|
||||
return SpatialIndex::Region( pt1, pt2, 2 );
|
||||
}
|
||||
|
||||
bool QgsSpatialIndex::featureInfo( const QgsFeature& f, SpatialIndex::Region& r, QgsFeatureId &id )
|
||||
@ -267,7 +267,7 @@ bool QgsSpatialIndex::featureInfo( const QgsFeature& f, SpatialIndex::Region& r,
|
||||
|
||||
bool QgsSpatialIndex::insertFeature( const QgsFeature& f )
|
||||
{
|
||||
Region r;
|
||||
SpatialIndex::Region r;
|
||||
QgsFeatureId id;
|
||||
if ( !featureInfo( f, r, id ) )
|
||||
return false;
|
||||
@ -298,7 +298,7 @@ bool QgsSpatialIndex::insertFeature( const QgsFeature& f )
|
||||
|
||||
bool QgsSpatialIndex::deleteFeature( const QgsFeature& f )
|
||||
{
|
||||
Region r;
|
||||
SpatialIndex::Region r;
|
||||
QgsFeatureId id;
|
||||
if ( !featureInfo( f, r, id ) )
|
||||
return false;
|
||||
@ -312,7 +312,7 @@ QList<QgsFeatureId> QgsSpatialIndex::intersects( const QgsRectangle& rect ) cons
|
||||
QList<QgsFeatureId> list;
|
||||
QgisVisitor visitor( list );
|
||||
|
||||
Region r = rectToRegion( rect );
|
||||
SpatialIndex::Region r = rectToRegion( rect );
|
||||
|
||||
d->mRTree->intersectsWithQuery( r, visitor );
|
||||
|
||||
|
@ -70,7 +70,7 @@ Qgs25DRenderer::Qgs25DRenderer()
|
||||
QgsStringMap wallProperties;
|
||||
wallProperties.insert( "geometryModifier", WALL_EXPRESSION );
|
||||
wallProperties.insert( "symbolType", "Fill" );
|
||||
QgsSymbolLayerV2* walls = QgsGeometryGeneratorSymbolLayerV2::create( wallProperties );;
|
||||
QgsSymbolLayerV2* walls = QgsGeometryGeneratorSymbolLayerV2::create( wallProperties );
|
||||
|
||||
QgsStringMap roofProperties;
|
||||
roofProperties.insert( "geometryModifier", ROOF_EXPRESSION );
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "qgsmultipointv2.h"
|
||||
#include "qgspointv2.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgswkbptr.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QPainter>
|
||||
@ -169,7 +170,7 @@ void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, Qg
|
||||
QgsGeometry groupGeom( groupMultiPoint );
|
||||
QgsGeometry* centroid = groupGeom.centroid();
|
||||
QPointF pt;
|
||||
_getPoint( pt, context, centroid->asWkb() );
|
||||
_getPoint( pt, context, QgsConstWkbPtr( centroid->asWkb(), centroid->wkbSize() ) );
|
||||
delete centroid;
|
||||
|
||||
//calculate max diagonal size from all symbols in group
|
||||
|
@ -42,14 +42,12 @@
|
||||
|
||||
|
||||
|
||||
const unsigned char* QgsFeatureRendererV2::_getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb )
|
||||
QgsConstWkbPtr QgsFeatureRendererV2::_getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
unsigned int wkbType;
|
||||
wkbPtr >> wkbType >> pt.rx() >> pt.ry();
|
||||
|
||||
if ( static_cast< QgsWKBTypes::Type >( wkbType ) == QgsWKBTypes::Point25D || static_cast< QgsWKBTypes::Type >( wkbType ) == QgsWKBTypes::PointZ )
|
||||
wkbPtr += sizeof( double );
|
||||
QgsDebugCall;
|
||||
QgsWKBTypes::Type type = wkbPtr.readHeader();
|
||||
wkbPtr >> pt.rx() >> pt.ry();
|
||||
wkbPtr += ( QgsWKBTypes::coordDimensions( type ) - 2 ) * sizeof( double );
|
||||
|
||||
if ( context.coordinateTransform() )
|
||||
{
|
||||
@ -62,17 +60,13 @@ const unsigned char* QgsFeatureRendererV2::_getPoint( QPointF& pt, QgsRenderCont
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
|
||||
QgsConstWkbPtr QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkbPtr, bool clipToExtent )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
unsigned int wkbType, nPoints;
|
||||
wkbPtr >> wkbType >> nPoints;
|
||||
QgsDebugCall;
|
||||
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();
|
||||
unsigned int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
const QgsCoordinateTransform* ct = context.coordinateTransform();
|
||||
const QgsMapToPixel& mtp = context.mapToPixel();
|
||||
|
||||
@ -83,22 +77,20 @@ const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRe
|
||||
double cw = e.width() / 10;
|
||||
double ch = e.height() / 10;
|
||||
QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch );
|
||||
wkbPtr = QgsConstWkbPtr( QgsClipper::clippedLineWKB( wkb, clipRect, pts ) );
|
||||
wkbPtr -= 1 + 2 * sizeof( int );
|
||||
wkbPtr = QgsClipper::clippedLineWKB( wkbPtr, clipRect, pts );
|
||||
}
|
||||
else
|
||||
{
|
||||
pts.resize( nPoints );
|
||||
|
||||
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
|
||||
QPointF* ptr = pts.data();
|
||||
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
|
||||
{
|
||||
wkbPtr >> x >> y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
|
||||
*ptr = QPointF( x, y );
|
||||
wkbPtr >> ptr->rx() >> ptr->ry();
|
||||
wkbPtr += skipZM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,20 +109,16 @@ const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRe
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
|
||||
QgsConstWkbPtr QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkbPtr, bool clipToExtent )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
|
||||
unsigned int wkbType, numRings;
|
||||
wkbPtr >> wkbType >> numRings;
|
||||
QgsDebugCall;
|
||||
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();
|
||||
unsigned int numRings;
|
||||
wkbPtr >> numRings;
|
||||
|
||||
if ( numRings == 0 ) // sanity check for zero rings in polygon
|
||||
return wkbPtr;
|
||||
|
||||
bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
|
||||
double x, y;
|
||||
holes.clear();
|
||||
|
||||
const QgsCoordinateTransform* ct = context.coordinateTransform();
|
||||
@ -140,6 +128,8 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
|
||||
double ch = e.height() / 10;
|
||||
QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch );
|
||||
|
||||
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
|
||||
for ( unsigned int idx = 0; idx < numRings; idx++ )
|
||||
{
|
||||
unsigned int nPoints;
|
||||
@ -151,13 +141,8 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
|
||||
QPointF* ptr = poly.data();
|
||||
for ( unsigned int jdx = 0; jdx < nPoints; ++jdx, ++ptr )
|
||||
{
|
||||
wkbPtr >> x >> y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
|
||||
*ptr = QPointF( x, y );
|
||||
wkbPtr >> ptr->rx() >> ptr->ry();
|
||||
wkbPtr += skipZM;
|
||||
}
|
||||
|
||||
if ( nPoints < 1 )
|
||||
@ -173,7 +158,6 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
|
||||
ct->transformPolygon( poly );
|
||||
}
|
||||
|
||||
|
||||
ptr = poly.data();
|
||||
for ( int i = 0; i < poly.size(); ++i, ++ptr )
|
||||
{
|
||||
|
@ -401,9 +401,9 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
//! render editing vertex marker for a polygon
|
||||
void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context );
|
||||
|
||||
static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb );
|
||||
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr wkb );
|
||||
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );
|
||||
|
||||
|
@ -107,17 +107,12 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, const QgsSymbolLayerV2List& layers )
|
||||
}
|
||||
|
||||
|
||||
const unsigned char* QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
|
||||
QgsConstWkbPtr QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkbPtr, bool clipToExtent )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
unsigned int wkbType, nPoints;
|
||||
wkbPtr >> wkbType >> nPoints;
|
||||
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();
|
||||
unsigned int nPoints;
|
||||
wkbPtr >> nPoints;
|
||||
|
||||
bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
const QgsCoordinateTransform* ct = context.coordinateTransform();
|
||||
const QgsMapToPixel& mtp = context.mapToPixel();
|
||||
|
||||
@ -128,22 +123,21 @@ const unsigned char* QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderConte
|
||||
double cw = e.width() / 10;
|
||||
double ch = e.height() / 10;
|
||||
QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch );
|
||||
wkbPtr = QgsConstWkbPtr( QgsClipper::clippedLineWKB( wkb, clipRect, pts ) );
|
||||
wkbPtr -= 1 + 2 * sizeof( int );
|
||||
wkbPtr = QgsClipper::clippedLineWKB( wkbPtr, clipRect, pts );
|
||||
}
|
||||
else
|
||||
{
|
||||
pts.resize( nPoints );
|
||||
|
||||
QPointF* ptr = pts.data();
|
||||
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
Q_ASSERT( skipZM >= 0 );
|
||||
|
||||
QPointF *ptr = pts.data();
|
||||
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
|
||||
{
|
||||
wkbPtr >> x >> y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
|
||||
*ptr = QPointF( x, y );
|
||||
wkbPtr >> ptr->rx() >> ptr->ry();
|
||||
wkbPtr += skipZM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +147,7 @@ const unsigned char* QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderConte
|
||||
ct->transformPolygon( pts );
|
||||
}
|
||||
|
||||
QPointF* ptr = pts.data();
|
||||
QPointF *ptr = pts.data();
|
||||
for ( int i = 0; i < pts.size(); ++i, ++ptr )
|
||||
{
|
||||
mtp.transformInPlace( ptr->rx(), ptr->ry() );
|
||||
@ -162,20 +156,16 @@ const unsigned char* QgsSymbolV2::_getLineString( QPolygonF& pts, QgsRenderConte
|
||||
return wkbPtr;
|
||||
}
|
||||
|
||||
const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
|
||||
QgsConstWkbPtr QgsSymbolV2::_getPolygon( QPolygonF &pts, QList<QPolygonF> &holes, QgsRenderContext &context, QgsConstWkbPtr wkbPtr, bool clipToExtent )
|
||||
{
|
||||
QgsConstWkbPtr wkbPtr( wkb + 1 );
|
||||
|
||||
unsigned int wkbType, numRings;
|
||||
wkbPtr >> wkbType >> numRings;
|
||||
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();
|
||||
QgsDebugMsg( QString( "wkbType=%1" ).arg( wkbType ) );
|
||||
unsigned int numRings;
|
||||
wkbPtr >> numRings;
|
||||
|
||||
if ( numRings == 0 ) // sanity check for zero rings in polygon
|
||||
return wkbPtr;
|
||||
|
||||
bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) );
|
||||
|
||||
double x, y;
|
||||
holes.clear();
|
||||
|
||||
const QgsCoordinateTransform* ct = context.coordinateTransform();
|
||||
@ -185,6 +175,9 @@ const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>&
|
||||
double ch = e.height() / 10;
|
||||
QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch );
|
||||
|
||||
int skipZM = ( QgsWKBTypes::coordDimensions( wkbType ) - 2 ) * sizeof( double );
|
||||
Q_ASSERT( skipZM >= 0 );
|
||||
|
||||
for ( unsigned int idx = 0; idx < numRings; idx++ )
|
||||
{
|
||||
unsigned int nPoints;
|
||||
@ -192,17 +185,11 @@ const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>&
|
||||
|
||||
QPolygonF poly( nPoints );
|
||||
|
||||
// Extract the points from the WKB and store in a pair of vectors.
|
||||
QPointF* ptr = poly.data();
|
||||
QPointF *ptr = poly.data();
|
||||
for ( unsigned int jdx = 0; jdx < nPoints; ++jdx, ++ptr )
|
||||
{
|
||||
wkbPtr >> x >> y;
|
||||
if ( hasZValue )
|
||||
wkbPtr += sizeof( double );
|
||||
if ( hasMValue )
|
||||
wkbPtr += sizeof( double );
|
||||
|
||||
*ptr = QPointF( x, y );
|
||||
wkbPtr >> ptr->rx() >> ptr->ry();
|
||||
wkbPtr += skipZM;
|
||||
}
|
||||
|
||||
if ( nPoints < 1 )
|
||||
@ -210,7 +197,10 @@ const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>&
|
||||
|
||||
//clip close to view extent, if needed
|
||||
QRectF ptsRect = poly.boundingRect();
|
||||
if ( clipToExtent && !context.extent().contains( ptsRect ) ) QgsClipper::trimPolygon( poly, clipRect );
|
||||
if ( clipToExtent && !context.extent().contains( ptsRect ) )
|
||||
{
|
||||
QgsClipper::trimPolygon( poly, clipRect );
|
||||
}
|
||||
|
||||
//transform the QPolygonF to screen coordinates
|
||||
if ( ct )
|
||||
@ -218,7 +208,6 @@ const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>&
|
||||
ct->transformPolygon( poly );
|
||||
}
|
||||
|
||||
|
||||
ptr = poly.data();
|
||||
for ( int i = 0; i < poly.size(); ++i, ++ptr )
|
||||
{
|
||||
@ -695,7 +684,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
return;
|
||||
}
|
||||
|
||||
const QgsGeometry* segmentizedGeometry = geom;
|
||||
const QgsGeometry *segmentizedGeometry = geom;
|
||||
bool deleteSegmentizedGeometry = false;
|
||||
context.setGeometry( geom->geometry() );
|
||||
|
||||
@ -704,7 +693,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
//convert curve types to normal point/line/polygon ones
|
||||
if ( QgsWKBTypes::isCurvedType( geom->geometry()->wkbType() ) )
|
||||
{
|
||||
QgsAbstractGeometryV2* g = geom->geometry()->segmentize();
|
||||
QgsAbstractGeometryV2 *g = geom->geometry()->segmentize();
|
||||
if ( !g )
|
||||
{
|
||||
return;
|
||||
@ -733,7 +722,6 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
}
|
||||
|
||||
const QgsPointV2* point = static_cast< const QgsPointV2* >( segmentizedGeometry->geometry() );
|
||||
|
||||
_getPoint( pt, context, point );
|
||||
( static_cast<QgsMarkerSymbolV2*>( this ) )->renderPoint( pt, &feature, context, layer, selected );
|
||||
|
||||
@ -754,7 +742,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
QgsDebugMsg( "linestring can be drawn only with line symbol!" );
|
||||
break;
|
||||
}
|
||||
_getLineString( pts, context, segmentizedGeometry->asWkb(), !tileMapRendering && clipFeaturesToExtent() );
|
||||
_getLineString( pts, context, QgsConstWkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() ), !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsLineSymbolV2*>( this )->renderPolyline( pts, &feature, context, layer, selected );
|
||||
}
|
||||
break;
|
||||
@ -767,7 +755,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
QgsDebugMsg( "polygon can be drawn only with fill symbol!" );
|
||||
break;
|
||||
}
|
||||
_getPolygon( pts, holes, context, segmentizedGeometry->asWkb(), !tileMapRendering && clipFeaturesToExtent() );
|
||||
_getPolygon( pts, holes, context, QgsConstWkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() ), !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsFillSymbolV2*>( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected );
|
||||
}
|
||||
break;
|
||||
@ -806,10 +794,11 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
break;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb() + 1 + sizeof( int ) );
|
||||
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
unsigned int num;
|
||||
wkbPtr >> num;
|
||||
const unsigned char* ptr = wkbPtr;
|
||||
|
||||
const QgsGeometryCollectionV2* geomCollection = dynamic_cast<const QgsGeometryCollectionV2*>( geom->geometry() );
|
||||
|
||||
@ -821,7 +810,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
{
|
||||
context.setGeometry( geomCollection->geometryN( i ) );
|
||||
}
|
||||
ptr = QgsConstWkbPtr( _getLineString( pts, context, ptr, !tileMapRendering && clipFeaturesToExtent() ) );
|
||||
wkbPtr = _getLineString( pts, context, wkbPtr, !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsLineSymbolV2*>( this )->renderPolyline( pts, &feature, context, layer, selected );
|
||||
}
|
||||
}
|
||||
@ -836,10 +825,11 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
break;
|
||||
}
|
||||
|
||||
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb() + 1 + sizeof( int ) );
|
||||
QgsConstWkbPtr wkbPtr( segmentizedGeometry->asWkb(), segmentizedGeometry->wkbSize() );
|
||||
wkbPtr.readHeader();
|
||||
|
||||
unsigned int num;
|
||||
wkbPtr >> num;
|
||||
const unsigned char* ptr = wkbPtr;
|
||||
|
||||
QPolygonF pts;
|
||||
QList<QPolygonF> holes;
|
||||
@ -854,7 +844,8 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
|
||||
{
|
||||
context.setGeometry( geomCollection->geometryN( i ) );
|
||||
}
|
||||
ptr = _getPolygon( pts, holes, context, ptr, !tileMapRendering && clipFeaturesToExtent() );
|
||||
|
||||
wkbPtr = _getPolygon( pts, holes, context, wkbPtr, !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsFillSymbolV2*>( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected );
|
||||
}
|
||||
break;
|
||||
|
@ -276,13 +276,13 @@ class CORE_EXPORT QgsSymbolV2
|
||||
* Creates a line string in screen coordinates from a wkb string in map
|
||||
* coordinates
|
||||
*/
|
||||
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
/**
|
||||
* Creates a polygon in screen coordinates from a wkb string in map
|
||||
* coordinates
|
||||
*/
|
||||
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
|
||||
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
|
||||
|
||||
/**
|
||||
* Retrieve a cloned list of all layers that make up this symbol.
|
||||
|
@ -168,21 +168,21 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
|
||||
|
||||
//! Set how often map preview should be updated while it is being rendered (in milliseconds)
|
||||
//! @note added in 2.4
|
||||
void setMapUpdateInterval( int timeMiliseconds );
|
||||
void setMapUpdateInterval( int timeMilliseconds );
|
||||
|
||||
//! Find out how often map preview should be updated while it is being rendered (in milliseconds)
|
||||
//! @note added in 2.4
|
||||
int mapUpdateInterval() const;
|
||||
|
||||
//! @deprecated since 2.4 - there could be more than just one "map" items
|
||||
Q_DECL_DEPRECATED QgsMapCanvasMap* map();
|
||||
Q_DECL_DEPRECATED QgsMapCanvasMap *map();
|
||||
|
||||
//! @deprecated since 2.4 - use mapSettings() for anything related to current renderer settings
|
||||
//// SIP: removed /Transfer/ because it crashes after few calls to iface.mapCanvas().mapRenderer().hasCrsTransformEnabled()
|
||||
//// and in fact there is no transfer of ownership from c++ to python!
|
||||
//// Actually the problem comes from the fact that "hasCrsTransformEnabled" is both a signal and a normal method
|
||||
//// /KeepReference/ is necessary because otherwise mapRenderer().hasCrsTransformEnabled() was crashing
|
||||
Q_DECL_DEPRECATED QgsMapRenderer* mapRenderer();
|
||||
Q_DECL_DEPRECATED QgsMapRenderer *mapRenderer();
|
||||
|
||||
//! Accessor for the canvas paint device
|
||||
//! @deprecated since 2.4
|
||||
|
@ -385,51 +385,47 @@ void QgsGPXFeatureIterator::readAttributes( QgsFeature& feature, const QgsTrack&
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
QgsGeometry* QgsGPXFeatureIterator::readWaypointGeometry( const QgsWaypoint& wpt )
|
||||
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 ) );
|
||||
int size = 1 + sizeof( int ) + 2 * sizeof( double );
|
||||
unsigned char *geo = new unsigned char[size];
|
||||
|
||||
QgsWkbPtr wkbPtr( geo, size );
|
||||
wkbPtr << ( char ) QgsApplication::endian() << QGis::WKBPoint << wpt.lon << wpt.lat;
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb(( unsigned char * )geo, 21 );
|
||||
g->fromWkb( geo, size );
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
QgsGeometry* QgsGPXFeatureIterator::readRouteGeometry( const QgsRoute& rte )
|
||||
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 );
|
||||
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() << QGis::WKBLineString << rte.points.size();
|
||||
|
||||
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 ) );
|
||||
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* theGeometry = new QgsGeometry();
|
||||
theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * nPoints );
|
||||
return theGeometry;
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( geo, size );
|
||||
return g;
|
||||
}
|
||||
|
||||
QgsGeometry* QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack& trk )
|
||||
QgsGeometry *QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack& trk )
|
||||
{
|
||||
// TODO: support multi line string for segments
|
||||
|
||||
if ( trk.segments.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
@ -439,39 +435,38 @@ QgsGeometry* QgsGPXFeatureIterator::readTrackGeometry( const QgsTrack& trk )
|
||||
{
|
||||
totalPoints += trk.segments[i].points.size();
|
||||
}
|
||||
|
||||
if ( totalPoints == 0 )
|
||||
return nullptr;
|
||||
|
||||
//QgsDebugMsg( "GPX feature track total points: " + QString::number( totalPoints ) );
|
||||
|
||||
// some wkb voodoo
|
||||
char* geo = new char[9 + 16 * totalPoints];
|
||||
int size = 1 + 2 * sizeof( int ) + 2 * sizeof( double ) * totalPoints;
|
||||
unsigned char *geo = new unsigned char[size];
|
||||
if ( !geo )
|
||||
{
|
||||
QgsDebugMsg( "Too large track!!!" );
|
||||
QgsDebugMsg( "Track too large!" );
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
QgsWkbPtr wkbPtr( geo, size );
|
||||
wkbPtr << ( char ) QgsApplication::endian() << QGis::WKBLineString << totalPoints;
|
||||
|
||||
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++;
|
||||
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* theGeometry = new QgsGeometry();
|
||||
theGeometry->fromWkb(( unsigned char * )geo, 9 + 16 * totalPoints );
|
||||
return theGeometry;
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( geo, size );
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,7 +529,7 @@ bool QgsGrassFeatureIterator::fetchFeature( QgsFeature& feature )
|
||||
{
|
||||
feature.setAttribute( 1, QgsGrass::vectorTypeName( type ) );
|
||||
|
||||
int node1, node2;;
|
||||
int node1, node2;
|
||||
Vect_get_line_nodes( mSource->map(), lid, &node1, &node2 );
|
||||
feature.setAttribute( 2, node1 );
|
||||
if ( mSource->mLayerType == QgsGrassProvider::TOPO_LINE )
|
||||
|
@ -657,7 +657,7 @@ QString QgsHttpRequestHandler::readPostBody() const
|
||||
QgsMessageLog::logMessage( "length is: " + lengthQString );
|
||||
if ( conversionSuccess )
|
||||
{
|
||||
input = ( char* )malloc( length + 1 );
|
||||
input = new char[length + 1];
|
||||
memset( input, 0, length + 1 );
|
||||
for ( int i = 0; i < length; ++i )
|
||||
{
|
||||
@ -672,7 +672,7 @@ QString QgsHttpRequestHandler::readPostBody() const
|
||||
{
|
||||
QgsMessageLog::logMessage( "input is NULL " );
|
||||
}
|
||||
free( input );
|
||||
delete [] input;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1189,7 +1189,7 @@ void QgsServerProjectParser::layerFromLegendLayer( const QDomElement& legendLaye
|
||||
QList<QDomElement> QgsServerProjectParser::findLegendGroupElements() const
|
||||
{
|
||||
QList<QDomElement> LegendGroupElemList;
|
||||
QgsLayerTreeGroup* rootLayerTreeGroup = new QgsLayerTreeGroup;;
|
||||
QgsLayerTreeGroup* rootLayerTreeGroup = new QgsLayerTreeGroup;
|
||||
|
||||
QDomElement layerTreeElem = mXMLDoc->documentElement().firstChildElement( "layer-tree-group" );
|
||||
if ( !layerTreeElem.isNull() )
|
||||
|
@ -503,19 +503,19 @@ void TestQgsGeometry::pointV2()
|
||||
unsigned char* wkb = p12.asWkb( size );
|
||||
QCOMPARE( size, p12.wkbSize() );
|
||||
QgsPointV2 p13;
|
||||
p13.fromWkb( wkb );
|
||||
p13.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QVERIFY( p13 == p12 );
|
||||
|
||||
//bad WKB - check for no crash
|
||||
p13 = QgsPointV2( 1, 2 );
|
||||
QVERIFY( !p13.fromWkb( 0 ) );
|
||||
QVERIFY( !p13.fromWkb( QgsConstWkbPtr( nullptr, 0 ) ) );
|
||||
QCOMPARE( p13.wkbType(), QgsWKBTypes::Unknown );
|
||||
QgsLineStringV2 line;
|
||||
p13 = QgsPointV2( 1, 2 );
|
||||
wkb = line.asWkb( size );
|
||||
QVERIFY( !p13.fromWkb( wkb ) );
|
||||
QVERIFY( !p13.fromWkb( QgsConstWkbPtr( wkb, size ) ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p13.wkbType(), QgsWKBTypes::Unknown );
|
||||
@ -1310,7 +1310,7 @@ void TestQgsGeometry::lineStringV2()
|
||||
unsigned char* wkb = l15.asWkb( size );
|
||||
QCOMPARE( size, l15.wkbSize() );
|
||||
QgsLineStringV2 l16;
|
||||
l16.fromWkb( wkb );
|
||||
l16.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( l16.numPoints(), 4 );
|
||||
@ -1328,11 +1328,11 @@ void TestQgsGeometry::lineStringV2()
|
||||
|
||||
//bad WKB - check for no crash
|
||||
l16.clear();
|
||||
QVERIFY( !l16.fromWkb( 0 ) );
|
||||
QVERIFY( !l16.fromWkb( QgsConstWkbPtr( nullptr, 0 ) ) );
|
||||
QCOMPARE( l16.wkbType(), QgsWKBTypes::Unknown );
|
||||
QgsPointV2 point( 1, 2 );
|
||||
wkb = point.asWkb( size ) ;
|
||||
QVERIFY( !l16.fromWkb( wkb ) );
|
||||
QVERIFY( !l16.fromWkb( QgsConstWkbPtr( wkb, size ) ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( l16.wkbType(), QgsWKBTypes::Unknown );
|
||||
@ -2058,7 +2058,7 @@ void TestQgsGeometry::lineStringV2()
|
||||
QVERIFY( l37.boundingBox().isNull() );
|
||||
l37.setPoints( QList< QgsPointV2 >() << QgsPointV2( 5, 10 ) << QgsPointV2( 10, 15 ) );
|
||||
wkb = toAppend->asWkb( size );
|
||||
l37.fromWkb( wkb );
|
||||
l37.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( l37.boundingBox(), QgsRectangle( 1, 0, 4, 2 ) );
|
||||
@ -2658,7 +2658,7 @@ void TestQgsGeometry::polygonV2()
|
||||
unsigned char* wkb = p16.asWkb( size );
|
||||
QCOMPARE( size, p16.wkbSize() );
|
||||
QgsPolygonV2 p17;
|
||||
p17.fromWkb( wkb );
|
||||
p17.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p16, p17 );
|
||||
@ -2678,7 +2678,7 @@ void TestQgsGeometry::polygonV2()
|
||||
size = 0;
|
||||
wkb = p16.asWkb( size );
|
||||
QCOMPARE( size, p16.wkbSize() );
|
||||
p17.fromWkb( wkb );
|
||||
p17.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p16, p17 );
|
||||
@ -2698,7 +2698,7 @@ void TestQgsGeometry::polygonV2()
|
||||
size = 0;
|
||||
wkb = p16.asWkb( size );
|
||||
QCOMPARE( size, p16.wkbSize() );
|
||||
p17.fromWkb( wkb );
|
||||
p17.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p16, p17 );
|
||||
@ -2718,7 +2718,7 @@ void TestQgsGeometry::polygonV2()
|
||||
size = 0;
|
||||
wkb = p16.asWkb( size );
|
||||
QCOMPARE( size, p16.wkbSize() );
|
||||
p17.fromWkb( wkb );
|
||||
p17.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p16, p17 );
|
||||
@ -2738,19 +2738,19 @@ void TestQgsGeometry::polygonV2()
|
||||
size = 0;
|
||||
wkb = p16.asWkb( size );
|
||||
QCOMPARE( size, p16.wkbSize() );
|
||||
p17.clear();;
|
||||
p17.fromWkb( wkb );
|
||||
p17.clear();
|
||||
p17.fromWkb( QgsConstWkbPtr( wkb, size ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p16, p17 );
|
||||
|
||||
//bad WKB - check for no crash
|
||||
p17.clear();
|
||||
QVERIFY( !p17.fromWkb( 0 ) );
|
||||
QVERIFY( !p17.fromWkb( QgsConstWkbPtr( nullptr, 0 ) ) );
|
||||
QCOMPARE( p17.wkbType(), QgsWKBTypes::Unknown );
|
||||
QgsPointV2 point( 1, 2 );
|
||||
wkb = point.asWkb( size ) ;
|
||||
QVERIFY( !p17.fromWkb( wkb ) );
|
||||
QVERIFY( !p17.fromWkb( QgsConstWkbPtr( wkb, size ) ) );
|
||||
delete[] wkb;
|
||||
wkb = 0;
|
||||
QCOMPARE( p17.wkbType(), QgsWKBTypes::Unknown );
|
||||
|
@ -99,7 +99,7 @@ void TestQgsGeometryImport::pointWkb()
|
||||
//create wkb
|
||||
char byteOrder = QgsApplication::endian();
|
||||
unsigned char* geomPtr = new unsigned char[21];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, 21 );
|
||||
wkb << byteOrder << QGis::WKBPoint << x << y;
|
||||
|
||||
QgsGeometry geom;
|
||||
@ -178,7 +178,7 @@ void TestQgsGeometryImport::linestringWkb()
|
||||
char byteOrder = QgsApplication::endian();
|
||||
int wkbSize = 1 + 2 * sizeof( int ) + line.size() * 2 * sizeof( double );
|
||||
unsigned char* geomPtr = new unsigned char[wkbSize];
|
||||
QgsWkbPtr wkb( geomPtr );
|
||||
QgsWkbPtr wkb( geomPtr, wkbSize );
|
||||
wkb << byteOrder << QGis::WKBLineString << line.size();
|
||||
|
||||
for ( int i = 0; i < line.size(); ++i )
|
||||
|
Loading…
x
Reference in New Issue
Block a user