绘制点,以便它们不重叠,如果它们具有相同的坐标
我有一个函数可以获取经度和纬度并将其转换为x和y进行绘图。转换到X和Y工作正常,这不是我遇到的问题。绘制点,以便它们不重叠,如果它们具有相同的坐标
我想确保两点不绘制在同一个地方。在一组结果中,大约有30个在另一个之上(因为它们具有相同的经度和纬度),这个数字可能会大得多。
目前,我试图通过移动点至点的左侧,右侧,顶部或底部,使一个正方形来实现这一目标。一旦绘制了由点组成的正方形,然后移动到下一行并在前一个正方形周围绘制另一个点的平方。
的代码是Javascript支持,但是它是非常通用的,所以我想这是稍微无关。
我的代码如下:
var prevLong, prevLat, rand = 1, line = 1, spread = 8, i = 0;
function plot_points(long, lat){
// CODE HERE TO CONVERT long and lat into x and y
// System to not overlap the points
if((prevLat == lat) && (prevLong == long)) {
if(rand==1) {
x += spread*line;
} else if(rand==2) {
x -= spread*line;
} else if(rand==3) {
y += spread*line;
} else if(rand==4) {
y -= spread*line;
} else if(rand==5) {
x += spread*line;
y += spread*line;
} else if(rand==6) {
x -= spread*line;
y -= spread*line;
} else if(rand==7) {
x += spread*line;
y -= spread*line;
} else if(rand==8) {
x -= spread*line;
y += spread*line;
// x = double
} else if(rand==9) {
x += spread*line;
y += spread;
} else if(rand==10) {
x += spread;
y += spread*line;
} else if(rand==11) {
x -= spread*line;
y -= spread;
} else if(rand==12) {
x -= spread;
y -= spread*line;
} else if(rand==13) {
x += spread*line;
y -= spread;
} else if(rand==14) {
x += spread;
y -= spread*line;
} else if(rand==15) {
x += spread*line;
y -= spread;
} else if(rand==16) {
x += spread;
y -= spread*line;
} else if(rand==17) {
x -= spread*line;
y += spread;
} else if(rand==18) {
x -= spread;
y += spread*line;
} else if(rand==19) {
x -= spread*line;
y += spread;
} else if(rand==20) {
x -= spread;
y += spread*line;
}
if(rand == 20) {rand = 1; line++; } else { rand++; }
i++
} else {
line = 1;
i = 0;
}
prevLat = latitude;
prevLong = longitude;
return [x,y];
}
这是输出:
它不能正常工作,我甚至不知道如果我以正确的方式接近问题在所有。
有没有人需要这样做?你会建议什么方法?
通过对坐标进行分组开始。直到最后一步,您的long,lat - > x,y转换可能不是必需的。一种方法是创建一个散列图,您可以在其中存储每个长/经位置和每个位置的计数。
然后你转换每个长,纬度位置为X,Y坐标和使用次数来决定如何呈现围绕x,y位置但按点数大小为中心的点。
一个工作算法,以呈现一个正方形是:
var count = 30; // example
result = [];
var width = count/Math.sqrt(count);
width = Math.floor(width);
height = Math.floor(count/width);
var remain = count % width;
var i,j;
for(i = 0; i < width; i++)
for(j = 0; j < height; j++)
result.push([x-Math.floor(width/2)+i, y-Math.floor(height/2)+j];
for(i = 0; i < remain; i++)
result.push([x-Math.floor(width/2)+i, y-Math.floor(height/2)+j];
输入是点,X,Y的中心坐标计数,输出是点呈现的阵列。
最后一行是剩下的点,e.g 15点多呈现:
OOOO
OOOO
OOOO
OOO
这种方法似乎有效。我目前无法测试,但明天我会明白发生了什么。谢谢! – betamax 2010-04-16 18:33:49
使用Ernelli的解决方案作为一个例子,我设法让绘图工作正常。这似乎有点冗长,但有效,并且不慢。
Ernelli的解决方案有一个错误在第二个for循环:
for(j = 0; i < height; i++)
应该是:
for(j = 0; j < height; j++)
无论如何,这是我的代码,我使用和工作。 pointArray是所有要被绘制的元件的阵列:
var countArray = new Array();
// Go through every point and group same co-ordinates together
for (var i = pointArray.length-1; i > -1; i--) {
if(pointArray[i] != undefined)
{
var found = 0;
// Check if this point is already in array
for (var j = countArray.length-1; j > -1; j--)
{
if(countArray[j] != undefined)
{
if((pointArray[i].getBBox().x == countArray[j]["x"]) && (pointArray[i].getBBox().y == countArray[j]["y"]))
{
countArray[j]["points"].push(pointArray[i]);
found = 1;
}
}
}
// The point is not in the array, so add it
if(found != 1)
{
var index = countArray.length;
countArray[index] = new Array();
countArray[index]["x"] = pointArray[i].getBBox().x;
countArray[index]["y"] = pointArray[i].getBBox().y;
countArray[index]["points"] = new Array();
countArray[index]["points"].push(pointArray[i]);
}
}
}
// For each co-ordinate
for (var j = countArray.length-1; j > -1; j--)
{
if(countArray[j] != undefined)
{
// If there is more than one point
if(countArray[j]["points"].length > 1) {
// Calculate the square points
var count = countArray[j]["points"].length;
var x = countArray[j]["x"];
var y = countArray[j]["x"];
result = [];
var width = count/Math.sqrt(count);
width = Math.floor(width);
height = Math.floor(count/width);
var remain = count % width;
var i2,j2, xx, yy;
var space = 8;
for(i2 = 0; i2 < width*space; i2+=space)
{
for(j2 = 0; j2 < height*space; j2+=space)
{
result.push([(Math.floor(width/2)+i2), (Math.floor(height/2)+j2)]);
}
}
for(i2 = 0; i2 < remain*space; i2+=space)
{
result.push([(Math.floor(width/2)+i2), (Math.floor(height/2)+j2)]);
}
// Go through each point and then translate it to it's new position
for (var jj = countArray[j]["points"].length-1; jj > -1; jj--)
{
if(countArray[j]["points"][jj] != undefined)
{
if(result[jj] != undefined)
{
countArray[j]["points"][jj].translate(result[jj][0]-((width*8)/2), result[jj][1]-((height*8)/2))
}
}
}
} // End if count more than 1
} // End if undefined
}
注意,此使用许多raphael.js功能(如getBBox和平移)
感谢您发现错误,我更新了示例代码。 – Ernelli 2010-04-20 07:14:15
你是否打开到密度表示的备选implmentations?要么通过直径,颜色或其他变体? – 2010-04-16 18:04:37
您的意思是,例如,将具有相同坐标的点合并为一个点,然后使用大小/颜色来显示密度?每个点代表一个不同的数据,因此他们需要分开识别。 IE浏览器。从一个角度来看,有许多不同的值是独特的。 – betamax 2010-04-16 18:11:11
关于您的评论,我的解决方案假定所有的点都以相同的颜色呈现。我仍然认为用相同的坐标来计算点的数量比较容易,然后根据总数来排列点。这些点当然可以根据其他标准进行着色,但是可以根据计数进行排列。 – Ernelli 2010-04-16 18:31:34