DockWindow.vb
' Copyright 2011 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. ' ' 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 at <your ArcGIS Explorer install location>/DeveloperKit/userestrictions.txt. ' Imports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.Drawing Imports System.Data Imports System.Linq Imports System.Text Imports System.Windows.Forms Imports ESRI.ArcGISExplorer Imports ESRI.ArcGISExplorer.Application Imports ESRI.ArcGISExplorer.Mapping Imports ESRI.ArcGISExplorer.Geometry Imports ESRI.ArcGISExplorer.Data Imports ESRI.ArcGISExplorer.Threading Public Class DockWindow Inherits ESRI.ArcGISExplorer.Application.DockWindow Public Sub New() InitializeComponent() End Sub Private _mapDisp As MapDisplay = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay Private Sub txtLocation_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles txtLocation.DragDrop 'Make sure we have a treenode being dropped If Not e.Data.GetDataPresent(GetType(TreeNode)) Then Return End If 'From the node, grab the text to display and then save the note for use later Dim node As TreeNode = TryCast(DirectCast(e.Data.GetData(GetType(TreeNode)), TreeNode).Clone(), TreeNode) txtLocation.Text = node.Text txtLocation.Tag = node.Tag End Sub Private Sub txtLocation_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles txtLocation.DragOver e.Effect = DragDropEffects.None 'make sure that we only allow point data from notes Dim node As TreeNode = TryCast(DirectCast(e.Data.GetData(GetType(TreeNode)), TreeNode).Clone(), TreeNode) Dim result As ESRI.ArcGISExplorer.Mapping.Note = TryCast(node.Tag, Note) If result IsNot Nothing Then If result.Graphic.Geometry.[GetType]() Is GetType(ESRI.ArcGISExplorer.Geometry.Point) Then e.Effect = DragDropEffects.Move Return End If End If Return End Sub Private Sub btnExecute_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnExecute.Click 'Make sure we have values in the location and distance boxes. If txtDistance.Text = "" OrElse txtLocation.Text = "" Then Return End If 'Make sure the value in the distance box is numeric If Not IsNumeric(txtDistance.Text) Then MessageBox.Show("Distance value must be numeric!!", "Bad Value") Return End If 'Make sure distance value is less than 10 miles If System.Convert.ToDouble(txtDistance.Text) > 10 Then MessageBox.Show("Distance value must be less than 10 miles!!", "Bad Value") Return End If 'Get the point geometry out of the tag on the Location textbox Dim queryPt As ESRI.ArcGISExplorer.Geometry.Point = Nothing If txtLocation.Tag.[GetType]() Is GetType(Note) Then Dim result As ESRI.ArcGISExplorer.Mapping.Note = TryCast(txtLocation.Tag, Note) queryPt = TryCast(result.Graphic.Geometry, ESRI.ArcGISExplorer.Geometry.Point) Else queryPt = TryCast(txtLocation.Tag, ESRI.ArcGISExplorer.Geometry.Point) End If If queryPt Is Nothing Then Return End If 'Execute the query against the Demographics data QueryDemographics(queryPt, System.Convert.ToDouble(txtDistance.Text)) End Sub Private Sub QueryDemographics(ByVal queryPt As ESRI.ArcGISExplorer.Geometry.Point, ByVal dist As Double) 'Open up ProgressHelper to show are progress. Dim help As ProgressHelper = New ProgressHelper("Query Progress", "Calculating Demographics in the area", "Forming query polygon ...") help.Show() 'Create a square polygon to pass to the service for query purposes based on the location Dim pts As New List(Of ESRI.ArcGISExplorer.Geometry.Point)() pts.Add(TryCast(GeometryOperations.Move(queryPt, dist, dist, Unit.Linear.MilesStatute), ESRI.ArcGISExplorer.Geometry.Point)) pts.Add(TryCast(GeometryOperations.Move(queryPt, dist, (dist * -1), Unit.Linear.MilesStatute), ESRI.ArcGISExplorer.Geometry.Point)) pts.Add(TryCast(GeometryOperations.Move(queryPt, (dist * -1), (dist * -1), Unit.Linear.MilesStatute), ESRI.ArcGISExplorer.Geometry.Point)) pts.Add(TryCast(GeometryOperations.Move(queryPt, (dist * -1), dist, Unit.Linear.MilesStatute), ESRI.ArcGISExplorer.Geometry.Point)) Dim searchPoly As New Polygon(pts, queryPt.CoordinateSystem) searchPoly.Close() searchPoly = GeometryOperations.Project(searchPoly, CoordinateSystem.GeographicCoordinateSystems.NorthAmerica.NAD1983) help.UpdateMessage("Executing SOAP call to ArcGIS Online ...") 'Make the connection to the server we will use for retrieving demographic information Dim mapServer As New censusServer.ESRI_Census_USA_MapServer() mapServer.Url = "http://sampleserver1.arcgisonline.com/ArcGIS/services/Demographics/ESRI_Census_USA/MapServer" 'Call the Census service to calculate the demographic information for the polygon. Dim spf As New censusServer.SpatialFilter() spf.FilterGeometry = SoapConverter.GeometryToSoap(Of Polygon, censusServer.PolygonN)(searchPoly) spf.SpatialRel = censusServer.esriSpatialRelEnum.esriSpatialRelIntersects spf.SubFields = "AGE_UNDER5, AGE_5_17, AGE_18_21, AGE_22_29, AGE_30_39, AGE_40_49, AGE_50_64, AGE_65_UP, MALES, FEMALES" Dim temp As String = mapServer.GetDefaultMapName() Dim recs As censusServer.RecordSet = mapServer.QueryFeatureData("Layers", 1, spf) help.UpdateMessage("Summing results of query ...") 'Loop through the records that were returned and tally up the demographic data Dim males As Integer = 0 Dim females As Integer = 0 Dim age_u5 As Integer = 0 Dim age_5_17 As Integer = 0 Dim age_18_21 As Integer = 0 Dim age_22_29 As Integer = 0 Dim age_30_39 As Integer = 0 Dim age_40_49 As Integer = 0 Dim age_50_64 As Integer = 0 Dim age_65_up As Integer = 0 For j As Integer = 0 To recs.Records.Length - 1 Dim censusRec As censusServer.Record = recs.Records(j) males += System.Convert.ToInt16(censusRec.Values(9)) females += System.Convert.ToInt16(censusRec.Values(10)) age_u5 += System.Convert.ToInt16(censusRec.Values(1)) age_5_17 += System.Convert.ToInt16(censusRec.Values(2)) age_18_21 += System.Convert.ToInt16(censusRec.Values(3)) age_22_29 += System.Convert.ToInt16(censusRec.Values(4)) age_30_39 += System.Convert.ToInt16(censusRec.Values(5)) age_40_49 += System.Convert.ToInt16(censusRec.Values(6)) age_50_64 += System.Convert.ToInt16(censusRec.Values(7)) age_65_up += System.Convert.ToInt16(censusRec.Values(8)) Next Dim genderTotal As Integer = males + females Dim ageTotal As Integer = age_u5 + age_5_17 + age_18_21 + age_22_29 + age_30_39 + age_40_49 + age_50_64 + age_65_up Dim dMales As Double = (System.Convert.ToDouble(males) / System.Convert.ToDouble(genderTotal)) * 100 Dim dFemales As Double = (System.Convert.ToDouble(females) / System.Convert.ToDouble(genderTotal)) * 100 Dim dage_u5 As Double = (System.Convert.ToDouble(age_u5) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_5_17 As Double = (System.Convert.ToDouble(age_5_17) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_18_21 As Double = (System.Convert.ToDouble(age_18_21) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_22_29 As Double = (System.Convert.ToDouble(age_22_29) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_30_39 As Double = (System.Convert.ToDouble(age_30_39) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_40_49 As Double = (System.Convert.ToDouble(age_40_49) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_50_64 As Double = (System.Convert.ToDouble(age_50_64) / System.Convert.ToDouble(ageTotal)) * 100 Dim dage_65_up As Double = (System.Convert.ToDouble(age_65_up) / System.Convert.ToDouble(ageTotal)) * 100 help.UpdateMessage("Creating popup message ...") 'Figure out the percentage information for males and females, then generate the popup using 'the Google chart api. Dim perc As String = "Males(" & dMales.ToString("###.#") & "%)|Females(" & dFemales.ToString("###.#") & "%)" Dim popup As String = "<b><font size='4'>" & "Gender</font></b>" & "<br><img src=""" & "http://chart.apis.google.com/chart?cht=p3&chd=t:" & dMales.ToString() & "," & dFemales.ToString() & "&chs=350x100&chl=" & perc & """ />" popup += "<br><br><b><font size='4'>" & "Age</font></b>" & "<br><img src=""" & "http://chart.apis.google.com/chart?cht=p3&chd=t:" & dage_u5.ToString() & "," & dage_5_17.ToString() popup += "," & dage_18_21.ToString() & "," & dage_22_29.ToString() & "," & dage_30_39.ToString() & "," & dage_40_49.ToString() & "," & dage_50_64 & "," & dage_65_up & "&chs=350x100&chl=Under 5|5 to 17|18 to 21|22 to 29|30 to 39|40 to 49|50 to 64|over 64" & """ />" 'Add the polygon to the map as a note or graphic depending on the checkbox Dim searchGraphic As New Graphic(searchPoly, Symbol.CreateFill(Color.Orange, Color.Black)) searchGraphic.Tag = "demographic query polygon" If chkResult.Checked Then Dim newNote As New Note(txtDistance.Text & " mile demographic query", searchGraphic) newNote.Popup.Content = popup _mapDisp.Map.ChildItems.Add(newNote) Else RemovePreviousGraphic() _mapDisp.Graphics.Add(searchGraphic) btnRemove.Enabled = True End If 'Check extent and make sure we aren't zoomed in too far to show all of search shape Dim env As Envelope = GeometryOperations.Scale(searchPoly.GetEnvelope(), 1.25) If _mapDisp.Extent.Height < env.Height Or _mapDisp.Extent.Width < env.Width Then _mapDisp.ZoomTo(env) 'Whether we are adding a graphic or a note, we can still show the popup information (it 'just won't be stored for the graphic). ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay.HidePopups(True) Dim tempPopup As Popup = New Popup(ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay, popup, "Demographic information") tempPopup.Activate() 'Close out the progress window help.Close() Return End Sub Private Sub RemovePreviousGraphic() If _mapDisp.Graphics.Count = 0 Then Return End If 'Loop through the graphics in the map and remove the first one found with the demographic query tag Dim graphs As GraphicCollection = _mapDisp.Graphics For Each graph As Graphic In graphs If DirectCast(graph.Tag, String) = "demographic query polygon" Then _mapDisp.Graphics.Remove(graph) Return End If Next End Sub Private Sub btnLocate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLocate.Click 'Capture a point from the map Dim loc As ESRI.ArcGISExplorer.Geometry.Point = _mapDisp.TrackPoint() If loc Is Nothing Then Return End If 'If we got a point, then add some text to the location box and the point as the tag txtLocation.Text = loc.Y.ToString("###.##") & " " & loc.X.ToString("###.##") txtLocation.Tag = TryCast(loc, Object) End Sub Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click 'Call the routine to search for a demographic query graphic RemovePreviousGraphic() btnRemove.Enabled = False End Sub End Class