public async void SendPatrolCarAlerts()
        {
            try
            {
                while (true)
                {
                    double    distance    = generateDistanceTravelled(this.locationReportingInterval);
                    GPSCoords newLocation = calculateCoords(this.carLatPosition, this.carLongPosition, distance, this.milesPerDegreeLat, this.milesPerDegreeLong);
                    this.carLatPosition  = newLocation.Latitude;
                    this.carLongPosition = newLocation.Longitude;
                    var alert = new PatrolCarLocationAlert()
                    {
                        CarID             = this.carName,
                        CarNum            = this.carNum,
                        LocationLatitude  = this.carLatPosition,
                        LocationLongitude = this.carLongPosition,
                        Speed             = this.speed,
                        Time = DateTime.UtcNow
                    };

                    var serializedAlert = JsonConvert.SerializeObject(alert);
                    var data            = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(serializedAlert));
                    data.Properties.Add("Type", $"Telemetry_{DateTime.Now.ToLongTimeString()}");
                    await this.deviceClient.SendEventAsync(data);

                    Trace.TraceInformation($"Sending: {alert.ToString()}");
                    await Task.Delay(this.locationReportingInterval * 1000);
                }
            }
            catch (Exception e)
            {
                Trace.TraceError($"Error sending message: {e.Message}");
            }
        }
        private GPSCoords calculateCoords(double carLatPosition, double carLongPosition, double distance, double milesPerDegreeLat, double milesPerDegreeLong)
        {
            int directionFactorLat  = 0;
            int directionFactorLong = 0;

            if (this.speed >= 60)
            {
                directionFactorLat  = this.previousDirectionFactorLat;
                directionFactorLong = this.previousDirectionFactorLong;
            }
            else if (this.speed > 30)
            {
                directionFactorLat  = this.previousDirectionFactorLat;
                directionFactorLong = rnd.Next(3) - 1;
                this.previousDirectionFactorLong = directionFactorLong;
            }
            else if (this.speed > 10)
            {
                directionFactorLong             = this.previousDirectionFactorLong;
                directionFactorLat              = rnd.Next(3) - 1;
                this.previousDirectionFactorLat = directionFactorLat;
            }
            else
            {
                directionFactorLat               = rnd.Next(3) - 1;
                directionFactorLong              = rnd.Next(3) - 1;
                this.previousDirectionFactorLat  = directionFactorLat;
                this.previousDirectionFactorLong = directionFactorLong;
            }

            double    latDistance  = rnd.NextDouble() * distance * directionFactorLat;
            double    longDistance = Math.Sqrt((distance * distance) - (latDistance * latDistance)) * directionFactorLong;
            GPSCoords newCoords    = new GPSCoords
            {
                Latitude  = carLatPosition + latDistance / milesPerDegreeLat,
                Longitude = carLongPosition + longDistance / milesPerDegreeLong
            };

            return(newCoords);
        }
        public async void SendPatrolCarAlerts()
        {
            try
            {
                while (true)
                {
                    double distance = 0;

                    if (!chasing)
                    {
                        // If not chasing a suspect vehicle, then just patrol the local area
                        distance = generateDistanceTravelled(this.locationReportingInterval);
                    }
                    else
                    {
                        // Close in on the suspect vehicle's last known location
                        distance = this.locationReportingInterval / this.speed;
                        GeoCoordinate patrolCarCoords = new GeoCoordinate(this.carLatPosition, this.carLongPosition);

                        // Determine the bearing of the suspect vehicle's last known location relative to the current location of the patrol car
                        // - very crude approximation - do we need to travel N, S, E or W?
                        if (this.carLatPosition != this.targetCoordinates.Latitude)
                        {
                            this.previousDirectionFactorLat = (this.carLatPosition < this.targetCoordinates.Latitude) ? 1 : -1;
                        }
                        if (this.carLongPosition != this.targetCoordinates.Longitude)
                        {
                            this.previousDirectionFactorLong = (this.carLongPosition < this.targetCoordinates.Longitude) ? 1 : -1;
                        }

                        // If the distance to a suspect vehicle location is less than 200 meters, treat it as intercepted for this simulation
                        if (patrolCarCoords.GetDistanceTo(this.targetCoordinates) < 200)
                        {
                            this.chasing = false;
                            Trace.TraceInformation($"ALERT ****** {this.carName} has intercepted suspect vehicle ******");
                        }
                    }

                    GPSCoords newLocation = calculateCoords(this.carLatPosition, this.carLongPosition, distance, this.milesPerDegreeLat, this.milesPerDegreeLong);
                    this.carLatPosition  = newLocation.Latitude;
                    this.carLongPosition = newLocation.Longitude;

                    var alert = new PatrolCarLocationAlert()
                    {
                        CarID             = this.carName,
                        CarNum            = this.carNum,
                        LocationLatitude  = this.carLatPosition,
                        LocationLongitude = this.carLongPosition,
                        Speed             = this.speed,
                        Time = DateTime.UtcNow
                    };

                    var serializedAlert = JsonConvert.SerializeObject(alert);
                    var data            = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(serializedAlert));
                    data.Properties.Add("Type", $"Telemetry_{DateTime.Now.ToLongTimeString()}");
                    await this.deviceClient.SendEventAsync(data);

                    Trace.TraceInformation($"Sending: {alert.ToString()}");
                    await Task.Delay(this.locationReportingInterval * 1000);
                }
            }
            catch (Exception e)
            {
                Trace.TraceError($"Error sending message: {e.Message}");
            }
        }