Added calculateDistance between two locations and first tests.

master
Rafael 2024-05-27 14:40:46 +02:00
parent ed8f1b810b
commit a0f9dd43da
9 changed files with 225 additions and 30 deletions

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../helper.dart';
import '../utils/helper.dart';
class ProfileCategoryForm<T> extends StatefulWidget {
final String title;

View File

@ -1,5 +1,5 @@
import '../constants.dart';
import '../helper.dart';
import '../utils/math.dart';
class MyLocation {
final String street;
@ -43,8 +43,8 @@ class MyLocation {
/// Returns: locality, country. In case of an error: latitude, longitude.
String toStringDegree() {
try {
String latResult = convertDecimalToDMS(latitude!);
String longResult = convertDecimalToDMS(longitude!);
String latResult = convertDecimalToDMS(latitude!, isLatitude: true);
String longResult = convertDecimalToDMS(longitude!, isLatitude: false);
return '$latResult, $longResult';
} catch (e) {
// on error return origin values

View File

@ -2,7 +2,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../components/my_button.dart';
import '../components/my_textfield.dart';
import '../helper.dart';
import '../utils/helper.dart';
import '../services/auth/auth_service.dart';
class LoginPage extends StatelessWidget {

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../components/my_button.dart';
import '../components/my_textfield.dart';
import '../helper.dart';
import '../utils/helper.dart';
import '../services/auth/auth_service.dart';
import '../services/user_service.dart';

View File

@ -2,7 +2,7 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../../constants.dart';
import '../../helper.dart';
import '../../utils/helper.dart';
import '../../models/message.dart';
class ChatService {

View File

@ -12,32 +12,11 @@ bool equalContent(List<dynamic> list1, List<dynamic> list2) {
/// Creates a composite ID from the passed [ids].
/// In the format id(1)_id(n)
///
String getCompoundId(List<String> ids){
String getCompoundId(List<String> ids) {
ids.sort(); // sort to ensure the result is the same for any order of ids
return ids.join('_');
}
///
/// Convert decimal coordinate to degrees minutes seconds (DMS).
///
String convertDecimalToDMS(double decimalValue) {
bool isNegative = decimalValue < 0;
double absoluteValue = decimalValue.abs();
int degrees = absoluteValue.toInt();
double minutesDecimal = (absoluteValue - degrees) * 60;
int minutes = minutesDecimal.toInt();
double secondsDecimal = (minutesDecimal - minutes) * 60;
double seconds = double.parse(secondsDecimal.toStringAsFixed(2));
String direction = isNegative
? (decimalValue < 0 ? 'W' : 'S')
: (decimalValue >= 0 ? (degrees != 0 ? 'N' : 'E') : '');
// return formatted string
return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs()}" $direction';
}
///
/// Get the [displayName] of our own Enumerations.
///
@ -72,4 +51,4 @@ void showMsg(BuildContext context, String title, String content) {
],
),
);
}
}

View File

@ -0,0 +1,47 @@
import 'dart:math';
///
/// Convert decimal coordinate to degrees minutes seconds (DMS).
///
String convertDecimalToDMS(double decimalValue, {required bool isLatitude}) {
bool isNegative = decimalValue < 0;
double absoluteValue = decimalValue.abs();
int degrees = absoluteValue.toInt();
double minutesDecimal = (absoluteValue - degrees) * 60;
int minutes = minutesDecimal.toInt();
double secondsDecimal = (minutesDecimal - minutes) * 60;
double seconds = double.parse(secondsDecimal.toStringAsFixed(2));
String direction;
if (isLatitude) {
direction = isNegative ? 'S' : 'N';
} else {
direction = isNegative ? 'W' : 'E';
}
// return formatted string
return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs().toStringAsFixed(2)}" $direction';
}
///
/// Distance in kilometers between two location coordinates
///
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
const R = 6371; // earth radius in kilometers
// distance between latitudes and longitudes
final dLat = _degreesToRadians(lat2 - lat1);
final dLon = _degreesToRadians(lon2 - lon1);
final a = sin(dLat / 2) * sin(dLat / 2) +
cos(_degreesToRadians(lat1)) * cos(_degreesToRadians(lat2)) *
sin(dLon / 2) * sin(dLon / 2);
final c = 2 * atan2(sqrt(a), sqrt(1 - a));
return R * c;
}
double _degreesToRadians(double degrees) {
return degrees * pi / 180;
}

View File

@ -0,0 +1,81 @@
import 'package:cofounderella/utils/helper.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('getCompoundId', () {
test('returns correct compound ID for a sorted list', () {
List<String> ids = ['id3', 'id1', 'id2'];
String result = getCompoundId(ids);
expect(result, 'id1_id2_id3');
});
test('returns correct compound ID for an already sorted list', () {
List<String> ids = ['id1', 'id2', 'id3'];
String result = getCompoundId(ids);
expect(result, 'id1_id2_id3');
});
test('returns correct compound ID for a single element list', () {
List<String> ids = ['id1'];
String result = getCompoundId(ids);
expect(result, 'id1');
});
test('returns correct compound ID for empty elements', () {
List<String> ids = ['id1','','id2',''];
String result = getCompoundId(ids);
expect(result, '__id1_id2');
});
test('returns correct compound ID for an empty list', () {
List<String> ids = [];
String result = getCompoundId(ids);
expect(result, '');
});
});
group('equalContent', () {
test('returns true for lists with the same content in the same order', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 3];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns true for lists with the same content in different orders',
() {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [3, 1, 2];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for lists with different content', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2, 4];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns false for lists with different lengths', () {
List<dynamic> list1 = [1, 2, 3];
List<dynamic> list2 = [1, 2];
bool result = equalContent(list1, list2);
expect(result, false);
});
test('returns true for empty lists', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [];
bool result = equalContent(list1, list2);
expect(result, true);
});
test('returns false for one empty and one non-empty list', () {
List<dynamic> list1 = [];
List<dynamic> list2 = [1];
bool result = equalContent(list1, list2);
expect(result, false);
});
});
}

