如何将TopoJSON线串转换为多边形?

时间:2016-09-08 13:03:54

标签: topojson

我有一个TopoJSON文件,其中包含印度北方邦各个地区的边界。在地图上加载数据时,只能看到区域的轮廓;地区本身没有填补。

我认为问题在于每个地区都属于GeometryCollection类型,其中geometries由一系列LineString组成。

相反,我希望每个分区的Polygon类型都只有arcs

例如,第一个对象是:

    {
        "type": "GeometryCollection",
        "geometries": [{
            "type": "GeometryCollection",
            "properties": {
                "district_number": 1,
                "district_name": "Ghaziabad"
            },
            "geometries": [{
                "type": "LineString",
                "arcs": [0]
            }, {
                "type": "LineString",
                "arcs": [1]
            }, {
                "type": "LineString",
                "arcs": [2]
            }, {
                "type": "LineString",
                "arcs": [3]
            }, {
                "type": "LineString",
                "arcs": [4]
            }, {
                "type": "LineString",
                "arcs": [5]
            }]
    }

我想我想将它和其他所有对象转换为:

    {
        "type": "Polygon",
        "properties": {
            "district_number": 1,
            "district_name": "Ghaziabad"
        },
        "arcs": [[0,1,2,3,4,5]]
    }

我可以手动修复它,但这看起来很疯狂。还有更好的方法吗?

更新

所以我想出了如何将对象转换为我想要的结果,但是我得到了一些非常古怪的多边形。这是我(非常笨重)的代码。感谢Saeed Adel Mehraban对此的一些指导。

   d3.json('map.topojson',function(error,data){ // get my json that needs to be converted

    var arr = data.objects.collection.geometries; // this is the relevant array
    var newArr = [];  // in order to map each object, i need to put each one into a new array as a single-item array

    arr.forEach(function(d,i){
      var curr = [d];
      newArr.push(curr);
    })

    newArr.forEach(function(e,i){ // now that i have my new array, i want to convert each object that contains a LineString into a Polygon

      var output = e.map(function(d){

        var arcsArr = []; // an empty array to push each single value of the LineString arcs into
        return {
          "type": "Polygon", // change the type to polygon
          "properties": d.properties, // keep the properties
          "arcs": d.geometries.map(function(g) { // a single key-value pair for arcs, made up of the individual arcs from the LineString
            arcsArr.push(g.arcs[0]);
            return [arcsArr]; // the array of arcs must be in another array
          })
        };

      });

      var output = output[0]; // get only the first item in the output array, which is the object i have modified
      output.arcs = output.arcs[0]; // and change the arcs so we're only taking the first array (as we've duplicated the arrays)
      $('body').append(JSON.stringify(output)+','); // append the whole thing to the body so I can copy it and paste it into the appropriate part of the JSON
    });
  });

这个“有用”的意思是我的LineString确实被转换为Polygon s,保留了原始边界。但是多边形本身就是一场噩梦,直线以各种角度交叉在地图上。

是否有像命令行工具可以将LineString s的边界转换为Polygon s?

2 个答案:

答案 0 :(得分:0)

也许地图功能如下? (我用简单的假设来编写数据模式。我不能保证它适用于复杂的线串,因为我不熟悉topojson格式。但它适用于你提供的数据)

var foo = [
  {
    "type": "GeometryCollection",
    "geometries": [{
      "type": "GeometryCollection",
      "properties": {
        "district_number": 1,
        "district_name": "Ghaziabad"
      },
      "geometries": [{
        "type": "LineString",
        "arcs": [0]
      }, {
        "type": "LineString",
        "arcs": [1]
      }, {
        "type": "LineString",
        "arcs": [2]
      }, {
        "type": "LineString",
        "arcs": [3]
      }, {
        "type": "LineString",
        "arcs": [4]
      }, {
        "type": "LineString",
        "arcs": [5]
      }]
    }]
  }
];
var bar = foo.map(function(d) {
  return {
    "type": "Polygon",
    "properties": d.geometries[0].properties,
    "arc": d.geometries.map(function(g1) {
      return g1.geometries.map(function(g) {
        return g.arcs[0];
      });
    })
  };
});

console.log(bar);

答案 1 :(得分:0)

我认为我遇到了同样的问题。

这是赞比亚绘制为每个弧的svg折线(红色是列出的第一个弧,洋红色是最后一个弧):

Zambia drawn as a svg polyline foreach arc

但是,当尝试通过连接圆弧来创建多边形时:

concatenated arcs

发生了什么事,每个对象的弧都是顺时针列出的,但每个对象的弧都是逆时针列出的。没有看到OP正在使用的topojson,我无法100%确认这一点,但我怀疑情况确实如此。

我通过在圆弧上反转点来解决此问题,然后将它们推到点数组以绘制多边形,现在一切正常:

enter image description here