Skip to content Skip to sidebar Skip to footer

How Can I Draw GeoJSON In Three.js As A Mesh And Not A Line, And Fill With Color?

I'm making a globe in three.js and will be adding some data layers. All of the layers will be created from geoJSON. I have set it up so that the globe (the first data file, which i

Solution 1:

As @mlkn said you have to use triangles to fill a mesh.

I messed around a little:

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();
}

The Object3D obj is wrapping both lines and meshes.

Faces (triangles) are created here:

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
    }
}

The result is bit of a mess, I don't know if because of the data or the vertex order/generation.

Demo:

That threeGeoJSON is poorly written IMO, without structure, as an example you just need to change the name of var scene = ... to var myscene = ... and the whole lib stop working, that's poor design.

Also there's a high amount of CPU usage, probably too many draw calls.


Solution 2:

You have segments which form an outline and draw them as lines. But filled shape is have to be constructed from triangles (more on webgl draw modes there).

So to render filled country you need to make a triangulation of your set of segments. There are multiple ways to do that, and ready to use code is available (for example, this earcut implementation).

However, since you want to map shape on globe, next problem could be the size of produced polygons. If triangulation you use produces big triangles, and you transform vertices to spherical coords, big triangles will be noticable flat. Here could be used displacement mapping in fragment shader or further triangles subdivision (based on triangles area, for example).

The last but not the least: triangulation is computationally expensive, so if you don't need to do it dynamically, consider offline geometry preparation. If you need to triangulate dynamic data: consider using webworker for that task (or super-fast non javascript server if project is big).


Post a Comment for "How Can I Draw GeoJSON In Three.js As A Mesh And Not A Line, And Fill With Color?"