Access

 MS Access i OpenLayers - Własne i graficzne punkty na śladzie GPX.

Kształty punktów na mapie

Biblioteka OpenLayers umożliwia utworzenie 6 różnych punktów o zdefiniowanych kształtach:
circle (domyślny), square, star, x, cross oraz triangle.

Domyślne kształty punktów   
1. Zdefiniowane kształty punktów.

Własne kształty punktów.

Jeżeli uznamy, że 6 kształtów punktów to zbyt mało, możemy spróbować utworzyć punkty o własnych kształtach. Poniżej przedstawiam sposoby (przykłady znalezione gdzieś w Internecie) jak utworzyć 8 innych kształtów punktów: lightning, rectangle, church, flag, arrow, pointToIcon, boatright, ship
oraz 4 moje kształty własne:
flagLeft, flagRight, pennantRight, pennantLeft

// znalezione w internecie
OpenLayers.Renderer.symbol.lightning = [0,0,4,2,6,0,10,5,6,3,4,5,0,0];
OpenLayers.Renderer.symbol.rectangle = [0,0,4,0,4,10,0,10,0,0];
OpenLayers.Renderer.symbol.church = [4,0,6,0,6,4,10,4,10,6,6,6,6,14,4,14,4,6,0,6,0,4,4,4,4,0];
OpenLayers.Renderer.symbol.flag = [0,0,0,140,120,140,120,60,4,60,4,0,0,0];
OpenLayers.Renderer.symbol.arrow = [0,2,1,0,2,2,1,0,0,2];
OpenLayers.Renderer.symbol.pointToIcon = [100,70,20,50,42,70,20,90];
OpenLayers.Renderer.symbol.boatright = [45,0,35,10,0,10,0,0,25,0,25,-55,0,-10,25,-10,25,-55,
																				45,-2,25,-5,25,0,45,0];
OpenLayers.Renderer.symbol.ship = [-4,0,-3,-6,0,-14,3,-6,4,0,4,7,3,11,2,14,-2,14,-3,11,-4,7,-4,0];
// moje własne punkty
OpenLayers.Renderer.symbol.flagLeft = [0,0,0,-140,-120,-140,-120,-60,-4,-60,-4,0,0,0];
OpenLayers.Renderer.symbol.flagRight = [0,0,0,-140,120,-140,120,-60,4,-60,4,0,0,0];
OpenLayers.Renderer.symbol.pennantRight = [0,0,0,-140,120,-100,120,-100,120,-60,4,-60,4,0,0,0];
OpenLayers.Renderer.symbol.pennantLeft = [0,0,0,-140,-120,-100,-120,-100,-120,-60,-4,-60,-4,0,0,0];

Własne kształty punktów   
2. Dodatkowe własne punkty na mapie.
function fDrawPoints(){
// utwórz warstwę wektorową o domyślnym stylu punktów 'stylePointDefault'
createPointsLayer('marysin','Punkty na śladzie Marysin');
// własne punkty
createPoint(22.47000,51.284000,'lightning','lm',20,-10,15,0,'#f0f',2,'#00f','lightning');
createPoint(22.47500,51.286000,'rectangle','lm',20,-10,15,0,'#800',2,'#0f0','rectangle');
createPoint(22.48000,51.288000,'church','lm',20,-10,15,0,'#008',2,'#f00','church');
createPoint(22.48500,51.290000,'flag','lm',20,-10,15,0,'#800',2,'#0ff','flag');
createPoint(22.49000,51.292000,'arrow','lm',20,-10,10,0,'#088',2,'#ff0','arrow');
createPoint(22.49500,51.294000,'pointToIcon','lm',20,-10,15,0,'#008',2,'#f0f','pointToIcon');
createPoint(22.50000,51.296000,'boatright','lm',20,-10,15,0,'#f00',2,'#080','boatright');
createPoint(22.50500,51.298000,'ship','lm',20,-10,15,0,'#800',2,'#088','ship');
createPoint(22.51020,51.300000,'flagLeft','lm',20,-10,15,0,'#00f',2,'#808','flagLeft');
createPoint(22.51540,51.302000,'flagRight','lm',20,-10,15,0,'#0f0',2,'#00f','flagRight');
createPoint(22.52060,51.304000,'pennantLeft','lm',20,-10,15,0,'#00f',2,'#080','pennantLeft');
createPoint(22.52580,51.306000,'pennantRight','lm',20,-10,15,0,'#00f',2,'#c00','pennantRight');

// dodaj warstwę 'vectorPointsLayer' do obiektu 'map'
map.addLayer(vectorPointsLayer);
}
 

Graficzne symbole punktów (External Graphic)

