Maria globe client: Difference between revisions

From Maria GDK Wiki
Jump to navigation Jump to search
()
()
Tag: Replaced
Line 44: Line 44:
[[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]]

Revision as of 10:34, 2 October 2019

This page describes how to create a Maria GDK map client utilising MariaGlobeMapControl with 2D and 3D visualisation of map, tracks and draw objects.

Maria Globe Client

General

This page is under construction!
Note
  • You will need to include the TPG.Maria.MariaGlobeMapControl NuGet package (Currently available Teleplan Globe internal only)
  • 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

Utilising the globe control

Globe First-3D.PNG

Map interaction

Map Pref 3D.PNG

Draw object interaction

DrawObjects 3D.PNG

Track interaction

Track 3D.PNG

Auto follow

Auto follow track 3D.PNG

Advanced map settings

3D Set P15 Y120 R30 af.png