Ejemplo n.º 1
0
    /// \addtogroup ogrlayer_editing OGR layer editing
    /// Here is a list of methods and properties to save changes made to OgrLayer back to datasource.
    /// The properties and methods described here belong to OgrLayer class.\n
    ///
    ///  \dot
    /// digraph ogrediting {
    /// splines = true;
    /// node [shape= "polygon", fontname=Helvetica, fontsize=9, style = filled, color = palegreen, height = 0.3, width = 1.2];
    /// lb [ label="OgrLayer" URL="\ref OgrLayer"];
    /// node [shape = "ellipse", color = khaki, width = 0.2, height = 0.2, style = filled]
    /// gr   [label="OGR layer editing"   URL="\ref ogrlayer_editing"];
    /// edge [ arrowhead="open", style = solid, arrowsize = 0.6, fontname = "Arial", fontsize = 9, fontcolor = blue, color = "#606060" ]
    /// lb -> gr;
    /// }
    /// \enddot
    /// <a href = "diagrams.html">Graph description</a>\n
    ///
    /// Editing of underlying in-memory %shapefile can be done for all types of OGR layers. \n
    ///
    /// However saving of these changes back to datasource isn't always possible because of following reasons:\n
    /// - it isn't supported by driver;
    /// - forUpdate flag parameter wasn't specified on opening the layer;
    /// - layer was opened from SQL query;
    /// - data was reprojected during adding to the map;
    /// - layer doesn't have feature ID column.\n
    ///
    /// Use OgrLayer.get_SupportsEditing to check if saving is possible for current layer.\n
    ///
    /// Feature ID column corresponds to primary key in database table.
    /// Such column will be added as first field in attribute table of %shapefile (with index 0). This field
    /// must not be edited by client code. The presence of feature ID column can be tested with OgrLayer.FidColumnName
    /// property which will return empty string if no such column exists.\n
    ///
    /// To save the changes to datasource OgrLayer.SaveChanges method should be called.
    /// It supports saving of the following types of changes (provided that other preconditions are met ):
    /// - editing of values in attribute table;
    /// - any editing of geometry of individual shapes;
    /// - adding of new shapes;
    /// - deleting of exiting shapes.\n
    ///
    /// \note OgrLayer doesn't support any changes in order or number of fields in attribute table. Therefore
    /// fields must not be added or deleted in order for OgrLayer.SaveChanges to work.\n
    ///
    /// Edited shapes must be marked with modified flag via Shapefile.set_ShapeModified. See code sample in OgrLayer.SaveChanges
    /// documentation.\n
    ///
    /// Errors during the saving operation are registered in the log which can be accessed using OgrLayer.get_UpdateSourceErrorMsg.\n
    ///
    /// OgrLayer.SaveChanges method may change the order of rows in the database table
    /// (for example PostgreSQL driver places the updated rows in the end of table).
    /// Therefore on reloading of layer after the SaveChanges operation indices of shapes may change.
    ///
    /// The following code demonstrates how various types of editing for OGR layer can be made
    /// with saving of changes back to the datasource.
    /// \code
    /// private static string CONNECTION_STRING = "PG:host=localhost dbname=london user=postgres password=1234";
    ///
    /// var layer = new OgrLayer();
    /// layer.GlobalCallback = form;
    ///
    /// bool forUpdate = true;
    /// if (!layer.OpenFromDatabase(CONNECTION_STRING, "buildings", forUpdate))
    /// {
    ///     Debug.Print("Failed to open layer: " + layer.get_ErrorMsg(layer.LastErrorCode));
    ///     return false;
    /// }
    ///
    /// // check if editing is supported for driver
    /// Debug.Print("Driver supports editing: " + layer.TestCapability(tkOgrLayerCapability.olcRandomWrite));
    ///
    /// now check if we can actually do it, as there can be other limitations
    ///
    /// if (!layer.get_SupportsEditing(tkOgrSaveType.ostSaveAll))
    /// {
    ///     Debug.Print("Can't edit a layer: " + layer.get_ErrorMsg(layer.LastErrorCode));
    ///     layer.Close();
    ///     return false;
    /// }
    ///
    /// var sf = layer.GetBuffer();
    /// if (sf != null)
    /// {
    ///     // possible types of editing
    ///     bool editValue = true;
    ///     bool addShape = true;
    ///     bool editShape = true;
    ///     bool removeShape = true;
    ///
    ///     if (editValue)
    ///     {
    ///         int shapeIndex = 0;
    ///         int fieldIndex = 2;
    ///         object val = sf.get_CellValue(fieldIndex, shapeIndex);
    ///         sf.EditCellValue(fieldIndex, shapeIndex, "test_writing");
    ///
    ///         // this flag will notify the driver that changes should saved back to source
    ///         sf.ShapeModified[shapeIndex] = true;
    ///     }
    ///
    ///     if (addShape)
    ///     {
    ///         int shapeIndex = sf.NumShapes;
    ///         var shp = sf.get_Shape(0);
    ///         shp = shp.Buffer(1, 50);
    ///
    ///         // modified flag is set automatically in this case
    ///         bool result = sf.EditInsertShape(shp, ref shapeIndex);
    ///         Debug.Print("Shape was inserted: " + result);
    ///     }
    ///
    ///     if (editShape)
    ///     {
    ///         // since shapefile is in in-memory mode, geometry of shapes can be changed directly;
    ///         // bear in mind that this won't work for file-based shapefiles, in that case get_Shape will
    ///         // populate Shape object which will have no further link with parent shapefile
    ///         var shp = sf.get_Shape(sf.NumShapes - 1);
    ///         for (int i = 0; i < shp.NumPoints; i++)
    ///         {
    ///             double x = 0.0, y = 0.0;
    ///             if (shp.get_XY(i, ref x, ref y))
    ///                 shp.put_XY(i, x + 0.01, y + 0.01);  // let's move it a little
    ///         }
    ///     }
    ///
    ///     if (removeShape)
    ///     {
    ///         bool result = sf.EditDeleteShape(sf.NumShapes - 1);
    ///         Debug.Print("Shape was deleted: " + result);
    ///     }
    ///
    ///     // saving it
    ///     int count;
    ///     var saveResults = layer.SaveChanges(out count);
    ///
    ///     Debug.Print("Save result: " + saveResults.ToString());
    ///     Debug.Print("Number of shapes saved: " + count);
    ///
    ///     // displaying info on errors
    ///     for (int i = 0; i < layer.UpdateSourceErrorCount; i++)
    ///     {
    ///         Debug.Print(string.Format("Error for shape id {0}: {1}",
    ///         layer.UpdateSourceErrorShapeIndex[i], layer.UpdateSourceErrorMsg[i]));
    ///     }
    ///     return true;
    /// }
    /// layer.Close();
    /// return false;
    /// \endcode
    /// @{

    /// <summary>
    /// Gets a value indicating whether the layer supports editing.
    /// </summary>
    /// <remarks>
    /// The property works like this:\n
    /// 1) checks whether underlying driver supports random write operation:
    /// OgrLayer.TestCapability(tkOgrLayerCapability::olcRandomWrite);\n
    /// 2) the presence of Feature Id column is verified;\n
    /// 3) checks if the data is still in the same projection (OgrLayer.DataIsReprojected).\n
    ///
    /// OgrLayer.SaveChanges method doesn't make the first check, thus trying to write
    /// the data even if functionality isn't advertised by driver.
    /// </remarks>
    /// <param name="editingType">The requested type of editing.</param>
    /// <returns>True in case editing is supported.</returns>
    public bool get_SupportsEditing(tkOgrSaveType editingType)
    {
        throw new NotImplementedException();
    }
