Friday, February 11, 2011

Zoom-in to feature in ArcGIS Engine using ArcGIS Server and REST

The first blog post on how to use ArcGIS Server from ArcGIS Engine. This post show how to zoom in on a feature using a custom query.

I start by creating JSON query:

 Private Sub TestREST2ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TestREST2ToolStripMenuItem.Click
Dim state As String = "Alaska"
'Skapar fråga för REST:
Dim requestUri As String = "http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer/4/query"
Dim data As New StringBuilder()
data.AppendFormat("?f={0}", "json")
'case sensitive
data.AppendFormat("&Where=Name%3D'" & state & "'")
data.AppendFormat("&returnGeometry=true")
data.AppendFormat("&returnIdsOnly=false")
data.AppendFormat("&outFields=*")
ZoomTo(requestUri, data.ToString())
End Sub


Check out the service http://server.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Median_Household_Income/MapServer/4/query to find out what questions you can ask.

The ZoomTo method looks like this and loops through the result for the features returned and zoom in to the extent of the polygon returned:

 Sub ZoomTo(ByVal requestUri As String, ByVal data As String)
'Ställer REST frågan:
Dim request As HttpWebRequest = TryCast(WebRequest.Create(requestUri & data), HttpWebRequest)
'Hanterar resultat
Using response As HttpWebResponse = TryCast(request.GetResponse(), HttpWebResponse)
Dim reader As New StreamReader(response.GetResponseStream())
Dim responseString As String = reader.ReadToEnd()
Dim jss As New System.Web.Script.Serialization.JavaScriptSerializer()
jss.MaxJsonLength = 10000000
'Skulle kunna köra med datakontrakt, men då måste man skapa objektstrukturen.
'DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(object))
'Parsar resultatet för att skapa upp polygon.
Dim results As IDictionary(Of String, Object) = TryCast(jss.DeserializeObject(responseString), IDictionary(Of String, Object))
If results IsNot Nothing AndAlso results.ContainsKey("features") Then
Dim features As IEnumerable(Of Object) = TryCast(results("features"), IEnumerable(Of Object))
For Each feature As IDictionary(Of String, Object) In features
Dim geometries As IDictionary(Of String, Object) = TryCast(feature("geometry"), IDictionary(Of String, Object))
Dim polygon As Polygon = New Polygon()
Dim rings As IEnumerable(Of Object) = TryCast(geometries("rings"), IEnumerable(Of Object))
Dim i As Integer = rings.Count()
For Each ring As IEnumerable(Of Object) In rings
Dim pointCol As IPointCollection = New Ring()
For Each vertex As IEnumerable(Of Object) In ring
Dim point As IPoint = New Point()
point.X = Convert.ToDouble(vertex.ElementAt(0))
point.Y = Convert.ToDouble(vertex.ElementAt(1))
pointCol.AddPoint(point)
Next
polygon.AddPointCollection(pointCol)
Next
'Sätter om extent via polygonens
Dim control As AxMapControl = axMapControl1
control.ActiveView.Extent = TryCast(polygon, IPolygon).Envelope
control.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewAll, Nothing, Nothing)
'GetLegend()
'Dim attributes As IDictionary(Of String, Object) = TryCast(feature("attributes"), IDictionary(Of String, Object))
Next
End If
End Using
End Sub



I'm making a lot of assumptions here, that the result is a polygon, that there is only one polygon returned. But it shows the concept of getting features using REST.



The test application shows US when I start:



And zoom in on Alaska when I run the test method:


I have not done anything to boost the performance, so it feels very slow.

No comments: