Свойство 'features' не существует для типа 'Feature' - PullRequest
2 голосов
/ 07 мая 2019

Я новичок в Angular и пытаюсь построить карту Германии с Angular / d3.Данные карты хранятся в файле Топойсона plz_map_ger.json:

{
"type": "Topology",
"arcs": [...],
"transform": {...},
"objects": {
      "plz5stellig": {...}
      }
 }

Это мой код для рисования карты:

import * as d3 from "d3";
import * as t from 'topojson';

...

d3.json("../../assets/plz_map_ger.json")
  .then(function(top:any) {
    g.selectAll('path')
      .data(t.feature(top, top.objects.plz5stellig).features)
      .enter()
      .append('path')
      .attr('d', path)
      .attr("class","kreisgrenzen")
      .on("click", function() {
        d3.select(this).attr("class","selected-kreis");
      });

Однако я получаю следующую ошибку компиляции:

error TS2339: Property 'features' does not exist on type 'Feature<Point, { [name: string]: any; }>'.

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

Редактировать: Когда я наводю курсор на ошибку в VS Code, я получаю следующее сообщение:

Property 'features' does not exist on type 'Feature<Point, { [name: string]: any; }>'.ts(2339)

Я использую следующий файл Topojson (этот файл немного упрощен, однако структура остаетсято же самое), созданный с mapshaper.org: gist.github.com /.../ plz_map_ger.json

1 Ответ

1 голос
/ 07 мая 2019

Согласно типам функция feature() возвращает либо Feature, либо FeatureCollection.Только FeatureCollection будет иметь атрибут .features, который вы ищете.

Проверка кода пакета TopoJSON (строки 4 - 8), мы видим, что a FeatureCollection возвращается, только если topology имеет GeometryCollection в качестве type.

export default function(topology, o) {
  return o.type === "GeometryCollection"
  ? {type: "FeatureCollection", features: o.geometries.map(function(o) { return feature(topology, o); })}
      : feature(topology, o);
}

Вы загружаете topology асинхронно, поэтому для компилятора невозможно узнать, является ли.type равно GeometryCollection или нет.

Для решения этой проблемы вам необходимо установить типы GeoJSON (npm i @types/geojson).

Затем можно установитьтип временной переменной

    ...
    d3.json("../../assets/plz_map_ger.json")
      .then(function(top:any) {

          // This row sets the temporary variable
          let mapFeatures: FeatureCollection = t.feature(top, top.objects.plz5stellig)

           g.selectAll('path')

          // We use the temporary variable here
          .data(mapFeatures.features)
          .enter()
          .append('path')
          .attr('d', path)
          .attr("class","kreisgrenzen")
          .on("click", function() {
            d3.select(this).attr("class","selected-kreis");
          });
      });

Или вы можете явным образом привести коллекцию в коллекцию объектов (благодаря @altocumulus)

  ...
    d3.json("../../assets/plz_map_ger.json")
      .then(function(top:any) {
           g.selectAll('path')
          // explicit cast
          .data((t.feature(top, top.objects.plz5stellig) as GeometryCollection).features)
          .enter()
          .append('path')
          .attr('d', path)
          .attr("class","kreisgrenzen")
          .on("click", function() {
            d3.select(this).attr("class","selected-kreis");
          });
      });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...