View File

@ -0,0 +1,88 @@
import 'package:cofounderella/utils/math.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Distance Calculation', () {
test('returns correct distance between Berlin and Paris', () {
// Example coordinates for Berlin and Paris
double berlinLat = 52.516216;
double berlinLon = 13.377646;
double parisLat = 48.858119;
double parisLon = 2.294483;
// Calculated distance between Berlin and Paris
double distance = calculateDistance(berlinLat, berlinLon, parisLat, parisLon);
// Expected approximate distance in kilometers
double expectedDistance = 879.1;
// Comparison of both distances
expect(distance, closeTo(expectedDistance, 1.0));
});
test('returns correct distance between same coordinates', () {
double lat = 49.469548;
double lon = 8.48243;
double distance = calculateDistance(lat, lon, lat, lon);
expect(distance, equals(0.0));
});
test('returns correct distance for long distances', () {
// Example coordinates for New York and Sydney
double newYorkLat = 40.7128;
double newYorkLon = -74.0060;
double sydneyLat = -33.8688;
double sydneyLon = 151.2093;
double distance = calculateDistance(newYorkLat, newYorkLon, sydneyLat, sydneyLon);
double expectedDistance = 15988; // in kilometers
// Comparison of the calculated and expected distance
// with a tolerance of 10 due to the enormous distance
expect(distance, closeTo(expectedDistance, 10.0));
});
});
group('Coordinate Conversion', () {
test('converts positive latitude correctly', () {
double decimalValue = 40.7128;
String result = convertDecimalToDMS(decimalValue, isLatitude: true);
expect(result, '40° 42\' 46.08" N');
});
test('converts negative latitude correctly', () {
double decimalValue = -40.7128;
String result = convertDecimalToDMS(decimalValue, isLatitude: true);
expect(result, '40° 42\' 46.08" S');
});
test('converts positive longitude correctly', () {
double decimalValue = 74.0060;
String result = convertDecimalToDMS(decimalValue, isLatitude: false);
expect(result, '74° 0\' 21.60" E');
});
test('converts negative longitude correctly', () {
double decimalValue = -74.0060;
String result = convertDecimalToDMS(decimalValue, isLatitude: false);
expect(result, '74° 0\' 21.60" W');
});
test('handles zero latitude correctly', () {
double decimalValue = 0.0;
String result = convertDecimalToDMS(decimalValue, isLatitude: true);
expect(result, '0° 0\' 0.00" N');
});
test('handles zero longitude correctly', () {
double decimalValue = 0.0;
String result = convertDecimalToDMS(decimalValue, isLatitude: false);
expect(result, '0° 0\' 0.00" E');
});
});
}