[QGIS Commit] r8626 - in trunk/qgis/src/providers: . memory
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sun Jun 8 13:57:41 EDT 2008
Author: wonder
Date: 2008-06-08 13:57:40 -0400 (Sun, 08 Jun 2008)
New Revision: 8626
Added:
trunk/qgis/src/providers/memory/
trunk/qgis/src/providers/memory/CMakeLists.txt
trunk/qgis/src/providers/memory/memoryprovider.cpp
trunk/qgis/src/providers/memory/memoryprovider.h
Modified:
trunk/qgis/src/providers/CMakeLists.txt
Log:
Added "memory" provider. It stores all data in heap, offering 3rd party developers fast provider for temporary data.
Modified: trunk/qgis/src/providers/CMakeLists.txt
===================================================================
--- trunk/qgis/src/providers/CMakeLists.txt 2008-06-08 12:40:50 UTC (rev 8625)
+++ trunk/qgis/src/providers/CMakeLists.txt 2008-06-08 17:57:40 UTC (rev 8626)
@@ -1,5 +1,5 @@
-SUBDIRS (ogr wms delimitedtext)
+SUBDIRS (memory ogr wms delimitedtext)
IF (POSTGRES_FOUND)
SUBDIRS (postgres)
Added: trunk/qgis/src/providers/memory/CMakeLists.txt
===================================================================
--- trunk/qgis/src/providers/memory/CMakeLists.txt (rev 0)
+++ trunk/qgis/src/providers/memory/CMakeLists.txt 2008-06-08 17:57:40 UTC (rev 8626)
@@ -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})
Added: trunk/qgis/src/providers/memory/memoryprovider.cpp
===================================================================
--- trunk/qgis/src/providers/memory/memoryprovider.cpp (rev 0)
+++ trunk/qgis/src/providers/memory/memoryprovider.cpp 2008-06-08 17:57:40 UTC (rev 8626)
@@ -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;
+}
Added: trunk/qgis/src/providers/memory/memoryprovider.h
===================================================================
--- trunk/qgis/src/providers/memory/memoryprovider.h (rev 0)
+++ trunk/qgis/src/providers/memory/memoryprovider.h 2008-06-08 17:57:40 UTC (rev 8626)
@@ -0,0 +1,193 @@
+/***************************************************************************
+ memoryprovider.h - 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 "qgsvectordataprovider.h"
+
+
+typedef QMap<int, QgsFeature> QgsFeatureMap;
+
+
+class QgsMemoryProvider : public QgsVectorDataProvider
+{
+public:
+ QgsMemoryProvider(QString uri = QString());
+
+ virtual ~QgsMemoryProvider();
+
+ /* Implementation of functions from QgsVectorDataProvider */
+
+ /**
+ * Returns the permanent storage type for this layer as a friendly name.
+ */
+ virtual QString storageType() const;
+
+ /** Select features based on a bounding rectangle. Features can be retrieved with calls to getNextFeature.
+ * @param fetchAttributes list of attributes which should be fetched
+ * @param rect spatial filter
+ * @param fetchGeometry true if the feature geometry should be fetched
+ * @param useIntersect true if an accurate intersection test should be used,
+ * false if a test based on bounding box is sufficient
+ */
+ virtual void select(QgsAttributeList fetchAttributes = QgsAttributeList(),
+ QgsRect rect = QgsRect(),
+ bool fetchGeometry = true,
+ bool useIntersect = false);
+
+ /**
+ * Get the next feature resulting from a select operation.
+ * @param feature feature which will receive data from the provider
+ * @return true when there was a feature to fetch, false when end was hit
+ *
+ * mFile should be open with the file pointer at the record of the next
+ * feature, or EOF. The feature found on the current line is parsed.
+ */
+ virtual bool getNextFeature(QgsFeature& feature);
+
+ /**
+ * Gets the feature at the given feature ID.
+ * @param featureId id of the feature
+ * @param feature feature which will receive the data
+ * @param fetchGeoemtry if true, geometry will be fetched from the provider
+ * @param fetchAttributes a list containing the indexes of the attribute fields to copy
+ * @return True when feature was found, otherwise false
+ */
+ virtual bool getFeatureAtId(int featureId,
+ QgsFeature& feature,
+ bool fetchGeometry = true,
+ QgsAttributeList fetchAttributes = QgsAttributeList());
+
+ /**
+ * Get feature type.
+ * @return int representing the feature type
+ */
+ virtual QGis::WKBTYPE geometryType() const;
+
+ /**
+ * Number of features in the layer
+ * @return long containing number of features
+ */
+ virtual long featureCount() const;
+
+ /**
+ * Number of attribute fields for a feature in the layer
+ */
+ virtual uint fieldCount() const;
+
+ /**
+ * Return a map of indexes with field names for this layer
+ * @return map of fields
+ */
+ virtual const QgsFieldMap & fields() const;
+
+ /** Restart reading features from previous select operation */
+ virtual void reset();
+
+
+ /**
+ * Adds a list of features
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool addFeatures(QgsFeatureList & flist);
+
+ /**
+ * Deletes a feature
+ * @param id list containing feature ids to delete
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool deleteFeatures(const QgsFeatureIds & id);
+
+
+ /**
+ * Adds new attributes
+ * @param attributes map with attribute name as key and type as value
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool addAttributes(const QgsNewAttributesMap & attributes);
+
+ /**
+ * Deletes existing attributes
+ * @param attributes a set containing names of attributes
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool deleteAttributes(const QgsAttributeIds& attributes);
+
+ /**
+ * Changes attribute values of existing features.
+ * @param attr_map a map containing changed attributes
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool changeAttributeValues(const QgsChangedAttributesMap & attr_map);
+
+ /**
+ * Changes geometries of existing features
+ * @param geometry_map A std::map containing the feature IDs to change the geometries of.
+ * the second map parameter being the new geometries themselves
+ * @return true in case of success and false in case of failure
+ */
+ virtual bool changeGeometryValues(QgsGeometryMap & geometry_map);
+
+ /** Returns a bitmask containing the supported capabilities
+ Note, some capabilities may change depending on whether
+ a spatial filter is active on this provider, so it may
+ be prudent to check this value per intended operation.
+ */
+ virtual int capabilities() const;
+
+
+ /* Implementation of functions from QgsDataProvider */
+
+ /**
+ * return a provider name
+ */
+ QString name() const;
+
+ /**
+ * return description
+ */
+ QString description() const;
+
+ /**
+ * Return the extent for this data layer
+ */
+ virtual QgsRect extent();
+
+ /**
+ * Returns true if this is a valid provider
+ */
+ bool isValid();
+
+ virtual QgsSpatialRefSys getSRS();
+
+protected:
+
+ // called when added / removed features or geometries has been changed
+ void updateExtent();
+
+private:
+ // fields
+ QgsFieldMap mFields;
+ QGis::WKBTYPE mWkbType;
+ QgsRect mExtent;
+
+ // features
+ QgsFeatureMap mFeatures;
+ int mNextFeatureId;
+
+ // selection
+ QgsAttributeList mSelectAttrs;
+ QgsRect mSelectRect;
+ bool mSelectGeometry, mSelectUseIntersect;
+ QgsFeatureMap::iterator mSelectIterator;
+};
More information about the QGIS-commit
mailing list