Moving around the map view
Unless you want to create a completely static map, without the controls required for the user to pan or zoom, you would like the user to be able to navigate and explore the map.
There can be situations when the controls are not enough. Imagine a web application where the user can make a search, such as Everest, and the application must find its location and fly to it. In this case, you need to navigate by code and not by using a control.
This recipe shows you some of the OpenLayers.Map
class methods that will allow you to improve the user's experience.
The application layout contains three main sections. At the top there is a label to show the current map center position and zoom level. It is automatically updated when the map is moved or the zoom is changed.
The map is in the center and there are a bunch of controls on the right to set and test the main map methods to interact with the view.
As you will see, the map has no control attached to it, so the only way to interact with it is through the right controls.
Note
We omit the HTML code necessary to create the application layout, so if you are interested in the HTML code you can take a look at the source code available on the Packt Publishing website.
How to do it...
Create an HTML file with OpenLayers dependencies.
Note
The HTML code to create the buttons and layout of the previous screenshot is extensive and not related to the goal of the book, so here we avoid writing it.
Add a
div
element to hold the map instance:<div id="ch1_moving_around" style="width: 100%; height: 500px;"></div>
Create a map instance. This time we specify a listener for some events that will update the center and zoom values of the label on top of the map:
var map = new OpenLayers.Map("ch1_moving_around", { controls: [], eventListeners: { "move": changeListener, "moveend": changeListener, "zoomend": changeListener } }); function changeListener() { var center = map.getCenter(); document.getElementById("center").innerHTML = "("+center.lon + " lon , " + center.lat + " lat)"; var zoom = map.getZoom(); document.getElementById("zoom").innerHTML = zoom + " level"; }
Add one layer and center the view:
var wms = new OpenLayers.Layer.WMS("OpenLayers WMS Basic", "http://vmap0.tiles.osgeo.org/wms/vmap0", { layers: 'basic' }); map.addLayer(wms); map.setCenter(new OpenLayers.LonLat(0, 0), 2);
Insert the code that will be executed by the button actions:
function moveByPx() { var x = dijit.byId('movebyxpix').get('value'); var y = dijit.byId('movebyypix').get('value'); map.moveByPx(x,y); } function moveTo() { var lon = dijit.byId('movetolon').get('value'); var lat = dijit.byId('movetolat').get('value'); var zoom = dijit.byId('movetozoom').get('value'); var force = dijit.byId('movetoforceZoomChange').get('checked'); var drag = dijit.byId('movetodragging').get('checked'); map.moveTo(new OpenLayers.LonLat(lon, lat), zoom, { forceZoomChange: force, dragging: drag }); } function setCenter() { var lon = dijit.byId('setCenterlon').get('value'); var lat = dijit.byId('setCenterlat').get('value'); var zoom = dijit.byId('setCenterzoom').get('value'); var force = dijit.byId('setCenterforceZoomChange').get('checked'); var drag = dijit.byId('setCenterdragging').get('checked'); map.setCenter(new OpenLayers.LonLat(lon, lat), zoom, { forceZoomChange: force, dragging: drag }); } function pan() { var x = dijit.byId('panxpix').get('value'); var y = dijit.byId('panypix').get('value'); var anim = dijit.byId('pananimate').get('checked'); var drag = dijit.byId('pandragging').get('checked'); map.pan(x,y, { animate: anim, dragging: drag }); } function panTo() { var lon = dijit.byId('panTolon').get('value'); var lat = dijit.byId('panTolat').get('value'); map.panTo(new OpenLayers.LonLat(lon, lat)); }
How it works...
To update the center and zoom level values at the top, we have instantiated the Map
object with some event listeners attached to it. Actually, the same listener function is attached to all three events:
var map = new OpenLayers.Map("ch1_moving_around", { controls: [], eventListeners: { "move": changeListener, "moveend": changeListener, "zoomend": changeListener } });
Within the
changeListener()
function we use map.getCenter()
, which returns an OpenLayers.LonLat
object, and map.getZoom()
to get the current values and update the top-left label.
function changeListener() { var center = map.getCenter(); document.getElementById("center").innerHTML = "("+center.lon + " lon , " + center.lat + " lat)"; var zoom = map.getZoom(); document.getElementById("zoom").innerHTML = zoom + " level"; }
For every button, an action is executed. They are responsible to get the required values and invoke a map
method.
The map.moveByPx()
method moves the map by a delta value specified in pixels. Note, it moves the map; it doesn't pan, so don't expect any effect.
function moveByPx() { var x = dijit.byId('movebyxpix').get('value'); var y = dijit.byId('movebyypix').get('value'); map.moveByPx(x,y); }
The map.moveTo()
method is similar to the previous one but moves the view to a specified position (instead of an increment) and is specified with an OpenLayers.LonLat
instance.
The map.setCenter()
method is similar to map.moveTo()
but it centers the view on the specified location.
Finally, there are two pan-related actions, which make nice smooth movements. The map.pan()
method moves the view with a pan effect specified by a pixel delta. The map.panTo()
method does something similar, it moves the view to a specified location.
See also
The Managing map's stack layers recipe
The Restricting the map extent recipe