-
Notifications
You must be signed in to change notification settings - Fork 152
Home
We're doing our best to follow Semantic Versioning for version number guidelines. These docs are written against v1.0.0 and should be valid for all v1.x.y versions.
Modest Maps is as much a vocabulary for tiled maps as it is a code library. See ModestMapsNess for a more concise overview.
Please also play with the examples for hints on intended usage.
A Map
requires a DOM element, provider and optional dimensions
and event handlers. The simplest way to create one is in the window
onload handler with a TemplatedMapProvider
and the id of a div with width and height set.
// name of a div element:
var parent = 'map';
// defaults to Google-style Mercator projection, so works
// out of the box with OpenStreetMap and friends:
var template = 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png';
var provider = new com.modestmaps.TemplatedMapProvider(template);
// without a size, it will expand to fit the parent:
var map = new com.modestmaps.Map(parent, provider);
Alternatively you can specify a fixed size:
// name of a div element:
var parent = 'map';
// defaults to Google-style Mercator projection, so works
// out of the box with OpenStreetMap and friends:
var template = 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png';
var provider = new com.modestmaps.TemplatedMapProvider(template);
var dimensions = new com.modestmaps.Point(600,400);
var map = new com.modestmaps.Map(parent, provider, dimensions);
And you can also specify a provider with a more complex method of generating URLs:
// name of a div element:
var parent = 'map';
// defaults to Google-style Mercator projection, so works
// out of the box with OpenStreetMap and friends:
var provider = new com.modestmaps.MapProvider(function(c) {
var img = [ c.zoom, c.column, c.row ].join('/') + '.png';
return 'http://tile.openstreetmap.org/' + img;
});
var dimensions = new com.modestmaps.Point(600,400);
var map = new com.modestmaps.Map(parent, provider, dimensions);
To set the Location
of the center of the map use setCenter(location)
.
To set the zoom level use setZoom(number)
. Or use
setCenterZoom(location,number)
to set both the center and the zoom level at the same time:
map.setCenter(new com.modestmaps.Location(37.7749295, -122.4194155));
map.setCenterZoom(new com.modestmaps.Location(37.7749295, -122.4194155), 11);
map.setZoom(11);
To set the map to a location and zoom level that will show a given
bounding box (extent) or a set of points, use setExtent(locations)
and pass it an array of 2 or more Locations
:
var locations = [
new com.modestmaps.Location(37.7749295, -122.4194155),
new com.modestmaps.Location(37.8043722, -122.2708026),
new com.modestmaps.Location(37.8715926, -122.272747)
];
map.setExtent(locations);
You can query the map position using getCenter()
, getZoom()
and getExtent()
:
var locations = map.getExtent(); // returns an array of Locations
var loc = map.getCenter() // returns a single Location
var zoomLevel = map.getZoom();
Note that calling map.setCenter(map.getCenter())
should do
nothing, but calling map.setExtent(map.getExtent())
could result
in a zoom out to ensure that setExtent performs correctly.
To set the map size (e.g. in a window.onresize handler) use setSize
and pass it a point or two numbers:
// the following are equivalent:
map.setSize(new com.modestmaps.Point(600,400));
map.setSize(600,400);
Note that the map will automatically resize if you didn't supply initial dimensions in the constructor and your CSS specifies relative sizes such as percentages or ems.
Map
can report on several events using a simple callback system.
To be notified of map changes subscribe to some or all of the
following events: panned
, zoomed
, extentset
, centered
,
resized
, drawn
. Each callback will receive the current map as its first argument.
To make overlays that follow the map, or update parts of the page when the map changes, the simplest callback to register is 'drawn':
map.addCallback('drawn', function(m) {
// respond to new center:
document.getElementById('info').innerHTML = m.getCenter().toString();
});
Map also exposes a removeCallback
method for keeping things
tidy, and uses dispatchCallback
internally to notify listeners of changes.
We're considering changing to an extremely simple callback model with only one event (perhaps only the 'drawn' event). We'd welcome your feedback on this.
Map provides several different ways to change the current
center and zoom level, apart from setCenterZoom
and setExtent
.
Some of them are useful when wiring up map controls such as
zoomIn
and zoomOut
, that go in and out by whole zoom
levels, and panLeft
, panRight
, panDown
and
panUp
that move in 100px increments.
When responding to mouse-wheel or gesture zooming events
you'll probably want to use zoomByAbout
:
// Madrid
var madridLocation = new com.modestmaps.Location(40.4, -3.7);
// Madrid on screen:
var madridPoint = map.locationPoint(madridLocation);
// zoom in by one step, keeping SF in the same place on screen:
map.zoomByAbout(1, madridPoint);
When responding to mouse events, or scripting animation, you'll
probably want to use the relative functions zoomBy
and panBy
:
// zoom in by one step:
map.zoomBy(1);
// scroll by 50,50:
map.panBy(50,50);
To convert from geographic Locations to on screen Points, use map.pointLocation
and map.locationPoint
:
// Dijbouti
var l1 = new com.modestmaps.Location(11.7, 42.5);
// Dijbouti on screen:
var p1 = map.locationPoint(l1);
// some pixels in the map:
var p2 = new com.modestmaps.Point(100, 100);
// the geographic location of p2:
var l2 = map.pointLocation(p2);
There are also equivalent internal functions for converting
to/from coordinates: coordinatePoint(coord)
and pointCoordinate(point)
.
At time of writing, Map
also exposes several functions which
are only for internal use. We're working on moving the javascript patterns
we use for these objects so that these internal APIs don't leak
into your work. For the record, we don't expect you to use any
of the following methods (unless you're doing work on the
Modest Maps internals yourself, of course): getStats
,
enforceLimits
, draw
, getTileComplete
, requestRedraw
,
getRedraw
, createOrGetLayer
, checkCache
, getCenterDistanceCompare
.
If you're supplying your own image tiles for your map,
you'll need to know how to create layers and providers.
Usually these are supplied to the Map
constructor.
Layers are levels of tiles that can be added, removed, and rearranged on a map. Each layer has one provider, which delivers specific data to the layer, like tile URLs, based on map coordinates.
If you want to switch layers in response to a button
press, you can call map.setLayerAt
with a new layer instead.
The MapProvider
class expects a callback
function that can turn a Coordinate
into a URL string:
var provider = new com.modestmaps.MapProvider(function(c) {
var img = [ c.zoom, c.column, c.row ].join('/') + '.png';
return 'http://tile.openstreetmap.org/' + img;
});
The TemplatedMapProvider
is an easier interface to MapProvider
which
takes a string with attractive mustache syntax to generate tile URLs:
var template = 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png';
var provider = new com.modestmaps.TemplatedMapProvider(template);
The TemplatedMapProvider
also takes a template argument {S}
,
that replaces part of the URL with one of an array of strings. You
can use this for subdomains of a tile server.
var template = 'http://{S}tile.openstreetmap.org/{Z}/{X}/{Y}.png';
var subdomains = [ '', 'a.', 'b.', 'c.' ];
var provider = new com.modestmaps.TemplatedMapProvider(template, subdomains);
The TemplatedMapProvider
is similar to the OpenLayers.Layer.XYZ
class, or Leaflet's L.TileLayer
Providers also implement a few properties and functions that alter how
Modest Maps loads tiles (or does not load tiles) such as outerLimits
and
sourceCoordinate
, and the functions used by map to convert to and from
Locations and Coordinates: locationCoordinate(location)
and
coordinateLocation(coord)
.
new in 1.0.0
Layers wrap Providers and do much of the work of requesting and manages the tiles that Providers suggest.
// Create a new layer with OpenStreetMap tiles
var osmProvider = new com.modestmaps.TemplatedMapProvider('http://{S}tile.openstreetmap.org/{Z}/{X}/{Y}.png');
var osmLayer = new com.modestmaps.Layer(osmProvider);
// Change a layer's provider
layer.setProvider(newProvider);
Projections are used internally by Modest Maps providers to convert from Locations to Coordinates.
Internally, the rawProject
and rawUnproject
functions are the
pure mathematics of the operation (we use Wolfram Mathworld and Wikipedia
to find interesting projections). These are the only ones that
need overriding by subclasses. The project
and unproject
functions use these, and in turn are used by locationCoordinate
and coordinateLocation
which are then used by providers. You'll probably
just want to use the versions offered by Map
.
Modest Maps offers two projections out of the box: LinearProjection
and MercatorProjection
. The built-in providers all assume Mercator
is what you want, but this is easily overridden.
Transformations are used internally by Modest Maps projections to convert from one projection space to another, and apply any needed translations, rotations and scales to get everything lined up.
e.g. to transform from a Mercator projected Location in radians to a map Coordinate at zoom level 26, you could use the following Transformation:
var t = new com.modestmaps.Transformation(1.068070779e7, 0, 3.355443185e7,
0, -1.068070890e7, 3.355443057e7);
These magic numbers can be derived from three control points using some simple linear algebra. Modest Maps provides helpers for these. For example, to derive a similar Transformation to the above, but for a Coordinate at zoom level 0, use:
var pi = Math.PI;
var t = com.modestmaps.deriveTransformation(-pi, pi, 0, 0, pi, pi, 1, 0, -pi, -pi, 0, 1);
The Transformation
class then offers transform
and
untransform
methods that operate on Points
.
var point = new com.modestmaps.Point(x, y)
// Get a point between two other points, biased by `t`.
var p3 = com.modestmaps.Point.interpolate(p1, p2, t)
// Get the euclidean distance between two points
var d = com.modestmaps.Point.distance(p1, p2);
Point is a simple data object with x and y properties. It's most often used to represent pixel positions on screen or within the map.
var p1 = new com.modestmaps.Point(10, 20);
var p2 = new com.modestmaps.Point(20, 20);
// d is 10
var d = com.modestmaps.Point.distance(p1,p2);
// p3 is half way between p1 and p2: (15,20)
var amount = 0.5;
var p3 = com.modestmaps.Point.interpolate(p1,p2,amount);
var loc = new com.modestmaps.Location(latitude, longitude);
// Get the distance between two points, in
// meters, with a sphere of radius r meters (default 6378000)
var d = com.modestmaps.Location.distance(l1, l2, r)
// Get the interpolation of two points, biased by f,
// along the great circle
var l3 = com.modestmaps.Location.interpolate(l1, l2, f)
Location is similar to Point, but for geographic coordinates. It has lat and lon properties (and expects them in that order, unlike Point which works the other way around). It represents locations on the surface of the earth in degrees latitude and longitude. You can use a site like getlatlon.com to find the latitude and longitude of places by name.
// Create a new location at 30 latitude, 114 longitude (Xinjiezhen)
var loc = new com.modestmaps.Location(30, 114);
var coord = new com.modestmaps.Coordinate(row, column, zoom);
// Get a string key to refer to this coordinate
var key = coord.toKey();
// Get the whole-number coordinate that contains a potentially
// in-between coordinate
var container = coord.container();
// Get a copy of this coordinate
var copy = coord.copy();
// Navigation with coordinates
var zoomedTo = coord.zoomTo(5);
var zoomedIn = coord.zoomTo(1);
var pannedLeft = coord.left(1);
Coordinate is used internally to represent tiles, and the map state - so they have instance functions that let you do all of the navigation that you'd expect out of a map. It has row, column and zoom properties.
It also has several methods that help you navigate from one coordinate to
another: up
, right
, down
, left
, zoomTo
and zoomBy
. All return
a new Coordinate. Additionally, copy
can be used to clone a Coordinate
and container
can be used to obtain a Coordinate with floored row, column
and zoom for generating tile URLs.
Modest Maps assumes you want an interactive map for use in a desktop web
browser and automatically creates a com.modestmaps.MouseHandler
for dealing
with mouse drag, double click and wheel events.
If you create a map with an empty array in the fourth parameter it is then
up to you to write the interaction code and use functions like map.panBy
and map.zoomBy
to move the map in response to events:
// fourth argument is null, map will be static (no mouse actions):
var map = new com.modestmaps.Map(parent, provider, dimensions, null);
Event handlers are currently properties of the map (hence they are passed
into the constructor) but this will probably change with future versions
since they can exist quite happily away from the Map
internals.
Used internally for inheritance, com.modestmaps.extend
is sometimes
useful for implementing new projections and map providers. For example, to implement
var LinearProjection = function(zoom, transformation) {
// this is a bit like 'super'
com.modestmaps.Projection.call(this, zoom, transformation);
};
LinearProjection.prototype = {
rawProject: function(point) {
return new com.modestmaps.Point(point.x, point.y);
},
rawUnproject: function(point) {
return new com.modestmaps.Point(point.x, point.y);
}
};
com.modestmaps.extend(LinearProjection, com.modestmaps.Projection);
These are likely to change or be replaced with an existing toolkit
but are currently available for helping manage cross browser DOM event
handling and CSS style querying. For the record, they are cancelEvent
,
addEvent
, removeEvent
and getStyle
.
To respond to events in the map such as panning, zooming, see addCallback
.
The CallbackManager
and RequestManager
classes are used internally
and should not considered stable APIs.
The official Modest Maps namespace is com.modestmaps
, which is used
in these examples for correctness. This is aliased to MM
. If another
object wants to occupy MM
, one can call MM.noConflict()
and
Modest Maps will only inhabit its extended name, com.modestmaps
.