We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

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

Platform: Xamarin.Forms |
Control: SfCircularGauge |
Published Date: April 21, 2020 |
Last Revised Date: April 21, 2020

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

2X faster development

The ultimate Xamarin UI toolkit to boost your development speed.
ADD COMMENT
You must log in to leave a comment
Comments
Muhammad
Aug 21, 2020

Great Post really helpful. Thanks a lot.

Reply

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile