What is a geometry projection?
Geometry projection is the process of transforming the vertices of a geometric shape from one coordinate system (or spatial reference) to another. A geometry projection can occur dynamically in a map, manually on the client-side, or by requesting it to happen on the server-side. To execute the analysis, you can use ArcGIS Maps SDK for JavaScript, ArcGIS Maps SDKs for Native Apps, or ArcGIS API for Python. See the code examples below.
You can use geometry projections to:
- Correctly display the location of geographic features on a map or scene.
- Convert geometries from a projected coordinate system to a geographic coordinate system e.g. Web mercator to WGS 84.
- Convert geometries from a geographic coordinate system to a projected coordinate system e.g. WGS 84 to Web mercator.
- Align and display multiple datasets with different spatial references with a single spatial reference.
- Correct data to perform different types of geometry and spatial analysis.
- Accurately calculate length and area.
How to project a geometry
- Create a geometry from a dataset or a hosted feature layer.
- Determine the current spatial reference.
- Choose an new spatial reference.
- Project the geometry.
Types of projection operations
Operation | Description | Example |
---|---|---|
Project | Returns a projected geometry in the specified spatial reference. |
Using projections
mercator to latitude and longitude
One of the most common tasks is to convert between web mercator and latitude and longitude. Most basemap styles services provide data in web mercator coordinates and often GPS data, navigation location, and other point data is obtained using latitude and longitude (WGS84). To convert between the coordinates most ArcGIS APIs provide a method to do so. To learn how to do this with different APIs, see the Coordinate conversion example below.
Map projection
By default, most ArcGIS APIs automatically project geometries on the fly to match the spatial reference of the map. The geometries can be add to the map as layers or graphics. Therefore, in most cases, if your data doesn't match the spatial reference of the map, you don't need to manually project layers with geometries. Learn more about layers in Data layers.
Measurement
Projecting geometries is also important to ensure accurate measurements of length and area. When measuring length, you should ensure the projected coordinate system of the geometries preserves distance. When measuring area, you should ensure the projected coordinate system of the input geometries preserves area.
Spatial analysis
In order to perform spatial analyses and produce accurate results, all of the input geometry data has to be in the same coordinate system (spatial reference). If the input data is not the same, you need to project the geometries beforehand. Learn more about performing spatial analysis in Feature analysis.
Code examples
Coordinate conversion
For some of the ArcGIS client APIs, if a map uses a Web Mercator spatial reference when graphics and features in layers are added, the coordinates are automatically projected to WGS 84 and are available in latitude and longitude. Therefore, in this case, you can access the latitude and longitude coordinates directly do not need to project the geometries.
In the case that coordinates are not converted automatically, you have to use methods to convert them.
This example demonstrates how point coordinates are converted from Web Mercator (wkid:102100/3857) to WGS 84 (wkid:4326) (i.e. latitude/longitude). Click on the map or search for places to display both sets of coordinates.
view.openPopup({
title: "COORDINATES",
content: `
<div class="tbl">
<div>
<span><b>Web Mercator</b></span>
<span>X: ${point.x.toFixed(5)}</span>
<span>Y: ${point.y.toFixed(5)}</span>
<span>Wkid: ${point.spatialReference.wkid}</span>
</div>
<div>
<span><b>WGS84</b></span>
<span>Longitude: ${point.longitude.toFixed(5)}</span>
<span>Latitude: ${point.latitude.toFixed(5)}</span>
<span>Wkid: 4326</span>
</div>
</div>`,
includeDefaultActions: false,
});
Dynamic projection
In this example, GeoJSON data of countries defined with a WGS 1984 (wkid 4326) coordinate system is added to the map as a layer. The map view spatial reference is set to World Equidistant conic (wkid 54027). The map view automatically projects and displays the data on-the-fly.
When data is projected in the view, coordinates of the geometries are converted to the new coordinate system, and are available to access, but the underlying data source is not changed.
// Countries GeoJSON file
const dataUrl = "/documentation//data/countries.geojson";
const geoJSONLayer = new GeoJSONLayer({
url: dataUrl,
copyright: "Esri",
spatialReference: {
wkid: 4326 // WGS 1984
},
renderer: {
type: "simple",
symbol: {
type: "simple-fill",
color: [255, 255, 255, 1],
outline: {
width: 0.5,
color: [100, 70, 170, .75]
}
}
}
});
const view = new MapView({
container: "viewDiv",
map: {
layers: [geoJSONLayer] // Autocast the map object
},
spatialReference: {
wkid: 54027 // World Equidistant conic, maintains length
},
center,
scale: 200000000,
constraints:{
minScale: 200000000
}
});
Client-side projection
In this example, data of countries defined with in the Web Mercator (wkid 102100) coordinate system is added to the map as a layer. The map view spatial reference is set to WGS 1984. When you click the map, the geometry is projected to wkid 8858 and displayed.
const countryFeatureProjected = results[0].graphic.clone();
const { attributes, geometry } = countryFeatureProjected;
// Spatial reference to project to
const projectedSpatialReference = {
wkid: 8858 // Equal Earth Americas
}
const projectedGeometry = projectionEngine.project(geometry, projectedSpatialReference);
Server-side projection
In this example, the map view spatial reference is set to Web mercator (wkid 102100) and the data of the countries layer loaded is also set to Web Mercator. But when you click on the map view a request is been sent to the server to recover the country that was hit and it is requested also to recover the geometry in a different spatial reference (wkid: 54010, World Eckert VI), which is displayed in the side panel and added to the view, which, in turn, reprojects it again.
const countryQuery = {
spatialRelationship: "intersects",
geometry: event.mapPoint,
outFields: ["*"],
outSpatialReference: {
wkid: 54027
},
returnGeometry: true
};
countriesGeneralized.queryFeatures(countryQuery)
.then((results) => {
if(results.features.length > 0){
const selectedCountry = results.features[0];
selectedCountry.symbol = solidFillSymbol;
view.graphics.removeAll();
view.graphics.add(selectedCountry);
outputView.graphics.removeAll();
outputView.graphics.add(selectedCountry);
outputView.extent = selectedCountry.geometry.extent;
infoDiv.innerHTML = `
<b>Country</b>: ${selectedCountry.attributes.COUNTRY}<br>
<b><a href="${dataUrl}/0/query?where=1=1&outFields=*&f=pjson">Incoming data</a> WKID</b>: ${countriesGeneralized.spatialReference.wkid}<br>
<b>Projected country WKID</b>: ${selectedCountry.geometry.spatialReference.wkid}<br>
<code><pre>${JSON.stringify(selectedCountry.geometry.toJSON(), null, 2)}</pre></code>
`;
}else{
infoDiv.innerHTML = `
No country selected. Try again. br>
Select a country on the map.
`;
}
}).catch((error) => {
console.error(error);
});