目的:
1.arcgis server9.2 ADF实现GraphicsLayer的保存和读取显示。
准备工作:
1.用ArcGis Server Manager或者ArcCatalog发布一个叫usa的Map Service,并且把这个Service启动起来。
完成后的效果图:

开始:
1.新建名为SaveGraphicsLayer的ASP.NET Web应用程序,在页面上添加MapResourceManager1、Map1、Toolbar1、Toc1控件。
2.MapResourceManager1添加两个MapResourceItem,上面的一个名为myGraphicsLayer,DataSourceType为GraphicsLayer用来显示GraphicsLayer数据,下面一个名为usa,DataSourceType为ArcGIS Server Local,就是用来显示上面发布的usa的Map Service。其他的控件做相应是设置工作。
3.在Toolbar1中除了添加MapZoomIn、MapZoomOut、MapPan、MapFullExtent功能以外在添加一个Tool用来实现在地图上添加点,就是在myGraphicsLayer中显示,关于这个Tool的html代码如下:
1
<
esri:Tool
ClientAction
="Point"
JavaScriptFile
=""
Name
="AddGraphicPoint"
ServerActionAssembly
="SaveGraphicsLayer"
ServerActionClass
="SaveGraphicsLayer.ElementGraphicTool"
Text
="Add Graphic Point"
ToolTip
="Add Graphic Point"
/>
4.添加ElementGraphicTool.cs文件类用来实现上面的这个Tool的功能,在地图上点击然后添加一个黑色圆点的功能,具体不多解释了可以参考前面的例子ArcGIS.Server.9.2.DotNet自带例子分析(三、一) ,代码如下:
1
namespace
SaveGraphicsLayer
2

{
3
public class ElementGraphicTool : IMapServerToolAction
4
{
5
IMapServerToolAction 成员#region IMapServerToolAction 成员
6
7
public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs)
8
{
9
//获取map控件
10
ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control;
11
//转成点
12
PointEventArgs pointEventArgs = (PointEventArgs)toolEventArgs;
13
//屏幕点
14
System.Drawing.Point screenPoint = pointEventArgs.ScreenPoint;
15
16
//屏幕坐标转成地理坐标
17
ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(screenPoint.X, screenPoint.Y, adfMap.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
18
19
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality adfGraphicsMapFunctionality = null;
20
//MapFunctionality
21
foreach (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mapFunctionality in adfMap.GetFunctionalities())
22
{
23
//当Resource为ADFGraphicsResource,ADFGraphicsResource为GraphicsLayer, 保存在内存中用显示临时图层
24
if (mapFunctionality.Resource.Name == "myGraphicsLayer")
25
{
26
adfGraphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)mapFunctionality;
27
break;
28
}
29
}
30
31
//从adfGraphicsMapFunctionality获取名为Element Graphics的DataTable
32
//ElementGraphicsLayers通常用来显示图形元素,例如显示Map中被选择的图形元素。图层并不用来存储属性,而可以存储不同的图形类型。
33
ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = null;
34
foreach (System.Data.DataTable dataTable in adfGraphicsMapFunctionality.GraphicsDataSet.Tables)
35
{
36
if (dataTable.TableName == "Element Graphics")
37
{
38
elementGraphicsLayer = (ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)dataTable;
39
break;
40
}
41
}
42
43
//如果名为Element Graphics的DataTable为null,就新建Element Graphics DataTable添加到adfGraphicsMapFunctionality.GraphicsDataSet中,同时刷新Toc1显示
44
if (elementGraphicsLayer == null)
45
{
46
elementGraphicsLayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
47
elementGraphicsLayer.TableName = "Element Graphics";
48
adfGraphicsMapFunctionality.GraphicsDataSet.Tables.Add(elementGraphicsLayer);
49
}
50
51
//定义标点样式
52
ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol simpleMarkerSymbol = new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();
53
simpleMarkerSymbol.Color = System.Drawing.Color.Black;
54
simpleMarkerSymbol.Width = 10;
55
56
//定义标点选中样式
57
ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol simpleSelectedMarkerSymbol = new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();
58
simpleSelectedMarkerSymbol.Color = System.Drawing.Color.Yellow;
59
simpleSelectedMarkerSymbol.Width = 12;
60
simpleSelectedMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star;
61
62
ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement graphicElement = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfPoint, simpleMarkerSymbol, simpleSelectedMarkerSymbol);
63
//把标点添加到elementGraphicsLayer
64
elementGraphicsLayer.Add(graphicElement);
65
//刷新显示
66
if (adfMap.ImageBlendingMode == ImageBlendingMode.WebTier)
67
{
68
//整个地图控件刷新
69
adfMap.Refresh();
70
}
71
else
72
{
73
//只刷新部分Resource
74
adfMap.RefreshResource(adfGraphicsMapFunctionality.Resource.Name);
75
}
76
}
77
78
#endregion
79
}
80
}
81
5.这样就完成了在地图的GraphicsLayer添加点的功能,接下来我们要实现保存GraphicsLayer内容到数据库或者xml等,也能从数据库或者xml文件把保存的内容取出来显示。
6.首先在页面上添加两个button的input控件,一个是保存
GraphicsLayer,一个是把保存的GraphicsLayer取出来显示。具体html代码如下:
1
<
input
id
="saveGraphicsLayer"
type
="button"
onclick
='sGraphicsLayer()'
value
="保存GraphicsLayer"
/><
br
/>
2
<
input
id
="getGraphicsLayer"
type
="button"
onclick
='gGraphicsLayer()'
value
="取出GraphicsLayer"
/>
7. 切换到Default.aspx.cs页,同以前一样需要实现ICallbackEventHandler接口,实现GetCallbackResult()和RaiseCallbackEvent(string eventArgument)两方法,具体代码如下:
1
public
partial
class
_Default : System.Web.UI.Page, ICallbackEventHandler
2

