0

I am trying to draw realistic (non-straight) borders of randomly generated countries using d3.geoVoronoi and topojson.merge. This is what I am doing:

  1. I create 3 Voronoi diagrams, say A, B and C, respectively with 100, 1000, and 10000 cells.
  2. I merge the voronoi cells of B (1000 cells) if their centroid is contained in the same cell of A (100 cells). In this way I obtain B', with 100 cells having irregular borders.
  3. I repeat point 2, this time merging the cells of C (10000) if their centroid belongs to B'. I thus obtain B'', with 100 cells with even more realistic borders.

In principle the procedure could be repeated to obtain even more detailed borders, but I am already running into problems. When I draw B'' (black lines in the figures), it looks weird. Why? Does it have to do with the winding order of B'? How can I fix this?

Figures: Figure 1, Figure 2, Figure 3

const v_land = d3.geoVoronoi(land_Points);
    let countries_polygons_land = v_land.polygons(land_Points);

    const countries_topology2 = {
        type: "Topology",
        polygons: countries_polygons_land
    };
    const countries_topoJSON_land = topojson.topology(countries_topology2);
    const countries_geojson_land = topojson.feature(countries_topoJSON_land, countries_topoJSON_land.objects.polygons); 

    // MERGE
    let mergedGeoJSON = countries_geojson_land;
    let featureCluster = create2DArray(mergedGeoJSON.features.length);
    let newFeature;

    for (let k=1; k<points.length; k++) {

        // Merge smaller states within greater boundaries
        for (let i=0; i < mergedGeoJSON.features.length; i++) {
            for (let j=0; j < countries_geojson[k].features.length; j++) {
                if(d3.geoContains(mergedGeoJSON.features[i], d3.geoCentroid(countries_geojson[k].features[j]))) {
                    featureCluster[i].push(countries_topoJSON[k].objects.polygons.geometries[j]);
                }
            }   
        }  
        // Create geoJSON
        mergedGeoJSON = {
            type: "FeatureCollection",
            features: []
        }
        for (let i=0; i < featureCluster.length; i++) {
            newFeature = {
                type: "Feature",
                geometry: topojson.merge(countries_topoJSON[k], featureCluster[i])
            }
            mergedGeoJSON.features.push(newFeature);
        }
        // Draw Polygons (realistic)
        ctx.beginPath(), 
        path(mergedGeoJSON), 
        ctx.strokeStyle = `rgba(0, 0, 0, 1)`, 
        ctx.lineWidth = 0.5*k, 
        ctx.lineJoin = 'round', 
        ctx.stroke();
    }
Fede
  • 91
  • 6

0 Answers0