|
Array (Vorgabe für obige Punkte):
Werte für die oben verwendete Deutschlandkarte $imgSize[0]
|
Die AufgabenstellungAuf der Homepage sind auf einer Deutschlandkarte mit Punkten Standorte zu markieren (z.B. Standorte von Zweigstellen, Wohnorte von Mitgliedern, Büros von Vereinen usw. usw.). Wie macht man so etwas? - Ich habe dies auf einer von mir betreuten Website realisieren müssen und gebe hier mein Wissen und meine Erfahrungen damit weiter.Die visuelle MethodeMit einem Bildbearbeitungsprogramm werden mit dem Pinsel die Punkte in die Grafik gesetzt. Nachteil: Änderungen sind nur mühsam anzubringen. Und man weiß auf der kleinen Karte nicht so genau, wo der Punkt hinzusetzen ist. Meist wird man eine Landkarte oder Straßenkarte (in größerem Maßstab) zu Hilfe nehmen müssen. Der Vorteil jedoch: Schnell zu realisieren. PHP wird nicht benötigt.Die mathematische Methode - manuell umgesetztDie geographische Position des Punktes (Längen- und Breitengrad) wird ermittelt. Dazu gibt es Webseiten (z.B. iTouchMap.com), auf denen Orte oder sogar Adressen eingegeben werden und die die Postion liefern. Mit einem Taschenrechner wird nun daraus manuell die Pixel-Position auf der Grafik-Karte errechnet. Die Formel dazu ist weiter unten zu finden - auch eine ausführliche Erläuterung dazu steht auf dieser Seite. Mit einem Bildbearbeitungsprogramm lassen sich nun die Punkte mit einem "Pinsel" exakt auf die richtige Position setzen. Alle derartigen Programme zeigen die aktuelle Pixel-Position des Pinsels/Pointers an. Auch hier ist PHP nicht erforderlich.Die mathematische Methode - automatisch umgesetztDiese Methode erfordert PHP. Die Punkte werden dynamisch zur Laufzeit auf die Karte (Grafik) gesetzt. Dazu benötigt man den Punkt als kleine Grafik, z.B. in der Größe 6x6 Pixel. Auch andere kleine Symbole sind geeignet. Zunächst wird per Hand die geographische Position des Ortes ermittelt (z.B. über die Website iTouchMap.com). Die Angaben werden in einem PHP-Array (oder noch besser: in einer Datenbank-Tabelle) abgelegt. Dort sind sie leicht änderbar. Im Falle von MySQL sogar online und es wird kein Upload notwendig. Mittels PHP wird die Position des Punktes in Pixeln auf der Deutschland-Grafik errechnet. - Es gibt auch Software hierfür, deren Installation als HTML-Erweiterung erfordert aber einigen Aufwand. Siehe dazu die Seite von GISwiki [GISwiki - Das freie Portal für Geoinformatik (GIS)]. In den meisten Fällen fährt man aber mit der eigenen Codierung besser. Sie ist ausreichend genau für Grafiken von Ländern in der Größe Deutschlands, die z.B. den Bereich eines halben Bildschirms einnehmen.Formel zur Umrechnung eines Längen-/Breitengrades in eine PixelpositionErläuterungen zu dieser Formel, was dort im Einzelnen berechnet wird, sind weiter unten zu finden. Diese Formel paßt so nur für Positionen auf der nördlichen Halbkugel und östlich des Längengrades Null. Änderungen zur Berücksichtigung anderer Positionen sind aber leicht möglich. Zu beachten ist aber, daß sich bei großen Ländern (z.B. ganz Europa) im oberen und unteren Bereich Verzerrungen ergeben können. Evtl. ist hier über eine Tabelle ein Korrekturfaktor für jeden Breitengrad vorzugeben. Nun die Formel:
$Left=round(((($Longitude - $Easting) / $HorizGPx * $ZoomFaktor)-($DotSize/2)),0); Hinweis: Die Längengrade innerhalb Deutschlands werden auf dem Globus von links nach rechts gezählt, die Breitengrade (Latitude) werden von unten (vom Äquator aus) nach oben (zum Nordpol hin) gezählt, deshalb unterscheiden sich die beiden Formeln ein wenig. Die Variablen darin:
$Left = Ergebnis Punktposition horizontal in Pixel innerhalb der Grafik In der linken Spalte auf dieser Seite, unterhalb der Deutschlandkarte und der Arrays, stehen die notwendigen Werte ($Easting, $Northing, $VertiGPx, $VHorizGPx) für die hier verwendete Deutschlandkarte. Weiter unten habe ich unter der Überschrift "Manuelle Ermittlung ..." den Vorgang beschrieben, wie diese Werte bei einer eigenen Deutschlandkarte ermittelt werden können. Punkt abbilden und MouseOver-CodingSo setze ich mit PHP den Punkt auf die Deutschlandkarte. Wichtig ist, daß der z-index für den Punkt einen höheren Wert als der z-index der Deutschlandkarte besitzt, damit die Punkte sichtbar sind. Sind beim Überfahren der Punkte Informationen in einer kleinen Textbox anzuzeigen, wird das mit dem Event "onmouseover" und "onmouseout" realisiert. Jede Textbox muß dabei einen eindeutigen Namen besitzen. Ich habe dazu die Satznummer aus dem Array, der die Punkt-Koordinaten enthält, verwendet und in die Variable $ID gebracht. Die Satznummer ist immer eindeutig und man erspart sich die Vergabe und Kontrolle von eigenen IDs.
echo "<img style='position:absolute;left:".$Left."px;top:".$Top."px;z-index:3;cursor:hand;' src='\"punkt.gif.\"' "; Die kleine Textbox für das "MouseOver" wird bei mir mit dem folgenden Coding generiert. Die Box enthät den Text aus meinem Array $Punkte. Da die Textbox als oberste Schicht erscheinen soll, d.h. alle anderen Abbildungen und Texte überdecken soll, muß der z-index den hoechsten Wert haben. Die Position der Textbox habe ich in der Variablen $TopMouseOver 58 Pixel über den Punkt gelegt. In der Variablen $ID steht der oben erwähnte eindeutige Name der Info-Box. $Left/$Top enthalten die Position des Punktes.
$TopMouseOver=$Top-58; Bei Klick auf einen Punkt eine Seite anzeigenSollen die Punkte auf der Deutschlandkarte auch anklickbar sein, so wird mit PHP die IMG-Anweisung des Punktes in einen Link eingebettet. Oder man verwendet den Event "onclick". Hier ist ein Beispiel für ONCLICK, wobei links oben ein kleines Fenster geöffnet wird, dem mittels URL-Parameter Informationen oder IDs weitergegeben werden.echo " onclick='window.open(\"info.php?ID=".$ID."&Txt=".$Punkte[$n][$pText]."\",\"_new\",\"toolbar=no,width=300,height=200\");'>\n"; Format des Längen- und BreitengradesZum Rechnen wird die Angabe als Dezimalzahl benötigt. Die Schreibweise in Grad/Minuten/Sekunden (z.B. 53°33'8'' manchmal auch 53:33:8 geschrieben), ist umzurechnen. Das geschieht wie folgt: Grad + Minuten/60 + Sekunden/360. Damit ergibt z.B. 53°33'8" den Wert 53,5522 (in PHP zu schreiben mit Dezimalpunkt, also z.B. $Longitude=53.5522;
Mit einem Taschenrechner erfolgt die Umrechnung sinnvollerweise durch die folgende Eingabe: Eine PHP-Funktion zum Umrechnen, die beide Schreibweisen berücksichtigt, kann wie folgt aussehen. In obige Formel ist dann in PHP statt $Longitude der Funktionsaufruf UmDez($Longitude) einzusetzen. Gleiches gilt für Latitude.
function UmDez($x){
$ZoomfaktorVergrößerungs- oder Verkleinerungsfaktor der gezeigten Grafik gegenüber der Originaldatei. Errechnet aus Hoehe der dargestellten Grafik geteilt durch Hoehe der Image-Datei. Diesen Faktor kann man natürlich auch ignorieren, wenn die Deutschland-Grafik immer in der Originalgröße angezeigt werden. Auch wenn die Größe verändert wird, könnte man dies bei der Berechnung der Konstanten "Grad pro Pixel" gleich berücksichtigen. Ich rate aber davon ab. Das Coding wird flexibler, wenn man den Zoomfaktor errechnen läßt und zur Laufzeit errechnet. Ich kann dann jederzeit die Größe der Grafik auf dem Bildschirm verändern, ohne andere Faktoren oder Konstanten ändern zu müssen.Beispiel: Hat die Grafik-Datei "deutschlandkarte.jpg" zum Beispiel eine Hoehe von 350 Pixel und lautet die Anweisung zum Einbinden der Grafik: <IMG src="deutschlandkarte1.jpg" height="440" width="348" border="0"> Dann errechnet sich der Zoomfaktor aus 440/348 was den Wert 1,264 (in PHP als 1.264 zu schreiben) ergibt. Wenn man mit verschiedensten Deutschlandkarten-Grafiken experimentiert, ist es sinnvoll, diesen Wert automatisch zu ermitteln. In den Variablen $imgHeight und $imgWidth legt man die gewünschte Darstellungsgröße fest. Alle weiteren Informationen lassen sich mit PHP-Anweisungen errechnen. Das Coding dazu:
$imgHeight=440;$imgWidth=348; // Hohe/Breite der Deutschlandkarte in der Anzeige
|
Es wird eine Deutschlandkarte als Grafik benötigt. Von dieser Karte muß man die geographische Lage der linken oberen Ecke und die gesamte Breite und Höhe dieser Karte in der Natur kennen. Diese Angabe muß in Grad (Minuten und Sekunden als Dezimalstellen) vorliegen. Die Größe der Grafik in Pixeln ist ja bekannt bzw. kann schnell abgelesen werden. Meine verwendete Karte ist von GISwiki und dort werden diese Information gleich mitgeliefert. Weiter unten steht, wie die Position und der Faktor "Grad pro Pixel (oder anders ausgedrückt: Das Verhältnis eines Pixel zur Natur, ausgedrückt in Grad) auch selbst ermittelt werden kann.
Die Deutschlandkarte muß auf der Website auf eine absolute Position gelegt werden. Nun wird die geographische Position eines Punktes (z.B. 53°16'33''Nord, 8°2'59''Ost) in eine Dezimalzahl umgewandelt (die erste Angabe z.B. in 53,2758). Von diesen Zahlen wird die Position (in Grad) der linken oberen Ecke der Grafik abgezogen und schon hat man die Position auf der Grafik. Allerdings noch in Grad. Ein Grad hat in Deutschlands Mitte übrigense eine vertikale Ausdehnung von 111,111 km (eine nautische Meile) und eine horizontale Ausdehnung zwischen 60 km und 75 km (bekanntlich geht diese Ausdehnung am Nordpol auf 0 zurück). Die Position in Grad ist somit durch einen Faktor "Grad pro Pixel" zu dividieren. Das Ergebnis ist die Pixelposition (Left/Top) innerhalb der Grafik. Bleibt noch die Anfangsposition (in Pixel) der Grafik dazuzuzählen und schon läßt sich an dieser Stelle ein Punkt als Grafikdatei positionieren. Eine kleine Korrektur ist notwendig, damit der Mittelpunkt des Punktes an der errechneten Stelle steht: Die halbe größe des Punktes ist jeweils abzuziehen.
Achtung - nicht irritieren lassen: Eine Tatsache ist in den beiden Formeln automatisch berücksichtigt worden. Die vertikale Position (Breitengrad oder Latitude) wird bei uns auf der nördlichen Halbkugel vom Äquator aus zum Nordpol hin gezählt, also von unten nach oben. Die Lage des gesuchten Punktes (Abstand vom oberen Rand, Abstand vom linken Rand) in Grad wird deshalb jeweils anders berechnet.
So, das war der Weg bzw. die Formel im Erzählton. Bei falschen Ergebnissen hilft das Verständnis der Formel ganz erheblich, die Ursache des Fehlers zu finden.
Informationen zu den Längen- und Breitengraden, die das Verständnis vertiefen, sind auf der Website von [Meeresgeo-Online] zu finden.
Auf meiner eigenen Website www.blockfloetenorchester.de habe ich dieses Problem an einigen Stellen und ich experimentiere dort mit einer "automatischen" Lösung, die mir die Punkte zur Laufzeit bei Kollisionen entsprechend verschiebt. Noch bin ich nicht zufrieden mit dem Ergebnis, da ich die Punkte der Einfachheit halber nach rechts bzw. rechts-unten verschiebe. Liegen aber viele Punkte dicht beieinander, so wird die Verschiebung recht gravierend. Die Punkte sollten aber möglichst nahe am wirklichen Ort platziert werden.
Die folgende Seite zeigt das augenblickliche Ergebnis. Auf der linken Karte sind die Punkte gemäß ihrer Koordinaten gesetzt, auf der rechten Karte wurden die Kollisionen korrigiert (Punkte verschoben.
Man kann auch versuchen, für $Northing einen Ort auf der oberen Kante der Grafik zu finden (z.B. Breitengrad von List auf Westerland) und für $Easting einen Ort am linken Rand (irgendetwas westlich von Aachen, der Längengrad wird benötigt). Über die Website www.worldmap.com lassen sich die Koordinaten für diese Orte ermitteln. Noch besser: Die angezeigte Karte so weit verschieben, dass die Grenze sichtbar wird und auf diese Klicken. Es werden nun der Breiten- und Längengrad für den angeklickten Punkt angezeigt. Das Ergebnis ist aber nur verwendbar, wenn die Deutschlandkarte so geschnitten ist, daß die Grenzen von Deutschland sehr nahe am Rande der Grafik liegen. Manchmal kann es günstig sein, die Grafik derart zu beschneiden und später entsprechende "Margins" vorzusehen.
Der Wert für $VertiGPx (Grad pro Pixel in der Vertikalen) kann aus den Angaben "Hoehe der Grafik in Pixel" geteilt durch "Hoehe dieser Strecke in der Natur in Grad". Letzteres läßt sich an einer guten Deutschlandkarte ablesen und errechnen bzw. über die Lokalisierung zweier Orte am Rand der Karte errechnen. Den nördlichen Punkt haben wir mit List schon gefunden. Die Differenz zur Lage von z.B. Oberstorf (Breitengrad) ergibt die Höhe. Analog dazu ist der Wert $HoriGPx für "Grad pro Pixel" in der Horizontalen zu errechnen. Hierzu benötigt man neben der Position von Aachen noch die Position eines Punktes bei Aachen (jeweils Längengrad).
Wenn das Ergebnis eine sehr kleine Dezimalzahl ist, z.B. 0,012345 oder 0,0101, so ist das richtig. Das ist die richtige Größe. Ein Ergebnis von 0,01 sagt ja aus, daß ein Pixel meiner Grafik ein Hunderstel Grad darstellt. Diese Werte sind ja so etwas wie der Maßstab der Karte.
Weil die Grade auf der Vertikalen (das sind die Breitengrade) immer genau den gleichen Abstand haben (111,111 km), ist die Left-Position des Punktes genau berechnet worden, gleichgültig wo sich der Punkt auf der Karte befindet. Bei der Berechnung der horizontalen Position ist das nicht der Fall, weill hier die Abstände nach Norden hin abnehmen und damit zumeist auf den Karten verzerrt dargestellt werden. Am Nordpol betragen die Abstände Null. Aber die Ungenauigkeit macht sich nur in den oberen Ecken der Karte bemerkbar.
Ich habe die Details auf der folgenden Seite mit einer Testkarte genau beschrieben.
Meeresgeo-Online: Erläuterungen zur Anordnung der Längen- und Breitengrade auf der Erdkugel
Worldatlas.com - Landkarten (weltweit) als Grafik http://worldatlas.com/aatlas/world.htm