Kartenraster (Graticule), Abstände gemäss Kartenmassstab

Ich möchte das Kartenraster so einstellen, dass es in etwa mit dem Kartenmassstab zusammenpasst. Also wenn z.B. der Massstab in einem Zoomlevel 200m anzeigt, sollte das Raster 200mx200m sein. Frage, ist es möglich beim Massstab die angezeigte Länge abzufragen? Falls nicht, wie wird diese Länge berechnet? Gibt es andere Möglichkeiten, das Raster entsprechend einzustellen?

Wyo

berechnet wird die angezeigte Länge mit:
var topRounded=this.getBarLen(topMax); in CLASS_NAME:“OpenLayers.Control.ScaleLine”

Aber frag mich nicht, wie du den Wert da heraus bekommst.

gruß,
ajoessen

Wenn schon müsste ich den Code von ScaleLine in Graticule einbauen. Dazu kommt, dass Scale und Measure eigentlich den genau gleichen Code enthalten sollten, also läuft jede Änderung auf einen beträchtlichen Umbau hinaus.

Wyo

Moin,

OSM verwendet die Merkatorprojektion: Längengrade, die in der Realität nach Norden zusammenlaufen, werden bei dieser Projektion auseinandergezogen und auf konstantem Abstand gehalten. Deshalb entspricht eine fixe Anzahl Pixel am oberen und unteren Fensterrand unterschiedlichen Entfernungen.

Kann man sich ausrechnen lassen: http://www.netzwolf.info/kartografie/osm/tilebrowser?tx=8&ty=5&tz=4

OpenLayers.Control.Graticule benutzt für Länge und Breite die gleiche Rasterweite - in Winkelgraden gerechnet.
Am Äquator erzeugt das ein quadratisches Raster - nach Norden werden die Kästchen immer länglicher.
Weiterhin: bei konstantem Zoom ändert sich die Länge des Striches der Scaleanzeige, wenn man nach Norden/Süden geht.

Man kann natürlich einfach aus dem aktuellen Stand der Scale-Anzeige eine Rasterweite berechnen und dieses Raster vom Gratitude zeichnen lassen (braucht daselbst natürlich eine kleine Modifikation). Dann liegen die Rasterlinien allerdings auf krummen Werten, die Labels haben dann keinen Sinn mehr. Man muss sich zwischen (a) glatten Längen/Breiten-Angaben in Grad/Minuten und (b) glatten Werten für den Rasterabstand in Metern/Kilometern entscheiden.

Ich benutze deshalb das UTM-Gitter. Da liegen die Gitterlinien auf glatten Metern/Kilometern und ich kann trivial die Rasterweite anzeigen:

http://www.netzwolf.info/kartografie/openlayers/utmgrid

Der Nachteil: das Raster ist außer an den Bezugsmeridianen nicht mehr parallel zu Längen- und Breitengraden.

Gruß Wolf

Hi Wolf,

tolle Seiten hast auf Deiner HP zusammengestellt, Respekt!

Sehr informativ.

Ciao,
Frank

