Pickpoint

Markup: {{pickpoint}}

Quick start

The example below, running in the Mappia calculator - click it to run it live. Full-size picture

  1. Run it

    Click the picture: the map opens right here and runs the example. Nothing is saved, and nothing to install.

  2. Try it
    • Click a state on the map: its first four attributes appear in a notification.
    • The switch turns off after the click; turn “Click a state on the map” on again to pick another state.
  3. 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.

Key parameters

ParameterExampleWhat it does
onMarkonPickedName of a function in functions, called after each click with evt.features[mapIndex]: what each map holds at that point.
onefeaturetrueKeep only the last picked point. Without it, each click adds to the selection and clicking a picked feature again removes it.
unselectfalseBy default the tool switches itself off after each click; unselect=false keeps it on for several clicks.
checkedtrueStart with the tool switched on, so the first click on the map already picks.
idpick_stateNames the tool: inputs.id["pick_state"] holds the selection; read it with getAttributes(mapIndex) in beforeCalc.
labelRegion ${Name}Text drawn on the map next to each picked feature; ${attribute} is replaced by that feature’s value.

Every parameter, with its type and default, is in the reference at the end of this page.

Complete example

The query 24 lines · runs as is
// PickPoint: click the map to pick a feature; onMark receives the attributes of every map at
// that point (evt.features[mapIndex][i].data). onefeature keeps a single picked point.
[
  {
    title: "Pick a state",
    name: "CSR:estados",
    source: "calculate",
    opacity: 0.6,
    visibility: true,
    paramsButtonConfig: [{ type: "query", pressed: true }],
    descriptionHtml:
      "{{pickpoint|id=pick_state|text=Click a state on the map|checked=true|onefeature=true|geometryColor=#27ae60|onMark=onPicked}}",
    functions: {
      onPicked: function (evt) {
        var feature = evt.features && evt.features[0] && evt.features[0][0];
        if (!feature) return;
        var data = feature.data;
        ExtjsUtils.ALERTIFY.log(Object.keys(data).slice(0, 4).map(function (key) {
          return "<b>" + key + "</b>: " + data[key];
        }).join("<br>"));
      },
    },
  },
];

Customize it

Read what was picked

onMark receives one object per click:

  • evt.type is "add" when the click picked something and "remove" when it unpicked it.
  • evt.features[i] is what map i of name returned at that point: an array whose first entry has the attributes in .data. It is empty on a removal.

Inside onMark, this is the tool, so this.value.getAttributes(i) lists the attributes of every picked point on map i, in click order ({} where the click hit nothing on that map). runOnClick is an alias of onMark; when you write both, onMark wins.

Use the selection in the calculation

The layer recalculates after every click, once every map has answered, so beforeCalc always sees the current selection:

beforeCalc: function (inputs) {
  var picked = inputs.id["pick_state"].getAttributes(0); // one object per picked point
  var names = picked.map(function (attrs) { return attrs.name; }); // an attribute of your map
  // use the plain values here, e.g. to swap a map with this.changeLayers(...)
}

Turn the selection into plain values in beforeCalc. Never hand the tool’s value itself to expression: it holds map features, and expression runs in a worker that only receives plain data (see the execution model).

Change what the tool draws

  • geometryColor=#FF00FF colours the picked geometry; without it each click gets a random colour.
  • markLayerInd=1 chooses which map of name has its clicked geometry drawn.
  • pointVisibility=false hides the marker at the clicked point; lat=-15.8|lon=-47.9 places it before the first click.
  • text=... is the label of the switch. Without it, the switch shows the coordinates of the last click.
  • notify=false hides the “click on the map” notification shown when the tool is switched on.

Control it from code

  • Ext.getCmp("pick_state").toggle(true) switches the tool on, false off; no argument inverts it.
  • inputs.id["pick_state"].removeAll() clears the selection, for example from a {{button}} handler (there this is the layer: this.getInputs().id["pick_state"]). removeAttribute(index) removes one picked point.
  • getPointPos() gives [lon, lat] of the last click, in degrees.
  • searchAttribute(mapIndex, "code", "3106200") returns the attributes of a picked feature whose attribute matches, or null.

