EditAttributes.cs

This example demonstrates how to implement a simple GUI for editing attributes of the individual shapes. A shapefile with buildings will be shown.The labels which display the name and type of building are added. After clicking on a building a dialog will appear with text boxes to display attributes of the object. The new values will be saved after the clicking on OK button. The label on the map will be updated showing the new values of the attributes. Here is a screenshot with the results of the code execution.

using System;
using System.IO;
using System.Windows.Forms;
using AxMapWinGIS;
using MapWinGIS;
namespace Examples
{
public partial class MapExamples
{
// <summary>
// A simple GUI for editing attributes of the individual shapes.
// </summary>
public void EditAttributes(AxMap axMap1, string dataPath)
{
axMap1.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR;
string filename = dataPath + "buildings.shp";
if (!File.Exists(filename))
{
MessageBox.Show("Couldn't file the file: " + filename);
return;
}
var sf = new Shapefile();
sf.Open(filename, null);
int layerHandle = axMap1.AddLayer(sf, true);
sf = axMap1.get_Shapefile(layerHandle); // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding
if (!sf.Table.StartEditingTable(null))
{
MessageBox.Show("Failed to start edit mode: " + sf.Table.ErrorMsg[sf.LastErrorCode]);
}
else
{
string expression = "";
for (int i = 1; i < sf.NumFields; i++) // all the fields will be displayed apart the first one
{
expression += "[" + sf.Field[i].Name + "]";
if (i != sf.NumFields - 1)
{
const string endLine = "\"\n\"";
expression += string.Format("+ {0} +", endLine);
}
}
sf.Labels.Generate(expression, tkLabelPositioning.lpCentroid, false);
sf.Labels.TextRenderingHint = tkTextRenderingHint.SystemDefault;
axMap1.SendMouseDown = true;
axMap1.CursorMode = tkCursorMode.cmNone;
MapEvents.MouseDownEvent += AxMap1MouseDownEvent2; // change MapEvents to axMap1
this.ZoomToValue(sf, "Name", "Lakeview");
}
}
// <summary>
// Zooms map to the specified object
// </summary>
public void ZoomToValue(Shapefile sf, string fieldName, string value)
{
int fieldIndex = sf.Table.FieldIndexByName[fieldName];
if (fieldIndex != -1)
{
for (int i = 0; i < sf.NumShapes; i++)
{
if ((string)sf.CellValue[fieldIndex, i] == value)
{
axMap1.Extents = sf.Shape[i].Extents;
axMap1.MapUnits = tkUnitsOfMeasure.umMeters;
axMap1.CurrentScale = 5000;
}
}
}
}
// <summary>
// Handles mouse down event. Creates the editing form on the fly.
// </summary>
private void AxMap1MouseDownEvent2(object sender, _DMapEvents_MouseDownEvent e)
{
int layerHandle = axMap1.get_LayerHandle(0); // it's assumed here that the layer we want to edit is the first 1 (with 0 index)
Shapefile sf = axMap1.get_Shapefile(layerHandle);
if (sf != null)
{
double projX = 0.0;
double projY = 0.0;
axMap1.PixelToProj(e.x, e.y, ref projX, ref projY);
object result = null;
Extents ext = new Extents();
ext.SetBounds(projX, projY, 0.0, projX, projY, 0.0);
if (sf.SelectShapes(ext, 0.0, SelectMode.INCLUSION, ref result))
{
int[] shapes = result as int[];
if (shapes == null) return;
if (shapes.Length > 1)
{
string s = "More than one shapes were selected. Shape indices:";
for (int i = 0; i < shapes.Length; i++)
s += shapes[i] + Environment.NewLine;
MessageBox.Show(s);
}
else
{
sf.set_ShapeSelected(shapes[0], true); // selecting the shape we are about to edit
axMap1.Redraw(); Application.DoEvents();
Form form = new Form();
for (int i = 0; i < sf.NumFields; i++)
{
System.Windows.Forms.Label label = new System.Windows.Forms.Label();
label.Left = 15;
label.Top = i * 30 + 5;
label.Text = sf.Field[i].Name;
label.Width = 60;
form.Controls.Add(label);
TextBox box = new TextBox();
box.Left = 80;
box.Top = label.Top;
box.Width = 80;
box.Text = sf.CellValue[i, shapes[0]].ToString();
box.Name = sf.Field[i].Name;
form.Controls.Add(box);
}
form.Width = 180;
form.Height = sf.NumFields * 30 + 70;
Button btn = new Button
{
Text = "Ok",
Top = sf.NumFields*30 + 10,
Left = 20,
Width = 70,
Height = 25
};
btn.Click += BtnClick;
form.Controls.Add(btn);
btn = new Button
{
Text = "Cancel",
Top = sf.NumFields*30 + 10,
Left = 100,
Width = 70,
Height = 25
};
btn.Click += BtnClick;
form.Controls.Add(btn);
form.FormClosed += FormFormClosed;
form.Text = "Shape: " + shapes[0];
form.ShowInTaskbar = false;
form.StartPosition = FormStartPosition.CenterParent;
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.MaximizeBox = false;
form.MinimizeBox = false;
form.ShowDialog(axMap1.Parent);
}
}
}
// Execute this code if you want to save the results.
// sf.StopEditingShapes(true, true, null);
}
// <summary>
// Clears selected shapes on the closing of the form
// </summary>
void FormFormClosed(object sender, FormClosedEventArgs e)
{
int layerHandle = axMap1.get_LayerHandle(0);
Shapefile sf = axMap1.get_Shapefile(layerHandle);
if (sf != null)
{
sf.SelectNone();
axMap1.Redraw();
}
}
// <summary>
// Submits new attibutes and updates the labels
// </summary>
void BtnClick(object sender, EventArgs e)
{
Form form = (sender as Control).Parent as Form;
if (form == null) return;
Button btn = sender as Button;
if (btn != null)
{
int layerHandle = axMap1.get_LayerHandle(0);
Shapefile sf = axMap1.get_Shapefile(layerHandle);
if (sf != null)
{
if (btn.Text == "Ok")
{
// now we shall find the selected shape, the one being edited
// in real-world application would be better of course to store the index of this shape in private variable
int shapeIndex = -1;
for (int i = 0; i < sf.NumShapes; i++)
{
if (sf.ShapeSelected[i])
{
shapeIndex = i;
break;
}
}
if (shapeIndex != -1)
{
foreach (Control control in form.Controls)
{
if (control is TextBox)
{
int fieldIndex = sf.Table.FieldIndexByName[control.Name];
if (fieldIndex != -1)
sf.EditCellValue(fieldIndex, shapeIndex, control.Text);
}
}
sf.Labels.Expression = sf.Labels.Expression; // update the labels
axMap1.Redraw();
}
}
}
}
form.Close();
}
}
}
SelectMode
The selection mode, which determines which shapes will be considered as included in the rectangular s...
Definition: Enumerations.cs:149
tkLabelPositioning
The available positioning of the label relative to the parent shape.
Definition: Enumerations.cs:835
tkCursorMode
Available cursor modes. Determines the default respond of map to the action of user.
Definition: Enumerations.cs:344
tkMapProjection
Commonly used map projections to be set in Form Designer (see AxMap.Projection property).
Definition: Enumerations.cs:1741
tkUnitsOfMeasure
The possible units of measure for the data being displaying on map.
Definition: Enumerations.cs:1397
Map component for visualization of vector, raster or grid data.
Definition: AxMap.cs:56
void Redraw()
Redraws all layers in the map if the map is not locked.
Definition: AxMap.cs:183
Represents a rectangle on the map.
Definition: Extents.cs:49
void SetBounds(double xMin, double yMin, double zMin, double xMax, double yMax, double zMax)
Sets the bounds for the extents object.
Definition: Extents.cs:85
string Expression
Gets or sets the expression used to generate text of labels from the attribute table of the shapefile...
Definition: Labels.cs:158
Provides a functionality for accessing and editing ESRI shapefiles.
Definition: Shapefile.cs:72
Labels Labels
Gets or sets the instance of the Labels class associated with the shapefile.
Definition: Shapefile.cs:184
Extents Extents
Gets bounding box which encompass all the shapes in the shapefile.
Definition: Shapefile.cs:146
int NumShapes
Gets the number of shapes in the shapefile.
Definition: Shapefile.cs:254
int Generate(string Expression, tkLabelPositioning Method, bool LargestPartOnly)
Generates labels for each shape of the parent shapefile.
Definition: Labels.cs:490
void PixelToProj(double pixelX, double pixelY, ref double projX, ref double projY)
Converts pixel coordinates to projected map coordinates
Definition: AxMap.cs:2634
tkUnitsOfMeasure MapUnits
Gets or sets the units of measure for the map.
Definition: AxMap.cs:2622
tkMapProjection Projection
Sets projection of the map. It providers 2 most commonly used coordinate system/projections to be eas...
Definition: AxMap.cs:2709
double CurrentScale
Gets or sets the current map scale.
Definition: AxMap.cs:2395
Extents Extents
Gets or sets the extents of the map using an Extents object.
Definition: AxMap.cs:2426
tkCursorMode CursorMode
Gets or sets the cursor mode for the map.
Definition: AxMap.cs:456
bool SendMouseDown
Gets or sets whether the map sends mouse down events.
Definition: AxMap.cs:553
int get_LayerHandle(int layerPosition)
Gets the handle of the layer at the given position in the map. Returns -1 if there is no layer at the...
Definition: AxMap.cs:1352
int AddLayer(object Object, bool visible)
Adds a layer to the map.
Definition: AxMap.cs:1342
Shapefile get_Shapefile(int layerHandle)
Gets shapefile object associated with the layer.
Definition: AxMap.cs:1546
void SelectNone()
Clears selection from all shapes.
Definition: Shapefile.cs:1803
void set_ShapeSelected(int shapeIndex, bool pVal)
Selects or deselects the specified shape. The _DMapEvents.SelectionChanged event is not fired.
Definition: Shapefile.cs:1768
bool SelectShapes(Extents boundBox, double tolerance, SelectMode selectMode, ref object result)
Returns an array with indices of shapes which are located inside specified bounds.
Definition: Shapefile.cs:1877
Table Table
Gets the reference to the attribute table associated with the shapefile.
Definition: Shapefile.cs:677
bool EditCellValue(int fieldIndex, int shapeIndex, object newVal)
Sets the new value for particular cell in attribute table. The table must be in editing mode.
Definition: Shapefile.cs:633
int NumFields
Gets the number of fields in attribute table of the shapefile.
Definition: Shapefile.cs:672