## Calculating the Distance Between Geographical Coordinates in Kotlin

There’s an equation I’ve often found useful and have generally used it for calculating the distance between geographical coordinates. Most recently, I used the equation in a program for a 360 interactive video player to find the distance between an area that a user selected and some point of interest. Fundamentally it is an equation measuring distances on a sphere and has many uses.

I was adjusting the source code to be used in an Android application, and thought that the code might be useful to others. I am reposting it here. I tend to work in SI units, but you could use this for miles, yards, inches, or another unit if you have the radius of the sphere of interest. The constants defined in the class provide the radius of the rarth in miles, kilometers, and meters. One of these values (or your own custom value) must be passed to have the results returned to be scaled for those units.

```class DistanceCalculator {
companion object {
}

return `val` * (Math.PI / 180)
}

fun ToDegree(`val`: Double): Double {
return `val` * 180 / Math.PI
}

fun DiffRadian(val1: Double, val2: Double): Double {
}

public fun CalcDistance(p1: coordinate, p2: coordinate): Double {
return CalcDistance(
p1.latitude,
p1.longitude,
p2.latitude,
p2.longitude,
)
}

fun Bearing(p1: coordinate, p2: coordinate): Double? {
return Bearing(p1.latitude, p1.longitude, p2.latitude, p2.longitude)
}

fun Bearing(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Double? {
run {
val dLat = lat2 - lat2
var dLon = lng2 - lng1
val dPhi: Double = Math.log( Math.tan(lat2 / 2 + Math.PI / 4) / Math.tan(lat1 / 2 + Math.PI / 4) )
val q: Double =
if (Math.abs(dLat) > 0) dLat / dPhi else Math.cos(lat1)
if (Math.abs(dLon) > Math.PI) {
dLon = if (dLon > 0) -(2 * Math.PI - dLon) else 2 * Math.PI + dLon
}
//var d = Math.Sqrt(dLat * dLat + q * q * dLon * dLon) * R;
}
}

public fun CalcDistance(
lat1: Double,
lng1: Double,
lat2: Double,
lng2: Double,
): Double {
return radius * 2 * Math.asin(
Math.min(
1.0, Math.sqrt(
Math.pow(
Math.sin(
), 2.0
)
Math.sin(
), 2.0
)
)
)
)
}
}
```

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Mastodon: @j2inet@masto.ai
Instagram: @j2inet
Telegram: j2inet

## Connecting to AWS IoT’s MQTT Server with .Net

A client I was working with wanted communication between systems for a solution to use AWS IoT for broadcasting messages among the computers making up the solution and controlling various computers. I worked on the solution for the system, but had minimal access to their AWS resources, which is consisten with their security policies. Usually, if I have access to the AWS subscription I could use an MQTT viewer that is part of the service for performing some diagnostic tasks. With this client, I didn’t have that access and had to make my own viewer when performing diagnostics.

Making a viewer is pretty easy once you have the resources that you need. I chose WPF because of the speed at which a functional UI could be build along with M2Mqtt as an MQTT client. Before writing any code, there was some work that needed to be done with the certificates. When accessing an AWS MQTT Instance, the information that you will need includes the domain name for the MQTT instance, an Amazon root certificate, a certificate and private key file. You’ll need this information packaged in a `pfx` file to easily use it with `M2Mqtt.` Packaging these certificates that way is just a matter of running a command. For the files I had, let’s use these names.

• `000-certificate.pem.crt` – The certificate file for the AWS MQTT Instance
• `000-private.pem.key` – The private key for the AWS MQTT instance
• `AmazonRootCA1.cer` – The AWS root certificate

Using those file names, the command that I used was as follows.

```openssl pkcs12 -export -in .\000-certificate.pem.crt -inkey .\000-private.pem.key -out certificate.pfx -certfile .\AmazonRootCA1.cer
```

After this command runs, I have a file named `certificate.pfx`. I’ll be using this in my .Net viewer.