Charts from picked values

Highcharts is loaded on the map pages. Put a container such as <div id="pick_chart" style="height:220px"></div> in descriptionHtml and draw or update the chart from onMark. The pattern is on the Charts page.

Pitfalls

  • The tool asks the map server what lies under the click, so onMark runs a moment after the click, once every map in name has answered.
  • The tool lives on a source: "calculate" layer, as in the example, and queries every map in name.
  • Write callbacks as regular functions, not arrow functions: the tool sets this for them.

Real maps that use it

PickPoint from map to analyse

PickPoint from map to analyse

PickPoint from map to analyse

AMAZONES - Brazil nut

AMAZONES - Brazil nut

AMAZONES - Fire

AMAZONES - Fire

AMAZONES - Non-timber rubber

AMAZONES - Non-timber rubber

X-ray of the CAR - Forest Code balance per property

X-ray of the CAR - Forest Code balance per prop...

Reference: every parameter

Generated from the platform source. Every entry, searchable, is in the API reference; the raw data is api.json. Open an entry for its description, parameters and example; # links to it.

pickpoint · pick a point on the map (input)

PickPoint33 entries

Written in a layer's descriptionHtml as {{pickpoint|parameter=value|...}}

Creates an input that allows users to interact with the real cell or feature value at any position.

The returned values are from the original mal to the selected point,
in case of RASTER is returned a cell value, in case of shapefile the geometry is returned too.
Usage: {{pickpoint}}
View the complete PickPoint API here

checked

Boolean= false# Defines if Pickpoint should start selected.

Defines if Pickpoint should start selected. Set it true to start it enabled, false otherwise.

|checked = false|

fieldLabel

String# Sets the label for the 'pickpoint' button widget.

Sets the label for the 'pickpoint' button widget.

'Pick a point coordinate (Lat,Lon)'

geometryColor

String= undefined# If defined sets a color to use when drawing a geometry by this tool.

If defined sets a color to use when drawing a geometry by this tool. Otherwise a random color will be used at each interaction.

|geometryColor=#FF00FF|

getAttributes

function(mapIndex) : Array.<Object># Returns the attributes of every selected point for one of the layers of the composed map: one object per selection (in click order) holding the feature data of that layer, or {} when the click …

Returns the attributes of every selected point for one of the layers of the composed map: one object per selection (in click order) holding the feature data of that layer, or {} when the click hit nothing on it (e.g. a raster). This is the usual way to read the selection in beforeCalc.

mapIndex Number
0-based index of the layer inside the composed layer (name order).

Returns Attribute objects of the selected features on that layer.

beforeCalc: function(inputs) {
    var picked = inputs.id['property_pick'].getAttributes(1);
    var names = picked.map(function(attrs) { return attrs.Name; });
}

getLastEvent

function() : OpenLayers.Event|null# Returns the map click event handled by the last selection (its type is set to add or remove), or null before the first click.

Returns the map click event handled by the last selection (its type is set to add or remove), or null before the first click. Use evt.xy for the pixel and ExtjsUtils.COORDINATE.getLatLong(evt) for the coordinate.

Returns The last handled click event.

var evt = inputs.id['property_pick'].getLastEvent();

getPointPos

function() : Array.<Number># Returns the geographic position of the last clicked point (the marker), in the map's desired projection (normally EPSG:4326 — longitude, latitude).

Returns the geographic position of the last clicked point (the marker), in the map's desired projection (normally EPSG:4326 — longitude, latitude).

Returns [x, y] — longitude and latitude of the last click.

var lonLat = inputs.id['property_pick'].getPointPos(); // [-56.07, -4.04]

iconCls

String= cmn-toggle-icon# Defines the CSS class of the toggle switch icon; replace the default to restyle the switch.

Defines the CSS class of the toggle switch icon; replace the default to restyle the switch. labelBefore=true places the text before the switch, and inputValue sets the DOM value of the checkbox input (both passed through to the checkbox).

