mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Use str tree spatial index from geos for the wfsprovider
git-svn-id: http://svn.osgeo.org/qgis/trunk@5889 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
4e0db539a7
commit
80084da84c
@ -2489,9 +2489,6 @@ geos::Geometry* QgsGeometry::geosGeometry() const
|
||||
ptr += sizeof(double);
|
||||
y = (double *) ptr;
|
||||
ptr += sizeof(double);
|
||||
#ifdef QGISDEBUG
|
||||
qWarning("QgsGeometry::geosGeometry: adding coordinate pair "+QString::number(*x)+"//"+QString::number(*y));
|
||||
#endif
|
||||
sequence->add(geos::Coordinate(*x,*y));
|
||||
}
|
||||
return geosGeometryFactory->createLineString(sequence);
|
||||
@ -2603,9 +2600,6 @@ geos::Geometry* QgsGeometry::geosGeometry() const
|
||||
ptr += sizeof(double);
|
||||
y = (double *) ptr;
|
||||
ptr += sizeof(double);
|
||||
#ifdef QGISDEBUG
|
||||
//qWarning("adding coordinate pair "+QString::number(*x)+"//"+QString::number(*y));
|
||||
#endif
|
||||
sequence->add(geos::Coordinate(*x,*y));
|
||||
}
|
||||
geos::LinearRing* ring=geosGeometryFactory->createLinearRing(sequence);
|
||||
@ -2723,9 +2717,9 @@ bool QgsGeometry::exportGeosToWkb() const
|
||||
for (int n = 0; n < numPoints; n++)
|
||||
{
|
||||
#ifdef QGISDEBUG
|
||||
std::cout << "QgsGeometry::exportGeosToWkb: Adding "
|
||||
<< sequence->getAt(n).x << ", "
|
||||
<< sequence->getAt(n).y << "." << std::endl;
|
||||
//std::cout << "QgsGeometry::exportGeosToWkb: Adding "
|
||||
// << sequence->getAt(n).x << ", "
|
||||
// << sequence->getAt(n).y << "." << std::endl;
|
||||
#endif
|
||||
// assign x
|
||||
memcpy(ptr, &(sequence->getAt(n).x), sizeof(double));
|
||||
|
@ -36,9 +36,8 @@ static const QString TEXT_PROVIDER_DESCRIPTION = "WFS data provider";
|
||||
static const QString WFS_NAMESPACE = "http://www.opengis.net/wfs";
|
||||
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
|
||||
|
||||
QgsWFSProvider::QgsWFSProvider(const QString& uri): QgsVectorDataProvider(uri), mFilter(0), mUseIntersect(false), mSourceSRS(0)
|
||||
QgsWFSProvider::QgsWFSProvider(const QString& uri): QgsVectorDataProvider(uri), mUseIntersect(false), mSourceSRS(0), mSelectedFeatures(0), mFeatureCount(0)
|
||||
{
|
||||
mFeatureIterator = mFeatures.begin();
|
||||
if(getFeature(uri) == 0)
|
||||
{
|
||||
//provider valid
|
||||
@ -47,16 +46,20 @@ QgsWFSProvider::QgsWFSProvider(const QString& uri): QgsVectorDataProvider(uri),
|
||||
{
|
||||
//provider invalid
|
||||
}
|
||||
//set spatial filter to the whole extent
|
||||
select(&mExtent, false);
|
||||
}
|
||||
|
||||
QgsWFSProvider::~QgsWFSProvider()
|
||||
{
|
||||
for(std::vector<QgsFeature*>::iterator it = mFeatures.begin(); it != mFeatures.end(); ++it)
|
||||
delete mSelectedFeatures;
|
||||
delete mSourceSRS;
|
||||
for(std::list<std::pair<geos::Envelope*, QgsFeature*> >::iterator it = mEnvelopesAndFeatures.begin();\
|
||||
it != mEnvelopesAndFeatures.end(); ++it)
|
||||
{
|
||||
delete (*it);
|
||||
delete it->first;
|
||||
delete it->second;
|
||||
}
|
||||
mFeatures.clear();
|
||||
delete mFilter;
|
||||
}
|
||||
|
||||
QgsFeature* QgsWFSProvider::getFirstFeature(bool fetchAttributes)
|
||||
@ -80,29 +83,29 @@ QgsFeature* QgsWFSProvider::getNextFeature(std::list<int> const & attlist, int f
|
||||
{
|
||||
while(true) //go through the loop until we find a feature in the filter
|
||||
{
|
||||
if(mFeatureIterator == mFeatures.end())
|
||||
if(!mSelectedFeatures || mFeatureIterator == mSelectedFeatures->end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QgsFeature* f = new QgsFeature();
|
||||
unsigned char* geom = (*mFeatureIterator)->getGeometry();
|
||||
int geomSize = (*mFeatureIterator)->getGeometrySize();
|
||||
unsigned char* geom = ((QgsFeature*)(*mFeatureIterator))->getGeometry();
|
||||
int geomSize = ((QgsFeature*)(*mFeatureIterator))->getGeometrySize();
|
||||
|
||||
unsigned char* copiedGeom = new unsigned char[geomSize];
|
||||
memcpy(copiedGeom, geom, geomSize);
|
||||
f->setGeometryAndOwnership(copiedGeom, geomSize);
|
||||
f->setFeatureId((*mFeatureIterator)->featureId());
|
||||
f->setFeatureId(((QgsFeature*)(*mFeatureIterator))->featureId());
|
||||
|
||||
const std::vector<QgsFeatureAttribute> attributes = (*mFeatureIterator)->attributeMap();
|
||||
const std::vector<QgsFeatureAttribute> attributes = ((QgsFeature*)(*mFeatureIterator))->attributeMap();
|
||||
for(std::list<int>::const_iterator it = attlist.begin(); it != attlist.end(); ++it)
|
||||
{
|
||||
f->addAttribute(attributes[*it].fieldName(), attributes[*it].fieldValue(), attributes[*it].isNumeric());
|
||||
}
|
||||
++mFeatureIterator;
|
||||
if(mFilter && mUseIntersect)
|
||||
if(mUseIntersect)
|
||||
{
|
||||
if(f->geometry()->fast_intersects(mFilter))
|
||||
if(f->geometry()->fast_intersects(&mSpatialFilter))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
@ -130,7 +133,7 @@ int QgsWFSProvider::geometryType() const
|
||||
|
||||
long QgsWFSProvider::featureCount() const
|
||||
{
|
||||
return mFeatures.size();
|
||||
return mFeatureCount;
|
||||
}
|
||||
|
||||
int QgsWFSProvider::fieldCount() const
|
||||
@ -145,9 +148,13 @@ std::vector<QgsField> const & QgsWFSProvider::fields() const
|
||||
|
||||
void QgsWFSProvider::reset()
|
||||
{
|
||||
mFeatureIterator = mFeatures.begin();
|
||||
delete mFilter;
|
||||
mFilter = 0;
|
||||
geos::Envelope e(mExtent.xMin(), mExtent.xMax(), mExtent.yMin(), mExtent.yMax());
|
||||
delete mSelectedFeatures;
|
||||
mSelectedFeatures = mSpatialIndex.query(&e);
|
||||
if(mSelectedFeatures)
|
||||
{
|
||||
mFeatureIterator = mSelectedFeatures->begin();
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsWFSProvider::minValue(int position)
|
||||
@ -231,9 +238,12 @@ bool QgsWFSProvider::isValid()
|
||||
|
||||
void QgsWFSProvider::select(QgsRect *mbr, bool useIntersect)
|
||||
{
|
||||
reset();
|
||||
mFilter = new QgsRect(*mbr);
|
||||
mUseIntersect = useIntersect;
|
||||
delete mSelectedFeatures;
|
||||
mSpatialFilter = *mbr;
|
||||
geos::Envelope filter(mbr->xMin(), mbr->xMax(), mbr->yMin(), mbr->yMax());
|
||||
mSelectedFeatures = mSpatialIndex.query(&filter);
|
||||
mFeatureIterator = mSelectedFeatures->begin();
|
||||
}
|
||||
|
||||
int QgsWFSProvider::getCapabilities(const QString& uri, QgsWFSProvider::REQUEST_ENCODING e, std::list<QString>& typenames, std::list< std::list<QString> >& crs)
|
||||
@ -404,7 +414,7 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
|
||||
|
||||
setSRSFromGML2(featureCollectionElement);
|
||||
|
||||
if(getFeaturesFromGML2(featureCollectionElement, geometryAttribute, mFeatures) != 0)
|
||||
if(getFeaturesFromGML2(featureCollectionElement, geometryAttribute) != 0)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
@ -638,7 +648,7 @@ int QgsWFSProvider::setSRSFromGML2(const QDomElement& wfsCollectionElement)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement, const QString& geometryAttribute, std::vector<QgsFeature*>& features) const
|
||||
int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement, const QString& geometryAttribute)
|
||||
{
|
||||
QDomNodeList featureTypeNodeList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "featureMember");
|
||||
QDomElement currentFeatureMemberElem;
|
||||
@ -650,6 +660,9 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
|
||||
unsigned char* wkb = 0;
|
||||
int wkbSize = 0;
|
||||
QGis::WKBTYPE currentType;
|
||||
QgsRect featureBBox;
|
||||
geos::Envelope* geosBBox;
|
||||
mFeatureCount = 0;
|
||||
|
||||
for(int i = 0; i < featureTypeNodeList.size(); ++i)
|
||||
{
|
||||
@ -679,7 +692,12 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
|
||||
}
|
||||
if(wkb && wkbSize > 0)
|
||||
{
|
||||
features.push_back(f);
|
||||
//insert bbox and pointer to feature into search tree
|
||||
featureBBox = f->boundingBox();
|
||||
geosBBox = new geos::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());
|
||||
mSpatialIndex.insert(geosBBox, (void*)f);
|
||||
mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, f));
|
||||
++mFeatureCount;
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "qgis.h"
|
||||
#include "qgsrect.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include <indexStrtree.h>
|
||||
|
||||
class QgsRect;
|
||||
|
||||
@ -86,13 +87,17 @@ class QgsWFSProvider: public QgsVectorDataProvider
|
||||
/**Bounding box for the layer*/
|
||||
QgsRect mExtent;
|
||||
/**Spatial filter for the layer*/
|
||||
QgsRect* mFilter;
|
||||
QgsRect mSpatialFilter;
|
||||
/**Flag if precise intersection test is needed. Otherwise, every feature is returned (even if a filter is set)*/
|
||||
bool mUseIntersect;
|
||||
/**Stores all the features*/
|
||||
std::vector<QgsFeature*> mFeatures;
|
||||
/**A spatial index for fast access to a feature subset*/
|
||||
geos::STRtree mSpatialIndex;
|
||||
/**Stores all the inserted rectangles and features. This is used to clean up the memory in the destructor*/
|
||||
std::list< std::pair<geos::Envelope*, QgsFeature*> > mEnvelopesAndFeatures;
|
||||
/**Vector where the QgsFeature* of a query are inserted*/
|
||||
std::vector<void*>* mSelectedFeatures;
|
||||
/**Iterator on the feature vector for use in reset(), getNextFeature(), etc...*/
|
||||
std::vector<QgsFeature*>::iterator mFeatureIterator;
|
||||
std::vector<void*>::iterator mFeatureIterator;
|
||||
/**Geometry type of the features in this layer*/
|
||||
mutable QGis::WKBTYPE mWKBType;
|
||||
/**Source SRS*/
|
||||
@ -100,6 +105,7 @@ class QgsWFSProvider: public QgsVectorDataProvider
|
||||
/**Stores the minimum/maximum values for each attribute
|
||||
The position in the vector is equal to the position of an attribute in the layers attribute vector*/
|
||||
std::vector< std::pair<QString, QString> > mMinMaxCash;
|
||||
int mFeatureCount;
|
||||
|
||||
/**Goes through all the features and their attributes and populates mMinMaxCash with entries*/
|
||||
void fillMinMaxCash();
|
||||
@ -123,7 +129,7 @@ class QgsWFSProvider: public QgsVectorDataProvider
|
||||
//GML2 specific methods
|
||||
int getExtentFromGML2(QgsRect* extent, const QDomElement& wfsCollectionElement) const;
|
||||
|
||||
int getFeaturesFromGML2(const QDomElement& wfsCollectionElement, const QString& geometryAttribute, std::vector<QgsFeature*>& features) const;
|
||||
int getFeaturesFromGML2(const QDomElement& wfsCollectionElement, const QString& geometryAttribute);
|
||||
|
||||
int getWkbFromGML2(const QDomNode& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
|
||||
/**Creates WKB from a <Point> element*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user