gpt4 book ai didi

javascript - D3 主线插值看起来不对

转载 作者:行者123 更新时间:2023-11-30 12:48:55 28 4
gpt4 key购买 nike

我正在尝试使用 d3.svg.line().interpolate() 选项给一个多边形 - 用 d3 绘制 - 平滑边缘,但我得到的结果看起来很奇怪。

我从诺基亚 HERE api 接收多边形数据作为世界坐标数据,格式为 [lat1, long1, alt1, lat2, long2, alt2 ...] 所以在 routingCallback 函数中 - 这在响应出现时调用 - 我首先对其进行优化,使其看起来像这样 [[lat1, long1], [lat2, long2] ...]。在 d3.svg.line() 然后我使用这个坐标数组来计算像素位置。我正在使用 Leaflet在 map 上绘制多边形,所以我使用 map.latLngToLayerPoint()功能来做到这一点。多边形的实际绘制发生在 reset() 中,它在数据可用后和每次 map 缩放时立即从 routingCallback 调用

var map = new L.Map("map", {"center": [52.515, 13.38], zoom: 12})
.addLayer(new L.TileLayer('http://{s}.tile.cloudmade.com/---account key---/120322/256/{z}/{x}/{y}.png'));

map.on("viewreset", reset);


var svg = d3.select(map.getPanes().overlayPane).append("svg"),
g = svg.append("g").attr("class", "leaflet-zoom-hide group-element"),

bounds = [[],[]],
polygon,
refinedData,

line = d3.svg.line()
.x(function(d) {
var location = L.latLng(d[0], d[1]),
point = map.latLngToLayerPoint(location);
return point.x;
})
.y(function(d) {
var location = L.latLng(d[0], d[1]),
point = map.latLngToLayerPoint(location);
return point.y;
})
.interpolate("cardinal"),

routingCallback = function(observedRouter, key, value) {
if(value == "finished") {
var rawData = observedRouter.calculateIsolineResponse.isolines[0].asArray(),
refinedData = [];

for(var i = 2; i < rawData.length; i += 3) {
var lon = rawData[i-1],
lat = rawData[i-2];

refinedData.push([lat, lon]);
}

if(polygon)
polygon.remove();

polygon = g
.data([refinedData])
.append("path")
.style("stroke", "#000")
.style("fill", "none")
.attr("class", "isoline");

reset();
}
if(value == "failed") {
console.log(observedRouter.getErrorCause());
}
};


getIsolineData = function(isoline) {

return data;
};

function reset() {
var xExtent = d3.extent(refinedData, function(d) {
var location = L.latLng(d[0], d[1]);
var point = map.latLngToLayerPoint(location);
return point.x;
});

var yExtent = d3.extent(refinedData, function(d) {
var location = L.latLng(d[0], d[1]);
var point = map.latLngToLayerPoint(location);
return point.y;
});

bounds[0][0] = xExtent[0];
bounds[0][1] = yExtent[0];
bounds[1][0] = xExtent[1];
bounds[1][1] = yExtent[1];

var topLeft = bounds[0],
bottomRight = bounds[1];

svg .attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");

g .attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");

polygon.attr("d", line);
}

我希望这会产生平滑的边缘,但我在每个 Angular 上都得到了一个小环。红色叠加层是没有插值的相同多边形。只有拐 Angular 处有点。中间不加分。

strange looking corners when using d3 cardinal interpolation. red overlay is the same polygon without interpolation

与点的顺序(顺时针/逆时针)有关系吗?我尝试重新排列这些点,但似乎什么也没发生。

最佳答案

我可以重新创建您得到的模式的唯一方法是,如果我将每个顶点添加到路径中两次。这在线性插值中不会很明显,但会在程序尝试平滑连接点时导致循环。

http://fiddle.jshell.net/weuLs/

编辑:

仔细查看您的代码,问题似乎出在您的 calculateIsolineResponse 函数中;我在 Leaflet API 中没有看到该名称,所以我认为它是自定义代码。您需要对其进行调试以找出重复点的原因。

如果您不能更改该代码,简单的解决方案是通过过滤器运行您的点数组以删除重复的点:

refinedData = refinedData.filter(function(d,i,a){
return ( (!i) || (d[0] != a[i-1][0]) || (d[1] != a[i-1][1]) );
});

如果它是数组中的第一个点,或者如果 lat 或 lon 值与前一个点不同,则该过滤器将返回 true。重复的点将返回 false 并从数组中过滤掉。

关于javascript - D3 主线插值看起来不对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21651235/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com