ArcGIS Server 9.3 中线缓冲区查询的实现
效果如上图。步骤如下:
1、加入一个按钮和一个textbox,并为按钮设置监听事件。如下所示:
请输入缓冲距离:<ext:TextField ID="txtBuffer" runat="server">
</ext:TextField>米<br /><br />
<ext:Button ID="btnOperAreaAnaysis" Text="作业带分析runat="server">
<Listeners>
<Click Handler="OperAreaAnaysis(#{txtBuffer});" />
</Listeners>
</ext:Button>
2、前台的点击按钮的js相应函数如下:
//作业带分析
function OperAreaAnaysis(txtField) {
if (txtField.getValue() == "") {
Ext.MessageBox.alert('提示', '为了使用作业带分析,请设置缓冲距离!', function() {
txtField.focus(true, true);
});
return false;
}
var map = $find('Map1');
//画线函数
map.getGeometry(ESRI.ADF.Graphics.ShapeType.Path, SelectPipe, null, 'red', 'blue', 'pointer', true);
}
function SelectPipe(inputGeometry) {
var map = $find('Map1');
var val = document.getElementById("txtBuffer").value;
var ringCoords = inputGeometry.getPath(0).get_coordinates();
var CoordsStr = "";
for (var i = 0; i < ringCoords.length; i++) {
CoordsStr += ringCoords[i][0] + ":" + ringCoords[i][1] + ";";
}
//callback函数
SetCustomOperation(CoordsStr + "%" + "OAA" + "*" + val);
requestTableData();//获取查询后的结果并显示在一个Ext的gridpanel中。
}
在Default页面加入 callback函数如下:
function SetCustomOperation(sVal)
{
var message ='';
message +=',' + sVal;
var context ='Map1';
<%=sCallBack%>
}
3、后台的callback函数如下:
public partial class _Default : System.Web.UI.Page,ICallbackEventHandler
{ public string sCallBack = string.Empty;
private string smapstring = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
sCallBack = Page.ClientScript.GetCallbackEventReference(this, "message", "processCallbackResult", "context", "postBackError", true);
}
}
}
#region ICallbackEventHandler 成员
public string GetCallbackResult()
{
return smapstring;
}
public void RaiseCallbackEvent(string eventArgument)
{
if (eventArgument.Contains("OAA"))
{
string[] str1 = eventArgument.Split('*');
string[] str2 = str1[0].Split(',');
string[] str3=str2[1].Split('%');
string str = str3[0];
OperationAreaAnaysis(str,str1[1]);
}
}
#endregion
4、接着是实现功能函数了。如下:
public void OperationAreaAnaysis(string str, string bufferdistance)
{
DataSet DS = new DataSet();
DataTable DT = new DataTable();
try
{
object[] oa = new object[1];
if (Map1.Scale > 8000)
{
oa[0] = "Ext.MessageBox.alert('提示','为了使用作业带分析,请把地图比例尺放大到8000以内');";
CallbackResult pRst = new CallbackResult(null, null, "javascript", oa);
Map1.CallbackResults.Add(pRst);
smapstring = Map1.CallbackResults.ToString();
Session["Gridview1"] = null;
return;
}
ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal MapRes = Map1.GetFunctionality("管线").Resource as ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal;
IServerContext sc = MapRes.ServerContextInfo.ServerContext;
ESRI.ArcGIS.Geometry.IPointCollection pPointColl = (ESRI.ArcGIS.Geometry.IPointCollection)sc.CreateObject("esriGeometry.Polyline");
string[] Coord1 = str.Split(';');
for (int i = 0; i < Coord1.Length - 1; i++)
{
string[] Coord2 = Coord1[i].Split(':');
ESRI.ArcGIS.Geometry.IPoint pPoint = (ESRI.ArcGIS.Geometry.IPoint)sc.CreateObject("esriGeometry.Point");
pPoint.X = Convert.ToDouble(Coord2[0]);
pPoint.Y = Convert.ToDouble(Coord2[1]);
object missingVal = System.Reflection.Missing.Value;
pPointColl.AddPoint(pPoint, ref missingVal, ref missingVal);
}
IGeometry pPolylineGeo = pPointColl as IGeometry;
ESRI.ArcGIS.Geometry.IGeometry igeo = null;
//缓冲需要的Geometry
igeo = pPolylineGeo;
double distance = Convert.ToDouble(bufferdistance) / 100000;//因为本例的地图坐标是WGS84坐标,所以转换了下单位
ESRI.ArcGIS.ADF.Web.Geometry.Polygon mappoly = null;
ESRI.ArcGIS.Geometry.ITopologicalOperator topop = (ESRI.ArcGIS.Geometry.ITopologicalOperator)igeo;
ESRI.ArcGIS.Geometry.IPolygon bufferPolygon;
bufferPolygon = (ESRI.ArcGIS.Geometry.IPolygon)topop.Buffer(distance);
// 定义valueobject的点
ESRI.ArcGIS.ADF.ArcGISServer.PolygonN buffer_polyn;
// 进行comobject到valueobject之间的转换
buffer_polyn = (ESRI.ArcGIS.ADF.ArcGISServer.PolygonN) ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ComObjectToValueObject(bufferPolygon, sc, typeof(ESRI.ArcGIS.ADF.ArcGISServer.PolygonN));
//缓冲分析的结果
mappoly = (ESRI.ArcGIS.ADF.Web.Geometry.Polygon) ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToAdfPolygon(buffer_polyn);
//把buffer结果范围进行显示
ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer glayer = null;
//查找ElementGraphicsLayer在Buffer中
ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality Tempfunc = Map1.GetFunctionality("TempEle");
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = Tempfunc.Resource as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource;
foreach (System.Data.DataTable dt in gResource.Graphics.Tables)
{
if (dt is ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)
{
glayer=(ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)dt;
break;
}
}
//如果Buffer中没有ElementGraphicsLayer就新增加一ElementGraphicsLayer
if (glayer == null)
{
glayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
gResource.Graphics.Tables.Add(glayer);
}
//清除ElementGraphicsLayer中的内容
glayer.Clear();
ESRI.ArcGIS.ADF.Web.Geometry.Geometry geom = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)mappoly;
//设置点显示
ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement ge = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(geom, System.Drawing.Color.BlueViolet);
//设置透明度
ge.Symbol.Transparency = 50;
//添加到Buffer中进行显示
glayer.Add(ge);
Map1.RefreshResource(gResource.Name);
//缓冲区查询
ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisfunc = Map1.GetFunctionality("兴趣点");
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisRes = gisfunc.Resource;
bool supp = gisRes.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
if (supp)
{
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality QFunc;
QFunc=(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisRes.CreateFunctionality( typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
string[] lids;
string[] lnames;
QFunc.GetQueryableLayers(null, out lids, out lnames);
ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();
spatialfilter.ReturnADFGeometries = true;
spatialfilter.MaxRecords = 10000;
spatialfilter.Geometry = mappoly;
for (int i = 0; i < lids.Length; i++)
{
DataTable datatable = QFunc.Query(gisfunc.Name, lids[i], spatialfilter);
datatable.TableName = gisRes.Name + "_" + lnames[i];
if (datatable.Rows.Count > 0)
{
if (DT.Rows.Count < 1)
{
DT = datatable.Clone();
}
DT.Merge(datatable);
}
}
}
DS.Tables.Add(DT);
Session["Gridview1"] = DS;
smapstring = Map1.CallbackResults.ToString();
if (DS.Tables[0].Rows.Count < 1)
return;
}
catch (Exception ex)
{
SystemLog.WriteLog("作业带分析出错!", ex);
}
Session["Gridview1"] = DS;
}
5、以上函数就已经获得缓冲区查询后的dataset了,自己将他展示出来就行了(本博客中有相关的内容,例如ArcgisServer9.3 中矩形选择查询的实现(利用callback机制))。