{
3
public string m_Callback = "";
4
public string m_Callback2 = "";
5
6
protected void Page_Load(object sender, EventArgs e)
7
{
8
//生成(取出GraphicsLayer)按钮点击事件中字符串:WebForm_DoCallback('__Page',argument,processCallbackResult,context,processCallbackError,true)
9
m_Callback = Page.ClientScript.GetCallbackEventReference(Page, "argument", "processCallbackResult", "context", "processCallbackError", true);
10
//生成(保存GraphicsLayer)按钮点击事件中字符串:WebForm_DoCallback('__Page',argument,myProcess,context,processCallbackError,true)
11
m_Callback2 = Page.ClientScript.GetCallbackEventReference(Page, "argument", "myProcess", "context", "processCallbackError", true);
12
}
13
14
ICallbackEventHandler 成员#region ICallbackEventHandler 成员
15
private string _callbackArg;
16
//处理客户端请求,并且把结果返回给客户端
17
string ICallbackEventHandler.GetCallbackResult()
18
{
19
return RaiseCallbackEvent(_callbackArg);
20
}
21
22
//接收客户端请求的字符串变量
23
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
24
{
25
_callbackArg = eventArgument;
26
}
27
28
#endregion
29
30
//具体处理方法
31
private string RaiseCallbackEvent(string _callbackArg)
32
{
33
string v="";
34
return v;
35
}
36
}
8.接下来切换到Default页面的html视图,编写
两个button的input控件的js脚本,代码和说明如下:
1
<
script
>
2
//
保存GraphicsLayer
3
function
sGraphicsLayer()
4

{
5
var argument = "ControlID=Map1&ControlType=Map&Type=save";
6
var context = "Map";
7
var rv=<%= m_Callback2 %>;
8
eval(rv);
9
}
10
11
function
myProcess()
12

{
13
alert("保存成功!");
14
}
15
16
//
还原GraphicsLayer
17
function
gGraphicsLayer()
18

{
19
var argument = "ControlID=Map1&ControlType=Map&Type=get";
20
var context = "Map";
21
var rv=<%= m_Callback %>;
22
eval(rv);
23
}
24
25
function
processCallbackError()
26

{
27
alert("出错啦!");
28
}
29
30
<
/
script>
9.当点击
两个button的input控件时执行的sGraphicsLayer()和gGraphicsLayer()方法会请求服务端,由服务端进行处理,所以需要在cs端添加相应的处理代码,全部代码说明如下:
1
namespace
SaveGraphicsLayer
2

