-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added "memory" provider. It stores all data in heap, offering 3rd par…
…ty developers fast provider for temporary data. git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@8626 c8812cc2-4d05-0410-92ff-de0c093fc19c
- Loading branch information
wonder
committed
Jun 8, 2008
1 parent
d9c0d80
commit c2158a6
Showing
4 changed files
with
524 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
|
||
SUBDIRS (ogr wms delimitedtext) | ||
SUBDIRS (memory ogr wms delimitedtext) | ||
|
||
IF (POSTGRES_FOUND) | ||
SUBDIRS (postgres) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
SET (MEMORY_SRCS memoryprovider.cpp) | ||
|
||
INCLUDE_DIRECTORIES( | ||
. | ||
../../core | ||
# ${GEOS_INCLUDE_DIR} | ||
) | ||
|
||
ADD_LIBRARY(memoryprovider MODULE ${MEMORY_SRCS}) | ||
|
||
TARGET_LINK_LIBRARIES(memoryprovider | ||
${QT_QTCORE_LIBRARY} | ||
# ${GDAL_LIBRARY} | ||
# ${GEOS_LIBRARY} | ||
qgis_core | ||
) | ||
|
||
|
||
INSTALL (TARGETS memoryprovider | ||
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR} | ||
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,308 @@ | ||
/*************************************************************************** | ||
memoryprovider.cpp - provider with storage in memory | ||
------------------ | ||
begin : June 2008 | ||
copyright : (C) 2008 by Martin Dobias | ||
email : wonder.sk at gmail.com | ||
*************************************************************************** | ||
* * | ||
* 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. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "memoryprovider.h" | ||
|
||
#include "qgsfeature.h" | ||
#include "qgsfield.h" | ||
#include "qgsgeometry.h" | ||
#include "qgslogger.h" | ||
#include "qgsspatialrefsys.h" | ||
|
||
|
||
static const QString TEXT_PROVIDER_KEY = "memory"; | ||
static const QString TEXT_PROVIDER_DESCRIPTION = "Memory provider"; | ||
|
||
QgsMemoryProvider::QgsMemoryProvider(QString uri) | ||
: QgsVectorDataProvider(uri) | ||
{ | ||
if (uri == "Point") | ||
mWkbType = QGis::WKBPoint; | ||
else if (uri == "LineString") | ||
mWkbType = QGis::WKBLineString; | ||
else if (uri == "Polygon") | ||
mWkbType = QGis::WKBPolygon; | ||
else if (uri == "WKBMultiPoint") | ||
mWkbType = QGis::WKBMultiPoint; | ||
else if (uri == "WKBMultiLineString") | ||
mWkbType = QGis::WKBMultiLineString; | ||
else if (uri == "WKBMultiPolygon") | ||
mWkbType = QGis::WKBMultiPolygon; | ||
else | ||
mWkbType = QGis::WKBUnknown; | ||
|
||
mNextFeatureId = 1; | ||
} | ||
|
||
QgsMemoryProvider::~QgsMemoryProvider() | ||
{ | ||
} | ||
|
||
QString QgsMemoryProvider::storageType() const | ||
{ | ||
return "Memory storage"; | ||
} | ||
|
||
bool QgsMemoryProvider::getNextFeature(QgsFeature& feature) | ||
{ | ||
bool hasFeature = FALSE; | ||
while (mSelectIterator != mFeatures.end()) | ||
{ | ||
if (mSelectRect.isEmpty()) | ||
{ | ||
hasFeature = TRUE; | ||
break; | ||
} | ||
else | ||
{ | ||
// TODO: could use some less accurate test when not using mSelectUseIntersect (e.g. spatial index) | ||
if (feature.geometry()->intersects(mSelectRect)) | ||
{ | ||
hasFeature = TRUE; | ||
break; | ||
} | ||
} | ||
|
||
mSelectIterator++; | ||
} | ||
|
||
// copy feature | ||
if (hasFeature) | ||
{ | ||
feature = mSelectIterator.value(); | ||
mSelectIterator++; | ||
} | ||
|
||
return hasFeature; | ||
} | ||
|
||
bool QgsMemoryProvider::getFeatureAtId(int featureId, | ||
QgsFeature& feature, | ||
bool fetchGeometry, | ||
QgsAttributeList fetchAttributes) | ||
{ | ||
QgsFeatureMap::iterator it = mFeatures.find(featureId); | ||
|
||
if (it == mFeatures.end()) | ||
return FALSE; | ||
|
||
feature = *it; | ||
return TRUE; | ||
} | ||
|
||
|
||
void QgsMemoryProvider::select(QgsAttributeList fetchAttributes, | ||
QgsRect rect, | ||
bool fetchGeometry, | ||
bool useIntersect) | ||
{ | ||
mSelectAttrs = fetchAttributes; | ||
mSelectRect = rect; | ||
mSelectGeometry = fetchGeometry; | ||
mSelectUseIntersect = useIntersect; | ||
|
||
reset(); | ||
} | ||
|
||
void QgsMemoryProvider::reset() | ||
{ | ||
mSelectIterator = mFeatures.begin(); | ||
} | ||
|
||
|
||
QgsRect QgsMemoryProvider::extent() | ||
{ | ||
return mExtent; | ||
} | ||
|
||
QGis::WKBTYPE QgsMemoryProvider::geometryType() const | ||
{ | ||
return mWkbType; | ||
} | ||
|
||
long QgsMemoryProvider::featureCount() const | ||
{ | ||
return mFeatures.count(); | ||
} | ||
|
||
uint QgsMemoryProvider::fieldCount() const | ||
{ | ||
return mFields.count(); | ||
} | ||
|
||
|
||
const QgsFieldMap & QgsMemoryProvider::fields() const | ||
{ | ||
return mFields; | ||
} | ||
|
||
bool QgsMemoryProvider::isValid() | ||
{ | ||
return (mWkbType != QGis::WKBUnknown); | ||
} | ||
|
||
QgsSpatialRefSys QgsMemoryProvider::getSRS() | ||
{ | ||
// TODO: make provider projection-aware | ||
return QgsSpatialRefSys(); // return default SRS | ||
} | ||
|
||
|
||
bool QgsMemoryProvider::addFeatures(QgsFeatureList & flist) | ||
{ | ||
// TODO: sanity checks of fields and geometries | ||
for (QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it) | ||
{ | ||
mFeatures[mNextFeatureId] = *it; | ||
mFeatures[mNextFeatureId].setFeatureId(mNextFeatureId); | ||
mNextFeatureId++; | ||
} | ||
|
||
updateExtent(); | ||
|
||
return TRUE; | ||
} | ||
|
||
bool QgsMemoryProvider::deleteFeatures(const QgsFeatureIds & id) | ||
{ | ||
for (QgsFeatureIds::const_iterator it = id.begin(); it != id.end(); ++it) | ||
mFeatures.remove(*it); | ||
|
||
updateExtent(); | ||
|
||
return TRUE; | ||
} | ||
|
||
bool QgsMemoryProvider::addAttributes(const QgsNewAttributesMap & attributes) | ||
{ | ||
for (QgsNewAttributesMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) | ||
{ | ||
QString name = it.key(); | ||
QString typeName = it.value(); | ||
QVariant::Type type; | ||
if (typeName == "int") | ||
type = QVariant::Int; | ||
else if (typeName == "double") | ||
type = QVariant::Double; | ||
else if (typeName == "string") | ||
type = QVariant::String; | ||
else | ||
{ | ||
QgsDebugMsg("Field type not supported: "+type); | ||
continue; | ||
} | ||
|
||
// add new field as a last one | ||
int nextId = -1; | ||
for (QgsFieldMap::iterator it2 = mFields.begin(); it2 != mFields.end(); ++it2) | ||
if (it2.key() > nextId) nextId = it2.key(); | ||
mFields[nextId+1] = QgsField(name, type, typeName); | ||
} | ||
return TRUE; | ||
} | ||
|
||
bool QgsMemoryProvider::deleteAttributes(const QgsAttributeIds& attributes) | ||
{ | ||
for (QgsAttributeIds::const_iterator it = attributes.begin(); it != attributes.end(); ++it) | ||
mFields.remove(*it); | ||
return TRUE; | ||
} | ||
|
||
bool QgsMemoryProvider::changeAttributeValues(const QgsChangedAttributesMap & attr_map) | ||
{ | ||
// TODO: change attribute values | ||
return FALSE; | ||
} | ||
|
||
bool QgsMemoryProvider::changeGeometryValues(QgsGeometryMap & geometry_map) | ||
{ | ||
// TODO: change geometries | ||
|
||
updateExtent(); | ||
|
||
return FALSE; | ||
} | ||
|
||
int QgsMemoryProvider::capabilities() const | ||
{ | ||
return AddFeatures | DeleteFeatures | ChangeGeometries | | ||
ChangeAttributeValues | AddAttributes | DeleteAttributes | | ||
SelectAtId | SelectGeometryAtId | RandomSelectGeometryAtId | SequentialSelectGeometryAtId; | ||
} | ||
|
||
|
||
void QgsMemoryProvider::updateExtent() | ||
{ | ||
if (mFeatures.count() == 0) | ||
{ | ||
mExtent = QgsRect(); | ||
} | ||
else | ||
{ | ||
mExtent = mFeatures.begin().value().geometry()->boundingBox(); | ||
for (QgsFeatureMap::iterator it = mFeatures.begin(); it != mFeatures.end(); ++it) | ||
mExtent.unionRect(it.value().geometry()->boundingBox()); | ||
} | ||
} | ||
|
||
|
||
|
||
// -------------------------------- | ||
|
||
QString QgsMemoryProvider::name() const | ||
{ | ||
return TEXT_PROVIDER_KEY; | ||
} | ||
|
||
QString QgsMemoryProvider::description() const | ||
{ | ||
return TEXT_PROVIDER_DESCRIPTION; | ||
} | ||
|
||
// -------------------------------- | ||
|
||
|
||
/** | ||
* Class factory to return a pointer to a newly created | ||
* QgsMemoryProvider object | ||
*/ | ||
QGISEXTERN QgsMemoryProvider *classFactory(const QString *uri) | ||
{ | ||
return new QgsMemoryProvider(*uri); | ||
} | ||
|
||
/** Required key function (used to map the plugin to a data store type) | ||
*/ | ||
QGISEXTERN QString providerKey() | ||
{ | ||
return TEXT_PROVIDER_KEY; | ||
} | ||
|
||
/** | ||
* Required description function | ||
*/ | ||
QGISEXTERN QString description() | ||
{ | ||
return TEXT_PROVIDER_DESCRIPTION; | ||
} | ||
|
||
/** | ||
* Required isProvider function. Used to determine if this shared library | ||
* is a data provider plugin | ||
*/ | ||
QGISEXTERN bool isProvider() | ||
{ | ||
return true; | ||
} |
Oops, something went wrong.