Mapy Google - kreator ścieżek - zarządzanie wieloma liniami

Tym razem zajmiemy się metodami zarządzania wieloma ścieżkami, które zostały utworzone w naszym edytorze. Opracujemy elementy odpowiedzialne za listowanie ścieżek, wyświetlanie współrzędnych aktywnej ścieżki oraz usuwanie wybranej linii.

Zaczniemy od zbudowania struktury, która pozwoli w miarę łatwo przechowywać obiekty linii. W tym celu zastosujemy listę dwukierunkową. Kod listy jest dostępny tutaj: http://code.google.com/p/google-maps-michal-examples/source/browse/trunk/DoubleLinkedList.js

Metody listy to:
  • push(element) - dodanie elementu na koniec listy
  • pop() - pobranie i usunięcie elementu z końca listy
  • getAt(i) - pobranie elementu z i-tej pozycji (liczymy od 0)
  • insertAt(i, element) - wstawienie elementu na i-tą pozycję
  • setAt(i, element) - napisanie danych na i-tej pozycji
  • toArray() - zwrócenie listy jako tablicy
Kolejkę tworzymy konstruktorem DoubleLinkedList(), czyli:
var polylines = new DoubleLinkedList();
Teraz możemy zabrać się za dodawanie linii do listy. W momencie, kiedy zaczynamy tworzyć linię jest wykonywane zdarzenie lineupdate dlatego, też w tym miejscu będziemy dodawać linię do listy. W momencie dodania jej do listy otrzymany indeks zapisujemy w obiekcie linii tak, aby był on później łatwo dostępny (bez konieczności szukania w liście). Ponieważ zdarzenie lineupdate nie przekazuje w parametrach uchwytu do aktualnej linii, dlatego w momencie podpinania zdarzenia tworzymy funkcję, która przekaże ten parametr.
GEvent.addListener(poly, "lineupdated", function(){updatePoly(poly);});
Funkcja updatePoly korzysta z uniwersalnej funkcji updatePolyData(i), która aktualizuje współrzędne dla linii, która ma i-ty indeks.
function updatePoly(poly) {
    if (poly.indexInDoubleLinkedList == undefined) {
        var i = polylines.push(poly);
        poly.indexInDoubleLinkedList = (i-1); // liczymy od zera
    }    
    updatePolyData(poly.indexInDoubleLinkedList);
}

W momencie zdarzenia zakończenia edycji linii nie musimy już wykonywać żadnych operacji.

Następnym elementem będzie nasza uniwersalna metoda updatePolyData. Będzie ona obsługiwać zarówno dostępny z poprzednich wpisów element textarea, ale także tabelkę ze spisem dostępnych ścieżek.
Obsługa textarea będzie opierała się na funkcji getCoordsLastPoly, ale zmienna poly, będzie przypisana jako:
var poly = polylines.getAt(i);
Tabelka jest zbudowana na elemencie table. W niej będziemy przechowywać informacje o numerze linii oraz jej długości. Będzie tam także umieszczony link do usuwania linii. Obsługa tabelki będzie więc sprowadzać się do odświeżania zawartości pola tbody wypełniając go zdefiniowanym HTML'em:
function updatePolyData(i) {
    // czyszczenie danych
 document.getElementById('tabelka').getElementsByTagName('tbody')[0].innerHTML = '';
 document.getElementById('textarea').innerHTML = '';
 
 if (polylines.length == 0) {
  return;
 }
 var poly = polylines.getAt(i); 
 
 /** obsługa tabelki **/
 
 var html = '';
 var polyIterator = polylines.startElement;
 for (var j=0; j<polylines.length; j++)
  html += 'Linia nr '+j+'';
  html += ''+Math.round(polylines.getAt(j).getLength()*100)/100+' m';
  html += 'usuń';
  polyIterator = polyIterator.nextElement;
 }
 document.getElementById('tabelka')
  .getElementsByTagName('tbody')[0].innerHTML = html;
 
 /** obsługa współrzędnych **/
 
 if (document.getElementById('plainText').checked) {
    for (var i=0; i<poly.getvertexcount(); i++)
     var vertex = poly.getVertex(i);
     document.getElementById('textarea').innerHTML += vertex.lat()+', '+vertex.lng()+"\n";
    }
  }else 
    poly.getKml(function(kml) {document.getElementById('textarea').innerHTML = kml});
 }
}

Pewna zmiana także jest wprowadzona w metodzie draw - mianowicie element poly jest lokalny:
function draw() {
    var poly = new GPolyline([], 'black');
    map.addOverlay(poly);
    poly.enableDrawing({});
    
    poly.enableEditing({onEvent: "mouseover"});
    poly.disableEditing({onEvent: "mouseout"});
    GEvent.addListener(poly, "lineupdated", function(){updatePoly(poly);});
      
    GEvent.addListener(poly, "click", function(latlng, index) {
        updatePolyData(poly.indexInDoubleLinkedList);
    });  
}

Usuwanie linii jest realizowane przez funkcję removeLine, gdzie parametrem jest indeks. Wykorzystując API Google Maps z obiektu GMap wykonujemy funkcję removeOverlay(GPolyline), która załatwia wszystko. Musimy jeszcze pamiętać o usunięciu elementu z listy oraz nadaniu pozostałym elementom nowych indeksów z listy.
function removeLine(i) {
 map.removeOverlay(polylines.getAt(i));
 polylines.removeAt(i);

 updatePolyData(0);
 var polyIterator = polylines.startElement;
 if (polylines.length>0)
 for (var j=0; j<polylines.length; j++)
  polyIterator.data.indexInDoubleLinkedList = j;
  polyIterator = polyIterator.nextElement;
 }
}

Ostateczny efekt jest następujący:

Nowa linia

numer liniidługośćusuń




Prześlij dalej:

Brak komentarzy:

Prześlij komentarz