p5.geo API reference
p5.geo targets p5.js 2.x. Coordinates are always latitude, longitude, in that order.
- createGeoMap()
- GeoMap
- geoPoints(), geoLines(), geoPolygons()
- p5.geo
- LatLon, View
- Passing numbers and strings
createGeoMap([options]) ⇒ GeoMap
Creates a map behind the canvas. Call it after createCanvas().
The canvas stays on top, transparent and click-through: the map handles dragging and scrolling, and mouseX, mouseY and p5's mouse events keep working. Call clear() (not background()) at the start of draw() so the map stays visible.
MapLibre GL JS is loaded automatically from jsDelivr, and attribution for the map data is shown automatically. The map can't be rotated or tilted, because shapes drawn on the canvas couldn't follow.
Kind: global function
| Param | Type | Default | Description |
|---|---|---|---|
| [options] | Object | ||
| [options.center] | Array.<number> | LatLon | [0, 0] | Where the map is centered, as [lat, lon] or { lat, lon } ({ lat, lng } also works). |
| [options.zoom] | number | 2 | Zoom level. See zoom. |
| [options.basemap] | string | Object | false | "'positron'" | 'positron', 'liberty' or 'bright' (keyless OpenFreeMap styles), a MapLibre style URL or style object, or false for no map: then nothing is added to the page and the GeoMap only converts coordinates. |
| [options.interactive] | boolean | true | Whether the map can be dragged and zoomed. With false, it stays where the sketch puts it. See interactive. |
| [options.mapOptions] | Object | Extra options for maplibregl.Map. | |
| [options.maplibregl] | Object | A MapLibre GL JS namespace to use instead of loading one. A global maplibregl is also used if present. |
Example
let myMap;
function setup() {
createCanvas(800, 600);
myMap = createGeoMap({ center: [35.68, 139.76], zoom: 12 });
}
function draw() {
clear();
const p = myMap.toScreen(35.6586, 139.7454); // Tokyo Tower
circle(p.x, p.y, 20);
}GeoMap
The geographic view of a sketch: where the map is centered, how far it is zoomed, and how latitude/longitude map onto the canvas. Create one with createGeoMap.
With a basemap (the default), MapLibre draws the map behind the p5 canvas and handles dragging and scrolling; the canvas stays transparent and click-through. With basemap: false, it only converts coordinates, with no map and no changes to the page.
Methods accept numeric strings as well as numbers (see Passing numbers and strings).
Kind: global class
- GeoMap
- .ready :
Promise.<GeoMap> - .maplibre :
Object - .toScreen(lat, [lon]) ⇒
p5.Vector|Array.<p5.Vector> - .fromScreen(x, y) ⇒
LatLon - .contains(item, x, y, [distance]) ⇒
boolean - .isMouseOver(item, [distance]) ⇒
boolean - .center([lat], [lon]) ⇒
LatLon|GeoMap - .zoom([level]) ⇒
number|GeoMap - .interactive([enabled]) ⇒
boolean|GeoMap - .fit(data, [options]) ⇒
GeoMap - .flyTo(lat, lon, [zoom]) ⇒
GeoMap - .saveCanvas([filename], [extension]) ⇒
Promise.<void> - .remove()
- .ready :
myMap.ready : Promise.<GeoMap>
Resolves to the GeoMap once the basemap has been created, or right away with basemap: false. There's no need to wait for it to draw: toScreen() works from the start.
Kind: instance property of GeoMap
myMap.maplibre : Object
The underlying maplibregl.Map, for anything p5.geo doesn't cover. null until ready resolves, and always null with basemap: false.
Kind: instance property of GeoMap
myMap.toScreen(lat, [lon]) ⇒ p5.Vector | Array.<p5.Vector>
Converts a latitude and longitude to a position on the canvas.
Also accepts { lat, lon } or [lat, lon], or an array of them, which returns an array of vectors. Use the array form for lines and polygon outlines, such as the path, outer and holes from geoLines and geoPolygons.
The basemap repeats the world sideways, so a single point goes on the copy of the world nearest the center of the canvas. An array is moved as one piece, so shapes never tear apart across the antimeridian. Works before the basemap has loaded.
Positions are measured from the top-left corner, like mouseX and mouseY. On a WEBGL canvas, where (0, 0) is the center, call translate(-width / 2, -height / 2) before drawing.
Kind: instance method of GeoMap
Returns: p5.Vector | Array.<p5.Vector> - The position on the canvas, or one per point.
| Param | Type | Description |
|---|---|---|
| lat | number | LatLon | Array.<number> | Array.<LatLon> | Latitude, or a point, or an array of points. |
| [lon] | number | Longitude, when lat is a number. |
Example
const p = myMap.toScreen(35.6586, 139.7454);
circle(p.x, p.y, 20);Example
beginShape();
for (const p of myMap.toScreen(country.outer)) vertex(p.x, p.y);
endShape(CLOSE);myMap.fromScreen(x, y) ⇒ LatLon
Converts a position on the canvas to a latitude and longitude.
Kind: instance method of GeoMap
| Param | Type |
|---|---|
| x | number |
| y | number |
Example
const here = myMap.fromScreen(mouseX, mouseY);
text(`${here.lat.toFixed(4)}, ${here.lon.toFixed(4)}`, mouseX, mouseY);myMap.contains(item, x, y, [distance]) ⇒ boolean
Whether a position on the canvas hits a shape, as drawn with toScreen(). What counts depends on what you pass:
- a polygon from geoPolygons (or an outline as an array of
{ lat, lon }): inside its outline and outside every hole; - a line from geoLines: within
distancepixels of it (default 5); - a point from geoPoints, or
{ lat, lon }: withindistancepixels of it (default 10). Pass the radius of the circle you draw.
For the mouse, use isMouseOver.
Kind: instance method of GeoMap
| Param | Type | Description |
|---|---|---|
| item | Object | Array.<LatLon> | A polygon, line or point. |
| x | number | |
| y | number | |
| [distance] | number | For lines and points, in pixels. |
Example
const touched = countries.filter((c) => myMap.contains(c, touches[0].x, touches[0].y));myMap.isMouseOver(item, [distance]) ⇒ boolean
Whether the mouse is over a shape, as drawn with toScreen(): inside a polygon, or within distance pixels of a line (default 5) or a point (default 10). Always false while the mouse is outside the canvas. See contains for what you can pass.
Kind: instance method of GeoMap
| Param | Type | Description |
|---|---|---|
| item | Object | Array.<LatLon> | A polygon, line or point. |
| [distance] | number | For lines and points, in pixels. |
Example
for (const country of countries) {
fill(myMap.isMouseOver(country) ? 'tomato' : 'white');
beginShape();
for (const p of myMap.toScreen(country.outer)) vertex(p.x, p.y);
endShape(CLOSE);
}Example
const p = myMap.toScreen(place);
circle(p.x, p.y, 20);
if (myMap.isMouseOver(place, 10)) text(place.properties.name, p.x + 12, p.y);myMap.center([lat], [lon]) ⇒ LatLon | GeoMap
Gets or sets the center of the map. With no arguments, returns the center. With center(lat, lon), center([lat, lon]) or center({ lat, lon }), moves the map there.
Kind: instance method of GeoMap
Returns: LatLon | GeoMap - The center, or the GeoMap when setting.
| Param | Type |
|---|---|
| [lat] | number | LatLon | Array.<number> |
| [lon] | number |
myMap.zoom([level]) ⇒ number | GeoMap
Gets or sets the zoom level. Each step doubles the scale; levels match MapLibre (the whole world is 512 pixels wide at zoom 0).
Kind: instance method of GeoMap
Returns: number | GeoMap - The zoom level (possibly fractional), or the GeoMap when setting.
| Param | Type |
|---|---|
| [level] | number |
myMap.interactive([enabled]) ⇒ boolean | GeoMap
Gets or sets whether the map can be dragged and zoomed with the mouse, touch and keyboard. A locked map can still be moved by code (center(), zoom(), flyTo(), fit()), and dragging on the canvas only reaches the sketch, such as mouseDragged(). Use it when the sketch handles the mouse itself; returning false from mousePressed() also stops mouse dragging, with a warning. Has no effect with basemap: false.
Kind: instance method of GeoMap
Returns: boolean | GeoMap - Whether the map is interactive, or the GeoMap when setting.
| Param | Type |
|---|---|
| [enabled] | boolean |
Example
// A map that stays put, so dragging draws instead.
myMap = createGeoMap({ center: [35.68, 139.76], zoom: 12, interactive: false });Example
// Press L to lock or unlock the map.
function keyPressed() {
if (key === 'l') myMap.interactive(!myMap.interactive());
}myMap.fit(data, [options]) ⇒ GeoMap
Centers and zooms so that all of the data is on the canvas.
Kind: instance method of GeoMap
| Param | Type | Default | Description |
|---|---|---|---|
| data | * | Anything geoPoints, geoLines or geoPolygons accept or return, or an array of { lat, lon }. | |
| [options] | Object | ||
| [options.padding] | number | 20 | Space to leave around the data, in pixels. |
| [options.maxZoom] | number | 16 | Upper limit, so a single point isn't zoomed in all the way. |
Example
countries = geoPolygons(await loadJSON('countries.geojson'));
myMap = createGeoMap({ basemap: false });
myMap.fit(countries);myMap.flyTo(lat, lon, [zoom]) ⇒ GeoMap
Animates to a place. Without a basemap, jumps there immediately.
Kind: instance method of GeoMap
| Param | Type | Description |
|---|---|---|
| lat | number | |
| lon | number | |
| [zoom] | number | Defaults to the current zoom level. |
myMap.saveCanvas([filename], [extension]) ⇒ Promise.<void>
Saves the canvas as an image file with the basemap under it, like p5's saveCanvas() (which would save the sketch alone). Waits for the map to finish loading first, and adds the map's attribution in the bottom-right corner.
Kind: instance method of GeoMap
Returns: Promise.<void> - Resolves once the download has started.
| Param | Type | Default | Description |
|---|---|---|---|
| [filename] | string | "'untitled'" | The file name, optionally with an extension. |
| [extension] | string | "'png'" | 'png', 'jpg' or 'webp'. |
Example
function keyPressed() {
if (key === 's') myMap.saveCanvas('my-map', 'png');
}myMap.remove()
Removes the map and puts the canvas back where it was. Also happens when the sketch's remove() is called.
Kind: instance method of GeoMap
geoPoints(data, [options]) ⇒ Array.<{lat: number, lon: number, properties: Object}>
Extracts points from a table, an array of objects, or GeoJSON.
- p5.Table from
loadTable(file, ',', 'header'): the latitude and longitude columns are found by name (lat,latitude,緯度/lon,lng,long,longitude,経度, not case-sensitive).propertiesholds every column of the row; values that look like numbers become numbers, others (such as"007") stay strings. Rows without a valid latitude and longitude are skipped, with a warning. - Array of objects: read the same way as table rows.
- GeoJSON (FeatureCollection, Feature or geometry): Point and MultiPoint geometries. A MultiPoint gives one item per point, sharing
properties.
Kind: global function
Throws:
ErrorIf no latitude or longitude column is found, ordataisundefined(for example, when the file hasn't loaded yet).
| Param | Type | Description |
|---|---|---|
| data | p5.Table | Array.<Object> | Object | |
| [options] | Object | |
| [options.lat] | string | Name of the latitude column, if it isn't found automatically. |
| [options.lon] | string | Name of the longitude column, if it isn't found automatically. |
Example
const table = await loadTable('places.csv', ',', 'header');
places = geoPoints(table);
// in draw():
for (const place of places) {
const p = myMap.toScreen(place);
circle(p.x, p.y, 10);
}geoLines(data) ⇒ Array.<{path: Array.<LatLon>, properties: Object}>
Extracts lines from GeoJSON: LineString and MultiLineString geometries. A MultiLineString gives one item per line, sharing properties.
Kind: global function
| Param | Type | Description |
|---|---|---|
| data | Object | GeoJSON: a FeatureCollection, a Feature or a geometry. |
Example
for (const line of lines) {
noFill();
beginShape();
for (const p of myMap.toScreen(line.path)) vertex(p.x, p.y);
endShape();
}geoPolygons(data) ⇒ Array.<{outer: Array.<LatLon>, holes: Array.<Array.<LatLon>>, properties: Object}>
Extracts polygons from GeoJSON: Polygon and MultiPolygon geometries. A MultiPolygon gives one item per polygon, sharing properties. outer is the outline; holes are cut-outs, to draw with beginContour() and endContour().
Kind: global function
| Param | Type | Description |
|---|---|---|
| data | Object | GeoJSON: a FeatureCollection, a Feature or a geometry. |
Example
beginShape();
for (const p of myMap.toScreen(country.outer)) vertex(p.x, p.y);
for (const hole of country.holes) {
beginContour();
for (const p of myMap.toScreen(hole)) vertex(p.x, p.y);
endContour();
}
endShape(CLOSE);p5.geo
The projection and data helpers as plain functions, independent of p5 and MapLibre. Available in sketches as p5.geo. They are strict: every argument must be a number, or they throw a TypeError.
Kind: global namespace
- geo :
object- .TILE_SIZE :
number - .MAX_LATITUDE :
number - .STYLES :
Object.<string, string> - .VERSION :
string - .containsLatLon(polygon, lat, lon) ⇒
boolean - .geoBounds(data) ⇒
Object - .lonToWorldX(lon) ⇒
number - .latToWorldY(lat) ⇒
number - .worldXToLon(x) ⇒
number - .worldYToLat(y) ⇒
number - .worldSize(zoom) ⇒
number - .project(lat, lon, view) ⇒
Object - .projectPath(points, view) ⇒
Array.<{x: number, y: number}> - .unproject(x, y, view) ⇒
LatLon - .fitView(bounds, width, height, [options]) ⇒
Object
- .TILE_SIZE :
p5.geo.TILE_SIZE : number
The width of the world in pixels at zoom 0. MapLibre uses 512, and matching it keeps zoom levels interchangeable.
Kind: static constant of geo
p5.geo.MAX_LATITUDE : number
The northern and southern limit of Web Mercator, in degrees. Latitudes beyond it are clamped.
Kind: static constant of geo
p5.geo.STYLES : Object.<string, string>
The basemap presets for the basemap option of createGeoMap: keyless OpenFreeMap styles, by name.
Kind: static constant of geo
p5.geo.VERSION : string
The version of p5.geo, such as "0.1.2", like p5.VERSION for p5.js. Handy for checking which version a sketch actually loaded, for example when a CDN or browser cache serves an older one.
Kind: static constant of geo
Example
console.log(p5.geo.VERSION);p5.geo.containsLatLon(polygon, lat, lon) ⇒ boolean
Whether a latitude and longitude is inside a polygon: inside its outline and outside every hole. Useful for questions about the data itself, such as which country an earthquake was in. Edges are treated as straight lines on the map, as they are drawn.
Polygons crossing the antimeridian need to be split there, as GeoJSON recommends.
Kind: static method of geo
| Param | Type | Description |
|---|---|---|
| polygon | Object | Array.<LatLon> | An item from geoPolygons, or an outline as an array of { lat, lon }. |
| lat | number | |
| lon | number |
Example
const inJapan = p5.geo.containsLatLon(japan, quake.lat, quake.lon);p5.geo.geoBounds(data) ⇒ Object
The bounding box of the data.
Kind: static method of geo
Returns: Object - null if the data is empty.
| Param | Type | Description |
|---|---|---|
| data | * | Anything geoPoints, geoLines or geoPolygons accept or return, or an array of { lat, lon }. |
p5.geo.lonToWorldX(lon) ⇒ number
Longitude → world units (0 at 180°W to 1 at 180°E).
Kind: static method of geo
| Param | Type |
|---|---|
| lon | number |
p5.geo.latToWorldY(lat) ⇒ number
Latitude → world units (0 at the northern limit to 1 at the southern limit).
Kind: static method of geo
| Param | Type |
|---|---|
| lat | number |
p5.geo.worldXToLon(x) ⇒ number
World units → longitude.
Kind: static method of geo
| Param | Type |
|---|---|
| x | number |
p5.geo.worldYToLat(y) ⇒ number
World units → latitude.
Kind: static method of geo
| Param | Type |
|---|---|
| y | number |
p5.geo.worldSize(zoom) ⇒ number
The width of the world in pixels at a zoom level.
Kind: static method of geo
| Param | Type |
|---|---|
| zoom | number |
p5.geo.project(lat, lon, view) ⇒ Object
Latitude/longitude → screen position. Uses the copy of the world nearest the center, so a point stays visible wherever the map is panned to (the basemap repeats the world sideways).
Kind: static method of geo
| Param | Type |
|---|---|
| lat | number |
| lon | number |
| view | View |
p5.geo.projectPath(points, view) ⇒ Array.<{x: number, y: number}>
Projects a line or polygon outline as one piece: the whole list moves to the copy of the world nearest the center. Projecting each point separately could tear shapes that straddle the far side of the world.
Kind: static method of geo
| Param | Type |
|---|---|
| points | Array.<LatLon> |
| view | View |
p5.geo.unproject(x, y, view) ⇒ LatLon
Screen position → latitude/longitude. Longitude is normalized to -180…180.
Kind: static method of geo
| Param | Type |
|---|---|
| x | number |
| y | number |
| view | View |
p5.geo.fitView(bounds, width, height, [options]) ⇒ Object
The center and zoom that fit a bounding box on a screen.
Kind: static method of geo
| Param | Type | Default | Description |
|---|---|---|---|
| bounds | Object | ||
| width | number | Screen width in pixels. | |
| height | number | Screen height in pixels. | |
| [options] | Object | ||
| [options.padding] | number | 20 | Space to leave on each side, in pixels. |
| [options.maxZoom] | number | 16 | Upper limit for the zoom. |
LatLon : Object
A latitude and longitude, in degrees.
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| lat | number | Latitude, from -90 (south) to 90 (north). |
| lon | number | Longitude, from -180 (west) to 180 (east). |
View : Object
What a map shows: its center sits in the middle of a width × height screen.
Kind: global typedef
Properties
| Name | Type | Description |
|---|---|---|
| lat | number | Latitude of the center. |
| lon | number | Longitude of the center. |
| zoom | number | Zoom level. |
| width | number | Screen width in pixels. |
| height | number | Screen height in pixels. |
Passing numbers and strings
GeoMap methods and the createGeoMap() options are forgiving, so that values read from a file can go straight in:
- Numeric strings become numbers.
myMap.toScreen('35.6586', '139.7454')works the same as with numbers, sotable.getString()results can be passed directly. This applies totoScreen,fromScreen,center,zoom,flyTo, thefitoptions, and thecenterandzoomoptions ofcreateGeoMap(). - Other values become
NaN, with a warning. An empty string,null,undefinedor text such as'abc'givesNaNand a console message naming the function and the argument, for examplep5.geo: toScreen() expected a number for lat, but got "abc".Each function and argument warns only once, so a mistake insidedraw()doesn't flood the console. Empty values are never treated as0. - They never throw.
The functions in p5.geo are strict instead: every argument must be a number, or they throw a TypeError naming the function and the argument. NaN counts as a number and passes through.
For bundlers and TypeScript, see Using with a bundler.