Jeżeli uznamy, że 6 zdefiniowanych kształtów punktów oraz wszystkie „wymyślone” przez nas kształty nie odpowiadają naszym wymogom estetycznym, to spróbujmy skorzystać z zewnętrznych plików graficznych do prezentacji punktów na mapie. „Darmowe„ pliki znaczników graficznych możemy pobrać ze strony:
www.iconfinder.com: Map Markers lub bezpośrednio ze strony www.icons-land.com: Vista Style Map Markers Icons Set
Na stronie tej znajdują się pliki graficzne, które odpowiadają moim oczekiwaniem. W Internecie znaleźć można wiele stron z „darmowymi„ plikami graficznymi. Zazwyczaj ceną za „darmowe„ pliki graficzne jest umieszczenie linku do strony z której pobraliśmy „darmowe„ pliki graficzne.

Zewnętrzne pliki graficzne   
2. Dodatkowe własne punkty na mapie.
Znak Informacja dodatkowa Przed użyciem darmowych ikon należy zapoznać się z Umową licencyjną Icons-Land Demo License Agreement

Pliki graficzne dostępne są w wielu rozmiarach. Począwszy od rozmiaru 16x16, poprzez 32x32, 48x48 i 64x64, aż do rozmiaru największego 256x256. Moim zdaniem najrozsądniejszy rozmiar grafiki punktów to 32x32 pikseli lub 48x48. W celach demonstracyjnych wybiorę kilka(naście) przypadkowych znaczników, a reszta to już implementacja kodu.

Tworzenie punktów graficznych w warstwie wektorowej.

O ile w przykładzie opisanym na poprzedniej stronie Punkty na śladzie w formacie *.gpx udało mi się utworzyć domyślny styl etykiet stylePointDefault to w tym przykładzie nie potrafię nadać stylu etykietom. Co prawda można przekazywać poszczególne atrybuty w argumentach funkcji, ale moim zdaniem, jest to bez sensu. Założeniem głównym jest prezentacja map i znaczników w formularzu MS Access, a skoro etykiety są niewidoczne w  MS Access w formancie Microsoft Web Browser, to kończę zabawę z etykietami. Wydaje mi się, że etykiety opisujące znaczniki, to taki kwiatek do kożucha . Za tydzień, może dwa pojawi się nowa funkcjonalność dotycząca punktów. Ale potrzymam Was w niepewności . Markery też być może niedługo będą.


// deklaracja warstwy wektorowej zawierającej graficzne punkty 'myGraphicPoint'
var vectorGraphicLayer;
var myGraphicPoint;

// utwórz warstwę wektorową na przyjęcie graficznych punktów
function createGraphicLayer(id, nameLayer, displayInLayerSwitcher, setVisibility){
	vectorGraphicLayer = new OpenLayers.Layer.Vector(nameLayer);
	// przypisz identyfikator warstwy
	vectorGraphicLayer.id = id;
	// pokaż warstwę w oknie przełącznika warstw
	vectorGraphicLayer.displayInLayerSwitcher = displayInLayerSwitcher;;
	// pokaż warstwę na mapie
	vectorGraphicLayer.setVisibility(setVisibility)
}

// funkcja tworząca pojedyncze punkty graficzne w warstwie wektorowej 'vectorGraphicLayer'
// o atrybutach określonych w argumentach funkcji
function createGraphicPoint(lon, lat, externalGraphic, graphicWidth, graphicHeight,
														 graphicXOffset, graphicYOffset) {
	var point = new OpenLayers.Geometry.Point(lon, lat).transform(epsg4326, epsg900913);
	myGraphicPoint = new OpenLayers.Feature.Vector(point, {},
					{'externalGraphic': externalGraphic,
					'graphicHeight': graphicHeight,
					'graphicWidth': graphicWidth,
					'graphicXOffset':graphicXOffset,
					'graphicYOffset':graphicYOffset
					//rotation: pointRotation	>= MS ACCESS przy rotacji externalGraphic dodaje
					//brzydką obwódkę i cienie oraz nie wyświetlane okno typu frameCloud
					}
			);
	vectorGraphicLayer.addFeatures(myGraphicPoint);
}

Przy wywoływaniu funkcji createGraphicPoint(...) tworzącej punkty graficzne należy zwrócić uwagę, czy znajdują się one w podfolderze Centered, czy NotCentered. Te pierwsze (centrowane) jest o wiele łatwiej dokładnie umiejscowić na ścieżce trasy GPX. Dla wszystkich plików z tego folderu przesunięcie graphicXOffset, graphicYOffset jest stałe i wynosi ok. (-size/2, -size). Dla takiej wartości znacznik (jego końcówka) znajduje się blisko śladu GPX.
Dla plików z podfolderu NotCentered należy indywidualnie dobrać przesunięcie. O ile przesunięcie pionowe graphicYOffset ma wartość stałą, równą -size, to przesunięcie poziome graphicXOffset przyjmuje wartości zależne chyba od pochylenie i wynoszą one: 0; -size/4; -size/2; -size.


