Projections
Besides the Coordinates class, the Maps SDK for Android provides a Projection abstract class that represents the base class for different geocoordinate systems such as:
ProjectionWGS84(World Geodetic System 1984)ProjectionGK(Gauss-Kruger)ProjectionUTM(Universal Transverse Mercator)ProjectionLAM(Lambert)ProjectionBNG(British National Grid)ProjectionMGRS(Military Grid Reference System)ProjectionW3W(What three words)
To work with projections, you'll need to import the following classes:
- Kotlin
- Java
import com.magiclane.sdk.places.Coordinates
import com.magiclane.sdk.projection.*
import com.magiclane.sdk.core.ProgressListener
import com.magiclane.sdk.core.GemError
import com.magiclane.sdk.places.Coordinates;
import com.magiclane.sdk.projection.*;
import com.magiclane.sdk.core.ProgressListener;
import com.magiclane.sdk.core.GemError;
To know the type of the Projection you can use the type property:
- Kotlin
- Java
val type = projection.type
EProjectionType type = projection.getType();
ProjectionWGS84
The ProjectionWGS84 projection is a widely used geodetic datum that serves as the foundation for GPS and other mapping systems. It provides a standard reference frame for the Earth's surface, allowing for accurate positioning and navigation. A ProjectionWGS84 projection can be instantiated using a Coordinates object:
- Kotlin
- Java
val obj = ProjectionWGS84(Coordinates(latitude = 5.0, longitude = 5.0))
ProjectionWGS84 obj = new ProjectionWGS84(new Coordinates(5.0, 5.0));
Then, the coordinates can be accessed and set using the coordinates property:
- Kotlin
- Java
val coordinates = obj.coordinates // Get coordinates
obj.coordinates = Coordinates(latitude = 10.0, longitude = 10.0) // Set coordinates
Coordinates coordinates = obj.getCoordinates(); // Get coordinates
obj.setCoordinates(new Coordinates(10.0, 10.0)); // Set coordinates
ProjectionGK
The ProjectionGK (Gauss-Kruger) projection is a cylindrical map projection that is commonly used for large-scale mapping in regions with a north-south orientation. It divides the Earth into zones, each with its own coordinate system, allowing for accurate representation of geographic features. A ProjectionGK projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionGK(x = 6325113.72, y = 5082540.66, zone = 1)
ProjectionGK obj = new ProjectionGK(6325113.72, 5082540.66, 1);
In order to obtain the x, y and zone values, the getEasting(), getNorthing() and getZone() methods can be used, while setting them can be done using the set() method:
- Kotlin
- Java
val obj = ProjectionGK(x = 6325113.72, y = 5082540.66, zone = 1)
val type = obj.type // EProjectionType.EPR_Gk
val zone = obj.getZone() // 1
val easting = obj.getEasting() // 6325113.72
val northing = obj.getNorthing() // 5082540.66
obj.set(x = 1.0, y = 1.0, zone = 2)
val newZone = obj.getZone() // 2
val newEasting = obj.getEasting() // 1.0
val newNorthing = obj.getNorthing() // 1.0
ProjectionGK obj = new ProjectionGK(6325113.72, 5082540.66, 1);
EProjectionType type = obj.getType(); // EProjectionType.EPR_Gk
int zone = obj.getZone(); // 1
double easting = obj.getEasting(); // 6325113.72
double northing = obj.getNorthing(); // 5082540.66
obj.set(1.0, 1.0, 2);
int newZone = obj.getZone(); // 2
double newEasting = obj.getEasting(); // 1.0
double newNorthing = obj.getNorthing(); // 1.0
The ProjectionGK projection is currently supported only for countries that use Bessel ellipsoid. Trying to convert to and from ProjectionGK projection for other countries will result in a GemError.notSupported error.
ProjectionBNG
The ProjectionBNG (British National Grid) projection is a coordinate system used in Great Britain for mapping and navigation. It provides a grid reference system that allows for precise location identification within the country. A ProjectionBNG projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionBNG(easting = 500000.0, northing = 4649776.0)
ProjectionBNG obj = new ProjectionBNG(500000.0, 4649776.0);
Alternatively, you can create a ProjectionBNG using a grid reference string:
- Kotlin
- Java
val obj = ProjectionBNG("TQ123456")
ProjectionBNG obj = new ProjectionBNG("TQ123456");
In order to obtain the easting and northing values, the getEasting() and getNorthing() methods can be used, while setting them can be done using the set() method. You can also access the grid reference using the gridReference property:
- Kotlin
- Java
val obj = ProjectionBNG(easting = 6325113.72, northing = 5082540.66)
obj.set(easting = 1.0, northing = 1.0)
val type = obj.type // EProjectionType.EPR_Bng
val newEasting = obj.getEasting() // 1.0
val newNorthing = obj.getNorthing() // 1.0
val gridRef = obj.gridReference // Grid reference string
ProjectionBNG obj = new ProjectionBNG(6325113.72, 5082540.66);
obj.set(1.0, 1.0);
EProjectionType type = obj.getType(); // EProjectionType.EPR_Bng
double newEasting = obj.getEasting(); // 1.0
double newNorthing = obj.getNorthing(); // 1.0
String gridRef = obj.getGridReference(); // Grid reference string
ProjectionMGRS
The ProjectionMGRS (Military Grid Reference System) projection is a coordinate system used by the military for precise location identification. It combines the UTM and UPS coordinate systems to provide a grid reference system that is easy to use in the field. A ProjectionMGRS projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionMGRS(easting = 99316, northing = 10163, zone = "30U", letters = "XC")
ProjectionMGRS obj = new ProjectionMGRS(99316, 10163, "30U", "XC");
In order to obtain the easting, northing, zone and letters values, the getEasting(), getNorthing(), getZone() and getSq100kIdentifier() methods can be used, while setting them can be done using the set() method:
- Kotlin
- Java
val obj = ProjectionMGRS(
easting = 6325113, northing = 5082540, zone = "A", letters = "letters")
obj.set(
easting = 1, northing = 1, zone = "B", letters = "newLetters")
val type = obj.type // EProjectionType.EPR_Mgrs
val newZone = obj.getZone() // "B"
val newEasting = obj.getEasting() // 1
val newNorthing = obj.getNorthing() // 1
val newLetters = obj.getSq100kIdentifier() // "newLetters"
ProjectionMGRS obj = new ProjectionMGRS(
6325113, 5082540, "A", "letters");
obj.set(
1, 1, "B", "newLetters");
EProjectionType type = obj.getType(); // EProjectionType.EPR_Mgrs
String newZone = obj.getZone(); // "B"
int newEasting = obj.getEasting(); // 1
int newNorthing = obj.getNorthing(); // 1
String newLetters = obj.getSq100kIdentifier(); // "newLetters"
ProjectionW3W
The ProjectionW3W (What three words) projection is a geocoding system that divides the world into a grid of 3m x 3m squares, each identified by a unique combination of three words. This system provides a simple and memorable way to reference specific locations. A ProjectionW3W projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionW3W("your-api-token")
ProjectionW3W obj = new ProjectionW3W("your-api-token");
In order to obtain and set the token and words values, the getToken(), setToken(), getWords() and setWords() methods can be used:
- Kotlin
- Java
val obj = ProjectionW3W()
obj.setToken("your-api-token")
obj.setWords("index.home.raft")
val token = obj.getToken()
val words = obj.getWords()
ProjectionW3W obj = new ProjectionW3W();
obj.setToken("your-api-token");
obj.setWords("index.home.raft");
String token = obj.getToken();
String words = obj.getWords();
ProjectionLAM
The ProjectionLAM (Lambert) projection is a conic map projection that is commonly used for large-scale mapping in regions with an east-west orientation. It provides a way to represent geographic features accurately while minimizing distortion. A ProjectionLAM projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionLAM(x = 6325113.72, y = 5082540.66)
ProjectionLAM obj = new ProjectionLAM(6325113.72, 5082540.66);
In order to obtain the x and y values, the getX() and getY() methods can be used, while setting them can be done using the set() method:
- Kotlin
- Java
val obj = ProjectionLAM(x = 6325113.72, y = 5082540.66)
obj.set(x = 1.0, y = 1.0)
val type = obj.type // EProjectionType.EPR_Lam
val newX = obj.getX() // 1.0
val newY = obj.getY() // 1.0
ProjectionLAM obj = new ProjectionLAM(6325113.72, 5082540.66);
obj.set(1.0, 1.0);
EProjectionType type = obj.getType(); // EProjectionType.EPR_Lam
double newX = obj.getX(); // 1.0
double newY = obj.getY(); // 1.0
ProjectionUTM
The ProjectionUTM (Universal Transverse Mercator) projection is a global map projection that divides the world into a series of zones, each with its own coordinate system. It provides a way to represent geographic features accurately while minimizing distortion. A ProjectionUTM projection can be instantiated using the following constructor:
- Kotlin
- Java
val obj = ProjectionUTM(x = 6325113.72, y = 5082540.66, zone = 1, hemisphere = EHemisphere.HEM_South)
ProjectionUTM obj = new ProjectionUTM(6325113.72, 5082540.66, 1, EHemisphere.HEM_South);
In order to obtain the x, y, zone and hemisphere values, the getX(), getY(), getZone() and getHemisphere() methods can be used, while setting them can be done using the set() method:
- Kotlin
- Java
val obj = ProjectionUTM(x = 6325113.72, y = 5082540.66, zone = 1, hemisphere = EHemisphere.HEM_South)
obj.set(x = 1.0, y = 1.0, zone = 2, hemisphere = EHemisphere.HEM_North.value)
val type = obj.type // EProjectionType.EPR_Utm
val newZone = obj.getZone() // 2
val newX = obj.getX() // 1.0
val newY = obj.getY() // 1.0
val newHemisphere = EHemisphere.entries[obj.getHemisphere()] // EHemisphere.HEM_North
ProjectionUTM obj = new ProjectionUTM(6325113.72, 5082540.66, 1, EHemisphere.HEM_South);
obj.set(1.0, 1.0, 2, EHemisphere.HEM_North.getValue());
EProjectionType type = obj.getType(); // EProjectionType.EPR_Utm
int newZone = obj.getZone(); // 2
double newX = obj.getX(); // 1.0
double newY = obj.getY(); // 1.0
EHemisphere newHemisphere = EHemisphere.values()[obj.getHemisphere()]; // EHemisphere.HEM_North
Projection Service
The ProjectionService object provides a method to convert between different projection types. It allows you to transform coordinates from one projection to another, making it easier to work with various geospatial data formats. The class is an object and features a static convert method:
- Kotlin
- Java
val from = ProjectionWGS84(Coordinates(latitude = 51.5074, longitude = -0.1278))
val to = ProjectionMGRS()
val progressListener = ProgressListener.create(
onCompleted = { errorCode, _ ->
if (errorCode == GemError.NoError) {
// Conversion successful
val easting = to.getEasting() // 99316
val northing = to.getNorthing() // 10163
val zone = to.getZone() // "30U"
val letters = to.getSq100kIdentifier() // "XC"
} else {
// Handle conversion error
println("Conversion failed with error: $errorCode")
}
}
)
// Start the conversion
ProjectionService.convert(from, to, progressListener)
ProjectionWGS84 from = new ProjectionWGS84(new Coordinates(51.5074, -0.1278));
ProjectionMGRS to = new ProjectionMGRS();
ProgressListener progressListener = ProgressListener.create(
(errorCode, hint) -> {
if (errorCode == GemError.NoError) {
// Conversion successful
int easting = to.getEasting(); // 99316
int northing = to.getNorthing(); // 10163
String zone = to.getZone(); // "30U"
String letters = to.getSq100kIdentifier(); // "XC"
} else {
// Handle conversion error
System.out.println("Conversion failed with error: " + errorCode);
}
}
);
// Start the conversion
ProjectionService.convert(from, to, progressListener);
ProjectionService.convert works with ProjectionW3W only if the ProjectionW3W object has a valid token that can be obtained from what3words.com. If the token is not set, the conversion will fail and the GemError.NotSupported error will be returned via the progress listener.
Practical Example
Here's a practical example showing how to convert a WGS84 coordinate to multiple projection systems, similar to the approach used in the SDK's sample applications:
- Kotlin
- Java
// Starting coordinates
val wgs84Projection = ProjectionWGS84(Coordinates(latitude = 51.5074, longitude = -0.1278))
// Convert to different projection types
val projectionTypes = listOf(
EProjectionType.EPR_Mgrs,
EProjectionType.EPR_Utm,
EProjectionType.EPR_Bng,
EProjectionType.EPR_Lam,
EProjectionType.EPR_Gk
)
for (projectionType in projectionTypes) {
val targetProjection: Projection = when (projectionType) {
EProjectionType.EPR_Mgrs -> ProjectionMGRS()
EProjectionType.EPR_Utm -> ProjectionUTM()
EProjectionType.EPR_Bng -> ProjectionBNG()
EProjectionType.EPR_Lam -> ProjectionLAM()
EProjectionType.EPR_Gk -> ProjectionGK()
EProjectionType.EPR_WhatThreeWords -> {
ProjectionW3W().also {
it.setToken("your-valid-w3w-token")
}
}
else -> continue
}
val progressListener = ProgressListener.create(
onCompleted = { errorCode, _ ->
if (errorCode == GemError.NoError) {
// Handle successful conversion
when (targetProjection) {
is ProjectionMGRS -> {
println("MGRS: ${targetProjection.getEasting()}, ${targetProjection.getNorthing()}")
println("Zone: ${targetProjection.getZone()}, Letters: ${targetProjection.getSq100kIdentifier()}")
}
is ProjectionUTM -> {
println("UTM: ${targetProjection.getX()}, ${targetProjection.getY()}")
println("Zone: ${targetProjection.getZone()}, Hemisphere: ${EHemisphere.entries[targetProjection.getHemisphere()]}")
}
is ProjectionBNG -> {
println("BNG: ${targetProjection.getEasting()}, ${targetProjection.getNorthing()}")
println("Grid Reference: ${targetProjection.gridReference}")
}
// Add other projection types as needed
}
} else {
println("Conversion to ${projectionType} failed with error: $errorCode")
}
}
)
ProjectionService.convert(wgs84Projection, targetProjection, progressListener)
}
// Starting coordinates
ProjectionWGS84 wgs84Projection = new ProjectionWGS84(new Coordinates(51.5074, -0.1278));
// Convert to different projection types
EProjectionType[] projectionTypes = {
EProjectionType.EPR_Mgrs,
EProjectionType.EPR_Utm,
EProjectionType.EPR_Bng,
EProjectionType.EPR_Lam,
EProjectionType.EPR_Gk
};
for (EProjectionType projectionType : projectionTypes) {
Projection targetProjection;
switch (projectionType) {
case EPR_Mgrs:
targetProjection = new ProjectionMGRS();
break;
case EPR_Utm:
targetProjection = new ProjectionUTM();
break;
case EPR_Bng:
targetProjection = new ProjectionBNG();
break;
case EPR_Lam:
targetProjection = new ProjectionLAM();
break;
case EPR_Gk:
targetProjection = new ProjectionGK();
break;
case EPR_WhatThreeWords:
ProjectionW3W w3w = new ProjectionW3W();
w3w.setToken("your-valid-w3w-token");
targetProjection = w3w;
break;
default:
continue;
}
Projection finalTarget = targetProjection;
ProgressListener progressListener = ProgressListener.create(
(errorCode, hint) -> {
if (errorCode == GemError.NoError) {
// Handle successful conversion
if (finalTarget instanceof ProjectionMGRS) {
ProjectionMGRS mgrs = (ProjectionMGRS) finalTarget;
System.out.println("MGRS: " + mgrs.getEasting() + ", " + mgrs.getNorthing());
System.out.println("Zone: " + mgrs.getZone() + ", Letters: " + mgrs.getSq100kIdentifier());
} else if (finalTarget instanceof ProjectionUTM) {
ProjectionUTM utm = (ProjectionUTM) finalTarget;
System.out.println("UTM: " + utm.getX() + ", " + utm.getY());
System.out.println("Zone: " + utm.getZone() + ", Hemisphere: " + EHemisphere.values()[utm.getHemisphere()]);
} else if (finalTarget instanceof ProjectionBNG) {
ProjectionBNG bng = (ProjectionBNG) finalTarget;
System.out.println("BNG: " + bng.getEasting() + ", " + bng.getNorthing());
System.out.println("Grid Reference: " + bng.getGridReference());
}
// Add other projection types as needed
} else {
System.out.println("Conversion to " + projectionType + " failed with error: " + errorCode);
}
}
);
ProjectionService.convert(wgs84Projection, targetProjection, progressListener);
}
This example demonstrates how to convert a single WGS84 coordinate to multiple projection systems and extract the relevant information from each converted projection.