Ich habe jetzt das UMT ins Graticule Control eingebaut (http://www.orpatec.ch/osm/tools/main.php). Ich frage mich allerdings ob ich nicht gescheiter alles alte rauswerfen und ein reines UMT Control bauen soll. Dazu hätte ich aber noch ein paar Fragen:

  • für was ist eigentlich der Parameter gridPixelDistance?
  • würde es Sinn machen, die UTM-Koordinaten auch für die ScaleLine sowie das Measure Control zu verwenden? Schiesslich sollten alle Distanzen übereinstimmen.

Wyo

Moin,

Der bestimmt zusammen mit gridUnits, in welchem Raster das Grid gezeichnet wird:

Die Stelle im Code ist:

var unit = ur && ul ?
            this.getGridUnit ((ur.x-ul.x) / this.map.getSize().w * this.gridPixelDistance) : null;

gridPixelDistance ← in diesem Pixelabstand sind Rasterlinien erwünscht

ur.x ← Rechtswert (=X-Koordinate im UTM-System) der unteren rechten Ecke der Karte (in Metern)
ul.x ← Rechtswert (=X-Koordinate im UTM-System) der unteren rechten Ecke der Karte (in Metern),

(ur.x-ul.x) ← Breite des dargestellten Kartenausschnittes in Metern
this.map.getSize().w ← Breite des dargestellten Kartenausschnitts in Pixeln
(ur.x-ul.x) / this.map.getSize().w ← Breite eines Pixels in Metern :slight_smile:

(ur.x-ul.x) / this.map.getSize().w * this.gridPixelDistance ← in diesem Meterabstand sind Rasterlinien erwünscht.

Das ist normalerweise ein “krummer” Wert. Um glatte Werte kümmert sich die Funktion getGridUnit: die liefert zu einem “krummen” Wert den kleinsten Wert aus einer Liste erlaubter Werte, der größer ist als die Vorgabe. Damit ist “gridPixelDistance” der Mindestabstand der Gridlinien angegeben in Pixel.

Das Grid selber bildet die ScaleLine und macht sie überflüssig. Zumindest solange das Grid dargestellt wird: wenn der dargestellte Kartenausschnitt in Breite deutlich mehr als etwa 6° anzeigt, wird UTM unbrauchbar und ich schalte das Grid ab. Bei einer deutlich größeren Karte ist eine Scale-Line aber ohnehin irreführend: http://www.netzwolf.info/kartografie/osm/tilebrowser?tx=8&ty=5&tz=4

Abstände und Flächen sollte man weiterhin sphärisch oder bei hohen Genauigkeitsanforderungen ellipsoid direkt auf den geografischen Koordinaten rechnen.

Gruß Wolf

Bei zoom=11 wird bei mir folgendes angezeigt:

Gridabstand = 10000m
gridPixelDistance = 100
this.map.getSize().w = 660
ca 3 1/2 Gridfelder angezeigt

D.h. eingestellt ist “gridPixelDistance = 100” tatsächlich verwendet wird aber ca. 200px Abstand. Kann es sein, dass da doch irgendwas falsch ist?


    getGridUnit: function (distance) {
        var gridUnits = [50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000];
        for (var i=0; i<gridUnits.length; i++) {
            if (distance < gridUnits[i]) return gridUnits[i];
        }
        return null;
    },

Wenn in getGridUnit abgerundet statt aufgerundet wird, würde es vermutlich passen.

Wyo
http://www.orpatec.ch/osm/tools/main.php

Moin,

Du hast einen wichtigen Satz unterschlagen:

:slight_smile:

Lass Dir auch die Werte ul.x und ul.r bzw. ur.x-ul.x anzeigen. Die hängen von der geographischen Breite ab und lassen sich nicht alleine aus dem Zoomwert ableiten.

Das ist der Mindestabstand.

Wenn das ca. 200px z.B 198 Pixel bedeutet, und der nächste Wert auf der Liste der erlaubten Grids um den Faktor 2 kleiner wäre (das ist bei mir die kleineste Schrittweite, aber natürlich kann man die Liste auch feiner abstufen, so man mag), dann hätte das Grid mit dem nächstfeineren Grid einen Abstand von 99 px, was unter dem Minimum liegt.

Wenn Du ein Grid “so um 100px” herum wünschst, gib als Minimum 70 an.

Alternativ kannst Du auch die getGridUnit-Routine so modifizieren, dass sie den Eintrag liefert, der “am nächsten dran” liegt.

Die Routine getGridUnit wird aufgerufen mit einem Mindestabstand in Metern und liefert den ersten Wert aus der Liste, der größer ist als der übergebene Parameter. Achtung: die Liste enthält natürlich auch Werte in Metern! Ich hab diese Funktionalität in eine eigene Funktion gepackt, damit man die überschreiben kann, wenn man da eine andere Regelung wünscht.

Gruß Wolf