Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions benchmark/crs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Future<void> main() async {
const N = 100000000;

const crs = Epsg3857();
final cachedCrs = Epsg3857Cached();
results.add(await timedRun('Concrete type: ${crs.code}.latLngToXY()', () {
double x = 0;
double y = 0;
Expand All @@ -40,6 +41,20 @@ Future<void> main() async {
}
return x + y;
}));
results.add(await timedRun(
'Concrete type (cached): ${cachedCrs.code}.latLngToXY()',
() {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
final latlng = LatLng((i % 90).toDouble(), (i % 180).toDouble());
final (cx, cy) = cachedCrs.latLngToXY(latlng, 1);
x += cx;
y += cy;
}
return x + y;
},
));

results.add(await timedRun('Concrete type: ${crs.code}.latLngToOffset()', () {
double x = 0;
Expand All @@ -53,13 +68,30 @@ Future<void> main() async {
return x + y;
}));

const crss = <Crs>[
Epsg3857(),
Epsg4326(),
results.add(await timedRun(
'Concrete type (cached): ${cachedCrs.code}.latLngToOffset()',
() {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
final latlng = LatLng((i % 90).toDouble(), (i % 180).toDouble());
final p = cachedCrs.latLngToOffset(latlng, 1);
x += p.dx;
y += p.dy;
}
return x + y;
},
));

final crss = <(String, Crs)>[
('EPSG:3857', const Epsg3857()),
('EPSG:3857 (cached)', Epsg3857Cached()),
('EPSG:4326', const Epsg4326()),
('EPSG:4326 (cached)', Epsg4326Cached()),
];

for (final crs in crss) {
results.add(await timedRun('${crs.code}.latLngToXY()', () {
for (final (label, crs) in crss) {
results.add(await timedRun('$label.latLngToXY()', () {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
Expand All @@ -71,7 +103,7 @@ Future<void> main() async {
return x + y;
}));

results.add(await timedRun('${crs.code}.latlngToPoint()', () {
results.add(await timedRun('$label.latlngToPoint()', () {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
Expand All @@ -83,7 +115,7 @@ Future<void> main() async {
return x + y;
}));

results.add(await timedRun('${crs.code}.pointToLatLng()', () {
results.add(await timedRun('$label.pointToLatLng()', () {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
Expand Down
44 changes: 42 additions & 2 deletions lib/src/geo/crs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ abstract class Crs {
LatLng offsetToLatLng(Offset point, double zoom);

/// Zoom to Scale function.
double scale(double zoom) => 256.0 * math.pow(2, zoom);
double scale(double zoom) => 256.0 * math.pow(2.0, zoom);

/// Scale to Zoom function.
double zoom(double scale) => math.log(scale / 256) / math.ln2;
double zoom(double scale) => math.log(scale / 256.0) / math.ln2;

/// Rescales the bounds to a given zoom value.
Rect? getProjectedBounds(double zoom);
Expand All @@ -85,6 +85,31 @@ abstract class Crs {
}
}

mixin _ScaleCacheMixin on Crs {
double _lastScaleZoom = double.nan;
double _lastScaleValue = double.nan;
double _lastZoomScale = double.nan;
double _lastZoomValue = double.nan;

@override
double scale(double zoom) {
if (zoom == _lastScaleZoom) return _lastScaleValue;
final value = super.scale(zoom);
_lastScaleZoom = zoom;
_lastScaleValue = value;
return value;
}

@override
double zoom(double scale) {
if (scale == _lastZoomScale) return _lastZoomValue;
final value = super.zoom(scale);
_lastZoomScale = scale;
_lastZoomValue = value;
return value;
}
}

/// Internal base class for CRS with a single zoom-level independent transformation.
@immutable
@internal
Expand Down Expand Up @@ -159,6 +184,11 @@ class CrsSimple extends CrsWithStaticTransformation {
);
}

/// Non-const CRS with cached scale/zoom.
class CrsSimpleCached extends CrsSimple with _ScaleCacheMixin {
CrsSimpleCached() : super();
}

/// EPSG:3857, The most common CRS used for rendering maps.
@immutable
class Epsg3857 extends CrsWithStaticTransformation {
Expand Down Expand Up @@ -199,6 +229,11 @@ class Epsg3857 extends CrsWithStaticTransformation {
bool get replicatesWorldLongitude => true;
}

/// Non-const CRS with cached scale/zoom.
class Epsg3857Cached extends Epsg3857 with _ScaleCacheMixin {
Epsg3857Cached() : super();
}

/// EPSG:4326, A common CRS among GIS enthusiasts.
/// Uses simple Equirectangular projection.
@immutable
Expand All @@ -214,6 +249,11 @@ class Epsg4326 extends CrsWithStaticTransformation {
);
}

/// Non-const CRS with cached scale/zoom.
class Epsg4326Cached extends Epsg4326 with _ScaleCacheMixin {
Epsg4326Cached() : super();
}

/// Custom CRS
@immutable
class Proj4Crs extends Crs {
Expand Down