Zdarzenia generowane przez punkt.
☞ Zmiana kursora myszy nad punktem na 'rączkę'
Dla punktów (w przeciwieństwie do znaczników) nie musimy obsługiwać (rejestrować) zdarzenia 'mouseover', zachodzącego, gdy kursor myszy znajduje się nad prostokątnym obszarem punktu. Aby zmienić wygląd kursora myszy nad obszarem punktu na 'rączkę' należy skorzystać z właściwości 'cursor' stylu tworzonego punktu, której to właściwości należy przypisać wartość 'pointer'.
... myGraphicPoint = new OpenLayers.Feature.Vector( geometry, {attributes}, {... style ..., 'cursor':'pointer' // ustaw kursor myszy na 'rączkę' } ...
Formant SelectFeature.
Właściwość 'onSelect' oraz 'onUnselect'. Utworzenie okna popup
Aby umożliwić interakcję warstwy wektorowej vectorLayer z użytkownikiem utworzymy formant SelectFeature, który nazwiemy 'featureSelected'. Interakcja opierać się będzie na przechwyceniu zdarzeń aktywacji i deaktywacji formantu. Dla przypadku aktywacji właściwości 'onSelect' zostaje przypisana funkcja createPopup(), a dla deaktywacji właściwości 'onUnselect' zostaje przypisana funkcja destroyPopup().
... var controls = { featureSelected: new OpenLayers.Control.SelectFeature( vectorLayer, { onSelect: createPopup, onUnselect: destroyPopup }) }; ...
function createPopup(myPoint) { ... myPoint.popup = new OpenLayers.Popup.FramedCloud( id = 'myFramedCloud', lonlat = myPoint.geometry.getBounds().getCenterLonLat(), contentSize = null, contentHTML = popupHtml, anchor = myPoint.icon, closeBox = true, closeBoxCallback = function() { controls['featureSelected'].unselectAll(); } ); // dla exclusive = true, zamykane są inne otwarte okna popup map.addPopup(myPoint.popup, exclusive = true); } ...
function destroyPopup(myPoint) { myPoint.popup.destroy(); myPoint.popup = null; } ...
Jak uatrakcyjnić okienka popup (dymki)
Podobnie, jak to miało miejsce w przypadku znaczników (markerów) okienka popup wyglądają marnie.
Aby okienka popup nieco upiększyć można dla każdego okienka przekazać w argumencie 'attributes'
konstruktora OpenLayers.Feature.Vector do funkcji addPopups(...)
dane okna 'popup' takie jak: tytuł (popupTitle), opis (popupDescription),
ścieżka do fotografii (popupImage) i podpis pod fotografią (popupImageCaption).
W funkcji addPopups(...) tworzymy pełny tekst HTML określający styl i treść
jaka będzie zawarta w znaczniku <div id="frameCloud"> okna 'popup' (dymku).
var popupHtml='' popupHtml+='<div id="frameCloud">' popupHtml+='<h1>'+myPoint.attributes.popupTitle+'</h1>' popupHtml+='<span id="dscr">'+myPoint.attributes.popupDescription+'</span>' popupHtml+='<div id="foto">' popupHtml+='<img src="'+myPoint.attributes.popupImage+'" alt="foto ' popupHtml+=myPoint.attributes.popupTitle+'"/><br>' popupHtml+='<span>'+myPoint.attributes.popupImageCaption+'</span>' popupHtml+='</div></div>';
Wewnętrzny arkusz stylów okienka popup
Podobnie jak w przypadku znaczników (markerów) 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>
Tworzenie punktów i powiązanych z nimi okien popup (dymków)
Pozostało tylko przedstawić kod odpowiedzialny za tworzenie punktów na mapie i powiązanych z nimi okien 'popup' oraz funkcję wywołującą.
// deklaracja warstwy wektorowej zawierającej graficzne punkty 'myPoint' var layerPoints; // deklaracja tablicy zawierającej wszystkie punkty (ToDo) var arrPoints = []; // utwórz warstwę wektorową na przyjęcie graficznych punktów function createlayerPoints(id, layerName, displayInLayerSwitcher, setVisibility){ layerPoints = new OpenLayers.Layer.Vector(layerName); // przypisz identyfikator warstwy layerPoints.id = id; // pokaż warstwę w oknie przełącznika warstw layerPoints.displayInLayerSwitcher = displayInLayerSwitcher;; // pokaż warstwę na mapie layerPoints.setVisibility(setVisibility) } /* funkcja tworząca pojedyncze punkty graficzne w warstwie wektorowej 'layerPoints' o atrybutach określonych w argumentach funkcji. W argumencie 'attributes' konstruktora OpenLayers.Feature.Vector przekazywane są do funkcji addPopups(...) dane okna 'popup', takie jak: tytuł (popupTitle), opis (popupDescription), ścieżka do fotografii (popupImage) i podpis pod fotografią (popupImageCaption) */ function createGraphicPoint(id, lon, lat, externalGraphic, graphicWidth, graphicHeight, graphicXOffset, graphicYOffset, popupTitle, popupDescription, popupImage, popupImageCaption) { var point = new OpenLayers.Geometry.Point(lon, lat).transform(epsg4326, epsg900913); // utwórz pojedynczy punkt var myPoint = new OpenLayers.Feature.Vector(point, {'popupTitle':popupTitle, 'popupDescription':popupDescription, 'popupImage':popupImage, 'popupImageCaption':popupImageCaption}, {'externalGraphic': externalGraphic, 'graphicHeight': graphicHeight, 'graphicWidth': graphicWidth, 'graphicXOffset':graphicXOffset, 'graphicYOffset':graphicYOffset, 'cursor':'pointer' // ustaw kursor myszy na 'rączkę' //rotation: pointRotation >= MS ACCESS przy rotacji externalGraphic dodaje //brzydką obwódkę i cienie, ucina grafikę oraz nie wyświetla okno typu framedCloud } ); // przypisz identyfikator znacznikowi myPoint.id = id //identyfikator płaszczyzny (ToDo) myPoint.PlaneID = id; // dodaj punkt do warstwy layerPoints.addFeatures(myPoint); // dodaj punkt do tablicy arrPoints[] - (ToDo) arrPoints.push(myPoint); } // pokaż punkty na mapie i wycentruj mapę function displayLayerMultiPoint(lon, lat, zoom){ map.addLayer(layerPoints); addPopups(); // wycentruj mapę w/m współrzędnych środka, powiększ do skali zoomLevel fInitCenterMap(22.501935,51.296918,14); } function addPopups(){ //utwórz formant 'featureSelected' var controls = { featureSelected: new OpenLayers.Control.SelectFeature( layerPoints, { onSelect: createPopup, onUnselect: destroyPopup }) }; /* Definicja okna popup, które będzie utworzone po kliknięciu punktu. • id - identyfikator okna popup • lonlat - położenie punktu • contentHTML - pełny tekst HTML określający styl i treść w oknie popup (dymku), dla punktów treść i zawartość okna 'popup' przekazywane są w argumencie 'attributes' typu 'object', tworzonego punktu • 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 (po uwzględnieniu offsetX, offsetY), dla anchor = myPoint.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 = myPoint.icon okno popup otwiera się prawidłowo. • closeBox - dla wartości true tworzony jest przycisk 'X' zamykający okno popup • closeBoxCallback - funkcja zwrotna, uruchamiana po kliknięciu przycisku closeBox. */ function createPopup(myPoint) { var popupHtml='' popupHtml+='<div id="frameCloud">' popupHtml+='<h1>'+myPoint.attributes.popupTitle+'</h1>' popupHtml+='<span id="dscr">'+myPoint.attributes.popupDescription+'</span>' popupHtml+='<div id="foto">' popupHtml+='<img src="'+myPoint.attributes.popupImage+'" alt="foto ' popupHtml+=myPoint.attributes.popupTitle+'"/><br>' popupHtml+='<span>'+myPoint.attributes.popupImageCaption+'</span>' popupHtml+='</div></div>'; myPoint.popup = new OpenLayers.Popup.FramedCloud( id = 'myFramedCloud', lonlat = myPoint.geometry.getBounds().getCenterLonLat(), contentSize = null, contentHTML = popupHtml, anchor = myPoint.icon, closeBox = true, closeBoxCallback = function() { controls['featureSelected'].unselectAll(); } ); // dla exclusive = true, zamykane są inne otwarte okna popup map.addPopup(myPoint.popup, exclusive = true); } function destroyPopup(myPoint) { myPoint.popup.destroy(); myPoint.popup = null; } // dodaj formant 'featureSelected' do warstwy layerPoints map.addControl(controls['featureSelected']); controls['featureSelected'].activate(); }
3. Trzy okna popup na mapie powiązane z punktami
// funkcja tworząca warstwę wektorową na przyjęcie punktów function fDrawExternalGraphic(id, layerName){ createlayerPoints(id, layerName, 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()+'/'; // tworzenie poszczególnych punktów graficznych w warstwie wektorowej 'layerPoints' lat="51.288912026211619"; lon="22.496877992525697" createGraphicPoint('Miejsce_01',lon,lat,path+'MapMarker_Ball__Azure.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" createGraphicPoint('Miejsce_02',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.28982";lon="22.501583" createGraphicPoint('Miejsce_03',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') displayLayerMultiPoint(22.501935,51.296918,14) }
Podobnie jak w przypadku znaczników (markerów) ograniczeniem jest sztywno ustalona w wewnętrznym arkuszu stylów szerokość fotografii na '140px'. Dla fotografii o orientacji poziomej okienko wygląda dobrze, ale dla fotografii o orientacji pionowej, fotografia jest zbyt wysoka. Optymalną wysokością fotografii jest ok. 100px. Aby móc zmienić wysokość fotografii w funkcji createGraphicPoint(...) powinniśmy przekazać w dodatkowym argumencie informację o orientacji fotografii.
Na razie zostawiam tak, jak jest. Być może uzupełnię kod w najbliższym czasie. (ToDo...)