Leaflet 中的 TopoJSON,来自 Omnivore:读取属性

TopoJSON in Leaflet, via Omnivore: reading properties

在跟随 tutorial on choropleth maps in Leaflet I realized that a Shapefile > GeoJSON conversion generated a very large file. TopoJSON proved a better alternative, except for being unable to access the properties for each geometry. I merged data from https://github.com/centraldedados/violencia-domestica into a TopoJSON file converted from a Shapefile 时,结构如下:

{
  "transform": {
    "scale": [
      0.0025081552497290688,
      0.0012125352320998587
    ],
    "translate": [
      -31.26818656921381,
      30.03017616271984
    ]
  },
  "objects": {"PRT_adm1": {
    "geometries": [
      {
        "type": "Polygon",
        "arcs": [[
          0,
          1,
          2,
          3,
          4
        ]],
        "properties": {
          "ENGTYPE_1": "District",
          "ISO": "PRT",
          "NL_NAME_1": null,
          "HASC_1": "PT.EV",
          "ID_0": 182,
          "NAME_0": "Portugal",
          "TYPE_1": "Distrito",
          "ID_1": 1,
          "NAME_1": "Évora",
          "CCN_1": 0,
          "CCA_1": null,
          "dgai_violencia_domestica_2008_2014": {
            "Valores": [
              {
                "Ano": "2009",
                "Entidade": [
                  {"GNR": "216"},
                  {"PSP": "171"}
                ]
              },
              {
                "Ano": "2010",
                "Entidade": [
                  {"GNR": "247"},
                  {"PSP": "162"}
                ]
              },
              {
                "Ano": "2011",
                "Entidade": [
                  {"GNR": "248"},
                  {"PSP": "181"}
                ]
              },
              {
                "Ano": "2012",
                "Entidade": [
                  {"GNR": "277"},
                  {"PSP": "150"}
                ]
              },
              {
                "Ano": "2013",
                "Entidade": [
                  {"GNR": "207"},
                  {"PSP": "169"}
                ]
              },
              {
                "Ano": "2014",
                "Entidade": [
                  {"GNR": "226"},
                  {"PSP": "137"}
                ]
              }
            ],
            "Distrito": "Évora",
            "Factor_amostra": 0.020521270111203194,
            "Somatorio_amostra": 2391
          },
          "VARNAME_1": null
        }
      },
      ...

并想访问每个对象的 "dgai_violencia_domestica_2008_2014.Factor_amostra" 属性,以便对颜色值进行编码。

使用 Leaflet+Omnivore 是否可行,或者是否需要 d3 或其他库?

地图的当前损坏版本存在 here,相关代码为:

L.mapbox.accessToken = '...';
var map = L.mapbox.map('map', 'mapbox.streets').setView([39.5, -8.60], 7);

// Omnivore will AJAX-request this file behind the scenes and parse it:
// note that there are considerations:
// - The file must either be on the same domain as the page that requests it,
//   or both the server it is requested from and the user's browser must
//   support CORS.

// Internally this function uses the TopoJSON library to decode the given file
// into GeoJSON.

function getColor(d) {
    return d > 0.75 ? '#800026' :
           d > 0.50  ? '#FC4E2A' :
           d > 0.25   ? '#FD8D3C' :
                      '#FFEDA0';
}

var pt = omnivore.topojson('dgai_violencia_domestica_2008_2014.topo.json');

function style(geometry) {
  return {
    fillColor: getColor(geometry.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra),
    weight: 1,
    opacity: 1,
    color: 'white',
    dashArray: '3',
    fillOpacity: 1
};
}

pt.setStyle(style);
pt.addTo(map);

朝正确的方向轻推,有人吗?

提前致谢。

做了一些测试,结果是 setStyle 函数不会执行:

pt.setStyle(function (feature) {
    console.log('Yay, i am executed!');
    return {
        'color': 'red'
    }
});

使用 Yay, i am executed! 永远不会记录到控制台。这让我怀疑 Omnivore 的 setStyle 方法有问题。所以我尝试了一个自定义层:

var geojson = new L.GeoJSON(null);

var pt = omnivore.topojson(url, null, geojson).addTo(map);

geojson.setStyle(function (feature) {
    console.log('Yay, i am executed!');
    return {
        'color': 'red'
    };
});

同样,Yay, i am executed! 永远不会记录到控制台。剩下要尝试的一件事是 L.GeoJSONstyle 选项:

var geojson = new L.GeoJSON(null, {
    'style': function (feature) {
        console.log('Yay, i am executed!');
        return {
            'color': 'red'
        };
    }
});

var pt = omnivore.topojson(url, null, geojson).addTo(map);

你瞧,这就是它应该做的。所以我用你的风格和颜色函数和数据集试了一下:

function getColor(d) {
    return d > 0.75 ? '#800026' :
           d > 0.50 ? '#FC4E2A' :
           d > 0.25 ? '#FD8D3C' :
                      '#FFEDA0';
}

function getStyle (feature) {
    return {
        fillColor: getColor(feature.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra),
        weight: 1,
        opacity: 1,
        color: 'white',
        dashArray: '3',
        fillOpacity: 1
    };
}

var geojson = new L.GeoJSON(null, {
    'style': getStyle
});

var pt = omnivore.topojson(url, null, geojson).addTo(map);

这给了我以下错误:

Uncaught TypeError: Cannot read property 'Peso_na_duracao_da_amostra' of undefined

那是因为在第三个特征中,属性 缺失了。所以您的数据集已损坏或不完整。希望这对您有所帮助,祝您好运,这是我的实验的 Plunker(到目前为止):

http://plnkr.co/edit/P6t96hTaOgSxTc4TPUuV?p=preview