Nachladene, unendliche Karte / sorry für die Monsterfrage
Georg
- programmiertechnik
0 Sven Rautenberg0 Don P
Hallo,
leider sehe ich offensichtlich den Wald vor lauter Bäumen nicht mehr, daher möchte ich um eure Mithilfe bitten.
Ich versuche derzeit eine scrollende Landkarte ähnlich der Anzeige wie bei Google-Maps bzw. Earth zu realisieren,
d.h. mein bisheriger Denkansatz war so, das ich innerhalb eines absolutem DIVs mit einer festen Größe ein zweites, größeres DIVs positioniere was ich anschließend per JS durch Änderungen der X/Y-Werte (Top/Left) innerhalb des Eltern-DIVs bewege.
Dieses funktioniert auch wie gewünscht.
Die eigentliche Karte habe ich in Blöcken a 100 x 100 px geteilt und lasse dieses entsprechend in das zu bewegende DIV einblenden.
Mein Eltern-DIV hat derzeit die Größe 500 x 300 px (also 15 sichtbare Karten-Blöcke), das Karten-DIV habe ich derzeit in einer Größe von 700 x 500 (also insgesamt 35 Karten-Blöcke) gehalten, positioniert jeweils mit -100px so das ich also jeweils eine Blockreihe noch oben, unten, links und rechts scrollen kann.
Da ich die Karte unendlich (!) halten möchte, möchte ich bei erreichen des Endes des jeweiligen anzeigbaren Karten-Blocks (in der X- oder Y-Achse) via AJAX-Aufruf das Karten-DIV aktualisieren.
Um Kartenelemente beliebig (auch nachträglich) hinzuzufügen, habe ich die einzelnen Kartenblöcke mit X- und Y-Werte im Namen versehen, ausgehend jeweils von 10000 (Kartenmitte, 1. Karte - linke obere Ecke dementsprechend 9998 [H] und 9997 [V]).
Beispiel:
Kartenblock 01 = 10000_10000.jpg
Kartenblock 02 = 9999_10000.jpg
Kartenblock 03 = 10001_10000.jpg
Kartenblock 04 = 10000_10001.jpg
In dem Beispiel liegt Block 02 links neben Block 01, Block 03 rechts neben Block 01 und Block 04 direkt unter Block 01.
Soweit, sogut.
Nun beginnen aber meine Probleme:
a) Irgendwie (und warum auch immer) funktioniert das nachladen bzw. das errechnen der Blocknamen (und damit Positionen) nicht wie erwartet, d.h. mal springt das Teil in den x oder y - Positionen nicht eine Blockbreite sondern zwei...
b) beim Nachladen setzte muß ich das zu bewegende DIV ja wieder auf die Positionen X/Y - 100px setzten, das erzeugt einen sehr unschönen "Hüpf"-Effekt
c) es ist eine schei...-Arbeit die Kartenblöcke dementsprechend zu benennen (aber das ist nicht das wichtigste).
Meine Fragen wären also dementsprechend:
1.) Gibt es vielleicht eine andere, sinnvollerer Lösung (oder gar was funktionierendes fertiges, vielleicht in Flash ???)
2.) Wenn 1=nein; warum funktioniert das nachladen, bzw. die Block-Berechnung nicht wie erwartet...
bzw.:
3.) Ist mein Lösungsansatz ansich korrekt ??
Ich hoffe auf zahlreiche Responses :-)
MfG
Georg
PS:
Hier ein paar Auszüge aus meinem Code (nicht schlagen, ich weiß das der nicht sauber ist) - nur lesen wenns interessiert:
"Grund-"JS ("zustand" habe ich verwendet da die Funktion solange aufgerufen werden soll, wie der User die Maustaste gedrückt hält)
<script language="javascript">
var grundblock_h = 9998;
var grundblock_v = 9997;
function aktumap(wert_h,wert_v) {
// Erzeugt den AJAX-Request / Übergibt die errechneten neuen Grundwerte (Top/Left) und fügt die Response per inner.HTML in das Karten-DIV ein...
}
function moveleft(zustand) {
if(zustand=='2') {
if (window.aktiv) window.clearTimeout(aktiv);
return;
} else {
var posleft = parseInt(document.getElementById('dmap').style.left);
var nleft = posleft - 2;
if(nleft=="-200") {
grundblock_v = grundblock_v + 1;
document.getElementById('dmap').style.display = "none";
aktumap(grundblock_h,grundblock_v);
document.getElementById('dmap').style.left = "-100px";
document.getElementById('dmap').style.display = "block";
} else {
document.getElementById('pixleft').innerHTML = nleft;
document.getElementById('dmap').style.left = nleft + "px";
}
aktiv=setTimeout("moveleft('1')",100);
}
}
function moveright(zustand) {
// Wie moveleft nur das hier als "Schaltwert" 0 verwendet wird und der v-Wert minus 1 gerechnet wird
}
function moveup(zustand) {
if(zustand=='2') {
if (window.aktiv) window.clearTimeout(aktiv);
return;
} else {
var postop = parseInt(document.getElementById('dmap').style.top);
var ntop = postop - 2;
if(ntop=="-200") {
grundblock_h = grundblock_h + 1;
document.getElementById('dmap').style.display = "none";
aktumap(grundblock_h,grundblock_v);
document.getElementById('dmap').style.top = "-100px";
document.getElementById('dmap').style.display = "block";
} else {
document.getElementById('pixtop').innerHTML = ntop;
document.getElementById('dmap').style.top = ntop + "px";
}
aktiv=setTimeout("moveup('1')",100);
}
}
function movedown(zustand) {
// Wie moveup nur das hier als "Schaltwert" 0 verwendet wird und der h-Wert minus 1 gerechnet wird
}
</script>
Die Funktionsaufrufe habe ich per "onmousedown="moveleft('1')" onmouseup="moveleft('2')" realisiert.
Mein HTML-Code ist:
<div id="pelement" style="width: 500px; height: 300px; overflow: hidden; background-color:#000000; position:absolute; left: 257px; top: 172px;">
<div id="dmap" style="width: 700px; height: 500px; left: -100px; top: -100px; position:absolute; background-color:#000000;">
<table style="width: 700px" cellspacing="0" cellpadding="0">
<tr>
<td style="height: 100px; width: 100px;"><img src="images/maps/9998_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/9999_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10000_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10001_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10002_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10003_9997.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10004_9997.jpg" border="0"></td>
</tr>
<tr>
<td style="height: 100px; width: 100px;"><img src="images/maps/9998_9998.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/9999_9998.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/10000_9998.jpg" border="0"></td>
... und so weiter...
Meine PHP für das AJAX-Request:
$grundblock_h = strip_tags($_GET['h']);
$grundblock_v = strip_tags($_GET['v']);
$block_h01 = $grundblock_h + 0;
$block_h02 = $grundblock_h + 1;
$block_h03 = $grundblock_h + 2;
$block_h04 = $grundblock_h + 3;
$block_h05 = $grundblock_h + 4;
$block_v01 = $grundblock_v + 0;
$block_v02 = $grundblock_v + 1;
$block_v03 = $grundblock_v + 2;
$block_v04 = $grundblock_v + 3;
$block_v05 = $grundblock_v + 4;
$block_v06 = $grundblock_v + 5;
$block_v07 = $grundblock_v + 6;
$gzae = 0;
echo '<table style="width: 700px" cellspacing="0" cellpadding="0">
<tr>
<td style="height: 100px; width: 100px;"><img src="images/maps/'.$block_v01.'_'.$block_h01.'.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/'.$block_v02.'_'.$block_h01.'.jpg" border="0"></td>
<td style="height: 100px; width: 100px;"><img src="images/maps/'.$block_v03.'_'.$block_h01.'.jpg" border="0"></td>
<td style="height: 100px;
...und so weiter...
Moin!
Ich versuche derzeit eine scrollende Landkarte ähnlich der Anzeige wie bei Google-Maps bzw. Earth zu realisieren,
Dann verwende OpenLayers. http://www.openlayers.org/
Es gibt keinen guten Grund, das Rad ein drittes Mal (nach Google und OpenLayers) erfinden zu wollen.
- Sven Rautenberg
Hallo Sven,
Es gibt keinen guten Grund, das Rad ein drittes Mal (nach Google und OpenLayers) erfinden zu wollen.
wenn ich nun aber gern Räder baue?
Ich hab schon viele Sachen programmiert nur weil ich wissen wollte wie es funktioniert.
Counter, Gästebücher, Foren, Captchas usw. hatten alle keinen praktischen Nutzen für mich ausser das ich gelernt habe wie es geht und warum man auf Counter, Captchas und andere Spielereien verzichten kann.
Ich finde das Argument kommt zu oft zu schnell.
Grüße, Matze
Hallo,
anscheinend habe ich mich sehr undrücklich in meiner Fragestellung ausgedrückt, denn mit meinem Begriff "unendliche Karte" war nicht eine fixe (Erd-)Karte gemeint wo ich über Längen-/Breitendefination mit einem fixem Körper (Erde) arbeiten kann.
Von daher scheint openLayers für mein Problem nicht geeignet zu sein, da diese von der Erde als oberste Hirachie ausgeht, bzw. ich feste Start-/Enddaten verwenden müsste - zumal die Kartenerzeugung im Verhältnis zu meiner "Block-"Methode ja noch aufwendiger wäre...
Da ich um etwaige Drittlösungen gebeten hatte, trotzdem natürlich danke für diesen Hinweis.
An der Art und Anzahl der Antworten bis jetzt, gehe ich einmal davon aus, das es mir es wohl wirklich nicht erspart bleibt weiter herumzuexperimentieren - es wäre natürlich super, wenn noch andere Ideen oder Lösungen gepostet werden :-)
Gruss
Georg
Moin!
anscheinend habe ich mich sehr undrücklich in meiner Fragestellung ausgedrückt, denn mit meinem Begriff "unendliche Karte" war nicht eine fixe (Erd-)Karte gemeint wo ich über Längen-/Breitendefination mit einem fixem Körper (Erde) arbeiten kann.
Das ist mir schon klar, dass du keine komplette Weltkarte meinst, und noch nicht mal die reale Welt an sich.
Aber was spricht dagegen, deine Karte als Ausschnitt einer fiktiven Welt aufzufassen, die Kartenkacheln dementsprechend einem kugelorientierten Koordinatensystem zuzuordnen und OpenLayers dazu zu verwenden, den entsprechenden Ausschnitt dieser Kugel anzuzeigen.
Von daher scheint openLayers für mein Problem nicht geeignet zu sein, da diese von der Erde als oberste Hirachie ausgeht, bzw. ich feste Start-/Enddaten verwenden müsste - zumal die Kartenerzeugung im Verhältnis zu meiner "Block-"Methode ja noch aufwendiger wäre...
Ich habe mich mit der auf dem Server notwendigen Struktur der Kartenkacheln nicht auseinandergesetzt, aber mein Eindruck bislang war, dass es lediglich eine Transformation von Koordinaten des Kartenausschnitts in Längen- und Breitengrad hin zu entsprechenden Bild-URLs ist. Oder zur URL eines Skriptes, welches diese Ortskoordinaten als Parameter erhält, und dann das entsprechende Bild rausrückt - egal ob live generiert oder vorgefertigt abgespeichert.
Ich glaube immer noch, dass OpenLayers auch für dein Problem eine Lösung wäre. Zugegeben um den Preis, dass du dein Problem vermutlich leicht verändern müsstest, damit es zu der Lösung besser paßt. :)
- Sven Rautenberg
Hallo,
mein bisheriger Denkansatz war so, das ich innerhalb eines absolutem DIVs mit einer festen Größe ein zweites, größeres DIVs positioniere was ich anschließend per JS durch Änderungen der X/Y-Werte (Top/Left) innerhalb des Eltern-DIVs bewege.
Die eigentliche Karte habe ich in Blöcken a 100 x 100 px geteilt und lasse dieses entsprechend in das zu bewegende DIV einblenden.
In "das zu bewegende DIV"? Habe den ersten Satz so verstanden, das das Sichtfenster-DIV fix ist und sich nur die Karte darunter bewegt.
3.) Ist mein Lösungsansatz ansich korrekt ??
Mit solchen endlos-Geschichten hatte ich schon des öfteren zu tun. Dabei ist es m.E. programmiertechnisch am bequemsten, wenn man das zu scrollende Dingens als Array anlegt – in deinem Fall zwei, für X- und Y-Richtung – und dann die endlose Rotation einfach durch umstellen der Array-Elemente vornimmt. In javascript z.B. mit array.push(array.shift())
in eine Richtung und mit array.unshift(array.pop())
in die andere. Das hat den Vorteil, dass man nicht mit Zählern hantieren muss.
Wenn du aber nahtlose Übergänge und ohne Sprünge haben willst, wird es nicht ganz ohne Positionszähler gehen. Das könnte so klappen, dass z.B. immer das 2. und/oder 3. Array-Element links oben im im Sichtfenster-DIV liegt.
Die Benennung würde ich einfach mit x1.jpg, x2.jpg, x3.jpg... in X-Richtung und mit y1.jpg, y2.jpg, y3.jpg... in Y-Richtung vornehmen. Diese packst du in ein X-Array und ein Y-Array und gestaltest das Scrollen so, dass immer x[1] und y[1] links oben im Sichtfenster-DIV liegen (nach maximalem scrollen nach links bzw. oben). Sobald dort das komplette Bild in X- oder Y-Richtung sichtbar ist und weiter Richtung x[0] oder y[0] gescrollt werden soll, müssen die Array-Elemente rotiert und die Position der sichtbaren Array-Elemente geändert werden:
Wenn z.B. weiter um 1px nach links gescrollt wird, ist in x[1] dann das Bild von vorher x[0] mit entsprechendem horizontalem Versatz (99px nach links) und in x[2] das Bild von vorher x[1] mit Versatz +1px.
Am einfachsten geht das, wenn jedes Bild genau die Größe des sichtbaren Ausschnitts hat, denn es muss ja der Versatz von jedem sichtbaren Bild beim Rotieren schlagartig geändert werden.
Etwas schwierig zu erklären, aber vielleicht hast du das Prinzip ja verstanden.
Gruß, Don P