Maria globe client: Difference between revisions

From Maria GDK Wiki
Jump to navigation Jump to search
()
()
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
This page describes how to create a Maria GDK map client utilising '''''MariaGlobeMapControl''''' with 2D and 3D visualisation of map, tracks and draw objects.
[[File:Globe-3D.PNG|right|thumb|Maria Globe Client]]


[[File:Globe-3D.PNG|right|thumb|Maria Globe Client]]
These pages describe how to create a Maria GDK map client utilising '''''MariaGlobeMapControl''''' with 2D and 3D visualisation of map, tracks and draw objects.


== General ==
== General ==


'''''<pre style="color: yellow; background:orange" >This page is under construction!</pre>'''''
; Note
; Note
:* You will need to include the '''''TPG.Maria.MariaGlobeMapControl''''' ''NuGet'' package (Currently available Teleplan Globe internal only)
:* You will need to include the '''''TPG.MariaGDK3D''''' NuGet package. (Currently available Teleplan Globe internal only)
:: For more info, see [[Development requirements#Loading Maria GDK Packages| Loading Maria GDK, NuGet Packages]]
:* Sample code is found in the '''''MariaGlobeClient''''' project, in the '''''Sample Projects''''' solution.  
:* Sample code is found in the '''''MariaGlobeClient''''' project, in the '''''Sample Projects''''' solution.  
:* Note that the sample code is specifying the service connections in ''code'', and not by '''''app.config'''''.
:* Note that the sample code is specifying the service connections in ''code'', and not by '''''app.config'''''.
:* For general troubleshooting, see [[Development_troubleshooting|Development troubleshooting]]
:* For general troubleshooting, see [[Development_troubleshooting|Development troubleshooting]]
== Sections ==
;The following main topics are handled:


{| class="wikitable"
{| class="wikitable"
|-
|-
|
|
[[Maria_globe_client/Utilising_the_globe_control|Utilising the globe control]]
;1. [[Maria_globe_client/Utilising_the_globe_control|Utilising the globe control]]
|
|
[[File:Globe_First-3D.PNG|150px|link=Maria_globe_client/Utilising_the_globe_control]]
[[File:Globe_First-3D.PNG|150px|link=Maria_globe_client/Utilising_the_globe_control]]
|-
|-
|  
|  
[[Maria_globe_client/Map_interaction|Map interaction]]
;2. [[Maria_globe_client/Map_interaction|Map interaction]]
|
|
[[File:Map_Pref_3D.PNG|150px|link=Maria_globe_client/Map_interaction]]
[[File:Map_Pref_3D.PNG|150px|link=Maria_globe_client/Map_interaction]]
|-
|-
|  
|  
[[Maria_globe_client/Draw_object_interaction|Draw object interaction]]
;3. [[Maria_globe_client/Draw_object_interaction|Draw object interaction]]
|
|
[[File:DrawObjects_3D.PNG|150px|link=Maria_globe_client/Draw_object_interaction]]
[[File:DrawObjects_3D.PNG|150px|link=Maria_globe_client/Draw_object_interaction]]
|-
|-
|  
|  
[[Maria_globe_client/Track_interaction|Track interaction]]
;4. [[Maria_globe_client/Track_interaction|Track interaction]]
|
|
[[File:Track_3D.PNG|150px|link=Maria_globe_client/Track_interaction]]
[[File:Track_3D.PNG|150px|link=Maria_globe_client/Track_interaction]]
|-
|-
|  
|  
[[Maria_globe_client/Auto_follow|Auto follow]]
;5. [[Maria_globe_client/Auto_follow|Auto follow]]
|
|
[[File:Auto_follow_track_3D.PNG|150px|link=Maria_globe_client/Auto_follow]]
[[File:Auto_follow_track_3D.PNG|150px|link=Maria_globe_client/Auto_follow]]
|-
|-
|  
|  
[[Maria_globe_client/Advanced_map_settings|Advanced map settings]]
;6. [[Maria_globe_client/Advanced_map_settings|Advanced map settings]]
|
|
[[File:3D_Set_P15_Y120_R30_af.png|150px|link=Maria_globe_client/Advanced_map_settings]]
[[File:3D_Set_P15_Y120_R30_af.png|150px|link=Maria_globe_client/Advanced_map_settings]]
|}
|}
== Advanced map settings ==
=== Map rotation ===
As default, 2D maps are displayed with north up, but you may rotate the map by modifying the map layer rotation parameter - GeoContext.RotateValue.
Add the following components:
* Text box to display the current rotation value
* Two buttons, for right (clockwise) add left (counter clockwise).
Add the following to your Main Window XAML:
<source lang="xml">
. . .
<Label Grid.Row="4" Grid.Column="0"
      Content="Rotation" FontWeight="DemiBold"/>
<TextBox Grid.Row="4" Grid.Column="1" Margin="3"
        Text="{Binding MapViewModel.Rotation}" TextAlignment="Right" />
<StackPanel  Grid.Row="5" Grid.Column="1" Orientation="Horizontal"
            VerticalAlignment="Center" HorizontalAlignment="Center">
    <RepeatButton Margin="3" Width="50"
                  Content="Left"
                  Command="{Binding MapViewModel.RotateLeftCmnd}"/>
    <RepeatButton Margin="3" Width="50"
                  Content="Right"
                  Command="{Binding MapViewModel.RotateRightCmnd}"/>
</StackPanel>
. . .
</source>
And implement corresponding properties and command handlers in '''''MapViewModel''''':
<source source lang="C#">
. . .
public ICommand RotateLeftCmnd { get { return new DelegateCommand(OnRotateLeft); } }
public ICommand RotateRightCmnd { get { return new DelegateCommand(OnRotateRight); } }
private void OnRotateLeft(object obj)
{
    Rotation += 1;
}
private void OnRotateRight(object obj)
{
    Rotation -= 1;
}
public int Rotation
{
    get { return _mapLayer.GeoContext != null ? (int)_mapLayer.GeoContext.RotateValue : 0; }
    set
    {               
        _mapLayer.GeoContext.RotateValue = value;
        NotifyPropertyChanged(() => Rotation);
    }
}
. . .
</source>
Pressing the buttons, the map is rotated, and the rotation display is updated accordingly.
[[File:Rotation.png|frame|none|Map rotation.]]
=== 3D map settings ===
==== 3D Properties ====
The '''''Globe Client''''' 3D view is the view from a camera towards a target, specified by the following parameters:
{| class="wikitable"
|-
!  !! Description !! 
|-
! scope="row" style="text-align:left;" | Camera yaw
| Horizontal rotation, degrees - counterclockwise.
|rowspan="3" | [[File:Roll_pitch_yaw_2.png|150px|Roll, pitch and yaw ]]
|-
! scope="row" style="text-align:left;" | Camera pitch
| Front/back rotation, degrees - counterclockwise
|-
! scope="row" style="text-align:left;" | Camera roll
| Left/right rotation, degrees - counterclockwise.
|-
! scope="row" style="text-align:left;" | Follow ground
| colspan="2" |
Lock the target altitude is to the elevation of the target position.
|-
! scope="row" style="text-align:left;" | Target altitude
| colspan="2" |
Height above sea level (0-elevation)  at target position.
Changes are not applicable while:
* auto follow is active, as the target elevation is defined by the item followed.
* follow ground is active.
|-
! scope="row" style="text-align:left;" | Target position
| colspan="2" |
Latitude and longitude. Changes are not applicable while:
* auto follow is active, as the target position is defined by the item followed.
|-
! scope="row" style="text-align:left;" | Target distance
| colspan="2" | Distance from camera to target.
|}
;Note
:* 3D rotations are ''not commutative''.
:: Performing the same rotations in different order will give different results.
==== Implementation ====
To visualise how these parameters are connected, add the following elements to your main window:
<source  lang="xml">
. . .
<GroupBox Header="3D Settings"
          IsEnabled="{Binding MapViewModel.Is3DMode}" >
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4"
              Content="Camera" FontWeight="DemiBold" />
       
        <Label Grid.Row="1" Grid.Column="0"
              Content="Yaw"  />
        <TextBox Grid.Row="1" Grid.Column="1" Margin="3" Width="60"
                Text="{Binding MapViewModel.CameraYaw, StringFormat=N2}" TextAlignment="Right"                           
                IsReadOnly="True"/>
        <RepeatButton Grid.Row="1" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseYawCmnd}"/>
        <RepeatButton Grid.Row="1" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseYawCmnd}"/>
       
        <Label Grid.Row="2" Grid.Column="0"
              Content="Roll" />
        <TextBox Grid.Row="2" Grid.Column="1" Margin="3" Width="60"
                Text="{Binding MapViewModel.CameraRoll, StringFormat=N2}" TextAlignment="Right"
                IsReadOnly="True"/>
        <RepeatButton Grid.Row="2" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseRollCmnd}"/>
        <RepeatButton Grid.Row="2" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseRollCmnd}"/>
       
        <Label Grid.Row="3" Grid.Column="0"
              Content="Pitch" />
        <TextBox Grid.Row="3" Grid.Column="1" Margin="3" Width="60"
                Text="{Binding MapViewModel.CameraPitch, StringFormat=N2}" TextAlignment="Right"
                IsReadOnly="True"/>
        <RepeatButton Grid.Row="3" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreasePitchCmnd}"/>
        <RepeatButton Grid.Row="3" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreasePitchCmnd}"/>
        <Label Grid.Row="4" Grid.Column="0"
              Content="Target" FontWeight="DemiBold" />
        <CheckBox Grid.Row="4"  Grid.Column="1" Grid.ColumnSpan="3" VerticalAlignment="Center" Margin="3"
                  Content="Follow ground"
                  IsChecked="{Binding MapViewModel.FollowGround}"/>
        <Label Grid.Row="5" Grid.Column="0"
              Content="Altitude" />
        <TextBox Grid.Row="5" Grid.Column="1" Margin="3" Width="60"
                Text="{Binding MapViewModel.TargetAltitude, StringFormat=N0}" TextAlignment="Right"
                IsReadOnly="True"/>
        <RepeatButton Grid.Row="5" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseTargetAltitudeCmnd}"/>
        <RepeatButton Grid.Row="5" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseTargetAltitudeCmnd}"/>
       
        <Label Grid.Row="6" Grid.Column="0"
              Content="Distance" />
        <TextBox Grid.Row="6" Grid.Column="1" Margin="3" Width="60"
                Text="{Binding MapViewModel.TargetDistance, StringFormat=N0}" TextAlignment="Right"
                IsReadOnly="True"/>
        <RepeatButton Grid.Row="6" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseTargetDistanceCmnd}"/>
        <RepeatButton Grid.Row="6" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseTargetDistanceCmnd}"/>
        <Label Grid.Row="7" Grid.Column="0"
              Content="Position" />
        <TextBox Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="3" Margin="3"                             
                Text="{Binding MapViewModel.TargetPosText, Mode=OneWay}" TextAlignment="Right"
                IsReadOnly="True"/>
        <Label Grid.Row="8" Grid.Column="1"
              Content="Latitude"/>
        <RepeatButton Grid.Row="8" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseTargetPosLatCmnd}"/>
        <RepeatButton Grid.Row="8" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseTargetPosLatCmnd}"/>
        <Label Grid.Row="9" Grid.Column="1"
              Content="Longitude"/>
        <RepeatButton Grid.Row="9" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="+"
                      Command="{Binding MapViewModel.IncreaseTargetPosLonCmnd}"/>
        <RepeatButton Grid.Row="9" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
                      Content="-"
                      Command="{Binding MapViewModel.DecreaseTargetPosLonCmnd}"/>
    </Grid>
