Added calculateDistance between two locations and first tests.
parent
ed8f1b810b
commit
a0f9dd43da
|
@ -1,5 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../helper.dart';
|
import '../utils/helper.dart';
|
||||||
|
|
||||||
class ProfileCategoryForm<T> extends StatefulWidget {
|
class ProfileCategoryForm<T> extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import '../constants.dart';
|
import '../constants.dart';
|
||||||
import '../helper.dart';
|
import '../utils/math.dart';
|
||||||
|
|
||||||
class MyLocation {
|
class MyLocation {
|
||||||
final String street;
|
final String street;
|
||||||
|
@ -43,8 +43,8 @@ class MyLocation {
|
||||||
/// Returns: locality, country. In case of an error: latitude, longitude.
|
/// Returns: locality, country. In case of an error: latitude, longitude.
|
||||||
String toStringDegree() {
|
String toStringDegree() {
|
||||||
try {
|
try {
|
||||||
String latResult = convertDecimalToDMS(latitude!);
|
String latResult = convertDecimalToDMS(latitude!, isLatitude: true);
|
||||||
String longResult = convertDecimalToDMS(longitude!);
|
String longResult = convertDecimalToDMS(longitude!, isLatitude: false);
|
||||||
return '$latResult, $longResult';
|
return '$latResult, $longResult';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// on error return origin values
|
// on error return origin values
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../components/my_button.dart';
|
import '../components/my_button.dart';
|
||||||
import '../components/my_textfield.dart';
|
import '../components/my_textfield.dart';
|
||||||
import '../helper.dart';
|
import '../utils/helper.dart';
|
||||||
import '../services/auth/auth_service.dart';
|
import '../services/auth/auth_service.dart';
|
||||||
|
|
||||||
class LoginPage extends StatelessWidget {
|
class LoginPage extends StatelessWidget {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:firebase_auth/firebase_auth.dart';
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import '../components/my_button.dart';
|
import '../components/my_button.dart';
|
||||||
import '../components/my_textfield.dart';
|
import '../components/my_textfield.dart';
|
||||||
import '../helper.dart';
|
import '../utils/helper.dart';
|
||||||
import '../services/auth/auth_service.dart';
|
import '../services/auth/auth_service.dart';
|
||||||
import '../services/user_service.dart';
|
import '../services/user_service.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
import 'package:firebase_auth/firebase_auth.dart';
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
|
||||||
import '../../constants.dart';
|
import '../../constants.dart';
|
||||||
import '../../helper.dart';
|
import '../../utils/helper.dart';
|
||||||
import '../../models/message.dart';
|
import '../../models/message.dart';
|
||||||
|
|
||||||
class ChatService {
|
class ChatService {
|
||||||
|
|
|
@ -12,32 +12,11 @@ bool equalContent(List<dynamic> list1, List<dynamic> list2) {
|
||||||
/// Creates a composite ID from the passed [ids].
|
/// Creates a composite ID from the passed [ids].
|
||||||
/// In the format id(1)_id(n)
|
/// 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
|
ids.sort(); // sort to ensure the result is the same for any order of ids
|
||||||
return ids.join('_');
|
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.
|
/// Get the [displayName] of our own Enumerations.
|
||||||
///
|
///
|
||||||
|
@ -72,4 +51,4 @@ void showMsg(BuildContext context, String title, String content) {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue