Skip to content

Commit

Permalink
feat(geobase): DistanceUnit enum class with unit types and conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
navispatial committed Jan 26, 2025
1 parent 5b1e760 commit 35e120a
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 8 deletions.
3 changes: 2 additions & 1 deletion dart/geobase/lib/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/// canvas origin, cardinal direction, DMS type, geo representation, axis
/// order, hemisphere, coordinate reference system types.
/// * Constants: epsilon, geodetic and screen related constants.
/// * Conversions: angle and distance units.
/// * Conversions: angle, area and distance units.
/// * Functions: conversions between radians and degrees, geographic coordinate
/// helpers.
/// * Presentation: DMS (degree-minutes-seconds geographic representations).
Expand Down Expand Up @@ -43,6 +43,7 @@ export 'src/common/constants/screen_ppi.dart';

// conversions
export 'src/common/conversions/angle_unit.dart';
export 'src/common/conversions/area_unit.dart';
export 'src/common/conversions/distance_unit.dart';

// functions
Expand Down
1 change: 1 addition & 0 deletions dart/geobase/lib/geobase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export 'src/common/constants/epsilon.dart';
export 'src/common/constants/geodetic.dart';
export 'src/common/constants/screen_ppi.dart';
export 'src/common/conversions/angle_unit.dart';
export 'src/common/conversions/area_unit.dart';
export 'src/common/conversions/distance_unit.dart';
export 'src/common/functions/geographic_functions.dart';
export 'src/common/functions/position_functions.dart';
Expand Down
12 changes: 6 additions & 6 deletions dart/geobase/lib/src/common/conversions/angle_unit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ enum AngleUnit {
milliradians(0.001, 'mrad'),

/// The SI base unit for angles.
///
///
/// 1 radian is approximately 57.296 degrees.
radians(1.0, 'rad'),

/// 1 arc second is equal to π / (180 * 60 * 60) radians.
///
///
/// 1 degree contains 60 * 60 = 3600 arc seconds.
arcSeconds(pi / (180 * 60 * 60), 'arcsec'),

/// 1 arc minute is equal to π / (180 * 60) radians.
///
///
/// 1 degree contains 60 arc minutes.
arcMinutes(pi / (180 * 60), 'arcmin'),

/// 1 degree is equal to π / 180 radians.
///
///
/// 1 degree is 1/360 of a full circle.
degrees(pi / 180, 'deg'),

/// 1 gradian is equal to π / 200 radians.
///
///
/// 1 gradian is 1/400 of a full circle.
gradians(pi / 200, 'gon'),

/// 1 turn is equal to 2π radians.
///
///
/// 1 turn is a full circle.
turns(2 * pi, 'turn');

Expand Down
83 changes: 83 additions & 0 deletions dart/geobase/lib/src/common/conversions/area_unit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) 2020-2025 Navibyte (https://navibyte.com). All rights reserved.
// Use of this source code is governed by a “BSD-3-Clause”-style license that is
// specified in the LICENSE file.
//
// Docs: https://github.com/navibyte/geospatial

/// An enumeration of area units.
///
/// The units are defined with conversion factors to square meters.
///
/// Examples:
///
/// ```dart
/// /// Convert directly from and to square meters.
/// final squareMeters = 10000.0;
/// final sqKmUnit = AreaUnit.squareKilometers;
/// final squareKilometers = sqKmUnit.fromSquareMeters(squareMeters); // 0.01
/// final squareMeters2 = sqKmUnit.toSquareMeters(squareKilometers); // 10000.0
///
/// /// You can also convert between units without using square meters.
/// final acres = sqKmUnit.toUnits(squareKilometers, AreaUnit.acres); // ~2.4711
/// ```
enum AreaUnit {
/// 1 square millimeter is equal to 1e-6 square meters.
squareMillimeters(1e-6, 'mm²'),

/// 1 square centimeter is equal to 1e-4 square meters.
squareCentimeters(1e-4, 'cm²'),

/// The SI base unit for area.
squareMeters(1.0, 'm²'),

/// 1 square kilometer is equal to 1e+6 square meters.
squareKilometers(1e6, 'km²'),

/// 1 square inch is equal to 0.00064516 square meters.
squareInches(0.00064516, 'in²'),

/// 1 square foot is equal to 0.09290304 square meters.
squareFeet(0.09290304, 'ft²'),

/// 1 square yard is equal to 0.83612736 square meters.
squareYards(0.83612736, 'yd²'),

/// 1 square mile is equal to 2589988.11 square meters.
squareMiles(2589988.11, 'mi²'),

/// 1 acre is equal to 4046.8564224 square meters.
acres(4046.8564224, 'ac'),

/// 1 hectare is equal to 10000 square meters.
hectares(10000.0, 'ha');

/// The conversion factor to square meters.
final double factorToSquareMeters;

/// The unit symbol.
final String symbol;

const AreaUnit(this.factorToSquareMeters, this.symbol);

/// Convert a value from this unit to square meters.
double toSquareMeters(double value) {
return value * factorToSquareMeters;
}

/// Convert a value from square meters to this unit.
double fromSquareMeters(double value) {
return value / factorToSquareMeters;
}

/// Convert a value from this unit to another unit.
double toUnits(double value, AreaUnit targetUnit) {
final valueInSquareMeters = toSquareMeters(value);
return targetUnit.fromSquareMeters(valueInSquareMeters);
}

/// Convert a value from another unit to this unit.
double fromUnits(double value, AreaUnit sourceUnit) {
final valueInSquareMeters = sourceUnit.toSquareMeters(value);
return fromSquareMeters(valueInSquareMeters);
}
}
2 changes: 1 addition & 1 deletion dart/geobase/lib/src/common/conversions/distance_unit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ enum DistanceUnit {
miles(1609.344, 'mi'),

/// 1 nautical mile is equal to 1852 meters.
///
///
/// Official unit symbols for nautical miles are "NM", "nmi" or "M" depending
/// on the context ([Wikipedia](https://en.wikipedia.org/wiki/Nautical_mile)).
nauticalMiles(1852.0, 'nmi');
Expand Down
128 changes: 128 additions & 0 deletions dart/geobase/test/common/conversion_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,132 @@ void main() {
);
});
});

