Tutorial GIS Silverlight : Silverlight GIS ESRI rilevamento delle coordinate

Un articolo di base sul mondo GIS riguardante il rilevamento delle coordinate.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

Introduzione

Vediamo come rilevare le coordinate (assolute e normali) nella mappa quando si sposta il mouse nella cartina.
Queste informazioni possono tornare utile in quei contesti in cui servono informazioni particolare della mappa.

Creazione del progetto

Si crea un nuovo progetto Silverlight, nel nostro caso sarà utilizzato la versione 5, come linguaggio di programmazione, scegliere quello di proprio interesse.
Aggiungiamo nella pagina il controllo “Mappa” a questo punto  inseriamo un controllo “Stackpanel” con un controllo “TextBlock”, qui di seguito si riporta il file XAML completo.


<Grid x:Name="LayoutRoot" Background="White">
<esri:Map Background="Transparent" HorizontalAlignment="Left" Name="Map1" VerticalAlignment="Top" WrapAround="True" ExtentChanged="Map1_ExtentChanged" ExtentChanging="Map1_ExtentChanged"        Height="300" Width="414">
 <esri:Map.Layers>
 <esri:LayerCollection>
<esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
</esri:LayerCollection>
 </esri:Map.Layers>
 </esri:Map>
  <StackPanel Orientation="Vertical" Margin="7,6,0,44" HorizontalAlignment="Left" Width="239">
 <StackPanel.Resources>
 <Style TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"/>
 <Setter Property="FontSize" Value="11" />
   </Style>
</StackPanel.Resources>
 <TextBlock>
<Run FontStyle="Italic">Assoluto</Run>
 <LineBreak />
<Run>MinX: </Run>
                   <Run Text="{Binding ElementName=Map1, Path=Extent.XMin, StringFormat=\{0:F3\}}" />
 <LineBreak />
<Run>MinY: </Run>
 <Run Text="{Binding ElementName=Map1, Path=Extent.YMin, StringFormat=\{0:F3\}}" />
  <LineBreak />
 <Run>MaxX: </Run>
<Run Text="{Binding ElementName=Map1, Path=Extent.XMax, StringFormat=\{0:F3\}}" />
 <LineBreak />
 <Run>MaxY: </Run>
 <Run Text="{Binding ElementName=Map1, Path=Extent.YMax, StringFormat=\{0:F3\}}" />
 <LineBreak />
 <LineBreak />
 <Run FontStyle="Italic">Normale</Run>
 <LineBreak />
 <Run>Left X: </Run>
<Run x:Name="MinXNormalized" />
 <LineBreak />
 <Run>Bottom Y: </Run>
 <Run x:Name="MinYNormalized"/>
  <LineBreak />
<Run>Right X: </Run>
   <Run x:Name="MaxXNormalized"/>
 <LineBreak />
 <Run>Top Y: </Run>
<Run x:Name="MaxYNormalized"/>
</TextBlock>
 </StackPanel>
 </Grid>




Figura 1 –  Finestra che visualizza le coordinate
A questo punto dobbiamo gestire gli eventi, in particolare l’evento “ExtentChanged” e “ExtentChanging” del controllo mappa.
Selezioniamo nel file XAML il primo evento, ossai “ExtentChanged” e  facciamo click sul tasto “Tabulatore” in modo che viene suggerito di inserire un nuovo gestore di eventi (figura 2).


Figura 2 – il suggerimento dell’evento
A questo punto facciamo doppio click sulla voce “Nuovo gestore eventi”, in modo che genera automaticamente tale evento.
Ora la stessa cosa per l’evento “ExtentChanging” ma questa volta impostiamo l’evento appena creato (figura 3) .


Figura 3 – Il suggerimento per l’evento.
Il codice XAML sarà come quello riportato in precedenza

Stesura del codice

Terminata la parte designer, non ci resta che scrivere il codice per impostare nei controlli “Textblock” i valori relative alle coordinate.
Qui di seguito si riporta il codice per il linguaggio VB.Net e C#.
Spazio di nomi
VB.Net
Imports Microsoft.VisualBasic
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client.Geometry
C#
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Geometry;





