Exemplo n.º 1
0
        /// <summary>
        /// The add layer 2 map.
        /// </summary>
        /// <param name="query">
        /// The query.
        /// </param>
        private static void AddLayer2Map(string query)
        {
            var gs = new GlobalSettings();

            var layer = new OgrLayer();

            if (!layer.OpenFromQuery(CONNECTION_STRING, query))
            {
                Debug.Print("Failed to open layer: " + layer.get_ErrorMsg(layer.LastErrorCode));
                Debug.Print("GDAL last error: " + layer.GdalLastErrorMsg);
            }
            else
            {
                Map.RemoveAllLayers();

                // either a) set layer projection to the map
                Map.GrabProjectionFromData = true;

                // or b) set map projection and reproject layer if needed
                Map.Projection = tkMapProjection.PROJECTION_WGS84;

                int layerHandle = Map.AddLayer(layer, true);
                if (layerHandle == -1)
                {
                    Debug.Print("Failed to add layer to the map");
                }
                else
                {
                    Map.Redraw();

                    // get the reference back from map
                    OgrLayer sameLayerFromMap = Map.get_OgrLayer(layerHandle);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///     The test reprojection.
        /// </summary>
        /// <returns>
        ///     The <see cref="bool" />.
        /// </returns>
        private static bool TestReprojection()
        {
            Debug.Print("\nStart OGR test");
            AxMap map = Fileformats.Map;

            map.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR;

            var gs = new GlobalSettings();

            gs.ShapeInputValidationMode  = tkShapeValidationMode.NoValidation;
            gs.ShapeOutputValidationMode = tkShapeValidationMode.NoValidation;

            int handle = map.AddLayerFromDatabase(CONNECTION_STRING, "belarus", true);

            if (handle == -1)
            {
                Debug.Print("Failed to open database layer");
            }
            else
            {
                Debug.Print("Layer was opened");
                OgrLayer l = map.get_OgrLayer(handle);
                if (l != null)
                {
                    Debug.Print("Layer was reprojected: " + l.DataIsReprojected);
                }
            }

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        ///     The test file manager.
        /// </summary>
        private static void TestFileManager()
        {
            string sql    = "SELECT * FROM Buildings WHERE gid < 50";
            int    handle = Map.AddLayerFromDatabase(CONNECTION_STRING, sql, true);

            if (handle == -1)
            {
                Debug.Print("Failed to open layer: " + Map.FileManager.get_ErrorMsg(Map.FileManager.LastErrorCode));

                // in case the reason of failure is still unclear, let's ask GDAL for details
                var gs = new GlobalSettings();
                Debug.Print("Last GDAL error: " + gs.GdalLastErrorMsg);
            }
            else
            {
                OgrLayer l = Map.get_OgrLayer(handle);
                if (l != null)
                {
                    Debug.Print("Number of features: " + l.FeatureCount);

                    // now access the data
                    Shapefile sf = l.GetBuffer();
                    Debug.Print("Number of shapes: " + sf.NumShapes);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///     The display underlying data.
        /// </summary>
        private static void DisplayUnderlyingData()
        {
            string layerName = "fields";

            var layer = new OgrLayer();

            if (layer.OpenFromDatabase(CONNECTION_STRING, layerName, false))
            {
                // let's frist try to extract some info without loading the data locally
                Extents ext = null;
                if (layer.get_Extents(out ext))
                {
                    Debug.WriteLine("Extents w/o loading the data: " + ext.ToDebugString());
                }

                Debug.WriteLine("Feature count: " + layer.FeatureCount);

                // now load the data locally and display the same info
                Shapefile shapefile = layer.GetBuffer();
                if (shapefile != null)
                {
                    Debug.WriteLine("Extents from the loaded data: " + shapefile.Extents.ToDebugString());

                    Debug.WriteLine("Shape count: " + shapefile.NumShapes);

                    Debug.WriteLine("Layer fields: ");
                    for (int i = 0; i < shapefile.NumFields; i++)
                    {
                        Debug.WriteLine(shapefile.get_Field(i).Name);
                    }
                }
            }
        }
Exemplo n.º 5
0
 internal VectorLayer(OgrLayer layer)
 {
     _layer = layer;
     if (layer == null)
     {
         throw new NullReferenceException("Internal layer is null.");
     }
 }
Exemplo n.º 6
0
        /// <summary>
        ///     The ways to open layer.
        /// </summary>
        private static void WaysToOpenLayer()
        {
            var layer = new OgrLayer();

            string layerName = "waterways";

            // 1) open one of exiting layers in datasource
            if (!layer.OpenFromDatabase(CONNECTION_STRING, layerName, true))
            {
                // waterways = layerName
                Debug.Print("Failed to open layer: " + layer.get_ErrorMsg(layer.LastErrorCode));
            }

            // 2) return temporary layer by a query
            if (!layer.OpenFromQuery(CONNECTION_STRING, "SELECT * FROM " + layerName))
            {
                Debug.Print("Failed to run a query: " + layer.get_ErrorMsg(layer.LastErrorCode));
            }

            // 3) the same using datasource
            var ds = new OgrDatasource();

            if (!ds.Open(CONNECTION_STRING))
            {
                Debug.Print("Failed to open datasource: " + ds.GdalLastErrorMsg);
            }
            else
            {
                layer = ds.GetLayerByName(layerName);
                if (layer == null)
                {
                    Debug.Print("Failed to open layer: " + ds.get_ErrorMsg(ds.LastErrorCode));
                }

                layer = ds.RunQuery("SELECT * FROM " + layerName);
                if (layer == null)
                {
                    Debug.Print("Failed to run a query: " + ds.get_ErrorMsg(ds.LastErrorCode));
                }
            }

            // 4) using FileManager
            var fm = new FileManager();

            layer = fm.OpenFromDatabase(CONNECTION_STRING, layerName); // layer name or query can be passed here
            if (layer == null)
            {
                Debug.WriteLine("Failed to open layer: " + fm.get_ErrorMsg(fm.LastErrorCode));

                // let's check GDAL error as well
                var gs = new GlobalSettings();
                Debug.WriteLine("GDAL error message: " + gs.GdalLastErrorMsg);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// The test read layer.
        /// </summary>
        /// <param name="layerName">
        /// The layer name.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private static bool TestReadLayer(string layerName)
        {
            var ds = new OgrDatasource();

            if (!ds.Open(CONNECTION_STRING))
            {
                Debug.Print("Failed to establish connection: " + ds.GdalLastErrorMsg);
            }
            else
            {
                OgrLayer layer = ds.GetLayerByName(layerName, true);

                if (layer != null)
                {
                    layer.GlobalCallback = form;
                    Debug.Print("Layer opened: " + layer.Name);

                    Extents ext;
                    if (layer.get_Extents(out ext))
                    {
                        Debug.Print(ext.ToDebugString());
                    }

                    Debug.Print("Geometry column name: " + layer.GeometryColumnName);
                    Debug.Print("Feature count: " + layer.FeatureCount);
                    Debug.Print("Supports editing: " + layer.get_SupportsEditing(tkOgrSaveType.ostSaveAll));

                    Map.RemoveAllLayers();
                    Map.Projection = tkMapProjection.PROJECTION_WGS84;

                    int handle = Map.AddLayer(layer, true);
                    Map.Redraw();

                    Debug.Print("Layer connection: " + layer.GetConnectionString());
                    Debug.Print("Layer source query: " + layer.GetSourceQuery());

                    string state = layer.Serialize();
                    Debug.Print("Serialized state: " + state);
                }
                else
                {
                    Debug.Print("Failed to open layer: " + layerName);
                }

                ds.Close();
            }

            return(true);
        }
Exemplo n.º 8
0
        /// <summary>
        ///     The test layer capabilities.
        /// </summary>
        private static void TestLayerCapabilities()
        {
            var layer = new OgrLayer();

            if (!layer.OpenFromDatabase(CONNECTION_STRING, "waterways", true))
            {
                Debug.Print("Failed to open layer: " + layer.get_ErrorMsg(layer.LastErrorCode));
            }
            else
            {
                Array values = Enum.GetValues(typeof(tkOgrLayerCapability));
                foreach (tkOgrLayerCapability value in values)
                {
                    Debug.Print(value + ": " + layer.TestCapability(value));
                }
            }
        }
Exemplo n.º 9
0
        public static ILayerSource Open(string filename, LayerType layerType)
        {
            switch (layerType)
            {
            case LayerType.Shapefile:
                var fs = new FeatureSet(filename);
                return(fs);

            case LayerType.Image:
                var img = BitmapSource.Open(filename, false);
                return(img);

            case LayerType.VectorLayer:
                var ogr    = new OgrLayer();
                var vector = new VectorLayer(ogr);
                return(vector);

            default:
                throw new ArgumentOutOfRangeException("layerType");
            }
        }
Exemplo n.º 10
0
        /// <summary>
        ///     The test deserialize.
        /// </summary>
        /// <returns>
        ///     The <see cref="bool" />.
        /// </returns>
        private static bool TestDeserialize()
        {
            string filename = @"d:\ogrlayer.xml";

            using (var reader = new StreamReader(filename))
            {
                string state = reader.ReadToEnd();
                var    layer = new OgrLayer();
                if (!layer.Deserialize(state))
                {
                    Debug.Print("Failed to deserialize layer");
                    return(false);
                }

                AxMap map = Fileformats.Map;
                map.RemoveAllLayers();
                map.Projection = tkMapProjection.PROJECTION_WGS84;
                map.AddLayer(layer, true);
            }

            return(true);
        }
Exemplo n.º 11
0
 public VectorLayer()
 {
     _layer = new OgrLayer();
 }
        public bool Redraw(bool reloadLayers = false)
        {
            Events.MapControl_BusyStateChange bc = new Events.MapControl_BusyStateChange();
            bc             = new Events.MapControl_BusyStateChange();
            bc.BusyState   = Events.BusyState.Busy;
            bc.KeyOfSender = "Redraw";
            bc.Percent     = 0;
            bc.Message     = Resources.MapControl_RedrawMap;
            MapControlTools.On_BusyStateChange(bc);

            if (reloadLayers)
            {
                double percentadd     = 80.0 / MapControlTools.Layers.Count;
                int    currentpercent = 10;

                foreach (ILayer layer in MapControlTools.Layers)
                {
                    Type editingLayerType = layer.GetType();
                    if (editingLayerType == typeof(ResTBDamagePotentialLayer))
                    {
                        OgrLayer o = AxMap.get_OgrLayer(((ResTBDamagePotentialLayer)layer).PointHandle);
                        o.ReloadFromSource();
                        o = AxMap.get_OgrLayer(((ResTBDamagePotentialLayer)layer).LineHandle);
                        o.ReloadFromSource();
                        o = AxMap.get_OgrLayer(((ResTBDamagePotentialLayer)layer).PolygonHandle);
                        o.ReloadFromSource();
                    }
                    else if (editingLayerType == typeof(ResTBRiskMapLayer))
                    {
                        OgrLayer o = AxMap.get_OgrLayer(((ResTBRiskMapLayer)layer).PointHandle);
                        o.ReloadFromSource();
                        o = AxMap.get_OgrLayer(((ResTBRiskMapLayer)layer).LineHandle);
                        o.ReloadFromSource();
                        o = AxMap.get_OgrLayer(((ResTBRiskMapLayer)layer).PolygonHandle);
                        o.ReloadFromSource();
                    }
                    else if (editingLayerType.BaseType != null && editingLayerType.BaseType == typeof(ResTBPostGISLayer))
                    {
                        OgrLayer o = AxMap.get_OgrLayer(((ResTBPostGISLayer)layer).Handle);
                        o.ReloadFromSource();
                    }

                    layer.ShapeCount = MapControlTools.ShapesCount(layer.Name);

                    currentpercent += (int)percentadd;
                    bc              = new Events.MapControl_BusyStateChange();
                    bc.BusyState    = Events.BusyState.Busy;
                    bc.KeyOfSender  = "Redraw";
                    bc.Percent      = currentpercent;
                    bc.Message      = Resources.MapControl_ReloadLayers;
                }
            }

            bc             = new Events.MapControl_BusyStateChange();
            bc.BusyState   = Events.BusyState.Busy;
            bc.KeyOfSender = "Redraw";
            bc.Percent     = 80;
            bc.Message     = Resources.MapControl_RedrawMap;
            MapControlTools.On_BusyStateChange(bc);
            AxMap.Redraw();

            foreach (BaseLayer l in MapControlTools.Layers)
            {
                l.ApplyStyle(AxMap);
            }

            bc             = new Events.MapControl_BusyStateChange();
            bc             = new Events.MapControl_BusyStateChange();
            bc.BusyState   = Events.BusyState.Idle;
            bc.KeyOfSender = "Redraw";
            bc.Percent     = 100;
            bc.Message     = Resources.MapControl_MapRefreshed;
            MapControlTools.On_BusyStateChange(bc);

            //MapControlTools.ReStartSelecting();

            return(true);
        }
Exemplo n.º 13
0
        public void ReadAttributesFromPostGISLayer()
        {
            var ogrDatasource = new OgrDatasource();

            try
            {
                var result = ogrDatasource.Open("PG:host=127.0.0.1 port=5432 dbname=mw_test user=mapwindow password=test123");
                Assert.IsTrue(result, "Cannot open PostGIS Connectie: " + ogrDatasource.GdalLastErrorMsg);
                Assert.IsTrue(ogrDatasource.LayerCount > 1, "No layers found");

                OgrLayer attributeLayer = null;
                for (var i = 0; i < ogrDatasource.LayerCount; i++)
                {
                    var layer = ogrDatasource.GetLayer(i);
                    Console.WriteLine(layer.Name);
                    if (layer.Name == "attributes")
                    {
                        attributeLayer = layer;
                    }
                }

                Assert.IsNotNull(attributeLayer, "Couldn't find the attribute layer");
                Console.WriteLine("Working with attributes layer");

                var sf = attributeLayer.GetBuffer();
                Assert.IsNotNull(sf, "Could not get buffer");

                var numShapes = sf.NumShapes;
                Assert.AreEqual(3, numShapes);

                var numFields = sf.NumFields;
                Assert.IsTrue(numFields > 0, "No fields found");

                var fidColumn = attributeLayer.FIDColumnName;
                Console.WriteLine("fidColumn: " + fidColumn);

                // First shape has all attributes filled:
                Console.WriteLine("Testing first shape, all filled");
                for (var fieldIndex = 0; fieldIndex < numFields; fieldIndex++)
                {
                    var value = sf.CellValue[fieldIndex, 0];
                    Console.WriteLine($"{sf.Field[fieldIndex].Name}: {value}");
                    Assert.IsNotNull(value, $"{sf.Field[fieldIndex].Name} should not be null");
                }

                // Second shape has only the geometry filled and the rest default values (which should be NULL):
                Console.WriteLine("Testing second shape, default values");
                var numNonNulls = 0;
                for (var fieldIndex = 0; fieldIndex < numFields; fieldIndex++)
                {
                    var value = sf.CellValue[fieldIndex, 1];
                    Console.WriteLine($"{sf.Field[fieldIndex].Name}: {value}");
                    // Skip FID because it always has a value:
                    if (sf.Field[fieldIndex].Name == fidColumn)
                    {
                        continue;
                    }
                    if (value != null)
                    {
                        numNonNulls++;
                    }
                }
                if (numNonNulls > 0)
                {
                    // No assert, need to check the third shape as well:
                    Console.WriteLine($"Error! Second shape has {numNonNulls} non NULL fields!");
                }

                // Third shape has all fields explicitly NULL:
                Console.WriteLine("Testing third shape, all null");
                numNonNulls = 0;
                for (var fieldIndex = 0; fieldIndex < numFields; fieldIndex++)
                {
                    var value = sf.CellValue[fieldIndex, 2];
                    Console.WriteLine($"{sf.Field[fieldIndex].Name}: {value}");
                    // Skip FID because it always has a value:
                    if (sf.Field[fieldIndex].Name == fidColumn)
                    {
                        continue;
                    }
                    if (value != null)
                    {
                        numNonNulls++;
                    }
                }
                Assert.AreEqual(0, numNonNulls, $"Third shape has {numNonNulls} non NULL fields!");
            }
            finally
            {
                ogrDatasource.Close();
            }
        }
Exemplo n.º 14
0
        public bool StartEditingLayer(string name, bool saveAndStopWhenFinish = false, FeatureType featureType = FeatureType.Any)
        {
            ILayer editLayer = MapControlTools.Layers.Where(m => m.Name == name).FirstOrDefault();

            if (editLayer == null)
            {
                return(false);
            }

            this.saveAndCloseWhenFinish = saveAndStopWhenFinish;

            Shapefile sf;

            var ogrLayer = AxMap.get_OgrLayer(editLayer.Handle);

            sf = AxMap.get_Shapefile(editLayer.Handle);

            _currentEditingLayer = editLayer;

            if (ogrLayer != null)
            {
                // Add the editing layer
                DBConnectionTool dBConnection = new DBConnectionTool(AxMap, MapControlTools);
                OgrDatasource    ds           = new OgrDatasource();
                if (!ds.Open(dBConnection.GetGdalConnectionString()))
                {
                    Events.MapControl_Error error = new Events.MapControl_Error()
                    {
                        ErrorCode = Events.ErrorCodes.CouldNotConnectDatabase, InMethod = "AddPostGISLayer", AxMapError = ds.GdalLastErrorMsg
                    };
                    On_Error(error);
                    return(false);
                }
                OgrLayer editlayer = null;
                if (featureType == FeatureType.Point)
                {
                    editlayer = ds.GetLayerByName(((ResTBPostGISLayer)editLayer).SQL_Layer + "(point)", true);
                    if (editLayer.GetType() == typeof(ResTBDamagePotentialLayer))
                    {
                        editLayer.Handle = ((ResTBDamagePotentialLayer)editLayer).PointHandle;
                    }
                }
                else if (featureType == FeatureType.Line)
                {
                    editlayer = ds.GetLayerByName(((ResTBPostGISLayer)editLayer).SQL_Layer + "(line)", true);
                    if (editLayer.GetType() == typeof(ResTBDamagePotentialLayer))
                    {
                        editLayer.Handle = ((ResTBDamagePotentialLayer)editLayer).LineHandle;
                    }
                }
                else if (featureType == FeatureType.Polygon)
                {
                    editlayer = ds.GetLayerByName(((ResTBPostGISLayer)editLayer).SQL_Layer + "(polygon)", true);
                    if (editLayer.GetType() == typeof(ResTBDamagePotentialLayer))
                    {
                        editLayer.Handle = ((ResTBDamagePotentialLayer)editLayer).PolygonHandle;
                    }
                }
                else
                {
                    editlayer = ds.GetLayerByName(((ResTBPostGISLayer)editLayer).SQL_Layer, true);
                }

                int editinghandle = AxMap.AddLayer(editlayer, false);
                ((ResTBPostGISLayer)editLayer).EditingLayer       = editlayer;
                ((ResTBPostGISLayer)editLayer).EditingLayerHandle = editinghandle;

                _currentEditingLayer = editLayer;

                OgrLayer ogrLayer2 = ((ResTBPostGISLayer)editLayer).EditingLayer;
                if (ogrLayer2.DynamicLoading)
                {
                    Events.MapControl_Error error = new Events.MapControl_Error()
                    {
                        ErrorCode = Events.ErrorCodes.EditingNotAllowed, InMethod = "StartEditingLayer", AxMapError = ""
                    };
                    On_Error(error);
                    return(false);
                }
                if (!ogrLayer2.SupportsEditing[tkOgrSaveType.ostSaveAll])
                {
                    Events.MapControl_Error error = new Events.MapControl_Error()
                    {
                        ErrorCode = Events.ErrorCodes.EditingNotSupported, InMethod = "StartEditingLayer", AxMapError = ogrLayer2.ErrorMsg[ogrLayer.LastErrorCode]
                    };
                    On_Error(error);
                    return(false);
                }

                AxMap.set_LayerVisible(editLayer.Handle, false);

                AxMap.set_LayerVisible(((ResTBPostGISLayer)editLayer).EditingLayerHandle, true);
                sf = AxMap.get_Shapefile(((ResTBPostGISLayer)editLayer).EditingLayerHandle);

                Utils utils = new Utils();
                if (featureType == FeatureType.Point)
                {
                    sf.DefaultDrawingOptions.PointSize = 15;
                    sf.DefaultDrawingOptions.FillColor = utils.ColorByName(tkMapColor.Blue);
                }
                else
                {
                    sf.DefaultDrawingOptions.LineWidth = 7;
                    sf.DefaultDrawingOptions.FillColor = utils.ColorByName(tkMapColor.Blue);
                    sf.DefaultDrawingOptions.LineColor = utils.ColorByName(tkMapColor.Blue);
                    AxMap.ShapeEditor.FillColor        = utils.ColorByName(tkMapColor.Blue);
                }

                //AxMap.ShapeEditor.LineWidth = 20;
                AxMap.ShapeEditor.LineColor = utils.ColorByName(tkMapColor.Blue);
                sf.VisibilityExpression     = ((ResTBPostGISLayer)editLayer).VisibilityExpression;
            }

            AxMap.SendMouseDown = true;
            AxMap.SendMouseUp   = true;

            AxMap.ChooseLayer           += AxMap_ChooseLayer;
            AxMap.AfterShapeEdit        += _map_AfterShapeEdit;
            AxMap.BeforeDeleteShape     += _map_BeforeDeleteShape;
            AxMap.BeforeShapeEdit       += _map_BeforeShapeEdit;
            AxMap.ShapeValidationFailed += _map_ShapeValidationFailed;
            AxMap.ValidateShape         += _map_ValidateShape;

            AxMap.ShapeEditor.IndicesVisible = false;
            AxMap.ShapeEditor.ShowLength     = false;
            AxMap.ShapeEditor.ShowArea       = false;
            AxMap.ShapeEditor.ValidationMode = tkEditorValidation.evFixWithGeos;

            if ((featureType == FeatureType.Point) || (featureType == FeatureType.Line))
            {
                AxMap.ShapeEditor.SnapBehavior = tkLayerSelection.lsNoLayer;
            }
            else
            {
                AxMap.ShapeEditor.SnapBehavior = tkLayerSelection.lsAllLayers;
            }

            sf.InteractiveEditing = true;
            Events.MapControl_EditingStateChange editingStateChange = new Events.MapControl_EditingStateChange()
            {
                EditingState = Events.EditingState.StartEditing, EditingLayer = editLayer
            };
            On_EditingStateChange(editingStateChange);



            return(true);
        }
Exemplo n.º 15
0
        /// <summary>
        ///     The test edit layer.
        /// </summary>
        /// <returns>
        ///     The <see cref="bool" />.
        /// </returns>
        private static bool TestEditLayer()
        {
            var layer = new OgrLayer();

            layer.GlobalCallback = form;

            if (!layer.OpenFromDatabase(CONNECTION_STRING, "buildings", true))
            {
                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);
            }

            Shapefile 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;
                    Shape 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 futher link with parent shapefile
                    Shape 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;
                tkOgrSaveResult saveResults = layer.SaveChanges(out count);

                Debug.Print("Save result: " + saveResults);
                Debug.Print("Number of shapes saved: " + count);

                // displaying info on errors
                for (int i = 0; i < layer.UpdateSourceErrorCount; i++)
                {
                    Debug.Print(
                        "Error for shape id {0}: {1}",
                        layer.UpdateSourceErrorShapeIndex[i],
                        layer.UpdateSourceErrorMsg[i]);
                }

                return(true);
            }

            layer.Close();
            return(false);
        }