{
3
public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
4
{
5
public string m_Callback = "";
6
public string m_Callback2 = "";
7
8
protected void Page_Load(object sender, EventArgs e)
9
{
10
//生成(取出GraphicsLayer)按钮点击事件中字符串:WebForm_DoCallback('__Page',argument,processCallbackResult,context,processCallbackError,true)
11
m_Callback = Page.ClientScript.GetCallbackEventReference(Page, "argument", "processCallbackResult", "context", "processCallbackError", true);
12
//生成(保存GraphicsLayer)按钮点击事件中字符串:WebForm_DoCallback('__Page',argument,myProcess,context,processCallbackError,true)
13
m_Callback2 = Page.ClientScript.GetCallbackEventReference(Page, "argument", "myProcess", "context", "processCallbackError", true);
14
}
15
16
ICallbackEventHandler 成员#region ICallbackEventHandler 成员
17
private string _callbackArg;
18
//处理客户端请求,并且把结果返回给客户端
19
string ICallbackEventHandler.GetCallbackResult()
20
{
21
return RaiseCallbackEvent(_callbackArg);
22
}
23
24
//接收客户端请求的字符串变量
25
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
26
{
27
_callbackArg = eventArgument;
28
}
29
30
#endregion
31
32
//具体处理方法
33
private string RaiseCallbackEvent(string _callbackArg)
34
{
35
string v = "";
36
NameValueCollection keyValColl = CallbackUtility.ParseStringIntoNameValueCollection(_callbackArg);
37
if (keyValColl["Type"].ToString() == "save")//保存GraphicsLayer
38
{
39
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality adfGraphicsMapFunctionality = null;
40
foreach (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mapFunctionality in Map1.GetFunctionalities())
41
{
42
if (mapFunctionality.Resource.Name == "myGraphicsLayer")
43
{
44
adfGraphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)mapFunctionality;
45
break;
46
}
47
}
48
49
foreach (System.Data.DataTable dataTable in adfGraphicsMapFunctionality.GraphicsDataSet.Tables)
50
{
51
if (dataTable.TableName == "Element Graphics")
52
{
53
//序列化GraphicsLayer,序列化后就可以把GraphicsLayer存入到数据库中
54
string tv = SerializeDataTable(dataTable);
55
//这里为了方便就存Session
56
Session["myg"] = tv;
57
break;
58
}
59
}
60
}
61
else if (keyValColl["Type"].ToString() == "get")//还原GraphicsLayer
62
{
63
//获取存储的GraphicsLayer
64
string myg = Session["myg"].ToString();
65
DataTable ndt = DeserializeDataTable(myg);
66
67
IEnumerable gfc = Map1.GetFunctionalities();
68
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = null;
69
70
foreach (IGISFunctionality gfunc in gfc)
71
{
72
//当Resource为Selection时
73
if ((gfunc.Resource is ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) && (gfunc.Resource.Name == "myGraphicsLayer"))
74
{
75
//清除myGraphicsLayer的原先内容
76
gResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;
77
gResource.Graphics.Tables.Clear();
78
//把myGraphicsLayer添加到Graphics进行显示
79
gResource.Graphics.Tables.Add(ndt);
80
}
81
}
82
//刷新地图显示
83
if (Map1.ImageBlendingMode == ImageBlendingMode.WebTier)
84
{
85
Map1.Refresh();
86
}
87
else if (Map1.ImageBlendingMode == ImageBlendingMode.Browser)
88
{
89
Map1.RefreshResource(gResource.Name);
90
}
91
92
}
93
94
v = Map1.CallbackResults.ToString();
95
return v;
96
}
97
98
//序列化DataTable,转成string型方便存储
99
private static string SerializeDataTable(DataTable pDt)
100
{
101
System.IO.MemoryStream memory = new MemoryStream();
102
BinaryFormatter b = new BinaryFormatter();
103
b.Serialize(memory, pDt);
104
byte[] buff = memory.GetBuffer();
105
memory.Close();
106
string inputString = System.Convert.ToBase64String(buff);
107
return inputString;
108
}
109
110
//反序列化DataTable,把string型转成DataTable
111
public static DataTable DeserializeDataTable(string inputString)
112
{
113
byte[] buff = System.Convert.FromBase64String(inputString);
114
BinaryFormatter b = new BinaryFormatter();
115
DataTable dt= (DataTable)b.Deserialize(new MemoryStream(buff));
116
return dt;
117
}
118
119
}
120
}
121
10.这样就可以运行测试效果,首先点击Toolbar1上的Add Graphic Point工具然后在地图上点击添加2个点,然后点击<保存GraphicsLayer>的按钮就会提示保“存成功!”,然后继续点击
Add Graphic Point工具,继续在地图上添加3个点这样地图上就有5个点了,然后点击<取出GraphicsLayer>按钮这样地图上有回复到2原先保存的那2个点,测试成功。