|iconCls=my-toggle-icon|

id

String# Defines the id of the tool (required).

Defines the id of the tool (required). It is the key used in inputs.id[ID] and the id of the checkbox component (Ext.getCmp(id)), so it must be unique in the page.

|id=property_pick|

inputValue

String# Defines the DOM value attribute of the underlying checkbox input (useful when the tool is inside an HTML form).

Defines the DOM value attribute of the underlying checkbox input (useful when the tool is inside an HTML form). It does not affect what inputs.id[ID] holds.

|inputValue=pick|

label

String# Defines a text template drawn on the map next to each selected feature.

Defines a text template drawn on the map next to each selected feature. ${attr} placeholders are replaced by the attribute values of the clicked feature (vector layers only; a raster cell has no attributes). Without it no label is drawn.

|label=Region ${Name}|

labelBefore

Boolean= false# Set true to render the text label before (left of) the toggle switch instead of after it.

Set true to render the text label before (left of) the toggle switch instead of after it.

|labelBefore=true|

lat

Number= 0# Defines the initial latitude (EPSG:4326, decimal degrees) of the marker shown when the tool is activated, before any click.

Defines the initial latitude (EPSG:4326, decimal degrees) of the marker shown when the tool is activated, before any click. Use it with lon; default 0.

|lat=-4.0396|lon=-56.07422|

lon

Number= 0# Defines the initial longitude (EPSG:4326, decimal degrees) of the marker shown when the tool is activated, before any click.

Defines the initial longitude (EPSG:4326, decimal degrees) of the marker shown when the tool is activated, before any click. Use it with lat to start on a point of interest; default 0.

|lat=-4.0396|lon=-56.07422|

markLayerInd

Number# Defines by layer index which one to draw its geometry when a click event happens.

Defines by layer index which one to draw its geometry when a click event happens. (0-indexed)

|markLayerInd = 0|

movePoint

function(evt)# Moves the marker of the last click to the position of a map mouse event.

Moves the marker of the last click to the position of a map mouse event. The tool calls it on every click; call it yourself only to relocate the marker from a synthetic event.

evt OpenLayers.Event
Map mouse event carrying the pixel position in evt.xy.
this.getInputs().id['property_pick'].movePoint(evt);

notify

Boolean= true# Set false to prevent the notify messages from appear (the "click on the map..." notification shown when the tool is activated).

Set false to prevent the notify messages from appear (the "click on the map..." notification shown when the tool is activated).

|notify=false|

onMark

function# Callback function called after clicking on a feature with this 'pickpoint' widget, once the feature info of every layer of the composed map has been received.

Callback function called after clicking on a feature with this 'pickpoint' widget, once the feature info of every layer of the composed map has been received. this is the pickpoint checkbox (or scope), so this.value is the PointAttributeManager. The name is resolved as a key of the layer functions object, then as a global function, then as inline function text.

eventAndProperties Object
A object with {mouse, type, features} passed into the callback function: - mouse: {PointerEvent} The mouse click event. - type: {String} 'add' when the click selected features, 'remove' when it unselected them. - features: {Array<Array<Object>>} One array per layer of the composed map with the feature(s) found at the click (empty on removal).
{ ...
 "descriptionHtml": "{{pickpoint|id=ANY_UNIQUE_ID|onMark=onMarkCallback}}",
  functions: {
    onMarkCallback: function(event) {
      for (var iLayer=0; iLayer < event.features.length; iLayer++) {
        for (var iFeature=0; iFeature < event.features[iLayer].length; iFeature++) {
          console.log(event.features[iLayer][iFeature].data);
        }
      }
    }
  }
 ...
 }

onefeature

boolean# Defines if PickPoint should keep only the last feature selected.

Defines if PickPoint should keep only the last feature selected. Set it true to keep only the last one, false otherwise.

|onefeature = false|

pointVisibility

Boolean= true# Defines if Pickpoint should show where the last click was.

Defines if Pickpoint should show where the last click was. Set it true to show, false otherwise.