Ejemplo n.º 2
0
 /// <summary>
 /// Saves local changes to the datasource.
 /// </summary>
 /// <remarks>
 /// To check whether the operation is supported for current layer use OgrLayer.get_SupportsEditing.\n
 ///
 /// The method works like this:\n
 ///
 /// 1) Underlying shapefile is analyzed for changes, i.e. for shapes with Shapefile.get_ShapeModified property set to true. \n
 /// 2) For each of such shapes UPDATE statement is generated by driver.
 /// Shapes are identified in source by the value of Feature ID column.\n
 /// 3) If update operation for particular shape fails the error is registered in:
 /// OgrLayer.get_UpdateSourceErrorMsg().\n
 ///
 /// The operation may fail for a particular shape because of 2 main reasons:
 /// - shape is invalid, while validateShapes parameter set to true;
 /// - new values aren't accepted by datasource, which often can maintain stricter data constraints.
 /// </remarks>
 /// <param name="savedCount">Returns number of saved changed.</param>
 /// <param name="saveType">Sets which part of data should be saved, geometry, attributes or both.
 /// Default value is tkOgrSaveType.ostSaveAll (i.e. both geometry and attributes).</param>
 /// <param name="validateShapes">Sets whether shapes will be validated before saving. Default value is true,
 /// i.e. invalid shapes won't be saved.</param>
 /// <returns>Result of the operation.</returns>
 public tkOgrSaveResult SaveChanges(out int savedCount, tkOgrSaveType saveType = tkOgrSaveType.ostSaveAll,
                                    bool validateShapes = true)
 {
     throw new NotImplementedException();
 }