zoomTo Features

Hallo zusammen,

ich verwende folgenden Code, um Features (Linien, Punkte) dynamisch auf einer Karte zu platzieren.


var data=new OpenLayers.Layer.Vector("Linien",
                             {
                             loadend: function(){
                             
                             },
                             protocol:   new OpenLayers.Protocol.HTTP({ 
                                                       params: {mindist: 1e6, id: 123, startTimestamp: document.getElementById('start').innerHTML, stopTimestamp: document.getElementById('stop').innerHTML},
                                                       url:     "data/map.php",
                                                       format:  new OpenLayers.Format.GPX({extractWaypoints:true, extractAttributes:true}),
                                                      simplify: 0.1, 
                                          }),
                                          
                              styleMap:   new OpenLayers.StyleMap({ 
                                                       fillColor: "#B6CCDE",
                                                       fillOpacity:     0.5,
                                                       pointRadius:     6,
                                                       strokeColor:     "red", 
                                                       strokeWidth:     3, //Breite des äußeren Kreisrings
                                                       strokeDashstyle: "solid",
                                                       graphicZIndex: 1,
                                                       strokeOpacity:   0.7}),
                                                      
                              strategies: [new OpenLayers.Strategy.BBOX({ratio: 1, resFactor: 1.1})],
                              
                              projection: new OpenLayers.Projection("EPSG:4326"),
                              moveTo: function (bounds, zoomChanged, dragging) {

                            	if (zoomChanged) {
                              this.strokeColor = "white";
            			          	this.protocol.params.mindist        = 1000000 / Math.pow(2, this.map.getZoom());
                              this.protocol.params.imei_id        = document.getElementById('imei').value;
                              this.protocol.params.startTimestamp =  document.getElementById('start').innerHTML;
                              this.protocol.params.stopTimestamp  =  document.getElementById('stop').innerHTML;
            			            }

			                         OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
		}
                              });


Ich möchte, dass die Karte dann so einzoomed, dass alle Features darauf sichtbar sind.

Meine Idee war:


var dataExtent = data.getDataExtent();
map.zoomToExtent(dataExtent);


Aber da erhalte ich lediglich die Meldung, dass data nicht definiert sei, dabei handelt es sich dabei um das Vectorlayer.

Hat jemand eine Idee, wie ich in den Kartenbereich zoomen kann, dass die Features alle sichtbar sind?

Viele Grüße
Boris

Hi Boris,

entweder siehst du bei map.zoomToExtent(…) das data nicht, weil das in einer anderen Funktion ist und data keine globale Variable.

Oder du rufst map.zoomToExtent(…) zu früh auf. Sobald Du map.addLayer(data) sagst, fängt ja der Browser erst mal an, die Daten im Hintergrund zu holen. Wenn Du in der nächsten Zeile dann gleich zoomToExtent sagst, hat er noch keine Daten, auf die er zoomen könnte.

Deshalb baut man sowas in eine Funktion ein, die nach dem Ende des Ladens ausgeführt wird. Deine leere Stelle bei “loadend: function(){ }” wäre da sicher geeignet, ich mach mir das immer extra mit

var data=new OpenLayers.Layer....(...);
data.events.register('loadend', data, function(evt){map.zoomToExtent(data.getDataExtent())});
map.addLayer(data);

Allerdings verwirrt mich der Wunsch ein bisschen: Du wünschst dir mit "strategies: [new OpenLayers.Strategy.BBOX[/i]…", dass alle Elemente in der gerade im Browser sichtbaren BBOX runtergeladen werden. Ausserdem willst Du, dass der Browser auf das gerade geladene zoomt. Das könnte ein für den Nutzer unerwartetes Verhalten geben, wenn eines deiner Elemente über das Browserfenster rausragt, worauf der Browser dann zoomt, worauf er die BBOX nachlädt, was ihn zoomen lässt und die neue BBOX laden und zoomen und …

Grüße, Max

Mein nächster Versuch:

data =new OpenLayers.Layer.Vector("Linien",
                             {
                             loadend: function(){
                             map.zoomToExtent(data.getDataExtent());
                             },
                             protocol:   new OpenLayers.Protocol.HTTP({ 
                                                       params: {mindist: 1e6, id: 123, startTimestamp: document.getElementById('start').innerHTML, stopTimestamp: document.getElementById('stop').innerHTML},
                                                       url:     "data/map.php",
                                                       format:  new OpenLayers.Format.GPX({extractWaypoints:true, extractAttributes:true}),
                                                      simplify: 0.1, 
                                          }),

Es passiert nichts, auch kein Fehler in der Console.

Verwende ich deinen Schnippsel, springt er mir immer vor Afrika.

Ich weiß, mein Vorhaben klingt verwirrend, ich wähle unterhalb der Karte zwei Werte in einem Diagramm aus, im Hintergrund werden dann die Routen berechnet und erst dann soll die Route auf der Karte angezeigt werden. Er soll dann auf die Gesamtroute zoomen, aber verschiebt oder zoomt der User, sollen nur die Werte angezeigt werden, die sich in dem Abschnitt befinden.

Wenn Du beim Laden kein map.setCenter(…) angibst, springt der Browser zum Äquator. Dann lädt er die Objekte in data/map.php in der aktuellen bbox, die vermutlich gar keine enthält. Der Extent dieser nicht vorhandenen Objekte ist auch nicht vorhanden und der Browser bleibt beim Äquator.

Probiers mal am Anfang mit map.setCenter(…) und irgendeinem grosszügigen Ausschnitt. Europa im Zoomlevel 4 oder so. Dann könnte der Start klappen. Was beim verschieben passiert, lässt sich nicht vorhersagen…

Wenn ich mich richtig entsinne passiert das auch oder gerade wenn man die falsche Projektion verwendet. Dann werden alle Daten um die Koordinate 0/0 herum dargestellt und die Stelle liegt nun mal “unten links” von Afrika.

Gruss
walter

Supi, vielen Dank, max, dein Hinweis “war” es, dies klappt nun, die Karte zoomt genau auf den relevanten Abschnitt.

Nun habe ich aber ein Folgeproblem.
Der Nutzer kann in der Karte nicht mehr zoomen oder verschieben, da folgerichtig ein event darauf liegt, welches immer wieder in den relevanen Abschnitt zoomt.

Ich ging nun also davon aus, dass das Pendant zu data.events.register(’ einfach data.events.unregister(’ ist, aber dies scheint nicht der Fall.
Habt ihr da noch einen Hinweis für mich? Falsche Syntax? Oder habe ich noch was vergessen?

Eigentlich dachte ich das auch. Du kannst aber auch irgendwas innerhalb der Funktion abfragen,* if(zaehler<1){map.zoomToExtent(…);}* oder so. Und zaehler mit jeder zoomen hochzählen.