|pointVisibility = false|

removeAll

function()# Clears the whole selection: every selected feature is removed from the map and from the list returned by getAttributes.

Clears the whole selection: every selected feature is removed from the map and from the list returned by getAttributes. Typical use: a "Clear" button handler, followed by a recalculation.

functions: {
    clearSelection: function() {
        this.getInputs().id['property_pick'].removeAll();
    }
}

removeAttribute

function(index)# Removes one selection (by its position in the getAttributes list) from the map and from the selection list.

Removes one selection (by its position in the getAttributes list) from the map and from the selection list. An invalid index changes nothing.

index Number
0-based index of the selection to remove (same order as getAttributes).
var pick = inputs.id['property_pick'];
for (var i = pick.getAttributes(1).length - 1; i >= 0; i--) {
    if (!pick.getAttributes(1)[i].Name) pick.removeAttribute(i);
}

runOnClick

function# Alias of onMark, kept so the pickpoint accepts the same callback name as the other map tools (hoverpixel, summedarea, areaintegral).

Alias of onMark, kept so the pickpoint accepts the same callback name as the other map tools (hoverpixel, summedarea, areaintegral). When both are written, onMark wins. See {@link PickPoint.onMark} for the callback signature.

|runOnClick=onMarkCallback|

runOnHover

function# Defines a callback function to run when clicking at the map.

Defines a callback function to run when clicking at the map.

Defines a callBack with following parameters function(mouseEvt, coordinates) --mouseEvt: {MouseEvent} Mouse hover event. --coordinates: {Openlayers.LatLon} Coordinate of the cursor over the map. PS: Can access the layer itself using the 'this' keyword.

runOnHoverOutside

function# True to run the callback function even when hovering outside of the layer, False to disable.

True to run the callback function even when hovering outside of the layer, False to disable. (Default False)

scope

Object# Defines the object used as this inside the onMark/runOnClick callback.

Defines the object used as this inside the onMark/runOnClick callback. By default it is the pickpoint checkbox component (so this.value is the PointAttributeManager). From the markup it can only reference an element created earlier in the same description, with the nested getid form.

|scope=getid=report_btn|

searchAttribute

function(mapIndex, propName, value) : Object|null# Finds, among the selected features of one layer, the first whose attribute propName equals value and returns its attributes.

Finds, among the selected features of one layer, the first whose attribute propName equals value and returns its attributes. Useful to check whether a given feature is already selected.

mapIndex Number
0-based index of the layer inside the composed layer.
propName String
Name of the attribute to compare.
value *
Value the attribute must have (compared with ==).

Returns The attributes of the matching selection, or null when none matches.

var found = inputs.id['property_pick'].searchAttribute(1, 'Code', '3106200');

setFeatureVisibility

function(state, feature)# Adds a feature to, or removes it from, the auxiliary vector layer where the tool draws its selections.

Adds a feature to, or removes it from, the auxiliary vector layer where the tool draws its selections. Lets a callback draw extra geometries (an OpenLayers.Feature.Vector) with the selection, or hide one of the selected features without forgetting it.

state Boolean
true to add (show) the feature, false to remove it.
feature OpenLayers.Feature.Vector|Array.<OpenLayers.Feature.Vector>
Feature(s) to add or remove.
inputs.id['property_pick'].setFeatureVisibility(true, new OpenLayers.Feature.Vector(geometry));

setPointVisibility

function(state)# Shows or hides the marker drawn at the last clicked position (the same marker controlled by the pointVisibility parameter).

Shows or hides the marker drawn at the last clicked position (the same marker controlled by the pointVisibility parameter).

state Boolean
true to show the marker, false to hide it.
inputs.id['property_pick'].setPointVisibility(false);

text

String# Defines the text shown next to the toggle.

Defines the text shown next to the toggle. When omitted the label shows the coordinate of the last click, (lat, lon), and is updated at every click.

|text=Click on the map to select an area|

toggle

function(forceState)# Activates or deactivates the pick mode from code (same as clicking the switch): the map cursor, the click listeners and the marker follow the new state.

