|
|
| (9 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]] |
| |} | | |} |
|
| |
| == Auto follow ==
| |
|
| |
| In this section, we will utilise the globe control auto follow functionality.
| |
|
| |
| ; 2D
| |
| :* valid for tracks and all draw object types
| |
| :* the specified object will always be displayed with its center point in the center of the screen.
| |
| :* if the item position is changed, the map area will be adjusted accordingly.
| |
| ; 3D
| |
| :* valid for tracks and point objects only
| |
|
| |
| === Auto follow control and display ===
| |
|
| |
| Add the following GUI elements to your main window:
| |
| * Check box to enable/disable auto follow
| |
| * Text box for display of currently followed item
| |
|
| |
| The XAML could look something like this:
| |
|
| |
| <source lang="xml">
| |
| ...
| |
| <GroupBox Header="Auto follow">
| |
| <StackPanel>
| |
| <CheckBox Margin="3"
| |
| Content="Follow selected"
| |
| IsChecked="{Binding IsAutoFollowActive}" />
| |
| <Label Content="Currently followed:" FontWeight="DemiBold" />
| |
| <TextBox Margin="3"
| |
| Text="{Binding AutoFollowItemName, Mode=OneWay}"
| |
| IsReadOnly="True"/>
| |
| </StackPanel>
| |
| </GroupBox>
| |
| ...
| |
| </source>
| |
|
| |
| In '''''MainViewModel''''' implement:
| |
| * Auto follow property,
| |
| * auto update property with timer, initialised in during the '''''LayerInitialized''''' event handler.
| |
|
| |
| <source lang="C#">
| |
| ...
| |
| public bool IsAutoFollowActive
| |
| {
| |
| get
| |
| {
| |
| return GlobeMapViewModel.AutoFollow.TargetItem != null;
| |
| }
| |
|
| |
| set
| |
| {
| |
| if (!(value && GlobeMapViewModel.AutoFollow.FollowSelectedItem()))
| |
| GlobeMapViewModel.AutoFollow.TargetItem = null;
| |
|
| |
| NotifyPropertyChanged(() => IsAutoFollowActive);
| |
| NotifyPropertyChanged(() => AutoFollowItemName);
| |
| }
| |
| }
| |
|
| |
| public string AutoFollowItemName
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.AutoFollow?.TargetItem != null)
| |
| {
| |
| return GlobeMapViewModel.AutoFollow.TargetItem.ToString();
| |
| }
| |
|
| |
| return "Inactive";
| |
| }
| |
| }
| |
| ...
| |
| </source>
| |
|
| |
| === Running with auto follow ===
| |
|
| |
| Activating/deactivating auto follow functionality, observe the following:
| |
| * in 3D mode, tracks and point objects only can be selected.
| |
| * the map will re-position to the activated item if the map is panned.
| |
| * the map will re-position to the activated item if the item is moved.
| |
| * the activated item will stay activated also when deselected in the map and when another item is selected.
| |
| ** To activate another item - deactivate, then activate the new item.
| |
|
| |
| {| class="wikitable"
| |
| |-
| |
| | [[File:Auto_follow_none_2D.PNG|500px|No auto follow, 2D]] <br> No auto follow, 2D
| |
| |-
| |
| | [[File:Auto_follow_area_2D.PNG|500px|Auto follow volume object, 2D]] <br> Auto follow volume object, 2D
| |
| | [[File:Auto_follow_line_2D.PNG|500px|Auto follow line object, 2D]] <br> Auto follow line object, 2D
| |
| |-
| |
| | [[File:Auto_follow_point_2D.PNG|500px|Auto follow point object, 2D]] <br> Auto follow point object, 2D
| |
| | [[File:Auto_follow_track_2D.PNG|500px|Auto follow track, 2D]] <br> Auto follow track, 2D
| |
| |-
| |
| | [[File:Auto_follow_point_3D.PNG|500px|Auto follow point object, 3D]] <br> Auto follow point object, 3D
| |
| | [[File:Auto_follow_track_3D.PNG|500px|Auto follow track, 3D]] <br> Auto follow track, 3D
| |
| |}
| |
|
| |
| == 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]] |