In the interest of keeping the program reusable, I’ve placed information on the paths to the certificate files in the applications settings. If I needed to change these files post-compilation, they are in a JSON file. These settings include the following.

• `BrokerDomainName` – The domain name of the MQTT Instance that the application connects to
• `BrokerCertificatePath` – The relative file path to the
• `BrokerRootCertificatePath` – The relative path to the AWS root certificate
• `BrokerPort` – the port that the MQTT Instance is using. Amazon uses port 883
• `ClientPrefix` – Prefix for the name that will be used for identifying this client.
• `DefaultTopic` – The topic that the client will automatically subscribe to upon starting

Concerning the client prefix, every client is identified by a unique string. To ensure the string is unique, I am generating a GUID when the application starts. It’s possible that someone starts more than one instance of the program. For this reason I don’t persist the GUID. A second instance of the program will have a different GUID. But I still want the string to be recognizable as having come from this program. The `ClientPrefix` string puts a recognizable string before the GUID to satisfy this need.

The paths in the settings are relative to the application. To load the certificates using these paths and to generate a new client name, I use the following code.

```Settings ds = Settings.Default;
var rootCertificatePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ds.BrokerRootCertificatePath);
var deviceCertificatePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ds.BrokerCertificatePath);
var rootCertificate = X509Certificate.CreateFromCertFile(rootCertificatePath);
var deviceCertificate = X509Certificate.CreateFromCertFile(deviceCertificatePath);
clientName = \$"{ds.ClientPrefix}-\${Guid.NewGuid().ToString()}";
```

With that, we have all the information that we need for connecting to the MQTT broker. We can instantiate a `MqttClient`, subscribe to it’s events, and start showing the message topics. The call to establish a connection is a blocking call. When it returns, a connection will have been established.

```client = new MqttClient(ds.BrokerDomainName, ds.BrokerPort, true, rootCertificate, deviceCertificate, MqttSslProtocols.TLSv1_2);
client.MqttMsgSubscribed += Client_MqttMsgSubscribed;
try
{
client.Connect(clientName);

var defaultTopic = ds.DefaultTopic;
if (!String.IsNullOrEmpty(defaultTopic))
{
client.Subscribe(new string[] { defaultTopic }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
}
} catch(Exception ex)
{
MessageBox.Show(ex.Message, "Could not connect");
}
```

The primary information of concern in a message is the topic. The message may also have a payload. I capture both of those items. It is possible that the payload contains data that isn’t a string. I’ve decided not to show it, but captured it anyway should I change my mind. To hold the information I use the following class.

```public class ReceivedMessage: ViewModelBase
{

private string _topic;
public String Topic {
get { return _topic; }
set
{
SetValueIfChanged(() => Topic, () => _topic, value);
}
}

{
set
{
}
}

DateTimeOffset _timestamp = DateTimeOffset.Now;
public DateTimeOffset Timestamp
{
get { return _timestamp; }
set
{
SetValueIfChanged(()=>Timestamp, () => _timestamp, value);
}
}
}
```

The base class from which this derives, `ViewModelBase`, is something I’ve talked about before. See this post if you need more information on how this base class allows this class to be bound to the UI. As new messages come in, I add their content to instances of `ReceivedMessage` and add them to an `ObservableCollection`. The collection is bound to a `ListView` on the UI. The entirety of the main UI window declaration follows. This UI uses only the default code for its code-behind.

```<Window x:Class="MessageWatcher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:MessageWatcher.ViewModels"
xmlns:local="clr-namespace:MessageWatcher"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">

<Grid>
<Grid.DataContext>
<vm:MainViewModel />
</Grid.DataContext>

<ListView ItemsSource="{Binding MessageList}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Topic}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

</Grid>
</Window>
```

With that, I had a working viewer for monitoring the messages as they went by.

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Mastodon: @j2inet@masto.ai
Instagram: @j2inet