Common_CustomJavaScript_CSharp\MapDataGridHover.aspx.cs
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // public partial class MapDataGridHover : System.Web.UI.Page { #region ASP.NET Page Life Cycle Event Handlers protected void Page_Load(object sender, System.EventArgs eventArgs) { // Get the __EVENTTARGET request parameter. This will specify any controls that are // the target of the event that triggered the Page request (i.e. postback) System.Collections.Specialized.NameValueCollection requestParameters = Page.Request.Params; string controlEvent = null; string controlID = requestParameters["__EVENTTARGET"]; // Check whether the __EVENTTARGET parameter is null or empty and whether it contains the // GridView control's ID if (!string.IsNullOrEmpty(controlID) && controlID.Contains(GridView1.ID)) { // Get any event arguments from the Page request controlEvent = requestParameters["__EVENTARGUMENT"]; // If the event arguments contain the string indicating initiation of our // custom postback event, call the method to zoom to the feature corresponding // to the clicked row if (controlEvent.Contains("CustomSelect$")) SelectRow(controlEvent, "EventID"); } // Make sure the page is not loading as a result of a postback (i.e. is in initial page load) if (!IsPostBack) { // Create table to hold data to link to graphics System.Data.DataTable dataTable = new System.Data.DataTable("FireEvents"); // Create and add columns System.Data.DataColumn eventIDDataColumn = new System.Data.DataColumn("EventID"); System.Data.DataColumn eventInfoDataColumn = new System.Data.DataColumn("EventInfo"); dataTable.Columns.Add(eventIDDataColumn); dataTable.Columns.Add(eventInfoDataColumn); // Create, populate, and add three rows System.Data.DataRow eventDataRow = dataTable.NewRow(); eventDataRow[eventIDDataColumn] = 1; eventDataRow[eventInfoDataColumn] = "value1"; dataTable.Rows.Add(eventDataRow); eventDataRow = dataTable.NewRow(); eventDataRow[eventIDDataColumn] = 2; eventDataRow[eventInfoDataColumn] = "value2"; dataTable.Rows.Add(eventDataRow); eventDataRow = dataTable.NewRow(); eventDataRow[eventIDDataColumn] = 3; eventDataRow[eventInfoDataColumn] = "value3"; dataTable.Rows.Add(eventDataRow); // Create a dataset and add the table to it System.Data.DataSet dataSet = new System.Data.DataSet(); dataSet.DataSetName = "FireEventsDataSet"; dataSet.Tables.Add(dataTable); // Set the dataset as the GridView's data source and add a handler for the GridView's RowDataBound event GridView1.DataSource = dataSet; GridView1.RowDataBound += new System.Web.UI.WebControls.GridViewRowEventHandler(GridView1_RowDataBound); // Add graphics to the map DrawGraphics(dataTable); // Bind the GridView to its data source and adjust its appearance GridView1.DataBind(); GridView1.Visible = true; GridView1.BorderWidth = 10; } } #endregion #region WebControl Event Handlers private void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs gridViewRowEventArgs) { // Only manipulate data rows if (gridViewRowEventArgs.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow) { ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality graphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)Map1.GetFunctionality("ADFGraphicsResource"); string graphicsTableName = Session["graphicsTableName"] as string; if (graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(graphicsTableName)) { string datasetName = graphicsMapFunctionality.GraphicsDataSet.DataSetName; ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = graphicsMapFunctionality.GraphicsDataSet.Tables[graphicsTableName] as ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer; string graphicsLayerClientID = Map1.GetGraphicsLayerClientID(graphicsLayer); //string.Format("{0}_{1}", datasetName, graphicsTableName); System.Web.UI.WebControls.GridViewRow gridViewRow = gridViewRowEventArgs.Row; // The index of the graphic feature is needed to get a reference to the graphic feature client-side. // The index of a graphic feature is zero-based, and is determined by the order in which it was added // to its graphic feature group. Here, we can use the gridViewRow's RowIndex, because we know that // the graphic features were added to the graphics layer in the order of the rows of the data table // that is bound to the GridView control int graphicFeatureIndex = gridViewRow.RowIndex; // Create a JavaScript string that will (1) set the background color of the current // row, (2) get the graphicFeatureGroup (i.e. layer) for the GraphicsLayer, (3) get // the graphicFeature corresponding to the current row index from the // graphicFeatureGroup, and (4) set the highlight on the graphicFeature string jsSetRowAndFeatureHighlight = "this.style.backgroundColor='{0}';" + "var graphicFeatureGroup = $find('{1}'); " + "var graphicFeature = graphicFeatureGroup.get({2}); " + "graphicFeature.set_highlight({3});"; // Assign the JavaScript string to the current row's onmouseover event. Specify the // row's background color as gray and the parameter to graphicFeature.set_highlight // as true gridViewRow.Attributes.Add("onmouseover", string.Format(jsSetRowAndFeatureHighlight, "gray", graphicsLayerClientID, graphicFeatureIndex, "true")); // Assign the JavaScript string to the current row's onmouseout event. Specify the // row's background color as white and the parameter to graphicFeature.set_highlight // as false gridViewRow.Attributes.Add("onmouseout", string.Format(jsSetRowAndFeatureHighlight, "white", graphicsLayerClientID, graphicFeatureIndex, "false")); // Construct a JavaScript string that uses Web ADF JavaScript to (1) retrieve the // graphicFeatureGroup (i.e. layer) corresponding to the graphics data layer, (2) // get the graphicFeature corresponding to the current row, (3) get the geometry of // the graphicFeature, (4) get the Page's client-side map object, and (5) zoom to // the graphicFeature string jsZoomToFeature = string.Format("var graphicFeatureGroup = $find('{0}'); " + "var graphicFeature = graphicFeatureGroup.get({1}); " + "var geometry = graphicFeature.get_geometry();" + "var map = $find('{2}');" + "map.zoomTo(geometry, .025, true);", graphicsLayerClientID, graphicFeatureIndex, Map1.ClientID); // Handle click on client gridViewRow.Attributes.Add("onclick", jsZoomToFeature); // Handle click on server //string jsDoPostback = ClientScript.GetPostBackEventReference(gridViewRow, "CustomSelect$" + // gridViewRow.RowIndex); //gridViewRow.Attributes.Add("onclick", jsDoPostback); } } } #endregion #region Instance Methods private void DrawGraphics(System.Data.DataTable dataTable) { // Get the map functionality for the graphics resource ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality graphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)Map1.GetFunctionality("ADFGraphicsResource"); // Make sure the graphics have not already been added to the map if ((Session["graphicsTableName"] != null) || (graphicsMapFunctionality.GraphicsDataSet.Tables.Contains((string)Session["graphicsTableName"]))) return; // Initialize default symbol ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol defaultSymbol = new ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/red_fire.gif"); defaultSymbol.XOffset = 16; defaultSymbol.YOffset = 16; defaultSymbol.Height = 32; defaultSymbol.Width = 32; defaultSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF; // Create default renderer with default symbol ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer defaultRenderer = new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(defaultSymbol); // Initialize selected symbol ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol selectedSymbol = new ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/yellow_fire.gif"); selectedSymbol.XOffset = 16; selectedSymbol.YOffset = 16; selectedSymbol.Height = 32; selectedSymbol.Width = 32; selectedSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF; // Create selected renderer with selected symbol ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer selectedRenderer = new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(selectedSymbol); // Initialize highlight symbol ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol highlightSymbol = new ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/blue_fire.gif"); highlightSymbol.XOffset = 16; highlightSymbol.YOffset = 16; highlightSymbol.Height = 32; highlightSymbol.Width = 32; highlightSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF; // Create highlight renderer with highlight symbol ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer highlightRenderer = new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(highlightSymbol); // Add a geometry column to the events table dataTable.Columns.Add("ADFGeometry", typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry)); // Convert the table to a feature graphics layer ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer eventsFeatureGraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(dataTable, defaultRenderer, selectedRenderer, highlightRenderer, false) as ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer; // Assign the layer's name and store it in session eventsFeatureGraphicsLayer.TableName = "MyEvents"; Session["graphicsTableName"] = eventsFeatureGraphicsLayer.TableName; // Create a random point geometry for each row in the table underlying the grapics layer System.Random randomClass = new System.Random(); foreach (System.Data.DataRow dataRow in eventsFeatureGraphicsLayer.Rows) { int x = randomClass.Next(-120, -80); int y = randomClass.Next(25, 45); ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = new ESRI.ArcGIS.ADF.Web.Geometry.Point(x, y); adfPoint.SpatialReference = Map1.SpatialReference; dataRow[eventsFeatureGraphicsLayer.GeometryColumnName] = adfPoint; } // Render the graphics layer on the client without callouts (i.e. maptips) eventsFeatureGraphicsLayer.RenderOnClient = true; eventsFeatureGraphicsLayer.EnableCallout = false; // Add the graphics layer to the graphics resource graphicsMapFunctionality.GraphicsDataSet.Tables.Add(eventsFeatureGraphicsLayer); // Refresh the graphics resource so the new graphics layer appears Map1.RefreshResource(graphicsMapFunctionality.Name); } private void SelectRow(string controlEvent, string uniqueIDFieldName) { // Parse the control event string string[] controlEventArray = controlEvent.Split('$'); // Set the selected index of the GridView to the argument of the control event GridView1.SelectedIndex = System.Int32.Parse(controlEventArray[1]); // Set the text color of the selected row to red GridView1.SelectedRowStyle.ForeColor = System.Drawing.Color.Red; // Find the column index of the unique ID field int uniqueIDFieldIndex = 0; foreach (System.Web.UI.WebControls.DataControlField dataControlField in GridView1.Columns) { if (dataControlField.HeaderText == uniqueIDFieldName) break; uniqueIDFieldIndex++; } // Get the value of the unique ID field from the selected row string selectedID = GridView1.SelectedRow.Cells[uniqueIDFieldIndex].Text; // Get the map functionality for the graphics resource ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality graphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)Map1.GetFunctionality("ADFGraphicsResource"); // Make sure the target graphics layer is present in the graphics resource string graphicsTableName = Session["graphicsTableName"] as string; if (graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(graphicsTableName)) { // Get the target graphics layer ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicsLayer = graphicsMapFunctionality.GraphicsDataSet.Tables[graphicsTableName] as ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer; // Unselect all features in the graphics layer foreach (System.Data.DataRow dataRow in graphicsLayer.Rows) dataRow["IS_SELECTED"] = false; // Use the event ID of the selected row in the GridView to retrieve the corresponding row in the data table // underlying the linked graphics layer System.Data.DataRow[] dataRowArray = graphicsLayer.Select(string.Format("EventID = '{0}'", selectedID)); // Assume that only one row was returned from the select operation, making the first row in the array // the one that corresponds to the graphic we wish to select System.Data.DataRow selectedDataRow = dataRowArray[0]; selectedDataRow["IS_SELECTED"] = true; // Get the selected row's geometry ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry = graphicsLayer.GeometryFromRow(selectedDataRow); // Get the envelope of the geoemtry ESRI.ArcGIS.ADF.Web.Geometry.Envelope boundingEnvelope = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope( double.MaxValue, double.MaxValue, double.MinValue, double.MinValue); if (adfGeometry is ESRI.ArcGIS.ADF.Web.Geometry.Polygon) { BoundingExtent((ESRI.ArcGIS.ADF.Web.Geometry.Polygon)adfGeometry, boundingEnvelope); // Expand the envelope to include some area around the feature on the map boundingEnvelope.Expand(5); } else if (adfGeometry is ESRI.ArcGIS.ADF.Web.Geometry.Point) { BoundingExtent((ESRI.ArcGIS.ADF.Web.Geometry.Point)adfGeometry, boundingEnvelope); //Map1.CenterAt(new ESRI.ArcGIS.ADF.Web.Geometry.Point(boundingEnvelope.XMin, boundingEnvelope.YMin)); // Expand the bounding envelope so that it is 1/8 of the map width. We do this instead of using // Envelope.Expand because that method expands by percentage. Since the bounding envelope of a // poing geometry has a height and width of zero, expanding by any percentage will result in no // change. double mapWidthSixteenth = Map1.GetFullExtent().Width / 16; boundingEnvelope = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope( boundingEnvelope.XMin - mapWidthSixteenth, boundingEnvelope.YMin - mapWidthSixteenth, boundingEnvelope.XMax + mapWidthSixteenth, boundingEnvelope.YMax + mapWidthSixteenth); } // Update the map's extent with the envelope Map1.Extent = boundingEnvelope; // Make sure the map has callback results if (Map1.CallbackResults.Count > 0) { // Register a script block to update the map via the Web ADF processCallbackResult function System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, this.GetType(), "updateMap", string.Format("ESRI.ADF.System.processCallbackResult('{0}');", Map1.CallbackResults.ToString().Replace("//", "////")), true); } } } // Retrieves the bounding box of a polygon private void BoundingExtent(ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfPolygon, ESRI.ArcGIS.ADF.Web.Geometry.Envelope boundingBox) { // Loop through all the rings of the polygon and update the bounding box to account for each vertex for (int i = 0; i < adfPolygon.Rings.Count; ++i) { ESRI.ArcGIS.ADF.Web.Geometry.Ring adfRing = adfPolygon.Rings[i]; for (int j = 0; j < adfRing.Points.Count; ++j) { BoundingExtent(adfRing.Points[j], boundingBox); } } } private void BoundingExtent(ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint, ESRI.ArcGIS.ADF.Web.Geometry.Envelope boundingBox) { // Update the passed-in envelope based on whether the passed-in point falls outside the envelope's bounds if (adfPoint.X < boundingBox.XMin) boundingBox.XMin = adfPoint.X; if (adfPoint.X > boundingBox.XMax) boundingBox.XMax = adfPoint.X; if (adfPoint.Y < boundingBox.YMin) boundingBox.YMin = adfPoint.Y; if (adfPoint.Y > boundingBox.YMax) boundingBox.YMax = adfPoint.Y; } #endregion }