【问题标题】:Property 'features' does not exist on type 'Feature<Point, { [name: string]: any; }>'类型 'Feature<Point, { [name: string]: any; 上不存在属性 'features' }>'
【发布时间】:2019-05-07 12:03:26
【问题描述】:

我是 Angular 的新手,我正在尝试使用 Angular/d3 构建德国地图。地图数据存储在一个Topojson文件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)

我使用以下由 mapshaper.org 创建的 Topojson 文件(这个文件有点简化,但结构保持不变): gist.github.com/.../plz_map_ger.json

【问题讨论】:

    标签: angular d3.js geojson topojson


    【解决方案1】:

    根据the types,函数feature()返回FeatureFeatureCollection。只有FeatureCollection 将具有您要查找的.features 属性。

    检查code of the TopoJSON Package(第4-8行)我们可以看到FeatureCollection只返回,如果topologyGeometryCollection 作为它的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");
              });
          });
    

    【讨论】:

    • feature(a, b) 函数可以返回 GeoJSON.FeatureGeoJSON.FeatureCollection 两者中的哪一个不是在编译时决定的,而是在运行时决定的,因为它取决于 type 属性异步加载的拓扑。
    • 所以设置mapFeatures的类型为GeoJSON.FeatureCollection;正确的?我也许应该更新解决方案。
    • 感谢您的讨论和帮助!我已经上传并链接了我在问题中使用的 Topojson 文件。
    猜你喜欢
    • 2023-04-03
    • 2021-08-08
    • 2021-12-28
    • 2021-02-08
    • 2019-09-20
    • 2018-09-09
    • 2019-12-31
    • 2022-12-17
    • 2021-11-29
    相关资源
    最近更新 更多