GeoJSON
The Mapbox Java SDK's GeoJSON module provides support for GeoJSON, an open standard file format for representing map data. Read the GeoJSON specification and the Mapbox Glossary's GeoJSON entry for more information about GeoJSON.
Geometries
The Java SDK provides classes for all GeoJSON geometry types. Point
, MultiPoint
, LineString
, MultiLineString
, Polygon
, MultiPolygon
, and GeometryCollection
all end up implementing the Geometry
interface. This shared interface gives you flexibility as you work with the Java SDK and potentially other Mapbox SDKs for Android.
The Point
object represents a single geographical coordinate. It contains two values, longitude and latitude, in that order. This order is the reverse of the LatLng
object in the Mapbox Maps SDK for Android. If you're using the Maps SDK and the Java SDK together, you'll need to convert between Point
and LatLng
objects.
Point point = Point.fromLngLat(LONGITUDE, LATITUDE); // Java SDK
LatLng latLng = new LatLng(point.latitude(), point.longitude()); // Maps SDK
Point point = Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude());
val point = Point.fromLngLat(LONGITUDE, LATITUDE) // Java SDK
val latLng = LatLng(point.latitude(), point.longitude()) // Maps SDK
val point = Point.fromLngLat(latLng.longitude, latLng.latitude)
All geometry classes can be created via several different static methods. Always use a static method to create a GeoJSON geometry class.
Creating a single Polygon
:
Polygon polygon = Polygon.fromLngLats(listOfPointList);
Polygon polygonFromOuterInner = Polygon.fromOuterInner(outerLineStringObject,innerLineStringObject);
val polygon: Polygon = Polygon.fromLngLats(listOfPointList)
val polygonFromOuterInner: Polygon = Polygon.fromOuterInner(outerLineStringObject,innerLineStringObject)
Creating a single MultiLineString
:
MultiLineString multiLineString = MultiLineString.fromLineString(singleLineString);
MultiLineString multiLineStringFromLngLat = MultiLineString.fromLngLats(listOfPointList);
MultiLineString multiLineStringFromJson = MultiLineString.fromJson(JSON_STRING);
val multiLineString = MultiLineString.fromLineString(singleLineString)
val multiLineStringFromLngLat = MultiLineString.fromLngLats(listOfPointList)
val multiLineStringFromJson = MultiLineString.fromJson(JSON_STRING)
Feature and FeatureCollection
In the GeoJSON specification, a feature is an individual (or in some cases, a group of) points, lines, or polygons. Read more about features in the Mapbox Glossary. A group of features is called a feature collection.
The Java SDK's GeoJSON module also provides Feature
and FeatureCollection
classes. These classes can be combined with the various GeoJSON geometry classes.
Feature pointFeature = Feature.fromGeometry(Point.fromLngLat(LONGITUDE, LATITUDE));
Feature multiPointFeature = Feature.fromGeometry(MultiPoint.fromLngLats(listOfPoints));
FeatureCollection featureCollectionFromSingleFeature = FeatureCollection.fromFeature(pointFeature);
FeatureCollection featureCollection = FeatureCollection.fromFeatures(listOfFeatures);
FeatureCollection featureCollectionFromJson = FeatureCollection.fromJson(jsonString);
val pointFeature = Feature.fromGeometry(Point.fromLngLat(LONGITUDE, LATITUDE))
val multiPointFeature = Feature.fromGeometry(MultiPoint.fromLngLats(listOfPoints))
val featureCollectionFromSingleFeature = FeatureCollection.fromFeature(pointFeature)
val featureCollection: FeatureCollection = FeatureCollection.fromFeatures(listOfFeatures)
val featureCollectionFromJson = FeatureCollection.fromJson(jsonString)
Cast to a specific geometry object
A Feature
's Geometry
can be cast to a specific geometry object.
In the code below, a Feature
is used to create a Polygon
:
String polygonFeatureJson = "{
" +
" "type": "Feature",
" +
" "properties": {},
" +
" "geometry": {
" +
" "type": "Polygon",
" +
" "coordinates": [
" +
" [
" +
" [
" +
" -20.7421875,
" +
" 38.8225909761771
" +
" ],
" +
" [
" +
" -22.8515625,
" +
" -36.03133177633187
" +
" ],
" +
" [
" +
" 51.328125,
" +
" -36.597889133070204
" +
" ],
" +
" [
" +
" 48.515625,
" +
" 39.90973623453719
" +
" ],
" +
" [
" +
" -20.7421875,
" +
" 38.8225909761771
" +
" ]
" +
" ]
" +
" ]
" +
" }
" +
" }";
Feature singleFeature = Feature.fromJson(polygonFeatureJson);
Polygon polygon = (Polygon) singleFeature.geometry();
val polygonFeatureJson =
"""
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-34.453125,
-45.08903556483102
],
[
71.71875,
-45.08903556483102
],
[
71.71875,
43.32517767999296
],
[
-34.453125,
43.32517767999296
],
[
-34.453125,
-45.08903556483102
]
]
]
}
}
"""
val singleFeature = Feature.fromJson(polygonFeatureJson)
val polygon = singleFeature.geometry() as Polygon?
Check a geometry type
You can check a Feature
's geometry type. In the code below, a log message would appear whenever a Feature
is a Point
:
FeatureCollection featureCollection = FeatureCollection.fromFeatures(featureList);
if (featureCollection.features() != null) {
for (Feature singleFeature : featureCollection.features()) {
if (singleFeature.geometry() instanceof Point) {
Log.d(TAG, "is a Point geometry");
}
}
}
val featureCollection = FeatureCollection.fromFeatures(featureList)
featureCollection.features()?.let { featureList ->
for (singleFeature in featureList) {
if (singleFeature.geometry() is Point) {
Log.d(TAG, "is a Point geometry")
}
}
}
Use with the Maps SDK
When installed with Maven, the Mapbox Maps SDK for Android includes the Java SDK's GeoJSON module, which means you don't have to explicitly declare the Java SDK module if you're already using the Maps SDK. If you install the Maps SDK via direct download, you will need to declare the Java SDK explicitly.
Because of the Maps SDK's dependency on the GeoJSON module, the Maps SDK has been developed to support the Geometry
, Feature
, and FeatureCollection
classes.
GeoJSON updates
The Java and Maps SDKs are often used together to create a Maps SDK GeoJsonSource
with a Feature
or FeatureCollection
.
For example, here's how you can create a GeoJsonSource
with a Feature
and then add the GeoJsonSource
to the map.
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Create a list to store our line coordinates.
List routeCoordinates = new ArrayList<Point>();
routeCoordinates.add(Point.fromLngLat(-118.394391, 33.397676));
routeCoordinates.add(Point.fromLngLat(-118.370917, 33.391142));
// Create the LineString from the list of coordinates and then make a GeoJSON FeatureCollection so that you can add the line to our map as a layer.
LineString lineString = LineString.fromLngLats(routeCoordinates);
Feature feature = Feature.fromGeometry(lineString);
GeoJsonSource geoJsonSource = new GeoJsonSource("geojson-source", feature);
style.addSource(geoJsonSource);
}
});
mapboxMap.getStyle {
// Create a list to store our line coordinates.
val routeCoordinates = ArrayList<Point>()
routeCoordinates.add(Point.fromLngLat(-118.394391, 33.397676))
routeCoordinates.add(Point.fromLngLat(-118.370917, 33.391142))
// Create the LineString from the list of coordinates and then make a GeoJSON FeatureCollection so that you can add the line to our map as a layer.
val lineString = LineString.fromLngLats(routeCoordinates)
val feature = Feature.fromGeometry(lineString)
val geoJsonSource = GeoJsonSource("geojson-source", feature)
it.addSource(geoJsonSource)
}
}
You can also update a GeoJsonSource
's GeoJSON data to visually update the data on the map. Rather than passing through a Feature
or FeatureCollection
in the source.setGeoJson()
method, you can pass a Geometry
object to setGeoJson()
directly.
For example, here's how to set a GeoJsonSource
's GeoJSON data with a LineString
:
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
GeoJsonSource source = style.getSourceAs(sourceId);
if (source != null && directionsRoute.geometry() != null) {
source.setGeoJson(LineString.fromPolyline(directionsRoute.geometry(), PRECISION_6));
}
}
});
mapboxMap?.getStyle { style ->
val source = style.getSourceAs<GeoJsonSource>(sourceId)
if (source != null && directionsRoute.geometry() != null) {
source.setGeoJson(LineString.fromPolyline(directionsRoute.geometry()!!, Constants.PRECISION_6))
}
}
Serialize and deserialize geometries
There might be a situation where you want to pass geometry data from one part of your project to another. A common case is putting data into an Android Intent
as you start a new activity.
The geometry classes all have fromJson()
and toJson()
static methods, which help with serialization. The formatted valid JSON String passed through the fromJson()
method will create the geometry object. This fromJson()
method also means you can use Gson
or other serialization/deserialization strategies.
MultiPolygon multiLineStringFromJson = MultiPolygon.fromJson(JSON_STRING);
String multiPolygonString = multiPolygon.toJson();
val multiLineStringFromJson = MultiPolygon.fromJson(JSON_STRING)
val multiPolygonString = multiPolygon.toJson()