[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