function fDrawExternalGraphic(){
	// 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()+'/';

	// utwórz warstwę wektorową
	createGraphicLayer(id, nameLayer, true, true)

	// tworzenie poszczególnych punktów graficznych w warstwie wektorowej 'vectorGraphicLayer'
	lat="51.288912026211619";lon="22.496877992525697"
	createGraphicPoint(lon,lat,path+'MapMarker_Ball__Azure.png', size, size, -size/2, -size);
	lat="51.289822971448302";lon="22.501583006232977"
	createGraphicPoint(lon,lat,path+'MapMarker_Ball_Left_Chartreuse.png', size, size, -size/2, -size);
	lat="51.289219977334142";lon="22.503895992413163"
	createGraphicPoint(lon,lat,path+'MapMarker_Ball_Right_Pink.png', size, size, -size/2, -size);
	lat="51.288394024595618"; lon="22.505702963098884"
	createGraphicPoint(lon,lat,path+'MapMarker_Board_Pink.png', size, size, -size/2, -size);
	lat="51.290338039398193"; lon="22.506549032405019"
	createGraphicPoint(lon,lat,path+'MapMarker_Bubble_Chartreuse.png', size, size, -size/2, -size);
	lat="51.2920300103724"; lon="22.505863979458809"
	createGraphicPoint(lon,lat,path+'MapMarker_DrawingPin_Left_Azure.png', size, size, -size/2, -size);
	lat="51.293702032417059"; lon="22.505411021411419"
	createGraphicPoint(lon,lat,path+'MapMarker_DrawingPin_Right_Pink.png', size, size, -size/2, -size);
	lat="51.295340023934841"; lon="22.504996033385396"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag2_Left_Chartreuse.png', size, size, -size/2, -size);
	lat="51.297403983771801"; lon="22.504101013764739"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag5_Pink.png', size, size, -size/2, -size);
	lat="51.299123028293252"; lon="22.503597009927034"
	createGraphicPoint(lon,lat,path+'MapMarker_Marker_Inside_Chartreuse.png', size, size, -size/2, -size);
	lat="51.300733024254441"; lon="22.503075990825891"
	createGraphicPoint(lon,lat,path+'MapMarker_Marker_Outside_Pink.png', size, size, -size/2, -size);
	lat="51.302910977974534"; lon="22.502304017543793"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin1__Azure.png', size, size, -size/2, -size);
	lat="51.305026989430189"; lon="22.501572025939822"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin2__Pink.png', size, size, -size/2, -size);
	lat="51.306459037587047"; lon="22.501102974638343"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin2_Left_Chartreuse.png', size, size, -size/2, -size);
	lat="51.307248026132584"; lon="22.498928960412741"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin2_Right_Azure.png', size, size, -size/2, -size);
	lat="51.307167978957295"; lon="22.495145034044981"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag2_Right_Pink.png', size, size, -size/2, -size);
	lat="51.307268980890512"; lon="22.491870978847146"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag4_Left_Azure.png', size, size, -size/2, -size);
	lat="51.305890996009111"; lon="22.490770015865564"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag4_Right_Chartreuse.png', size, size, -size/2, -size);

	// ścieżka do plików graficznych "NotCentered")
	path='markers/IconsLand/PNG/NotCentered/'+size.toString()+'x'+size.toString()+'/';

	lat="51.303506009280682"; lon="22.491532014682889"
	createGraphicPoint(lon,lat,path+'MapMarker_ChequeredFlag_Left_Azure.png', size, size, -size, -size);
	lat="51.301445988938212"; lon="22.49222201295197"
	createGraphicPoint(lon,lat,path+'MapMarker_ChequeredFlag_Right_Pink.png', size, size, 0, -size);
	lat="51.29940097220242"; lon="22.492963979020715"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag1_Left_Chartreuse.png', size, size, -size/2, -size);
	lat="51.297383029013872"; lon="22.493559010326862"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag1_Right_Pink.png', size, size, -size/4, -size);
	lat="51.295751994475722"; lon="22.494112970307469"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag3_Left_Chartreuse.png', size, size, -size, -size);
	lat="51.294504012912512"; lon="22.494491999968886"
	createGraphicPoint(lon,lat,path+'MapMarker_Flag3_Right_Azure.png', size, size, 0, -size);
	lat="51.28710899502039"; lon="22.500583967193961"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin1_Left_Chartreuse.png', size, size, -size/2, -size);
	lat="51.28674304112792"; lon="22.498324038460851"
	createGraphicPoint(lon,lat,path+'MapMarker_PushPin1_Right_Pink.png', size, size, -size/4, -size);

	// dodaj warstwę 'vectorGraphicLayer' do obiektu 'map'
	map.addLayer(vectorGraphicLayer);
}

