从GeoJson集合中提取属性和唯一值

时间:2019-07-11 16:07:57

标签: javascript arrays geojson

这是一个geojson对象,它具有功能数组,每个功能都有一个properties对象。

我知道有很多与映射数组和对象有关的问题,但是我找不到类似的情况。我尝试使用lodash mapgroupBy来映射属性并将值分组在它们的key下,但是老实说我只是不知道功能的组合。

我可以通过执行以下操作来获得属性名称部分:

// since properties are the same for all features
// I extract them alone first

let properties = Object.keys(features[0].properties)

properties.map(Prentelement =>
{
    let formated = {
        // this gives me the first part
        propertyName: Prentelement,

        // I can't figure out this part to map the values uniquely under
        children: [
          {
            value: "alex"
          },
          {
            value: "cairo"
          }
        ]
    }

    return formated;
})

这是输入格式的示例:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "Name": "cairo",
        "Type": "Province"
      }
    },
    {
      "type": "Feature",
      "properties": {
        "Name": "alex",
        "Type": "Province"
      }
    }
  ]
}

我想做的是对每个可用属性及其在不同功能上可能的值的一种总结。请注意,值可以在所有功能中重复,但最终结果只能使用一次。因此结果将是这样的数组:

[
  {
    propertyName: "Name",
    children: [
      {value: "alex"},
      {value: "cairo"}
    ]
  },
  {
    propertyName: "Type",
    children: [
      {value: "Province"}
    ]
  }
]

2 个答案:

答案 0 :(得分:1)

这里有一个解决方案,使用第一个Array.reduce()features数组按对象的属性分组。请注意,我们使用Sets仅保留唯一值。稍后,在第二步中,我们可以Array.map()先前生成的对象的entries得到所需的结构:

let input = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {"Name": "cairo", "Type": "Province"}
    },
    {
      "type": "Feature",
      "properties": {"Name": "alex", "Type": "Province"}
    }
  ]
};

// Step 1, group feature values by property.

let out = input.features.reduce((acc, {properties}) =>
{
    Object.entries(properties).forEach(([key, val]) =>
    {
        acc[key] = acc[key] || new Set();
        acc[key].add(val);
    });

    return acc;
}, {});

// Show the generated object on Step 1.

console.log("Step 1 - After grouping:", out);

for (const key in out)
{
    console.log(`${key} => ${[...out[key]]}`);
}

// Step 2, map the entries of the generated object.

out = Object.entries(out).map(([k, v]) =>
    ({PropertyName: k, Children: [...v].map(x => ({Value: x}))})
);

console.log("Step 2 - After mapping:", out);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

您可能需要阅读的其他文档:

答案 1 :(得分:1)

另一种方法(使用@Shidersz提供的相同输入数据):

     const result = input.features.reduce((acc, feature) => { 
             Object.keys(feature["properties"]).forEach(key => {
                 const index = acc.findIndex(property => {
                     return property["propertyName"] === key })

                 if (index === -1) {
                      acc.push({ propertyName: key, children: [ { value: feature["properties"][key]}] })
                 } else {
                      if (acc[index].children.findIndex(child => child.value === feature["properties"][key]) === -1) {
                        acc[index].children.push({ value: feature["properties"][key] })
                      }

                 }
             })

          return acc;

      }, []);

     console.log(JSON.stringify(result));