group('AreaUnit', () {
test('square meters to square kilometers', () {
expect(
AreaUnit.squareMeters.toUnits(1000000, AreaUnit.squareKilometers),
equals(1),
);
});

test('square kilometers to square meters', () {
expect(
AreaUnit.squareKilometers.toUnits(1, AreaUnit.squareMeters),
equals(1000000),
);
});

test('square meters to square miles', () {
expect(
AreaUnit.squareMeters.toUnits(2589988.11, AreaUnit.squareMiles),
closeTo(1, 0.0001),
);
});

test('square miles to square meters', () {
expect(
AreaUnit.squareMiles.toUnits(1, AreaUnit.squareMeters),
closeTo(2589988.11, 0.0001),
);
});

test('square kilometers to square miles', () {
expect(
AreaUnit.squareKilometers.toUnits(2.589988, AreaUnit.squareMiles),
closeTo(1, 0.0001),
);
});

test('square miles to square kilometers', () {
expect(
AreaUnit.squareMiles.toUnits(1, AreaUnit.squareKilometers),
closeTo(2.589988, 0.0001),
);
});

test('square meters to square feet', () {
expect(
AreaUnit.squareMeters.toUnits(0.092903, AreaUnit.squareFeet),
closeTo(1, 0.0001),
);
});

test('square feet to square meters', () {
expect(
AreaUnit.squareFeet.toUnits(1, AreaUnit.squareMeters),
closeTo(0.092903, 0.0001),
);
});

test('square kilometers to square feet', () {
expect(
AreaUnit.squareKilometers.toUnits(0.000000092903, AreaUnit.squareFeet),
closeTo(1, 0.0001),
);
});

test('square feet to square kilometers', () {
expect(
AreaUnit.squareFeet.toUnits(1, AreaUnit.squareKilometers),
closeTo(0.000000092903, 0.0001),
);
});

test('square miles to square feet', () {
expect(
AreaUnit.squareMiles.toUnits(0.00000003587, AreaUnit.squareFeet),
closeTo(1, 0.0001),
);
});

test('square feet to square miles', () {
expect(
AreaUnit.squareFeet.toUnits(1, AreaUnit.squareMiles),
closeTo(0.00000003587, 0.0001),
);
});

test('hectares to square meters', () {
expect(
AreaUnit.hectares.toUnits(1, AreaUnit.squareMeters),
equals(10000),
);
});

test('square meters to hectares', () {
expect(
AreaUnit.squareMeters.toUnits(10000, AreaUnit.hectares),
equals(1),
);
});

test('acres to square meters', () {
expect(
AreaUnit.acres.toUnits(1, AreaUnit.squareMeters),
closeTo(4046.8564224, 0.0001),
);
});

test('square meters to acres', () {
expect(
AreaUnit.squareMeters.toUnits(4046.8564224, AreaUnit.acres),
closeTo(1, 0.0001),
);
});

test('hectares to acres', () {
expect(
AreaUnit.hectares.toUnits(1, AreaUnit.acres),
closeTo(2.47105, 0.0001),
);
});

test('acres to hectares', () {
expect(
AreaUnit.acres.toUnits(1, AreaUnit.hectares),
closeTo(0.404686, 0.0001),
);
});
});
}

0 comments on commit 35e120a

Please sign in to comment.