Codice per gli eventi
VB.Net
Private Sub Map1_ExtentChanged(sender As System.Object, e As ESRI.ArcGIS.Client.ExtentEventArgs)
Dim newExtent As Envelope = Nothing
        If Map1.WrapAroundIsActive Then
            Dim normalizedExtent As Geometry = Geometry.NormalizeCentralMeridian(e.NewExtent)
            If TypeOf normalizedExtent Is Polygon Then
                newExtent = New Envelope()
                For Each p As MapPoint In (TryCast(normalizedExtent, Polygon)).Rings(0)
                    If p.X < newExtent.XMin OrElse Double.IsNaN(newExtent.XMin) Then
                        newExtent.XMin = p.X
                    End If
                    If p.Y < newExtent.YMin OrElse Double.IsNaN(newExtent.YMin) Then
                        newExtent.YMin = p.Y
                    End If
                Next p
                For Each p As MapPoint In (TryCast(normalizedExtent, Polygon)).Rings(1)
                    If p.X > newExtent.XMax OrElse Double.IsNaN(newExtent.XMax) Then
                        newExtent.XMax = p.X
                    End If
                    If p.Y > newExtent.YMax OrElse Double.IsNaN(newExtent.YMax) Then
                        newExtent.YMax = p.Y
                    End If
                Next p
            ElseIf TypeOf normalizedExtent Is Envelope Then
                newExtent = TryCast(normalizedExtent, Envelope)
            End If
        Else
            newExtent = e.NewExtent
        End If
        MinXNormalized.Text = newExtent.XMin.ToString("0.000")
        MinYNormalized.Text = newExtent.YMin.ToString("0.000")
        MaxXNormalized.Text = newExtent.XMax.ToString("0.000")
        MaxYNormalized.Text = newExtent.YMax.ToString("0.000")
    End Sub
C#
private void Map1_ExtentChanged(object sender, ESRI.ArcGIS.Client.ExtentEventArgs e)
{
            Envelope newExtent = null;
            if (Map1.WrapAroundIsActive)
            {
                Geometry normalizedExtent =   Geometry.NormalizeCentralMeridian(e.NewExtent);
                if (normalizedExtent is Polygon)
                {
                    newExtent = new Envelope();
                    foreach (MapPoint p in (normalizedExtent as Polygon).Rings[0])
                    {
                        if (p.X < newExtent.XMin || double.IsNaN(newExtent.XMin))
                            newExtent.XMin = p.X;
                        if (p.Y < newExtent.YMin || double.IsNaN(newExtent.YMin))
                            newExtent.YMin = p.Y;
                    }
                    foreach (MapPoint p in (normalizedExtent as Polygon).Rings[1])
                    {
                        if (p.X > newExtent.XMax || double.IsNaN(newExtent.XMax))
                            newExtent.XMax = p.X;
                        if (p.Y > newExtent.YMax || double.IsNaN(newExtent.YMax))
                            newExtent.YMax = p.Y;
                    }
                }
                else if (normalizedExtent is Envelope)
                    newExtent = normalizedExtent as Envelope;
            }
            else
                newExtent = e.NewExtent;
            MinXNormalized.Text = newExtent.XMin.ToString("0.000");
            MinYNormalized.Text = newExtent.YMin.ToString("0.000");
            MaxXNormalized.Text = newExtent.XMax.ToString("0.000");
            MaxYNormalized.Text = newExtent.YMax.ToString("0.000");
        }



Lo spazio dei nomi ESRI.ArcGIS.Client.Geometry ci permette di gestire le forme geometriche in ambito di GIS diverse da quelle fornite dal framework di Silverlight.
Il codice appena riporta, permette di rilevare i dati di determinate aree il tutto tramite un oggetto di tipo mapoint.
Con questi dati possiamo avere informazioni delle mappa, e precisamente la posizione del mouse e l’area in cui stiamo valutando.

Conclusioni

L’articolo ha voluto fornire una breve introduzione al mondo delle informazioni delle mappe riguardante coordinate e la gestione di alcuni eventi.