</GroupBox>
. . .
</source>
And add necessary command handlers and properties to '''''MapViewModel'''''
<source lang="csharp">
. . .
public ICommand IncreaseYawCmnd { get { return new DelegateCommand(OnIncreaseCameraYaw); } }
public ICommand DecreaseYawCmnd { get { return new DelegateCommand(OnDecreaseCameraYaw); } }
public ICommand IncreaseRollCmnd { get { return new DelegateCommand(OnIncreaseCameraRoll); } }
public ICommand DecreaseRollCmnd { get { return new DelegateCommand(OnDecreaseCameraRoll); } }
public ICommand IncreasePitchCmnd { get { return new DelegateCommand(OnIncreaseCameraPitch); } }
public ICommand DecreasePitchCmnd { get { return new DelegateCommand(OnDecreaseCameraPitch); } }
public ICommand IncreaseTargetDistanceCmnd { get { return new DelegateCommand(OnIncreaseTargetDistance); } }
public ICommand DecreaseTargetDistanceCmnd { get { return new DelegateCommand(OnDecreaseTargetDistance); } }
public ICommand IncreaseTargetAltitudeCmnd { get { return new DelegateCommand(OnIncreaseTargetAlttitude, CanModTargetAltitude); } }
public ICommand DecreaseTargetAltitudeCmnd { get { return new DelegateCommand(OnDecreaseTargetAltitide, CanModTargetAltitude); } }
public ICommand IncreaseTargetPosLatCmnd { get { return new DelegateCommand(OnIncreaseTargetPosLat, CanModTargetPosition); } }
public ICommand DecreaseTargetPosLatCmnd { get { return new DelegateCommand(OnDecreaseTargetPosLat, CanModTargetPosition); } }
public ICommand IncreaseTargetPosLonCmnd { get { return new DelegateCommand(OnIncreaseTargetPosLon, CanModTargetPosition); } }
public ICommand DecreaseTargetPosLonCmnd { get { return new DelegateCommand(OnDecreaseTargetPosLon, CanModTargetPosition); } }
public bool Autofollow
{
    get { return _autoFollow; }
    set
    {
        _autoFollow = value;
        RefreshTargetAndCameraValues();
    }
}
private void OnIncreaseCameraYaw(object obj) { CameraYaw += 1; }
private void OnDecreaseCameraYaw(object obj) { CameraYaw -= 1; }
private void OnIncreaseCameraRoll(object obj) { CameraRoll += 1; }
private void OnDecreaseCameraRoll(object obj) { CameraRoll -= 1; }
private void OnIncreaseCameraPitch(object obj) { CameraPitch += 1; }
private void OnDecreaseCameraPitch(object obj) { CameraPitch -= 1; }
private void OnIncreaseTargetAlttitude(object obj) { TargetAltitude += 10; }
private void OnDecreaseTargetAltitide(object obj) { TargetAltitude -= 10; }
private void OnIncreaseTargetPosLat(object obj) { TargetPos = new GeoPos(TargetPos.Lat + (1.0 / (60 * 60)), TargetPos.Lon ); }
private void OnDecreaseTargetPosLat(object obj) { TargetPos = new GeoPos(TargetPos.Lat - (1.0 / (60 * 60)), TargetPos.Lon ); }
private void OnIncreaseTargetPosLon(object obj) { TargetPos = new GeoPos(TargetPos.Lat, TargetPos.Lon + (1.0 / (60 * 60))); }
private void OnDecreaseTargetPosLon(object obj) { TargetPos = new GeoPos(TargetPos.Lat, TargetPos.Lon - (1.0 / (60 * 60))); }
private bool CanModTargetAltitude(object obj) { return !FollowGround && !Autofollow; }
private bool CanModTargetPosition(object obj) { return !Autofollow; }
private void OnIncreaseTargetDistance(object obj) { TargetDistance += 10; }
private void OnDecreaseTargetDistance(object obj) { TargetDistance -= 10; }
public double CameraYaw
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.Yaw;
        return 0;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.Yaw = value;
        }
        NotifyPropertyChanged(() => CameraYaw);
    }
}
public double CameraRoll
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.Roll;
        return 0;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.Roll = value;
        }
        NotifyPropertyChanged(() => CameraRoll);
    }
}
public double CameraPitch
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.Pitch;
        return 0;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.Pitch = value;
        }
        NotifyPropertyChanged(() => CameraPitch);
    }
}
public string TargetPosText { get { return TargetPos.ToString(); } }
public GeoPos TargetPos
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetPos;
        return GeoPos.InvalidPos;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetPos = value;
        }
        RefreshTargetAndCameraValues();
    }
}
public double TargetAltitude
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetAltitude;
        return 0;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetAltitude = value;
        }
        NotifyPropertyChanged(() => TargetAltitude);
    }
}
public bool FollowGround
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.FollowGround;
        return true;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.FollowGround = value;
        }
        NotifyPropertyChanged(() => FollowGround);
    }
}
public double TargetDistance
{
    get
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
            return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetDistance;
        return 0;
    }
    set
    {
        if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
        {
            GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetDistance = value;
        }
        NotifyPropertyChanged(() => TargetDistance);
    }
}
. . .
private void RefreshTargetAndCameraValues()
{
    NotifyPropertyChanged(() => FollowGround);
    NotifyPropertyChanged(() => Autofollow);
    NotifyPropertyChanged(() => CameraPitch);
    NotifyPropertyChanged(() => CameraRoll);
    NotifyPropertyChanged(() => CameraYaw);
    NotifyPropertyChanged(() => TargetAltitude);
    NotifyPropertyChanged(() => TargetPos);
    NotifyPropertyChanged(() => TargetPosText);
    NotifyPropertyChanged(() => TargetDistance);
}
. . .
</source>
... and update '''''MapViewModel.Autofollow''''' when auto follow has changed in '''''MainViewModel'''''!
<source lang="c#">
. . .
public bool IsAutoFollowActive
{
  . . .
    set
    {
        if (!(value && GlobeMapViewModel.AutoFollow.FollowSelectedItem()))
            GlobeMapViewModel.AutoFollow.TargetItem = null;
        MapViewModel.Autofollow = IsAutoFollowActive;
        NotifyPropertyChanged(() => IsAutoFollowActive);
        NotifyPropertyChanged(() => AutoFollowItemName);
    }
}
. . .
</source>
==== Running with display of 3D settings ====
Running the '''''Globe client''''' in 3D mode, altering the 3D parameters will give results like this:
{| class="wikitable"
|-
|
[[File:3D_Set_P90.png|450px|Default 3D setting ]]<br>
Default 3D setting
|
[[File:3D_Set_P15.png|450px| Modified ''pitch'' ]]<br>
Modified ''pitch''
|-
|
[[File:3D_Set_P15_Y120.png|450px|Modified ''yaw'' ]] <br>
Modified ''yaw''
|
[[File:3D_Set_P15_Y120_af.png|450px| With auto follow, track as target]]<br>
With auto follow, track as target
|-
|
[[File:3D_Set_P15_Y120_af_close.png|450px|Auto follow - closer ]] <br>
Auto follow - closer
|
[[File:3D_Set_P15_Y120_R30_af.png|450px| Modified ''roll'' ]]<br>
Modified ''roll''
|}
 






[[Category:Creating applications]]
[[Category:Creating applications]]

Latest revision as of 14:58, 28 October 2019

Maria Globe Client

These pages describe how to create a Maria GDK map client utilising MariaGlobeMapControl with 2D and 3D visualisation of map, tracks and draw objects.

General

Note
  • You will need to include the TPG.MariaGDK3D NuGet package. (Currently available Teleplan Globe internal only)
For more info, see Loading Maria GDK, NuGet Packages
  • Sample code is found in the MariaGlobeClient project, in the Sample Projects solution.
  • Note that the sample code is specifying the service connections in code, and not by app.config.
  • For general troubleshooting, see Development troubleshooting

Sections

The following main topics are handled
1. Utilising the globe control

Globe First-3D.PNG

2. Map interaction

Map Pref 3D.PNG

3. Draw object interaction

DrawObjects 3D.PNG

4. Track interaction

Track 3D.PNG

5. Auto follow

Auto follow track 3D.PNG

6. Advanced map settings

3D Set P15 Y120 R30 af.png