1. 将MapObject 2.1的控件加入控件TabTools中
选择 COM Components=>MapObjects 2.1 Map Control, 加进来后是 AxMapObject2.AxMap控件
2. 加载地图
MapObjects2.MapLayer layer; //图层
MapObjects2.GeoDataset gds; // 图层对应的数据
MapObjects2.DataConnection m_db = new MapObjects2.DataConnection(); // 图层集连接
// 打开 图层集连接:设置 .shp 文件所在的目录路径
m_db.Database = IconApplication.Instance.GetMapPath();
m_db.Connect();
// 查找图层:sample1.shp 地图(如果没有找到,则为空)
gds = m_db.FindGeoDataset("sample1");
// 将图层加载到 AxMapObject2.AxMap 控件中 => axMap1
layer = new MapObjects2.MapLayer();
layer.GeoDataset = gds;
layer.Symbol.Color = ConvertColorToMapSymbolColor(Color.Red); // layer中的颜色与C#定义不同,使用了自定义的方法转换
layer.Symbol.Size = 1; // 图层线宽 或 点的粗细度
layer.Visible = true; // 图层是否可视
axMap1.Layers.Add(layer); // 这个方法实际上是 Insert(0, layer),所以后面加载的地图在图层中的下标更小,显示级别更高(同区域,会由更高的级别覆盖低级别的图元)
// 自定义转换颜色方法
private UInt32 ConvertColorToMapSymbolColor(Color color)
{
return Convert.ToUInt32(color.R + color.G * 256 + color.B * 256 * 256);
}
3. 各种操作
a. 放大
// 设置当前操作的图标
// (是为了后面 MouseDownEvent 事件区分当前操作是放大、缩小、平移、选择等。
// 可以不设置,用其他变量记录也可以,主要是让操作人容易看清当前的操作状态)
axMap1.MousePointer = MapObjects2.MousePointerConstants.moZoomIn;
private void axMap1_MouseDownEvent(object sender, AxMapObjects2._DMapEvents_MouseDownEvent e)
{
switch (axMap1.MousePointer)
{
case MapObjects2.MousePointerConstants.moZoomIn:
{
// 选择放大到的区域
MapObjects2.Rectangle rect = axMap1.TrackRectangle();
if (rect == null || rect.Width < 0.00005 || rect.Height < 0.00005)
{
// 如果选择区域很小,可以认为是 单击、点选。就在当前范围下,放大 1.5 倍 ( 1/1.5 = 0.6667 )
rect = axMap1.Extent;
rect.ScaleRectangle(0.6667);
}
// 当选择的区域设置为 当前显示区域
axMap1.Extent = rect;
break;
}
case ....
b. 缩小
缩小与放大相似
axMap1.MousePointer = MapObjects2.MousePointerConstants.moZoomOut;
private void axMap1_MouseDownEvent(object sender, AxMapObjects2._DMapEvents_MouseDownEvent e)
{
switch (axMap1.MousePointer)
{
case ...
case MapObjects2.MousePointerConstants.moZoomOut:
{
MapObjects2.Rectangle rect = axMap1.TrackRectangle();
if (rect == null || rect.Width < 0.00005 || rect.Height < 0.00005)
{
rect = axMap1.Extent;
rect.ScaleRectangle(1.5); // 缩小为原来的 2/3 ( 1 / (2/3) = 3/2 = 1.5)
}
else
{
// 计算缩小率
double dRate = axMap1.Extent.Width / rect.Width * 10;
rect.ScaleRectangle(dRate);
}
axMap1.Extent = rect;
break;
}
c. 平移、拖动
axMap1.MousePointer = MapObjects2.MousePointerConstants.moPan;
private void axMap1_MouseDownEvent(object sender, AxMapObjects2._DMapEvents_MouseDownEvent e)
{
switch (axMap1.MousePointer)
{
case ...
case MapObjects2.MousePointerConstants.moPan:
{
axMap1.Pan();
break;
}
d. 选择图元
axMap1.MousePointer = MapObjects2.MousePointerConstants.moDefault;
private void axMap1_MouseDownEvent(object sender, AxMapObjects2._DMapEvents_MouseDownEvent e)
{
switch (axMap1.MousePointer)
{
case ...
case MapObjects2.MousePointerConstants.moDefault:
{
MapObjects2.Rectangle trackRect = axMap1.TrackRectangle();
// 获取当前选择的图层(只在一层图层中查)
MapObjects2.MapLayer layer = axMap.Layers.Item(currentLayerIndex) as MapObjects2.MapLayer;;
// 获取的图元集合=> selectRecs
MapObjects2.Recordset selectRecs;
// 根据不同的图层类型(点、线、面),有不同的查找方式
switch (layer.shapeType)
{
case MapObjects2.ShapeTypeConstants.moShapeTypePoint:
case MapObjects2.ShapeTypeConstants.moShapeTypePolygon:
{
selectRecs = layer.SearchShape(trackRect, MapObjects2.SearchMethodConstants.moAreaIntersect, string.Empty);
break;
}
case MapObjects2.ShapeTypeConstants.moShapeTypeLine:
default:
{
selectRecs = layer.SearchByDistance(trackRect, axMap1.ToMapDistance(1.5F), string.Empty);
break;
}
}
break;
}
e. 获取图层属性字段列表
MapObjects2.TableDesc tableDesc;
tableDesc = layer.Records.TableDesc;
for (short k = 0; k < tableDesc.FieldCount; k++)
{
fieldname = tableDesc.get_FieldName(k);
}
e. 通过图层属性数据查找数据
string expression;
field = layer.Records.Fields.Item( <地图属性的字段> );
switch (field.Type)
{
case MapObjects2.FieldTypeConstants.moLong:
case MapObjects2.FieldTypeConstants.moDouble:
{
expression = string.Format("{0}={1}", <地图属性的字段>, <属性值>);
break;
}
case MapObjects2.FieldTypeConstants.moString:
{
expression = string.Format("{0}='{1}'", <地图属性的字段>, <属性值>);
break;
}
default:
{
expression = string.Empty;
break;
}
}
if (expression == string.Empty)
{
continue;
}
MapObjects2.Recordset recs = layer.SearchExpression(expression);
f. 高亮显示选择的图元
private void highlightLayerRecordset(string fieldName, MapObjects2.MapLayer layer, MapObjects2.Recordset selectRecs, int layerIndex)
{
// MapObjects2.GroupRenderer 是定义一组颜色相同的图元列表。同一个图层允许有多个颜色显示定义组。
// 这里是利用 GroupRenderer 定义一组高亮显示的图元列表
MapObjects2.GroupRenderer gRen = (MapObjects2.GroupRenderer)layer.Renderer;
MapObjects2.GroupRenderer renColor;
if( gRen == null )
{
gRen = new MapObjects2.GroupRenderer();
gRen.DrawBackground = true;
layer.Renderer = gRen;
}
if( gRen.Count == 0 )
{
renColor = new MapObjects2.GroupRenderer();
gRen.Add(renColor);
}
else
{
renColor = (MapObjects2.GroupRenderer)gRen.get_Renderer(0);
}
// 先清除原来选择的图元的选择颜色
for (short i = Convert.ToInt16(renColor.Count - 1); i >= 0; i--)
{
renColor.Remove(i);
}
object v;
int selectCount = selectRecs.Count;
// 有时候 MapObjects2.Recordset 对象的 Count 的值是 -1,但实际上有数据
if (selectCount <= 0)
{
selectCount = 0;
selectRecs.MoveFirst();
while (selectRecs.EOF == false )
{
selectCount++;
selectRecs.MoveNext();
}
}
MapObjects2.ValueMapRenderer vmRen = new MapObjects2.ValueMapRenderer();
MapObjects2.Symbol sym;
vmRen.UseDefault = false;
vmRen.SymbolType = layer.Symbol.SymbolType; // 与图层相同的样式类型:点、线、面
vmRen.Field = fieldName
vmRen.ValueCount = Convert.ToInt16(selectCount); // 初设图元个数
selectRecs.MoveFirst();
int index=0;
while (selectRecs.EOF == false)
{
v = selectRecs.Fields.Item(fieldName).Value;
try
{
if( v.ToString() == "" )
{
continue;
}
vmRen.set_Value(Convert.ToInt16(index), v.ToString());
sym = vmRen.get_Symbol(Convert.ToInt16(index));
sym.Size = layer.Symbol.Size;
sym.Color = ConvertColorToMapSymbolColor(Color.Yellow); // 设置为黄色
index++;
}
finally
{
selectRecs.MoveNext();
}
}
// 有时候,在上面循环中会将一些不需要的图元排除,这里可以再次重设
vmRen.ValueCount = Convert.ToInt16(index);
if (vmRen.ValueCount > 0)
{
renColor.Add(vmRen);
}
axMap1.RefreshLayer(Convert.ToInt16(layerIndex));
}
h. 闪烁图元3秒
/// <summary>
/// 闪烁图元3 秒
/// </summary>
/// <param name="symbols">图元列表</param>
/// <param name="toCenter">是否自动将 图元的区域 移到 中心区域位置 显示</param>
private void FlashShape(MapObjects2.MapLayer layer, ArrayList symbols, bool toCenter)
{
MapObjects2.Rectangle shapeExtent = null;
object shape = null;
shape = symbols[0];
switch (layer.shapeType)
{
case MapObjects2.ShapeTypeConstants.moShapeTypePolygon:
{
#region // 将面型(多边形)图元 合并为 一个面型图元
MapObjects2.Polygon p;
p = shape as MapObjects2.Polygon;
for (int i = 1; i < symbols.Count; i++)
{
p = p.Union(symbols[i], axMap1.FullExtent) as MapObjects2.Polygon;
}
shape = p;
// 得到合并后的新图元的区域,是为了后面将当前新图元居中显示用
shapeExtent = p.Extent;
break;
#endregion
}
case MapObjects2.ShapeTypeConstants.moShapeTypeLine:
{
#region // 合并线性图元
MapObjects2.Line L;
L = shape as MapObjects2.Line;
for (int i = 1; i < symbols.Count; i++)
{
L = L.Union(symbols[i], axMap1.FullExtent) as MapObjects2.Line;
}
shape = L;
shapeExtent = L.Extent;
break;
#endregion
}
case MapObjects2.ShapeTypeConstants.moShapeTypePoint:
default:
{
MapObjects2.Points p;
p = shape as MapObjects2.Points;
// 点没有宽度,所以将设为全图的2% 大小
shapeExtent = new MapObjects2.Rectangle();
shapeExtent.Left = p.Extent.Center.X - axMap1.FullExtent.Width / 100;
shapeExtent.Right = p.Extent.Center.X + axMap1.FullExtent.Width / 100;
shapeExtent.Top = p.Extent.Center.Y + axMap1.FullExtent.Height / 100;
shapeExtent.Bottom = p.Extent.Center.Y - axMap1.FullExtent.Height / 100;
break;
}
}
if (shape != null)
{
if (toCenter)
{
// 放大至少达到当前范围的5%
MapObjects2.Rectangle rectExtent = axMap1.Extent;
double factor, factorX, factorY;
factorX = (shapeExtent.Width) * 20 / (rectExtent.Width);
factorY = (shapeExtent.Height) * 20 / (rectExtent.Height);
factor = (factorX > factorY) ? factorX : factorY;
if (factor < 1 && factor > 0)
{
rectExtent.ScaleRectangle(factor);
}
// 居中
double deltaX, deltaY;
deltaX = (shapeExtent.Center.X) - (rectExtent.Center.X);
deltaY = (shapeExtent.Center.Y) - (rectExtent.Center.Y);
if (rectExtent.IsPointIn(shapeExtent.Center) == false)
{
rectExtent.Offset(deltaX, deltaY);
}
axMap1.Extent = rectExtent;
axMap1.Refresh();
}
// 合并的图元闪烁3 秒
axMap1.FlashShape(shape, 3);
}
}