利用JavaScript实现图片标注
2010-02-08 16:02阅读:
功能:功能实现了现在网络流行的定位后在地图上画一个图标,点击图标后弹出消息框。
思路:根据查询条件获得一个点的地图坐标,然后转换为屏幕坐标,利用js脚本动态图片到相应位置。
效果图如下:
主要实现步骤:
1、SearchMapIdentity.cs,该类主要实现查询获取点的地图坐标,地图坐标转换为屏幕坐标的方法,点击小图标时的回发调用,代码如下:
using System; using System.Data; using System.Collections; using
System.Collections.Specialized; using System.Configuration; using
System.Web; using System.Web.Security; using System.Web.UI; using
System.Web.UI.WebControls; using
System.Web.UI.WebControls.WebParts; using
System.Web.UI.HtmlControls; using ESRI.ArcGIS.ADF.Web; using
ESRI.ArcGIS.ADF.Web.UI.WebControls; using
ESRI.ArcGIS.ADF.Web.DataSources; using
ESRI.ArcGIS.ADF.Web.Geometry; using
ESRI.ArcGIS.ADF.Web.Display.Graphics; using
System.Collections.Generic; namespace SearchMapIdentityTask{ public
class SearchMapIdentity { #region 私有字段
private Page m_page; private Map m_map; private ArrayList mapPoints
= null; private string content; private string m_callbackInvocation
= ''; private string m_filePath = ''; private string queryText =
''; private DataTable queryResult = null; private string queryField
= ''; private string readFields = ''; #endregion #region 相关属性
public Map Map { get { return m_map; } set { m_map = value; } }
public Page Page { get { return m_page; } set { m_page = value; } }
public string ClientCallbackInvocation { get { return
m_callbackInvocation; } set { m_callbackInvocation = value; } }
public string FilePath { get { return m_filePath; } set {
m_filePath = value; } } public string QueryText { get { return
queryText; } set { queryText = value; } } public ArrayList
MapPoints { get { return mapPoints; } set { mapPoints = value; } }
public string Content { get { return content; } set { content =
value; } } public DataTable QueryResult { get { return queryResult;
} set { queryResult = value; } } //需要用来作为Where条件的查询字段 public string
QueryField { get { return queryField; } set { queryField = value; }
} //需要显示在详细信息里的字段 public string ReadFields { get { return
readFields; } set { readFields = value; } } #endregion #region 构造函数
public SearchMapIdentity() { } public SearchMapIdentity(Map map) {
if (map != null) { m_map = map; } } public SearchMapIdentity(Map
map, string filePath) { m_map = map; m_filePath = filePath; }
#endregion #region 处理点击查询回调的函数 public void Identify(bool
isFirstIdentify,string layername) { int x = 0; int y = 0; ArrayList
xy = null; if (this.MapPoints == null || isFirstIdentify == true) {
xy = GetXY(this.Map,layername); } else { xy = this.MapPoints as
ArrayList; } foreach (object o in xy) { object[] arrayPoints = o as
object[]; ESRI.ArcGIS.ADF.Web.Geometry.Point p =
(ESRI.ArcGIS.ADF.Web.Geometry.Point)arrayPoints[0];
System.Drawing.Point screenPoint = MapToScreenPoint(p.X, p.Y); x =
screenPoint.X; y = screenPoint.Y; string content = arrayPoints[1]
as string; string oa =
string.Format('ReDrawZommToPoint({0},{1},{2},{3},\'{4}\');', x, y,
p.X, p.Y, content); CallbackResult cr1 = new CallbackResult(null,
null, 'javascript', oa); this.Map.CallbackResults.Add(cr1); } }
#endregion #region 处理点击小图片时回调的函数 public void DrawInfoWin(double
mapX, double mapY, string content) { System.Drawing.Point
screen_point = MapToScreenPoint(mapX, mapY); int[] rate = {
screen_point.X, screen_point.Y - 38 }; object[] oa = new object[1];
string sa = 'showInfoWindow(' + rate[0].ToString() + ',' +
rate[1].ToString() + ','' + content + '');'; oa[0] = sa;
CallbackResult cr1 = new CallbackResult(null, null, 'javascript',
oa); this.Map.CallbackResults.Add(cr1); } #endregion #region
获得查询点的结果集 public ArrayList GetXY(Map Map1,string layername) {
ArrayList XY = new ArrayList(); IEnumerable func_enum =
Map1.GetFunctionalities(); System.Data.DataTable datatable = null;
foreach (ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality
gisfunctionality in func_enum) {
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource =
gisfunctionality.Resource; if
(gisfunctionality.Resource.DataSource.DataSourceDefinition == 'In
Memory') { continue; } bool supported =
gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
if (supported) {
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc; qfunc =
(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(
typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
string[] lids; string[] lnames; qfunc.GetQueryableLayers(null, out
lids, out lnames); int layer_index = -1; for (int i = 0; i <
lnames.Length; i++) { if (lnames[i] == layername) { layer_index =
i; break; } } if (layer_index == -1) { continue; }
ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new
ESRI.ArcGIS.ADF.Web.SpatialFilter(); spatialfilter.Geometry =
Map1.GetFullExtent(); spatialfilter.ReturnADFGeometries = true;
spatialfilter.MaxRecords = 1000; spatialfilter.WhereClause =
this.QueryField + ' like '%' + this.QueryText + '%'';
//txtSearch.Text; 查询条件 datatable = qfunc.Query(null,
lids[layer_index], spatialfilter); this.QueryResult = datatable; if
(datatable != null) { int intShape = -1; foreach
(System.Data.DataColumn col in datatable.Columns) { if
(col.DataType == typeof(Geometry)) { intShape = col.Ordinal; break;
} } for (int i = 0; i < datatable.Rows.Count; i++) {
ESRI.ArcGIS.ADF.Web.Geometry.Point point2 =
(ESRI.ArcGIS.ADF.Web.Geometry.Point)datatable.Rows[i].ItemArray[intShape];
//让地图以某个点居中 this.Map.CenterAt(point2); Array readFieldPairs =
this.ReadFields.Split(';'.ToCharArray()); string[] readFieldValue;
//循环构造Content属性 if (readFieldPairs.Length > 0) { for (int j = 0;
j < readFieldPairs.Length-1; j++) { readFieldValue =
readFieldPairs.GetValue(j).ToString().Split(':'.ToCharArray());
this.Content += readFieldValue[0] + ':' +
datatable.Rows[i][readFieldValue[1]].ToString()+'<br>'; } }
object[] arraryPoint = new object[2]; arraryPoint[0] = point2;
arraryPoint[1] = this.Content; //将Content属性清空 this.Content = '';
XY.Add(arraryPoint); } } } } this.MapPoints = XY; return XY; }
#endregion #region 由地图坐标经过转换得到屏幕坐标的点 public System.Drawing.Point
MapToScreenPoint(double mapX, double mapY) {
ESRI.ArcGIS.ADF.Web.Geometry.Point adf_point = new
ESRI.ArcGIS.ADF.Web.Geometry.Point(mapX, mapY);
ESRI.ArcGIS.ADF.Web.Geometry.TransformationParams
transformationParameters =
this.Map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToScreen);
System.Drawing.Point screen_point =
adf_point.ToScreenPoint(transformationParameters); return
screen_point; } #endregion } }
2、SearchMapIdentityTask.cs,这个就是包装Task的类,主要代码如下
using System; using System.Collections.Generic; using System.Text;
using System.Web; using ESRI.ArcGIS.ADF.Web.UI.WebControls; using
ESRI.ArcGIS.ADF.Web.DataSources; using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls; using System.Web.UI; using
System.Collections; using System.Collections.Specialized; using
System.Data; using System.ComponentModel; using
System.Text.Regularexpression_rs; namespace SearchMapIdentityTask {
public class SearchMapIdentityTask : FloatingPanelTask { private
TextBox textBox = null; private HtmlInputButton button = null;
private HtmlSelect selLayers = null; private HtmlInputButton clear
= null; SearchMapIdentity searchMapIdentity = null; private string
queryField = ''; private string readFileds = ''; #region 相关属性
[Description('用户where条件中要查询的字段')] public string QueryField { get {
return queryField; } set { queryField = value; } }
[Description('设置需要在详细信息中显示的字段,格式为(字段1中文名:字段1数据库表名;字段2中文名:字段2数据库表名)')]
public string ReadFileds { get { return readFileds; } set {
readFileds = value; } } #endregion #region 构造函数 public
SearchMapIdentityTask() { this.Width = Unit.Pixel(200); }
#endregion #region 构建子控件 protected override void
CreateChildControls() { Controls.Clear();
base.CreateChildControls(); textBox = new TextBox(); textBox.ID =
'textBox'; textBox.Width=200; button = new HtmlInputButton();
button.ID = 'button'; button.Value = '查询'; clear = new
HtmlInputButton(); clear.ID = 'clear'; clear.Value = '清除结果';
selLayers = new HtmlSelect(); selLayers.ID = 'sellayer';
Controls.Add(selLayers); Controls.Add(textBox);
Controls.Add(button); Controls.Add(clear); string argument =
string.Format(''args='+document.getElementByIdx('{0}').value',
selLayers.ClientID); argument +=
string.Format('+':'+strTrim(document.getElementByIdx('{0}').value)',
textBox.ClientID); string onClick =
string.Format('executeTask({0},'{1}');', argument,
base.CallbackFunctionString);
//调用SearchMapIdentity.js里的clearIdentifyDiv函数,清楚上一次查询产生的div onClick
+= 'clearIdentifyDiv();'; string onKeyDown = string.Format('
if(event.keyCode==13) {{{0} return false;}}', onClick);
button.Attributes.Add('onclick', onClick);
//点击clear按钮时,调用清除查询结果的js函数 clear.Attributes.Add('onclick',
'clearIdentifyDiv()'); textBox.Attributes.Add('onkeydown',
onKeyDown); //调用填充下拉框函数 FillLayerSelect(); } #endregion #region
OnLoad—初始化一些初始变量 protected override void OnLoad(EventArgs e) {
base.OnLoad(e); //进行相关属性检查 if (this.QueryField == '') { throw new
Exception('QueryField属性未设置'); } Regex regex = new
Regex('^(\\S+:\\S+;)+$'); if (this.ReadFileds == '') { throw new
Exception('ReadFileds属性未设置'); } else if
(!regex.IsMatch(this.ReadFileds)) { throw new
Exception('ReadFileds格式不正确,请查看描述后修改!'); }
this.MapInstance.ScaleChanged += new
MapScaleChangeEventHandler(Map_ScaleChanged);
searchMapIdentity = new SearchMapIdentity(this.MapInstance);
searchMapIdentity.QueryField = this.QueryField;
searchMapIdentity.ReadFields = this.ReadFileds;
//searchMapIdentity.SetupIdentify(); if
(this.Page.Session['MapPoints'] != null) {
searchMapIdentity.MapPoints = this.Page.Session['MapPoints'] as
ArrayList; } } #endregion #region OnPreRender - 加载客户端脚本和设置属性
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e); if (this.Page != null) {
//注册SearchMapIdentity脚本 ClientScriptManager scriptMgr =
Page.ClientScript; Type controlType = this.GetType(); string
fileName = controlType.Namespace + '.SearchMapIdentity.js';
scriptMgr.RegisterClientScriptResource(controlType,
fileName); //注册回调的字符串 System.Text.StringBuilder sb = new
System.Text.StringBuilder(); sb.Append('<script
language='javascript' type='text/javascript'>var
MapSearchIdentifyCallbackStr = '' +
base.CallbackFunctionString + '';</script>'); if
(!Page.ClientScript.IsClientScriptBlockRegistered('MapSearchIdentify'))
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(),
'MapSearchIdentify', sb.ToString()); } } #endregion #region 回调处理函数
//得到传递进来的参数,赋给base.Input public override string GetCallbackResult()
{ NameValueCollection keyValCol1 =
CallbackUtility.ParseStringIntoNameValueCollection(_callbackArg);
if (keyValCol1['EventArg'] == 'executeTask') { string sInArgs =
keyValCol1['args']; string delim = ':'; char[] delchar =
delim.ToCharArray(); string[] args = sInArgs.Split(delchar);
object[] inputs = new object[2]; inputs[0] = args[0]; inputs[1] =
args[1]; base.Input = inputs; } else if (keyValCol1['EventArg'] ==
'startTaskActivityIndicator') { } else if
(keyValCol1['EventArg'] == 'hidden') { } //自己添加的分支,用户处理点击小图片是的回发处理
else if (keyValCol1['EventArg'] == 'ShowInfoWin') { double MapX =
Convert.ToDouble(keyValCol1['MapX']); double MapY =
Convert.ToDouble(keyValCol1['MapY']); string content =
keyValCol1['Content']; searchMapIdentity.DrawInfoWin(MapX, MapY,
content); return this.MapInstance.CallbackResults.ToString(); }
return base.GetCallbackResult(); } #endregion #region 执行TASK public
override void ExecuteTask() { if (Input == null) return; object[]
inputs = Input as object[]; string selLayer = inputs[0] as string;
string queryTxt = (string)inputs[1]; ViewState['selLayer'] =
selLayer; ViewState['queryTxt'] = queryTxt;
searchMapIdentity.QueryText = queryTxt;
searchMapIdentity.Identify(true, selLayer); DataTable datatable =
searchMapIdentity.QueryResult as DataTable; DataSet ds = new
DataSet(); ds.Tables.Add(datatable); ds.DataSetName = '查询'+
queryTxt +'的结果为:'; Page.Session['MapPoints'] =
searchMapIdentity.MapPoints; base.Results = ds; } #endregion
#region 处理依赖资源 public override
List<GISResourceItemDependency>
GetGISResourceItemDependencies() { throw new Exception('The
method or operation is not implemented.'); } #endregion #region
渲染控件格式 protected override void RenderContents(HtmlTextWriter
writer) { writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this.selLayers.RenderControl(writer); writer.RenderEndTag();
writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.AddStyleAttribute(HtmlTextWriterStyle.WhiteSpace, 'nowrap');
writer.RenderBeginTag(HtmlTextWriterTag.Td); if
(!string.IsNullOrEmpty(this.Input as string)) { this.textBox.Text =
this.Input as string; } else { this.textBox.Text = ''; }
this.textBox.RenderControl(writer); writer.RenderEndTag();
writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
this.button.RenderControl(writer); writer.Write(' ');
this.clear.RenderControl(writer); writer.RenderEndTag();
writer.RenderEndTag(); writer.RenderEndTag(); } #endregion #region
辅助函数 Map _map = null; TaskResults _taskResults = null; private Map
MapInstance { get { if (_map == null) { for (int i = 0; i <
base.TaskResultsContainers.Count; i++) { _taskResults =
Utility.FindControl(TaskResultsContainers[i].Name, Page) as
TaskResults; if (_taskResults != null && _taskResults.Map
!= null && _taskResults.Map.Length > 1) { _map =
Utility.FindControl(_taskResults.Map, this.Page) as Map; } if (_map
!= null) break; } } return _map; } } private TaskResults
getTaskResults() { if (_taskResults == null) _map = MapInstance;
return _taskResults; } //填充selLayers下拉框 private void
FillLayerSelect() { ListItem layerItem; IMapFunctionality mf =
MapInstance.GetFunctionality(0); if (mf == null) { layerItem = new
ListItem('<no layers found>', 'null');
selLayers.Items.Add(layerItem); return; } IGISResource gisresource
= mf.Resource; bool supported =
gisresource.SupportsFunctionality(typeof(IQueryFunctionality));
selLayers.Items.Clear(); if (supported) { IQueryFunctionality qfunc
= gisresource.CreateFunctionality(typeof(IQueryFunctionality),
null) as IQueryFunctionality; string[] lids; string[] lnames;
qfunc.GetQueryableLayers(null, out lids, out lnames,
ESRI.ArcGIS.ADF.Web.FeatureType.Point); int i = 0; while (i <
lnames.Length) { layerItem = new ListItem(lnames[i], lnames[i]);
selLayers.Items.Add(layerItem); i++; } } } #endregion #region
地图比例尺变化以后要执行的函数 protected void Map_ScaleChanged(object sender,
ESRI.ArcGIS.ADF.Web.UI.WebControls.ScaleEventArgs args) { if
(Page.IsPostBack || Page.IsCallback) { if (ViewState['selLayer'] !=
null && ViewState['queryTxt'] != null) {
searchMapIdentity.QueryText = '四川';
searchMapIdentity.Identify(false, ViewState['selLayer'] as string);
} } } #endregion } }
3、SearchMapIdentity.js,主要是些动态创建和定位div的js脚本
//显示详细信息的服务器回调函数 function DrawInfowindow(mapX,mapY,content) { if
(mapX==null||mapY==null) return; var
argument='EventArg=ShowInfoWin&MapX=' + mapX + '&MapY=' +
mapY + '&Content=' + content; var context =
Maps['Map1'].controlName;
eval_r(MapSearchIdentifyCallbackStr); } //删除已经标示的DIV
function clearIdentifyDiv() { var o = map.overlayObject while
(o.hasChildNodes()) { o.removeChild(o.lastChild); } } //将图片定位到指定点
function showZoomToPoint(x,y,mapX,mapY,content) { map =
Maps['Map1']; var pointdiv = document.createElement_x('div');
pointdiv.style.position='absolute'; pointdiv.style.zIndex=2; //
point is bottom center... 2 pixels up for shadow var cWidth =
Math.floor(pointdiv.clientWidth / 2); var cHeight =
pointdiv.clientHeight; if (cWidth==0) cWidth = 20; if (cHeight==0)
cHeight = 38; var idLeft = x -
parseInt(map.divObject.style.left)-cWidth/2; var idTop = y -
parseInt(map.divObject.style.top) - cHeight + 2;
pointdiv.innerHTML='<img src=images/blank.gif alt='' border='0'
hspace='0' vspace='0' onclick=\'DrawInfowindow(' + mapX + ',' +
mapY + ','' + content + '');\' />';
map.overlayObject.appendChild(pointdiv); pointdiv.style.left=
idLeft; pointdiv.style.top=idTop; return false; } //重新将图片定位到指定点
function ReDrawZommToPoint(x,y,mapX,mapY,content) {
window.setTimeout('showZoomToPoint(' + x + ',' + y + ',' + mapX +
',' + mapY + ',\'' + content + '\')',1000); } //显示详细信息的函数 function
showInfoWindow(x,y,content) { var div =
document.getElementByIdx('InfoWindow'); if (div==null) {
addInfowindow(); } window.status=content;
document.getElementByIdx('infowindowTitle').innerHTML='<b><font
color='black'>详细信息</font></b>' var
infoContentHtml='<font color='black'>' + content +
'</font><br>'; var
oNearQuery=document.getElementByIdx('tr_NearQuery');
infoContentHtml += '<span onclick='alert('call js functions u
need');'><u>点我吧</u></span> ';
document.getElementByIdx('infowindowContent').innerHTML=
infoContentHtml ; var div = document.getElementByIdx('InfoWindow');
var cWidth = Math.floor(div.clientWidth / 2); var cHeight =
div.clientHeight; if (cWidth==0) cWidth = 235; if (cHeight==0)
cHeight = 148; var idLeft = x - parseInt(map.divObject.style.left)
;//- cWidth; var idTop = y - parseInt(map.divObject.style.top) -
cHeight + 2; window.setTimeout('moveLayer('InfoWindow', ' + idLeft
+ ', ' + idTop + '); showLayer('InfoWindow');', 0); return false; }
//添加显示信息的div function addInfowindow() { var content=''; content =
'<div id='InfoWindow' ><table border='0' cellpadding='0'
cellspacing='0'>'; content += '<tr> '; content += ' <td
valign='top'><table width='235' border='0' cellspacing='0'
cellpadding='0'> '; content += ' <tr> '; content += '
<td><table border='0' cellspacing='0' cellpadding='0'>
'; content += ' <tr> '; content += ' <td id
='infowindowTitle' width='218' valign='middle'></td> ';
content += ' <td width='17' valign='middle'><img
onclick=\'closeInfoWindow();\'
onmouseover='this.src=\'images/close2.png\''
onmouseout='this.src=\'images/close1.png\'' src='images/close1.png'
width='8' height='6' /></td> '; content += ' </tr>
'; content += ' </table></td> '; content += '
</tr> '; content += ' <tr> '; content += ' <td >
'; content += ' <table align='center' width='220' border='0'
cellspacing='0' cellpadding='0'> '; content += ' <tr> ';
content += ' <td background='images/h-line.png' ></td>
'; content += ' </tr>'; content += ' </table> ';
content += ' </td> '; content += ' </tr> '; content +=
' <tr> '; content += ' <td valign='top'> '; content +=
' <table width='230' border='0' cellpadding='0'
cellspacing='0'> '; content += ' <tr> '; content += '
<td valign='top'> '; content += ' <div
id='infowindowContent' ></div> '; content += ' </td>
'; content += ' </tr>'; content += '
</table></td> '; content += ' </tr> '; content +=
' </table></td> '; content += ' </tr>'; content
+= '</table></div>';
map.overlayObject.insertAdjacentHTML('BeforeEnd', content); }
//关闭显示详细信息的div function closeInfoWindow() { var div =
document.getElementByIdx('InfoWindow'); if (div!=null) {
hideLayer('InfoWindow'); } } //辅助函数——清除字符串空格 function strTrim(s) {
var reg=/(^\s*)|(\s*$)/g; var ss=s.replace(reg,''); return ss;
}