2010-04-16 2 views
1

У меня есть функция, которая принимает долготу и широту и преобразует ее в 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]; 

} 

Это выход: output

Это не работает правильно, и я даже не знаю, если я подхожу к проблеме в правильном пути вообще.

Должен ли кто-нибудь это делать раньше? Какой метод вы бы предложили?

+1

Вы открыты для альтернативного implmentations представления плотности?Либо по диаметру, цвету, либо по другому варианту? –

+0

Вы имеете в виду, например, объединяя точки с одинаковыми координатами в одну точку, а затем используя размер/цвет, чтобы показать плотность? Каждая точка представляет собой другой фрагмент данных, поэтому их нужно отдельно идентифицировать. IE. с одной точки есть много разных значений, которые уникальны. – betamax

+0

Что касается вашего комментария, мое решение предполагало, что все точки были отображены с тем же цветом. Я по-прежнему считаю, что легче подсчитать количество точек с одинаковой координатой, а затем расположить точки в соответствии с общим количеством. Точки могут, конечно, быть окрашены в соответствии с другими критериями, но расположены в базе шаблонов на счетчике. – Ernelli

ответ

1

Начните с группировки координат. Ваше длинное, 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 координаты центра, выход представляет собой массив точек для визуализации.

Последняя строка остальные точки, например 15 точек квадрата штукатурок:

OOOO 
OOOO 
OOOO 
OOO 
+0

Этот подход кажется действительным. Я не могу проверить это на данный момент, но я вернусь завтра с тем, что произошло. Благодаря! – betamax

1

Используя решение Ernelli в качестве примера, мне удалось получить заговоры работает правильно. Кажется, что он немного длинный, но он работает, и он не медленный.

решение Ernelli имеет ошибку в секунду для цикла:

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 и перевод)

+0

Благодарим вас за обнаружение ошибки, я обновил свой пример кода. – Ernelli