Kur*_*urt 5 javascript d3.js d3.geo
我正在尝试获取画布元素的内容(实际上只是加载到画布上的图像)并使用 d3 将它们扭曲为不同的地图投影。所以我找到了一个这样做的例子(this other SO question)。
问题是它不适用于每个投影。编码:
var height = 375,
width = 750;
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var projection = d3.geo.lagrange()
.translate([width/2, height/2])
.scale(100); //SET SCALE HERE
var path = d3.geo.path().projection(projection);
var image = new Image();
image.crossOrigin = 'anonymous';
image.src = 'http://i.imgur.com/zZkxbz7.png';
image.onload = function() {
var dx = width,
dy = height;
context.drawImage(image, 0, 0, dx, dy);
var sourceData = context.getImageData(0, 0, dx, dy).data,
target = context.createImageData(dx, dy),
targetData = target.data;
for (var y = 0, i = -1; y < height; ++y) {
for (var x = 0; x < width; ++x) {
var p = projection.invert([x, y]), //ERROR HERE
? = p[0],
? = p[1];
if (? > 180 || ? < -180 || ? > 90 || ? < -90) {
i += 4;
continue;
}
var q = ((90 - ?) / 180 * dy | 0) * dx + ((180 + ?) / 360 * dx | 0) << 2;
targetData[++i] = sourceData[q];
targetData[++i] = sourceData[++q];
targetData[++i] = sourceData[++q];
targetData[++i] = 255;
}
}
context.clearRect(0, 0, width, height);
context.putImageData(target, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,如果我将投影的比例设置得太低(比如 80),那么变量 p(在 for 循环中)最终是null
. 我不确定为什么会发生这种情况,我需要设置比例以使投影适合画布区域。
一个有效的 jsfiddle 示例:http : //jsfiddle.net/vjnfyd8t/
(这是个有趣的问题)
我不太清楚这里发生了什么,但是FWIW,这是拉格朗日方法的实现invert()
。显然,在某些情况下,它会返回 null,大概是每当 x 或 y 超出某些范围时(x,y在这里已预先转换)。所以我想你应该忽略空值(例如通过将输出像素设置为透明),并且你仍然可以在最后获得正确的缩放地图。
这就是我通过忽略null
s 得到的结果(但用红色突出显示它们,以说明它发生的位置)
if (!p) {
targetData[++i] = 255;
targetData[++i] = 0;
targetData[++i] = 0;
targetData[++i] = 255;
continue;
}
Run Code Online (Sandbox Code Playgroud)
如果比例设置为 94,则红色带完全消失,并且看起来是最合适的(至少在该比例下)。这就是你想要的吗?
归档时间: |
|
查看次数: |
1283 次 |
最近记录: |