Zdarzenia generowane przez znacznik (marker).
☞ Rejestracja zdarzenia 'mouseover' i zmiana kursora myszy na 'rączkę'
Jednym ze zdarzeń jakie generuje znacznik, a które powinniśmy obsłużyć, jest zdarzenie 'mouseover'. Zachodzi ono, gdy kursor myszy znajduje się nad markerem. Po najechaniu kursorem myszy nad prostokątny obszar znacznika, powinniśmy zmienić kursor myszy na 'pointer'
... // funkcja tworząca pojedyncze punkty graficzne w warstwie wektorowej 'layerMarkers' // o atrybutach określonych w argumentach funkcji function createMarkers(id, lon, lat, markerFile, markerWidth, markerHeight, offsetX, offsetY, popupHtml) { ... // // utwórz znacznik (marker) var marker = feature.createMarker(); ... // rejestrowanie zdarzenia 'mouseover' nad znacznikiem marker.events.register('mouseover', marker, function(evt){ feature.layer.div.style.cursor = "pointer"; OpenLayers.Event.stop(evt); });
Rejestracja zdarzenia 'click' i utworzenie okna popup
Innym zdarzeniem jakie generuje znacznik, a które powinniśmy obsłużyć, jest zdarzenie 'click'. Zachodzi ono, gdy kursor myszy znajduje się nad markerem i równocześnie zostaje wciśnięty i puszczony prawy przycisk myszy.
... // funkcja tworząca pojedyncze punkty graficzne w warstwie wektorowej 'layerMarkers' // o atrybutach określonych w argumentach funkcji function createMarkers(id, lon, lat, markerFile, markerWidth, markerHeight, offsetX, offsetY, popupHtml) { ... // // utwórz znacznik (marker) var marker = feature.createMarker(); ... // rejestrowanie zdarzenie kliknięcia znacznika marker.events.register("click", marker, function(evt){ popup = new OpenLayers.Popup.FramedCloud( id = 'myFramedCloud', lonlat = marker.lonlat, contentSize = new OpenLayers.Size(0, 0), contentHTML = popupHtml, anchor = null, //marker.icon, closeBox = true); // dla exclusive = true, zamykane są inne otwarte okna popup map.addPopup(popup, exclusive = true); OpenLayers.Event.stop(evt); });
1. Znaczniki i okienka popup (dymki)
Pliki znaczników graficznych pobrano ze strony
www.icons-land.com
Jak uatrakcyjnić okienka popup (dymki)
Okienka popup wyglądają dość biednie. Ale można zawartość okienka nieco upiększyć. Można dla każdego okienka przekazać w argumencie popupHtml funkcji createMarkers(...) przekazać HTML, tak by umieścić zawartość okienka popup w znaczniku <div id="frameCloud">, w którym umieścimy inne znaczniki. Wszystkim elementom nadamy styl, tak by zawartość okienka popup odpowiadała naszym wymogom (lub zleceniodawcy ☺).
popupHtml='' popupHtml+='<div style="width:150px; border:3px double #080; padding:5px;">' popupHtml+='<h1 style="font-size: .8em; color:#008; text-align:center; font-weight:bold;' popupHtml+='border-bottom:1px solid #080; margin:0;">Miejsce 02.</h1>' popupHtml+='<span style="display:block; font-size:.8em; color:#800; margin: 5px 0; line-height:.9em;">' popupHtml+='To jest jeszcze ciekawsze miejsce, które powinieneś zobaczyć.</span>' popupHtml+='<div style="text-align:center; font-size:.7em; color:#008;"> ' popupHtml+='<img style="width:140px; border:3px double #ccc;" src="foto/02_thm.jpg" alt="Foto 2"/><br>' popupHtml+='fot.2 Jezioro Dąbrowskie' popupHtml+='</div></div>'
2. Nowy styl okienka popup (dymku)
Styl dla wszystkich elementów widocznego powyżej okienka popup zawiera prawie 700 znaków. Jest to nieco za dużo i ponadto nie ma potrzeby przekazywania takiego samego stylu dla każdej instancji okienka popup. Aby sobie ułatwić kontrolę nad stylem okna popup utworzymy wewnętrzny arkusz stylów, który umieścimy w części nagłówkowej (pomiędzy znacznikami <head> ... </head>) wyświetlanej strony.
<head> ... <style type="text/css"> #frameCloud {width:150px; border:3px double #080; padding:5px;} #frameCloud h1{ font-size:.8em; color:#008; text-align:center; font-weight:bold; border-bottom:1px solid #080; margin:0; } #frameCloud span#dscr{display:block; font-size:.8em; color:#800; margin: 5px 0; line-height:.9em;} #frameCloud div#foto{font-size:.7em; color:#008; text-align:center;} #frameCloud div#foto img{width:140px; border:3px double #ccc;} </style> ... </head>
Po takich zmianach, musimy dostosować funkcję createMarkers(...) tak, by można było w argumentach przekazać tytuł (popupTitle), opis wskazywanego miejsca (popupDescription), ścieżkę do pliku graficznego (popupImage) oraz podpis pod fotografią (popupImageCaption).
// deklaracja warstwy wektorowej zawierającej znaczniki (markery) var layerMarkers; // deklaracja tablicy zawierającej wszystkie markery (ToDo) var arrMarkers = []; // utwórz warstwę na przyjęcie znaczników (markerów) function createMarkersLayer(id, layerName, displayInLayerSwitcher, setVisibility){ layerMarkers = new OpenLayers.Layer.Markers(layerName); // przypisz identyfikator warstwy layerMarkers.id = id; // pokaż warstwę w oknie przełącznika warstw layerMarkers.displayInLayerSwitcher = displayInLayerSwitcher; // pokaż warstwę na mapie layerMarkers.setVisibility(setVisibility); } // funkcja tworząca pojedyncze znaczniki w warstwie wektorowej 'layerMarkers' // o atrybutach określonych w argumentach funkcji function createMarkers(id, lon, lat, markerFile, markerWidth, markerHeight, offsetX, offsetY, popupTitle, popupDescription, popupImage, popupImageCaption) { // konwertuj współrzędne geograficzne z układu odniesienia EPSG:4326 na EPSG:900913, var lonLat = new OpenLayers.LonLat(lon, lat).transform(epsg4326, epsg900913); // utwórz reprezentuję pary szerokość / wysokość var size = new OpenLayers.Size(markerWidth, markerHeight); // oblicz przesunięcie markera var offset = new OpenLayers.Pixel(offsetX, offsetY); // utwórz grafikę w oparciu o adres URL, o rozmiarze (size) // i przesunięciu punktu środkowego (offset)) var icon = new OpenLayers.Icon(markerFile,size, offset); // utwórz klasę feature na podstawie danych geograficznych i graficznych var feature = new OpenLayers.Feature(layerMarkers, lonLat, {'icon': icon}); // utwórz klasę 'popupClass', która będzie używana do tworzenia instancji nowego okna popup. feature.popupClass = OpenLayers.Class(OpenLayers.Popup.Anchored, {'autoSize': true}); // utwórz znacznik (marker) var marker = feature.createMarker(); // przypisz identyfikator znacznikowi marker.id = id; //identyfikator płaszczyzny (ToDo) marker.PlaneID = id; // rejestrowanie zdarzenie kliknięcia znacznika marker.events.register("click", marker, function(evt){ var popupHtml='' popupHtml+='<div id="frameCloud">' popupHtml+='<h1>'+popupTitle+'</h1>' popupHtml+='<span id="dscr">'+popupDescription+'</span>' popupHtml+='<div id="foto">' popupHtml+='<img src="'+popupImage+'" alt="foto '+popupTitle+'"/><br>' popupHtml+='<span>'+popupImageCaption+'</span>' popupHtml+='</div></div>' /* Definicja okna popup, które będzie utworzone po kliknięciu znacznika. • id - identyfikator okna popup • lonlat - położenie znacznika • contentHTML - pełny tekst HTML określający styl i treść w oknie popup (dymku) • contentSize - nie wiem co to jest • anchor - obiekt, do którego zostanie zakotwiczone okno popup. • w MS Access dla anchor = null i plików graficznych "Centered" dymek otwiera się dokładnie w punkcie lonlat znacznika (po uwzględnieniu offsetX, offsetY), dla anchor = marker.icon okienko popup otwiera się na krawędzi znacznika, • w FireFox dla anchor = null okno popup otwiera się za pierwszym razem w zbyt małym rozmiarze (z paskami przewijania), dla anchor = marker.icon okno popup otwiera się prawidłowo. • closeBox - dla wartości true tworzony jest przycisk 'X' zamykający okno popup */ //var anchor = {'size': new OpenLayers.Size(0,0), 'offset': new OpenLayers.Pixel(-24, -24)}; popup = new OpenLayers.Popup.FramedCloud( id = 'myFramedCloud', lonlat = marker.lonlat, contentSize = new OpenLayers.Size(0, 0), contentHTML = popupHtml, anchor = null, //marker.icon, closeBox = true); // dla exclusive = true, zamykane są inne otwarte okna popup map.addPopup(popup, exclusive = true); OpenLayers.Event.stop(evt); }); // rejestrowanie zdarzenia 'mouseover' nad znacznikiem // zmiana kursora myszy na 'rączkę' marker.events.register('mouseover', marker, function(evt){ feature.layer.div.style.cursor = "pointer"; OpenLayers.Event.stop(evt); }); // dodaj znacznik do warstwy layerMarkers.addMarker(marker); // dodaj znacznik do tablicy (ToDo) arrMarkers.push(marker); // dodaj warstwę znaczników do instancji mapy map.addLayer(layerMarkers); }
3. Trzy okna popup na mapie
function fDrawMarkers(){ // utwórz warstwę na przyjęcie znaczników (markerów) createMarkersLayer('dymki','Popup (dymki)', true, true) // współrzędne punktu var lon; var lat; // wielkość pliku graficznego i zarazem podkatalog plików graficznych var size=48; // ścieżka do plików graficznych "Centered") var path='markers/IconsLand/PNG/Centered/'+size.toString()+'x'+size.toString()+'/'; lat="51.30728";lon="22.50085" createMarkers('miejsce01',lon,lat, path+'MapMarker_Ball_Right_Pink.png', size, size, -size/2, -size, 'Miejsce 01.', 'To jest bardzo ciekawe miejsce, które należy odwiedzić.', 'foto/01_thm.jpg', 'fot.1 Pola i łąki') lat="51.3072";lon="22.49070" createMarkers('miejsce02',lon,lat, path+'MapMarker_Board_Pink.png', size, size, -size/2, -size, 'Miejsce 02.', 'To jest jeszcze ciekawsze miejsce, które powinieneś zobaczyć.', 'foto/02_thm.jpg', 'fot.2 Kwitnące drzewo') // ścieżka do plików graficznych "NotCentered") path='markers/IconsLand/PNG/NotCentered/'+size.toString()+'x'+size.toString()+'/'; lat="51.289822971448302";lon="22.501583006232977" createMarkers('miejsce03',lon,lat, path+'MapMarker_PushPin1_Right_Pink.png', size, size, -size/4, -size, 'Miejsce 03.', 'To jest najciekawsze miejsce, które bezwzględnie należy odwiedzić.', 'foto/03_thm.jpg', 'fot.3 Stara chata') // wycentruj mapę w/m współrzędnych środka, powiększ do skali zoomLevel fInitCenterMap(22.501000, 51.297918, 14); }
Pewnym ograniczeniem w stosowaniu znaczników jest sztywno ustalona w wewnętrznym arkuszu stylów szerokość fotografii na '140px'. O ile w oknach popup wyświetlane będą tylko fotografie poziome, okienko wygląda dobrze. Dla fotografii o orientacji pionowej, fotografia jest moim zdaniem zbyt duża (za wysoka). Optymalną wysokością fotografii jest ok. 100 pikseli. Ale by uzyskać taki efekt, powinniśmy w funkcji createMarkers(...) przekazać w dodatkowym argumencie informację o orientacji fotografii i nadać jej odpowiedni styl.
Na razie zostawiam tak, jak jest. Być może uzupełnię kod w najbliższym czasie. (ToDo...)