如何将three.js中的geoJSON绘制为网格而不是线条,并填充颜色?

时间:2016-11-10 05:22:03

标签: javascript three.js geojson

我正在使用three.js创建一个globe,并将添加一些数据层。所有图层都将从geoJSON创建。我已将其设置为全局(第一个数据文件,即国家/地区)显示为行。这使用ThreeGeoJSON

globe with lines

但是,我不想只是概述。我想填补这些国家的颜色。

我目前的项目可以在这里看到: http://bl.ocks.org/jhubley/321232d4ccefefcdc53218fd0adccac5

代码在这里: https://gist.github.com/jhubley/321232d4ccefefcdc53218fd0adccac5

我尝试创建一个新函数,将多边形和多边形渲染为网格而不是线条。该功能如下:

    function drawShape(x_values, y_values, z_values, options) {
        var shape_geom = new THREE.BoxGeometry();
        createVertexForEachPoint(shape_geom, x_values, y_values, z_values);

        var shape_material = new THREE.MeshBasicMaterial( {color: 0xffff00 } );
        var shape = new THREE.Mesh(shape_geom, shape_material);
        scene.add(shape);

        clearArrays();
    }

不幸的是,当我使用它时没有任何显示。控制台中没有任何错误可以帮助我理解原因。

任何人都可以解释我如何设置这些国家以便填补它们吗?任何建议或指示都将非常感激。

2 个答案:

答案 0 :(得分:1)

您有形成轮廓的线段并将它们绘制为线条。但填充的形状必须由三角形构成(更多关于webgl绘制模式there)。

因此,要渲染已填充的国家/地区,您需要对您的一组细分进行三角测量。有多种方法可以实现,并且可以使用准备好的代码(例如,this earcut implementation)。

但是,由于您要在地球上映射形状,下一个问题可能是生成的多边形的大小。如果您使用的三角测量产生大三角形,并且您将顶点变换为球形坐标,则大三角形将显着平坦。这里可以在片段着色器或其他三角形细分中使用displacement mapping(例如,基于三角形区域)。

最后但并非最不重要:三角测量计算成本很高,因此如果您不需要动态执行,请考虑离线几何准备。如果您需要对动态数据进行三角测量:请考虑对该任务使用webworker(如果项目很大,请使用超快速非JavaScript服务器)。

答案 1 :(得分:1)

正如@mlkn所说,你必须使用三角形填充网格。

我搞砸了一下:

function drawLine(x_values, y_values, z_values, options) {
  // container
  var obj = new THREE.Object3D();

  // lines
  var line_geom = new THREE.Geometry();
  createVertexForEachPoint(line_geom, x_values, y_values, z_values);
  var line_material = new THREE.LineBasicMaterial({
    color: 'yellow'
  });

  var line = new THREE.Line(line_geom, line_material);

  obj.add(line);

  // mesh
  var mesh_geom = new THREE.Geometry();
  createVertexForEachPoint(mesh_geom, x_values, y_values, z_values);
  var mesh_material = new THREE.MeshBasicMaterial({
    color: 'blue',
    side: THREE.DoubleSide
  });
  var mesh = new THREE.Mesh(mesh_geom, mesh_material);

  obj.add(mesh);

  scene.add(obj);

  clearArrays();
}

Object3D obj正在包裹线条和网格。

在这里创建面孔(三角形):

function createVertexForEachPoint(object_geometry, values_axis1, values_axis2, values_axis3) {
    for (var i = 0; i < values_axis1.length; i++) {
        object_geometry.vertices.push(new THREE.Vector3(values_axis1[i],
            values_axis2[i], values_axis3[i]));

        object_geometry.faces.push(new THREE.Face3(0, i + 1, i)); // <- add faces
    }
}

结果有点混乱,我不知道是因为数据还是顶点顺序/生成。

演示:

这三个GeoJSON编写得很差IMO,没有结构,作为一个例子,你只需要将var scene = ...的名称改为var myscene = ...并且整个lib停止工作,这是一个糟糕的设计。

此外还有大量的CPU使用率,可能是太多的绘制调用。