Activates or deactivates the pick mode from code (same as clicking the switch): the map cursor, the click listeners and the marker follow the new state. Call it on the checkbox component (Ext.getCmp(id)). Without an argument the state is inverted.

forceState Boolean
true to activate picking, false to deactivate; omit to invert.
Ext.getCmp('property_pick').toggle(true);

togglePoint

function(pointFeatures, evt) : Object# Adds a set of features (one array per layer of the composed map, as returned by GetFeatureInfo) to the selection, or removes it when the same features were already selected.

Adds a set of features (one array per layer of the composed map, as returned by GetFeatureInfo) to the selection, or removes it when the same features were already selected. With onefeature=true the previous selection is cleared first. The tool calls it after every click; the returned object is what onMark receives.

pointFeatures Array.<Array.<OpenLayers.Feature.Vector>>
Features found at the click, indexed by layer.
evt OpenLayers.Event
The click event that originated the selection.

Returns {mouse, type, features} — the event, 'add' or 'remove', and the features added (empty on removal).

unselect

Boolean= true# Defines if Pickpoint will be automatically disabled after each click.

Defines if Pickpoint will be automatically disabled after each click. Set it true to automatically disable, false otherwise (write unselect= or unselect=false to keep the tool active for several clicks).

|unselect = true|

value

Object# Value stored in inputs.id[ID]: the PointAttributeManager of the tool, the object that keeps the selected features.

Value stored in inputs.id[ID]: the PointAttributeManager of the tool, the object that keeps the selected features. Read it with getAttributes(mapIndex), searchAttribute(...), getPointPos(), getLastEvent(), and change it with removeAll(), removeAttribute(index), setPointVisibility(state), setFeatureVisibility(state, feature) (all listed in this group). The layer recalculates on the widget onmark event, fired after every click once the feature info of all layers arrived — so beforeCalc always sees the updated selection. The object holds map features, so do not send it to expression (WebWorker); extract plain values in beforeCalc.

{{pickpoint|id=property_pick|text=Select a property|markLayerInd=1|unselect=}}
beforeCalc: function(inputs) {
    var codes = inputs.id['property_pick'].getAttributes(1).map(function(a) { return a.Code; });
    this.changeLayers({name: 'CSR:properties', styles: codes.length ? 'highlight' : '', index: 1});
}

Highcharts · charts

Highcharts1 entry
Highcharts is a library used to easly create interactive charts.
Usage: (Highcharts.chart(DOM_ID, {});)
Highcharts JS has a complete set of examples and a nice documentation that can be accessed here.

chart

function(renderTo, options) : Object# Highcharts is loaded by the calculator and editor pages, so a query can call Highcharts.chart(...) without loading anything: put a container in the layer's descriptionHtml and create the chart …

Written as Highcharts.chart

Highcharts is loaded by the calculator and editor pages, so a query can call Highcharts.chart(...) without loading anything: put a container in the layer's descriptionHtml and create the chart once the panel exists - in onInputsReady, in beforeCalc or in a widget handler - then update it as results arrive instead of recreating it. ExtjsUtils.HIGHCHART.getById(id) gives the chart back from the container's id, which is what makes the update possible from another callback.

The bundled build covers the standard chart types plus highcharts-more. Extra modules are loaded on demand with AsyncLoader.loadScriptOnce (see the Sankey entry).

renderTo String
Id of the container element declared in descriptionHtml.
options Object
The Highcharts configuration object.

Returns The chart instance.

descriptionHtml: '<div id="emissions_chart" style="height:220px"></div>',
functions: {
    drawChart: function (values) {
        var chart = ExtjsUtils.HIGHCHART.getById('emissions_chart');
        if (chart) { chart.series[0].setData(values); return; }
        Highcharts.chart('emissions_chart', {
            chart: { type: 'column' },
            title: { text: 'Emissions by year' },
            xAxis: { categories: ['2020', '2021', '2022'] },
            series: [{ name: 'Mt', data: values }]
        });
    }
}