Aby przetestować wygląd plików graficznych różnej wielkości należy pobrać pliki ze strony:
http://www.icons-land.com/vista-map-markers-icons.php i rozpakować do folderu markers/IconsLand/. Mając pliki o wszystkich rozmiarach, możemy poprzez zmianę wartości zmiennej size na wartości odpowiadające rozmiarom pliku tj. 16, 32 ...256 możemy dobrać optymalną wielkość (wymiar) pliku graficznego.
W zademonstrowanym przykładzie ograniczam się tylko do plików o rozmiarze 48x48 pikseli. Poniżej przedstawiam jak prezentują się graficzne punkty w zależności od wymiarów grafiki pliku.

Plik graficzny - wielkość   
3. Wygląd punktów o różnej wielkości.

Atrybut stylu Rotation


Jednym z wielu atrybutów stylu punktu jest atrybut:
rotation:
{Number} określa kąt o jaki zostanie obrócony punkt graficzny. Obrót następuje zgodnie z kierunkiem ruchu wskazówek zegara wokół jego punktu środkowego, lub punktu poza środkiem, określonym przez atrybuty GraphicXOffsetgraphicYOffset.

Plik graficzny - rotacja   
4. MS Access - bez obrotu.        5. MS Access - obrót o 45o.              6. Firefox - obrót o 45o.      

Znak Uwaga Niestety, formant Microsoft Web Browser przy obrocie punktu tworzy czarną obwódkę wokół punktu i czarny cień pod symbolem punktu, a także „ucina” fragmenty obracanej grafiki.

Co prawda licencja nie zezwala na modyfikowane ikon w kształcie i / lub kolorze;
The Icons may not be modified in shape and/or color, ale chyba wolno poszczególne punkty obracać w programie graficznym o dowolny kąt i tworzyć kopię pliku graficznego o zmienionej nazwie.

Rotacja znacznika graficznego co 30o stopni

Teoretycznie efekt końcowy obrotu symbolu graficznego w dowolnym programie powinien być taki sam jak po zastosowaniu atrybutu stylu rotation: w przeglądarce internetowej.

Rotacja - Paint.net
7. Plik graficzny MapMarker_Ball__Pink.png obracany w programie Paint.net.

Niestety, tak nie jest. W przypadku darmowego programu Paint.net efekt końcowy nie jest zadowalający. Widoczne są duże rozmycia (nieostrości) symbolu znacznika graficznego.

Rotacja - Adobe Elements
8. Plik graficzny MapMarker_Ball__Pink.png obracany w programie Adobe Photoshop Elements 10.

Jeżeli użyjemy trochę lepszego, komercyjnego programu Adobe Photoshop Elements 10 (w sumie za nieduże pieniądze) to efekt jest zdecydowanie lepszy.

Rotacja - MS Access
9. Plik graficzny MapMarker_Ball__Pink.png obracany w formancie Microsoft Web Browser.

Jak widać na powyższym obrazku formant Microsoft Web Browser wypada żenująco, jeżeli chodzi o możliwości przetwarzania grafiki (tut. operacja obrotu grafiki). Prawdopodobnie formant ten nie wie co to jest „przezroczystość” i traktuje przezroczyste piksele jako piksele o kolorze '#000' (czarne). Ucinanie grafiki poddanej operacji obrotu świadczy o wielkich problemy tego formantu z przeliczeniem obszaru grafiki poddanej obrotowi .


Aby nie wyjść na malkontenta, chcę wyraźnie zaznaczyć: tylko formant Microsoft Web Browser w MS Access nie radzi sobie z obrotem punktów graficznych. W przeglądarkach Chrome, Firefox i Internet Explorer 11 wszystko jest OK. Jest, lub wszystko jest OK. Na razie sprawdzam wszystko online. Po osadzeniu strony na serwerze zobaczę, czy nie będzie problemów.
Jeżeli chodzi o obróbkę (obrót) plików graficznych należy dobrać sobie program spełniający nasze oczekiwania.

Funkcjonalność graficznych punktów

To czego brakuje zarówno punktom wektorowym jak również punktom graficznym, to brak interakcji. Punkty są „martwe”. A powinny po kliknięciu (bądź najechaniu wskaźnikiem myszy) wyświetlić w okienku Popup dane dotyczące zaznaczonego punktu, Okienko takie nazywane jest „dymkiem”, rzadziej „chmurką”.