Tracciare i punti in modo che non si sovrappongono se hanno le stesse coordinate
-
27-09-2019 - |
Domanda
Ho una funzione che prende longitudine e latitudine e lo converte in xey da tracciare. La conversione in X e Y sta funzionando benissimo e questo non è ciò che ho il problema con.
Voglio assicurare che due punti non vengono tracciate nello stesso luogo. In una serie di risultati ci sono circa 30 uno sopra l'altro (perché hanno la stessa latitudine e longitudine), questo numero potrebbe essere molto più grande.
Al momento sto cercando di raggiungere questo obiettivo spostando i punti a sinistra, destra, in alto o in basso del punto per fare un quadrato. Una volta che un quadrato costituito da punti è stato elaborato, per poi passare alla riga successiva su e disegnare un altro quadrato di punti intorno al quadrato precedente.
Il codice è Javascript, ma è molto generico, quindi credo che sia un po 'irrilevante.
Il mio codice è il seguente:
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];
}
Questa è l'uscita:
E non funziona correttamente e non so nemmeno se mi sto avvicinando il problema in modo corretto a tutti.
Qualcuno ha avuto a che fare prima? Quale metodo suggerisce?
Soluzione
Inizia raggruppando le coordinate. Il vostro tempo, lat -> x, y la conversione potrebbe non essere necessario fino a quando l'ultimo passo. Un metodo è quello di creare una mappa di hash in cui si memorizzano ogni tempo / posizione Lat e un conteggio per ogni posizione.
Poi si converte ogni tempo, la posizione lat in una x, y coordinate e utilizzare il conteggio per decidere come rendere i punti centrati intorno x, y posizione, ma con una dimensione in base al numero di punti.
Un algoritmo che lavora per rendere una piazza è:
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];
ingresso è conteggio di puntini, x, y coordinate centro, l'uscita è una matrice di punti a rendering.
L'ultima riga è restanti punti, per esempio un quadrato 15 dot esegue il rendering:
OOOO
OOOO
OOOO
OOO
Altri suggerimenti
Utilizzando la soluzione di Ernelli come esempio, sono riuscito a ottenere il tracciato di funzionare correttamente. Sembra un po 'lungo senza fiato, ma funziona e non è lento.
La soluzione di Ernelli ha un errore nel secondo ciclo:
for(j = 0; i < height; i++)
Dovrebbe essere:
for(j = 0; j < height; j++)
In ogni caso, questo è il mio codice che sto usando e che sta lavorando. pointArray è un array di tutti gli elementi che devono essere tracciata:
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
}
Si noti che questo utilizza molti Raphaël.js funzioni (come getBBox e tradurre)