Quick start
The example below, running in the Mappia calculator - click it to run it live. Full-size picture
- Run it
Click the picture: the map opens right here and runs the example. Nothing is saved, and nothing to install.
- Try it
- Move the cursor over the map: a notification shows the elevation in metres and the position in degrees.
- Turn off “Show the elevation under the cursor” in the layer panel to stop the readings.
- Make it yours
Copy the query, change it - the key parameters are below - and run it again in the playground, or paste it into the Mappia editor to save it as your map.
- More ways to use it
Key parameters
| Parameter | Example | What it does |
|---|---|---|
runOnHover | onHover | Name of a function in functions, called on every mouse move with (layerVals, inputs, coordinates, event, lastInfo); this is the layer. |
runOnClick | onMapClick | The same, but called only when the user clicks the map. |
checked | true | Start with the tool switched on. By default the user switches it on in the layer panel. |
runOnHoverOutside | true | Also call runOnHover where the map has no data; layerVals is then null. runOnClickOutside does the same for clicks. |
text | Show the elevation under the cursor | Label of the switch in the layer panel. |
id | elevation_hover | Names the tool: inputs.id["elevation_hover"] holds the last click and hover positions, in degrees. |
Every parameter, with its type and default, is in the reference at the end of this page.
Complete example
The query 25 lines · runs as is
// Hoverpixel: reads the value of each map under the cursor and passes it to runOnHover
// (layerVals, inputs, coordinates); this = the layer.
[
{
title: "Elevation under the cursor",
name: "CSR:altimetria",
source: "calculate",
opacity: 0.7,
visibility: true,
paramsButtonConfig: [{ type: "query", pressed: true }],
descriptionHtml:
"{{hoverpixel|id=elevation_hover|text=Show the elevation under the cursor|checked=true|runOnHover=onHover}}",
functions: {
onHover: function (layerVals, inputs, coordinates) {
// coordinates come in the map's projection (metres): convert them to degrees to show
var degrees = coordinates.clone().transform(ExtjsUtils.JS.getMap().getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));
ExtjsUtils.ALERTIFY.log("Elevation: <b>" + Math.round(layerVals[0]) + " m</b><br>" +
degrees.lat.toFixed(2) + ", " + degrees.lon.toFixed(2));
},
},
expression: function (layersVals) {
return layersVals[0];
},
},
];More examples
Other ways to use Hoverpixel, each a complete query that runs as is - like the one above.
Values in the panel
As the pointer moves, runOnHover writes the values of two maps under it into a label of the panel - here forest biomass and elevation.
Click the picture to run it live. Full-size picture
The query 29 lines · runs as is
// Values in the panel: as the pointer moves, runOnHover writes the values of two maps under it into a label of the panel - here forest biomass and elevation.
// With two maps in name, runOnHover receives both values: layerVals[0] and layerVals[1].
// A place without data comes as an empty value.
[
{
title: "Biomass and elevation under the pointer",
name: "CSR:biomassa_baccini_bioma_am,CSR:altimetria",
source: "calculate",
opacity: 0.75,
visibility: true,
paramsButtonConfig: [{ type: "query", pressed: true }],
descriptionHtml:
"{{hoverpixel|id=readout_hover|text=Read the maps under the pointer|checked=true|hideLabel=true|runOnHover=showValues}}" +
"{{label|id=readout|text=Move the pointer over the map.}}",
functions: {
showValues: function (layerVals) {
var label = Ext.getCmp("readout");
if (!label) return;
function show(value, unit) {
return value === null || value === undefined || isNaN(value) ? "no data" : Math.round(value) + " " + unit;
}
label.setText("Biomass: " + show(layerVals[0], "t/ha") + " - elevation: " + show(layerVals[1], "m"));
},
},
expression: function (layersVals) {
return layersVals[0]; // the map shows the biomass
},
},
];Customize it
What the callback receives
layerVals: one value per map inname, in the same order. When the layer has anexpression, one more entry at the end holds its result for that pixel.inputs: the layer’s widget values;inputs.id[ID]works here.coordinates: the position in the map’s projection (metres), despite itslat/lonnames. For degrees usecoordinates.clone().transform(ExtjsUtils.JS.getMap().getProjectionObject(), new OpenLayers.Projection("EPSG:4326")), as the example does.event: the mouse event.lastInfo:{click, hover}, the previous click and hover as{lon, lat}in degrees. The current position is stored only after your callback returns, so usecoordinatesfor it.
Show the value in the panel instead of notifications
A notification on every mouse move gets noisy. Put an element in descriptionHtml and write into it:
descriptionHtml: "{{hoverpixel|id=elevation_hover|checked=true|runOnHover=onHover}}" +
"<p>Elevation: <b id='elevation_value'>-</b></p>",
functions: {
onHover: function (layerVals) {
var target = document.getElementById("elevation_value");
if (target) target.innerHTML = Math.round(layerVals[0]) + " m";
},
},
What the values are
The tool reads the colour each map draws under the cursor and turns it into a value through the map’s legend. On a classified map you get the value of the class: a range such as “10 - 20” gives its middle, 15, and a text class stays text. For the original cell values, read a map published as a raw map with an operation such as raw (see the property catalogue).
Recalculating the layer
Moving or clicking never recalculates the layer. inputs.id[ID] is always current, but nothing runs beforeCalc again. React inside runOnHover / runOnClick, which already receive the values, or trigger a recalculation yourself, for example with forceRecalc() on an InputManager.
Pitfalls
- Outside the map’s data the callbacks are not called, unless you set
runOnHoverOutside/runOnClickOutside; thenlayerValsisnull, so check it first. - The tool reads the maps of its own layer, a
source: "calculate"layer as in the example. It pauses while the layer is hidden and resumes in the same state when it is shown again. unselectonly changes the message shown when the tool is switched on; the tool never switches itself off after a click.- Write callbacks as regular
functions, not arrow functions:thisis the layer.