#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 год, и этот ответ помог мне, спасибо