Articles in this section
Category / Section

How to design a compass that always points to a specific place in Xamarin.Forms circular gauge (SfCircularGauge)

3 mins read

Description

This article describes how to design a compass that always points to a specific place in Xamarin.Forms circular gauge (radial gauge).

Solution

i) Design Gauge appearance as Compass

By using the StartAngle, SweepAngle, StartValue, EndValue, NeedlePointer, and LabelCreated event of Xamarin.Forms circular gauge, you can design the Gauge appearance as compass.

The following steps design the Gauge appearance as compass.

Step 1: Using the StartAngle and SweepAngle change the Gauge initial rendering point as compass.

…
<SyncfusionGauge:Scale x:Name="scale"
                       StartAngle="270"
                       StartValue="0"
                       EndValue="360"
                       Interval="45"
                       LabelOffset="0.75"
                       SweepAngle="360"
                       MinorTicksPerInterval="1"
                       ShowLastLabel="False"
                       ScaleStartOffset="0.99"
                       ScaleEndOffset="0.9">
<SyncfusionGauge:Scale.Pointers>
…

 

Step 2: Change the Gauge label content with direction notations by using the LabelCreated event and label value.

…
<SyncfusionGauge:Scale x:Name="scale"
                       …
                       LabelCreated="Scale_LabelCreated">
<SyncfusionGauge:Scale.Pointers>
…

 

…
private void Scale_LabelCreated(object sender, Syncfusion.SfGauge.XForms.LabelCreatedEventArgs args)
{
    switch ((string)args.LabelContent)
    {
        case "0":
            args.LabelContent = "N";
            break;
        case "45":
            args.LabelContent = "NE";
            break;
        case "90":
            args.LabelContent = "E";
            break;
        case "135":
            args.LabelContent = "SE";
            break;
        case "180":
            args.LabelContent = "S";
            break;
        case "225":
            args.LabelContent = "SW";
            break;
        case "270":
            args.LabelContent = "W";
            break;
        case "315":
            args.LabelContent = "NW";
            break;
        case "360":
            args.LabelContent = "N";
            break;
    }
}
…

 

Step 3: Add the needle pointer to show the direction of specific location.

…
<SyncfusionGauge:Scale.Pointers>
    <SyncfusionGauge:NeedlePointer x:Name="pointer1"
                                   Type="Triangle"
                                   LengthFactor="0.65"
                                   Thickness="30"
                                   KnobRadius="30"
                                   KnobStrokeWidth="3"
                                   EnableAnimation="True" />
</SyncfusionGauge:Scale.Pointers>
…

 

ii)Make Compass to always point to a specific place

By using the Xamarin.Essentials’s methods, you can get the device current location and north direction based on those values and you can also update the needle pointer of circular gauge.

Step 1: Get the device current location by using the GeolocationRequest() and Geolocation.GetLocationAsync() methods of Xamarin.Essentials.

…
public MainPage()
{
    InitializeComponent();
    GetLocation();
}
 
private async void GetLocation()
{
    var request = new GeolocationRequest(GeolocationAccuracy.Medium);
    var location = await Geolocation.GetLocationAsync(request);
    current_latitude = location.Latitude;
    current_longitude = location.Longitude;
}
…

 

Step 2: Calculate the degree between the device current location and target location and update the needle pointer value.

…
public MainPage()
{
    InitializeComponent();
…
    PointToQibla();
}
 
private double Mod(double a, double b)
{
    return a - b * Math.Floor(a / b);
}
 
void PointToQibla()
{
    double latt_from_radians = current_latitude * Math.PI / 180;
    double long_from_radians = current_longitude * Math.PI / 180;
    double latt_to_radians = QiblaLatitude * Math.PI / 180;
    double lang_to_radians = QiblaLongitude * Math.PI / 180;
    double bearing = Math.Atan2(Math.Sin(lang_to_radians - long_from_radians) * Math.Cos(latt_to_radians), (Math.Cos(latt_from_radians) * Math.Sin(latt_to_radians)) - (Math.Sin(latt_from_radians) * Math.Cos(latt_to_radians) * Math.Cos(lang_to_radians - long_from_radians)));
    bearing = Mod(bearing, 2 * Math.PI);
    double bearing_degree = bearing * 180 / Math.PI;
    pointer1.Value = bearing_degree;
}
…

 

Step 3: By rotating the Gauge to make the north side of the Gauge always point the north direction and repeat the step 2 when the device direction gets changed by using the Compass.ReadingChanged event of Xamarin.Essentials to make the compass to always point a specific place.

…
public MainPage()
{
    InitializeComponent();
    Compass.ReadingChanged += Compass_ReadingChanged;
}
 
void Compass_ReadingChanged(object sender, CompassChangedEventArgs e)
{
    circularGauge.RotateTo(360 - e.Reading.HeadingMagneticNorth);
    PointToQibla();
}
…

 

Output

Compass like CircularGauge

You can find the sample in the following link.

https://github.com/SyncfusionExamples/xamarin_gauge_samples/tree/master/Samples/QiblaLocater

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments
Please sign in to leave a comment
Access denied
Access denied