`
yh_private
  • 浏览: 38766 次
  • 性别: Icon_minigender_1
  • 来自: 长春
最近访客 更多访客>>
社区版块
存档分类
最新评论

ArcGIS API for Silverlight开发入门(4):用户与地理信息之间的桥梁--GraphicsLayer

阅读更多
我们与地图交互的过程时刻在进行着:一个拉框放大操作,或者对地图内容的查询等。这些交互过程中的输入输出,通常都是反映在独立于地图数据一个“层”上。比如拉框放大,我们能看见鼠标所画的一个矩形;又比如对兴趣点的查询,结果通常是将符合条件的兴趣点的形状高亮显示在那个独立的“层”中,通过它既可以反映用户的输入,又可以展现地图的输出。这个“层”就是GraphicsLayer。
        其实ADF开发中也有GraphicsLayer的概念,同样在其他两个客户端API(JavaScript/Flex)中也能找到GraphicsLayer的身影,它们都是一样一样的。
        本节我们主要看如何在GraphicsLayer中展现内容。当然第一个工作就是添加ESRI.ArcGIS.dll的引用,引入esri的xml命名空间;接下来在Map中添加一个GraphicsLayer图层:
<esri:Map x:Name="Map1">
<esri:Map.Layers>
<!-- 其他图层 -->
<esri:GraphicsLayer ID="GLayer" />
</esri:Map.Layers>
</esri:Map>

要使GraphicsLayer中的内容处于最顶端(不被其他图层内容覆盖),就要将它放在Map标签里的最下头,像上面那样。从命名我们不难看出,GraphicLayer里面放的就是Graphic的集合了。Graphic(ESRI.ArcGIS.Graphic)是GraphicsLayer中的基本元素,它包括了Geometry(在ESRI.ArcGIS.Geometry命名空间中),Symbol(在ESRI.ArcGIS.Symbol命名空间中),Attributes等属性。所有显示在地图中的矢量元素都有一个Geometry,里面包含了若干地理坐标,用于显示地图上地物的形状,它是Point,Polyline,Polygon等的总称,在这里代表了Graphic的形状。Symbol代表了Graphic的外观,它是一系列符号的总称,我们通常跟SimpleMarkerSymbol,SimpleLineSymbol和SimpleFillSymbol等打交道,它们分别对应了上面3种不同的Geometry(Point,Polyline,Polygon)。
        要让一个Graphic显示出来,总共分3步:
1、定义Graphic:
在xaml中
<esri:Graphic>
</esri:Graphic>

复制代码
在code-behind中
Graphic g= new Graphic()
2、设置Graphic的Geometry和Symbol属性:
在xaml中
<esri:Graphic>
<esri:Graphic.Symbol>
<esriSymbols:SimpleMarkerSymbol Color="Blue" Size="12" Style="Square" />
</esri:Graphic.Symbol>
<esriGeometry:MapPoint X="108" Y="30" />
</esri:Graphic>

复制代码
在code-behind中
Graphic g = new Graphic()
{
Geometry = new MapPoint(108, 30),
Symbol = new SimpleMarkerSymbol()
{
Color = new SolidColorBrush(Colors.Blue),
Size = 12,
Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square
}
};

3、把定义好的Graphic添加到GraphicsLayer里:
在xaml中
<esri:GraphicsLayer ID="GLayer">
<esri:GraphicsLayer.Graphics>
<esri:Graphic>
<esri:Graphic.Symbol>
<esriSymbols:SimpleMarkerSymbol Color="Blue" Size="12" Style="Square" />
</esri:Graphic.Symbol>
<esriGeometry:MapPoint X="108" Y="30" />
</esri:Graphic>
</esri:GraphicsLayer.Graphics>
</esri:GraphicsLayer>

复制代码
在code-behind中
Graphic g = new Graphic()
{
Geometry = new MapPoint(108, 30),
Symbol = new SimpleMarkerSymbol()
{
Color = new SolidColorBrush(Colors.Blue),
Size = 12,
Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square
}
};
GraphicsLayer glayer = Map1.Layers["GLayer"] as GraphicsLayer;
glayer.Graphics.Add(g);

复制代码
看一下效果:


        图中还有其他的图形,无非是改变了Graphic的Geometry和Symbol属性。图上的那只灰熊是一段动画文件,利用Silverlight的特性,能够定义出表现力丰富的各种符号。
        尽管能够完全在xaml中来完成工作,但还是建议将可视化元素的定义放在xaml中,将实现的逻辑部分放在code-behind中。看一下添加图中那些Graphic的代码:
<Grid.Resources>
<esriSymbols:SimpleMarkerSymbol x:Name="RedMarkerSymbol" Color="Red" Size="12" Style="Circle" />
<!-- 可惜目前Silverlight只支持Jpeg和PNG格式的图像,所以PictureMarkerSymbol无法显示GIF格式的图像,否则会报ImagingError的错误 -->
<esriSymbolsictureMarkerSymbol x:Name="PinPictureMarkerSymbol" Source="imgs/pin.png" OffsetX="10" OffsetY="10" />
<esriSymbols:SimpleLineSymbol x:Name="RedLineSymbol" Color="Red" Width="4" Style="Solid" />
<esriSymbols:CartographicLineSymbol x:Name="CartoLineSymbol" Color="Red" Width="10" DashCap="Triangle" LineJoin="Round" DashArray="6,2" />
<esriSymbols:SimpleFillSymbol x:Name="RedFillSymbol" Fill="#66FF0000" BorderBrush="Red" BorderThickness="2" />
</Grid.Resources>

<MediaElement x:Name="BearVideo" />

复制代码
private void AddGraphics()
{
GraphicsLayer glayer = Map1.Layers["GLayer"] as GraphicsLayer;
Graphic[] graphics = new Graphic[8];
graphics[0] = new Graphic()
{
Geometry = new MapPoint(108, 34),
Symbol = RedMarkerSymbol
};

graphics[1] = new Graphic()
{
Geometry = new MapPoint(108, 30),
Symbol = new SimpleMarkerSymbol()
{
Color = new SolidColorBrush(Colors.Blue),
Size = 12,
Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square
}
};

graphics[2] = new Graphic()
{
Geometry = new MapPoint(108, 25),
Symbol = PinPictureMarkerSymbol
};

graphics[3] = new Graphic()
{
Geometry = new MapPoint(108, 20),
Symbol = new TextSymbol()
{
FontFamily = new FontFamily("微软雅黑, 宋体"),
FontSize = 14,
Foreground = new SolidColorBrush(Colors.Black),
Text = "这是text symbol"
}
};

graphics[4] = new Graphic();
graphics[4].Symbol = RedLineSymbol;
ESRI.ArcGIS.Geometry.PointCollection pc = new ESRI.ArcGIS.Geometry.PointCollection()
{
new MapPoint(95,10),
new MapPoint(110,-15),
new MapPoint(130,10)
};
ESRI.ArcGIS.Geometry.Polyline pl = new ESRI.ArcGIS.Geometry.Polyline();
pl.Paths.Add(pc);
graphics[4].Geometry = pl;

graphics[5] = new Graphic();
graphics[5].Symbol = CartoLineSymbol;
ESRI.ArcGIS.Geometry.PointCollection pc1 = new ESRI.ArcGIS.Geometry.PointCollection()
{
new MapPoint(95,0),
new MapPoint(110,-25),
new MapPoint(130,0)
};
ESRI.ArcGIS.Geometry.Polyline pl1 = new ESRI.ArcGIS.Geometry.Polyline();
pl1.Paths.Add(pc1);
graphics[5].Geometry = pl1;

graphics[6] = new Graphic()
{
Symbol = RedFillSymbol
};
ESRI.ArcGIS.Geometry.PointCollection pc2 = new ESRI.ArcGIS.Geometry.PointCollection()
{
new MapPoint(110,-30),
new MapPoint(130,-30),
new MapPoint(130,-45),
new MapPoint(120,-55),
new MapPoint(110,-45),
new MapPoint(110,-30)
};
ESRI.ArcGIS.Geometry.Polygon pg = new ESRI.ArcGIS.Geometry.Polygon();
pg.Rings.Add(pc2);
graphics[6].Geometry=pg;

graphics[7] = new Graphic();
//MediaElement的Name属性只能在xaml中定义(见帮助),所以决定了MediaElement不能完全在cs代码中定义
BearVideo.Source = new Uri("http://serverapps.esri.com/media/bear.wmv", UriKind.RelativeOrAbsolute);
BearVideo.IsHitTestVisible=false;
BearVideo.IsMuted=true;
BearVideo.AutoPlay=true;
BearVideo.Opacity=0;
ESRI.ArcGIS.Geometry.Polygon pg2 = new ESRI.ArcGIS.Geometry.Polygon();
ESRI.ArcGIS.Geometry.PointCollection pc3 = new ESRI.ArcGIS.Geometry.PointCollection()
{
new MapPoint(10,-20),
new MapPoint(32,7),
new MapPoint(62,-35),
new MapPoint(11,-36),
new MapPoint(10,-20)
};
pg2.Rings.Add(pc3);
graphics[7].Geometry=pg2;
graphics[7].Symbol = new SimpleFillSymbol()
{
Fill = new VideoBrush()
{
SourceName = BearVideo.Name,
Opacity = 0.6,
Stretch = Stretch.UniformToFill
}
};


foreach (Graphic g in graphics)
{
glayer.Graphics.Add(g);
g.MouseLeftButtonDown+=new MouseButtonEventHandler(graphic_MouseLeftButtonDown);
}
}

private void graphic_MouseLeftButtonDown(object o,MouseButtonEventArgs e)
{
Graphic g=o as Graphic;
MessageBox.Show(string.Format("Geometry:{0}\nSymbol:{1}",g.Geometry.GetType().ToString(),g.Symbol.GetType().ToString()));
}

复制代码
可以看到,完全能够在一个Graphic上定义一些事件,来达到程序的目的。大家可以试着把上面的内容在xaml中改写一遍。看到这里肯定会产生一个疑问:难道每个Geometry的定义都这么困难吗?其实SilverlightAPI已经给我们提供了ESRI.ArcGIS.Draw(继承自xaml中的Canvas)类,它能非常方便的捕捉到用户的鼠标操作,从而获取各种Geometry来供程序使用。
        可以把Draw理解成一块画板,调用Draw的Active()方法,就可以开始在画板上面绘画,程序会自动记录鼠标画出的每个Geometry,调用DeActive()方法,停止绘画。Active()有一个DrawMode参数,它决定了我们即将在这个画板上画出的内容类型:Point,Polyline,Polygon等。在画的过程中我们可以看到地图上可以实时反映出我们绘画的内容,而这些则利用了Draw的预定义Symbol:DefaultMarkerSymbol,DefaultLineSymbol,DefaultPolygonSymbol等。对应关系如下:


        每当完成一个图形的绘制,就会触发Draw.OnDrawComplete事件,利用事件参数就可以获得Geometry,之后可以创建一个Graphic,设置一个Symbol(一般使用Draw的预定义Symbol),把画好的这个Graphic添加到一个GraphicsLayer中。
        点击这里,查看一个比较完整的Graphics的例子。
最后来看一下这个例子的部分代码:
<Grid.Resources>
<esriSymbols:SimpleMarkerSymbol x:Name="DefaultMarkerSymbol" Color="Red" Size="12" Style="Circle" />
<esriSymbols:CartographicLineSymbol x:Name="DefaultLineSymbol" Color="Red" Width="4" />
<esriSymbols:SimpleFillSymbol x:Name="DefaultFillSymbol" Fill="#33FF0000" BorderBrush="Red" BorderThickness="2" />
<esriSymbols:SimpleFillSymbol x:Name="DefaultPolygonSymbol" Fill="#33FF0000" BorderBrush="Red" BorderThickness="2" />
</Grid.Resources>

<esriraw x:Name="Draw1"
DefaultRectangleSymbol="{StaticResource DefaultFillSymbol}"
DefaultMarkerSymbol="{StaticResource DefaultMarkerSymbol}"
DefaultLineSymbol="{StaticResource DefaultLineSymbol}"
DefaultPolygonSymbol="{StaticResource DefaultPolygonSymbol}"
Loaded="Draw1_Loaded"
OnDrawComplete="Draw1_OnDrawComplete" />

<Canvas VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20,20,0,0" Width="430" Height="110">
<Rectangle RadiusX="10" RadiusY="10" Width="430" Height="110" Fill="#98000000" Stroke="#FF6495ED" />
<Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Canvas.Left="10" Canvas.Top="10" Width="410" Height="90" />

<StackPanel Orientation="Vertical" Canvas.Top="5" Canvas.Left="20">
<esriWidgets:Toolbar x:Name="ToolBar1" MaxItemHeight="80" MaxItemWidth="80" Width="380" Height="80"
ToolbarIndexChanged="ToolBar1_ToolbarIndexChanged"
ToolbarItemClicked="ToolBar1_ToolbarItemClicked">
<esriWidgets:Toolbar.Items>
<esriWidgets:ToolbarItemCollection>
<esriWidgets:ToolbarItem Text="添加点">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/DrawPoint.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="添加折线">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/DrawPolyline.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="添加多边形">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/DrawPolygon.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="添加矩形">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/DrawRectangle.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="添加曲线">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/DrawFreehand.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="停止添加动作">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/StopDraw.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
<esriWidgets:ToolbarItem Text="清空绘制的图形">
<esriWidgets:ToolbarItem.Content>
<Image Source="imgs/eraser.png" Stretch="UniformToFill" Margin="5" />
</esriWidgets:ToolbarItem.Content>
</esriWidgets:ToolbarItem>
</esriWidgets:ToolbarItemCollection>
</esriWidgets:Toolbar.Items>
</esriWidgets:Toolbar>
<TextBlock x:Name="StatusTextBlock" Text="" FontWeight="Bold" HorizontalAlignment="Center"/>
</StackPanel>
</Canvas>

复制代码
private void Draw1_Loaded(object sender, RoutedEventArgs e)
{
Draw1.Map = Map1;
}

private void Draw1_OnDrawComplete(object sender, ESRI.ArcGIS.DrawEventArgs args)
{
ESRI.ArcGIS.GraphicsLayer graphicsLayer = Map1.Layers["GLayer2"] as ESRI.ArcGIS.GraphicsLayer;
ESRI.ArcGIS.Graphic graphic = new ESRI.ArcGIS.Graphic()
{
Geometry = args.Geometry,
Symbol = _activeSymbol,
};
graphicsLayer.Graphics.Add(graphic);
}

private void ToolBar1_ToolbarIndexChanged(object sender, ESRI.ArcGIS.Widgets.SelectedToolbarItemArgs e)
{
StatusTextBlock.Text = e.Item.Text;
}

private void ToolBar1_ToolbarItemClicked(object sender, ESRI.ArcGIS.Widgets.SelectedToolbarItemArgs e)
{
Draw1.Deactivate();
switch (e.Index)
{
case 0: // Point
Draw1.Activate(ESRI.ArcGIS.DrawMode.Point);
_activeSymbol = strobeSymbol;
break;
case 1: // Polyline
Draw1.Activate(ESRI.ArcGIS.DrawMode.Polyline);
_activeSymbol = DefaultLineSymbol;
break;
case 2: // Polygon
Draw1.Activate(ESRI.ArcGIS.DrawMode.Polygon);
_activeSymbol = DefaultPolygonSymbol;
break;
case 3: // Rectangle
Draw1.Activate(ESRI.ArcGIS.DrawMode.Rectangle);
_activeSymbol = DefaultFillSymbol;
break;
case 4: // Freehand
Draw1.Activate(ESRI.ArcGIS.DrawMode.Freehand);
_activeSymbol = waveLineSymbol;
break;
case 5: // Stop Graphics
break;
case 6: // Clear Graphics
ESRI.ArcGIS.GraphicsLayer graphicsLayer = Map1.Layers["GLayer2"] as ESRI.ArcGIS.GraphicsLayer;
graphicsLayer.ClearGraphics();
break;

}
}

复制代码
大家可以注意一下例子中添加的点符号和曲线符号。只要有足够的想象力,完全可以利用Silverlight定制出非常炫的符号效果来。
        好了,下一节我们来了解如何使用这些画出的图形与地图数据交互。
分享到:
评论

相关推荐

    arcgis api for silverlight开发入门

    ### ArcGIS API for Silverlight 开发入门 #### 一、为何选择 Silverlight API? 随着信息技术的发展,GIS领域也需要不断地更新迭代以适应新的技术趋势。Silverlight作为一种新兴的技术平台,为GIS开发提供了新的...

    ArcGIS_API_for_Silverlight开发入门

    ArcGIS API for Silverlight 是一款强大的地图和地理信息系统(GIS)开发工具,由Esri公司提供,用于在Microsoft Silverlight平台上构建交互式的地图应用。它允许开发者利用Silverlight的丰富用户体验功能,结合...

    ArcGis_Silverlight_API应用开发教程

    以上内容涵盖了ArcGIS Silverlight API应用开发的基础知识和技术要点,对于希望从事地理信息系统开发的人员来说是非常宝贵的参考资料。通过掌握这些知识点,开发者可以更好地利用该API构建出高效、美观的地图应用。

    ArcGISAPI二次开发培训

    ### ArcGIS API 二次开发培训知识点详解 #### 一、ArcGIS API 下载与安装 - **下载地址**: ArcGIS API 可以从官方...开发者可以根据自己的需求选择合适的对象和服务来进行定制化开发,实现丰富的地理信息系统功能。

    ArcGIS Silverlight API 应用开发教程

    ArcGIS Silverlight API应用开发教程详细介绍了如何利用ArcGIS API for Silverlight开发地理信息系统(GIS)应用。首先,教程引入了REST架构风格的概念,并解释了REST的基本原理和在Web服务中的优势。REST作为一种...

    一个ArcGIS API for Siverlight的简单小程序

    《ArcGIS API for Silverlight:探索地理信息系统的小程序实践》 ArcGIS API for Silverlight是Esri公司提供的一款用于构建Web GIS应用的开发工具,它允许开发者在Silverlight平台上创建丰富的交互式地图应用。本篇...

    ArcGIS_Silverlight_API

    ArcGIS API for Silverlight是Esri提供的一个库,旨在帮助开发者使用Silverlight快速构建地理信息系统(GIS)应用。该API封装了许多复杂的GIS功能,使得开发者能够轻松地集成地图显示、查询、编辑等功能到自己的...

    ArcGIS Server RIA开发模式— for silverlight

    本文将详细介绍Silverlight的基本概念、发展历程,以及如何利用ArcGIS for Silverlight API进行地理信息系统(GIS)的应用开发。 #### Silverlight大事记 - **2007年9月**:Silverlight 1.0 正式发布,主要支持富...

    ArcGIS_API_for_Silverlight.rar_GIS编程_C#_

    《ArcGIS API for Silverlight开发入门》是一本深入探讨GIS(地理信息系统)编程与C#结合的实践指南。ArcGIS API for Silverlight是Esri公司提供的一个强大的工具,用于构建基于Web的地理空间应用程序,特别是在...

    arcgis for siverlight地图上点、线、多边形、矩形和任意图形绘制

    这涉及到地理信息系统(GIS)的基础知识,Silverlight编程技术,以及ArcGIS SDK中的相关API。 首先,让我们深入了解ArcGIS for Silverlight。ArcGIS是由Esri公司开发的一套全面的GIS解决方案,它提供了丰富的地图...

    ArcGIS Sliverlight 开发

    在IT行业中,ArcGIS Silverlight开发是一个特定领域的技术,它结合了Esri的地理信息系统(GIS)技术与Microsoft的Silverlight框架,用于构建交互式的、丰富的互联网地图应用程序。本篇文章将深入探讨ArcGIS ...

    实现地图定位冒气泡的功能

    Silverlight ArcGIS API是由Esri提供的一组工具包,用于在Silverlight应用程序中开发和集成地理信息系统(GIS)功能。它提供了一系列API和服务,使开发者能够轻松地在应用中添加地图、图层管理、空间查询等功能。本...

    ArcGIS Server RIA开发

    ### ArcGIS Server RIA开发详解 #### 背景与RIA技术 随着互联网技术的不断发展,用户对于网络应用的需求也在不断增长。...开发者可以根据实际需求选择合适的技术栈,构建高效、稳定的地理信息系统。

    GraphicsLayer导出为Shapefile 扩展

    ArcGIS Silverlight API是Esri ArcGIS平台的一部分,它允许开发人员使用Silverlight技术构建与地图交互的应用程序。API提供了丰富的控件和服务,如Map、Layer、Geometry等,使得用户能够创建具有复杂地图功能的Web...

Global site tag (gtag.js) - Google Analytics