не удается получить доступ к элементу «координаты» коллекции объектов geojson

#angular #typescript #geojson

#angular #typescript #geojson

Вопрос:

В моем приложении Angular у меня есть коллекция объектов GeoJSON, которая представляет собой массив объектов, каждый из которых содержит объект геометрии и объект свойств. Структура выглядит следующим образом:

 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: {
        ...
  

Я пытаюсь создать маркер mapboxgl для каждого объекта в коллекции, и мне нужно получить координаты от каждого объекта GeoJSON, компилятор сообщает мне, что координаты не являются частью объекта. Конкретная ошибка: свойство «координаты» не существует для типа «Геометрия». Свойство «координаты» не существует для типа «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);
  

Моя консоль.отображение журнала

  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
  

Координаты находятся именно там, где я их ожидаю, но я не могу до них добраться. Я перепробовал всевозможные способы объявления коллекции объектов, но не могу найти правильную комбинацию.

Что мне нужно сделать, чтобы получить доступ к координатам?

Спасибо…..

Ответ №1:

Что мне нужно сделать, чтобы получить доступ к координатам?

Короткий ответ

Проверьте, что geometry это a Point , прежде чем пытаться получить доступ к его coordinates свойству.

 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);

}
  

Объяснение

Проблема, с которой вы столкнулись, возникает из-за того, что это Geometry тип объединения.

Тип объединения описывает значение, которое может быть одного из нескольких типов. Мы используем вертикальную полосу ( | ) для разделения каждого типа…

Это Geometry определение типа объединения:

 export type Geometry = 
    Point |
    MultiPoint | 
    LineString | 
    MultiLineString | 
    Polygon | 
    MultiPolygon | 
    GeometryCollection;
  

Как вы можете видеть, Geometry тип представляет собой объединение семи типов. К сожалению, не все из этих типов включают coordinates свойство.

Если у нас есть значение, имеющее тип объединения, мы можем получить доступ только к элементам, которые являются общими для всех типов в объединении.

Вот почему мы можем получить доступ к coordinates свойству только после того, как мы сузили тип.

Некоторые другие варианты

Если вы используете только Point типы в своем FeatureCollection , используйте Point тип в качестве общего параметра:

 let staticBreadcrumbs: FeatureCollection<Point>;
  

Если вы используете различные типы в своем FeatureCollection , затем используйте приведение, чтобы сообщить программе проверки типов, что вы уверены, что у вас есть Point :

 (staticBreadcrumbs.features[0].geometry as Point).coordinates[0]
  

Как показано в кратком ответе, вместо использования приведения вы можете использовать условный оператор для сужения типа:

 const geometry = staticBreadcrumbs.features[0].geometry;

if (geometry.type === 'Point') {
    const coordinates00 = geometry.coordinates[0];
    const coordinates01 = geometry.coordinates[1];
}
  

Здесь приведена краткая демонстрация этого последнего примера.

Комментарии:

1. Спасибо за это отличное объяснение! Я не знаю, что я когда-либо понял бы это сам. Но ваше объяснение имеет смысл. Спасибо!

2. Просто изменил свой код, и теперь он работает так, как я ожидал. Еще раз спасибо за ваше отличное объяснение. Узнал много интересного о typescript.

3. Этот ответ достаточно полезен, поскольку он применим к широкому спектру ситуаций сужения ссылок на машинописные тексты. Слава.

4. Сейчас 2022 год, и этот ответ помог мне, спасибо