javascript - D3 : hide voronoi strokes that fall 'in the sea'

标签 javascript d3.js svg geojson

隐藏所有落入海中的 voronoi 笔划的最“昂贵”的方法是什么?

在陆地上运行的笔划(和多边形填充)应该是可见的,而在海上的笔划应该隐藏起来。我想我的目标从下图应该很清楚了:

enter image description here

我可以想到两个选项:

  1. 以某种方式将 voronoi 多边形“重新剪辑”到基础国家/地区 ('土地')多边形。这听起来 super CPU 密集型。这不是一个 不错的选择,所以我们不去那里。
  2. 在 voronoi 曲面分割之上叠加一个“海”多边形。那 在视觉上会非常有效,而且正是我所需要的。我将如何根据国家 basemap 计算新的海洋多边形? (例如这个 jsfiddle with a geoJSON D3 map ) 我有多张多边形复杂程度各不相同的 map ,因此我需要一种万无一失的方法来构建该 map 。

有什么想法吗?

最佳答案

一个简单的选项,不需要:

  • 海洋多边形
  • 重绘陆地多边形/合并陆地多边形
  • 剪辑路径

是使用 svg 模式。这听起来可能有点奇怪,而且我对性能影响并不乐观,但是您的 voronoi 图的模式可用于填充您的国家/地区/特征(保留边界并允许一次且仅绘制一次特征).

这要求多边形填充不依赖于地理特征,而是依赖于 voronoi - 您的图像对每个多边形使用相同的填充,但您的问题文本可能暗示情况并非如此

要使用这样的图案,请创建一个与您的 map 宽度和高度相同的图案。在模式中,放置 voronoi 图路径。最后,将每个特征的填充设置为图案:

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var projection = d3.geoMercator()
  .scale((width - 3) / (2 * Math.PI))
  .translate([width / 2, height / 2]);

var path = d3.geoPath()
  .projection(projection);

var graticule = d3.geoGraticule();

d3.json("https://unpkg.com/world-atlas@1/world/50m.json", function(error, world) {
  if (error) throw error;
  
  // random points:
  var circles = d3.range(20).map(function() {
    return {
      x: Math.round(Math.random() * width),
      y: Math.round(Math.random() * height)
    };
  });
	
  // voronoi:
  var voronoi = d3.voronoi()
    .x(function(d) { return d.x; })
    .y(function(d) { return d.y; })
    .extent([[-1, -1], [width + 1, height + 1]]);	
      
      
  // pattern:
  var pattern = svg.append("defs")
    .append("pattern")
    .attr("id","voronoi")
    .attr("patternUnits","userSpaceOnUse")
    .attr("width", width)
    .attr("height",height)
    .attr("x",0)
    .attr("y",0)
	  	
  pattern.selectAll("path")
    .data(voronoi.polygons(circles))
    .enter()
    .append("path")
    .attr("d", renderCell)
    .attr("fill",function(d,i) { return d3.schemeCategory20[i]; })
		
  // append paths as normal:
  var features = svg.selectAll(null)
    .data(topojson.feature(world,world.objects.countries).features)
    .enter()
    .append("path")
    .attr("class", "boundary")
    .attr("d", path)
    .attr("fill","url(#voronoi)");  // fill with pattern
	
  function renderCell(d) {
    return d == null ? null : "M" + d.join("L") + "Z";
  }	
	
	 
});
.boundary {
  stroke: black;
  stroke-width: 1px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<svg width="600" height="400"></svg>

关于javascript - D3 : hide voronoi strokes that fall 'in the sea' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48922105/

相关文章:

javascript - 如何在php的echo语句中使用三元运算符

javascript - HighChart中导出的多个图表与屏幕上显示的不一样

javascript - 图片上方的半透明div

javascript - 无法引用从标题中包含空格的 csv 文件导入的 d3.js 数据

angularjs - 在应用程序模块中注入(inject)的material.svgAssetsCache - angular js

python - 使用 selenium python 单击 svg

javascript - 从 Silverlight 迁移到 Html5/JavaScript

javascript - 在 while 循环 D3 中更新参数

javascript - D3.js 力定向图 - 圆圈中的 png - 使图像呈圆形

.net - 为什么在 dotnetnuke 中启用复合文件时 SVG 背景图像会中断?