Skip to content

Projections

🌐 Built-in projections on WGS84

Projections available

See the WGS84 class for built-in projections on WGS 84 (World Geodetic System 1984) geographic coordinates.

The class provides projection adapters allowing conversions:

  • between WGS84 geographic and geocentric cartesian positions
  • between WGS84 geographic and geographic positions on the target datum
  • between WGS84 geographic and UTM projected positions
  • between positions projected to different UTM zones based on the WGS84 datum
  • between WGS84 geographic and Web Mercator projected positions

Applied on position objects

Here projected Web Mercator coordinates are metric coordinates with both x and y values having the valid value range of (-20037508.34, 20037508.34).

// Sample point as geographic coordinates.
const geographic = Geographic(lon: -0.0014, lat: 51.4778);
// Geographic (WGS 84 longitude-latitude) to Projected (WGS 84 Web Mercator).
final forward = WGS84.webMercator.forward;
final projected = geographic.project(forward);
// Projected (WGS 84 Web Mercator) to Geographic (WGS 84 longitude-latitude).
final inverse = WGS84.webMercator.inverse;
final unprojected = projected.project(inverse);
print('$unprojected <=> $projected');

Even if this sample shows only conversions between geographic and Web Mercator coordinates, the same approach can be used with other projections provided by the WGS84 class.

Applied on projection objects

This sample shows how to apply projections using initialized projection instances.

// Geographic (WGS 84 longitude-latitude) to Projected (WGS 84 Web Mercator)
final forward = WGS84.webMercator.forward;
final projected = forward.project(
const Geographic(lon: -0.0014, lat: 51.4778),
to: Projected.create,
);
// Projected (WGS 84 Web Mercator) to Geographic (WGS 84 longitude-latitude)
final inverse = WGS84.webMercator.inverse;
final unprojected = inverse.project(
projected,
to: Geographic.create,
);
print('${unprojected.toText(decimals: 5)}'
' <=> ${projected.toText(decimals: 5)}');

Applied on geometries and features

Geometry classes introduced in simple geometries and feature objects introduced in geospatial features have also project method that allow applying projections directly on them.

// The source point geometry with a position in WGS 84 coordinates.
final positionWgs84 = Geographic(lon: 2.2945, lat: 48.8582);
final point = Point(positionWgs84);
// Project to UTM projected coordinates (in zone 31 N).
final zone31N = UtmZone(31, 'N');
final wgs84toUtm31N = WGS84.utmZone(zone31N).forward;
final pointUtm31N = point.project(wgs84toUtm31N);
// Project back to WGS 84 coordinates.
final utm31NtoWgs84 = WGS84.utmZone(zone31N).inverse;
final pointWgs84 = pointUtm31N.project(utm31NtoWgs84);
// Print the original and projected point coordinates.
// {"type":"Point","coordinates":[2.2945,48.8582]} =>
// {"type":"Point","coordinates":[448251.80,5411932.68]} =>
// {"type":"Point","coordinates":[2.2945,48.8582]}"
print('${point.toText(decimals: 4)} => ${pointUtm31N.toText(decimals: 2)}'
' => ${pointWgs84.toText(decimals: 4)}');
// Project between WGS84 based UTM zones. Note that resulting coordinates may
// have strange values if the point do not locate inside the target zone.
final zone30N = UtmZone(30, 'N');
final utm31NtoUtm30N = WGS84.utmZoneToZone(zone31N, zone30N).forward;
final pointUtm30N = pointUtm31N.project(utm31NtoUtm30N);
print(pointUtm30N.position.toText(decimals: 2)); // 888276.96,5425220.84
// It's always possible to check the UTM zone a point is located in.
final zone = UtmZone.fromGeographic(positionWgs84);
print(zone); // 31 N
// The source WGS84 geographic position to geocentric cartesian.
final wgs84toGeocentric = WGS84.geocentric.forward;
final pointGeocentric = point.project(wgs84toGeocentric);
// prints "4200952.55,168323.77,4780198.41"
print(pointGeocentric.position.toText(decimals: 2));
// The source WGS84 geographic position to WG84 web mercator (metric).
final wgs84toWebMercator = WGS84.webMercator.forward;
final pointWebMercator = point.project(wgs84toWebMercator);
print(pointWebMercator.position.toText(decimals: 2)); // 255422.57,6250835.06

🗺️ External proj4dart package

An alternative way to apply coordinate projections is to use the proj4dart package. The package provides more projection definitions and capabilities than the built-in projections in the geobase package.

Coordinate projections based on the external proj4dart package requires imports like:

// import the default geobase library
import 'package:geobase/geobase.dart';
// need also an additional import with dependency to `proj4dart`
import 'package:geobase/projections_proj4d.dart';

Then a sample to use coordinate projections:

// The projection adapter between WGS84 (CRS84) and EPSG:23700 (definition)
// (based on the sample at https://pub.dev/packages/proj4dart).
final adapter = Proj4d.init(
CoordRefSys.CRS84,
CoordRefSys.normalized('EPSG:23700'),
targetDef: '+proj=somerc +lat_0=47.14439372222222 +lon_0=19.04857177777778 '
'+k_0=0.99993 +x_0=650000 +y_0=200000 +ellps=GRS67 '
'+towgs84=52.17,-71.82,-14.9,0,0,0,0 +units=m +no_defs',
);
// The forward projection from WGS84 (CRS84) to EPSG:23700.
final forward = adapter.forward;
// A source geographic position.
const geographic = Geographic(lat: 46.8922, lon: 17.8880);
// Apply the forward projection returning a projected position in EPSG:23700.
final projected = geographic.project(forward);
// Prints: "561647.27300,172651.56518"
print(projected.toText(decimals: 5));

Please see the documentation of proj4dart package about it’s capabilities, and accuracy of forward and inverse projections.

🧩 Custom projections

It’s also possible to implement your own custom projections by extending ProjectionAdapter mixin in your projection class. See Dart code of projections between WGS 84 (geographic) and Web Mercator (projected with metric coordinates) as an example. Custom projections can be applied to geometry and feature objects just like projections provided by packages discussed above.