1,994 changes: 1,253 additions & 741 deletions qgis/src/qgsfeature.cpp

Large diffs are not rendered by default.

176 changes: 151 additions & 25 deletions qgis/src/qgsfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ email : sherman at mrcc.com
#ifndef QGSFEATURE_H
#define QGSFEATURE_H

#include <geos.h>
//#include <geos.h>
#include <qstring.h>
#include <map>
#include <vector>

#include "qgsfeatureattribute.h"
#include "qgis.h"
#include "qgspoint.h"

#include "qgsfeatureattribute.h"
#include "qgsgeometry.h"
//#include "qgspoint.h"

class QgsRect;

Expand All @@ -41,16 +43,28 @@ class QgsFeature {
QgsFeature();
QgsFeature(int id, QString const & typeName = "" );

/** create a copy of this feature in its uncommitted state.
To do this, you also pass in a reference to the feature's
layer's uncommitted attribute and geometry changes.
The resulting feature will have those changes applied.
This is useful in the cut/copy routine, where you'd
want a copy of the "current" feature, not the on-disk feature.
*/
QgsFeature( QgsFeature const & rhs,
std::map<int,std::map<QString,QString> > & changedAttributes,
std::map<int, QgsGeometry> & changedGeometries );

/** copy ctor needed due to internal pointer */
QgsFeature( QgsFeature const & );
QgsFeature( QgsFeature const & rhs );

/** assignment operator needed due to internal pointer */
QgsFeature & operator=( QgsFeature const & rhs );

//! Destructor
~QgsFeature();


/**
* Get the feature id for this feature
* @return Feature id
Expand Down Expand Up @@ -109,31 +123,118 @@ class QgsFeature {
* Set the validity of the feature.
*/
void setValid(bool validity);

/**
* Return the dirty state of this feature.
* Dirty is set if (e.g.) the feature's geometry has been modified in-memory.
*/
bool isDirty() const;

/**
* Reset the dirtiness of the feature. (i.e. make clean)
* You would normally do this after it's saved to permanent storage (e.g. disk, an ACID-compliant database)
*/
void resetDirty();

/**
* Get the geometry object associated with this feature
*/
QgsGeometry * geometry();

/**
* Get the geometry object associated with this feature
* The caller assumes responsibility for the QgsGeometry*'s destruction.
*/
QgsGeometry * geometryAndOwnership();

/** gets the most recent in-memory version of the geometry (deprecated function in favour of geometry()) */
unsigned char * getGeometry() const;

// /** gets only the committed version of the geometry */
// unsigned char * getCommittedGeometry() const;
//
// /** gets the most recent in-memory version of the geometry only
// if it has been modified since committed (isDirty() == TRUE) */
// unsigned char * getModifiedGeometry() const;

size_t getGeometrySize() const;

/* size_t getCommittedGeometrySize() const;
size_t getModifiedGeometrySize() const;*/

QString const& wellKnownText() const;

/** Set WKB geometry*/
void setGeometry(unsigned char * geometry, size_t length);
/** Set this feature's geometry from another QgsGeometry object (deep copy)
*/
void setGeometry(QgsGeometry& geom);

/**
* Set this feature's geometry from WKB
*
* This feature assumes responsibility for destroying geom.
*/
void setGeometryAndOwnership(unsigned char * geom, size_t length);

/** Set bulk-modified WKB geometry
\note this function assumes the Geometry is not committed.
*/
/* void setModifiedGeometry(unsigned char * geom, size_t length);*/

/** Insert a new vertex before the given vertex number,
* ring and item (first number is index 0)
* Not meaningful for Point geometries
*/
// bool insertVertexBefore(double x, double y, int beforeVertex = 0, int atRing = 0, int atItem = 0);

/** Moves the vertex at the given position number,
* ring and item (first number is index 0)
* to the given coordinates
*/
/* bool moveVertexAt(double x, double y, int atVertex = 0, int atRing = 0, int atItem = 0);*/

/**
* Modifies x and y to indicate the location of
* the vertex at the given position number,
* ring and item (first number is index 0)
* to the given coordinates
*/
/* bool vertexAt(double &x, double &y, int atVertex = 0, int atRing = 0, int atItem = 0) const;*/

/**Shows a popup dialog to change attribute values
@return true if dialog is accepted, false if rejected*/
bool attributeDialog();

/**Test for intersection with a rectangle (uses GEOS)*/
bool intersects(QgsRect* r) const;
// /**Test for intersection with a rectangle (uses GEOS)*/
// bool intersects(QgsRect* r) const;

/**Returns the Vertex closest to a given point*/
QgsPoint closestVertex(const QgsPoint& point) const;

/**Returns the bounding box of this feature*/
QgsRect boundingBox() const;

/**Creates a geos geometry from this features geometry. Note, that the returned object needs to be deleted*/
geos::Geometry* geosGeometry() const;
// QgsPoint closestVertex(const QgsPoint& point) const;

/** Returns the line segment closest to the given point in beforeVertex, atRing and atItem
Returns the SQUARE of the closest distance in minDist.
Returns the closest point on the line segment to the given point
TODO: point handling
TODO: const correctness
*/
// QgsPoint closestSegment(QgsPoint& point,
// QgsPoint& segStart, QgsPoint& segStop,
// double& minSqrDist);

// QgsPoint QgsFeature::closestSegmentWithContext(QgsPoint& point,
// int& beforeVertex, int& atRing, int& atItem,
// double& minSqrDist);
//
//
/**Returns the bounding box of this feature*/
QgsRect boundingBox() const;
//
/** Creates a geos geometry from this features geometry. Note, that the returned object needs to be deleted.
@note This function is deprecated - use geometry()->geosGeometry() instead.
*/
geos::Geometry* geosGeometry() const;

private:

Expand All @@ -150,23 +251,48 @@ class QgsFeature {
This is usually set by a call to OGRGeometry::exportToWkb()
*/
unsigned char * geometry;

/** size of geometry */
size_t geometrySize;
QgsGeometry* mGeometry;

/** Indicator if the mGeometry is owned by this QgsFeature.
If so, this QgsFeature takes responsibility for the mGeometry's destruction.
*/
bool mOwnsGeometry;

// /** pointer to modified (dirty / uncommitted) geometry in binary WKB format
// This is only valid if isDirty().
// */
// unsigned char * modifiedGeometry;
//
// /** size of geometry */
// size_t geometrySize;
//
// /** size of modified geometry */
// size_t modifiedGeometrySize;

//! Flag to indicate if this feature is valid
bool mValid;

//! Flag to indicate if this feature is dirty (e.g. geometry has been modified in-memory)
bool mDirty;

/// feature type name
QString mTypeName;

/**WKT representation of the geometry*/
mutable QString mWKT;

/**Exports the current WKB to mWKT
@return true in case of success and false else*/
bool exportToWKT() const;
// /**WKT representation of the geometry*/
// mutable QString mWKT;
//
// /**Exports the current WKB to mWKT
// @return true in case of success and false else*/
// bool exportToWKT(unsigned char * geom) const;
// bool exportToWKT() const;
//
// /** Squared distance from point to the given line segment
// * TODO: Perhaps move this to QgsPoint
// */
// double distanceSquaredPointToSegment(QgsPoint& point,
// double *x1, double *y1,
// double *x2, double *y2,
// QgsPoint& minDistPoint);

}; // class QgsFeature

Expand Down
1,458 changes: 1,458 additions & 0 deletions qgis/src/qgsgeometry.cpp

Large diffs are not rendered by default.

153 changes: 153 additions & 0 deletions qgis/src/qgsgeometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/***************************************************************************
qgsgeometry.h - Geometry (stored as Open Geospatial Consortium WKB)
-------------------------------------------------------------------
Date : 02 May 2005
Copyright : (C) 2005 by Brendan Morley
email : morb at ozemail dot com dot au
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* $Id$ */

#ifndef QGSGEOMETRY_H
#define QGSGEOMETRY_H

#include <qstring.h>

#include <geos.h>

#include "qgsgeometryvertexindex.h"
#include "qgspoint.h"
#include "qgsrect.h"


/**
* Represents a geometry with input and output in formats specified by
* (at least) the Open Geospatial Consortium (WKB / WKT), and containing
* various functions for geoprocessing of the geometry.
*
* The geometry is represented internally by the OGC WKB format, though
* perhaps this will be migrated to GEOS geometry in future.
*
* @author Brendan Morley
*/

class QgsGeometry {

public:


//! Constructor
QgsGeometry();

/** copy constructor will prompt a deep copy of the object */
QgsGeometry( QgsGeometry const & );

/** assignments will prompt a deep copy of the object */
QgsGeometry & operator=( QgsGeometry const & rhs );

//! Destructor
~QgsGeometry();


/**
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 setFromWkb(unsigned char * wkb, size_t length);

/**
Returns the buffer containing this geometry in WKB format.
You may wish to use in conjunction with wkbSize().
*/
unsigned char * wkbBuffer() const;

/**
Returns the size of the WKB in wkbBuffer().
*/
size_t wkbSize() const;

/**
Returns the QString containing this geometry in WKT format.
*/
QString const& wkt() const;

/**
Returns the vertex closest to the given point
*/
QgsPoint closestVertex(const QgsPoint& point) const;

/** Insert a new vertex before the given vertex index,
* ring and item (first number is index 0)
* Not meaningful for Point geometries
*/
bool insertVertexBefore(double x, double y, QgsGeometryVertexIndex beforeVertex);

/** Moves the vertex at the given position number,
* ring and item (first number is index 0)
* to the given coordinates
*/
bool moveVertexAt(double x, double y, QgsGeometryVertexIndex atVertex);

/**
* Modifies x and y to indicate the location of
* the vertex at the given position number,
* ring and item (first number is index 0)
* to the given coordinates
*/
bool vertexAt(double &x, double &y, QgsGeometryVertexIndex atVertex) const;

QgsPoint closestSegmentWithContext(QgsPoint& point,
QgsGeometryVertexIndex& beforeVertex,
double& minSqrDist);

/**Returns the bounding box of this feature*/
QgsRect boundingBox() const;

/**Test for intersection with a rectangle (uses GEOS)*/
bool intersects(QgsRect* r) const;

/**Creates a geos geometry from this features geometry. Note, that the returned object needs to be deleted*/
geos::Geometry* geosGeometry() const;




private:

/** pointer to geometry in binary WKB format
This is the class' native implementation
*/
unsigned char * mGeometry;


/** size of geometry */
size_t mGeometrySize;


/** cached WKT version of this geometry */
mutable QString mWkt;


/** Squared distance from point to the given line segment
* TODO: Perhaps move this to QgsPoint
*/
double distanceSquaredPointToSegment(QgsPoint& point,
double *x1, double *y1,
double *x2, double *y2,
QgsPoint& minDistPoint);

/**Exports the current WKB to mWkt
@return true in case of success and false else*/
bool exportToWkt(unsigned char * geom) const;
bool exportToWkt() const;


}; // class QgsGeometry

#endif
4 changes: 2 additions & 2 deletions qgis/src/qgsmapcanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,7 @@ void QgsMapCanvas::mouseReleaseEvent(QMouseEvent * e)
memcpy(&wkb[1],&wkbtype, sizeof(int));
memcpy(&wkb[5], &x, sizeof(double));
memcpy(&wkb[5]+sizeof(double), &y, sizeof(double));
f->setGeometry(&wkb[0],size);
f->setGeometryAndOwnership(&wkb[0],size);

//add the fields to the QgsFeature
std::vector<QgsField> fields=vlayer->fields();
Expand Down Expand Up @@ -1721,7 +1721,7 @@ void QgsMapCanvas::mouseReleaseEvent(QMouseEvent * e)
y=it->y();
memcpy(&wkb[position],&y,sizeof(double));
}
f->setGeometry(&wkb[0],size);
f->setGeometryAndOwnership(&wkb[0],size);

