I have a GeoJSON feature collection in my Angular app that is an array of features, each containing a geometry object and properties object. Structure looks like this:
import { FeatureCollection, Feature } from 'geojson';
staticBreadcrumbs: GeoJSON.FeatureCollection<GeoJSON.Geometry>;
this.staticBreadcrumbs = {
type : 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
property1: 'property1',
property2: 'property2'
},
geometry: {
type: 'Point',
coordinates: [-117.14024305343628, 32.81294345855713]
}
},
{
type: 'Feature',
properties: {
...
I'm trying to create a mapboxgl marker for each feature in the collection and need to get the coordinates from each GeoJSON object, the compiler is telling me that the coordinates aren't part of the feature. The specific error is: Property 'coordinates' does not exist on type 'Geometry'. Property 'coordinates' does not exist on type 'GeometryCollection'.
console.log('this.staticBreadcrumbs.features[0]', this.staticBreadcrumbs.features[0]);
var marker = new Marker(el)
.setLngLat([
this.staticBreadcrumbs.features[0].geometry.coordinates[0],
this.staticBreadcrumbs.features[0].geometry.coordinates[1]
])
.addTo(this.map);
My console.log displays
this.staticBreadcrumbs.features[0]
{type: "Feature", properties: {…}, geometry: {…}}
1. geometry:
1. coordinates: Array(2)
1. 0: -117.14024305343628
2. 1: 32.81294345855713
3. length: 2
4. __proto__: Array(0)
2. type: "Point"
2. __proto__: Object
2. properties: {deviceID: "CAP498", altitude: 401.6721913312, autonomous: 0, azimuth: 0, batteryStatusLabel: "Nominal", …}
3. type: "Feature"
4. __proto__: Object
The coordinates are exactly where I expect them to be, but I can't get to them. I have tried all sort of different ways to declare the Feature collection, but I can't find the right combination.
What do I need to do in order to access the coordinates?
Thanks.....
GeoJSON object properties are in OL accessible through . get(propertyName) method. For example, if your GeoJSON has property named otherParameter , you can access it in OL with geojsonLayer. get('otherParameter') .
GeoJSON supports the following feature types: Point (including addresses and locations) Line string (including streets, highways, and boundaries) Polygon (including countries, provinces, and tracts of land) Multipart collections of point, line string, or polygon features.
The specification does not forbid it explicitly, but feature collections do not have properties. GeoJSON spec only mentions the following keys for FeatureCollection: type - must be `FeatureCollection. features - array of feaures.
The coordinate reference system (CRS) of a GeoJSON object is determined by its. "crs" member (referred to as the CRS object below). If an object has no crs.
What do I need to do in order to access the coordinates?
Check that geometry
is a Point
before trying to access its coordinates
property.
if (staticBreadcrumbs.features[0].geometry.type === 'Point') {
var marker = new Marker(el)
.setLngLat([
this.staticBreadcrumbs.features[0].geometry.coordinates[0],
this.staticBreadcrumbs.features[0].geometry.coordinates[1]
])
.addTo(this.map);
}
The problem you're experiencing happens because Geometry
is a union type.
A union type describes a value that can be one of several types. We use the vertical bar (
|
) to separate each type...
This is the Geometry
union type definition:
export type Geometry =
Point |
MultiPoint |
LineString |
MultiLineString |
Polygon |
MultiPolygon |
GeometryCollection;
As you can see, the Geometry
type is a union of seven types. Unfortunately, not all of those types include the coordinates
property.
If we have a value that has a union type, we can only access members that are common to all types in the union.
That is why we are only able to access the coordinates
property after we have narrowed the type.
If you're using only Point
types in your FeatureCollection
, then use the Point
type as the generic parameter:
let staticBreadcrumbs: FeatureCollection<Point>;
If you're using a variety of types in your FeatureCollection
, then use a cast to tell the type checker that you're sure you have a Point
:
(staticBreadcrumbs.features[0].geometry as Point).coordinates[0]
As shown in the Short Answer, instead of using a cast, you can use a conditional statement to narrow the type:
const geometry = staticBreadcrumbs.features[0].geometry;
if (geometry.type === 'Point') {
const coordinates00 = geometry.coordinates[0];
const coordinates01 = geometry.coordinates[1];
}
There is a short demo of that last example here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With