//add the fields to the QgsFeature
std::vector<QgsField> fields=vlayer->fields();
Expand Down
6 changes: 3 additions & 3 deletions qgis/src/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ void QgsVectorLayer::select(QgsRect * rect, bool lock)
//also test the not commited features
for(std::list<QgsFeature*>::iterator it=mAddedFeatures.begin();it!=mAddedFeatures.end();++it)
{
if((*it)->intersects(rect))
if((*it)->geometry()->intersects(rect))
{
select((*it)->featureId());
if (tabledisplay)
Expand Down Expand Up @@ -2497,7 +2497,7 @@ bool QgsVectorLayer::snapPoint(QgsPoint& point, double tolerance)
dataProvider->select(&selectrect);
while ((fet = dataProvider->getNextFeature(false)))
{
vertexFeature=fet->closestVertex(point);
vertexFeature=fet->geometry()->closestVertex(point);
minvertexdist=vertexFeature.sqrDist(point.x(),point.y());
if(minvertexdist<mindist)
{
Expand All @@ -2509,7 +2509,7 @@ bool QgsVectorLayer::snapPoint(QgsPoint& point, double tolerance)
//also go through the not commited features
for(std::list<QgsFeature*>::iterator iter=mAddedFeatures.begin();iter!=mAddedFeatures.end();++iter)
{
vertexFeature=(*iter)->closestVertex(point);
vertexFeature=(*iter)->geometry()->closestVertex(point);
minvertexdist=vertexFeature.sqrDist(point.x(),point.y());
if(minvertexdist<mindist)
{
Expand Down