Where to look. What you write in a layer is under Layers and Kinds of layer; in a group, under Groups; before the list, joined with &&, under Query setup; in the link, under Map links and embedding. Functions your code calls are the ExtjsUtils helpers, or the layer's own methods (this., under Kinds of layer).
property: a key you write · callback: a function you write and the platform calls · method: a function the layer has, called on this · helper: ExtjsUtils.NAME.member · setting: applies to the whole query · link parameter: ?name=value of a map link
Find anything: press / and type a name (opacity), the way code writes it (ExtjsUtils.ALERTIFY.confirmChoice, this.setCalculateLegend, {{slider, ?queryid) or a few words; Enter opens the entry. Every entry has a link (#) you can share. Not sure where something lives? Read Where to find it: layers, settings and links.
Layers: what you write in a layer
Not every key works on every kind: calculated, file and tile layers have a panel (descriptionHtml) and row buttons (paramsButtonConfig), a published map does not. Each entry says when it is limited to some kinds; what one kind adds is under Kinds of layer.
A layer that shows one published map:
Example
[
{
// The Layer name
title: 'My first layer!',
// The map that will be shown
name: 'CSR:altimetria',
// Flag to make the map show on start
visibility: true,
},
]Layer properties
LayersProperties31 entriescategorical
Boolean= falseproperty# Switches the generated legend of a source: 'calculate' layer to categorical mode.
categoricalSwitches the generated legend of a source: 'calculate' layer to categorical mode. When true, every distinct value returned by expression() becomes its own legend entry (values are grouped by value, never into ranges) and the colours come from categoricalPalette. When false the values are grouped into at most maxQntEntries ranges coloured with the sequential (blue to red) palette. Use it when the expression returns classes (land use, geology, ...) instead of a continuous number.
[
{
title: 'Categorical result',
color: '#FFA500',
elements: [
{
title: 'One legend entry per geology class',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
updateAutomatically: true,
categorical: true,
expression: function(layersVals, inputs) {
return layersVals[0];
},
},
],
},
]categoricalPalette
Array.<Array.<Number>>= 300 built-in coloursproperty# Colours of the legend entries of a categorical source: 'calculate' layer (see categorical), as an array of [R, G, B] triplets (0 to 255).
categoricalPaletteColours of the legend entries of a categorical source: 'calculate' layer (see categorical), as an array of [R, G, B] triplets (0 to 255). The entries are assigned, in the sorted order of the values returned by expression(), spreading evenly over the palette. When omitted a built-in 300-colour palette is used. The palette length is also the upper limit for maxQntEntries.
[
{
title: 'Custom categorical colours',
color: '#FFA500',
elements: [
{
title: 'Geology classes with a four colour palette',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
updateAutomatically: true,
categorical: true,
categoricalPalette: [[43, 3, 192], [126, 222, 20], [243, 99, 6], [34, 67, 2]],
expression: function(layersVals, inputs) {
return layersVals[0];
},
},
],
},
]description
String= 'XYZ Title' or 'Vector Title'property# Define the text that will be displayed when the mouse hover the Legend Window Title.
descriptionDefine the text that will be displayed when the mouse hover the Legend Window Title. This description applies when the 'source' of the map is 'xyz' or the Layer is a 'vector'.
[
{
title: 'Example of description for XYZ map',
color: '#666699',
elements: [
{
title: 'This is the Layer Legend Window Title, hover me!',
name: 'planet:planet',
source: 'xyz',
url: 'https://tiles.planet.com/basemaps/v1/planet-tiles/planet_medres_visual_2021-09_mosaic/gmap/${z}/${x}/${y}.png?api_key=PLAK78456687760442eaa3d3da16aaac5f2d',
visibility: true,
description: 'Hover the Layer Title',
},
],
},
]descriptionHtml
String= string.emptyproperty# Define the content that will be displayed at the Query section ("Exibir Consulta" button).
descriptionHtmlDefine the content that will be displayed at the Query section ("Exibir Consulta" button). This property accepts any string in HTML format. Besides that, you can also use predefined tools. Only calculated, file and tile (xyz) layers have this panel; on a published map (no source, source: 'local' or a server added with addRemoteWMSServer) it is ignored.
[
{
title: 'Example of descriptionHTML',
color: '#FFA500',
elements: [
{
title: 'This Layer has a custom descriptionHTML',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
pressed: true
},
],
descriptionHtml:
'<p>You can use HTML tags</p>'
+
'{{label|text=Or the tools from Mappia:}}'
+
'{{button|text=I\'m a button from Mappia}}',
},
],
},
]See also You can find more information about the tools available for use in: Tools Section.
disabledAttributes
String= nullproperty# Define which styles will be hidden in the Style Chooser Combobox from Layers that has the 'source' property as 'local'.
disabledAttributesDefine which styles will be hidden in the Style Chooser Combobox from Layers that has the 'source' property as 'local'. You need to pass the name of a style as in the GetCapabilities() xml. They follow the pattern of the map name, underline (_) and then the number of the style. (<map_name>_<number>). You can hide more than one style. For this you only need to separate their names by commas.
[
{
title: 'Example of disabledAttributes',
color: '#666699',
elements: [
{
title: 'This Layer hides the styles \'Mapa geológico\' and \'Tempo geológico\' from the styles choose combobox',
name: 'CSR:geologia',
source: 'local',
visibility: true,
// geologia_2 is the style 'Tempo geológico'
// geologia_1 is the style 'Mapa geológico'
// The 'disabledAttributes' property is used to hide the styles from the styles chooser combobox
// All styles that are hidden must be separated by commas
disabledAttributes: 'geologia_2,geologia_1',
},
],
},
]exclusiveGroupDetails
String= string.emptyproperty# Define a name for a Layer Details.
exclusiveGroupDetailsDefine a name for a Layer Details. Between all Layers with the same ‘exclusiveGroupDetails’ name, only one Layer can have its Legend open each time.
[
{
viewTitle: 'Only one Legend can be open each time',
title: 'Example of exclusiveGroupDetails',
color: '#666699',
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'calculate',
exclusiveGroupDetails: 'ExampleName',
visibility: true,
},
{
title: 'Layer 2',
name: 'CSR:rios_principais',
source: 'calculate',
exclusiveGroupDetails: 'ExampleName',
visibility: true,
},
{
title: 'Layer 3',
name: 'CSR:geologia',
source: 'calculate',
exclusiveGroupDetails: 'ExampleName',
visibility: true,
},
],
},
]extents
Array.<Numeric>= Array.emptyproperty# Define which tiles will be used to render the map.
extentsDefine which tiles will be used to render the map. All the tiles that are within the 'extents' coordinates will be used to render the map. The extents must be in EPSG:4326 (coordinates in lat,long). Also, the array values need to be in the order: [minX, minY, maxX, maxY].
// Play around with the maps visibility to check the regions defined by the extents.
[
{
title: 'Example of extents',
color: '#FFA900',
elements: [
{
title: 'Restricted extents',
name: 'CSR:altimetria',
visibility: true,
// Follows the order [minX, minY, maxX, maxY]
extents: [-48.5, -14.5, -46.0, -13.0],
},
{
title: 'Restricted extents 2',
name: 'CSR:altimetria',
visibility: true,
// Follows the order [minX, minY, maxX, maxY]
extents: [-43.9, -19.8, -43.1, -18.9],
},
{
title: 'This Layer displays the hole map',
name: 'CSR:altimetria',
// This extents render the whole world.
extents: [-180.0000, -90.0000, 180.0000, 90.0000],
startListed: true,
},
],
},
]global
Objectproperty# A second way to declare query globals from a layer: an object whose properties become temporary globals, passed to ExtjsUtils.QUERY.setQueryGlobalProperties while the layer is interpreted.
globalA second way to declare query globals from a layer: an object whose properties become temporary globals, passed to ExtjsUtils.QUERY.setQueryGlobalProperties while the layer is interpreted. The usual form is the ExtjsUtils.QUERY.setQueryGlobalProperties({...}) && [...] chain at the top of the query; the production survey found no query using this key (zero users).
[
{
title: 'Group',
elements: [
{
title: 'Layer with its own globals',
name: 'CSR:estados',
source: 'local',
visibility: true,
global: {
statesLoaded: function() { ExtjsUtils.ALERTIFY.log('States ready'); }
}
}
]
}
]hideLegendButton
Boolean= falseproperty# Hides the legend of the layer in its Legend Window.
hideLegendButtonHides the legend of the layer in its Legend Window. Set it to 'true' to hide it, 'false' to display it. It applies to every layer source: on a local layer it hides the "show legend" toggle button of the row; on a calculate, file or xyz layer it hides the generated legend container (with the legend title and the opacity slider) and the "show legend" button at the bottom of the query section, so only the descriptionHtml remains.
[
{
title: 'Hiding the Legend Button',
color: '#FFA500',
elements: [
{
title: 'The Layer Legend Button will be hidden',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
hideLegendButton: true,
descriptionHtml:
'{{label|text=The legend button is hidden, only the descriptionHtml is visible}}',
},
],
},
]hideListing
Boolean= falseproperty# Hides the layer from its group's menu at the top of the screen: the list that appears when the mouse is over the group title.
hideListingHides the layer from its group's menu at the top of the screen: the list that appears when the mouse is over the group title. Set it to true to leave the layer out of that menu; false (the default) lists it.
[
{
title: 'A Group with 3 Layers, but one is hidden',
color: '#FFA500',
elements: [
{
title: 'Map of the altitude in Brazil',
name: 'CSR:altimetria',
source: 'local',
},
{
title: 'This Layer will be hidden at the Group list',
name: 'CSR:rios_principais',
source: 'local',
hideListing: true,
},
{
title: 'Map of the geology in Brazil',
name: 'CSR:geologia',
source: 'local',
},
],
},
]hideMetadata
Boolean= falseproperty# If true, hides the metadata button in the Legend Window for this layer.
hideMetadataIf true, hides the metadata button in the Legend Window for this layer. The button is also hidden when the link has options=hidemetadata: either one hides it, and hideMetadata: false cannot bring it back. Calculated, file and tile (xyz) layers only have this button when their paramsButtonConfig has a {type: 'metadata'} entry.
[
{
title: 'Hiding the metadata button',
color: '#FFA500',
elements: [
{
title: 'This Layer has no metadata button',
name: 'CSR:geologia',
source: 'local',
visibility: true,
hideMetadata: true,
},
],
},
]hideStyleChooser
Boolean= falseproperty# Define if should hide the Combobox with the map possible styles that can be applied to a map in a Layer that has the 'source' 'local'.
hideStyleChooserDefine if should hide the Combobox with the map possible styles that can be applied to a map in a Layer that has the 'source' 'local'.
[
{
title: 'Example with hidden style Combobox',
color: '#FFA500',
elements: [
{
title: 'Map of the geology in Brazil',
name: 'CSR:geologia',
source: 'local',
visibility: true,
startLegendOpen: true,
hideStyleChooser: true,
},
],
},
]hideTilePlaceholder
Boolean= falseproperty# Removes the stretched placeholder tile that is shown while the real tiles load (the OpenLayers resize transition).
hideTilePlaceholderRemoves the stretched placeholder tile that is shown while the real tiles load (the OpenLayers resize transition). Set it to true for layers whose content changes between loads, such as timeline or calculated maps, to avoid the previous image being stretched before the new one appears. Applies to local and calculate layers; a composed layer also passes it on to the maps replaced with changeLayers.
[
{
title: 'No stretched tiles while loading',
color: '#FFA500',
elements: [
{
title: 'Map of the geology in Brazil',
name: 'CSR:geologia',
source: 'local',
visibility: true,
hideTilePlaceholder: true,
},
],
},
]insideOpacity
Array.<Numeric>= [1, 1, 1, ...]property# Defines the opacity for the maps defined in the 'name' property.
insideOpacityDefines the opacity for the maps defined in the 'name' property. This property is an array of values which are the opacity that will be applied in the same order that the map was defined in the 'name' property. For example, the first value in the 'insideOpacity' array will define the opacity for the first map defined in the 'name' property, the second value is the opacity for the second map, and so on. The opacity value is a number between 0 and 1. 0 being transparent and 1 opaque.
[
{
title: 'Example of insideOpacity',
color: '#666699',
elements: [
{
name: 'CSR:estados,CSR:rios_principais,CSR:geologia',
source: 'calculate',
// The values are applied to the layers in the same order as they are defined in the name property. So the CSR:estados map has the opacity of 0.5, the CSR:rios_principais map has the opacity of 1, and the CSR:geologia map has the opacity of 0.7.
insideOpacity: [0.5, 1, 0.7],
visibility: true,
},
],
},
]legendTitle
String= string.emptyproperty# Defines the text that will be displayed at the top of the 'legendhtml tool' declared at the 'descriptionHtml' property
legendTitleDefines the text that will be displayed at the top of the 'legendhtml tool' declared at the 'descriptionHtml' property
[
{
title: 'Example custom legend title',
color: '#FFA500',
elements: [
{
title: 'Map of the geology in Brazil',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
legendTitle: 'This is a custom legend title',
descriptionHtml:
'{{legendhtml}}',
},
],
},
]maxQntEntries
Number= 18property# Maximum number of legend entries generated from the values returned by expression() on a non-categorical source: 'calculate' layer; when there are more distinct values than this they are grouped into value ranges.
maxQntEntriesMaximum number of legend entries generated from the values returned by expression() on a non-categorical source: 'calculate' layer; when there are more distinct values than this they are grouped into value ranges. The value is clamped to the length of the active palette. PS: the automatic grouping currently always uses the built-in limit of 18, so a custom value is kept on the layer but does not change the generated legend. Use setCalculateLegend() when you need full control over the legend entries.
{
name: 'CSR:altimetria',
source: 'calculate',
maxQntEntries: 10,
expression: function(layersVals, inputs) {
return layersVals[0];
},
}name
String= string.emptyproperty# Defines the maps that will be a part of the Layer.
nameDefines the maps that will be a part of the Layer. Every map defined in here will be shown when the Layer is active. Besides that, all of their information can be used to calculate a new map combining their data. In this website you will find some of the maps that can be used: http://maps.csr.ufmg.br/geonetwork/srv/por/search. You can find their name at the section "Visão geral do mapa" under its image. Those maps have the prefix "CSR:" before their names. Maps can also be uploaded by you. For that, you just need to define the 'source' property as 'file'.
[
{
title: 'A Group with two maps',
color: '#FFA500',
elements: [
{
title: 'This Layer has two maps!',
// Each map is separated by commas
// The first map is CSR:rios_principais that have the rivers of Brazil
// The second map is CSR:estados that show the states of Brazil
name: 'CSR:rios_principais,CSR:estados_cf',
visibility: true,
},
],
},
]opacity
Numeric= 1property# Define the opacity of the Layer.
opacityDefine the opacity of the Layer. The opacity is a value between 0 and 1 that is a scale for its transparency. 0 is completely transparent. 1 is completely visible.
[
{
title: 'Example of opacity in a Layer',
color: '#666699',
elements: [
{
title: 'This Layer has its opacity set to 50% of the original visibility',
name: 'CSR:geologia',
source: 'local',
visibility: true,
opacity: 0.5,
},
],
},
]otherNames
Stringproperty# Defines additional maps to be available for the query, which will be listed in the filtered stored capabilities.
otherNamesDefines additional maps to be available for the query, which will be listed in the filtered stored capabilities. Every map included in layer definition needs to be either in 'name' property or 'otherNames' property.
PS: This property must be used along with the 'capabilities' url option, which filters the 'GetCapabilities' response with only the maps included in layer definition. (Performance Optimization, faster loading). PS2: This property is only needed outside of the editor mode.
{
name: "CSR:estados,CSR:airports",
otherNames: "CSR:municipios,CSR:rodovias",
beforeCalc: function(layerVals, inputVals) {
this.changeLayers([{name: 'CSR:municipios', styles: fMapName + "_1", index: 0},
{name: 'CSR:rodovias', styles: 'rodovias_1', index: 1}]);
}
}
Function 'changeLayers' needs the definition of the 4 maps: 'estados', 'airports', 'municipios' and 'rodovias'.
If the 'otherNames' is not defined, only the maps defined at 'name' property will be available.
Applies to calculated layers (`source: 'calculate'`), the ones that swap maps with `changeLayers`.priority
Number= 0property# Defines the order of which map will be rendered on top of the others.
priorityDefines the order of which map will be rendered on top of the others. Layers with higher 'priority' will always be rendered on top of the layers with lower 'priority'.
[
{
title: 'At the bottom will be the geology, then the states and at top the rivers',
color: '#FFA500',
elements: [
{
title: 'Map of the states in Brazil',
name: 'CSR:estados',
source: 'local',
priority: 2,
visibility: true,
},
{
title: 'Map of the rivers in Brazil',
name: 'CSR:rios_principais',
source: 'local',
priority: 3,
visibility: true,
},
{
title: 'Map of the geology in Brazil',
name: 'CSR:geologia',
source: 'local',
priority: 1,
visibility: true,
},
],
},
]showLoadingModal
Boolean= falseproperty# Shows the "generating legend" loading mask visibly over the page while the layer is paused (calculating or loading a resource).
showLoadingModalShows the "generating legend" loading mask visibly over the page while the layer is paused (calculating or loading a resource). By default the mask is an invisible overlay that only changes the cursor to "wait"; set it to true to make it visible. Only shown while the layer is visible. Applies to calculate and file layers.
[
{
title: 'Visible loading mask',
color: '#FFA500',
elements: [
{
title: 'A slow calculation with a visible loading mask',
name: 'CSR:altimetria',
source: 'calculate',
visibility: true,
updateAutomatically: true,
showLoadingModal: true,
expression: function(layersVals, inputs) {
return layersVals[0];
},
},
],
},
]showRemoveBtn
Boolean= falseproperty# Defines it the remove button at the top right of the Layer Legend Window show be displayed.
showRemoveBtnDefines it the remove button at the top right of the Layer Legend Window show be displayed. Set it to 'true' to show it. Set it to 'false' to hide it.
[
{
title: 'Hiding the remove button',
color: '#FFA500',
elements: [
{
title: 'The \'X\' button at the top right of this Layer removes this map',
name: 'CSR:rios_principais',
source: 'local',
visibility: true,
},
{
title: 'There is no button to remove the this map',
name: 'CSR:estados',
source: 'local',
visibility: true,
showRemoveBtn: false,
},
],
},
]source
String= 'local'property# Defines the source from where the maps declared at the name will be loaded from.
sourceDefines the source from where the maps declared at the name will be loaded from. The Source can be one of the following:
'local': The maps in the name will be loaded from the CSR servers
'calculate': The maps in the name gonna be used to calculate a new map in the expression() function and the result will be displayed as the Layer
'file': The map will be loaded from a file or other custom source. For this, you need to define the file type in the 'type' property and the file where the map should be loaded. For example, for a JSON file, you also need to define the 'json' property.
'xyz': The map will be loaded from an url by the XYZ protocol. The url property is required for this type of source. You can find more informations about the XYZ protocol at: https://developers.planet.com/docs/basemaps/tile-services/xyz/
// Example of how to load a map with the local source
[
{
title: 'Map rendered by a local source',
color: '#666699',
elements: [
{
title: 'Map with local source',
name: 'CSR:paises',
source: 'local',
visibility: true,
},
],
},
]// Example of how to load a map with the calculated source
[
{
title: 'Map rendered based on calculation',
color: '#666699',
elements: [
{
title: 'Filtering a part of the map',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
updateAutomatically: true,
expression: function(layersVals, inputs) {
// layerVals have the value of the legend applied in every pixel of the map
let mapValue = layersVals[0];
// Remove every type of relief that is not 'Mantiqueira'
if(mapValue != 'Mantiqueira') { // If the pixel is not 'Mantiqueira'
return undefined; // Don't show the pixel
}
// If the pixel is 'Mantiqueira', return the value of the pixel
return mapValue;
},
},
],
},
]// Example of how to load a map with the file source
[
{
title: 'Map rendered based on file source',
color: '#FFA500',
elements: [
{
title: 'Map with file source',
name: 'example:map_file_source',
source: 'file',
visibility: true,
// The map is rendered based on the GeoJSON below
// The GeoJSON needs to be in EPSG:3857
json: JSON.stringify(
{
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:3857"
}
},
"coordinates": [
[
[
-625570.6,
6465993.0,
],
[
-305006.9,
6696510.8,
],
[
-546330.2,
6768547.6,
],
[
-445478.6,
7053093.0,
],
[
-279794.0,
7056694.8,
],
[
-359034.5,
7337638.4,
],
[
-211359.0,
7485313.8,
],
[
62380.8,
6955843.3,
],
[
220861.7,
6909019.4,
],
[
91195.5,
6700112.6,
],
[
213658.1,
6682103.4,
],
[
-625570.6,
6465993.0,
],
],
],
}
),
},
],
},
]// Example of how to load a map with the XYZ source
// The XYZ source is used to load a map from a URL that contains the {z}, {x} and {y} placeholders
// The {z} is the zoom level, {x} is the longitude and {y} is the latitude
[
{
title: 'Map rendered by a XYZ source',
color: '#666699',
elements: [
{
title: 'Base map loaded by XYZ source',
// The name of the map that will be added. This name must be unique
name: 'planet:planet',
source: 'xyz',
// The url of the map that will be loaded. The ${z}, ${x} and ${y} placeholders will be replaced by the map library
url: 'https://tiles.planet.com/basemaps/v1/planet-tiles/planet_medres_visual_2021-09_mosaic/gmap/${z}/${x}/${y}.png?api_key=PLAK78456687760442eaa3d3da16aaac5f2d',
visibility: true,
},
],
},
]startLegendOpen
Boolean= falseproperty# Defines if the Legend Window should start or not.
startLegendOpenDefines if the Legend Window should start or not. Set it to 'true' to make it start open. Set it to 'false' for it to start closed. Applies to published maps only (no source, source: 'local' or a server added with addRemoteWMSServer). Calculated, file and tile (xyz) layers ignore it: their details already start open, and paramsButtonConfig: [{type: 'query', pressed: true}] makes them start on the layer's panel instead.
[
{
title: 'The Legend Window the Layer will start open',
color: '#FFA500',
elements: [
{
title: 'This Layer Legend Window will start open',
name: 'CSR:geologia',
source: 'local',
startLegendOpen: true,
visibility: true,
},
],
},
]startListed
Boolean= falseproperty# Define if the Layer should start with its Legend Window visible or not.
startListedDefine if the Layer should start with its Legend Window visible or not. This does not make the Layer visible on the map by itself. For that, you need to set the 'visibility' property to 'true'. 'startListed' just displays the Legend Window associated with the Layer.
[
{
title: 'The Legend Window of the third Layer will start visible',
color: '#FFA500',
elements: [
{
title: 'Map of the altitude in Brazil',
name: 'CSR:altimetria',
source: 'local',
},
{
title: 'Map of the rivers in Brazil',
name: 'CSR:rios_principais',
source: 'local',
},
{
title: 'This Layer Legend Window will start visible, but is not map',
name: 'CSR:geologia',
source: 'local',
startListed: true,
},
],
},
]styles
String= string.emptyproperty# Defines which styles will be applied over the maps defined at the 'name' property.
stylesDefines which styles will be applied over the maps defined at the 'name' property. The styles are applied in the same order as the maps are declared in name. For example, if there are 3 maps in the 'name' property and 3 styles. The first style will be applied to the first map, the second to the second map, and so on. A style's Mappia identifier is the map name without its namespace plus _ and an index (estados published with two styles gives estados_0 and estados_1), and the styles a map really offers are the ones its published capabilities declare: open the layer's style chooser in the interface to see and pick them, or read the Style entries of the map in the WMS capabilities. Styles are created when the map is published (a QGIS style file is converted at publication time), not by the query. PS: Styles are separated by comma, one per map in name, in the same order.
[
{
title: 'Example of style',
color: '#666699',
elements: [
{
name: 'CSR:precip_monthly_average,CSR:precip_monthly_average',
// The first style 'precip_monthly_average_1' is applied to the first map 'precip_monthly_average' and the second style 'precip_monthly_average_2' is applied to the second map 'precip_monthly_average'
styles: 'precip_monthly_average_1,precip_monthly_average_2',
// The source needs to be calculate to apply the style
source: 'calculate',
visibility: true,
},
],
},
]{
...,
name: 'CSR:municipios',
style: 'municipios_0',
...
}{
...,
name: 'CSR:estados,CSR:geologia',
style: 'estados_0,geologia_1',
...
}thumbUrl
String= undefinedproperty# Define the thumbnail image that is displayed when the mouse hovers the Legend Window title.
thumbUrlDefine the thumbnail image that is displayed when the mouse hovers the Legend Window title. You can define any image you would like to display as the map thumbnail. You just need to pass its URL.
[
{
title: 'Example of thumbUrl',
color: '#FFA900',
elements: [
{
title: 'There is a puppy hidden in here! Hover me! <3',
name: 'CSR:altimetria',
visibility: true,
thumbUrl: 'https://fastly.picsum.photos/id/237/200/300.jpg?hmac=TmmQSbShHz9CdQm0NkEjx1Dyh_Y984R9LpNrpvH2D_U',
},
],
},
]title
String= 'layer_name' The default value is the layer name.property# Defines the Title that will be displayed at the Legend Window in the top left corner of the screen and inside the Group List at the top center of the screen.
titleDefines the Title that will be displayed at the Legend Window in the top left corner of the screen and inside the Group List at the top center of the screen.
[
{
title: 'The title of the Group shows up at the top center of the screen and has a List inside it.',
color: '#FFA500',
elements: [
{
title: 'The title of the Layer is shown at the Legend Window and inside the menu of the Group name.',
name: 'CSR:capitals',
visibility: true,
},
],
},
]updateAutomatically
Boolean= falseproperty# Decides what happens when the reader changes an input of the layer's panel (a widget in descriptionHtml).
updateAutomaticallyDecides what happens when the reader changes an input of the layer's panel (a widget in descriptionHtml). true: the layer is calculated again at once. false (the default): a short countdown starts, with a button to refresh now, so several changes make one calculation. The layer is drawn either way. Applies to calculated and file layers.
[
{
title: 'The map will be automatically calculated',
color: '#666699',
elements: [
{
title: 'This layer is showing just one type of relief',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
updateAutomatically: true,
expression: function(layersVals, inputs) {
// layerVals have the value of the legend applied in every pixel of the map
let mapValue = layersVals[0];
// Remove every type of relief that is not 'Mantiqueira'
if(mapValue != 'Mantiqueira') { // If the pixel is not 'Mantiqueira'
return undefined; // Don't show the pixel
}
// If the pixel is 'Mantiqueira', return the value of the pixel
return mapValue;
},
},
],
},
]viewColor
Stringproperty# HTML color to use on the group.
viewColorHTML color to use on the group.
[{
viewColor: "#FFFFFF",
viewTitle: "DADOS BASE",
color: "#FF000F",
elements: [
{name: 'CSR:AMAZONIA_limite', showRemoveBtn: false, visibility: true,
hideListing: true, startListed: true, priority: 10000}
]}]visibility
Boolean= falseproperty# Define if the Layer should start visible or not.
visibilityDefine if the Layer should start visible or not. Set it to 'true' for the Layer start visible. Otherwise, set it to 'false' and the Layer will start hidden.
[
{
title: 'Example of visibility in a Layer',
color: '#666699',
elements: [
{
title: 'This layer will start visible',
name: 'CSR:geologia',
source: 'local',
visibility: true,
},
],
},
]More layer properties
ConfigLayer14 entriesattribution
Stringproperty# Recognizes someone as the platform author, showing in the "Powered by: {insert name}".
attributionRecognizes someone as the platform author, showing in the "Powered by: {insert name}".
customLayerClass
String= string.emptyproperty# Extra CSS class added to the row of the layer in the Legend Window and to its vertical options menu (see verticalMenu), so the layer can be styled with ExtjsUtils.CSS.defineClass or a stylesheet.
customLayerClassExtra CSS class added to the row of the layer in the Legend Window and to its vertical options menu (see verticalMenu), so the layer can be styled with ExtjsUtils.CSS.defineClass or a stylesheet. The same key on a viewTitle group is added to the group node instead (GroupProperties.customLayerClass).
[
{
title: 'Styled layer row',
color: '#FFA500',
elements: [
{
title: 'This row has a custom background',
name: 'CSR:geologia',
source: 'local',
visibility: true,
customLayerClass: 'highlighted-layer',
},
],
},
]group
Stringproperty# Only the value "background" does anything: it makes the layer a basemap, drawn under every other layer and listed in the background picker instead of the layer list.
groupOnly the value "background" does anything: it makes the layer a basemap, drawn under every other layer and listed in the background picker instead of the layer list. Any other value is ignored (it does not group layers: groups are { title, elements: [...] } objects). To let only one of several layers be visible at a time, use toggleGroup.
[{visibility: true, group: "background", name: "CSR:planet_brasil_2024", priority: 5}]maxExtent
OpenLayers.Boundsproperty# Defines a geographical limit for a map rendering.
maxExtentDefines a geographical limit for a map rendering.
maxZoom
Numericproperty# Defines the limit of the real max zoom of a given layer.
maxZoomDefines the limit of the real max zoom of a given layer. When map zoom exceed this, the image is reused and stretched.
maxscale
Numericproperty# Defines the limit of the real max scale of a given layer.
maxscaleDefines the limit of the real max scale of a given layer. When the map scale value exceeds the defined one, the image is reused and stretched.
metadataUrl
string|nullproperty# Defines the url to show custom layers metadata information.
metadataUrlDefines the url to show custom layers metadata information. If empty, the default value is obtained from layer metadata from the WMS definition.
PS: The linked domain must have CORS headers enabled.
minscale
Numericproperty# Defines the limit of the real min scale of a given layer.
minscaleDefines the limit of the real min scale of a given layer. When the map scale reaches a value lower than the defined one, the image is reused and compressed.
openGroup
Boolean= falseproperty# Defines if the group starts opened, even without any visible layers.
openGroupDefines if the group starts opened, even without any visible layers. Set it true to start open, false otherwise. PS: If one layer is visible, the group will start open. It works at both levels: on a viewTitle group it makes that group start expanded; on a layer it expands every viewTitle ancestor of the layer (see GroupProperties.openGroup).
operation
String= string.emptyproperty# Defines how the pixels of each map of a source: 'calculate' layer are decoded into the values that expression() receives in layersVals.
operationDefines how the pixels of each map of a source: 'calculate' layer are decoded into the values that expression() receives in layersVals. It is a comma-separated list with one token per map in name, in the same order; an empty token keeps that map on the default decoding (for example 'raw,,sum' leaves the second map on the default). Tokens are case and whitespace insensitive. The accepted tokens (see RawMaps.operations for the full description of each one) are:
- (empty or unknown):
NORMAL, the regular WMS image, each pixel is a legend colour/category. raw: the value of the most centred original cell of the region covered by the pixel.rgba: the RGBA bytes of the pixel packed as one integer.sum: area-weighted sum of the covered cells.average: area-weighted mean of the covered cells.max/min: largest / smallest cell at least partially covered.integral: summed-area table, the sum over a rectangle from its four corners.areaintegral: summed-area table of the covered areas.area: original map area inside the covered region.cells: weighted count of original cells inside the covered region. Every token other than the default andrgbarequires the map to be published as a Raw Map offering that operation; otherwise the console logsError: Operation X is not defined for layer Y.
[
{
title: 'Population from raw maps',
color: '#FFA500',
elements: [
{
title: 'Total population of each pixel',
// The same raw map is stacked twice, read with two different operations,
// and the states map keeps the default decoding (empty token).
name: 'CSR:pop_density_estimate_2015,CSR:estados,CSR:pop_density_estimate_2015',
operation: 'average,,area',
source: 'calculate',
visibility: true,
updateAutomatically: true,
descriptionHtml: '{{hoverpixel}}',
expression: function(layersVals, inputs) {
var density = layersVals[0]; // people per km2 (area-weighted mean)
var stateName = layersVals[1]; // legend value of the regular WMS map
var areaKm2 = layersVals[2]; // area of the original cells covered by this pixel
return density * areaKm2;
},
},
],
},
]shouldKeepRecord
Boolean= trueproperty# Defines what the 'X' (remove) button of the Legend Window does (see showRemoveBtn).
shouldKeepRecordDefines what the 'X' (remove) button of the Legend Window does (see showRemoveBtn). When true the layer record is kept: the layer is only hidden and removed from the listing, so it can be listed again from the group menu at the top. When false the layer is removed from the map for good.
[
{
title: 'Removing a layer for good',
color: '#FFA500',
elements: [
{
title: 'The X button removes this map from the query',
name: 'CSR:rios_principais',
source: 'local',
visibility: true,
shouldKeepRecord: false,
},
],
},
]toggleGroup
Stringproperty# Places a layer in a group of layers with mutually exclusive visibility.
toggleGroupPlaces a layer in a group of layers with mutually exclusive visibility.
At most one layer of the same group will be visible, when one is shown, the others will be hidden.
[{name: "CSR:estados": toggleGroup:"political_division"},
{name: "CSR:paises": toggleGroup:"political_division"}
]useLayerTooltip
Boolean|Numberproperty# If false, the layer tooltip is not shown.
useLayerTooltipIf false, the layer tooltip is not shown. If a number, the layer tooltip is shown for the specified layer. (Only supported for layers with source: "calculate") Otherwise follow tooltip default behavior that varies from map source
verticalMenu
Boolean= falseproperty# Uses the compact layout for the Legend Window of the layer: the secondary buttons (remove, metadata, download, zoom to extents) and a vertical opacity slider move into a small options menu opened by …
verticalMenuUses the compact layout for the Legend Window of the layer: the secondary buttons (remove, metadata, download, zoom to extents) and a vertical opacity slider move into a small options menu opened by a gear button, instead of being drawn in the row with the horizontal opacity slider. Usually used together with customLayerClass.
[
{
title: 'Compact Legend Window',
color: '#FFA500',
elements: [
{
title: 'The layer options are in a vertical menu',
name: 'CSR:geologia',
source: 'local',
visibility: true,
verticalMenu: true,
customLayerClass: 'my-compact-layer',
},
],
},
]Layer callbacks: functions you write
LayersFunctions7 entriesafterCalc
function= nullcallback# This function is executed right after the 'expression()' calculations.
afterCalcThis function is executed right after the 'expression()' calculations. This function is only available for a Layer with a 'source' of type 'calculate' and that has defined the 'expression()' function.
- inputs Array
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
[
{
title: 'Example of afterCalc function',
color: '#FFA500',
elements: [
{
title: 'This afterCalc function will show a message at the bottom right of the screen',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
pressed: true
},
],
descriptionHtml:
'{{label|text=The afterCalc is run after every expression() execution}}'
+
'{{textfield|fieldLabel=Enter your name|id=textInput|labelStyle=text-align:center;}}',
// The expression function is mandatory to use the afterCalc function.
expression: function(layerVals, inputs) {
return undefined;
},
afterCalc: function(inputs) {
let inputValue = inputs[0];
ExtjsUtils.ALERTIFY.log('Hello ' + inputValue + '!');
},
},
],
},
]beforeCalc
function= nullcallback# This function is executed before any calculation is made in the 'expression()' function.
beforeCalcThis function is executed before any calculation is made in the 'expression()' function. It runs on calculated layers (source: 'calculate'), even when there is no 'expression()', and on file layers (source: 'file'), where it runs again whenever an input changes or a resource finishes loading (see VectorLayer.generateNewLegend).
- inputs Array
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
[
{
title: 'Example of beforeCalc function',
color: '#FFA500',
elements: [
{
title: 'This beforeCalc function will show a message at the bottom right of the screen',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
pressed: true
},
],
descriptionHtml:
'{{label|text=The beforeCalc function will be called after every user interaction before any calculation}}'
+
'{{textfield|fieldLabel=Enter your name|id=textInput|labelStyle=text-align:center;}}',
beforeCalc: function(inputs) {
let inputValue = inputs[0];
ExtjsUtils.ALERTIFY.log('Hello ' + inputValue + '!');
},
},
],
},
]expression
function= nullcallback# This function is executed for every pixel in the map.
expressionThis function is executed for every pixel in the map. It can be used to process the information of all maps in the Layer to create a new one. This function is called regularly to update the map.
- layerVals Array.<LayerValues>
- Is an array that has the value associated with the current pixel for each map defined in the 'name' property. The values order is the same as the one in ‘name’. For example, if in the 'name' property we have 'name: CSR:geologia,CSR:altimetria' the layerVals[0] has the value for the 'CSR:geologia' map and the layerVals[1] has the value for the 'CSR:altimetria'.
- inputs Array
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
Returns Value of each processed pixel.
[
{
title: 'Example of expression function',
color: '#FFA500',
elements: [
{
title: 'This Layer is the result of the calculation of two maps',
name: 'CSR:geologia,CSR:altimetria',
source: 'calculate',
legendTitle: 'All geologys above 800m',
visibility: true,
expression: function(layerVals, inputs) {
let geologyValue = layerVals[0];
let altitudeValue = layerVals[1];
// Hide all values lower than 800
if (altitudeValue < 800) {
return undefined;
}
return geologyValue;
},
},
],
},
]functions
Object= null# Associate custom functions to handle events on layer callbacks such as button callbacks or any layer callbacks.
functionsAssociate custom functions to handle events on layer callbacks such as button callbacks or any layer callbacks. These functions are scoped to the Layer and can be referenced by name on layer widget callbacks. Functions can also be accessed using this.functions['<function_name>'].
[
{
title: 'Example of functions property',
color: '#666699',
elements: [
{
title: 'Click the button to see a message',
name: 'CSR:geologia',
group: 'Query',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type:'query',
pressed: true,
},
],
descriptionHtml:
'{{button|id=test_button|text=Click me!|handler=handleTestButtonClick}}',
functions: {
handleTestButtonClick: function() {
ExtjsUtils.ALERTIFY.log('Button clicked!');
},
},
},
],
},
]legendColor
functioncallback# This function generates the color of each value/category of the calculated map generated by the 'expression()' function.
legendColorThis function generates the color of each value/category of the calculated map generated by the 'expression()' function. The return value is the legend color that will be applied to the category. PS: This function callback is called in layer context.
- color Array.<Numeric>
- Array with three numbers (0 to 255) that define the RGB color of the original legend.
- inputs Array.<Object>
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
- lastValue String
- The last legend value that had its color calculated.
- currentValue String
- The actual legend value that it's being calculated.
- ruleIndex Numeric
- The index of the actual legend value that it’s being calculated. I.e. The first legend value is 0, the second is 1, and so on.
Returns The new color to the value in [R,G,B] format.
[
{
title: 'Example of legendColor',
color: '#666699',
elements: [
{
title: 'The legendColor function will generate a custom color for each category, based on its value',
name: 'CSR:altimetria',
source: 'calculate',
updateAutomatically: true,
visibility: true,
expression: function(layersVals, inputs) {
return layersVals[0];
},
// This create a custom colors palette for the legend of the result map from the 'expression' function
legendColor: function(color, inputs, lastValue, currentValue, ruleIndex) {
let red = 0;
let green = currentValue * 255 / 1830;
let blue = 0;
return [red, green, blue];
},
},
],
},
]onInputsReady
function= nullcallback# This function is called when all inputs have been loaded and are ready.
onInputsReadyThis function is called when all inputs have been loaded and are ready. Even from Layers that aren’t visible.
- inputs Array
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
[
{
title: 'Example of onInputsReady function',
color: '#666699',
elements: [
{
title: 'This Layer shows the starting value of the text input field',
name: 'CSR:geologia',
group: 'Query',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type:'query',
pressed: true,
},
],
descriptionHtml:
'{{textfield|id=textInput|fieldLabel=Message|value=I love maps!|labelStyle=text-align:center;}}',
onInputsReady: function(inputs) {
let textInputValue = inputs[0];
ExtjsUtils.ALERTIFY.log('The text input initial value is: ' + textInputValue);
},
},
],
},
]onVisibilityChange
function= nullcallback# This function is called whenever a Layer changes its visibility.
onVisibilityChangeThis function is called whenever a Layer changes its visibility. Like, when the user toggle the value in the visibility button at the top right in the Legend Window.
- visibility Boolean
- It’s true if the Layer is visible or false otherwise.
- inputs Object
- The value of each input defined in the descriptionHtml. The order of the values is the same as the inputs (i.e. the first input in the descriptionHtml is inputs[0], the second is inputs[1] and so on).
[
{
title: 'Example of callback when changing the visibility',
color: '#FFA500',
elements: [
{
title: 'The function onVisibilityChange will be called when the visibility of this layer changes.',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type:"query",
pressed: true
},
],
descriptionHtml:
'{{label|text=You can change the map visibility by clicking at the eye icon on the top of this window}}',
onVisibilityChange: function(state, inputs) {
if(state) {
ExtjsUtils.ALERTIFY.log('The layer is now visible');
}
else {
ExtjsUtils.ALERTIFY.log('The layer is now hidden');
}
},
},
],
},
]Row buttons (paramsButtonConfig)
paramsButtonConfigProperties8 entriesenableToggle
Boolean= trueproperty# Makes the row button of a paramsButtonConfig entry that mirrors a widget (an entry with associatedButtonID) a toggle (true) or a plain push button (false).
enableToggleMakes the row button of a paramsButtonConfig entry that mirrors a widget (an entry with associatedButtonID) a toggle (true) or a plain push button (false). PS: Once the mirrored widget is found the platform sets it from that widget (a checkbox or a toggle button makes it a toggle), so your value only counts while the widget does not exist.
paramsButtonConfig: [{ type: 'associated', associatedButtonID: 'my_button', enableToggle: false }]hideBottomButton
Boolean= falseproperty# Hides the text buttons at the bottom of the query and legend sections of the Legend Window ("Show query"/"Hide query" and "Show legend"/"Hide legend").
hideBottomButtonHides the text buttons at the bottom of the query and legend sections of the Legend Window ("Show query"/"Hide query" and "Show legend"/"Hide legend"). Set it to 'true' to hide them or 'false' to display them. It only works inside a paramsButtonConfig entry of type: 'query' (or in the bare object form of paramsButtonConfig, which is treated as the query entry); a hideBottomButton written directly on the layer or in a group's defaultProperties is ignored.
[
{
title: 'Example of paramButtonConfig hideBottomButton property',
color: '#FFA500',
elements: [
{
title: 'The buttons at the bottom of the Legend Window are hidden',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=There are no buttons in here}}',
paramsButtonConfig: [
{
type: 'query',
hideBottomButton: false,
},
],
},
],
},
]hideButton
Boolean= falseproperty# Define if the associated button should be hidden.
hideButtonDefine if the associated button should be hidden. Set it to 'true' to hide the button or 'false' to show it. This property only applies to the type: 'query'
[
{
title: 'Example of paramButtonConfig hideButton property',
color: '#FFA500',
elements: [
{
title: 'The query button in hidden',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
hideButton: true,
},
],
},
],
},
]iconCls
String= string.emptyproperty# Define a class that will be added to the html in the associated button.
iconClsDefine a class that will be added to the html in the associated button.
This class can be one that has a image on it like:
- 'gxp-icon-togglevisibility' is the icon of the Show/Hide Map Button (The first icon on the Legend Window, from left to right)
- 'gxp-icon-removelayers' is the icon of the Remove Layer Button (The second icon on the Legend Window, from left to right)
- 'gxp-icon-parameters-expand' is the icon of the Show Query Button (The third icon on the Legend Window, from left to right)
- 'gxp-icon-legend-expand' is the icon of the Show Legend Button (The forth icon on the Legend Window, from left to right)
- 'gxp-icon-downloadmapbutton' is the icon of the Download Button (The fifth icon on the Legend Window, from left to right)
[
{
title: 'Example of paramButtonConfig iconCls property',
color: '#A020F0',
elements: [
{
title: 'The query button is the download icon:',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=Here is the query region}}',
paramsButtonConfig: [
{
type: 'query',
tooltip: 'This is actually the query button',
// Here you can add any class you choose
iconCls: 'gxp-icon-downloadmapbutton',
},
],
},
],
},
]pressed
Boolean= falseproperty# Defines if the button should start pressed or not.
pressedDefines if the button should start pressed or not. Set it to 'true' for it to start pressed or 'false' for start unpressed. For example, the 'query' button type set as pressed will display the Query region (where the descriptionHtml content is) by default instead of the Legend region. This property applies only to the types: 'query',
[
{
title: 'Example of paramButtonConfig pressed property',
color: '#A020F0',
elements: [
{
title: 'The param button config set the query button to be pressed at the start',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=The region of the descriptionHtml will start opened}}',
paramsButtonConfig: [
{
type: 'query',
pressed: true,
},
],
},
],
},
]toggleGroup
String= string.emptyproperty# Defines a group for all the buttons that has the same toggleGroup name.
toggleGroupDefines a group for all the buttons that has the same toggleGroup name. From all the buttons on the same group, only one can be active at each time. Whenever another one is activated the previous one collapses.
[
{
title: 'Example of paramButtonConfig toogleGroup',
color: '#FFA500',
elements: [
{
title: 'Layer 1',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=This is the description of Layer 1. Only one can be open each time.}}',
paramsButtonConfig: [
{
type: 'query',
toggleGroup: 'Group1',
},
],
},
{
title: 'Layer 2',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=This is the description of Layer 2. Only one can be open each time.}}',
paramsButtonConfig: [
{
type: 'query',
toggleGroup: 'Group1',
},
],
},
{
title: 'Layer 3',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=This is the description of Layer 3. Only one can be open each time.}}',
paramsButtonConfig: [
{
type: 'query',
toggleGroup: 'Group1',
},
],
},
],
},
]tooltip
String= string.emptyproperty# Defines the help tooltip text that is displayed when the mouse hover the associated button.
tooltipDefines the help tooltip text that is displayed when the mouse hover the associated button.
[
{
title: 'Example of paramButtonConfig tooltip property',
color: '#A020F0',
elements: [
{
title: 'The query button is the third of the buttons at the right:',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
descriptionHtml:
'{{label|text=Hover the query button. That is the third button from left to right.}}',
paramsButtonConfig: [
{
type: 'query',
pressed: true,
},
],
},
],
},
]type
String= 'query'property# Define which button will be affected by the configurations.
typeDefine which button will be affected by the configurations. The type can be one of the following:
'query': The query button shows or hides the Query panel (where the descriptionHtml is drawn).
'download': The download button is the one with a downward arrow. This button allows the user to download the dataset. It also defines which Layer should be downloaded when more than one Layer is shown by its internal layer index.
'metadata': The metadata button is the one with a script icon. This button displays a popup with more information about the maps used in the actual Layer. You can make it show one of the inside composite Layer by his index.
'associated': Creates a custom button that is linked to another button defined in the descriptionHtml. When one is pressed the other is also pressed.
paramsButtonConfig is normally an array of entries and each entry must declare its type (an entry without type is ignored). It may also be a single object instead of an array: it is then treated as one entry of type: 'query' (unless the object declares another type). PS: The properties are aditional, so the common must always be present, and for each type his corresponding property must be added.
// Example on how to use the query type paramsButtonConfig
[
{
title: 'Example of paramButtonConfig types',
color: '#FFA500',
elements: [
{
title: 'This Layer has custom buttons on the Legend Window',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
startLegendOpen: true,
descriptionHtml:
'{{label|text=The third button is the Query type}}',
paramsButtonConfig: [
{
type: 'query',
tooltip: 'This is the query button',
pressed: true,
handler: function handleClick(button, clickEvent) {
ExtjsUtils.ALERTIFY.log('You\'ve clicked the query button');
},
},
],
},
],
},
]// Example on how to use the metadata type paramsButtonConfig
[
{
title: 'Example of paramButtonConfig types',
color: '#FFA500',
elements: [
{
title: 'This Layer has custom buttons on the Legend Window',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
startLegendOpen: true,
descriptionHtml:
'{{label|text=The third button is the metadata type}}',
paramsButtonConfig: [
{
type: 'query',
pressed: true,
},
{
type: 'metadata',
tooltip: 'This is the metadata button',
handler: function handleClick(button, clickEvent) {
ExtjsUtils.ALERTIFY.log('You\'ve clicked the metadata button');
},
},
],
},
],
},
]// Example on how to use the download type paramsButtonConfig
[
{
title: 'Example of paramButtonConfig types',
color: '#FFA500',
elements: [
{
title: 'This Layer has custom buttons on the Legend Window',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
startLegendOpen: true,
descriptionHtml:
'{{label|text=The last button is the download type}}',
paramsButtonConfig: [
{
type: 'query',
pressed: true,
},
{
type: 'download',
tooltip: 'This is the download button',
handler: function handleClick(button, clickEvent) {
ExtjsUtils.ALERTIFY.log('You\'ve clicked the download button');
},
},
],
},
],
},
]// Example on how to use the associated type paramsButtonConfig
[
{
title: 'Example of paramButtonConfig types',
color: '#FFA500',
elements: [
{
title: 'This Layer has custom buttons on the Legend Window',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
startLegendOpen: true,
descriptionHtml:
'{{label|text=The third button is the associated type}}'
+
'{{button|id=test_button|text=This is the custom associated button|enableToggle=true}}',
paramsButtonConfig: [
{
type: 'query',
pressed: true,
},
{
type: 'associated',
tooltip: 'This is the custom button',
associatedButtonID: 'test_button',
// The handler only triggers for the Legend Window button (not the descriptionHtml associatedButton)
handler: function handleClick(button, clickEvent) {
ExtjsUtils.ALERTIFY.log('You\'ve clicked the custom button');
},
},
],
},
],
},
]Row button callbacks
paramsButtonConfigFunctions2 entrieshandler
functioncallback# Defines a function that will be called when the associated button is clicked.
handlerDefines a function that will be called when the associated button is clicked.
- button Object
- is the button that was clicked by the mouse.
- clickEvent MouseEvent
- is the object that carries more information about the click event.
[
{
title: 'Example of callback when clicking in a Legend Window button',
color: '#A020F0',
elements: [
{
title: 'The handleClick function will be called when the query button is clicked',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
handler: function handleClick(button, clickEvent) {
ExtjsUtils.ALERTIFY.log('You clicked the query button');
},
},
],
},
],
},
]toggleHandler
function= nullcallback# This function is called whenever the associated button change its toggle state.
toggleHandlerThis function is called whenever the associated button change its toggle state. PS: Using custom function, ignore the associatedButtonID "It doesnt have to even exists".
- button Ext.Button
- The button element that was clicked
- state Boolean
- The next state of the button, true means pressed
[
{
title: 'Example of paramButtonConfig toogleHandler',
color: '#FFA500',
elements: [
{
title: 'Layer 1',
name: 'CSR:geologia',
source: 'calculate',
visibility: true,
paramsButtonConfig: [
{
type: 'query',
toggleHandler: function handleToggle(button, state) {
let queryButtonState = state ? 'pressed' : 'unpressed';
console.log(`Layer 1 query button is: ${queryButtonState}`);
},
},
],
},
],
},
]Kinds of layer: what each source adds
Published maps: styles from QGIS
QGIS1 entrystyles
String# Where a map's styles come from: they are not written in the query.
stylesWhere a map's styles come from: they are not written in the query. A map is published with one or more styles, and when it is published from QGIS the layer's QGIS style is converted at publication time, so the classes, colours and legend labels the map shows online are the ones set in QGIS. Each converted style becomes a Mappia style identifier - the map name without its namespace, plus _ and an index - and those identifiers are what a query selects with the styles property, what the layer's style chooser lists, and what the legend renders.
So changing how a map looks is a publication step, not a query change: restyle it in QGIS, publish again, and reference the style from the query.
{
...,
name: 'CSR:estados',
styles: 'estados_0',
...
}Calculated layers: raw maps and operation tokens
RawMaps1 entryoperations
Object# Enumeration of the operations a map of a source: 'calculate' layer can be decoded with.
operationsEnumeration of the operations a map of a source: 'calculate' layer can be decoded with. This is what the operation layer key selects, one token per map in name; the tokens are the lower-case names below, matched case and whitespace insensitive. The values are integers; getFromString(token) and getName(value) convert between the two forms.
- NORMAL (0, an empty or unknown token): a regular WMS image, each cell is a legend colour/category and not a Raw Map.
- RAW (1,
raw): each resulting cell has the value of the most centred original cell of the aggregated region. - RGBA (2,
rgba): each resulting cell is an integer packing the RGBA bytes of the pixel (input and output are integers). - SUM (3,
sum): each resulting cell is the weighted sum of the cells of the covered region, the weight being the covered fraction of each cell (VALUE * COVERED_PERCENTAGE). - AVERAGE (4,
average): each resulting cell is the weighted mean of the cells of the covered region. - MAX (5,
max): the greatest cell at least partially covered by the region. - MIN (6,
min): the smallest cell at least partially covered by the region. - INTEGRAL (7,
integral): summed-area table, so the sum inside any rectangle is obtained from its four corner cells only. - AREAINTEGRAL (8,
areaintegral): summed-area table of the covered areas (no further description in the source). - AREA (9,
area): each cell carries the original map area inside the aggregated region, so totals can be computed at any scale with full precision. - CELLS (10,
cells): weighted count of the original cells inside the region. Every operation other than NORMAL and RGBA requires the map to be published as a Raw Map that offers it.
LayerWorkerUtils.MapOperations.getFromString('sum'); // 3 (LayerWorkerUtils.MapOperations.SUM)
LayerWorkerUtils.MapOperations.getName(3); // 'SUM'Calculated layers: methods (this.)
LayerInternal14 entriescallFunction
function(name, anyArguments) : *method# Calls one of the layer's own functions by name with the layer as this.
callFunctionWritten as this.callFunction
Calls one of the layer's own functions by name with the layer as this. Extra arguments are passed through to the function.
- name String
- Key of the layer's
functionsobject. - anyArguments *
- Arguments forwarded to the function.
Returns Whatever the function returns.
this.callFunction('getAssociatedLayer'); // or this.callFunction('getAssociatedLayer', 'param1', 2, [], {}, 'param5');changeLayers
function(newConfigs, force)method# Replaces an internal layer at a given index.
changeLayersWritten as this.changeLayers
Replaces an internal layer at a given index. PS: It's highly recommended to pass multiple configurations in an array, instead of calling this function multiple times in the same callback.
- newConfigs Array|Object
- One or more layers configurations with a property 'index' indicating the replacing layer. Each config object must contain at least the following properties: [{name: 'MAP_FULL_NAME', styles: 'MAP_STYLE', index: 'MAP_INDEX_TO_CHANGE'}, ... ]
- force Boolean
- Force redraw even if no change is done when the layer is the same.
{
name: "CSR:rodovias,CSR:municipios",
otherNames: "CSR:roads",
beforeCalc: function(layerVals, inputVals) {
this.changeLayers([{name: 'CSR:roads', styles: fMapName + "_1", index: 0}]);
}
}generateNewLegend
function()method# Schedules a new legend: cancels the calculations in progress, runs beforeCalc(inputs) with the current input values and, when every tile is loaded and the layer is not paused, recalculates the map and its legend.
generateNewLegendWritten as this.generateNewLegend
Schedules a new legend: cancels the calculations in progress, runs beforeCalc(inputs) with the current input values and, when every tile is loaded and the layer is not paused, recalculates the map and its legend. It is the supported way to force the layer to refresh itself from outside a normal calculation cycle (for example from onVisibilityChange or a {{button}} handler).
onVisibilityChange: function(visible, inputs) {
if (visible && !this.isCalculationPaused()) {
this.generateNewLegend();
}
}getInputs
function() : Arraymethod# Returns the current value of every input tool declared in descriptionHtml, in declaration order (the same array beforeCalc, expression and afterCalc receive as inputs).
getInputsWritten as this.getInputs
Returns the current value of every input tool declared in descriptionHtml, in declaration order (the same array beforeCalc, expression and afterCalc receive as inputs). A value can be a simple one (number, string) or a complex object (a CSV table, a picked point, ...). Use it from callbacks that do not receive inputs, such as a {{button}} handler.
Returns The input values in the order the tools are declared.
functions: {
onClickButton: function() {
var inputs = this.getInputs();
ExtjsUtils.ALERTIFY.log('First input: ' + inputs[0]);
}
}getInsideLayers
function() : Array.<OpenLayers.Layer.WMS>method# Returns the OpenLayers WMS layers that compose this layer, one per map in name and in the same order (a copy of the internal array, so changing it does not affect the layer).
getInsideLayersWritten as this.getInsideLayers
Returns the OpenLayers WMS layers that compose this layer, one per map in name and in the same order (a copy of the internal array, so changing it does not affect the layer).
Returns The inside layers.
var firstMapName = this.getInsideLayers()[0].params.LAYERS;getLayerDefinedFunctionsByName
function(name) : function|undefinedmethod# Returns one of the functions declared in the layer's functions object by its name (the same functions that markup tools reference by name, e.g. handler=onClick).
getLayerDefinedFunctionsByNameWritten as this.getLayerDefinedFunctionsByName
Returns one of the functions declared in the layer's functions object by its name (the same functions that markup tools reference by name, e.g. handler=onClick). Composed-layer twin of VectorLayer.getLayerDefinedFunctionsByName; the returned function is not bound, so call it with .call(this, ...) from a layer callback to keep the layer as this.
- name String
- Key of the layer's
functionsobject.
Returns The function, or undefined when there is no function with that name.
{
name: 'CSR:geologia',
source: 'calculate',
functions: {
onClick: function(feature, inputs) { ExtjsUtils.ALERTIFY.log('clicked'); }
},
beforeCalc: function(inputs) {
this.getLayerDefinedFunctionsByName('onClick').call(this, null, inputs);
},
}getLegendEntries
function() : Array.<{color: Array.<Number>, title: String, isNull: Boolean}>method# Returns the entries of the legend currently applied to the calculated map, in legend order.
getLegendEntriesWritten as this.getLegendEntries
Returns the entries of the legend currently applied to the calculated map, in legend order. Each entry has the [R, G, B] colour of the pixels, the title shown in the legend (the value itself when no title was defined) and whether it represents the null value of the map. Returns an empty array before the first legend is generated. Use it to build a custom legend (e.g. an HTML gradient) or to map a colour back to its category.
Returns The legend entries.
afterCalc: function(inputs) {
var html = this.getLegendEntries().map(function(entry) {
return '<span style="background: rgb(' + entry.color.join(',') + ')">' + entry.title + '</span>';
}).join('');
}getVisibleLayerIndexes
function() : Array.<Number>method# Returns the indexes (positions in the name list) of the composing maps that are currently visible, in ascending order.
getVisibleLayerIndexesWritten as this.getVisibleLayerIndexes
Returns the indexes (positions in the name list) of the composing maps that are currently visible, in ascending order. Useful inside beforeCalc/expression when some of the inside maps were toggled with setInsideLayerVisibility().
Returns Indexes of the visible inside maps.
beforeCalc: function(inputs) {
var visible = this.getVisibleLayerIndexes(); // e.g. [0, 2]
}isCalculationPaused
function() : Booleanmethod# Returns calculation status.
isCalculationPausedWritten as this.isCalculationPaused
Returns calculation status. True if calculations are paused, false otherwise.
Returns Calculation is paused
pauseAndStopCalculations
function()method# Cancels the calculations in progress and pauses the start of new ones (the "generating legend" indicator is shown while paused).
pauseAndStopCalculationsWritten as this.pauseAndStopCalculations
Cancels the calculations in progress and pauses the start of new ones (the "generating legend" indicator is shown while paused). Call it when something the expression depends on starts loading, and resumeCalculations() when it is done. The pause is cumulative: every call needs a matching resumeCalculations() before the layer calculates again (isCalculationPaused() tells the state).
onInputsReady: function(inputs) {
var layer = this;
layer.pauseAndStopCalculations();
ExtjsUtils.REQUEST.get('https://maps.csr.ufmg.br/theme/app/data/example.json', function(resp) {
layer.myData = JSON.parse(resp.responseText);
layer.resumeCalculations(); // redraws with the loaded data
});
}resumeCalculations
function(qnt)method# Undoes pauseAndStopCalculations().
resumeCalculationsWritten as this.resumeCalculations
Undoes pauseAndStopCalculations(). Call it whenever a resource finished loading; when the last pending pause is released the layer is redrawn (which recalculates it).
- qnt Number
- How many pauses to release at once.
0releases nothing and never redraws; omitted means 1.
this.resumeCalculations();setCalculateLegend
function(legendEntries)method# Defines the legend of the calculated map yourself, which also skips the automatic legend calculation for this cycle.
setCalculateLegendWritten as this.setCalculateLegend
Defines the legend of the calculated map yourself, which also skips the automatic legend calculation for this cycle. It is meant to be called inside beforeCalc, the moment right before a new legend would be computed, but it can also be called from a tool callback (e.g. a {{button}} handler). When the given entries equal the current legend nothing is redrawn.
- legendEntries Array.<{color: Array.<Number>, value: *, title: String}>
- Legend entries sorted by
valuein ascending order (entries out of order are ignored).coloris the[R, G, B]colour of the entry,valuethe highest value that maps to it,titlethe label shown in the legend.
beforeCalc: function(inputs) {
this.setCalculateLegend([
{color: [0, 0, 255], value: 500, title: 'Up to 500 m'},
{color: [255, 255, 0], value: 1000, title: 'From 500 m to 1000 m'},
{color: [255, 0, 0], value: 3000, title: 'Above 1000 m'},
]);
}setInsideLayerVisibility
function(visibility, layerIndex)method# Shows or hides the maps that compose the layer (the ones listed in name) without touching the layer itself.
setInsideLayerVisibilityWritten as this.setInsideLayerVisibility
Shows or hides the maps that compose the layer (the ones listed in name) without touching the layer itself. Pass layerIndex to change one map only, omit it to change all of them. The platform hides every inside map when the layer has an expression() (only the calculated result is shown) and shows them all otherwise; use this to reveal one of the source maps behind a calculated result.
- visibility Boolean
- True to show the map(s), false to hide them.
- layerIndex Number
- Index of the map in the
namelist; when omitted every inside map is changed.
afterCalc: function(inputs) {
this.setInsideLayerVisibility(true, 0); // show the first source map under the calculated result
}setLayerOperation
function(layerIndex, operation)method# Sets the decoding operation of one of the maps of the composed layer (the same tokens accepted by the operation layer key, e.g. 'raw', 'sum', 'average'; '' or null means the default decoding).
setLayerOperationWritten as this.setLayerOperation
Sets the decoding operation of one of the maps of the composed layer (the same tokens accepted by the operation layer key, e.g. 'raw', 'sum', 'average'; '' or null means the default decoding). The platform calls it from the operation key at creation; when called at runtime the new operation is only used after the map legends are read again (for example when changeLayers replaces a map).
- layerIndex Number
- Index of the map in the
namelist (0 based). - operation String
- Operation token, or
''/nullfor the default decoding.
this.setLayerOperation(1, 'sum');Calculated layers: this inside expression
ValuesCalculation7 entriescalcTilesValues
function(imageDataTiles, inputs) : Array.<(Number|String)>method# Internal — the pixel loop of a calculate layer: for every pixel of the tile it reads one value per inner map (colour looked up in the map's legend, or the raw cell value for raw/sum/... …
calcTilesValuesWritten as this.calcTilesValues
Internal — the pixel loop of a calculate layer: for every pixel of the tile it reads one value per inner map (colour looked up in the map's legend, or the raw cell value for raw/sum/... operations) and calls the layer's expression(layersVals, inputs) with them. Pixels that are null in every map become this.nullValue without calling the expression. The expression is invoked with this bound to this ValuesCalculation instance, which is why this.isNumeric(v) works inside an expression (ValuesCalculation.prototype.isNumeric(v) also works). Tenant code never calls this directly; the layer worker does.
- imageDataTiles Array.<Uint8ClampedArray>
- One ImageData
dataarray per inner map, for the same tile position (without the result tile). - inputs Array
- The layer's input values, in the order defined for the layer (what
expressionreceives as its second argument).
Returns One result per pixel, in the tile's pixel order.
getColorFromInt
function(value) : Array.<Number>method# Unpacks the four RGBA bytes packed in a 32-bit integer: byte 0 (lowest) is red, byte 1 green, byte 2 blue and byte 3 alpha.
getColorFromIntWritten as this.getColorFromInt
Unpacks the four RGBA bytes packed in a 32-bit integer: byte 0 (lowest) is red, byte 1 green, byte 2 blue and byte 3 alpha. This is the packing the rgba map operation uses, where a pixel colour travels as one integer (the layer worker paints such results with getNonNullColorFromInt). Inside an expression function this is the ValuesCalculation instance, so this.getColorFromInt(v) works there; ValuesCalculation.prototype.getColorFromInt(v) also works, anywhere.
- value Number
- The packed RGBA integer.
Returns [r, g, b, a], each component in 0..255.
ValuesCalculation.prototype.getColorFromInt(0xFF0080FF); // [255, 128, 0, 255]expression: function(layersVals, inputs) {
var rgba = this.getColorFromInt(layersVals[0]); // an inner map with operation: "rgba"
return rgba[3] === 0 ? this.nullValue : (rgba[0] + rgba[1] + rgba[2]) / 3; // grey level
}getNonNullColorFromInt
function(value, nullValues) : Array.<Number>|nullmethod# getColorFromInt with a null check: returns this.nullColor (null) when the packed integer is one of the values listed in nullValues, and the unpacked [r, g, b, a] otherwise.
getNonNullColorFromIntWritten as this.getNonNullColorFromInt
getColorFromInt with a null check: returns this.nullColor (null) when the packed integer is one of the values listed in nullValues, and the unpacked [r, g, b, a] otherwise. Handy when a map encodes "no data" as one or more specific colours. Inside an expression function this is the ValuesCalculation instance, so this.getNonNullColorFromInt(v, nulls) works there; ValuesCalculation.prototype.getNonNullColorFromInt(v, nulls) also works, anywhere.
- value Number
- The packed RGBA integer (see
getColorFromInt). - nullValues Array.<Number>
- Packed integers that should be treated as null.
Returns [r, g, b, a], or null when value is in nullValues.
expression: function(layersVals, inputs) {
var rgba = this.getNonNullColorFromInt(layersVals[0], [0, 0xFFFFFFFF]);
return rgba === null ? this.nullValue : rgba[0];
}getValueFromLegend
function(legend) : Number|String|nullmethod# Turns a legend label into the value that best represents it — the same conversion the calculation applies to every map legend before the expression sees layersVals.
getValueFromLegendWritten as this.getValueFromLegend
Turns a legend label into the value that best represents it — the same conversion the calculation applies to every map legend before the expression sees layersVals. A numeric label ("12", "1,5", "1.000") becomes that number (a single comma is read as the decimal separator, "1.000"/"1,000" as thousands), a range ("10 - 20", "10 – 20", "10 to 20") becomes its midpoint, a leading comparison operator ("> 800", "<= 5", "> 800") is stripped first, and any other text ("Floresta") is returned unchanged. An empty label returns null. Use it to interpret legend titles you read with ExtjsUtils.LAYER.getLayerLegend the same way the layer does. Inside an expression function this is the ValuesCalculation instance, so this.getValueFromLegend(label) works there; ValuesCalculation.prototype.getValueFromLegend(label) also works, anywhere. To mark a pixel transparent, pass/return this.nullValue.
- legend String
- The legend title to interpret.
Returns The number the label represents, the label itself when it is not numeric, or null when it is empty.
ValuesCalculation.prototype.getValueFromLegend("10 - 20"); // 15
ValuesCalculation.prototype.getValueFromLegend("> 800"); // 800
ValuesCalculation.prototype.getValueFromLegend("1,5"); // 1.5
ValuesCalculation.prototype.getValueFromLegend("Floresta"); // "Floresta"isNumeric
function(value) : Booleanmethod# Tells whether a value represents a number: a Number, or a String that is a plain decimal/exponential number ("12", "-3.5", "1e3").
isNumericWritten as this.isNumeric
Tells whether a value represents a number: a Number, or a String that is a plain decimal/exponential number ("12", "-3.5", "1e3"). Map values read from a legend can be either a number or the legend's text (e.g. "Floresta"), so use this in an expression before doing arithmetic on layersVals[i]. Inside an expression function this is the ValuesCalculation instance, so this.isNumeric(v) works there; ValuesCalculation.prototype.isNumeric(v) also works, anywhere.
- value String|Number
- The value to test.
Returns true when the value is numeric, false otherwise.
[{
name: "CSR:cultivo_cafe_cafe",
source: "calculate",
expression: function(layersVals, inputs) {
// layersVals[0] may be a legend label instead of a number
return this.isNumeric(layersVals[0]) ? layersVals[0] * inputs[0] : this.nullValue;
}
}]nullValue
Number# The value that stands for "no data" in a calculation: NaN.
nullValueWritten as this.nullValue
The value that stands for "no data" in a calculation: NaN. Return this.nullValue from an expression to leave the pixel transparent, and compare against it (with isNaN) when an inner map's value may be null. Inside an expression function this is the ValuesCalculation instance, so this.nullValue is the way to reach it there (ValuesCalculation.prototype.nullValue works anywhere).
expression: function(layersVals, inputs) {
if (isNaN(layersVals[0]) || layersVals[0] < inputs[0]) {
return this.nullValue; // transparent pixel
}
return layersVals[0];
}simplifyLegend
function(n) : Number|Stringmethod# Returns a shorter representation of a numeric value for display in a legend: values with an absolute value below 0.005 are written in exponential notation with 2 decimals, other values below 1 are …
simplifyLegendWritten as this.simplifyLegend
Returns a shorter representation of a numeric value for display in a legend: values with an absolute value below 0.005 are written in exponential notation with 2 decimals, other values below 1 are kept to 3 significant digits and everything else is rounded to 2 decimals. Non-numeric values are returned unchanged. Useful inside afterCalc or legendTitle code that formats the legend entries of a calculated layer. Inside an expression function this is the ValuesCalculation instance, so this.simplifyLegend(n) works there (and ValuesCalculation.prototype.simplifyLegend(n) works anywhere).
- n Number|String
- The value to simplify.
Returns The simplified value (a string when exponential notation or toPrecision was used), or n itself when it is not numeric.
ValuesCalculation.prototype.simplifyLegend(0.001234); // "1.23e-3"
ValuesCalculation.prototype.simplifyLegend(0.4567); // "0.457"
ValuesCalculation.prototype.simplifyLegend(1234.5678); // 1234.57Calculated layers: legend reader
JsonLegendReader7 entriesgetJsonLegend
function(layer) : Array.<Object>|undefined# Returns the loaded legend entries of a map: an array of {color: [r, g, b], title} objects in legend order, or undefined while the legend has not been loaded (or failed).
getJsonLegendReturns the loaded legend entries of a map: an array of {color: [r, g, b], title} objects in legend order, or undefined while the legend has not been loaded (or failed). This is the documented route to a map's legend — it accepts the layer object itself and is what ExtjsUtils.LAYER.getLayerLegend(composedLayer, index) uses; the inner jsonLegends.getJsonLegend(id) needs the unique id instead.
- layer OpenLayers.Layer|String
- The layer object (an inner map of a Composed layer, typically), or its unique id.
Returns The legend entries {color: Array<Number>, title: String}, or undefined when not loaded.
// inside afterCalc / onInputsReady of a Composed layer (this === the layer)
var entries = this.jsonLegendReader.getJsonLegend(this.layers[0]) || [];
entries.forEach(function(entry) {
console.log(entry.title, ExtjsUtils.HTML.rgbToColorStyle(entry.color));
});getLayerOperationCellType
function(layer, operation) : Number# Returns the cell type (LayerWorkerUtils.CellTypes: INT32, UINT32, FLOAT32) the calculation must use to decode a map under a given operation, as declared by the map's description metadata.
getLayerOperationCellTypeReturns the cell type (LayerWorkerUtils.CellTypes: INT32, UINT32, FLOAT32) the calculation must use to decode a map under a given operation, as declared by the map's description metadata. Falls back to INT32 when the map does not declare the operation (see hasOperation). Mostly informational for query authors; the calculation calls it itself.
- layer OpenLayers.Layer|String
- The layer object, or its unique id.
- operation Number
- The operation, one of
LayerWorkerUtils.MapOperations.
Returns The cell type, one of LayerWorkerUtils.CellTypes.
var cellType = layer.jsonLegendReader.getLayerOperationCellType(layer.layers[0], LayerWorkerUtils.MapOperations.RAW);
console.log(cellType === LayerWorkerUtils.CellTypes.FLOAT32);getLayerUniqueId
function(layer) : String# Returns the key under which the reader stores a layer's legend: the string itself when given a string, the layer's id (assigned by Ext.id) when given a WMS layer object, and an empty string for …
getLayerUniqueIdReturns the key under which the reader stores a layer's legend: the string itself when given a string, the layer's id (assigned by Ext.id) when given a WMS layer object, and an empty string for anything else (a layer without params). Use it to build the id the jsonLegends manager methods expect.
- layer OpenLayers.Layer|String
- The layer object, or an id already.
Returns The layer's unique id.
var id = layer.jsonLegendReader.getLayerUniqueId(layer.layers[0]);
var loaded = layer.jsonLegendReader.jsonLegends.wasLoaded(id);getLegend
function(layer, color) : String# Looks up the legend title of a colour in a map's legend: the title of the entry whose [r, g, b] equals the first three components of color.
getLegendLooks up the legend title of a colour in a map's legend: the title of the entry whose [r, g, b] equals the first three components of color. Returns an empty string when the map has no legend loaded, the colour is not in it, or color has fewer than three components. This is what turns a pixel colour read from an inner map into its class name (e.g. for a tooltip); for the Composed layer's own calculated legend use ExtjsUtils.LEGENDS.getColorTitle(layer, r, g, b) instead.
- layer OpenLayers.Layer|String
- The layer object, or its unique id.
- color Array.<Number>
- The colour to look up,
[r, g, b]or[r, g, b, a].
Returns The legend title, or "" when there is none.
var title = layer.jsonLegendReader.getLegend(layer.layers[0], [0, 128, 0]); // "Floresta"hasOperation
function(layerID, operationType) : Boolean# Tells whether a map supports a given decoding operation (see RawMaps.operations): the normal and rgba operations are always supported (they only need the WMS image), the others (raw, sum, …
hasOperationTells whether a map supports a given decoding operation (see RawMaps.operations): the normal and rgba operations are always supported (they only need the WMS image), the others (raw, sum, average, ...) only when the map's description metadata declares a cell type for them. Useful to check, after the legends loaded, whether an operation you plan to set on a layer will actually work.
- layerID OpenLayers.Layer|String
- The layer object, or its unique id.
- operationType Number
- The operation, one of
LayerWorkerUtils.MapOperations(e.g.LayerWorkerUtils.MapOperations.RAW).
Returns true when the map supports the operation.
var supportsRaw = layer.jsonLegendReader.hasOperation(layer.layers[0], LayerWorkerUtils.MapOperations.RAW);jsonLegends
Object# The legend store of the reader, keyed by layer unique id (see getLayerUniqueId: a layer's id, e.g. layer.layers[0].id for an inner map of a Composed layer).
jsonLegendsThe legend store of the reader, keyed by layer unique id (see getLayerUniqueId: a layer's id, e.g. layer.layers[0].id for an inner map of a Composed layer). Queries reach it as layer.jsonLegendReader.jsonLegends and mostly call getJsonLegend(id); prefer the outer getJsonLegend(layer) or ExtjsUtils.LAYER.getLayerLegend(layer, index) when you hold the layer object. Its four methods: getJsonLegend(layerUniqueId) → Array<{color: [r, g, b], title: String}>|undefined — the loaded legend entries (undefined while not loaded or after remove); setJsonLegend(layerUniqueId, legendArray) — stores a legend array for that id; wasLoaded(layerUniqueId) → Boolean — whether a legend (even an empty one) is stored; remove(layerUniqueId) — forgets the stored legend, so it is fetched again next time.
// colour of the legend entry whose title matches a value, for a Composed layer's first map
function getLegendColor(composedLayer, title) {
var entries = composedLayer.jsonLegendReader.jsonLegends.getJsonLegend(composedLayer.layers[0].id) || [];
for (var i = 0; i < entries.length; i++) {
if (entries[i].title === title) return ExtjsUtils.HTML.rgbToColorStyle(entries[i].color);
}
return null;
}setLayerLegend
function(layer, legendContent)# Stores the legend of a layer from its JSON content, replacing whatever the reader had for it.
setLayerLegendStores the legend of a layer from its JSON content, replacing whatever the reader had for it. The platform calls it when a legend request finishes; a query can call it to inject a legend for a map that has none (or to override the server's), e.g. before a calculate layer reads the legend values. A string is evaluated as JSON.
- layer OpenLayers.Layer|String
- The layer object, or its unique id (see
getLayerUniqueId). - legendContent String|Array.<Object>
- The legend: an array of
{color: [r, g, b], title: String}entries, or that array as JSON text.
layer.jsonLegendReader.setLayerLegend(layer.layers[0], [
{color: [0, 128, 0], title: "Floresta"},
{color: [255, 255, 0], title: "Agricultura"}
]);File layers: data
FileLayer5 entriesjson
Array.<Object>|Object# Inline data of a source: 'file' layer with type: 'json'.
jsonInline data of a source: 'file' layer with type: 'json'. Either a GeoJSON object (FeatureCollection, Feature or a geometry; its projection is taken from fromProj, its crs or guessed from the coordinates) or an array of plain objects, each converted to a feature with convertJsonEntryToFeature (see coordinates/getVector). A JSON string is also accepted.
{
name: 'CSR:inline_points',
source: 'file',
type: 'json',
fromProj: 'EPSG:4326',
json: [
{name: 'Belo Horizonte', lon: -43.94, lat: -19.92},
{name: 'Brasilia', lon: -47.88, lat: -15.79},
],
}loadData
function# Custom loader of a source: 'file' layer with type: 'load': function(inputs, config) called with the layer as this, receiving the current input values and the layer definition.
loadDataCustom loader of a source: 'file' layer with type: 'load': function(inputs, config) called with the layer as this, receiving the current input values and the layer definition. Add the features yourself (this.addFeatures, this.loadGeojson, ...) and trigger startLoadingLayer before and endLoadingLayer after every asynchronous load, so the layer knows when the data is ready (onInputsReady/onLoad depend on it).
{
name: 'CSR:filtered_file',
source: 'file',
type: 'load',
url: 'https://maps.csr.ufmg.br/theme/app/data/example.geojson',
loadData: function(inputs, config) {
var layer = this;
layer.events.triggerEvent('startLoadingLayer');
ExtjsUtils.REQUEST.get(config.url, function(resp) {
var geojson = JSON.parse(resp.responseText);
geojson.features = geojson.features.filter(function(feat) {
return feat.properties.area > 100;
});
layer.loadGeojson(geojson);
layer.events.triggerEvent('endLoadingLayer');
}, function() {
layer.events.triggerEvent('endLoadingLayer');
}, false, layer);
},
}onVisibilityChange
function# Callback when layer visibility is changed.
onVisibilityChangeCallback when layer visibility is changed.
PS: Is not called for the initial visibility of the layer.
[{...
onVisibilityChange: function(visibilityChangeEvent) {
alert("layer visibility changed");
}
}]
Layer scope and evt as parameter.type
String= "json"# Defines how a source: 'file' layer gets its features (case insensitive).
typeDefines how a source: 'file' layer gets its features (case insensitive). One of:
'load': you load the data yourself in the loadData callback (function(inputs, config), called with the layer as this).
The callback must trigger this.events.triggerEvent('startLoadingLayer') before and this.events.triggerEvent('endLoadingLayer') after each load (the calls are cumulative). 'csv': fetches the CSV file at url; each line becomes a feature through convertJsonEntryToFeature (see coordinates/getVector). 'json': uses the inline json data: a GeoJSON object (FeatureCollection, Feature or geometry) or an array of plain objects converted with convertJsonEntryToFeature. 'jsonurl': fetches an array of plain objects from url and converts each one with convertJsonEntryToFeature. 'geojsonurl': fetches a GeoJSON file from url (projection detected from its crs, fromProj or the coordinates). 'empty': creates no feature; the usual choice for layers that are drawn into or filled later with loadGeojson/addFeatures.
When omitted the type is 'json'; an unknown value falls back to 'jsonurl'.
[
{
title: 'Vector layers',
color: '#FFA500',
elements: [
{
title: 'Municipalities from a GeoJSON file',
name: 'CSR:municipalities_file',
source: 'file',
type: 'geojsonurl',
url: 'https://maps.csr.ufmg.br/theme/app/data/example.geojson',
visibility: true,
},
{
title: 'Empty layer to draw on',
name: 'CSR:drawing_file',
source: 'file',
type: 'empty',
visibility: true,
},
],
},
]url
String# URL of the data of a source: 'file' layer, used by the types csv (a CSV file), jsonurl (a JSON array of plain objects) and geojsonurl (a GeoJSON file).
urlURL of the data of a source: 'file' layer, used by the types csv (a CSV file), jsonurl (a JSON array of plain objects) and geojsonurl (a GeoJSON file). Relative URLs are resolved against the Mappia page. Also available inside loadData as config.url for type: 'load'.
{
name: 'example_points',
source: 'file',
type: 'jsonurl',
// shipped with the platform: [{"lon":-50, "lat":-10, "name":"name1"}, ...]
url: '/theme/app/data/points_example.json',
coordinates: {x: 'lon', y: 'lat'},
}File layers: style, events, drawing
VectorLayer44 entriesactivateDrawMode
function(mode) : Boolean# Select polygon/line tool and enter edit mode when needed (split-button menu).
activateDrawModeSelect polygon/line tool and enter edit mode when needed (split-button menu).
- mode String
- 'polygon' or 'line' — must be one of the layer's configured
drawModes.
Returns true if the mode was activated (entering edit mode if not already active); false if mode isn't in the layer's drawModes.
applyFeatureChanges
function() : Boolean# Finish sketch or deselect feature (triggers featureEditEnd when applicable).
applyFeatureChangesFinish sketch or deselect feature (triggers featureEditEnd when applicable).
Returns true if a sketch was finished or a feature was deselected; false if there was no active modify control.
applyGeomOp
function(sourceGeoms, options) : Object# Replace geometries on this drawable VectorLayer with id/attribute control via one options object.
applyGeomOpReplace geometries on this drawable VectorLayer with id/attribute control via one options object. Only available on vector layers from VectorFileSource (e.g. drawable: true). Implementation helpers live in {@link DrawableSplit.applyGeomOp}.
- sourceGeoms Array.<OpenLayers.Geometry>
- Features selected by
feature.geometryidentity. - options Object|function
- If a function, treated as
{ operation: fn }. - options.operation String|function
'difference'|'intersection'|'keep'orfunction(sourceGeom, sourceFeature) => Geometry[].- options.with OpenLayers.Geometry
- Operand for difference / intersection.
- options.attributes String|function
'keep'|'empty'orfunction(sourceAttrs, pieceIndex, pieceCount) => Object.- options.preserveId Boolean
- First piece of each source keeps OpenLayers id/fid.
// Cut overlaps (difference) — ``layer`` must be a drawable VectorLayer
layer.applyGeomOp(intersecting, {
operation: 'difference', with: editedUnion
});
// Clip to CAR (intersection)
layer.applyGeomOp(outsideGeoms, {
operation: 'intersection', with: carGeometry
});
// Custom pieces + empty attrs
layer.applyGeomOp(geoms, {
operation: function(g) { return [myTransform(g)]; },
attributes: 'empty'
});callFunction
function(name, anyArguments) : *# Calls one of the layer's own functions by name with the layer as this; falls back to a method of the layer with that name.
callFunctionCalls one of the layer's own functions by name with the layer as this; falls back to a method of the layer with that name. Extra arguments are passed through to the function.
- name String
- Key of the
functionsobject (or a layer method name). - anyArguments *
- Arguments forwarded to the function.
Returns Whatever the function returns; undefined when no function was found.
{...
functions: {
FUNCTION_NAME: function(parameter1) {
var layer = this;
console.log(this, parameter1);
}
},
beforeCalc: function () {
this.callFunction('FUNCTION_NAME', 'parameter1');
}
}cancelDrawing
function() : Boolean# Cancel the in-progress sketch/edit without committing changes.
cancelDrawingCancel the in-progress sketch/edit without committing changes.
Returns true if a sketch was cancelled; false if there was no active modify control.
cluster
Object# AnimatedCluster options.
clusterAnimatedCluster options. Truthy object enables clustering even when clusterDistance is omitted.
Zoom / map state is not passed into callbacks — read it yourself via this.layer.map (call scope is the strategy) or ExtjsUtils.JS.getMap().
cluster: {
distance: function() {
return this.layer.map.getZoom() > 14 ? 40 : 80;
},
clusterKey: function(feature) {
var zoom = this.layer.map.getZoom();
if (zoom <= 10) return feature.attributes.regiao;
if (zoom <= 14) return feature.attributes.bairro;
return null; // distance only
},
clusterGeometry: function(cluster) {
var key = cluster.attributes.clusterKey;
var zoom = this.layer.map.getZoom();
if (zoom <= 10 && REGION_GEOMS[key]) return REGION_GEOMS[key];
if (zoom <= 14 && BAIRRO_GEOMS[key]) return BAIRRO_GEOMS[key];
return this.defaultClusterGeometry(cluster); // hull / point
},
minClusterPolygonPx: 28
}clusterDistance
Numeric# Defines the minimum relative distance (in pixels) to clusterize points.
clusterDistanceDefines the minimum relative distance (in pixels) to clusterize points. Set 0 to never clusterize, or a value greater than 0 to set the minimum distance. For a membership key or dynamic distance, use {@link VectorLayer.cluster} instead (or together — cluster options win; clusterDistance fills default distance). PS: When filters are applied, you can use the property 'count' on 'VectorLayer.styleMap' property to check how many points exists in the current cluster.
(Standalone doc comment: the value is read inside strategies below, which carries the cluster block, so this one is named explicitly.)
convertJsonEntryToFeature
function(curObj, optionalGetLonLat) : OpenLayers.Feature.Vector# Converts a JsonObject into a Layer Feature (that can be added to layer).
convertJsonEntryToFeatureConverts a JsonObject into a Layer Feature (that can be added to layer).
- curObj JsonObject
- Object with properties.
- optionalGetLonLat function
- Optional function to get position coordinates from JSON. P.S.: Optional function to get X,Y values from Obj. (By default Longitude and Latitude use fields: lon and lat) function optionalGetLonLat(curObj) returns OpenLayers.LonLat curObj: Object with JSON properties. This function receive the 'curObj' and expects to returns the object properties.
Returns Returns the Feature from JsonObj.
coordinates
Object# Redefines the coordinate property names to {x, y}.
coordinatesRedefines the coordinate property names to {x, y}. PS: Used only if the 'VectorLayer.getVector' is not defined.
coordinates: {
'x': 'lon',
'y': 'lat'
}defaultStyle
Object# Defines the default style that will be applied to the geometry.
defaultStyleDefines the default style that will be applied to the geometry. PS: Accepts 'context' and 'rules'.
Property 'context': allows definition of functions.
Property 'rules': allows definition of filters (only the geometries that fit into this rule will be displayed).
Look at some examples at: http://dev.openlayers.org/examples/
defaultStyle: {color: '${getColor}', context: {getColor: function(attr){return 'green';} }deselectFeature
function() : Boolean# Deselect the currently selected/edited feature without discarding it.
deselectFeatureDeselect the currently selected/edited feature without discarding it.
Returns true if a feature was deselected; false if there was no active modify control or nothing was selected.
drawable
Boolean|Object# Makes a vector layer editable: users can sketch, edit and delete polygon (optionally polygon+line) features, with configurable overlap resolution.
drawableMakes a vector layer editable: users can sketch, edit and delete polygon (optionally polygon+line) features, with configurable overlap resolution. Set to true for defaults, or an object to configure:
maxGeomCount{Number} — maximum number of features allowed on the layer.onFeaturesChange{Function(evt)} — fires on any feature-set change
(add/remove/clear/load);evt.typeidentifies the cause.onGeomLimitReached{Function} — called when a draw attempt would exceedmaxGeomCount.onEditToggle{Function(active, detail)} — sketch/edit mode turned on or off.
detail:{ active, editingIntent, reason },reasonis'toggle'(user/tenant)
or'visibility'(layer show/hide).onDrawingStatusChange{Function(detail)} — fine-grained sketch/edit state for UI.
detail.status:'off'|'ready'|'drawing'|'drawing_line'|'feature_selected'|'vertex_drag',
plusdrawMode,canFinishDrawing,canApplyFeatureChanges,sketchPointCount,
selectedFeature.drawModes{Array<String>} —['polygon'](default) or['polygon','line'],
the sketch tools available in edit mode. Alias:drawingTypes.drawingHints{String|Boolean} —false|true|'toolbar'|'bar'|'both',
lightweight on-map edit guidance.onOverlap{String|Array<String>} — a single action key (applied without prompt)
or an ordered list of keys to prompt for when a new/edited feature overlaps
another. Defaults to merge/cut/keep ({@link DrawableSplit.OVERLAP_ACTIONS}).
Applied bylayer.resolveOverlap.buttons{Object} — layer-row toolbar overrides:edit,clear,removeLast,loadFile.
Exposed at runtime as layer.drawableController — see VectorLayer.activateDrawMode, VectorLayer.finishDrawing, VectorLayer.cancelDrawing, VectorLayer.deselectFeature, VectorLayer.applyFeatureChanges.
[{
name: "CSR:file_draw", source: "file", type: "empty",
drawable: {
maxGeomCount: 5,
drawModes: ['polygon', 'line'],
onOverlap: ['merge', 'cut', 'keep'],
onDrawingStatusChange: function(detail) { console.log(detail.status); },
onEditToggle: function(active, detail) { console.log(active, detail.reason); }
}
}]fillGeometryLayer
function(config)# Loads (or reloads) the layer's features from a data-loading config, following its type strategy: load calls config.loadData, csv/jsonurl/ geojsonurl fetch config.url, json uses the …
fillGeometryLayerLoads (or reloads) the layer's features from a data-loading config, following its type strategy: load calls config.loadData, csv/jsonurl/ geojsonurl fetch config.url, json uses the inline config.json, empty adds nothing. Unknown types fall back to jsonurl. This is what the platform calls with the layer definition; call it yourself to swap the data at runtime.
- config GeometryLayerConfig
- Data-loading configuration.
layer.fillGeometryLayer({
url: 'https://maps.csr.ufmg.br/theme/app/data/conab/limite_macroregioes.geojson',
type: 'load',
loadData: function(inputs, config) {
var layer = this;
function featFilterCb(feat){
return ['31', '35'].indexOf(feat.properties.geocodigo.toString().substring(0, 2)) !== -1;
}
layer.events.triggerEvent('startLoadingLayer');
ExtjsUtils.REQUEST.get(config.url, function(resp) {
var jsonObjects = JSON.parse(resp.responseText);
jsonObjects.features = jsonObjects.features.filter(featFilterCb);
layer.addFeatures(layer.convertGeojson2Features(jsonObjects));
layer.events.triggerEvent('endLoadingLayer');
}, function() {
layer.events.triggerEvent('endLoadingLayer');
}, false, layer);
}
})findFeatureById
function(featureId) : OpenLayers.Feature.Vector|null# Find a feature by the id returned from getFeatureId (fid, id, or index).
findFeatureByIdFind a feature by the id returned from getFeatureId (fid, id, or index). Prefer this over OpenLayers getFeatureById when callers use getFeatureId ids.
- featureId String|Number
- Id as returned by
getFeatureId.
Returns The matching feature, or null.
finishDrawing
function() : Boolean# Commit in-progress polygon sketch (same as double-click).
finishDrawingCommit in-progress polygon sketch (same as double-click).
Returns true if a sketch was committed; false if there was no active modify control.
fromProj
String# Defines the projection of the JSON (accepts only EPSG:4326 and EPSG:900913).
fromProjDefines the projection of the JSON (accepts only EPSG:4326 and EPSG:900913).
EPSG:900913generateNewLegend
function()# Runs the layer's beforeCalc(inputs) again with the current input values.
generateNewLegendRuns the layer's beforeCalc(inputs) again with the current input values. It is the supported way to force a vector layer to refresh whatever beforeCalc builds (styles, filters, charts) from outside a normal cycle, for example from onVisibilityChange; the platform calls it itself when a resource finishes loading. Guard it with isCalculationPaused() and waitingRenderAndLoadAssync so it does not run while data is still loading.
onVisibilityChange: function(evt) {
if (this.getVisibility() && !this.isCalculationPaused() && this.waitingRenderAndLoadAssync == 0) {
this.generateNewLegend();
}
}getEditingFeatureId
function() : String|Number|null# Feature id currently selected for vertex edit (drawable modify control), if any.
getEditingFeatureIdFeature id currently selected for vertex edit (drawable modify control), if any.
getFeatureId
function(feature) : String|Number|null# Stable-enough id for a feature on this layer: fid, then OpenLayers id, otherwise the feature's index in layer.features (no synthetic attributes).
getFeatureIdStable-enough id for a feature on this layer: fid, then OpenLayers id, otherwise the feature's index in layer.features (no synthetic attributes).
- feature OpenLayers.Feature.Vector
- Feature of this layer.
Returns Its fid, id or index; null when it is not on the layer.
getInputs
function() : Array# Returns the current value of every input tool declared in descriptionHtml, in declaration order (the same array the layer callbacks receive as inputs).
getInputsReturns the current value of every input tool declared in descriptionHtml, in declaration order (the same array the layer callbacks receive as inputs). Use it from callbacks that do not receive inputs, such as a {{button}} handler or onFeatureChangeCallback.
Returns The input values in the order the tools are declared.
var firstInput = this.getInputs()[0];getLayerDefinedFunctionsByName
function(name) : function|Undefined# Gets the layer inner function.
getLayerDefinedFunctionsByNameGets the layer inner function.
Define the layer inner function at VectorLayer. Ex: {
name: 'CSR:map_name',
function: {
nameFunctionExample: function(){alert('a');}
} }
- name String
- Function name
getVector
function# Defines the callback function to parse the layer data and get the geometry.
getVectorDefines the callback function to parse the layer data and get the geometry. Callback Function getVector function(attribute, config)
- attribute Object
- Object with attributes.
- config Object
- Layer config.
Returns Return or the lat long point or the vector with the complex geometry.
hoverSelectedStyle
Object# Defines the style that will be applied to the geometry when the mouse hovers over a selected feature.
hoverSelectedStyleDefines the style that will be applied to the geometry when the mouse hovers over a selected feature. Default hover selected style is the selected style
PS: Accepts 'context' and 'rules'.
Property 'context': allows definition of functions.
Property 'rules': allows definition of filters (only the geometries that fit into this rule will be displayed). PS2: Hover Select depends on both 'onHover' and 'onClick' properties to work.
Look at some examples at: http://dev.openlayers.org/examples/
[{color: '${getColor}', context: {getColor: function(attr){return 'green';} }]hoverStyle
Object# Defines the style that will be applied to the geometry when mouse is hovering.
hoverStyleDefines the style that will be applied to the geometry when mouse is hovering. PS: Accepts 'context' and 'rules'.
Property 'context': allows definition of functions.
Property 'rules': allows definition of filters (only the geometries that fit into this rule will be displayed). PS2: Hover depends on 'onHover' property that allows to hovering.
Look at some examples at: http://dev.openlayers.org/examples/
[{color: '${getColor}', context: {getColor: function(attr){return 'green';} }]llbbox
OpenLayers.Bounds# Bounds of the features currently on the layer, recomputed automatically after features are added or removed (and extended while drawing).
llbboxBounds of the features currently on the layer, recomputed automatically after features are added or removed (and extended while drawing). Despite the name it is expressed in the map projection, not in lon/lat, so it can be passed straight to map.zoomToExtent. Read-only; undefined until the first feature is added.
onLoad: function(inputs) {
if (this.llbbox) {
app.mapPanel.map.zoomToExtent(this.llbbox);
}
}loadGeojson
function()# Function to load geojson and draw on the layer.
loadGeojsonFunction to load geojson and draw on the layer.
onAdded
function()# Called when the layer is on the map with its features loaded.
onAddedCalled when the layer is on the map with its features loaded. If the layer is still fetching (jsonurl / geojsonurl / csv / async load), waits for that load to finish first so this.features / this.getDataExtent() are available (a failed load still calls it). this is the layer.
AddedEvent {
element: {DOM} 'DOM element of the layer',
layer: {OpenLayers.Layer.Vector} 'Javascript Object of the layer',
map: {Map} 'MapPanel where the layer was added.',
type: {String} 'Type of the event ( added )' }
onAdded: function(evt) {
var bounds = this.getDataExtent();
if (bounds) ExtjsUtils.JS.getMap().zoomToExtent(bounds);
}onBeforeFeatureChangeCallback
function# Defines the callback function that is called before a layer feature is added, removed or edited.
onBeforeFeatureChangeCallbackDefines the callback function that is called before a layer feature is added, removed or edited. PS: If it returns false, the change operation is canceled.
- operationType String
- Receive the operation type: 'add' or 'remove' when adding or removing respectively.
- arrFeatures Array
- Array of features affected.
{
...,
onBeforeFeatureChangeCallback: function(operationType, arrFeatures) {
},
...
}onClick
function# Defines the callback function to the click event on Layer.
onClickDefines the callback function to the click event on Layer.
- event Object
- The click event Object.
- source VectorFileSource
- Auxiliary functions to deal with Vector Layer.
- inputs Array.<Object>
- Array with all layer input values.
{
...,
onClick: function (feature) {
console.log(feature.attributes);
console.log("Triggered click event!");
},
...
}[{
name:"CSR:FileGeojson",
source: "file",
type: "geojsonurl",
url: "/theme/app/data/fip_interativo/amazonia/amazonia_municipios.geojson",
onClick: function(feature, layerSource, inputs, toggleStatus) {
console.log(arguments);
}
}]onClickCfg
function# Defines the callback function to the Click Select controller.
onClickCfgDefines the callback function to the Click Select controller. The additional parameters are listed in http://dev.openlayers.org/docs/files/OpenLayers/Control/SelectFeature-js.html.
onFeatureChangeCallback
function# Defines a function that is called after a layer feature is added, removed or edited.
onFeatureChangeCallbackDefines a function that is called after a layer feature is added, removed or edited.
- operationType String
- One of:
'add'(features added in bulk, e.g. after loading data),'add1'(a single feature added interactively),'remove'(features removed),'editend'(a drawable-layer sketch/edit was committed),'editvertex'(a vertex was dragged/modified while editing). - arrFeatures Array
- Array of features affected.
- detail Object
- Optional context. For
editend:{ drawMode: 'polygon'|'line' }.
{
...,
onFeatureChangeCallback: function (operationType, arrFeatures) {
},
...
}onHover
function# Defines the callback function on 'Vector Layer' hover.
onHoverDefines the callback function on 'Vector Layer' hover.
- evt Object
- Features.
- state Boolean
- True when hover starts, false when it ends.
- controller Object
- The controller itself.
- inputs Object
- Layer widget values.
{
...,
onHover: function (evt, state, controller, inputs) {
console.log(state ? "Started": "Ended");
},
...
}[{
name:"CSR:FileGeojson",
source: "file",
type: "geojsonurl",
url: "/theme/app/data/fip_interativo/amazonia/amazonia_municipios.geojson",
onHover: function(feature, state, controller, inputs) {
console.log(feature.attributes);
console.log(arguments);
}
}]onInputsReady
function# Called when all inputs are ready on layer.
onInputsReadyCalled when all inputs are ready on layer.
onLoad
function# Defines the callback function to be called after the layer is loaded or added to a map.
onLoadDefines the callback function to be called after the layer is loaded or added to a map. PS: You can use 'this' to access layer properties.
- widgetValues Array
- inputs for onLoad callback
{
...,
onLoad: function (widgetValues) {
print(this.title) // prints the layer title
},
...
}onSelectionToggle
function# Defines the callback function to the unselect feature.
onSelectionToggleDefines the callback function to the unselect feature.
- event Object
- The click event Object.
- source VectorFileSource
- Auxiliary functions to deal with Vector Layer.
- inputs Array.<Object>
- Array with all layer input values.
[{
name:"CSR:FileGeojson",
source: "file",
type: "geojsonurl",
url: "/theme/app/data/fip_interativo/amazonia/amazonia_municipios.geojson",
onSelectionToggle: function(feature, layerSource, inputs, toggleStatus) {
console.log(feature.attributes);
alert(toggleStatus);
}
}]popupCallback
function# Not implemented for file layers: accepted but never called (see popupTemplate).
popupCallbackNot implemented for file layers: accepted but never called (see popupTemplate). Use onClick, which receives the clicked feature.
- attributes Array
- attributes for popupCallback
- inputs Array
- inputs for popupCallback
{
...,
popupCallback: function (attributes, inputs) {
},
...
}popupTemplate
String# Not implemented for file layers: the value is accepted and kept on the layer, but nothing reads it, so no popup ever opens (the template belongs to the gxp feed sources this layer does not extend).
popupTemplateNot implemented for file layers: the value is accepted and kept on the layer, but nothing reads it, so no popup ever opens (the template belongs to the gxp feed sources this layer does not extend). Show a feature's attributes from onClick instead - for example with ExtjsUtils.ALERTIFY.log or ExtjsUtils.TooltipHelper.CreateTooltipOnPosition.
onClick: function (feature) { ExtjsUtils.ALERTIFY.log("<b>" + feature.attributes.name + "</b>"); }resolveOverlap
function(editedGeoms, intersectingGeoms, options)# Resolve overlaps between edited and existing polygons on this drawable VectorLayer.
resolveOverlapResolve overlaps between edited and existing polygons on this drawable VectorLayer. Uses drawable.onOverlap: a single key applies immediately; an array prompts via ALERTIFY.confirmChoice (merge / cut / keep).
- editedGeoms Array.<OpenLayers.Geometry>
- Geometries just drawn or edited.
- intersectingGeoms Array.<OpenLayers.Geometry>
- Existing geometries they overlap.
- options Object
- Optional overrides.
- options.onOverlap String|Array.<String>
- Override controller
onOverlap. - options.message String
- Prompt text.
- options.onComplete function
- After the chosen action (or no-op).
drawableLayer.resolveOverlap(editedGeoms, intersectingGeoms, {
onComplete: function() { drawableLayer.callFunction('validateGeometries'); }
});selectController
OpenLayers.Control.CustomSelectFeature= undefined# The selection control created for the layer when onClick, onSelectionToggle or onHover is defined (undefined otherwise).
selectControllerThe selection control created for the layer when onClick, onSelectionToggle or onHover is defined (undefined otherwise). It is the OpenLayers.Control.CustomSelectFeature instance, so you can call its select(feature), unselect(feature), unselectAll(), activate()/deactivate() from layer callbacks, e.g. to select a feature found with findFeatureById.
functions: {
selectFirst: function() {
if (this.selectController && this.features.length) {
this.selectController.unselectAll();
this.selectController.select(this.features[0]);
}
}
}selectStyle
Object# Defines the default style that will be applied to the selected geometry.
selectStyleDefines the default style that will be applied to the selected geometry. PS: Accepts 'context' and 'rules'.
Property 'context': allows definition of functions.
Property 'rules': allows definition of filters (only the geometries that fit into this rule will be displayed). PS2: Selected depends on 'onClick' property that allows to select.
Look at some examples at: http://dev.openlayers.org/examples/
[{color: '${getColor}', context: {getColor: function(attr){return 'green';} }]setDrawing
function(enabled, callbackOnAdd)# Defines drawing features on layers.
setDrawingDefines drawing features on layers. PS: Function is available to the VectorLayer.
- enabled Boolean
- True to enable drawing, False otherwise.
- callbackOnAdd function
- Callback when a new feature is drew. P.S.: You can use 'this' to access layer properties. P.S.2: The callback function receives 2 parameters: - vectorLayer: Current layer. - drawEvent: The info of the added polygon.
this.setDrawing(false, function (vectorLayer, drawEvent) {})showLoadingModal
Boolean= false# Shows the "generating legend" loading mask visibly over the page while the layer is paused (loading its data or another resource).
showLoadingModalShows the "generating legend" loading mask visibly over the page while the layer is paused (loading its data or another resource). By default the mask is an invisible overlay that only changes the cursor to "wait"; set it to true in the layer definition to make it visible. Only shown while the layer is visible. The same key exists for calculate layers (LayersProperties.showLoadingModal).
{
name: 'CSR:my_points',
source: 'file',
type: 'geojsonurl',
url: 'https://maps.csr.ufmg.br/theme/app/data/example.geojson',
showLoadingModal: true,
}styleMap
Object|OpenLayers.StyleMap# Customizes the layer visualization.
styleMapCustomizes the layer visualization. PS: It is an advanced parameter, so it might be easier to use selectedStyle, defaultStyle and hoverStyle. PS2: The 'hover' style is applied on hover event.
StyleMap{[default, select, hover, selectedHover]: Style {rules:[Rule,], context: {getRadius: function() {return Math.random()}}}waitingRenderAndLoadAssync
Number= 0# Number of asynchronous resources of the layer still loading (its own data for csv, json, jsonurl, geojsonurl and load types, plus {{loadcsv}}/{{loadjson}} inputs and any …
waitingRenderAndLoadAssyncNumber of asynchronous resources of the layer still loading (its own data for csv, json, jsonurl, geojsonurl and load types, plus {{loadcsv}}/{{loadjson}} inputs and any startLoadingLayer you trigger yourself). It is increased on startLoadingLayer/startLoadingResource and decreased on endLoadingLayer/endLoadingResource; onInputsReady fires when it reaches 0. Read-only: use it as a guard before refreshing the layer.
if (this.waitingRenderAndLoadAssync == 0) { this.generateNewLegend(); }File layers: click and hover control
CustomSelectFeature16 entriesclick
Boolean= false# Select on click.
clickSelect on click. When true, clicking a feature selects it (select), clicking a selected one again unselects it when toggle is set, and clicking outside unselects all when clickout is set. The platform sets it for layers with onClick / onSelectionToggle. When false, select/unselect are no-ops.
clickFeature
function(feature)# Internal — feature-handler callback run when a feature is clicked (only registered when click is true): toggles the feature off when it was selected and toggle is set, otherwise unselects the …
clickFeatureInternal — feature-handler callback run when a feature is clicked (only registered when click is true): toggles the feature off when it was selected and toggle is set, otherwise unselects the others (unless multiple) and selects it. Tenant code normally does not call it; call select/unselect instead.
- feature OpenLayers.Feature.Vector
- The clicked feature.
clickoutFeature
function(feature)# Internal — feature-handler callback run when the user clicks outside a previously clicked (selected) feature: unselects everything when the clickout option is set.
clickoutFeatureInternal — feature-handler callback run when the user clicks outside a previously clicked (selected) feature: unselects everything when the clickout option is set. Tenant code normally does not call it.
- feature OpenLayers.Feature.Vector
- The feature that was selected before the click.
defaultStyle
String= "default"# Name of the StyleMap render intent used to draw a feature that is neither hovered nor selected (getFeatureCurrentStyle returns it in that case).
defaultStyleName of the StyleMap render intent used to draw a feature that is neither hovered nor selected (getFeatureCurrentStyle returns it in that case).
getFeatureCurrentStyle
function(feature, hovered) : String# Returns the name of the StyleMap render intent a feature should be drawn with right now, given whether it is selected (in layer.selectedFeatures) and whether it is hovered: selectHoverStyle when …
getFeatureCurrentStyleReturns the name of the StyleMap render intent a feature should be drawn with right now, given whether it is selected (in layer.selectedFeatures) and whether it is hovered: selectHoverStyle when both, selectedStyle when only selected, hoverStyle when only hovered, defaultStyle otherwise. Useful when redrawing a feature yourself (layer.drawFeature(feature, style)) after changing its attributes.
- feature OpenLayers.Feature.Vector
- The feature to inspect.
- hovered Boolean
- Whether the mouse is currently over the feature.
Returns The render intent name, e.g. "select".
feature.attributes.value = newValue;
layer.drawFeature(feature, layer.selectController.getFeatureCurrentStyle(feature, false));highlight
function(feature)# Highlights a feature as if the mouse were over it, without selecting it: redraws it with hoverStyle (or selectHoverStyle when it is selected) and fires the control's …
highlightHighlights a feature as if the mouse were over it, without selecting it: redraws it with hoverStyle (or selectHoverStyle when it is selected) and fires the control's beforefeaturehighlighted/featurehighlighted events — which, on a file layer, run the onHover callback with state true. Use it to mirror a hover coming from a list or chart outside the map; call unhighlight to revert.
- feature OpenLayers.Feature.Vector
- The feature to highlight.
// highlight a municipality when its row is hovered in a table
layer.selectController.highlight(layer.findFeatureById(rowId));hover
Boolean= false# Highlight on mouse over and unhighlight on mouse out (without selecting).
hoverhoverStyle
String= "hover"# Name of the StyleMap render intent used to draw a hovered, unselected feature.
hoverStyleName of the StyleMap render intent used to draw a hovered, unselected feature. It matches the VectorLayer.hoverStyle entry of the layer's styleMap.
multiple
Boolean= false# Allows more than one selected feature at a time: with false selecting a feature unselects the previous one.
multipleAllows more than one selected feature at a time: with false selecting a feature unselects the previous one. Pass it through onClickCfg: {multiple: true}.
outFeature
function(feature)# Internal — feature-handler callback run when the mouse leaves a feature (only registered when hover is true): unhighlights it, redrawing with defaultStyle or, if it is selected, …
outFeatureInternal — feature-handler callback run when the mouse leaves a feature (only registered when hover is true): unhighlights it, redrawing with defaultStyle or, if it is selected, selectedStyle; when another select control had highlighted the feature before, that control's highlight is restored instead. Tenant code normally does not call it; call unhighlight instead.
- feature OpenLayers.Feature.Vector
- The feature the mouse left.
overFeature
function(feature)# Internal — feature-handler callback run when the mouse enters a feature (only registered when hover is true): highlights it, redrawing with hoverStyle or, if it is selected, selectHoverStyle.
overFeatureInternal — feature-handler callback run when the mouse enters a feature (only registered when hover is true): highlights it, redrawing with hoverStyle or, if it is selected, selectHoverStyle. Tenant code normally does not call it; call highlight instead.
- feature OpenLayers.Feature.Vector
- The feature under the mouse.
select
function(feature)# Selects a feature programmatically, exactly as a click would: adds it to layer.selectedFeatures, redraws it with selectedStyle (or selectHoverStyle while hovered), fires the layer's …
selectSelects a feature programmatically, exactly as a click would: adds it to layer.selectedFeatures, redraws it with selectedStyle (or selectHoverStyle while hovered), fires the layer's beforefeatureselected/featureselected events and calls the onSelect option — so a file layer's onClick/onSelectionToggle callback runs too. Does nothing when the control was created with click: false. Use it to select a feature from a list or a parent-page message; unselectAll() (inherited) clears the selection.
- feature OpenLayers.Feature.Vector
- The feature to select (must belong to the control's layer).
// select the feature whose attribute matches, from a tenant global called by a button
var layer = ExtjsUtils.LAYER.getLayerByName("CSR:municipios");
var feature = layer.findFeatureById(featureId);
if (feature) {
layer.selectController.unselectAll();
layer.selectController.select(feature);
}selectHoverStyle
String= "selectedHover"# Name of the StyleMap render intent used to draw a feature that is selected AND hovered.
selectHoverStyleName of the StyleMap render intent used to draw a feature that is selected AND hovered. It matches the VectorLayer.hoverSelectedStyle entry of the layer's styleMap.
selectedStyle
String= "selected"# Name of the StyleMap render intent used to draw a selected feature that is not hovered.
selectedStyleName of the StyleMap render intent used to draw a selected feature that is not hovered. The platform passes "select" for file layers (the VectorLayer.selectStyle entry of the layer's styleMap); this is the stock default otherwise.
unhighlight
function(feature)# Removes the hover highlight of a feature: redraws it with the feature's own style if it has one, else the layer's style, else defaultStyle (or selectedStyle when it is selected), and fires …
unhighlightRemoves the hover highlight of a feature: redraws it with the feature's own style if it has one, else the layer's style, else defaultStyle (or selectedStyle when it is selected), and fires the control's featureunhighlighted event — which, on a file layer, runs the onHover callback with state false. When several select controls highlighted the feature, the previous control's highlight is kept.
- feature OpenLayers.Feature.Vector
- The feature to unhighlight.
layer.selectController.unhighlight(layer.findFeatureById(rowId));unselect
function(feature)# Unselects a feature programmatically: removes it from layer.selectedFeatures, redraws it with defaultStyle (or hoverStyle while hovered), fires the layer's featureunselected event and calls …
unselectUnselects a feature programmatically: removes it from layer.selectedFeatures, redraws it with defaultStyle (or hoverStyle while hovered), fires the layer's featureunselected event and calls the onUnselect option — so a file layer's onSelectionToggle callback runs with its unselect status. Does nothing when the control was created with click: false.
- feature OpenLayers.Feature.Vector
- The feature to unselect.
var selected = layer.selectedFeatures.slice();
selected.forEach(function(feature) { layer.selectController.unselect(feature); });File layers: vertex editing control
CustomModifyFeature5 entriesDrawing
Object# Pure drawing/status constants and helpers of the modify control (no control instance needed), reachable as OpenLayers.Control.CustomModifyFeature.Drawing.
DrawingPure drawing/status constants and helpers of the modify control (no control instance needed), reachable as OpenLayers.Control.CustomModifyFeature.Drawing. What a query uses from it is DRAWING_STATUS, the enum of the detail.status values that drawable.onDrawingStatusChange(detail) reports: OFF: "off" (not editing), READY: "ready" (editing active, nothing sketched or selected), DRAWING: "drawing" (a polygon sketch is in progress), DRAWING_LINE: "drawing_line" (a line sketch is in progress), FEATURE_SELECTED: "feature_selected" (an existing feature is selected for editing) and VERTEX_DRAG: "vertex_drag" (a vertex of the selected feature is being dragged). It also holds DRAW_MODES (POLYGON: "polygon", LINE: "line", the detail.drawMode values), the default Portuguese STATUS_LABELS per status, MIN_POLYGON_SKETCH_POINTS (4) / MIN_LINE_SKETCH_POINTS (2) and minSketchPointsForMode(drawMode). Compare against the constants instead of hard-coding the strings.
drawable: {
onDrawingStatusChange: function(detail) {
var S = OpenLayers.Control.CustomModifyFeature.Drawing.DRAWING_STATUS;
finishButton.setDisabled(!(detail.status === S.DRAWING || detail.status === S.DRAWING_LINE) || !detail.canFinishDrawing);
applyButton.setDisabled(detail.status !== S.FEATURE_SELECTED);
}
}buildStatusDetail
function() : Object# Builds the current drawing/edit status of the control on demand — the same detail object drawable.onDrawingStatusChange(detail) receives, so a host UI can read the state at any moment (e.g. when …
buildStatusDetailBuilds the current drawing/edit status of the control on demand — the same detail object drawable.onDrawingStatusChange(detail) receives, so a host UI can read the state at any moment (e.g. when it is first shown) instead of waiting for the next change. Fields: status (one of CustomModifyFeature.Drawing.DRAWING_STATUS, never "off" here — the control only exists while editing), drawMode, isDrawing, featureSelected, vertexDrag, selectedFeature (the OpenLayers.Feature.Vector or null), sketchPointCount, canFinishDrawing, canDeselectFeature, canApplyFeatureChanges and canCancelDrawing. Reachable as layer.drawableController.modifyFeatureControl.buildStatusDetail().
Returns The status detail object described above.
var detail = layer.drawableController.modifyFeatureControl.buildStatusDetail();
if (detail.canApplyFeatureChanges) {
layer.drawableController.applyFeatureChanges();
}getActiveDrawMode
function() : String# The geometry mode new sketches use on this control: "polygon" (default) or "line" (only when the layer's drawable.drawModes includes it), i.e. one of CustomModifyFeature.Drawing.DRAW_MODES.
getActiveDrawModeThe geometry mode new sketches use on this control: "polygon" (default) or "line" (only when the layer's drawable.drawModes includes it), i.e. one of CustomModifyFeature.Drawing.DRAW_MODES. Reachable as layer.drawableController.modifyFeatureControl.getActiveDrawMode(); the same value arrives as detail.drawMode in onDrawingStatusChange.
Returns "polygon" or "line".
var control = layer.drawableController.modifyFeatureControl;
if (control.getActiveDrawMode() === OpenLayers.Control.CustomModifyFeature.Drawing.DRAW_MODES.LINE) {
console.log("next sketch cuts polygons along a line");
}getSelectedFeatureId
function() : String|Number|null# Id of the feature currently selected for editing.
getSelectedFeatureIdId of the feature currently selected for editing.
isFeatureSelected
function() : Boolean# Whether a feature of the layer is currently selected for editing on this control (its vertices are shown and draggable).
isFeatureSelectedWhether a feature of the layer is currently selected for editing on this control (its vertices are shown and draggable). Reachable as layer.drawableController.modifyFeatureControl.isFeatureSelected(); use getSelectedFeatureId() to know which one.
Returns true while a feature is selected for editing.
var control = layer.drawableController.modifyFeatureControl;
if (control.isFeatureSelected()) {
console.log("editing feature " + control.getSelectedFeatureId());
}Tile layers (xyz)
XYZLayer3 entriesname
String# Defines a map identifier.
nameDefines a map identifier. This name should be unique.
[
...
{
source: "xyz",
name:"XYZ:map_name",
}
...
]source
Object# Adds a layer to store the source.
sourceAdds a layer to store the source.
- layerCfg LayerConfig
- Layer XYZ configuration. LayerConfig { url: url, name: name, isBaseLayer: isBaseLayer, sphericalMercator: sphericalMercator }
url
String# Defines the url where the map can be fetched from.
urlDefines the url where the map can be fetched from. Use the ${x} ${y} ${z} as placeholder for x, y and z coordinates.
"https://tiles.planet.com/basemaps/v1/planet-tiles/planet_medres_visual_2021-09_mosaic/gmap/${z}/${x}/${y}.png?api_key=b24ae87a99624d2cbd8ed6aeb9703280"Groups: what you write in a group
Not the same as the layer key group, of which only group: "background" does something (it makes the layer a basemap).
Two groups, each an entry of the top menu:
Example
[
{
title: 'My first Group!',
color: '#A020F0',
elements: [
{
title: 'Layer 1 of group 1',
name: 'CSR:batimetria',
visibility: true,
},
],
},
{
title: 'My second Group!!',
color: '#FFA900',
elements: [
{
title: 'Layer 1 of group 2',
name: 'CSR:altimetria',
visibility: true,
},
],
},
]Group properties
GroupProperties8 entriescolor
String= string.emptyproperty# Defines the Color of the group.
colorDefines the Color of the group. This is the Color of the Title and some elements inside the sub menu on the top of the screen.
[
{
title: 'My orange group',
color: '#FFA500',
},
]customLayerClass
String= string.emptyproperty# Extra CSS class added to the node of a viewTitle group in the Legend Window, so the group title and its rows can be styled with ExtjsUtils.CSS.defineClass or a stylesheet.
customLayerClassExtra CSS class added to the node of a viewTitle group in the Legend Window, so the group title and its rows can be styled with ExtjsUtils.CSS.defineClass or a stylesheet. Only groups with a viewTitle create a node; on a layer the same key styles the layer row instead (ConfigLayer.customLayerClass).
[
{
viewTitle: 'Styled group',
viewColor: '#FFA500',
title: 'Group 1',
color: '#666699',
customLayerClass: 'highlighted-group',
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'local',
startListed: true,
},
],
},
]defaultProperties
Object= {}property# Specifies properties that apply universally to all layers within a group, including nested subgroups and their respective layers.
defaultPropertiesSpecifies properties that apply universally to all layers within a group, including nested subgroups and their respective layers. Priority is determined by specificity: a property defined at the layer level takes precedence, followed by properties defined in the nearest group, and so forth.
[
{
title: 'Example of defaultProperties',
color: '#FFA500',
defaultProperties: {
source: 'local',
visibility: true,
opacity: 0.7,
},
elements: [
{
title: 'Layer 1',
name: 'CSR:geologia',
},
{
title: 'Layer 2',
name: 'CSR:rios_principais',
},
{
title: 'Layer 3',
name: 'CSR:estados',
// Any internal redefinition will override the defaultProperties
visibility: false,
},
],
},
]elements
Array.<Layers>= Array.emptyproperty# Defines the Layers that will be part of the Group.
elementsDefines the Layers that will be part of the Group. Each Layer can have multiple maps inside it. All maps inside a Layer will be shown together when that Layer is enabled. Besides that, all information about those maps can be used to calculate a new one using custom functions that can be writen in JavaScript.
[
{
title: 'A group with Layers!',
color: '#FFA500',
elements: [
// Define your Layers here
],
},
]See also To learn more about Layers and it’s properties, check their documentation at: Layer Section.
global
Objectproperty# A second way to declare query globals: an object whose properties become temporary globals, passed to ExtjsUtils.QUERY.setQueryGlobalProperties while the group is interpreted (before its layers).
globalA second way to declare query globals: an object whose properties become temporary globals, passed to ExtjsUtils.QUERY.setQueryGlobalProperties while the group is interpreted (before its layers). The usual form is the ExtjsUtils.QUERY.setQueryGlobalProperties({...}) && [...] chain at the top of the query; the production survey found no query using this key (zero users).
[
{
title: 'Group with its own globals',
global: {
formatArea: function(value) { return ExtjsUtils.NUMBER.abbreviateNumber(value) + ' ha'; }
},
elements: [
{ title: 'Layer 1', name: 'CSR:estados', source: 'local', visibility: true }
]
}
]openGroup
Boolean= falseproperty# Defines if the 'viewTitle' should start opening or collapse.
openGroupDefines if the 'viewTitle' should start opening or collapse. Set it to 'true' for the 'viewTitle' start open or 'false' for it to start closed. This property only applies to a group that has the 'viewTitle' property defined. If the Group View has any visible Layers or any Layer has the 'openGroup' property set to 'true', the Group View will start open. It works at both levels: on the viewTitle group it makes the group start expanded, on a layer it expands every viewTitle ancestor of that layer.
[
{
viewTitle: 'This Group View will start opened',
viewColor: '#FFFFFF',
title: 'Group 1',
color: '#666699',
openGroup: true,
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'calculate',
startListed: true,
},
],
},
{
viewTitle: 'This Group View will start closed',
viewColor: '#FFFFFF',
title: 'Group 2',
color: '#666699',
elements: [
{
title: 'Layer 2',
name: 'CSR:rios_principais',
source: 'calculate',
startListed: true,
},
],
},
]title
String= string.emptyproperty# Defines the Title of the group.
titleDefines the Title of the group. The Title is shown at the sub menu on the top of the screen.
[
{
title: 'My new group!',
},
]viewTitle
String= string.emptyproperty# Define the Title of the View that will gather together the elements inside it (Groups or other Views).
viewTitleDefine the Title of the View that will gather together the elements inside it (Groups or other Views). If an external View has in its elements another definition of a 'viewTitle', subviews will be created, like in the second example.
// Exemple 1: View with a Layers inside it
[
{
viewTitle: 'This View has a Group 3 Layers',
title: 'This is a Group with 3 Layers',
color: '#5BA300',
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'local',
opacity: 0.5,
visibility: true,
},
{
title: 'Layer 2',
name: 'CSR:rios_principais',
source: 'local',
opacity: 0.5,
visibility: true,
},
{
title: 'Layer 3',
name: 'CSR:geologia',
source: 'local',
opacity: 0.65,
visibility: true,
},
],
},
]// Exemple 2: View with others 'viewTitle' defined inside it
[
{
// This is the definition of the View
viewTitle: 'This External View has 2 others Inner Views inside it, each with 1 Group that has 1 Layer',
title: 'This View has 2 Groups, each with 1 Layer',
color: '#0073E6',
elements: [
{
title: 'Group 1',
// This 'viewTitle' will create a division in the menu that shows when the mouse hovers the navigation bar option 'This View has 2 Groups, each with 1 Layer'
viewTitle: 'Inner View with Group 1',
color: '#E6308A',
elements: [
{
title: 'Group 1 - Layer 1',
name: 'CSR:altimetria',
source: 'local',
visibility: true,
},
],
},
{
title: 'Group 2',
// This 'viewTitle' will create a division in the menu that shows when the mouse hovers the navigation bar option 'This View has 2 Groups, each with 1 Layer'
viewTitle: 'Inner View with Group 2',
color: '#B51963',
elements: [
{
title: 'Group 2 - Layer 1',
name: 'CSR:batimetria',
source: 'local',
visibility: true,
},
],
},
],
},
]Group callbacks (viewTitle groups)
GroupFunctions2 entriesonClickViewGroup
function= nullcallback# Called whenever the user clicks the title of a viewTitle group in the Legend Window.
onClickViewGroupCalled whenever the user clicks the title of a viewTitle group in the Legend Window. It belongs on a group that has viewTitle: the handler is bound to that group's tree node, so this is the node and view.expanded tells whether the group is open after the click. When declared on a layer instead of a group, it is attached to the layer's nearest viewTitle ancestor (once per layer that declares it); on a flat layer with no viewTitle ancestor it is bound to the invisible root node, i.e. it never fires.
- view Ext.tree.TreeNode
- The tree node of the group that was clicked (
view.expanded,view.text,view.childNodes). - clickEvent Ext.EventObject
- The click event, with details such as the mouse position.
[
{
viewTitle: 'Example View (Click me!)',
viewColor: '#FFA500',
title: 'Click the view to change its state',
color: '#666699',
openGroup: true,
onClickViewGroup: function handleClickViewGroup(view, clickEvent) {
let viewState = (view.expanded ? 'open' : 'closed');
ExtjsUtils.ALERTIFY.log('The ' + view.text + ' is ' + viewState );
},
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'local',
startListed: true,
},
],
},
]onToggleViewGroup
function= nullcallback# Called whenever a viewTitle group of the Legend Window is expanded or collapsed (by the user or by code).
onToggleViewGroupCalled whenever a viewTitle group of the Legend Window is expanded or collapsed (by the user or by code). It belongs on a group that has viewTitle: the handler is bound to that group's tree node, so this is the node and view.expanded is true after an expand and false after a collapse. When declared on a layer instead of a group, it is attached to the layer's nearest viewTitle ancestor (once per layer that declares it); on a flat layer with no viewTitle ancestor it is bound to the invisible root node, i.e. it never fires. A typical use is hiding the layers of the collapsed group and restoring them on expand.
- view Ext.tree.TreeNode
- The tree node of the group whose state changed (
view.expanded,view.text,view.childNodes).
[
{
viewTitle: 'Example View (Click me!)',
viewColor: '#FFA500',
title: 'Click the view to change its state',
color: '#666699',
openGroup: true,
onToggleViewGroup: function handleToggleViewGroup(view) {
let viewState = (view.expanded ? 'open' : 'closed');
ExtjsUtils.ALERTIFY.log('The ' + view.text + ' is ' + viewState );
},
elements: [
{
title: 'Layer 1',
name: 'CSR:estados',
source: 'local',
startListed: true,
},
],
},
]Panel widgets
The markup rules shared by every widget come first; each widget also has a page with a live example under the Tools tab.
Examples:
Example
{
...,
descriptionHtml: '{{toolIdentifier|paramName=paramValue}}',
...
}
{
...,
descriptionHtml: '{{button|id=btn_id|enableToggle=false}}' + '{{opacityslider}}',
...
}Markup rules for every widget
MarkupSyntax11 entriesFunction-valued parameters (handler, runOnClick, runOnHover, onSelect, ...) are resolved in this order: a key of the layer 'functions' object, then a global with that name (setQueryGlobalProperties), then the text itself evaluated as a function (a body, or a full 'function(){...}' expression).
cls
String# cls=<class> adds CSS classes to the created element.
clscls=<class> adds CSS classes to the created element. Unlike other keys, repeating it concatenates the values (with no separator — start the second one with a space, or list all classes in a single cls).
{{label|cls=slider_label bold|text=0%}}defaultParsing
String|Number# How a plain param=value is converted before reaching the tool: a value that looks like a number (10, -4.5, 1e3) becomes a JavaScript number, an empty value (param=) becomes the empty string …
defaultParsingHow a plain param=value is converted before reaching the tool: a value that looks like a number (10, -4.5, 1e3) becomes a JavaScript number, an empty value (param=) becomes the empty string (falsy), and anything else stays a string — tools that need arrays or objects (data, steps, values, filterLayers, backgroundColors) parse the string themselves as JSON. true/false are NOT converted: param=true is the string "true" (truthy) and param=false is rewritten to an empty value (see falseValue). A parameter written without = (|pressed|) also gets the empty string, except for the special keys listed in this group (isnumeric). The same parameter written twice keeps the last value (cls and on_<event> accumulate instead).
{{slider|id=s|minValue=0|maxValue=100|value=20|fieldLabel=Deforestation}}escapedEquals
String# Write \= to put a literal = inside a value; a bare = would start a nested key (see nestedKeys).
escapedEqualsWrite \= to put a literal = inside a value; a bare = would start a nested key (see nestedKeys). Needed above all in URLs with query strings. Inside a JavaScript string remember to double the backslash ('\\='). The value of html= is exempt: everything after its first = is kept as is.
{{loadcsv|id=csv|url=/wmtp/calc/areacategorical/?layers\=CSR:estados&styles\=1}}falseValue
Boolean# param=false is rewritten to param= (an empty, falsy value) before parsing, because the literal text "false" would otherwise be a truthy string.
falseValueparam=false is rewritten to param= (an empty, falsy value) before parsing, because the literal text "false" would otherwise be a truthy string. Use it to switch off a boolean parameter whose default is true (unselect=false, notify=false, hideLabel=false). Only a false at the very end of the parameter is rewritten.
{{pickpoint|id=pick|unselect=false|notify=false}}function
function# function=<body> stores a function whose body is the given text (function () { <body> }), evaluated with no try/catch and no lookup in the layer functions.
functionfunction=<body> stores a function whose body is the given text (function () { <body> }), evaluated with no try/catch and no lookup in the layer functions. Use the nested form param=function=<body> to assign it to a parameter (a top-level function= only sets a function key); escape any = in the body as \=. Rarely needed: the callback parameters of the tools (handler, runOnClick, onSelect...) already accept function names or inline text.
{{button|id=b|text=Log|handler=function=console.log('clicked')}}getid
Object# getid=ID gives access to an element created EARLIER in the same description (by any tag with that id).
getidgetid=ID gives access to an element created EARLIER in the same description (by any tag with that id). At the top level (|getid=slider1|) the element is stored in the tool config under getid; the common use is to attach a listener to it with getid=ID|getid=on_<event>=... (see on_event), or the nested param=getid=ID to hand the element to a parameter (scope=getid=btn). Order matters: the referenced tag must appear before the one using getid.
{{slider|id=perc_slider|value=20}}{{label|id=perc_label|text=20%|getid=perc_slider|getid=on_change=Ext.getCmp('perc_label').setText(this.getValue() + '%')}}html
String# html= is the one key whose value is taken verbatim up to the next |: = characters inside it are kept and no nesting happens.
htmlhtml= is the one key whose value is taken verbatim up to the next |: = characters inside it are kept and no nesting happens. Used by label and window.
{{label|html=<a href="https://maps.csr.ufmg.br/?queryid=1">open</a>}}isnumeric
Boolean# |isnumeric| (or isnumeric=true) installs a validator that only accepts numeric text — the field is marked invalid with the localized "must be a number" message otherwise.
isnumeric|isnumeric| (or isnumeric=true) installs a validator that only accepts numeric text — the field is marked invalid with the localized "must be a number" message otherwise. Meant for textfield. Note that the input value is still delivered as a string; convert it with parseFloat.
{{textfield|id=soy_value|value=43|isnumeric|fieldLabel=Value (US$/Ton)}}nestedKeys
Object# a=b=c creates a nested object: the tool receives {a: {b: c}}.
nestedKeysa=b=c creates a nested object: the tool receives {a: {b: c}}. The innermost key=value is parsed with the same rules as a top-level one, so the special keys work at any depth — plugins=tip=... builds a slider tip plugin, scope=getid=ID assigns an element created earlier, listeners=on_change=... is not needed because getid/on_<event> already cover the common case.
{{slider|id=s|plugins=tip={0}% of the area}}on_event
function# on_<event>=<code> adds a listener for an Ext event (change, select, afteredit, toggle...) on an element referenced with getid — the form is getid=ID|getid=on_<event>=<code>; it cannot …
on_eventon_<event>=<code> adds a listener for an Ext event (change, select, afteredit, toggle...) on an element referenced with getid — the form is getid=ID|getid=on_<event>=<code>; it cannot be used on the tag's own element. <code> is either a full function(...) {...} or a statement body; it is evaluated directly (no lookup in the layer functions or in globals) and runs with this = the referenced element and the event's own arguments. Several on_ listeners may be attached to the same element.
{{textfield|id=price|isnumeric}}{{label|id=price_lbl|getid=price|getid=on_afteredit=Ext.getCmp('price_lbl').setText('US$ ' + this.getRawValue())}}tip
Object# tip=<format> builds an Ext.slider.Tip whose text is String.format(format, thumbValue, value of thumb 0, value of thumb 1...), so {0} is the dragged thumb value.
tiptip=<format> builds an Ext.slider.Tip whose text is String.format(format, thumbValue, value of thumb 0, value of thumb 1...), so {0} is the dragged thumb value. It must be assigned to a slider's plugins with the nested form plugins=tip=<format>; a top-level tip= is stored in the config but not used by the slider.
{{slider|id=perc_slider|plugins=tip={0}% of the area|increment=5}}Free HTML
HTML1 entrycontent
String# Free HTML inside a layer's descriptionHtml: everything that is not a {{tag}} is passed through to the panel untouched, so a description can carry headings, images, links, tables and the container …
contentFree HTML inside a layer's descriptionHtml: everything that is not a {{tag}} is passed through to the panel untouched, so a description can carry headings, images, links, tables and the container elements a chart or a custom control needs. Widgets and HTML mix freely in the same string, and the HTML around a widget is rendered before the widget is created, so an element declared here can already be referenced by an id.
Two things to keep in mind. Inside a {{tag|...}} the pipe separates parameters, so HTML that must live in a parameter goes in html= (verbatim to the end of the value) or has its = escaped as \\=. And the description is written inside a JavaScript string in the query, so quotes have to be escaped or alternated as usual.
descriptionHtml:
'<h3>Deforestation</h3>' +
'<p>Pick the minimum area to highlight.</p>' +
'{{slider|id=threshold|minValue=0|maxValue=100|value=20}}' +
'<div id="chart_area" style="height:220px"></div>'areaintegral · sum inside a rectangle (input)
AreaIntegral9 entriesWritten in a layer's descriptionHtml as {{areaintegral|parameter=value|...}}
Callback parameters (layersValues {Array[Number]}, inputs {Array}, boundingBox {Array[Number]} in EPSG:4326, pixel {x,y}, lastInfo {first, second})
Usage: {{areaintegral|runOnClick=onAreaSummed}}
getLayerValues
function(mousePoint, layer) : Array.<Number>|null# Reads the composed map at one screen position: one value per inner layer (decoded from the tile colours through the legend, null cells read as 0) plus one extra entry with the layer expression result for those values.
getLayerValuesReads the composed map at one screen position: one value per inner layer (decoded from the tile colours through the legend, null cells read as 0) plus one extra entry with the layer expression result for those values. The tool samples the four corners of the rectangle with it and combines them as a summed-area table (sum = minXY + maxXY - minXmaxY - maxXminY), which is why the maps must be published with the integral operation. Returns null when the layer is hidden or the position is outside the map data.
- mousePoint Object
- Absolute screen position
{x, y}to sample. - layer OpenLayers.Layer.Composed
- The composed layer to read (normally the tool's own layer).
Returns [value of layer 0, ..., value of layer n-1, expression result], or null.
iconCls
String= cmn-toggle-icon# Defines the CSS class of the toggle switch icon; replace the default to restyle the switch.
iconClsDefines the CSS class of the toggle switch icon; replace the default to restyle the switch.
|iconCls=my-toggle-icon|id
String# Defines the id of the tool: the key used in inputs.id[ID] and the id of the container component (Ext.getCmp(id); the switch itself is Ext.getCmp(id).items.get(0)).
idDefines the id of the tool: the key used in inputs.id[ID] and the id of the container component (Ext.getCmp(id); the switch itself is Ext.getCmp(id).items.get(0)). Generated when omitted.
|id=integral_tool|labelBefore
Boolean= false# Set true to render the text label before (left of) the toggle switch instead of after it.
labelBeforeSet true to render the text label before (left of) the toggle switch instead of after it.
|labelBefore=true|notify
Boolean= true# Set false to suppress the notification shown when the tool is activated.
notifySet false to suppress the notification shown when the tool is activated.
|notify=false|runOnClick
function# Defines the callback run after the second click closes the rectangle, with the sums computed.
runOnClickDefines the callback run after the second click closes the rectangle, with the sums computed. Called as runOnClick(layersValues, inputs, boundingBox, pixel, lastInfo) with this = the layer: layersValues has one summed value per inner layer (see getLayerValues), inputs is layer.getInputs(), boundingBox is [minLon, minLat, maxLon, maxLat] in EPSG:4326, pixel the {x, y} of the second click and lastInfo the {first, second} {lon, lat} of the two clicks. The name is resolved as a key of the layer functions object, then as a global function, then as inline function text. The tool deactivates itself after the callback.
|runOnClick=onAreaSummed|functions: {
onAreaSummed: function(layersValues, inputs, boundingBox, pixel, lastInfo) {
ExtjsUtils.ALERTIFY.log('Sum inside ' + boundingBox.join(', ') + ': ' + layersValues[0]);
}
}text
String# Defines the text shown next to the toggle switch.
textDefines the text shown next to the toggle switch.
|text=Sum a rectangle|unselect
Boolean= true# Only changes the activation message (true: one selection expected, false: several); the tool always deactivates itself after the second click.
unselectOnly changes the activation message (true: one selection expected, false: several); the tool always deactivates itself after the second click.
|unselect=false|value
Array.<Number># Value stored in inputs.id[ID]: the layersValues array of the tool — one summed value per inner layer of the composed map for the last rectangle (empty before the first one).
valueValue stored in inputs.id[ID]: the layersValues array of the tool — one summed value per inner layer of the composed map for the last rectangle (empty before the first one). The array is updated in place after the second click, so beforeCalc/expression always read the latest sums. The input is registered on the forceupdatelayer event of the switch, which the tool does not fire by itself: react inside runOnClick, or call Ext.getCmp(id).items.get(0).forceUpdateLayer() there to recalculate the layer with the new sums.
{{areaintegral|id=integral_tool|runOnClick=onAreaSummed}}functions: {
onAreaSummed: function(layersValues, inputs) {
Ext.getCmp('integral_tool').items.get(0).forceUpdateLayer(); // beforeCalc will see inputs.id['integral_tool']
}
}button · push or toggle button
Button9 entriesWritten in a layer's descriptionHtml as {{button|parameter=value|...}}
enableToggle
Boolean= false# Defines the button type as toggle.
enableToggleDefines the button type as toggle. Set true to use as toggle, false otherwise. PS: When its true the callback is 'toggleHandler', otherwise the callback is 'handler'.
|enableToggle=true|fieldLabel
String# Defines the button label.
fieldLabelDefines the button label.
|fieldLabel=A button|handler
function= undefined# Defines the callback function on button click event.
handlerDefines the callback function on button click event. This should be used when the enableToggle property is false. this inside the callback is the layer.
The value is resolved in this order: (1) a key of the layer functions object with that name; (2) a global function with that name (e.g. defined with setQueryGlobalProperties); (3) otherwise the text itself is evaluated as a function — either a full function(){...} expression or a plain statement body. With enableToggle=true and no toggleHandler, handler is used as the toggle handler.
- button Ext.Button
- The button element that was clicked.
- clickEvent EventObject
- An event object carrying information about the click event.
|handler=onExportClick||handler = function (button, clickEvent){
console.log(button, clickEvent);
}|id
String# Defines the id to identify the object.
idDefines the id to identify the object.
|id=exemple_button|pressed
Boolean= false# Defines the button initial state.
pressedDefines the button initial state. Set it true to start pressed (only if enableToggle = true), false otherwise.
|pressed=true|text
String# Defines the button text.
textDefines the button text.
|text=Click On Me|toggle
function# Alias of toggleHandler: a function given as toggle= is moved to toggleHandler (unless one is already defined), so the Ext toggle() method of the button is never overwritten.
toggleAlias of toggleHandler: a function given as toggle= is moved to toggleHandler (unless one is already defined), so the Ext toggle() method of the button is never overwritten. Prefer toggleHandler.
|enableToggle=true|toggle=onToggleDetails|toggleHandler
function= undefined# Defines the callback function on button toggle event.
toggleHandlerDefines the callback function on button toggle event. This should be used when the enableToggle property is true. this inside the callback is the layer.
The value is resolved in this order: (1) a key of the layer functions object with that name; (2) a global function with that name (e.g. defined with setQueryGlobalProperties); (3) otherwise the text itself is evaluated as a function — either a full function(){...} expression or a plain statement body.
- button Ext.Button
- The button element that was clicked.
- state Boolean
- The next state of the button, true means pressed.
|enableToggle=true|toggleHandler=onToggleDetails||toggleHandler = function (button, pressed){
console.log(button, pressed);
}|checkbox · on/off, calls a function
Checkbox13 entriesWritten in a layer's descriptionHtml as {{checkbox|parameter=value|...}}
Usage: {{checkbox|text=Show details|handler=onToggleDetails}}
checked
Boolean= false# Set true to start checked.
checkedSet true to start checked. handler is not run for the initial state.
|checked=true|fieldLabel
String# Defines a label at the left of the whole field (Ext fieldLabel), in addition to the text shown next to the switch.
fieldLabelDefines a label at the left of the whole field (Ext fieldLabel), in addition to the text shown next to the switch. hideLabel=true removes it and its reserved space.
|fieldLabel=Options|forceUpdateLayer
function()# Fires the forceupdatelayer event of the widget.
forceUpdateLayerFires the forceupdatelayer event of the widget. For the map-interaction tools registered as inputs (summedarea, areaintegral) this is the event the layer listens to, so calling it marks the input as changed and recalculates the layer with the values currently stored in inputs.id[ID].
Ext.getCmp('sum_tool').items.get(0).forceUpdateLayer();handler
function# Defines the callback run whenever the checkbox is checked or unchecked (by the user or by toggle()).
handlerDefines the callback run whenever the checkbox is checked or unchecked (by the user or by toggle()). Called as handler(checkbox, checked) with this = the layer. The value is resolved in this order: a key of the layer functions object, then a global function with that name, then the text itself evaluated as a function (a full function(){...} or a statement body). The checkbox is not a layer input: read checked here and act (e.g. setValues on an InputManager, changeLayers...). It is also called once with checked=false when the widget is removed together with its layer.
|handler=onToggleDetails|functions: {
onToggleDetails: function(checkbox, checked) {
this.getInputs().id['state'].setValues({details: checked});
}
}iconCls
String= cmn-toggle-icon# Defines the CSS class of the toggle switch icon; replace the default to restyle the switch.
iconClsDefines the CSS class of the toggle switch icon; replace the default to restyle the switch.
|iconCls=my-toggle-icon|id
String# Defines the id of the checkbox component (Ext.getCmp(id)), e.g. to call toggle() or setBoxLabel() from a button.
idDefines the id of the checkbox component (Ext.getCmp(id)), e.g. to call toggle() or setBoxLabel() from a button. Generated when omitted.
|id=show_details|inputValue
String# Defines the DOM value attribute of the underlying <input type="checkbox"> (useful inside an HTML form).
inputValueDefines the DOM value attribute of the underlying <input type="checkbox"> (useful inside an HTML form).
|inputValue=details|labelBefore
Boolean= false# Set true to render the text before (left of) the toggle switch instead of after it.
labelBeforeSet true to render the text before (left of) the toggle switch instead of after it.
|labelBefore=true|notify
Boolean= true# Accepted for parity with the map-picking switches (pickpoint, hoverpixel...), where it controls the activation notification.
notifyAccepted for parity with the map-picking switches (pickpoint, hoverpixel...), where it controls the activation notification. A plain checkbox shows no notification, so the value has no effect here.
setBoxLabel
function(boxLabel)# Changes the text shown next to the checkbox (the markup text parameter) after it was rendered.
setBoxLabelChanges the text shown next to the checkbox (the markup text parameter) after it was rendered. Available on every checkbox-style tool (checkbox, pickpoint, hoverpixel, summedarea, areaintegral); get the component with Ext.getCmp(id).
- boxLabel String
- New label text (HTML allowed).
Ext.getCmp('my_checkbox').setBoxLabel('Show details (3)');text
String# Defines the text shown next to the toggle switch (the checkbox boxLabel).
textDefines the text shown next to the toggle switch (the checkbox boxLabel).
|text=Show details|toggle
function(forceState)# Checks or unchecks the checkbox from code, running its handler as if the user had clicked it.
toggleChecks or unchecks the checkbox from code, running its handler as if the user had clicked it. Without an argument the current state is inverted. Get the component with Ext.getCmp(id).
- forceState Boolean
trueto check,falseto uncheck; omit to invert the current state.
Ext.getCmp('show_details').toggle(false); // uncheckunselect
Boolean= true# Accepted for parity with the map-picking switches, where it selects the activation message.
unselectAccepted for parity with the map-picking switches, where it selects the activation message. A plain checkbox never unchecks itself, so the value has no effect here.
combobox · pick from a list (input)
Combobox11 entriesWritten in a layer's descriptionHtml as {{combobox|parameter=value|...}}
Usage: '{{combobox}}' or examples.
data
Array.<Array.<String>>= undefined# Defines the data that will be displayed in the Combobox.
dataDefines the data that will be displayed in the Combobox.
|data = [["Val_1"], ["Val_2"],..]|editable
Boolean= false# Determines if the Combobox is editable.
editableDetermines if the Combobox is editable. That is, if it allows the user to type inside the input field. Set it true to allow it, false otherwise.
|editable=true|fieldLabel
String# Defines a label for the Combobox.
fieldLabelDefines a label for the Combobox. It will be shown at the left of the Combobox, by default.
|fieldLabel=This is the field label|getValue
function() : String# Returns the currently selected value (the text of the chosen data entry).
getValueReturns the currently selected value (the text of the chosen data entry). Call it on the component (Ext.getCmp(id) or a getid= reference); inputs.id[ID] already holds the same value.
Returns The selected value.
var region = Ext.getCmp('region_combo').getValue();hideLabel
Boolean= false# Defines if the label of the Combobox should be displayed.
hideLabelDefines if the label of the Combobox should be displayed. Set true to hide the label, false to show it.
|hideLabel=true|id
String# Defines the id to identify the object.
idDefines the id to identify the object.
|id=legend_combobox|labelStyle
String# Defines the style of the label.
labelStyleDefines the style of the label. You can use CSS to style the label element.
|labelStyle=font-weight: bold; color: red;|onSelect
function# Defines a callback run when the user picks an entry.
onSelectDefines a callback run when the user picks an entry. It receives the Ext select event arguments (combo, record, index) — read the chosen text with record.get('value') — and this is the layer. The value is resolved as a key of the layer functions object or, failing that, the text itself is evaluated as a function (a body or a full function(){...}); unlike the other callbacks it does NOT look for a global (setQueryGlobalProperties) function of that name. PS: the layer is recalculated on select anyway; use onSelect for side effects such as changing layers or updating a window.
|onSelect=onRegionSelected|functions: {
onRegionSelected: function(combo, record, index) {
this.changeLayers({name: 'CSR:' + record.get('value'), index: 0});
}
}setValue
function(value)# Selects an entry from code.
setValueSelects an entry from code. Pass one of the data values; it does not fire select, so call forceRecalc() on an InputManager (or fire the event) when the layer must be recalculated.
- value String
- One of the values listed in
data.
Ext.getCmp('region_combo').setValue('Protected Areas');value
String# Value stored in inputs.id[ID] (and inputs[i]): the selected entry of data as a string (the first entry is selected initially).
valueValue stored in inputs.id[ID] (and inputs[i]): the selected entry of data as a string (the first entry is selected initially). The layer recalculates on the combobox select event (user choice).
{{combobox|id=region_combo|fieldLabel=Region|data=[['Municipalities'],['Protected Areas']]}}beforeCalc: function(inputs) {
var region = inputs.id['region_combo']; // 'Municipalities' or 'Protected Areas'
}width
Number= 190# Defines the width of the combobox in pixels.
widthDefines the width of the combobox in pixels.
|width=250|filefield · open a local file (input)
FileField7 entriesWritten in a layer's descriptionHtml as {{filefield|parameter=value|...}}
PS: This object cannot be sent to 'expression'.
Usage: {{filefield|fieldLabel=loadshp|id=loadshp|_onChange=function(){alert('changed')}}}
eventNames
Array.<string># Defines the list of events by name.
eventNamesDefines the list of events by name. Use this property to define callback functions to any of the following events.
['added', 'afterrender', 'beforedestroy', 'beforehide', 'beforerender', 'beforeshow', 'beforestaterestore',
'beforestatesave', 'blur', 'change', 'destroy', 'disable', 'enable', 'focus', 'hide', 'invalid', 'move', 'removed', 'render',
'resize', 'show', 'specialkey', 'staterestore', 'statesave', 'valid']fieldLabel
String# Defines the label shown at the left of the file input (Ext fieldLabel).
fieldLabelDefines the label shown at the left of the file input (Ext fieldLabel). hideLabel=true removes the label and its reserved space; other Ext.form.Field configs are passed through unchanged.
|fieldLabel=Load a shapefile (.zip)|hideLabel
Boolean= false# Set true to hide the label element and the space reserved for it.
hideLabelSet true to hide the label element and the space reserved for it.
|hideLabel=true|id
String# Defines the id of the input; it is the key used in inputs.id[ID] and the id of the Ext field (Ext.getCmp(id)), so it must be unique in the page.
idDefines the id of the input; it is the key used in inputs.id[ID] and the id of the Ext field (Ext.getCmp(id)), so it must be unique in the page.
|id=loadshp|ignoreUpdate
Boolean= false# Defines if it should ignore the widget change event.
ignoreUpdateDefines if it should ignore the widget change event. If it's false, it dispatches the update event at every file selection.
inputType
String= file# The HTML input type.
inputTypeThe HTML input type. It is always forced to file by the tool, so a value written in the markup is ignored (documented only to explain why it cannot be changed).
value
function# Value stored in inputs.id[ID]: not the file itself but a getter function.
valueValue stored in inputs.id[ID]: not the file itself but a getter function. Call it — inputs.id[ID]() — to obtain the selected File (the first entry of the DOM files list) or undefined when nothing is selected. It is a function so the value can never be serialized to the calculation WebWorker (expression); read it in beforeCalc, in a _onchange= callback or in a button handler. The layer recalculates on the change event of the input (a new file chosen) unless ignoreUpdate=true.
{{filefield|fieldLabel=loadshp|id=loadshp|_onChange=onSelectFile}}functions: {
onSelectFile: function() {
var file = this.getInputs().id['loadshp']();
if (file) ExtjsUtils.GEOJSON.shapefile2GeojsonAsync(file, {layer: this, fromProj: 'EPSG:4326'});
}
}hoverpixel · value under the mouse (input)
Hoverpixel16 entriesWritten in a layer's descriptionHtml as {{hoverpixel|parameter=value|...}}
Usage: {{hoverpixel}}
checked
Boolean= false# Defines if the hoverPixel should start enabled.
checkedDefines if the hoverPixel should start enabled. Set true to start enabled, false otherwise.
|checked = true|fieldLabel
String# Define the text that will be displayed at the left of the toggler
fieldLabelDefine the text that will be displayed at the left of the toggler
|text=This is the label text|getLayerValues
function(evt, layer) : Array.<Number>|null# Reads the values of the composed map under a mouse event: one value per inner layer (from the legend colours of the rendered tiles) plus one extra entry with the result of the layer expression for those values.
getLayerValuesReads the values of the composed map under a mouse event: one value per inner layer (from the legend colours of the rendered tiles) plus one extra entry with the result of the layer expression for those values. This is the layerVals argument of runOnClick/runOnHover; call it from code (Ext.getCmp(id).items.get(0).getLayerValues(evt, layer)) to sample the map from any mouse event. Returns null when the layer is hidden, the legend is not loaded yet, or the mouse is outside the map data (all layers null/transparent).
- evt MouseEvent
- Mouse event with the screen position to sample.
- layer OpenLayers.Layer.Composed
- The composed layer to read (normally the tool's own layer).
Returns [value of layer 0, ..., value of layer n-1, expression result], or null.
hideLabel
Boolean= false# Defines if the label of the HoverPixel should be displayed.
hideLabelDefines if the label of the HoverPixel should be displayed. Set true to hide the label, false to show it.
|hideLabel=true|iconCls
String= cmn-toggle-icon# Defines the CSS class of the toggle switch icon; replace the default to restyle the switch.
iconClsDefines the CSS class of the toggle switch icon; replace the default to restyle the switch.
|iconCls=my-toggle-icon|id
String# Defines the id to identify the object.
idDefines the id to identify the object.
|id=exemple_hover_pixel|labelBefore
Boolean= false# Set true to render the text label before (left of) the toggle switch instead of after it.
labelBeforeSet true to render the text label before (left of) the toggle switch instead of after it.
|labelBefore=true|labelStyle
String# Defines the style of the label at the HoverPixel toggler.
labelStyleDefines the style of the label at the HoverPixel toggler. You can use CSS to style the label element.
|labelStyle=font-weight: bold; color: red;|notify
Boolean= true# Set false to suppress the notification shown when the tool is activated ("click on the map...").
notifySet false to suppress the notification shown when the tool is activated ("click on the map...").
|notify=false|runOnClick
function= undefined# Defines a callback when the user clicks on the map.
runOnClickDefines a callback when the user clicks on the map.
It passes the following parameters for the callback function: handleOnClick(layerVals, inputs, coordinates, clickEvent, lastCoordinates)
- layerVals Array
- Array with the values of the maps at the pixel that was clicked.
- inputs Array
- Array with the values of the inputs defined in the descriptionHtml.
- coordinates OpenLayers.LonLat
- The point that was clicked, in the map's projection (Web Mercator, metres) despite the names:
lonis x andlatis y. For degrees, transform it:coordinates.clone().transform(ExtjsUtils.JS.getMap().getProjectionObject(), new OpenLayers.Projection("EPSG:4326"))(lastCoordinates below already holds degrees, of the previous click and hover). - clickEvent MouseEvent
- Mouse event that triggered the function.
- lastCoordinates Object
- Object with the last coordinates (latitude, longitude) from the last click and the last hover events. lastCoordinates = { click: { lat: // Latitude of the last click lon: // Longitude of the last click }, hover: { lat: // Latitude of the last hover lon: // Longitude of the last hover } }
|handleOnClick: function(layerVals, inputs, coordinates, clickEvent, lastCoordinates) {
var degrees = coordinates.clone().transform(ExtjsUtils.JS.getMap().getProjectionObject(), new OpenLayers.Projection("EPSG:4326"));
ExtjsUtils.ALERTIFY.log("Latitude: " + degrees.lat.toFixed(3) + " Longitude: " + degrees.lon.toFixed(3));
}|runOnClickOutside
function# True to run the callback function even when clicking outside of the layer, False to disable.
runOnClickOutsideTrue to run the callback function even when clicking outside of the layer, False to disable. (Default False)
runOnHover
function= undefined# Defines a callback when the user hovers the map.
runOnHoverDefines a callback when the user hovers the map.
It passes the following parameters for the callback function: handleOnClick(layerVals, inputs, coordinates, clickEvent, lastCoordinates)
- layerVals Array
- Array with the values of the maps at the pixel that was hovered.
- inputs Array
- Array with the values of the inputs defined in the descriptionHtml.
- coordinates OpenLayers.LonLat
- The point that was hovered, in the map's projection (Web Mercator, metres) despite the names:
lonis x andlatis y. For degrees, transform it:coordinates.clone().transform(ExtjsUtils.JS.getMap().getProjectionObject(), new OpenLayers.Projection("EPSG:4326"))(lastCoordinates below already holds degrees, of the previous click and hover). - mouseMoveEvent MouseEvent
- Mouse event that triggered the function.
- lastCoordinates Object
- Object with the last coordinates (latitude, longitude) from the last click and the last hover events. lastCoordinates = { click: { lat: // Latitude of the last click lon: // Longitude of the last click }, hover: { lat: // Latitude of the last hover lon: // Longitude of the last hover } }
|handleOnHover: function(layerVals, inputs, coordinates, mouseMoveEvent, lastCoordinates) {
ExtjsUtils.ALERTIFY.log("Latitude: " + coordinates.lat + " Longitude: " + coordinates.lon);
}|runOnHoverOutside
function# True to run the callback function even when hovering outside of the layer, False to disable.
runOnHoverOutsideTrue to run the callback function even when hovering outside of the layer, False to disable. (Default False)
text
String# Define the text that will be displayed at the right of the toggler
textDefine the text that will be displayed at the right of the toggler
|text=This is the example text|unselect
Boolean= true# Only changes the activation message: with the default true it says a single point is expected, with false several.
unselectOnly changes the activation message: with the default true it says a single point is expected, with false several. The hoverpixel is never deactivated automatically after a click.
|unselect=false|value
Object# Value stored in inputs.id[ID]: the lastInfo object {click, hover} with the coordinates ({lon, lat} in EPSG:4326, or null before the first event) of the last click and of the last mouse move …
valueValue stored in inputs.id[ID]: the lastInfo object {click, hover} with the coordinates ({lon, lat} in EPSG:4326, or null before the first event) of the last click and of the last mouse move while the tool is active. The object is updated in place, so it is always current when read in beforeCalc/expression; it is also the last argument of runOnClick/runOnHover (inside the callback it still holds the previous event — the current one is written right after the callback returns; use the coordinates argument for the current position). The input is registered on the forceupdatelayer event of the widget, which nothing fires by itself — moving the mouse or clicking does not recalculate the layer. React inside runOnClick/runOnHover (which also receive the map values) or trigger the recalculation yourself (e.g. forceRecalc() on an InputManager).
{{hoverpixel|id=hover_tool|text=Inspect values|runOnClick=onMapClick}}functions: {
onMapClick: function(layerVals, inputs, coords, evt, lastInfo) {
console.log(coords, lastInfo.click, inputs.id['hover_tool'] === lastInfo); // current, previous, true
}
}inputmanager · values kept for your functions (input)
InputManager6 entriesWritten in a layer's descriptionHtml as {{inputmanager|parameter=value|...}}
PS: DOM elements cannot be used in 'expression' context, because them cannot be sent to WebWorkers (javascript language limitation).
Usage: '{{inputmanager}}'
forceRecalc
function()# Force a legend map recalculation.
forceRecalcForce a legend map recalculation.
getValue
function(key) : *# Get the stored value by his property name, if it does not exists returns null.
getValueGet the stored value by his property name, if it does not exists returns null.
- key String
- Stored property name.
Returns Desired stored property when it exists or null otherwise.
id
String# Defines the id of the input; it is the key used to reach the manager in inputs.id[ID] (required, the tool renders nothing visible).
idDefines the id of the input; it is the key used to reach the manager in inputs.id[ID] (required, the tool renders nothing visible).
|id=state|setDefaultValues
function(obj, local)# Set default values to the stored elements, these values are used before any other value is defined and never update or replace another stored values.
setDefaultValuesSet default values to the stored elements, these values are used before any other value is defined and never update or replace another stored values.
PS: Auxiliary function to make easy wrinting the script (typically called in onInputsReady or at the start of beforeCalc). PS: This function never fire layer update.
- obj Object
- Default values properties.
- local Boolean
- True when the properties should be store locally (and not sent to expression WebWorkers callbacks).
inputs.id['state'].setDefaultValues({year: 2020, scenario: 'base'});setValues
function(obj, cancelUpdate, local)# Stores object properties for later usage.
setValuesStores object properties for later usage.
PS: If has name property collision the older is replaced. PS: Values go to one of two buckets of the manager: global (the default — serialized and sent to expression, so it must hold plain JSON-compatible data) or _local_ (with local=true — kept in the browser only, may hold DOM elements, Ext components, functions or circular objects). getValue(key) looks in global first, then in _local_.
- obj Object
- Object with the properties to be stored.
- cancelUpdate Boolean
- False if this change must cause layer recalculation, True otherwise.
- local Boolean
- True to store the property locally, False otherwise. The local properties aren't sent to 'expression' calbacks. (i.e. If a element is recursive or have DOM elements, it must local avoid stringify errors on 'expression' callbacks)
inputs.id['state'].setValues({year: 2020}); // recalculates the layerinputs.id['state'].setValues({lastInterval: cur}, true, true); // silent, browser-onlyvalue
Object# Value stored in inputs.id[ID]: the manager object itself, with getValue(key), setValues(obj, cancelUpdate, local), setDefaultValues(obj, local) and forceRecalc() (listed in this group) and …
valueValue stored in inputs.id[ID]: the manager object itself, with getValue(key), setValues(obj, cancelUpdate, local), setDefaultValues(obj, local) and forceRecalc() (listed in this group) and the global bucket where the stored properties live (inputs.id[ID].global.key is a shortcut for getValue). The layer recalculates on its own change event, which setValues (unless cancelled) and forceRecalc trigger. Only the global bucket reaches expression (WebWorker); values stored with local=true are kept in a bucket that is not serialized and can therefore hold DOM/Ext references.
{{inputmanager|id=state}}beforeCalc: function(inputs) {
var year = inputs.id['state'].getValue('year') || 2020;
}label · text
Label6 entriesWritten in a layer's descriptionHtml as {{label|parameter=value|...}}
Usage: {{label|}}
cls
String# Extra CSS class(es) added to the <label> element.
clsExtra CSS class(es) added to the <label> element.
{{label|cls=slider_label|text=0%}}forId
String# Defines the id of the form field the label is for (rendered as the for attribute of the <label>), so clicking the label focuses that field.
forIdDefines the id of the form field the label is for (rendered as the for attribute of the <label>), so clicking the label focuses that field.
{{label|text=Price (US$)|forId=soy_value}}{{textfield|id=soy_value|isnumeric}}html
String# Defines the content of the label as raw HTML (not escaped).
htmlDefines the content of the label as raw HTML (not escaped). Everything after html= up to the next | is the value, so it may contain = characters. text wins when both are given.
{{label|cls=slider_label|html=0% <b>...</b> 100%|id=scale_label}}id
String# Defines the id of the label component (Ext.getCmp(id)), needed to change its text from code or to reference it with getid= in another tag.
idDefines the id of the label component (Ext.getCmp(id)), needed to change its text from code or to reference it with getid= in another tag. Generated when omitted.
{{label|id=deforestation_label|text=20%}}style
String# Inline CSS applied to the <label> element.
styleInline CSS applied to the <label> element. Any other Ext.form.Label/Ext.Component config (hidden, width...) is passed through unchanged.
{{label|text=Total|style=font-weight: bold; color: #336699;}}text
String# Defines the text of the label.
textDefines the text of the label. It is HTML-escaped, so use html when markup is needed. Update it later with Ext.getCmp(id).setText(text) (typically from an on_change= listener of a slider or textfield through getid=).
{{label|id=deforestation_label|text=Deforestation: 20%}}legendhtml · legend of the calculated map
LegendHtml7 entriesWritten in a layer's descriptionHtml as {{legendhtml|parameter=value|...}}
Usage: '{{legendhtml}}'
autoWidth
Boolean= true# Set true (default) to let the legend panel take the width of its container; set false to give it a fixed width.
autoWidthSet true (default) to let the legend panel take the width of its container; set false to give it a fixed width.
|autoWidth=false|width=250|filterLayers
Array.<Number>= null# Defines an array of indexes of layers to be included in map legend (from 0 to quantity of layers).
filterLayersDefines an array of indexes of layers to be included in map legend (from 0 to quantity of layers). If not defined, all layer legends are shown by default. Otherwise, only the listed indexes are included.
Ex: A composed layer with three maps: name: "CSR:estados,CSR:roads,CSR:municipalities", If 'filterLayers=[0,1]' is defined in the layer object only the legends of 'CSR:estatdos' and 'CSR:roads' are shown.
|filterLayers = [1,2]|id
String# Defines the id of the legend panel component (Ext.getCmp(id)), e.g. to show()/hide() it or to find the legend entries inside it.
idDefines the id of the legend panel component (Ext.getCmp(id)), e.g. to show()/hide() it or to find the legend entries inside it. Generated when omitted. Other GeoExt.WMSLegend/Ext.Panel configs (cls, style, hidden, useScaleParameter, autoWidth...) are passed through.
|id=main_legend|legendId
String= null# Defines the legend container id.
legendIdDefines the legend container id. You can use this id to toggle each legend filter individually.
|legendId=WIDGET_OBJECT_ID|preventClick
Boolean= false# Defines if the user can filter the maps categories by clicking on the legend.
preventClickDefines if the user can filter the maps categories by clicking on the legend. Set it true to ignore the legend click, false otherwise.
|preventClick = true|reverseLegend
Boolean= false# Defines if it should sort the legend on the decreasing order.
reverseLegendDefines if it should sort the legend on the decreasing order. Set it true to use the decreasing order, false otherwise.
|reverseLegend = true|useScaleParameter
Boolean= false# Set true to request a new legend image from the server whenever the map scale changes (GeoServer SCALE parameter), for styles that depend on the scale.
useScaleParameterSet true to request a new legend image from the server whenever the map scale changes (GeoServer SCALE parameter), for styles that depend on the scale. Off by default: the legend is generated once and reused, which is faster and keeps the click-to-filter behaviour stable.
|useScaleParameter=true|livecomposedsplit · split-screen comparison
LiveComposedSplit16 entriesWritten in a layer's descriptionHtml as {{livecomposedsplit|parameter=value|...}}
The layer must be a Composed layer (typically the same WMS layer twice in `name` with two `styles`). Put the tool in `descriptionHtml`, open the query panel, choose left/right styles, then press Compare to show a draggable vertical divider.
Required parameters: displayNames, layerNames (same order and length). Recommended: id, baseName, leftDefault, rightDefault. Optional: layout=compact (default, stacked for the layer card) or layout=inline (legacy single row).
Usage: {{livecomposedsplit|id=...|displayNames=...|layerNames=...|baseName=...|leftDefault=...|rightDefault=...}}
applySelectedStyles
function()# Pushes the two selected styles to the composed layer (changeLayers with the left style on child 0 and the right style on child 1) and makes both children visible.
applySelectedStylesPushes the two selected styles to the composed layer (changeLayers with the left style on child 0 and the right style on child 1) and makes both children visible. Called when Compare is pressed; after calling it yourself use refreshActiveSplit() so the divider clips the new child divs.
Ext.getCmp('precip_split_container').applySelectedStyles();baseName
String# WMS layer name used with each style (e.g. CSR:precip_monthly_average).
baseNameWMS layer name used with each style (e.g. CSR:precip_monthly_average). Defaults to layer.params.LAYERS when omitted.
|baseName=CSR:precip_monthly_average|cls
String# Extra CSS class for the Compare toggle button (replaces the default clickable; the class live-composed-split-compare is always added).
clsExtra CSS class for the Compare toggle button (replaces the default clickable; the class live-composed-split-compare is always added).
|cls=my-compare-button|composedLayerName
String# Name of the Composed layer to split.
composedLayerNameName of the Composed layer to split. If omitted, the first OpenLayers.Layer.Composed on the map is used.
|composedLayerName=CSR:precip_monthly_average|destroySplitControl
function()# Removes the split divider control from the map for good (it is recreated on the next Compare press).
destroySplitControlRemoves the split divider control from the map for good (it is recreated on the next Compare press). The panel calls it when its layer is removed; call it to force a clean state. It does not restore the single-style view — press the Compare button off (toggle(false)) for the normal close.
Ext.getCmp('precip_split_container').destroySplitControl();displayNames
String# Comma-separated labels shown in the left/right combo boxes (required).
displayNamesComma-separated labels shown in the left/right combo boxes (required).
|displayNames=January,February,March,April,May,June,July,August,September,October,November,December|id
String# Id of the Compare button (wrapper id is id + "_container").
idId of the Compare button (wrapper id is id + "_container").
|id=my_composed_split|isComparisonActive
function() : Boolean# Tells whether the split comparison is currently shown on the map (Compare pressed and the divider active).
isComparisonActiveTells whether the split comparison is currently shown on the map (Compare pressed and the divider active). Get the panel with Ext.getCmp(id + '_container'), where id is the markup id.
Returns true while the two styles are being compared.
if (Ext.getCmp('precip_split_container').isComparisonActive()) { ... }layerNames
String# Comma-separated WMS style names aligned with displayNames (required).
layerNamesComma-separated WMS style names aligned with displayNames (required). When Compare is pressed, the composed layer switches to the selected pair.
|layerNames=precip_monthly_average_1,precip_monthly_average_2,...|layout
String= compact# Presentation inside the layer query panel. compact (default): stacked fields that fit the ~300px layer card. inline: horizontal row (legacy Left / Right / Compare on one line).
layoutPresentation inside the layer query panel. compact (default): stacked fields that fit the ~300px layer card. inline: horizontal row (legacy Left / Right / Compare on one line).
|layout=inline|leftDefault
String# Initial left combo value; must be one of displayNames.
leftDefaultInitial left combo value; must be one of displayNames.
|leftDefault=January|refreshActiveSplit
function()# Re-applies the selected styles and re-clips the split after the composed layer's children were replaced (e.g. by your own changeLayers call), keeping the divider position.
refreshActiveSplitRe-applies the selected styles and re-clips the split after the composed layer's children were replaced (e.g. by your own changeLayers call), keeping the divider position. Does nothing while the comparison is not active.
Ext.getCmp('precip_split_container').refreshActiveSplit();rightDefault
String# Initial right combo value; must be one of displayNames (and different from left).
rightDefaultInitial right combo value; must be one of displayNames (and different from left).
|rightDefault=August|setComparisonEditingEnabled
function(enabled)# Enables or disables the right-side combo and the swap button.
setComparisonEditingEnabledEnables or disables the right-side combo and the swap button. The panel calls it itself (only the left combo is editable while idle; both unlock when comparing); call it to lock the choice while data loads.
- enabled Boolean
trueto allow changing the right side and swapping,falseto lock them.
Ext.getCmp('precip_split_container').setComparisonEditingEnabled(false);swapSides
function()# Exchanges the left and right styles (combos and map) and re-clips the split, keeping the divider where it is.
swapSidesExchanges the left and right styles (combos and map) and re-clips the split, keeping the divider where it is. Does nothing while the comparison is not active — what the swap button does.
Ext.getCmp('precip_split_container').swapSides();text
String= Compare Layers# Label on the Compare toggle button (before the split is active).
textLabel on the Compare toggle button (before the split is active).
|text=Compare Monthly Data|loadcsv · load a CSV table (input)
LoadCsv14 entriesWritten in a layer's descriptionHtml as {{loadcsv|parameter=value|...}}
columnNameToInd
function(columnName) : Number# Get the index of a column with the 'columnName' name.
columnNameToIndGet the index of a column with the 'columnName' name.
- columnName String
- Column name to search for.
Returns When it exists returns the column index, otherwise -1.
columnNamesToIndexes
function(columnNames) : Array.<Number># Resolves column names to column indexes: every string entry is looked up in the header (-1 when absent) and every numeric entry is kept as it is.
columnNamesToIndexesResolves column names to column indexes: every string entry is looked up in the header (-1 when absent) and every numeric entry is kept as it is. A single value is accepted in place of the array. This is what getLines/createIndexes do with their columns argument.
- columnNames Array.<(String|Number)>|String|Number
- Column names and/or indexes.
Returns The column indexes, in the same order.
inputs.id["fire_csv"].columnNamesToIndexes(["Year", 2]); // e.g. [1, 2]cors
Boolean= false# Downloads the CSV through the Mappia CORS proxy; use it for servers that do not send CORS headers.
corsDownloads the CSV through the Mappia CORS proxy; use it for servers that do not send CORS headers.
|cors=true|createIndexes
function(columns)# Create indexes for faster search.
createIndexesCreate indexes for faster search.
PS: Indexes are used to faster results on "getLines" calls, apply only when all [columns] are indexes.
- columns Array
- (Optional) Array of indexes/names of the filtered columns.
{...
beforeCalc: function(inputs) {
inputs.id['CSV_WIDGET_EXAMPLE_ID'].createIndexes(['Key', 'Year']);
alert(inputs.id['CSV_WIDGET_EXAMPLE_ID'].getLines(['Key','Year'], [100, 2020]).length);
}
}getColunsInd
function() : Array.<String># Returns a copy of the header row — the column names, in order — so query code can discover columns instead of hard-coding indexes.
getColunsIndReturns a copy of the header row — the column names, in order — so query code can discover columns instead of hard-coding indexes. The name is a historical typo of getColumnsInd, kept for compatibility (the platform and many queries call it by this spelling; there is no correctly spelled alias).
Returns Copy of the header row.
var headers = inputs.id["fire_csv"].getColunsInd(); // ["Municipality", "Year", "Fires"]
var iFires = headers.indexOf("Fires");getLineCount
function() : Number# Number of data lines in the table (the header line is not counted).
getLineCountNumber of data lines in the table (the header line is not counted).
Returns How many data lines the CSV has.
var csv = inputs.id["fire_csv"];
for (var i = 0; i < csv.getLineCount(); i++) total += parseFloat(csv.getValue(2, i));getLines
function(columns, values, includeHeader) : Array.<Array.<String>># Returns the lines (arrays of cell strings) whose cells in columns equal the corresponding entries of values.
getLinesReturns the lines (arrays of cell strings) whose cells in columns equal the corresponding entries of values. Columns may be given by index or by header name; to filter on several columns give one value per column, e.g. getLines([1, "Year"], ["Park A", 2024]). Values are compared as strings (the CSV is always text). Called with no arguments it returns every data line (header skipped) — a common idiom. When all filtered columns were indexed with createIndexes the lookup uses the index instead of scanning every line.
- columns Array.<(String|Number)>
- Indexes and/or names of the columns to filter on.
- values Array
- One value per entry of
columns. - includeHeader Boolean
- True to also return the header line when it matches (only in the scanning path, i.e. without indexes).
Returns The matching lines; all data lines when no filter is given.
var csv = inputs.id["fire_csv"];
var rows2024 = csv.getLines(["Year"], [2024]); // by header name
var rowsParkA = csv.getLines([0, "Year"], ["Park A", 2024]); // two columns
var allRows = csv.getLines(); // every data linegetValue
function(column, line, includeHeader) : String# Get a value by the matrix index and column.
getValueGet a value by the matrix index and column.
- column Number
- Column index (First index is 0).
- line Number
- Line index (First index is 0).
- includeHeader boolean
- True to include the header line in the matrix index, False to ignore.
Returns Get the cell value.
id
String# Defines the id of the input; it is the key used to read the table in inputs.id[ID] (required, the tool renders nothing visible).
idDefines the id of the input; it is the key used to read the table in inputs.id[ID] (required, the tool renders nothing visible).
|id=emissions_csv|removeEmptyLines
boolean= false# Ignore the empty lines, removing them from the parsed CSV.
removeEmptyLinesIgnore the empty lines, removing them from the parsed CSV. True to remove the empty lines from the CSV.
setValue
function(column, line, value)# Change a cell value by its cell index.
setValueChange a cell value by its cell index.
- column Numeric
- Column index.
- line Numeric
- Line index to change (ignore the header information when it exists).
- value *
- New value to replace the older value.
trim
Boolean= false# Requests that cell values be trimmed of surrounding whitespace.
trimRequests that cell values be trimmed of surrounding whitespace. The flag is accepted and forwarded to the CSV parser, but the current parser ignores it (cells are stored as written, quotes removed), so trim values yourself when needed. Kept for compatibility with existing queries.
|trim=true|url
String# Defines the URL of the CSV file to download (required).
urlDefines the URL of the CSV file to download (required). Relative URLs are resolved against the Mappia host, so backend endpoints such as /wmtp/calc/... work; escape = inside query strings as \=. The layer waits for the download before calculating.
|url=/theme/app/data/emissoesco2.csv||url=/wmtp/calc/areacategorical/?layers\=CSR:estados&styles\=1|value
ExtjsUtils.CSV.CsvTable# Value stored in inputs.id[ID]: an ExtjsUtils.CSV.CsvTable wrapping the parsed file (first row = header).
valueValue stored in inputs.id[ID]: an ExtjsUtils.CSV.CsvTable wrapping the parsed file (first row = header). Read it with the CsvTable methods listed in this group (getLines, getValue, columnNameToInd, createIndexes, getLineCount...). It is undefined until the download finishes: the layer waits for the resource and recalculates on its waitend event, so beforeCalc/expression can rely on it being loaded.
{{loadcsv|id=emissions_csv|url=/theme/app/data/emissoesco2.csv|removeEmptyLines=true}}beforeCalc: function(inputs) {
var csv = inputs.id['emissions_csv']; // columns: percentage, carbon_loss
var rows = csv.getLines(0, '25'); // rows whose first column equals 25
}loadjson · load JSON (input)
LoadJson4 entriesWritten in a layer's descriptionHtml as {{loadjson|parameter=value|...}}
Usage: {{loadjson}}
cors
Boolean= false# Loads the JSON through the Mappia CORS proxy (for servers without CORS headers).
corsLoads the JSON through the Mappia CORS proxy (for servers without CORS headers).
|cors=true|id
String# Defines an id for the stored info on layerInputs.
idDefines an id for the stored info on layerInputs.
|id=window-div-id|on javascript: layer.getInputs().id["NAME_DEFINED_HERE"]url
String# Defines the url to load the json from.
urlDefines the url to load the json from.
|url=https://maps.csr.ufmg.br/theme/app/data/conab/limites_municipios_conab.geojson|value
Object|Array# Value stored in inputs.id[ID]: the parsed JSON (JSON.parse of the response body — an object or an array; an empty response gives []).
valueValue stored in inputs.id[ID]: the parsed JSON (JSON.parse of the response body — an object or an array; an empty response gives []). It is undefined until the download finishes: the layer waits for the resource and recalculates on its waitend event, so beforeCalc/expression can rely on it being loaded.
{{loadjson|id=limits|url=https://maps.csr.ufmg.br/theme/app/data/example.geojson}}beforeCalc: function(inputs) {
var geojson = inputs.id['limits'];
console.log(geojson.features.length);
}opacityslider · layer opacity
OpacitySlider8 entriesWritten in a layer's descriptionHtml as {{opacityslider|parameter=value|...}}
Usage: '{{opacityslider}}'
aggressive
Boolean= false# Set true to apply the opacity while the thumb is being dragged instead of only when it is released.
aggressiveSet true to apply the opacity while the thumb is being dragged instead of only when it is released.
|aggressive=true|changeVisibility
Boolean= false# Set true to let the slider also control the layer visibility: the layer is hidden when the slider reaches minValue and shown again when it leaves it.
changeVisibilitySet true to let the slider also control the layer visibility: the layer is hidden when the slider reaches minValue and shown again when it leaves it. The layer must be visible when the slider is created.
|changeVisibility=true|complementaryLayer
OpenLayers.Layer# A second layer that is hidden when the slider reaches maxValue (GeoExt option to fade between two layers).
complementaryLayerA second layer that is hidden when the slider reaches maxValue (GeoExt option to fade between two layers). GeoExt expects a layer object here, which the markup cannot express (a string is not resolved to a layer), so this option is only usable from code; documented for completeness.
id
String# Defines the id of the slider component (Ext.getCmp(id)), e.g. to read getValue() or to hide() it.
idDefines the id of the slider component (Ext.getCmp(id)), e.g. to read getValue() or to hide() it. Generated when omitted. Every parameter of the tool is passed to GeoExt.LayerOpacitySlider / Ext.slider.SingleSlider unchanged (width, cls, vertical, hidden...).
|id=opacity|inverse
Boolean= false# Set true to make the slider work with transparency instead of opacity (100 = fully transparent).
inverseSet true to make the slider work with transparency instead of opacity (100 = fully transparent).
|inverse=true|maxValue
Number= 100# Defines the maximum value of the slider (opacity percent at the right end).
maxValueDefines the maximum value of the slider (opacity percent at the right end).
|maxValue=90|minValue
Number= 0# Defines the minimum value of the slider (opacity percent at the left end).
minValueDefines the minimum value of the slider (opacity percent at the left end).
|minValue=10|value
Number= 100# Defines the initial slider value (opacity in percent).
valueDefines the initial slider value (opacity in percent). It is only used when the layer has no opacity yet (opacity not set on the layer): otherwise the slider starts at the layer's current opacity.
|value=50|pickpoint · pick a point on the map (input)
PickPoint33 entriesWritten in a layer's descriptionHtml as {{pickpoint|parameter=value|...}}
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}}
checked
Boolean= false# Defines if Pickpoint should start selected.
checkedDefines 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.
fieldLabelSets 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.
geometryColorIf 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 …
getAttributesReturns 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 (
nameorder).
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.
getLastEventReturns 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).
getPointPosReturns 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.
iconClsDefines 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).
idDefines 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).
inputValueDefines 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.
labelDefines 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.
labelBeforeSet 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.
latDefines 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.
lonDefines 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.
markLayerIndDefines 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.
movePointMoves 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).
notifySet 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.
onMarkCallback 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.
onefeatureDefines 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.
pointVisibilityDefines 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.
removeAllClears 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.
removeAttributeRemoves 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).
runOnClickrunOnHover
function# Defines a callback function to run when clicking at the map.
runOnHoverDefines 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.
runOnHoverOutsideTrue 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.
scopeDefines 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.
searchAttributeFinds, 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.
setFeatureVisibilityAdds 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
trueto add (show) the feature,falseto 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).
setPointVisibilityShows or hides the marker drawn at the last clicked position (the same marker controlled by the pointVisibility parameter).
- state Boolean
trueto show the marker,falseto hide it.
inputs.id['property_pick'].setPointVisibility(false);text
String# Defines the text shown next to the toggle.
textDefines 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.
toggleActivates 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
trueto activate picking,falseto 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.
togglePointAdds 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.
unselectDefines 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.
valueValue 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});
}slider · number or range (input)
Slider17 entriesWritten in a layer's descriptionHtml as {{slider|parameter=value|...}}
backgroundColors
Array.<String># Array of colors of background slider values, to define background slider color based in slider value.
backgroundColorsArray of colors of background slider values, to define background slider color based in slider value. The values are defined from most to minimum with two properties each:
- color: {String} CSS color definition for the current interval. i.e. 'red','black','#FF0000', '#000000'.
- startValue: {Numeric} If defined define the initial value which above will apply this color, otherwise use theminimum slider value as default.
Ex.:
backgroundColors: [
{
// Define background color to red when slider has value above 75.
color: "red",
startValue: 75
},
{
// Define background color starting from value 0.
// That results two intervals, from 0 to 75 as blue, and from 76 to 100 as red.
color: "blue",
startValue: 0
}
]
cls
String# Extra CSS class(es) added to the slider element (appended to the default clickable).
clsExtra CSS class(es) added to the slider element (appended to the default clickable).
|cls=my_slider|disabled
Boolean= false# Set true to render the slider disabled (Ext disabled); enable it later with Ext.getCmp(id).enable().
disabledSet true to render the slider disabled (Ext disabled); enable it later with Ext.getCmp(id).enable().
|disabled=true|fieldLabel
String# Defines the label shown at the left of the slider (Ext fieldLabel).
fieldLabelDefines the label shown at the left of the slider (Ext fieldLabel).
|fieldLabel=Deforestation (%)|getValue
function() : Number# Returns the current value of a single-thumb slider.
getValueReturns the current value of a single-thumb slider. Call it on the component (Ext.getCmp(id) or a getid= reference), not on inputs.id[ID], which already holds the plain value.
Returns The current slider value.
var v = Ext.getCmp('deforestation_slider').getValue();getValues
function() : Array.<Number># Returns the value of every thumb; use it for range sliders created with values=[lo, hi].
getValuesReturns the value of every thumb; use it for range sliders created with values=[lo, hi].
Returns One value per thumb, in thumb order.
var range = Ext.getCmp('interval_slider').getValues(); // [lo, hi]gradient
Boolean= false# Set true to blend the backgroundColors into a continuous gradient along the filled part of the slider (each colour fading into the next from its startValue).
gradientSet true to blend the backgroundColors into a continuous gradient along the filled part of the slider (each colour fading into the next from its startValue). With the default false each interval is a solid colour, with a short blend only around the thumb. Has no effect without backgroundColors.
|backgroundColors=[{color: "green", startValue: 0}, {color: "red", startValue: 50}]|gradient=true|hideLabel
Boolean= false# Set true to hide the label and the space reserved for it (Ext hideLabel).
hideLabelSet true to hide the label and the space reserved for it (Ext hideLabel).
|hideLabel=true|id
String# Defines the id to identify the object.
idDefines the id to identify the object.
|id=example_slider|increment
Number# Defines the step of each increment or decrement in the actual value of the slider when being dragged.
incrementDefines the step of each increment or decrement in the actual value of the slider when being dragged.
|increment = 10|maxValue
Number# Defines the maximum value of the slider.
maxValueDefines the maximum value of the slider.
|maxValue = 100|minValue
Number# Defines the minimum value of the slider.
minValueDefines the minimum value of the slider.
|minValue = 0|setValue
function(value, animate)# Sets the slider value from code.
setValueSets the slider value from code. Firing the change event (the default) also updates inputs.id[ID] and recalculates the layer. For a range slider pass the thumb index first: setValue(index, value).
- value Number
- New value (clamped to
minValue/maxValue). - animate Boolean
- Set false to move the thumb without animation.
Ext.getCmp('deforestation_slider').setValue(20);thumbStyle
String= null# Defines extra CSS class(es) added to the slider thumb (the draggable handle), to restyle it.
thumbStyleDefines extra CSS class(es) added to the slider thumb (the draggable handle), to restyle it.
|thumbStyle=x-slider-thumb-cut|value
Number# Defines the initial value of the slider (default 100).
valueDefines the initial value of the slider (default 100).
At runtime the same value is what inputs.id[ID] (and inputs[i]) holds in beforeCalc/expression: a number, or an array [lower, upper] when the values range form is used. The layer recalculates on the slider change event (thumb released or value set from code).
|value = 100|beforeCalc: function(inputs) {
var threshold = inputs.id['deforestation_slider']; // number
}values
Array.<Number># Defines the slider interval limits.
valuesDefines the slider interval limits. If defined, the slider will be displayed as a range slider. It's return at the 'inputs' parameter will be a array of two values.
|values = [0, 250]||beforeCalc: function(inputs) {
let lowerValue = inputs[0][0]; // The value of the left drag
let upperValue = inputs[0][1]; // The value of the right drag
}|width
Number# Defines the slider width in pixels.
widthDefines the slider width in pixels. Any other Ext.slider.SingleSlider config (cls, fieldLabel, hideLabel, disabled, style, keyIncrement...) is also passed through unchanged.
|width=200|summedarea · sum inside a drawn area (input)
SummedArea10 entriesWritten in a layer's descriptionHtml as {{summedarea|parameter=value|...}}
CallBack parameters (context {OpenLayers.Layer}, layersValues {Array[Number]}, inputs {[Object]}, feature {Geometry})
runOnClick {Function} Callback called exactly after sum the map region.,
PS: 'layersValues' return the sum of each internal layer and an adittional value which is the sum of all pixels of resulting layer.
description
function(name, config, layer, parameters) : Ext.Container# Creates an input of summatory in any arbitrary area.
descriptionCreates an input of summatory in any arbitrary area.
CallBack parameters (context {OpenLayers.Layer}, layersValues {Array[Number]}, inputs {[Object]}, feature {Geometry}) runOnClick {Function} Callback called exactly after sum the map region.,
PS: 'layersValues' return the sum of each internal layer and an adittional value which is the sum of all pixels of resulting layer.
- name String
- Input name "summedarea".
- config Object
- Properties to customize the element.
- layer OpenLayers.Layer
- Layer which the widget is defined.
- parameters Array
- Array de parametros antes do processamento para o input.
Returns Returns an instance of summedarea Input.
getSummedLayerValues
function(layer, feature) : Array# Sums, for each inner layer of the composed map, the values of the rendered cells that fall inside a polygon (values decoded from the tile colours through the layer legend, null cells skipped).
getSummedLayerValuesSums, for each inner layer of the composed map, the values of the rendered cells that fall inside a polygon (values decoded from the tile colours through the layer legend, null cells skipped). This is what runOnClick receives as layersValues; call it from code (Ext.getCmp(id).items.get(0).getSummedLayerValues(layer, feature)) to sum any polygon feature. The returned array has one sum per inner layer followed by two extra entries: the number of cells read from the last layer and an array with the count of non-null cells of every layer.
- layer OpenLayers.Layer.Composed
- The composed layer whose tiles are read (normally the tool's own layer).
- feature OpenLayers.Feature.Vector
- Polygon feature delimiting the area to sum.
Returns [sum layer 0, ..., sum layer n-1, cellCount, [nonNull layer 0, ..., nonNull layer n-1]].
iconCls
String= cmn-toggle-icon# Defines the CSS class of the toggle switch icon; replace the default to restyle the switch.
iconClsDefines the CSS class of the toggle switch icon; replace the default to restyle the switch.
|iconCls=my-toggle-icon|id
String# Defines the id of the tool: the key used in inputs.id[ID] and the id of the container component (Ext.getCmp(id); the switch itself is Ext.getCmp(id).items.get(0)).
idDefines the id of the tool: the key used in inputs.id[ID] and the id of the container component (Ext.getCmp(id); the switch itself is Ext.getCmp(id).items.get(0)). Generated when omitted.
|id=sum_tool|labelBefore
Boolean= false# Set true to render the text label before (left of) the toggle switch instead of after it.
labelBeforeSet true to render the text label before (left of) the toggle switch instead of after it.
|labelBefore=true|notify
Boolean= true# Set false to suppress the notification shown when the tool is activated.
notifySet false to suppress the notification shown when the tool is activated.
|notify=false|runOnClick
function# Defines the callback run when the user finishes drawing the polygon (double-click closes it), with the values already summed.
runOnClickDefines the callback run when the user finishes drawing the polygon (double-click closes it), with the values already summed. Called as runOnClick(layersValues, inputs, feature) with this = the layer: layersValues is the array described in getSummedLayerValues, inputs is layer.getInputs() and feature the drawn OpenLayers.Feature.Vector polygon. The name is resolved as a key of the layer functions object, then as a global function, then as inline function text. The tool deactivates itself after the callback.
|runOnClick=onClickSum|functions: {
onClickSum: function(layersValues, inputs, feature) {
ExtjsUtils.ALERTIFY.log('Sum of layer 0: ' + layersValues[0] + ' (' + layersValues[layersValues.length - 1][0] + ' cells)');
}
}text
String# Defines the text shown next to the toggle switch.
textDefines the text shown next to the toggle switch.
|text=Sum an area|unselect
Boolean= true# Only changes the activation message (true: one selection expected, false: several); the tool always deactivates itself after a polygon is summed.
unselectOnly changes the activation message (true: one selection expected, false: several); the tool always deactivates itself after a polygon is summed.
|unselect=false|value
Array.<Number># Value stored in inputs.id[ID]: an array meant to hold the last layersValues (one sum per inner layer, see getSummedLayerValues).
valueValue stored in inputs.id[ID]: an array meant to hold the last layersValues (one sum per inner layer, see getSummedLayerValues). In the current implementation the tool does not copy the sums into it after drawing — it stays empty — so read the results in runOnClick and store what you need with an InputManager (setValues). The input is registered on the forceupdatelayer event of the switch (Ext.getCmp(id).items.get(0).forceUpdateLayer() recalculates the layer).
{{summedarea|id=sum_tool|runOnClick=onClickSum}}{{inputmanager|id=sums}}functions: {
onClickSum: function(layersValues, inputs, feature) {
inputs.id['sums'].setValues({areaSum: layersValues[0]}); // recalculates the layer
}
}textfield · text box (input)
Textfield9 entriesWritten in a layer's descriptionHtml as {{textfield|parameter=value|...}}
Usage: '{{textfield}}'
afteredit
Event# Event fired once the field loses focus (blur) and its text differs from the value it had when editing started; the listener receives the TextField.
aftereditEvent fired once the field loses focus (blur) and its text differs from the value it had when editing started; the listener receives the TextField. Unlike keyup it fires a single time per edit, so use it for expensive reactions. Attach it with on_afteredit= through a getid= reference, or from code with Ext.getCmp(id).on('afteredit', fn).
{{textfield|id=soy_value|isnumeric}}{{label|getid=soy_value|getid=on_afteredit=console.log(this.getRawValue())}}Ext.getCmp('soy_value').on('afteredit', function(field) { console.log(field.getRawValue()); });fieldLabel
String# Defines the TextField label.
fieldLabelDefines the TextField label.
|fieldLabel = This is the field label|getRawValue
function() : String# Returns the text currently in the field, unprocessed (this is what inputs.id[ID] holds).
getRawValueReturns the text currently in the field, unprocessed (this is what inputs.id[ID] holds). Call it on the component (Ext.getCmp(id)).
Returns The raw text of the input element.
var text = Ext.getCmp('soy_value').getRawValue();hideLabel
Boolean= false# Defines if it should completely hide the label element (label and separator) of the TextField.
hideLabelDefines if it should completely hide the label element (label and separator) of the TextField. That is, if this property is set to true, the label will be hidden. Otherwise, the label will be shown by default. PS: Since the label will be shown by default, even if you do not specify a fieldLabel, the space for it will still be reserved so that the TextField will line up with other fields that do have labels. This space will be removed if you define it to be hidden.
|hideLabel = true|id
String# Defines the id to identify the object.
idDefines the id to identify the object.
|id=example_text_field|isnumeric
boolean# Defines the TextField content as numeric only.
isnumericDefines the TextField content as numeric only.
|isnumeric=true|setRawValue
function(value)# Replaces the text of the field from code.
setRawValueReplaces the text of the field from code. It does not fire keyup, so call forceRecalc() on an InputManager (or fire the event) when the layer must be recalculated with the new text.
- value String
- New text for the field.
Ext.getCmp('soy_value').setRawValue('43');style
String# Defines the TextField style properties.
styleDefines the TextField style properties. You can use CSS style rules to customize it.
|style = color:black;|value
String# Defines the initial value to the TextField content.
valueDefines the initial value to the TextField content.
At runtime inputs.id[ID] (and inputs[i]) holds the current text exactly as typed (getRawValue(), always a string — convert it with parseFloat when isnumeric is used). The layer recalculates on every keyup (each keystroke); the widget also fires afteredit when the field loses focus with a changed value.
|value = text|beforeCalc: function(inputs) {
var price = parseFloat(inputs.id['soy_value']) || 0;
}timeline · scenarios over time (input)
Timeline31 entriesWritten in a layer's descriptionHtml as {{timeline|parameter=value|...}}
fieldLabel
String# Defines a label for the Timeline.
fieldLabelDefines a label for the Timeline. It will be shown at the left of the button to hide the tiemline, by default.
|fieldLabel=This is the field label|getCurrentLayerStyle
function() : String# Returns the WMS style currently applied to the layer (layer.params.STYLES), or an empty string for the default style.
getCurrentLayerStyleReturns the WMS style currently applied to the layer (layer.params.STYLES), or an empty string for the default style.
Returns The active style name.
var style = Ext.getCmp('years_tl').getTimeline().getCurrentLayerStyle();getDesiredVisibility
function() : Boolean# Returns the visibility the timeline has, or will have when its layer becomes visible: true may be returned while the panel is actually hidden because the layer is hidden.
getDesiredVisibilityReturns the visibility the timeline has, or will have when its layer becomes visible: true may be returned while the panel is actually hidden because the layer is hidden.
Returns true when the timeline is (or will be) shown together with the layer.
var shown = Ext.getCmp('years_tl').getTimeline().getDesiredVisibility();getMainThumb
function() : Ext.slider.Thumb# Returns the main (middle) thumb of the slider — the one that selects the current step; its value is the 0-based step index.
getMainThumbReturns the main (middle) thumb of the slider — the one that selects the current step; its value is the 0-based step index. The outer thumbs (thumbs[0], thumbs[2]) bound the animation range.
Returns The main thumb; read the step index from .value.
var stepIndex = Ext.getCmp('years_tl').getTimeline().getMainThumb().value;getMaxThumbValue
function() : Number# Returns the position of the right (max) thumb: the last step index the animation reaches.
getMaxThumbValueReturns the position of the right (max) thumb: the last step index the animation reaches.
Returns 0-based step index of the max thumb.
var last = Ext.getCmp('years_tl').getTimeline().getMaxThumbValue();getMinThumbValue
function() : Number# Returns the position of the left (min) thumb: the step index the animation restarts from.
getMinThumbValueReturns the position of the left (min) thumb: the step index the animation restarts from.
Returns 0-based step index of the min thumb.
var first = Ext.getCmp('years_tl').getTimeline().getMinThumbValue();getStyleFromValue
function(value) : String|Object|undefined# Returns the style of a step key or, when the key has no style of its own, the style of the nearest previous key (numeric keys are compared as numbers, text keys by position in steps).
getStyleFromValueReturns the style of a step key or, when the key has no style of its own, the style of the nearest previous key (numeric keys are compared as numbers, text keys by position in steps).
- value String|Number
- A step key.
Returns The style (name or {style, name} object), or undefined when no previous step has one.
var style = Ext.getCmp('years_tl').getTimeline().getStyleFromValue('2014');getTimeline
function() : GeoExt.TimelinePanel# Returns the timeline panel driven by this button.
getTimelineReturns the timeline panel driven by this button. The markup id identifies the button, so this is the way to reach the panel methods (getValue, updateMainThumbValue, startAnimationStep, setSteps...).
Returns The timeline panel (null after the button was destroyed).
var timeline = Ext.getCmp('years_tl').getTimeline();
timeline.updateMainThumbValue(0); // first stepgetValue
function() : String# Returns the key of the step currently selected by the main thumb (the same value the layer receives in inputs.id[ID]).
getValueReturns the key of the step currently selected by the main thumb (the same value the layer receives in inputs.id[ID]).
Returns The current step key (first element of the steps entry).
var year = Ext.getCmp('years_tl').getTimeline().getValue(); // '2010'getValueFromStyle
function(style) : Number# Returns the step key whose style is the given one (the last match when several steps share a style), or the first step key when the style is empty or unknown.
getValueFromStyleReturns the step key whose style is the given one (the last match when several steps share a style), or the first step key when the style is empty or unknown. The key is returned through parseInt, so it is meaningful for numeric keys only (text keys give NaN).
- style String
- A style name as used in
steps.
Returns The numeric step key.
var year = Ext.getCmp('years_tl').getTimeline().getValueFromStyle('style_2010'); // 2010hideLabel
Boolean= false# Defines if the label of the timeline should be displayed.
hideLabelDefines if the label of the timeline should be displayed. Set true to hide the label, false to show it.
|hideLabel=true|id
String# Defines the id to identify the object.
idDefines the id to identify the object. It is the key used in inputs.id[ID] and the id of the show/hide button component: Ext.getCmp(id) returns the button and Ext.getCmp(id).getTimeline() the timeline panel (see the methods listed in this group).
|id=exemple_timeline|nextAnimationStep
function()# Advances the timeline one step (main thumb + 1), applying the style of the new step to the layer and firing change; does nothing when the main thumb is already at the max thumb.
nextAnimationStepAdvances the timeline one step (main thumb + 1), applying the style of the new step to the layer and firing change; does nothing when the main thumb is already at the max thumb. Useful for a custom "next" button.
Ext.getCmp('years_tl').getTimeline().nextAnimationStep();nextStepInterval
Number= 2100# Defines the duration of the interval between steps of the timeline in milliseconds.
nextStepIntervalDefines the duration of the interval between steps of the timeline in milliseconds.
|nextStepInterval=1000|onPlayToggle
function# Defines the callback function called when the play/stop button is toggled, BEFORE the animation starts or stops.
onPlayToggleDefines the callback function called when the play/stop button is toggled, BEFORE the animation starts or stops. It must return a truthy value: returning false/nothing cancels the start/stop (use it as a veto, e.g. while data is loading). pressed is true when the animation is about to start.
The value is resolved as a key of the layer functions object, then as a global function with that name, then as inline function text (function(...){...}; a plain statement body also works and returns true).
- pressed Boolean
- True if the button was pressed (animation about to start), False otherwise.
- layer Object
- The layer associated to this timeline.
- timeline Object
- The timeline panel.
- playBtn Object
- The play/stop button.
|onPlayToggle=onPlayToggle||onPlayToggle = function (pressed, layer, timeline, playBtn) {
console.log("The timeline is about to " + (pressed ? "start" : "stop"));
return true; // required, a falsy return cancels the toggle
}|playing
Boolean= false# true while the animation is running (between play and stop/end).
playingtrue while the animation is running (between play and stop/end). Read it on the panel (Ext.getCmp(id).getTimeline().playing) to know whether to call startAnimationStep() or stopAnimation().
if (!Ext.getCmp('years_tl').getTimeline().playing) Ext.getCmp('years_tl').getTimeline().startAnimationStep();preloadTiles
Boolean= false# Defines if the timeline should preload the tiles of the next steps to get smoother transitions.
preloadTilesDefines if the timeline should preload the tiles of the next steps to get smoother transitions. Set it true to preload, false otherwise.
|preloadTiles = true|renderHidden
Boolean= false# Defines the timeline initial visibility.
renderHiddenDefines the timeline initial visibility. Set it true to start with the timeline hidden, false otherwise.
|renderHidden = true|setCurrentLayerStyle
function(style)# Applies a style to the layer the way a step does: a style name, or a {style, name} object that also switches the WMS layer name (the object form of a steps entry).
setCurrentLayerStyleApplies a style to the layer the way a step does: a style name, or a {style, name} object that also switches the WMS layer name (the object form of a steps entry). For a composed layer the first inner layer is updated and the legend is rebuilt. The slider is not moved (use updateMainThumbValue).
- style String|Object
- Style name (
''for the default) or{style: 'name', name: 'CSR:layer'}.
Ext.getCmp('years_tl').getTimeline().setCurrentLayerStyle({style: 'estados_2', name: 'CSR:estados'});setDesiredVisibility
function(visible) : GeoExt.TimelinePanel# Shows or hides the timeline panel while keeping it consistent with the layer: when the layer is hidden the panel stays hidden and the requested state is remembered, to be applied as soon as the layer becomes visible.
setDesiredVisibilityShows or hides the timeline panel while keeping it consistent with the layer: when the layer is hidden the panel stays hidden and the requested state is remembered, to be applied as soon as the layer becomes visible. Prefer it over show()/hide(); the show/hide button follows the panel automatically.
- visible Boolean
trueto show the timeline (once the layer is visible),falseto hide it.
Returns The panel, for chaining.
Ext.getCmp('years_tl').getTimeline().setDesiredVisibility(true);setMaxThumbValue
function(value)# Moves the right (max) thumb, limiting the animation to the steps up to that index (no animation, no change event).
setMaxThumbValueMoves the right (max) thumb, limiting the animation to the steps up to that index (no animation, no change event).
- value Number
- 0-based step index for the max thumb.
Ext.getCmp('years_tl').getTimeline().setMaxThumbValue(5);setMinThumbValue
function(value)# Moves the left (min) thumb, making the animation start from that step index (no animation, no change event).
setMinThumbValueMoves the left (min) thumb, making the animation start from that step index (no animation, no change event).
- value Number
- 0-based step index for the min thumb.
Ext.getCmp('years_tl').getTimeline().setMinThumbValue(2);setSteps
function(steps)# Replaces the steps of the timeline and redraws it (labels, slider range and current step).
setStepsReplaces the steps of the timeline and redraws it (labels, slider range and current step). Unlike the markup steps parameter this takes the already-built object: keys are the step labels, values the style name or a {style, name} object. Use it to change the available periods at runtime (e.g. after a combobox selection).
- steps Object
- Map of step key to style:
{'1990': 'style_1990', '2000': {style: 's2000', name: 'CSR:layer'}}.
Ext.getCmp('years_tl').getTimeline().setSteps({2000: 'style_2000', 2010: 'style_2010'});startAnimationStep
function()# Starts (or resumes) the animation from the current step: each step is shown for nextStepInterval milliseconds after the layer finished loading it, up to the max thumb, where the animation stops by itself.
startAnimationStepStarts (or resumes) the animation from the current step: each step is shown for nextStepInterval milliseconds after the layer finished loading it, up to the max thumb, where the animation stops by itself. When the main thumb is already at the max thumb it restarts from the min thumb. Same as pressing the play button, except that onPlayToggle is not consulted.
Ext.getCmp('years_tl').getTimeline().startAnimationStep();steps
Array.<Array.<(String|Object)>># Defines the timeline change steps.
stepsDefines the timeline change steps.
|steps=[["step_0"], ["step_1"], ["step_2"]]||steps=[['Nome', {style:"step_0_style",name:"CSR:estados"}], ['Região', {style:"step_1_style",name:"CSR:estados"}], ['Geocódigo', {style:"step_2_style",name:"CSR:estados"}]]||steps=[['Nome', 'step_0'], ['Região', 'step_1'], ['Geocódigo', 'step_2']]||steps=[{1990: "layer_style0", 1991: "layer_style1", 1992: "layer_style2"}, 1993: "layer_style3"}]|stopAnimation
function()# Stops the running animation (cancels the pending step timer, releases the play button and hides the slider tip).
stopAnimationStops the running animation (cancels the pending step timer, releases the play button and hides the slider tip). The current step is kept. Safe to call when nothing is playing.
Ext.getCmp('years_tl').getTimeline().stopAnimation();toggleTimelineVisibility
function(forceState)# Shows or hides the timeline panel from code — what clicking the button does.
toggleTimelineVisibilityShows or hides the timeline panel from code — what clicking the button does. Without an argument the current (desired) visibility is inverted. The panel only appears while the layer is visible; the requested state is remembered otherwise (see setDesiredVisibility).
- forceState Boolean
trueto show the timeline,falseto hide it; omit to invert.
Ext.getCmp('years_tl').toggleTimelineVisibility(true);updateLayer
function(value)# Applies to the layer the style of a step key, without moving the slider.
updateLayerApplies to the layer the style of a step key, without moving the slider. When the key has no step of its own the style of the nearest previous numeric key is used (steps {2010: "s1", 2015: "s2"} and value 2014 keep/apply "s1"); nothing happens when that style is already active. Called by the slider on every change; call it yourself to preview a step, then updateMainThumbValue() to sync the thumb.
- value String|Number
- A step key (first element of a
stepsentry).
Ext.getCmp('years_tl').getTimeline().updateLayer('2010');updateMainThumbValue
function(value)# Moves the main thumb to a step index (0-based position in steps), applying that step's style to the layer and firing change — the programmatic way to select a step.
updateMainThumbValueMoves the main thumb to a step index (0-based position in steps), applying that step's style to the layer and firing change — the programmatic way to select a step. Without an argument it re-syncs the thumb with the layer's current style using getValueFromStyle (used when another tool changes the style). The min/max thumbs are pushed outwards when the index falls outside the current range.
- value Number
- Step index; omit to sync the thumb with the layer's current style.
Ext.getCmp('years_tl').getTimeline().updateMainThumbValue(2); // third stepvalue
String# Value stored in inputs.id[ID] (and inputs[i]): the key of the current step — the first element of the selected steps entry (e.g. "1990" or "January"), as a string.
valueValue stored in inputs.id[ID] (and inputs[i]): the key of the current step — the first element of the selected steps entry (e.g. "1990" or "January"), as a string. It changes whenever the main thumb moves (drag, click or animation) and the layer recalculates on the widget change event, after the layer style of the step was applied. The same change event is fired on the button (Ext.getCmp(id).on('change', function(button, value) {...})).
{{timeline|id=years_tl|nextStepInterval=1500|steps=[['1990', 'style_1990'], ['2000', 'style_2000'], ['2010', 'style_2010']]}}beforeCalc: function(inputs) {
var year = parseInt(inputs.id['years_tl'], 10);
}window · floating window (input)
Window22 entriesWritten in a layer's descriptionHtml as {{window|parameter=value|...}}
It can only be shown when the layer is visible.
btnID
String# Defines the id of the button that controls the window visibility.
btnIDDefines the id of the button that controls the window visibility.
|btnID = window-button-id|getButton
function() : Ext.Button# Returns the show/hide toggle Ext.Button (id btnID), e.g. to toggle(true), setText() or hide() it.
getButtonReturns the show/hide toggle Ext.Button (id btnID), e.g. to toggle(true), setText() or hide() it.
Returns The toggle button component.
this.getInputs().id['report_btn'].getButton().setText('Hide report');getContainer
function() : Ext.Container# Returns the content container (Ext.Container, id id) inside the window.
getContainerReturns the content container (Ext.Container, id id) inside the window. Use update(html) to replace its HTML, or add()/doLayout() to place Ext components in it.
Returns The content container of the window.
this.getInputs().id['report_btn'].getContainer().update('<p>' + text + '</p>');getIds
function() : Array.<String># Returns the ids of the three components created by the tool, in the order [windowID, id (content div), btnID].
getIdsReturns the ids of the three components created by the tool, in the order [windowID, id (content div), btnID].
Returns [windowId, containerId, buttonId].
var ids = this.getInputs().id['report_btn'].getIds(); // ['report_win', 'report_div', 'report_btn']getWindow
function() : Ext.Window# Returns the floating Ext.Window (use it for show(), hide(), setTitle(), setSize(), setPosition()...).
getWindowReturns the floating Ext.Window (use it for show(), hide(), setTitle(), setSize(), setPosition()...). Prefer getButton().toggle() to change visibility so the button stays in sync.
Returns The window component (it is destroyed together with the layer).
this.getInputs().id['report_btn'].getWindow().setTitle('Report - ' + year);height
number# Defines the floating window initial height.
heightDefines the floating window initial height.
|height = 600px|html
String# Defines the initial HTML content of the window's container div.
htmlDefines the initial HTML content of the window's container div. Because the parser treats everything after html= as the value, the content may contain = characters; it cannot contain | or }}. For content built at runtime, write into the container instead (inputs.id[ID].getContainer().update(html) or Ext.getCmp(id).update(html)).
|html=<div class="report">Loading...</div>|id
String# Defines an id for the div contained in the floating window (where the content can be drawn).
idDefines an id for the div contained in the floating window (where the content can be drawn).
|id = window-div-id|ignoreVisibility
Boolean# Defines if the window should ignore the layer visibility state.
ignoreVisibilityDefines if the window should ignore the layer visibility state. By default, the window visibility state is the same as the layer's. Set true to ignore the layer visibility state, false otherwise.
PS: The 'ignoreVisibility' is not compatible with the 'associatedButtonID' property. When both are used together, the ignoreVisibility value is ignored.
|ignoreVisibility = false|items
Array# Not supported: the tool always creates its own single content container (the div identified by id), so any items written in the markup are discarded.
itemsNot supported: the tool always creates its own single content container (the div identified by id), so any items written in the markup are discarded. Put content in with html=, or render into the container from code (Ext.getCmp(id) / inputs.id[ID].getContainer()).
onBeforeHide
function# Defines a callback function to be called before hiding the floating window.
onBeforeHideDefines a callback function to be called before hiding the floating window.
- layer Object
- Scope of the layer
- data Array
- [window, button, windowConfig] window: Window object; button: Button created; windowConfig: Window object configuration
|onBeforeHide = function (layer, [window, button, windowConfig]){
console.log(layer);
console.log([window, button, windowConfig]);
}|resize
function# Defines the callback function to be called when the floating window is resized.
resizeDefines the callback function to be called when the floating window is resized.
|resize = function (){
console.log("I was resized!");
}|startVisible
Boolean# Defines if the window should start visible or not.
startVisibleDefines if the window should start visible or not. Set true if it should, false otherwise.
|startVisible = false|text
string= Show/Hide Window# Defines the window button text.
textDefines the window button text.
|text = I am a button|title
String= Window# Defines the floating window's title.
titleDefines the floating window's title.
|title = Title of the Window|toggle
function(pressed)# Shows or hides the floating window from code by pressing/releasing its toggle button — the same as the user clicking it, so onBeforeHide still runs.
toggleShows or hides the floating window from code by pressing/releasing its toggle button — the same as the user clicking it, so onBeforeHide still runs. Call it on the button: inputs.id[ID].getButton().toggle(state) or Ext.getCmp(btnID).toggle(state). Without an argument the state is inverted.
- pressed Boolean
trueto show the window,falseto hide it; omit to invert.
this.getInputs().id['report_window'].getButton().toggle(true);underButtons
Boolean# Defines where the floating window will be positioned in relation to the buttons panel.
underButtonsDefines where the floating window will be positioned in relation to the buttons panel. Set true to position the window under the right buttons panel, false otherwise.
|underButtons = false|value
Object# Value stored in inputs.id[btnID] - under the show/hide button's id, not the markup id, so set btnID to read it (without one the key is an automatic id): a small handle object with the methods …
valueValue stored in inputs.id[btnID] - under the show/hide button's id, not the markup id, so set btnID to read it (without one the key is an automatic id): a small handle object with the methods getIds(), getWindow(), getButton() and getContainer() to reach the three Ext components of the tool (the floating window, its content div and the show/hide button). The input is registered on the window afterrender event, so it triggers one recalculation when the window is first rendered; it never changes afterwards. The handle contains component references, so do not use it inside expression (WebWorker) — read it in beforeCalc or in button/window callbacks.
{{window|id=report_div|btnID=report_btn|windowID=report_win|title=Report|startVisible=true}}beforeCalc: function(inputs) {
var wnd = inputs.id['report_btn'];
wnd.getContainer().update('<b>Total:</b> ' + total);
wnd.getButton().toggle(true);
}width
number# Defines the floating window initial width.
widthDefines the floating window initial width.
|width = 600px|windowID
String# Defines the window id.
windowIDDefines the window id.
|windowID = window-id|x
Number# Defines the initial absolute X position of the window, in pixels from the left edge of the page.
xDefines the initial absolute X position of the window, in pixels from the left edge of the page. A negative value counts from the right edge instead: the window's right side is placed at viewportWidth + x (e.g. x=-10 leaves a 10px margin on the right).
PS: Overwritten when 'underButtons' is used (or when neither x nor y is given).
|x=-115|y=103|y
Number# Defines the initial absolute Y position of the window, in pixels from the top of the page.
yDefines the initial absolute Y position of the window, in pixels from the top of the page. A negative value counts from the bottom edge instead: the window's bottom side is placed at viewportHeight + y (e.g. y=-20 leaves a 20px margin at the bottom).
PS: Overwritten when 'underButtons' is used (or when neither x nor y is given).
|x=20|y=-20|zoomlevel · current zoom (input)
ZoomLevel2 entriesWritten in a layer's descriptionHtml as {{zoomlevel|parameter=value|...}}
Usage: {{zoomlevel|id=zoom}} then inputs.id['zoom'] in beforeCalc/expression
id
String# Defines the id of the input; it is the key used to read the zoom level in inputs.id[ID] (required, the tool renders nothing visible).
idDefines the id of the input; it is the key used to read the zoom level in inputs.id[ID] (required, the tool renders nothing visible).
|id=zoom|value
Number# Value stored in inputs.id[ID] (and inputs[i]) for beforeCalc/expression: the current map zoom level as a number.
valueValue stored in inputs.id[ID] (and inputs[i]) for beforeCalc/expression: the current map zoom level as a number. It is refreshed on the map moveend event and only triggers a recalculation when the zoom actually changed (panning is ignored).
{{zoomlevel|id=zoom}}beforeCalc: function(inputs) {
var zoom = inputs.id['zoom'];
this.changeLayers({name: zoom > 10 ? 'CSR:municipalities' : 'CSR:estados', index: 0});
}Query setup: calls before the layer list
A query-wide setting and a registered server before the list:
Example
ExtjsUtils.CONFIGURATION.setOptions({ keepOnLeave: false }) &&
ExtjsUtils.QUERY.addRemoteWMSServer({
prodes: { url: "https://terrabrasilis.dpi.inpe.br/geoserver/prodes-legal-amz/ows?" },
}) && [
{ name: "yearly_deforestation", source: "prodes", title: "Deforestation (INPE)", visibility: true },
];QUERY · setup calls and the running query
QUERY40 entriesPathDescription
functionhelper# Internal — constructor of the objects the interpreter stores in each layer's path and viewPath arrays to describe the group (or view) the layer belongs to, one entry per nesting level.
PathDescriptionWritten as ExtjsUtils.QUERY.PathDescription
Internal — constructor of the objects the interpreter stores in each layer's path and viewPath arrays to describe the group (or view) the layer belongs to, one entry per nesting level. new PathDescription(groupNode, layerIndex, cfg): groupNode is the group definition object (its title is used) or a bare title string; layerIndex is the position of the layer in the flattened definition; cfg is copied as the group's configuration. Instances expose getTitle() (group/view title), getCfg() (copy of the group definition) and getDefinitionIndex() (the layer index). Tenant code normally does not build these — QUERY.addLayer with a group object does it — but a hand-built layer record can set path: [new ExtjsUtils.QUERY.PathDescription("My group", 0, null)] to appear under a group in the layer tree.
- groupNode Object|String
- Group definition object (its
titleis used) or the title itself. - layerIndex Number
- Index of the layer in the flattened query definition.
- cfg Object
- Group configuration to copy into the descriptor (may be null).
var pathEntry = new ExtjsUtils.QUERY.PathDescription("Remote layers", 0, null);
pathEntry.getTitle(); // "Remote layers"addLayer
function(cfg) : Array.<GeoExt.data.LayerRecord>helper# Adds layers to the map at runtime from the same definitions used in the query array.
addLayerWritten as ExtjsUtils.QUERY.addLayer
Adds layers to the map at runtime from the same definitions used in the query array. cfg may be a single layer definition, an array of definitions, or a full group object ({viewTitle, title, color, elements: [...]}) whose elements are then shown grouped in the layer tree. The definition goes through the regular query parse pipeline (group defaults, path/viewPath, priority order) with the current query's globals kept, so functions inside it (handlers, styleMap callbacks) still work. Side-effect APIs such as addRemoteWMSServer or decorate cannot be embedded in a definition object: register remote sources before calling addLayer, otherwise a layer whose source is unknown is skipped with "Source not found by name" in the console. Typically called from a setMappiaIoCallback handler or a button handler to inject layers on demand.
- cfg Object|Array.<Object>
- One layer definition, an array of definitions, or a group object with
elements.
Returns The layer records added to the map (skipped definitions are omitted).
// Single layer
ExtjsUtils.QUERY.addLayer({ name: "CSR:estados", title: "States", visibility: true });// A whole group, shown under its own view/title in the layer tree
ExtjsUtils.QUERY.addLayer({
viewTitle: "Data sources",
title: "Boundaries",
color: "#0073E6",
elements: [
{ name: "CSR:estados", title: "States", visibility: true },
{ name: "CSR:municipios", title: "Municipalities", visibility: false }
]
});addNewLayerAsBackground
function(layerDefinition, hideBackgroundLayers)helper# Adds a layer and uses it as the background map: the definition gets group: "background", visibility: true and a very low priority (so it stays under every other layer) and is added with QUERY.addLayer.
addNewLayerAsBackgroundWritten as ExtjsUtils.QUERY.addNewLayerAsBackground
Adds a layer and uses it as the background map: the definition gets group: "background", visibility: true and a very low priority (so it stays under every other layer) and is added with QUERY.addLayer. By default the current background layers are hidden first. A bare layer name string is accepted as the definition.
- layerDefinition Object|String
- Layer definition properties, or just the layer name.
- hideBackgroundLayers Boolean
- Hide the existing background layers before adding the new one.
ExtjsUtils.QUERY.addNewLayerAsBackground({"name": "CSR:paises"})ExtjsUtils.QUERY.addNewLayerAsBackground("CSR:paises", false)addRemoteWMSServer
function(wmsDefinitions) : Booleanhelper# Registers extra WMS servers as layer sources for the current query.
addRemoteWMSServerWritten as ExtjsUtils.QUERY.addRemoteWMSServer
Registers extra WMS servers as layer sources for the current query. Each key of wmsDefinitions becomes a source id: a layer selects it with source: "<id>" and uses the layer name published by that server's capabilities as name. Chain it with && before the layer array so the sources exist when the layers are created. Skipped in "just eval" mode.
Source definition properties:
url{String} URL of the WMS (mandatory unlessptypeis given).cors{Boolean} Route the requests through the Mappia CORS proxy (/cors/)
for servers without CORS headers.updateWMS{Boolean} Bypass the proxy cache (/cors/direct/) to get fresh content.storage{String} Rewritesurlfor hosted layer stores:"github"(raw
GitHub content, cache-busted),"jsdelivr"(jsDelivr CDN, append@VERSION
to the URL to force an update; releases: https://help.github.com/en/articles/creating-releases),
"remote"(no rewrite). All storage values append/getCapabilities.xml?.ptype{String} Source plugin type, default"gxp_customwmscsource".onLoad{Function} Called when the source capabilities are loaded.onError{Function} Called when the source fails to load.
With ?options=capabilities (calculator only) every URL is replaced by the per-query filtered capabilities endpoint.
- wmsDefinitions Object
- Map of source id to source definition.
Returns Always true, so the call can be chained with && QUERY_DESCRIPTION.
ExtjsUtils.QUERY.addRemoteWMSServer({
geoinfo: {
url: "http://geoinfo.cnps.embrapa.br/geoserver/wms?SERVICE=WMS&",
cors: true
},
ibge: {
url: "https://geoservicos.ibge.gov.br/geoserver/CCAR/wms?",
cors: true
},
gitHub: {
url: "https://github.com/asfixia/CustomWMS@0.1",
storage: "github",
updateWMS: true,
cors: true
}
})
&&
[
{ name: "CCAR:BC250_Trecho_Rodoviario_L", source: "ibge", visibility: true },
{ name: "my_layer", source: "gitHub" }
]clearQueryGlobalProperties
function()helper# Internal — undoes every side effect of the current query: deletes the globals it created, destroys its remote WMS sources, resets the stored settings, the query configuration (CONFIGURATION), the …
clearQueryGlobalPropertiesWritten as ExtjsUtils.QUERY.clearQueryGlobalProperties
Internal — undoes every side effect of the current query: deletes the globals it created, destroys its remote WMS sources, resets the stored settings, the query configuration (CONFIGURATION), the dynamic CSS rules, the header/footer decoration and the projection options. Called by the platform before a new query is loaded; tenant code normally does not call it.
ExtjsUtils.QUERY.clearQueryGlobalProperties();decorate
function(pageProperties) : Booleanhelper# Decorates the page for the current query: header logo and top-bar style, a footer, and arbitrary CSS rules.
decorateWritten as ExtjsUtils.QUERY.decorate
Decorates the page for the current query: header logo and top-bar style, a footer, and arbitrary CSS rules. Exactly three keys are reserved:
header{Object}:logo: {src, style}puts an image in the top bar's logo container
(styleis an object of CSS properties applied to the container);topbar: {style}styles
the top bar itself.footer{Object}:htmlis the footer content,stylean object of CSS properties for it;
the footer container is shown and pinned to the bottom of the page.run{Function}: called once, after the header/footer are applied — the place for
arbitrary code that must run when the query is decorated. Every other key is passed toCSS.defineClass(key, value)as a CSS rule: the key is the selector and the value the rule body (a string such as"display: none;"or an object of CSS properties). So an accidental extra key becomes a CSS rule — do not put code under a made-up key, userun. Everything is removed when another query loads, and the whole call is a no-op while the query is only being parsed. Chain it with&&before the layer array.
- pageProperties Object
header,footer,run, plusselector: "css rules"pairs.
Returns Always true, so the call can be chained with && QUERY_DESCRIPTION.
ExtjsUtils.QUERY.decorate({
header: {
logo: { src: "https://example.org/logo.png", style: { "padding-left": "10px" } },
topbar: { style: { "background-color": "#1b5e20" } }
},
footer: { html: "<b>Source:</b> my institution", style: { "text-align": "center" } },
run: function() { console.log("decorated"); },
".x-tree-node-anchor": "font-size: 14px;"
}) && QUERY_DESCRIPTIONdescribeQueryError
function(exception) : Objecthelper# Internal — turns an exception thrown while evaluating a query into {name, message, line?, column?}, the position read from the stack of the evaluated code (Chrome <anonymous>:L:C, Firefox …
describeQueryErrorWritten as ExtjsUtils.QUERY.describeQueryError
Internal — turns an exception thrown while evaluating a query into {name, message, line?, column?}, the position read from the stack of the evaluated code (Chrome <anonymous>:L:C, Firefox eval:L:C) and given in the query text - on its first line the evaluation wrapper's prefix is taken off the column. A SyntaxError usually has no position (the browser does not give one for evaluated code). Tenant code normally does not call it.
- exception Error
- The exception thrown by
evaluateQueryDescription.
Returns The description.
var described = ExtjsUtils.QUERY.describeQueryError(new ReferenceError("x is not defined"));evaluateQueryDescription
function(queryDescription) : Array|*helper# Internal — evaluates the query source text as a JavaScript expression (eval) and returns its value.
evaluateQueryDescriptionWritten as ExtjsUtils.QUERY.evaluateQueryDescription
Internal — evaluates the query source text as a JavaScript expression (eval) and returns its value. This is the step where ExtjsUtils.QUERY.setQueryGlobalProperties(...) && [...] chains actually run. An empty description evaluates to [{'name':'CSR:empty'}]. Tenant code normally does not call it.
- queryDescription String
- Query source text.
Returns The evaluated value; a valid query yields an array.
var parsed = ExtjsUtils.QUERY.evaluateQueryDescription("[{ name: 'CSR:estados' }]");failedSources
Array.<String># Reserved list for the remote WMS sources that failed to load.
failedSourcesWritten as ExtjsUtils.QUERY.failedSources
Reserved list for the remote WMS sources that failed to load. The platform currently does not populate it (a failed source is simply removed from remoteSources and logged).
getJustEvalFlag
function() : Booleanhelper# Internal — returns the justEval flag; a side-effect API checks it to skip its work while a query is only being parsed.
getJustEvalFlagWritten as ExtjsUtils.QUERY.getJustEvalFlag
Internal — returns the justEval flag; a side-effect API checks it to skip its work while a query is only being parsed. Tenant code normally does not call it, although a custom global function with side effects may use it the same way.
Returns True while the query is being evaluated only for parsing.
if (!ExtjsUtils.QUERY.getJustEvalFlag()) applyMySideEffect();getMappiaMessage
function(wrappedJsMsg) : Object|String|nullhelper# Internal — extracts the Mappia payload from a raw window "message" event: returns event.data.mappia_iframe, JSON-parsed when possible (a plain string is returned as is), or null when the event …
getMappiaMessageWritten as ExtjsUtils.QUERY.getMappiaMessage
Internal — extracts the Mappia payload from a raw window "message" event: returns event.data.mappia_iframe, JSON-parsed when possible (a plain string is returned as is), or null when the event does not carry a mappia_iframe field (i.e. it was not sent through MappiaIO / QUERY.postMessage). Used by queryState.initMessageHandler; tenant code normally does not call it.
- wrappedJsMsg MessageEvent
- The DOM message event received on
window.
Returns The parsed payload, or null when the event is not a Mappia message.
window.addEventListener("message", function(evt) {
var msg = ExtjsUtils.QUERY.getMappiaMessage(evt);
if (msg) console.log("Mappia message", msg);
});getStoredQuerySettings
function() : Objecthelper# Internal — returns the arguments the current query passed to the side-effect APIs, keyed by function name (see globalQueryStoredSettings).
getStoredQuerySettingsWritten as ExtjsUtils.QUERY.getStoredQuerySettings
Internal — returns the arguments the current query passed to the side-effect APIs, keyed by function name (see globalQueryStoredSettings). The editor and the offline-maps tool use it to re-read the query's remote sources; tenant code normally does not call it.
Returns Stored settings, e.g. { addRemoteWMSServer: {...}, decorate: {...} }.
var remoteStores = ExtjsUtils.QUERY.getStoredQuerySettings().addRemoteWMSServer || {};globalQueryStoredSettings
Object# Arguments the current query passed to the side-effect APIs, keyed by function name ("setQueryGlobalProperties", "addRemoteWMSServer", "decorate"), merged per key.
globalQueryStoredSettingsWritten as ExtjsUtils.QUERY.globalQueryStoredSettings
Arguments the current query passed to the side-effect APIs, keyed by function name ("setQueryGlobalProperties", "addRemoteWMSServer", "decorate"), merged per key. The editor and the offline-maps tool read it back through getStoredQuerySettings; it is reset when another query loads.
ExtjsUtils.QUERY.globalQueryStoredSettings.decorate // the object passed to QUERY.decorateinterpretDescription
function(queryDescriptionObj) : Array.<Object>helper# Internal — flattens the normalized query tree (old group syntax) into the ordered array of layer definitions the map is built from.
interpretDescriptionWritten as ExtjsUtils.QUERY.interpretDescription
Internal — flattens the normalized query tree (old group syntax) into the ordered array of layer definitions the map is built from. Each layer receives the properties represented by the tree: path/viewPath (arrays of PathDescription, one per nesting level), color and viewColor (arrays of group colours, default #000000), visibility (default false), source (default "local") and definitionOrder; the global key of every group and layer is applied through setQueryGlobalProperties. The result is sorted by priority (descending) and reversed so that the first definition ends up on top of the map. Tenant code normally does not call it.
- queryDescriptionObj Array
- Normalized query array, as returned by
parseQueryDefinition.
Returns Flat, ordered array of layer definitions (empty when the input is falsy).
var layers = ExtjsUtils.QUERY.interpretDescription(ExtjsUtils.QUERY.parseQueryDefinition(queryText, true));justEval
Boolean# When true the query is being evaluated only to be parsed/validated: addRemoteWMSServer, decorate, CONFIGURATION.setOptions and the runNow hook become no-ops.
justEvalWritten as ExtjsUtils.QUERY.justEval
When true the query is being evaluated only to be parsed/validated: addRemoteWMSServer, decorate, CONFIGURATION.setOptions and the runNow hook become no-ops. Set by parseQueryObject and read through getJustEvalFlag.
lastQueryError
Object|null= null# The error of the last query applied through MappiaIO (RUN_QUERY_APPLY), or null when it evaluated to a list of layers: {name, message, line?, column?} - line and column in the query text as the page sent it.
lastQueryErrorWritten as ExtjsUtils.QUERY.lastQueryError
The error of the last query applied through MappiaIO (RUN_QUERY_APPLY), or null when it evaluated to a list of layers: {name, message, line?, column?} - line and column in the query text as the page sent it. Reset at the start of every apply; it is what the page receives as mappia__queryError just before mappia__queryApplied.
// inside the map page: why did the last query apply nothing?
console.log(ExtjsUtils.QUERY.lastQueryError); // {name: "ReferenceError", message: "TITLE is not defined", line: 3, column: 12}layerLoading
SharedCounter# Counter of layer resources (files, GeoJSON, CSV, composed children) still loading for the current query.
layerLoadingWritten as ExtjsUtils.QUERY.layerLoading
Counter of layer resources (files, GeoJSON, CSV, composed children) still loading for the current query. It is recreated at the start of every query load. layerLoading.addZeroCallback(fn) fires fn when all layer loads finish — this is the standard "wait until the layers are loaded" hook for tenant code (the platform uses the same hook to zoom to the layers' extent and fire QUERY_LOADED). The callback stays registered unless it returns false, and only fires on a transition to zero, so check getCount() first when nothing may be loading.
ExtjsUtils.QUERY.setQueryGlobalProperties({
runNow: function() {
ExtjsUtils.QUERY.layerLoading.addZeroCallback(function() {
console.log("All layers of the query are loaded");
});
}
}) && QUERY_DESCRIPTIONloadCurrentQuery
function(map, queryDescription, afterLoadCallback) : Array.<Object>|nullhelper# Internal — loads a whole query into the application, replacing the current one: clears the previous query's globals, remote sources, CSS and decoration, removes every non-default layer, parses …
loadCurrentQueryWritten as ExtjsUtils.QUERY.loadCurrentQuery
Internal — loads a whole query into the application, replacing the current one: clears the previous query's globals, remote sources, CSS and decoration, removes every non-default layer, parses queryDescription (when it is a string), waits for the remote sources (sourceLoading) and then creates the layers; once layerLoading reaches zero it zooms to the layers' extent (unless the URL has extent), calls afterLoadCallback and fires QUERY_LOADED. Wrapped in queryState.startWaiting("loadCurrentQuery"). This is what the viewer, the editor and a RUN_QUERY_APPLY message use; tenant code normally does not call it.
- map GeoExplorer
- The application instance (
ExtjsUtils.JS.getApp()), despite the parameter name. - queryDescription String|Array.<Object>
- Query source text, or an already parsed query array.
- afterLoadCallback function
- Called after the layers were sent to load (also on failure).
Returns The parsed query definition on success, null when it failed to parse.
ExtjsUtils.QUERY.loadCurrentQuery(ExtjsUtils.JS.getApp(), "[{ name: 'CSR:estados' }]", function() { console.log("loaded"); });normalizeLayersWithNoGroup
function(queryDescription) : Arrayhelper# Internal — moves every top-level layer that is not inside a group into a default group (title Lang.maps, i.e. "Maps", color #000000) appended at the end, so that the interpreter only ever sees …
normalizeLayersWithNoGroupWritten as ExtjsUtils.QUERY.normalizeLayersWithNoGroup
Internal — moves every top-level layer that is not inside a group into a default group (title Lang.maps, i.e. "Maps", color #000000) appended at the end, so that the interpreter only ever sees groups at the top level. Works on the old (array-per-group) syntax and mutates the array in place. Tenant code normally does not call it.
- queryDescription Array
- Parsed query in the old group syntax.
Returns The same array, now containing only groups.
ExtjsUtils.QUERY.normalizeLayersWithNoGroup([{ name: "CSR:estados" }]);
// => [[{ title: "Maps", color: "#000000" }, { name: "CSR:estados" }]]parseQueryDefinition
function(queryDescription, keepGlobalProperties) : Array.<Object>|nullhelper# Internal — parses and validates query source text: returns the normalized query array (parseQueryObject) or null when the text does not evaluate to a non-empty array or throws (the error is logged to the console).
parseQueryDefinitionWritten as ExtjsUtils.QUERY.parseQueryDefinition
Internal — parses and validates query source text: returns the normalized query array (parseQueryObject) or null when the text does not evaluate to a non-empty array or throws (the error is logged to the console). Unless keepGlobalProperties is true the previous query's globals, remote sources, CSS and decoration are cleared before parsing; they are always cleared when the query turns out to be invalid. Used by the viewer/editor to load a query and by QUERY.addLayer (with keepGlobalProperties); tenant code normally does not call it.
- queryDescription String
- Query source text.
- keepGlobalProperties Boolean
- True to keep the current query's globals and side effects instead of clearing them first.
Returns The normalized query array, or null when the query is invalid.
var parsed = ExtjsUtils.QUERY.parseQueryDefinition("[{ name: 'CSR:estados' }]", true);parseQueryObject
function(queryDescription, justEval) : Arrayhelper# Internal — turns the query source text into the normalized array the interpreter expects: evaluateQueryDescription → parseToOldGroupSyntax → normalizeLayersWithNoGroup → setGroupDefaults.
parseQueryObjectWritten as ExtjsUtils.QUERY.parseQueryObject
Internal — turns the query source text into the normalized array the interpreter expects: evaluateQueryDescription → parseToOldGroupSyntax → normalizeLayersWithNoGroup → setGroupDefaults. With justEval true the justEval flag is raised during the evaluation, which makes side-effect APIs (addRemoteWMSServer, decorate, CONFIGURATION.setOptions, runNow) no-ops so the query can be validated without touching the page; the previous flag value is restored afterwards. Tenant code normally does not call it.
- queryDescription String
- Query source text.
- justEval Boolean
- True to only parse the query, suppressing its side-effect calls.
Returns Normalized query array in the old group syntax.
var parsed = ExtjsUtils.QUERY.parseQueryObject("[{ name: 'CSR:estados' }]", true);parseToNewGroupSyntax
function(queryDescription) : Arrayhelper# Internal — converts a parsed query from the old group syntax (a group is an array whose first element holds the group properties and the remaining elements are its layers) to the new syntax (a group …
parseToNewGroupSyntaxWritten as ExtjsUtils.QUERY.parseToNewGroupSyntax
Internal — converts a parsed query from the old group syntax (a group is an array whose first element holds the group properties and the remaining elements are its layers) to the new syntax (a group is an object with an elements array). Only the first level is converted. Tenant code normally does not call it.
- queryDescription Array
- Parsed query in the old (array-per-group) format.
Returns Query with each group as {title, color, ..., elements: [...]}.
ExtjsUtils.QUERY.parseToNewGroupSyntax([[{ title: "Group" }, { name: "CSR:estados" }]]);
// => [{ title: "Group", elements: [{ name: "CSR:estados" }] }]parseToOldGroupSyntax
function(queryDescription) : Arrayhelper# Internal — converts a parsed query from the new group syntax (a group is an object with an elements array) to the old syntax the interpreter works with (a group is an array whose first element …
parseToOldGroupSyntaxWritten as ExtjsUtils.QUERY.parseToOldGroupSyntax
Internal — converts a parsed query from the new group syntax (a group is an object with an elements array) to the old syntax the interpreter works with (a group is an array whose first element holds the group properties and the remaining elements are its layers). Nested groups are converted recursively; elements without elements are left untouched. Tenant code normally does not call it.
- queryDescription Array
- Parsed query, possibly mixing both group syntaxes.
Returns Query with every group as [groupProps, layer, layer, ...].
ExtjsUtils.QUERY.parseToOldGroupSyntax([{
title: "Group 1", color: "#FF0000",
elements: [{ name: "CSR:layer_name_1" }, { name: "CSR:layer_name_2" }]
}]);
// => [[{ title: "Group 1", color: "#FF0000", elements: null }, { name: "CSR:layer_name_1" }, { name: "CSR:layer_name_2" }]]queryState
Object# Internal — coordinates the "apply a query" cycle with the postMessage protocol used by the editor/calculator pages and by embedding sites (MappiaIO).
queryStateWritten as ExtjsUtils.QUERY.queryState
Internal — coordinates the "apply a query" cycle with the postMessage protocol used by the editor/calculator pages and by embedding sites (MappiaIO). It counts the operations still in progress (startWaiting/endWaiting) and queues incoming messages while any is active, so an applyQuery message or a MappiaIO message is never handled in the middle of a query load. Its members are documented under QueryState. Tenant code normally does not use it.
remoteSources
Array.<String># Ids of the remote WMS sources registered by the current query with addRemoteWMSServer (loaded or still loading).
remoteSourcesWritten as ExtjsUtils.QUERY.remoteSources
Ids of the remote WMS sources registered by the current query with addRemoteWMSServer (loaded or still loading). A source that fails to load is removed from it. Cleared when another query loads.
ExtjsUtils.QUERY.remoteSources.indexOf("ibge") >= 0removeLayer
function(layerName) : Booleanhelper# Removes from the map the layer with the given name (matched against the OpenLayers layer name or its WMS LAYERS param).
removeLayerWritten as ExtjsUtils.QUERY.removeLayer
Removes from the map the layer with the given name (matched against the OpenLayers layer name or its WMS LAYERS param). Use it together with QUERY.addLayer to swap layers at runtime.
- layerName String
- Full layer name, e.g.
"CSR:estados".
Returns True when the layer was removed, false otherwise.
ExtjsUtils.QUERY.removeLayer("CSR:estados");removeLayerByReference
function(curLayer) : Booleanhelper# Removes a layer from the map given its layer record (as returned by QUERY.addLayer) or its OpenLayers layer object.
removeLayerByReferenceWritten as ExtjsUtils.QUERY.removeLayerByReference
Removes a layer from the map given its layer record (as returned by QUERY.addLayer) or its OpenLayers layer object. Failures (e.g. a Google layer whose API did not initialise) are caught and logged, returning false.
- curLayer GeoExt.data.LayerRecord|OpenLayers.Layer
- Layer record or OpenLayers layer to remove.
Returns True if the layer was removed, false otherwise.
var records = ExtjsUtils.QUERY.addLayer({ name: "CSR:estados" });
// later
ExtjsUtils.QUERY.removeLayerByReference(records[0]);removeRemoteWMSServers
function(serverId)helper# Internal — destroys one remote WMS source registered by the query (by id) or, without an argument, all of them, removing them from remoteSources, app.layerSources and app.sources.
removeRemoteWMSServersWritten as ExtjsUtils.QUERY.removeRemoteWMSServers
Internal — destroys one remote WMS source registered by the query (by id) or, without an argument, all of them, removing them from remoteSources, app.layerSources and app.sources. Called when a source fails to load and when another query loads; tenant code normally does not call it.
- serverId String
- Id of the source to remove (the key used in
addRemoteWMSServer); omit to remove all.
ExtjsUtils.QUERY.removeRemoteWMSServers("ibge");resetQueryDecoration
function()helper# Internal — removes the page decoration applied by QUERY.decorate: clears the logo container of the top bar and empties and hides the footer container.
resetQueryDecorationWritten as ExtjsUtils.QUERY.resetQueryDecoration
Internal — removes the page decoration applied by QUERY.decorate: clears the logo container of the top bar and empties and hides the footer container. Part of clearQueryGlobalProperties; tenant code normally does not call it.
ExtjsUtils.QUERY.resetQueryDecoration();resetStoredGlobalQuerySettings
function()helper# Internal — empties globalQueryStoredSettings.
resetStoredGlobalQuerySettingsWritten as ExtjsUtils.QUERY.resetStoredGlobalQuerySettings
Internal — empties globalQueryStoredSettings. Part of clearQueryGlobalProperties; tenant code normally does not call it.
ExtjsUtils.QUERY.resetStoredGlobalQuerySettings();runNow
function()# The query's startup hook.
runNowThe query's startup hook. The query does not call this: it defines a global named runNow through setQueryGlobalProperties({ runNow: function() {...} }) and the platform calls it once, right after the globals of that call are registered (i.e. before the layer array is evaluated) and never again for the same query (runNow.already guards it). It is skipped while the query is only being parsed (justEval). Use it for one-time setup such as ZOOM.limitZoomLevel, registering layerLoading.addZeroCallback, custom controls or redirects. Because it runs before the layers exist, use layerLoading/QUERY_LOADED for work that needs them.
ExtjsUtils.QUERY.setQueryGlobalProperties({
runNow: function() {
ExtjsUtils.ZOOM.limitZoomLevel(17);
ExtjsUtils.QUERY.layerLoading.addZeroCallback(function() { console.log("layers loaded"); });
}
}) && QUERY_DESCRIPTIONrunOnceLayerVisible
function(layer, callback)helper# Runs callback once the given layer becomes visible.
runOnceLayerVisibleWritten as ExtjsUtils.QUERY.runOnceLayerVisible
Runs callback once the given layer becomes visible. If the layer is already visible the callback runs immediately; otherwise it waits for the layer's first visibilitychanged event and then unregisters itself. The callback is invoked with the layer as this. Typically used inside a layer's onLoad/runNow code to defer work (charts, legends) until the user actually turns the layer on.
- layer OpenLayers.Layer
- Layer whose visibility is awaited.
- callback function
- Function called once with the layer as
this.
ExtjsUtils.QUERY.runOnceLayerVisible(ExtjsUtils.LAYER.getLayerByName("CSR:estados"), function() {
console.log("Layer is now visible:", this.name);
});setBaseLayerVisibility
function(visibility)helper# Set baselayer visibility.
setBaseLayerVisibilityWritten as ExtjsUtils.QUERY.setBaseLayerVisibility
Set baselayer visibility.
Legacy helper: hides all backgrounds then sets the last one's visibility. Prefer per-layer visibility when loading a query (OpenLayers.BackgroundSelector applies each background's own visibility flag via applyVisibilitiesFromQuery).
- visibility Boolean
- The visibility applied to the last background layer.
ExtjsUtils.QUERY.setBaseLayerVisibility(false);setGroupDefaults
function(queryDescriptionObj) : Arrayhelper# Internal — applies each group's defaultProperties to every layer and subgroup inside it (recursively, with Ext.applyIf, so a value set on the layer itself or on a nearer group wins).
setGroupDefaultsWritten as ExtjsUtils.QUERY.setGroupDefaults
Internal — applies each group's defaultProperties to every layer and subgroup inside it (recursively, with Ext.applyIf, so a value set on the layer itself or on a nearer group wins). See GroupProperties.defaultProperties for the tenant-facing behaviour. Works on the old (array-per-group) syntax and mutates it in place. Tenant code normally does not call it.
- queryDescriptionObj Array
- Parsed query in the old group syntax.
Returns The same array with the defaults applied.
ExtjsUtils.QUERY.setGroupDefaults([[{ title: "G", defaultProperties: { opacity: 0.5 } }, { name: "CSR:estados" }]]);
// the layer now has opacity: 0.5setJustEvalFlag
function(status)helper# Internal — sets the justEval flag, which makes the query's side-effect APIs (addRemoteWMSServer, decorate, CONFIGURATION.setOptions, runNow) no-ops while a query is only being parsed.
setJustEvalFlagWritten as ExtjsUtils.QUERY.setJustEvalFlag
Internal — sets the justEval flag, which makes the query's side-effect APIs (addRemoteWMSServer, decorate, CONFIGURATION.setOptions, runNow) no-ops while a query is only being parsed. Tenant code normally does not call it.
- status Boolean
- New value of the flag.
ExtjsUtils.QUERY.setJustEvalFlag(true);setMappiaIoCallback
function(onMsgCallback) : Booleanhelper# Registers the function that receives the messages the parent window (embedding site or the MappiaIO library) sends to this Mappia page/iframe with postMessage({mappia_iframe: ...}).
setMappiaIoCallbackWritten as ExtjsUtils.QUERY.setMappiaIoCallback
Registers the function that receives the messages the parent window (embedding site or the MappiaIO library) sends to this Mappia page/iframe with postMessage({mappia_iframe: ...}). The callback gets the payload already unwrapped and JSON-parsed (an object or a string); protocol messages are filtered out, and messages received while a query is loading are queued and delivered afterwards. Registering posts CONFIRM_QUERY_LISTENING back to the parent, so the host knows it can start sending. A string with a function body is accepted as the callback. Use MappiaIO.postMessage to answer the parent.
- onMsgCallback function
- Callback
function(jsStr)receiving the payload (Object|String) sent by the parent window.
Returns Always true, so the call can be chained with && QUERY_DESCRIPTION.
ExtjsUtils.QUERY.setMappiaIoCallback(function(msg) {
if (msg && msg.type === "geojson") {
ExtjsUtils.QUERY.addLayer({ name: "Received", source: "file", type: "json", json: msg.geojson, visibility: true });
ExtjsUtils.QUERY.postMessage({ type: "loaded" });
}
}) && QUERY_DESCRIPTIONsetMessageCallback
function(callbackFunction) : Booleanhelper# Internal — alias of QUERY.setMappiaIoCallback: registers the function that receives the messages posted by the parent window (MappiaIO).
setMessageCallbackWritten as ExtjsUtils.QUERY.setMessageCallback
Internal — alias of QUERY.setMappiaIoCallback: registers the function that receives the messages posted by the parent window (MappiaIO). Kept for older queries; new code should call setMappiaIoCallback directly.
- callbackFunction function
- Callback that receives the message sent by the parent window.
Returns Always true (same as setMappiaIoCallback).
ExtjsUtils.QUERY.setMessageCallback(function(msg) { console.log(msg); }) && QUERY_DESCRIPTIONsetQueryGlobalProperties
function(globalProperties) : Booleanhelper# Defines globals for the query: every key of globalProperties becomes a window property (a value, an object or a function) that layer definitions, markup widgets (handler=, onMark=...) and …
setQueryGlobalPropertiesWritten as ExtjsUtils.QUERY.setQueryGlobalProperties
Defines globals for the query: every key of globalProperties becomes a window property (a value, an object or a function) that layer definitions, markup widgets (handler=, onMark=...) and other query code can reference by name. The names are recorded and the globals are deleted when another query loads. A key that already exists on window and was not created by the query is refused with "Global variable can't be redefined" in the console (the platform's own globals are protected; redefining one of the query's own keys is fine). runNow is the only key the platform itself invokes: right after the globals are registered QUERY.runNow is called once (see that entry). Chain it with && before the layer array so the globals exist when the layers are evaluated; QUERY_DESCRIPTION in the examples stands for that array.
- globalProperties Object
- Object whose keys become globals; each value may be a value, an object or a function.
Returns Always true, so the call can be chained with && QUERY_DESCRIPTION.
ExtjsUtils.QUERY.setQueryGlobalProperties({
globalCount: 0,
onLayerButton: function(btn) { console.log("clicked", btn); },
runNow: function() { ExtjsUtils.ZOOM.limitZoomLevel(17); }
}) && [
{ name: "CSR:estados", visibility: true, descriptionHtml: "{{button|id=b1|text=Go|handler=onLayerButton}}" }
]sourceLoading
SharedCounter# Counter of remote WMS sources (registered with addRemoteWMSServer) still loading their capabilities.
sourceLoadingWritten as ExtjsUtils.QUERY.sourceLoading
Counter of remote WMS sources (registered with addRemoteWMSServer) still loading their capabilities. It is recreated at the start of every query load, and the query's layers are only created once it drops to zero. sourceLoading.addZeroCallback(fn) fires fn when the last source finishes; the callback stays registered unless it returns false. The callback only fires on a transition to zero, so check getCount() first when nothing may be loading.
if (ExtjsUtils.QUERY.sourceLoading.getCount() === 0) onSourcesReady();
else ExtjsUtils.QUERY.sourceLoading.addZeroCallback(onSourcesReady);storeGlobalQuerySettings
function(propertyName, value)helper# Internal — records the arguments a query passed to a side-effect API (setQueryGlobalProperties, addRemoteWMSServer, decorate) in globalQueryStoredSettings[propertyName], merging the keys of …
storeGlobalQuerySettingsWritten as ExtjsUtils.QUERY.storeGlobalQuerySettings
Internal — records the arguments a query passed to a side-effect API (setQueryGlobalProperties, addRemoteWMSServer, decorate) in globalQueryStoredSettings[propertyName], merging the keys of value into what was already stored under that name. Tenant code normally does not call it.
- propertyName String
- Name of the API whose arguments are stored.
- value Object
- Object whose keys are merged into the stored settings.
ExtjsUtils.QUERY.storeGlobalQuerySettings("decorate", { footer: { html: "..." } });CONFIGURATION · query-wide settings (setOptions)
CONFIGURATION2 entriesDEFAULT_FROM_PROJ
String# Projection assumed for vector data (GeoJSON, CSV, JSON, shapefile) that carries no crs and whose layer sets no fromProj, when neither the query (CONFIGURATION.setOptions({ defaultFromProj })) …
DEFAULT_FROM_PROJProjection assumed for vector data (GeoJSON, CSV, JSON, shapefile) that carries no crs and whose layer sets no fromProj, when neither the query (CONFIGURATION.setOptions({ defaultFromProj })) nor the URL (?defaultFromProj=, options=defaultfromproj:CODE, options=nodefaultfromproj) says otherwise. It is the map projection (Web Mercator), so raw coordinates in metres load unchanged. Exposed as ExtjsUtils.CONFIGURATION.DEFAULT_FROM_PROJ. A file layer's GeoJSON is first guessed from its first coordinate (EPSG:4326 for lon/lat values, otherwise EPSG:3857), so for GeoJSON this default only applies when that guess fails.
setOptions
function(configurationOptions) : Booleanhelper# Defines query-level application configuration (iframe wheel behaviour, etc.).
setOptionsWritten as ExtjsUtils.CONFIGURATION.setOptions
Defines query-level application configuration (iframe wheel behaviour, etc.). Settings are stored with the query and cleared when another query loads.
- configurationOptions Object
- Query-level configuration options.
- configurationOptions.keepOnLeave Boolean
- When false, iframe mouseout blocks wheel until map click.
- configurationOptions.defaultFromProj String|null|false
- Default fromProj for CSV and JSON lists without crs (a file layer's GeoJSON first guesses EPSG:4326 or EPSG:3857 from its first coordinate; this default is used only when that guess fails). Precedence: this option, then the URL (
?defaultFromProj=,options=defaultfromproj:CODE,options=nodefaultfromproj), thenCONFIGURATION.DEFAULT_FROM_PROJ(EPSG:900913). null/false/"none" disables. - configurationOptions.backgroundSelector Boolean|Object
- When true (or options object), show the floating background basemap picker after the query loads (platform OpenLayers.BackgroundSelector.sync).
Returns True for chaining with && QUERY_DESCRIPTION
ExtjsUtils.CONFIGURATION.setOptions({ keepOnLeave: false }) && QUERY_DESCRIPTION
ExtjsUtils.CONFIGURATION.setOptions({ defaultFromProj: 'EPSG:4674' }) && QUERY_DESCRIPTION
ExtjsUtils.CONFIGURATION.setOptions({ backgroundSelector: true }) && QUERY_DESCRIPTIONPROJECTION · CRS codes and upload choices
PROJECTION3 entriesnormalizeCode
function(fullCodeName) : String|nullhelper# Normalizes a CRS name or code (a GeoJSON crs.properties.name, "EPSG:4674", "epsg4326", "urn:ogc:def:crs:OGC:1.3:CRS84", "SIRGAS 2000 / UTM zone 23S"...) to the canonical EPSG string OpenLayers uses.
normalizeCodeWritten as ExtjsUtils.PROJECTION.normalizeCode
Normalizes a CRS name or code (a GeoJSON crs.properties.name, "EPSG:4674", "epsg4326", "urn:ogc:def:crs:OGC:1.3:CRS84", "SIRGAS 2000 / UTM zone 23S"...) to the canonical EPSG string OpenLayers uses. Matching is case/whitespace-insensitive and covers the built-in definitions (WGS 84, SIRGAS 2000 and its UTM zones, Web Mercator — 900913 maps to EPSG:3857) plus the codes/patterns registered with setProjectionOptions. Returns null for an unknown CRS, so callers can fall back to a default projection.
- fullCodeName String
- CRS name or code as found in data files or user input.
Returns Canonical code such as "EPSG:4674", or null when it is not recognised.
ExtjsUtils.PROJECTION.normalizeCode("urn:ogc:def:crs:EPSG::4674"); // "EPSG:4674"
ExtjsUtils.PROJECTION.normalizeCode("EPSG:900913"); // "EPSG:3857"resolveProjectionObject
function(projection, fallbackProjection) : OpenLayers.Projection|nullhelper# Resolves a projection given in any usual form — an EPSG string, an OpenLayers.Projection, or any object with getCode() — to a real OpenLayers.Projection.
resolveProjectionObjectWritten as ExtjsUtils.PROJECTION.resolveProjectionObject
Resolves a projection given in any usual form — an EPSG string, an OpenLayers.Projection, or any object with getCode() — to a real OpenLayers.Projection. The code is normalised with normalizeCode first; when the input carries no usable code the fallbackProjection (typically the map projection) is returned instead of constructing new OpenLayers.Projection(<non-string>), which would throw "srsCode.indexOf is not a function" once Proj4js is loaded. Use it before geometry.transform(...) when the source projection comes from user data and may be missing.
- projection String|OpenLayers.Projection|Object
- Projection to resolve: EPSG code string, projection instance, or object exposing
getCode(). - fallbackProjection OpenLayers.Projection
- Projection returned when
projectionhas no usable code (e.g. the map projection).
Returns The resolved projection, the fallback, or null when neither is available.
var mapProj = ExtjsUtils.JS.getMap().getProjectionObject();
var fromProj = ExtjsUtils.PROJECTION.resolveProjectionObject(geojson.crs && geojson.crs.properties.name, mapProj);
feature.geometry.transform(fromProj, mapProj);setProjectionOptions
function(projectionOptions, config) : Booleanhelper# Register projection options for the current query.
setProjectionOptionsWritten as ExtjsUtils.PROJECTION.setProjectionOptions
Register projection options for the current query. Each entry: { code, label?, proj4?, codes?, patterns? } — label defaults to code. The same list drives bare-.shp upload choices and custom CRS registration. Also lazy-loads theme proj4 definitions (SIRGAS) when entries are set.
- projectionOptions Array|Object
- Entries, or { projectionOptions, includeDefaults? }
- config Object
- When first arg is an array: { includeDefaults?: Boolean } includeDefaults: true merges IDE defaults (EPSG:4326, EPSG:4674, EPSG:3857) before tenant entries.
Returns True for chaining with && QUERY_DESCRIPTION { code, label?, proj4?, wkt?, codes?, patterns? } proj4 and wkt are alternative CRS definitions (bundled Proj4js uses proj4 internally).
// Full explicit list (no IDE defaults added):
ExtjsUtils.PROJECTION.setProjectionOptions([
{ code: "EPSG:4326", label: "WGS 84" },
{ code: "EPSG:4674", label: "SIRGAS 2000" },
{ code: "EPSG:5534", label: "SAD69 / UTM 22S",
proj4: "+proj=utm +zone=22 +south +ellps=astral +units=m +no_defs",
codes: ["5534"], patterns: ["sad69"] }
]) && QUERY_DESCRIPTION// WKT instead of proj4:
ExtjsUtils.PROJECTION.setProjectionOptions([
{ code: "EPSG:5534", label: "SAD69 / UTM 22S", wkt: "PROJCS[...]", codes: ["5534"] }
]) && QUERY_DESCRIPTION// Only add a custom CRS; upload list = IDE defaults + EPSG:5534:
ExtjsUtils.PROJECTION.setProjectionOptions([
{ code: "EPSG:5534", label: "SAD69 / UTM 22S", proj4: "...", codes: ["5534"] }
], { includeDefaults: true }) && QUERY_DESCRIPTIONServer definition (addRemoteWMSServer)
SourceConfig3 entriesonError
function# Defines callback function to be called when the store failes to be loaded.
onErrorDefines callback function to be called when the store failes to be loaded.
onLoad
function# Defines callback function to be called when the store is successfully loaded.
onLoadDefines callback function to be called when the store is successfully loaded.
ptype
String= "gxp_customwmscsource"# The source plugin type of a layer source: the ptype key of a source definition given to ExtjsUtils.QUERY.addRemoteWMSServer, or of a sources entry of a saved map.
ptypeThe source plugin type of a layer source: the ptype key of a source definition given to ExtjsUtils.QUERY.addRemoteWMSServer, or of a sources entry of a saved map. It defaults to "gxp_customwmscsource" (the platform's tiled WMS source, used whenever url is given without a ptype); the other registered types are the gxp plugins ("gxp_googlesource", "gxp_osmsource", "gxp_arcrestsource", ...). The legacy aliases gx_wmssource, gx_olsource, gx_googlesource and gx_osmsource are still registered here so maps saved before version 2.3.2 (when those plugins were renamed) keep loading; do not use them in new queries.
ExtjsUtils.QUERY.addRemoteWMSServer({
google: { ptype: "gxp_googlesource" },
ibge: { url: "https://geoservicos.ibge.gov.br/geoserver/CCAR/wms?" } // ptype defaults to "gxp_customwmscsource"
}) && [
{ name: "HYBRID", source: "google", group: "background", visibility: true }
]Map links and embedding
The parameters of the link - language, toolbar buttons (tools=), page options (options=) - change how that link opens the map; the saved query stays the same. MappiaIO is for a page that embeds the map and talks to it.
Example
// Example link for sharing a map just with its visualization
https://maps.csr.ufmg.br/calculator/?queryid=473
// Example link for sharing a map with its Query visible
https://maps.csr.ufmg.br/editor/?queryid=473Link parameters (?name=value)
URLProperties8 entriesdefinitions
String= 'live'link parameter# Loads the map's layer catalog (the WMS GetCapabilities the layers are built from) from a capabilities cache saved in this browser, instead of from the server.
definitionsWritten as ?definitions=
Loads the map's layer catalog (the WMS GetCapabilities the layers are built from) from a capabilities cache saved in this browser, instead of from the server. definitions=live, like no parameter at all, loads the default catalog: the live one from the server (or, with options=capabilities, the query's own). Any other value is the name of a cache saved with ExtjsUtils.OFFLINE.downloadDefinitions({name}) (ExtjsUtils.OFFLINE.listDefinitions lists them); the service worker answers the catalog request from it, so the map also starts with the map server unreachable. Only the page opened with it is affected: other Mappia pages keep the live catalog. It needs the page controlled by the service worker: without one (the first visit, a hard reload) the page warns and loads the live catalog. A name with no saved cache also falls back to the live catalog. An empty value (definitions=) starts with an empty catalog, without any catalog request: the map does not wait for the server, and only layers that need no catalog record show. No service worker is needed for it. From code, ExtjsUtils.OFFLINE.useDefinitions(name) switches a running map.
// the map's catalog from the cache saved as "fazenda-42"
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&definitions=fazenda-42// the live catalog, said explicitly
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&definitions=live// starts with an empty catalog, at once
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&definitions=extent
Array.<Number>= [-443.628,-16.847,-407.373,3.294]link parameter# Defines in which part of the world the map will start on load.
extentWritten as ?extent=
Defines in which part of the world the map will start on load. The extents must be in EPSG:4326 (coordinates in lat,long). Also, the values need to be in the order: minX, minY, maxX, maxY, separated by comma with no spaces between them.
// Example of query in visualization mode
// This extents start the map center at Japan
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&extent=122,24,153,45// Example of query in edit mode
// This extents will display the whole world
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&extent=-180.0000,-90.0000,180.0000,90.0000lang
String= 'pt'link parameter# Define in which language the Mappia default messages and texts will be displayed.
langWritten as ?lang=
Define in which language the Mappia default messages and texts will be displayed. Actually, Mappia supports the following languages:
- Portuguese (Brazil): pt
- English: eng
// Example of query in visualization mode
// The default text will be displayed in portuguese
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&lang=pt// Example of query in edit mode
// The default text will be displayed in english
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&lang=engmap
string= string.emptylink parameter# Allow the user to define which 'local' maps to load on the URL.
mapWritten as ?map=
Allow the user to define which 'local' maps to load on the URL. You need to pass the map name like in the ones passed at the 'name' property of a Layer with 'source' set as 'local'. This property only applies for visualization mode.
// Example of loading a map without any 'queryid' in visualization mode
https://maps.csr.ufmg.br/calculator/?map=CSR:geologia// Example of loading two map without any 'queryid' in visualization mode
// and starting with them visible
https://maps.csr.ufmg.br/calculator/?map=CSR:geologia,CSR:estados&visiblelayers=2// Example of loading a map without any 'queryid'
https://maps.csr.ufmg.br/?map=CSR:geologiaoptions
string= string.emptylink parameter# Allows the user to set some configurations when the map loads, like displaying a scale, how many Layers will start visible, etc…
optionsWritten as ?options=
Allows the user to set some configurations when the map loads, like displaying a scale, how many Layers will start visible, etc…
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=<options_list>// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=<options_list>See also To learn more about the Options available and how to set them up, check their documentation at: URL Options Section.
queryid
Number= nulllink parameter# Define which Query will be loaded when the map loads.
queryidWritten as ?queryid=
Define which Query will be loaded when the map loads. Every saved Query at Mappia receives a Query id number. By adding that number to the 'queryid', you can select the query loaded by the link. You can find all Queries created at Mappia in the 'Query' button at the top left in the editor window. By hovering the button and selecting the 'Carregar Queries' option, a popup will show up with all the Queries created at Mappia. The older Queries are listed first.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=473// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=473tools
string= 'All tools available'link parameter# Define which tools will be available for the user to interact with the map.
toolsWritten as ?tools=
Define which tools will be available for the user to interact with the map. Every tool listed here will be available for the user. If left empty, Mappia will display all tools for the user.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=<tools_list>// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=<tools_list>See also To learn more about the Tools available and how to set them up, check their documentation at: URL Tools Section.
visiblelayers
Number|String= customlink parameter# How many layers start visible.
visiblelayersWritten as ?visiblelayers=
How many layers start visible. When the parameter is present it overrides the 'visibility' of every layer: all layers start hidden, then this many are turned on, counted in query order.
A positive number N: the first N layers of the query start visible.
A negative number -N: the last N layers start visible.
0: no layer starts visible.
custom: the same as leaving the parameter out: each layer's own 'visibility' decides.
Leaving it out (the default) lets each layer's 'visibility' decide; options=onlyfirstvisible is the same as visiblelayers=1. Any other text, null included, hides every layer.
// Example of query in visualization mode
// If the Layer has 3 Layers in the order: Layer1, Layer2 and Layer3,
// By setting 'visibelayers=2', the FIRST two Layers will start visible
// That is, the Layer1 and Layer2 will start visible
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&visiblelayers=2// Example of query in edit mode
// If the Layer has 3 Layers in the order: Layer1, Layer2 and Layer3
// By setting 'visiblelayers=-2', the LAST two Layers will start visible
// That is, the Layer3 and Layer2 will start visible
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&visiblelayers=-2// Example of query in edit mode
// By setting 'visiblelayers=0', no Layer will start visible when the map loads
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&visiblelayers=0// Example of query in visualization mode
// By setting 'visiblelayers=custom', the Layers will start visible based on
// its 'visibility' property. Only if 'visibility: true', the Layer will start visible
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&visiblelayers=customToolbar buttons (tools=)
URLTools9 entriesExample
// Example with all possible tools
https://maps.csr.ufmg.br/calculator/?queryid=474&tools=legend,measure,hovershowlegend,getfeature,customzoom,zoomextent,helpintro,metadatacustomzoom
Boolean= truelink parameter# If listed, will display the "Zoom de seleção" button.
customzoomWritten as tools=customzoom
If listed, will display the "Zoom de seleção" button. This button allows the user to drag the mouse to select a region to zoom in on the map.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=customzoom// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=customzoomgetfeature
Boolean= truelink parameter# If listed, will display the "Indentifica atributos da feição" button.
getfeatureWritten as tools=getfeature
If listed, will display the "Indentifica atributos da feição" button. This button, when active, allows the user to click at a specific point in the map and get the more informations of the point that was clicked.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=getfeature// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=getfeaturehelpintro
Boolean= truelink parameter# Define if should display the Help Tutorial button.
helpintroWritten as tools=helpintro
Define if should display the Help Tutorial button. This button opens a simple tutorial on how to use the Mappia features.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=helpintro// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=helpintrohovershowlegend
Boolean= truelink parameter# If listed, will display the "Exibir da legenda da feição sob o mouse" button.
hovershowlegendWritten as tools=hovershowlegend
If listed, will display the "Exibir da legenda da feição sob o mouse" button. This button, when active, allows the user to see the map Legend value of where the mouse is hovering.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=hovershowlegend// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=hovershowlegendlegend
Boolean= truelink parameter# If listed, will display the Legend popup button.
legendWritten as tools=legend
If listed, will display the Legend popup button. This button shows a popup with the Legend of the active layers.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=legend// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=legendmeasure
Boolean= truelink parameter# If listed, will display the Ruler button.
measureWritten as tools=measure
If listed, will display the Ruler button. This button allows the user to do measurements of distances in the map.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=measure// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=measuremetadata
Boolean= truelink parameter# If listed, will display the metadata button.
metadataWritten as tools=metadata
If listed, will display the metadata button. This button opens the description of the visible maps as published - source, date, scale and the other metadata recorded with each map.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=metadatanone
Boolean= falselink parameter# If passed as the only value for the ‘tools’ property, no tool will be available for the user to interact with the map.
noneWritten as tools=none
If passed as the only value for the ‘tools’ property, no tool will be available for the user to interact with the map.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=none// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=nonezoomextent
Boolean= truelink parameter# If listed, will display the "Zoom nos layer" button.
zoomextentWritten as tools=zoomextent
If listed, will display the "Zoom nos layer" button. The button that centers the screen at the actual visible layer.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&tools=zoomextent// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&tools=zoomextentPage options (options=)
URLOptions10 entriesExample
// Example with all possible options
https://maps.csr.ufmg.br/calculator/?queryid=474&options=capabilities,grid,scale,disabledownload,hidemetadata,overview,onlyfirstvisiblecapabilities
Boolean= falselink parameter# If listed, will load only the maps defined in the 'name' property of the Layers.
capabilitiesWritten as options=capabilities
If listed, will load only the maps defined in the 'name' property of the Layers. This can speed up the loading time of the Query.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=capabilities// Example of query in editor mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=capabilitiesdisabledownload
Boolean= falselink parameter# If listed, will hide the “download” button of the Legend Window.
disabledownloadWritten as options=disabledownload
If listed, will hide the “download” button of the Legend Window. The “download” button is the same one as the “paramButtonConfig” “download” type.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=disabledownload// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=disabledownloadgrid
Boolean= falselink parameter# If listed, will display the parallel and meridian lines grid.
gridWritten as options=grid
If listed, will display the parallel and meridian lines grid.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=grid// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=gridhidemetadata
Boolean= falselink parameter# If listed, will hide the “metadata” button of the Legend Window.
hidemetadataWritten as options=hidemetadata
If listed, will hide the “metadata” button of the Legend Window. The “metadata” button is the same one as the “paramButtonConfig” “metadata” type.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=hidemetadata// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=hidemetadatahidestylechooser
Boolean= falselink parameter# If listed, hides the style chooser of every layer in the layer panel, so the reader sees each map only in the style the query selected.
hidestylechooserWritten as options=hidestylechooser
If listed, hides the style chooser of every layer in the layer panel, so the reader sees each map only in the style the query selected. The per-layer equivalent is the layer property hideStyleChooser.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=hidestylechooserkeeponleave
Boolean= truelink parameter# Controls mouse wheel zoom when the map is embedded in an iframe.
keeponleaveWritten as options=keeponleave
Controls mouse wheel zoom when the map is embedded in an iframe.
Only applies when the page runs inside an iframe. When false, leaving the document (mouseout with destination HTML) blocks wheel zoom until the user clicks the map; wheel events over the viewport then show Lang.navigationWheelDisabled.
// Query-level setting (preferred for shared maps)
ExtjsUtils.CONFIGURATION.setOptions({ keepOnLeave: false }) && QUERY_DESCRIPTION// Plugin config (tools array in calculator / composer)
{ ptype: "gxp_usabilityhelper", keepOnLeave: false }// URL option (sets keepOnLeave via advToolsOptions; same as default true)
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=keeponleaveonlyfirstvisible
Boolean= falselink parameter# If listed, only the first Layer defined at the Query will be visible when the map loads.
onlyfirstvisibleWritten as options=onlyfirstvisible
If listed, only the first Layer defined at the Query will be visible when the map loads.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=onlyfirstvisible// Example of query in visualization mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=onlyfirstvisibleoverview
Boolean= falselink parameter# If listed, will display a zoom out interactable window at the bottom right when the user zooms in the map.
overviewWritten as options=overview
If listed, will display a zoom out interactable window at the bottom right when the user zooms in the map.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=overview// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=overviewscale
Boolean= falselink parameter# If listed, will display the scale of the map at the bottom left.
scaleWritten as options=scale
If listed, will display the scale of the map at the bottom left.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=scale// Example of query in edit mode
https://maps.csr.ufmg.br/editor/?queryid=<query_id>&options=scalestartopened
Boolean= falselink parameter# If listed, the layer panel (the Legend Window with the query's groups and layers) starts open when the map loads, instead of collapsed behind its button.
startopenedWritten as options=startopened
If listed, the layer panel (the Legend Window with the query's groups and layers) starts open when the map loads, instead of collapsed behind its button. Use it when the layer list is part of what the page is for; leave it out to give the map the whole screen.
// Example of query in visualization mode
https://maps.csr.ufmg.br/calculator/?queryid=<query_id>&options=startopenedMappiaIO · your page and the map
MappiaIO10 entrieshttps://maps.csr.ufmg.br/mappia_io.js, connects with MappiaIO(iframe, true), loads queries with applyQuery, sends objects with send and receives with addOnMessageCallback. Inside the map, the query receives with ExtjsUtils.QUERY.setMappiaIoCallback and answers with ExtjsUtils.QUERY.postMessage. Your page's buttons, lists and forms can drive the map (filter, zoom, highlight, edit a record), and the map tells the page what the user clicked, hovered or drew.MappiaIO
function(communicationTarget, keepAfterReady) : Object# Connects your page to a Mappia map in an iframe (or in a window you opened) and returns the connection: applyQuery loads a query into the map, send delivers an object to the query running there, …
MappiaIOConnects your page to a Mappia map in an iframe (or in a window you opened) and returns the connection: applyQuery loads a query into the map, send delivers an object to the query running there, addOnMessageCallback receives what the query sends back with ExtjsUtils.QUERY.postMessage. Load the library from the map server (<script src="https://maps.csr.ufmg.br/mappia_io.js">).
On creation it greets the map (mappia__checkDOM) until the map answers it is listening (mappia__confirmDOM); everything sent before that is queued and delivered in order, so applyQuery and send may be called right away. Messages travel through window.postMessage wrapped as {mappia_iframe: <JSON text>}, so the page and the map may be on different sites.
Do not open the map with noopener or noreferrer (on the iframe or in window.open): they cut the window link the messages travel on. window.open(url, "_blank", "width=1280,height=860") works; window.open(url, "_blank", "noopener,noreferrer") does not.
- communicationTarget String|HTMLIFrameElement|Window
- The map to talk to: the id of its iframe, the iframe element itself, or the window returned by
window.open. - keepAfterReady Boolean
truekeeps listening after the handshake - needed by any page that receives messages from the map or applies more than one query. Withfalsethe connection stops listening once the map has answered.
Returns The connection, whose methods return it again so calls can be chained.
<iframe id="mappia" src="https://maps.csr.ufmg.br/calculator/?lang=eng&options=scale"></iframe>
<script src="https://maps.csr.ufmg.br/mappia_io.js"></script>
<script>
var mappia = MappiaIO("mappia", true);
mappia.addOnMessageCallback(function (msg) { console.log("from the map:", msg); });
mappia.applyQuery('[{ name: "CSR:estados", title: "States", visibility: true }]');
mappia.send({ operation: "hello", message: "from the page" });
</script>addOnMessageCallback
function(callback) : Object# Registers a function that receives every message from the map.
addOnMessageCallbackRegisters a function that receives every message from the map. What the query posts with ExtjsUtils.QUERY.postMessage(object) arrives as that object; the platform's own notices arrive as strings starting with mappia__ - mappia__queryApplied once a query sent with applyQuery is in place, mappia__confirmQueryListening when a query registers its callback. Several functions may be registered; each gets every message, about 150 ms after it was posted. Needs a connection created with keepAfterReady true.
- callback function
function (message), called for each message.
Returns The connection.
mappia.addOnMessageCallback(function (msg) {
if (msg === "mappia__queryApplied") return showStatus("Map ready");
if (msg && msg.operation === "city_clicked") showDetails(msg.message);
});addOnRemoveCallback
function(callback) : Object# Registers a function run when remove stops the connection, to tidy up whatever the page attached to it.
addOnRemoveCallbackRegisters a function run when remove stops the connection, to tidy up whatever the page attached to it.
- callback function
- Called with no arguments.
Returns The connection.
addReadyCallback
function(callback) : Object# Runs callback once the map has answered the handshake - at once when it already has.
addReadyCallbackRuns callback once the map has answered the handshake - at once when it already has. The place to start a conversation that needs the map listening: apply the first query there, then send the page's starting state (filters, the record being edited...).
- callback function
- Called with no arguments.
Returns The connection.
mappia.addReadyCallback(function () {
fetch("/my-map-query.js").then(function (r) { return r.text(); }).then(function (text) {
mappia.applyQuery(text);
mappia.send({ operation: "setFilters", message: currentFilters });
});
});applyQuery
function(queryContent) : Object# Loads a query into the map - the same text you would type in the Mappia editor, of any length and not saved on the server - replacing the layers the map shows.
applyQueryLoads a query into the map - the same text you would type in the Mappia editor, of any length and not saved on the server - replacing the layers the map shows. The map confirms with the message mappia__queryApplied once the new layers are in place. A query that did not run (a syntax or runtime error, or a value that is not a list of layers) is confirmed too, but the message {action: "mappia__queryError", error: {name, message, line, column}} comes first. One connection can apply query after query; called before the handshake, it waits in the queue.
- queryContent String
- The query text.
Returns The connection (not a promise: listen for mappia__queryApplied).
mappia.addOnMessageCallback(function (msg) {
if (msg && msg.action === "mappia__queryError") console.warn("The query did not run:", msg.error.message, "line", msg.error.line);
else if (msg === "mappia__queryApplied") console.log("applied");
});
mappia.applyQuery('[{ name: "CSR:altimetria", title: "Elevation", visibility: true }]');applyQueryFromUrl
function(queryUrl) : Promise.<Object># Fetches the query text at queryUrl and applies it as applyQuery does - for a query kept as a file in your own site or repository.
applyQueryFromUrlFetches the query text at queryUrl and applies it as applyQuery does - for a query kept as a file in your own site or repository. The URL is read with fetch, so one on another site must allow cross-origin reads.
- queryUrl String
- Address of a file holding query text, such as
[{ name: "CSR:estados" }].
Returns Resolves with the connection once the text was fetched and sent - not when the map applied it: wait for the mappia__queryApplied message for that.
mappia.applyQueryFromUrl("/queries/my-map.js");isDomLoaded
function() : Boolean# Whether the map has answered the handshake.
isDomLoadedWhether the map has answered the handshake. Until it has, send and applyQuery queue their messages and deliver them, in order, as soon as it answers.
Returns true once the map is listening.
postMessage
function(jsStr)helper# Sends a message to the Mappia/iframe, allowing communication between the Mappia/iframe and the parent window.
postMessageWritten as ExtjsUtils.QUERY.postMessage
Sends a message to the Mappia/iframe, allowing communication between the Mappia/iframe and the parent window. (Compatible with MappiaIO library) The 'QUERY.setMappiaIoCallback' is responsible to interpret the sent message.
- jsStr Object|String
- Object to be sent from inside Mappia/iframe to parent window. Objects are JSON-stringified; the parent receives
{ mappia_iframe: jsStr }.
ExtjsUtils.QUERY.postMessage({a:1,b:2})remove
function() : Object# Stops listening to the map and runs the functions registered with addOnRemoveCallback.
removeStops listening to the map and runs the functions registered with addOnRemoveCallback. A connection created with keepAfterReady false calls it by itself right after the handshake; call it yourself when the page drops the map (a closed panel, a route change) so an old connection does not keep receiving messages.
Returns The connection.
send
function(message, forceSend) : Object# Delivers message to the query running in the map, which receives it in the function it registered with ExtjsUtils.QUERY.setMappiaIoCallback.
sendDelivers message to the query running in the map, which receives it in the function it registered with ExtjsUtils.QUERY.setMappiaIoCallback. The shape is yours to choose; by convention an object naming an operation and carrying a message, plus a requestId when the page waits for an answer. Objects travel as JSON (functions and dates do not survive); a message carrying a File or Blob ({operation: "import", file: file}) is sent as the object itself, so the file reaches the query intact. Never send strings starting with mappia__: the platform reserves them.
- message Object|String
- What to deliver to the query.
- forceSend Boolean
- Sends at once even before the handshake, skipping the queue. Pages normally leave it out.
Returns The connection.
mappia.send({ operation: "show_city", message: { name: "Belo Horizonte" } });
mappia.send({ operation: "list_cities", requestId: "r1" }); // the query answers with the same requestIdQUERY.queryState · apply-message queue (internal)
QueryState8 entriesUsage: ExtjsUtils.QUERY.queryState
cancelWaiting
function(name)# Internal — releases the operation started with startWaiting(name) when it failed (e.g. the query did not parse).
cancelWaitingInternal — releases the operation started with startWaiting(name) when it failed (e.g. the query did not parse). It currently behaves exactly like endWaiting(name): the counter is decremented and, at zero, the queued messages are still processed — they are not discarded. Tenant code normally does not call it.
- name String
- Identifier used in the matching
startWaitingcall.
ExtjsUtils.QUERY.queryState.cancelWaiting("myAsyncSetup");endWaiting
function(name)# Internal — marks the end of the operation started with startWaiting(name).
endWaitingInternal — marks the end of the operation started with startWaiting(name). Decrements the shared counter; when it reaches zero every queued message is processed in order (RUN_QUERY_APPLY messages apply their query, the others go to the MappiaIO callback). A name that is not active is rejected with a console error. Tenant code normally does not call it.
- name String
- Identifier used in the matching
startWaitingcall.
ExtjsUtils.QUERY.queryState.endWaiting("myAsyncSetup");handleMessage
function(jsMsg)# Internal — entry point for a RUN_QUERY_APPLY message ({action, queryContent}).
handleMessageInternal — entry point for a RUN_QUERY_APPLY message ({action, queryContent}). While waiting the message is queued; otherwise it is wrapped in a startWaiting/endWaiting pair so that it is applied through the queue right away. Tenant code normally does not call it.
- jsMsg Object
- Message object with
actionandqueryContent.
initMessageHandler
function()# Internal — installs the window "message" listener that receives the parent page's postMessage calls and immediately posts CONFIRM_DOM_LOADED back.
initMessageHandlerInternal — installs the window "message" listener that receives the parent page's postMessage calls and immediately posts CONFIRM_DOM_LOADED back. Protocol messages (CHECK_DOM, CHECK_QUERY, RUN_QUERY_APPLY) are answered by the platform; any other message is queued while isWaiting() is true, otherwise it is delivered to the callback registered with QUERY.setMappiaIoCallback. Called once by the editor/calculator pages when they load; tenant code does not call it.
isWaiting
function() : Boolean# Internal — tells whether at least one operation registered with startWaiting is still running, i.e. whether incoming messages are being queued.
isWaitingInternal — tells whether at least one operation registered with startWaiting is still running, i.e. whether incoming messages are being queued. Tenant code normally does not call it.
Returns True while the shared counter is greater than zero.
if (!ExtjsUtils.QUERY.queryState.isWaiting()) handleNow();queueMessage
function(message)# Internal — appends a message to the queue that is flushed when the counter reaches zero.
queueMessageInternal — appends a message to the queue that is flushed when the counter reaches zero. Meant to be called only while isWaiting() is true; a queued RUN_QUERY_APPLY message applies its query, any other message is delivered to the MappiaIO callback. Tenant code normally does not call it.
- message *
- Message payload as received from the parent window.
setQueryApplyHandler
function(handler)# Internal — replaces the default way a RUN_QUERY_APPLY message is applied (QUERY.loadCurrentQuery) with a custom handler; the editor uses it to load the received query text into its code panel …
setQueryApplyHandlerInternal — replaces the default way a RUN_QUERY_APPLY message is applied (QUERY.loadCurrentQuery) with a custom handler; the editor uses it to load the received query text into its code panel instead of straight into the map. The handler runs once the map is loaded (or is deferred to AFTER_APP_LOADING) and receives (queryContent, notifyQueryApplied); it must call notifyQueryApplied() when done so the parent window gets CONFIRM_QUERY_APPLIED. Tenant code normally does not call it.
- handler function
- Function
(queryContent, notifyQueryApplied)that applies the query.
ExtjsUtils.QUERY.queryState.setQueryApplyHandler(function(queryContent, notifyQueryApplied) {
ExtjsUtils.QUERY.loadCurrentQuery(ExtjsUtils.JS.getApp(), queryContent, notifyQueryApplied);
});startWaiting
function(name)# Internal — marks the start of an operation (a query load, the map loading) during which incoming messages must be queued instead of handled.
startWaitingInternal — marks the start of an operation (a query load, the map loading) during which incoming messages must be queued instead of handled. Increments the shared counter under name; a name that is already active is rejected with a console error. Pair it with endWaiting(name) (success) or cancelWaiting(name) (failure). Tenant code normally does not call it.
- name String
- Identifier of the operation, e.g.
"loadCurrentQuery".
ExtjsUtils.QUERY.queryState.startWaiting("myAsyncSetup");ExtjsUtils helpers (A-Z)
QUERY, CONFIGURATION and PROJECTION are under Query setup; OFFLINE under Offline maps.
ExtjsUtils · top-level helpers
ExtjsUtils30 entriesUsage: ExtjsUtils.<member>
ASSERTION_ENABLED
Boolean# When true, the console.assert checks spread through the platform code are evaluated (see dealWithAssertions); when false they are turned into console warnings.
ASSERTION_ENABLEDWritten as ExtjsUtils.ASSERTION_ENABLED
When true, the console.assert checks spread through the platform code are evaluated (see dealWithAssertions); when false they are turned into console warnings. Meant to be true only in development builds.
CancelEvent
function(evt)helper# Cancels the default browser action of a DOM event (preventDefault, or returnValue = false on old IE) — for instance to suppress the context menu or a link navigation.
CancelEventWritten as ExtjsUtils.CancelEvent
Cancels the default browser action of a DOM event (preventDefault, or returnValue = false on old IE) — for instance to suppress the context menu or a link navigation.
- evt Event
- The DOM event to cancel.
ExtjsUtils.addDomListener(document.getElementById('map'), 'contextmenu', ExtjsUtils.CancelEvent);DomObserver
functionhelper# Ext plugin that binds plain DOM events (the ones the Ext component itself does not expose, such as contextmenu) to the component's element as soon as it renders.
DomObserverWritten as ExtjsUtils.DomObserver
Ext plugin that binds plain DOM events (the ones the Ext component itself does not expose, such as contextmenu) to the component's element as soon as it renders. Create it with an object mapping DOM event names to handlers function(evt, component) — or with { listeners: {...} } — and put the instance in the component's plugins array.
{
xtype: 'gxp_fieldset',
plugins: [
new ExtjsUtils.DomObserver({
contextmenu: function(evt, comp) {
ExtjsUtils.CancelEvent(evt);
}
})
]
}NodeMouseoverPlugin
functionhelper# Ext plugin for an Ext.tree.TreePanel that makes the tree fire mouseover and mouseout events for its nodes ((node, evt)), which Ext 3.4 does not provide out of the box.
NodeMouseoverPluginWritten as ExtjsUtils.NodeMouseoverPlugin
Ext plugin for an Ext.tree.TreePanel that makes the tree fire mouseover and mouseout events for its nodes ((node, evt)), which Ext 3.4 does not provide out of the box. Add an instance to the tree's plugins and listen to those events on the tree.
var tree = new Ext.tree.TreePanel({
plugins: [new ExtjsUtils.NodeMouseoverPlugin()],
listeners: {
mouseover: function(node, evt) { console.log('over', node.text); },
mouseout: function(node, evt) { console.log('out', node.text); }
}
});SliderZIndexFixer
functionhelper# Ext plugin that works around a GeoExt.LayerOpacitySlider bug: after each drag the slider thumb keeps a raised z-index, so the plugin resets the thumb's z-index on dragend to the value given to …
SliderZIndexFixerWritten as ExtjsUtils.SliderZIndexFixer
Ext plugin that works around a GeoExt.LayerOpacitySlider bug: after each drag the slider thumb keeps a raised z-index, so the plugin resets the thumb's z-index on dragend to the value given to the constructor (default 0).
new GeoExt.LayerOpacitySlider({
layer: layer,
plugins: new ExtjsUtils.SliderZIndexFixer(0)
});addDomListener
function(domObj, evtName, fn, useCapture)helper# Adds a DOM event listener, working across old and new browsers (addEventListener or attachEvent).
addDomListenerWritten as ExtjsUtils.addDomListener
Adds a DOM event listener, working across old and new browsers (addEventListener or attachEvent). The usual query use is addDomListener(window, 'mousemove', fn) to track the element under the mouse for a floating popup. Remove it later with removeDomListener passing the very same function.
- domObj EventTarget
- DOM object to listen on (an element,
documentorwindow). - evtName String
- DOM event name, without the
onprefix (e.g.'mousemove','click'). - fn function
- Event callback; receives the DOM event.
- useCapture Boolean
- Register in the capture phase. Only honoured when
domObjiswindow,documentordocument.body; other targets always use the bubbling phase.
ExtjsUtils.addDomListener(window, 'mousemove', function(evt) {
window.lastHoveredElement = evt.target;
});addListenerToConfig
function(config, eventName, callback, scope) : Objecthelper# Adds a listener to an Ext config object's listeners[eventName] without losing a listener that is already there: when one exists, the new callback runs first and then the previous one, both …
addListenerToConfigWritten as ExtjsUtils.addListenerToConfig
Adds a listener to an Ext config object's listeners[eventName] without losing a listener that is already there: when one exists, the new callback runs first and then the previous one, both receiving the event arguments. Creates the listeners object when missing.
- config Object
- Ext component config object to modify.
- eventName String
- Name of the Ext event (e.g.
'afterrender','click'). - callback function
- Listener to add.
- scope Object
thisforcallback; defaults to the event's own scope.
Returns The same config object, modified.
var cfg = { xtype: 'button', text: 'Go', listeners: { click: function() { console.log('first'); } } };
ExtjsUtils.addListenerToConfig(cfg, 'click', function() { console.log('added'); });
// clicking now logs "added" then "first"bboxTransform
function(layerBBox, fromProjection, toProjection) : OpenLayers.Boundshelper# Reprojects a bounding box from one projection to another and returns it as a new OpenLayers.Bounds (the input is never modified).
bboxTransformWritten as ExtjsUtils.bboxTransform
Reprojects a bounding box from one projection to another and returns it as a new OpenLayers.Bounds (the input is never modified). The source projection defaults to lon/lat ("EPSG:4326"), which is what WMS capabilities bounding boxes use.
- layerBBox OpenLayers.Bounds|Array.<Number>
- The bounding box to reproject: an
OpenLayers.Boundsor a[left, bottom, right, top]array. - fromProjection String|OpenLayers.Projection
- Projection the bounding box is currently in.
- toProjection String|OpenLayers.Projection
- Projection to convert to (e.g. the map projection,
app.mapPanel.map.getProjection()).
Returns A new bounds object in toProjection.
// lon/lat box of Minas Gerais into the map projection, then zoom to it
var bounds = ExtjsUtils.bboxTransform([-51.1, -22.9, -39.9, -14.2], "EPSG:4326", app.mapPanel.map.getProjection());
app.mapPanel.map.zoomToExtent(bounds);dealWithAssertions
function()helper# Wraps console.assert so the assertions left in the platform code follow ASSERTION_ENABLED (read once, when this runs): when enabled they go through the native console.assert; when disabled …
dealWithAssertionsWritten as ExtjsUtils.dealWithAssertions
Wraps console.assert so the assertions left in the platform code follow ASSERTION_ENABLED (read once, when this runs): when enabled they go through the native console.assert; when disabled every console.assert call is turned into a console.warn of its arguments instead. Called once when this file is initialised; a query has no reason to call it.
ExtjsUtils.ASSERTION_ENABLED = false;
ExtjsUtils.dealWithAssertions(); // from now on console.assert only warnsdeepCompare
function(objA, objB, customCompare) : Booleanhelper# Deep equality of two values: every property is compared recursively (arrays, nested objects, dates, regular expressions and functions — the latter by their source text — with cycle protection).
deepCompareWritten as ExtjsUtils.deepCompare
Deep equality of two values: every property is compared recursively (arrays, nested objects, dates, regular expressions and functions — the latter by their source text — with cycle protection). An optional hook lets you decide the comparison of any pair of values yourself. Useful to detect whether a layer definition or an inputs object actually changed.
- objA *
- First value to compare.
- objB *
- Second value to compare.
- customCompare function
- Hook
function(x, y)called for every pair of values (the roots first, then each nested property) before the default comparison. Returntrue(equal) orfalse(different) to decide, orundefinedto let the default comparison run.
Returns true when the two values are deeply equal, false otherwise.
ExtjsUtils.deepCompare({ a: 1, b: [1, 2] }, { a: 1, b: [1, 2] }); // true
// Treat numbers closer than 0.001 as equal
ExtjsUtils.deepCompare(oldStats, newStats, function(x, y) {
if (typeof x === 'number' && typeof y === 'number') return Math.abs(x - y) < 0.001;
});default_background_map
Object# Layer definition of the platform's default basemap (OpenStreetMap Mapnik, from the osm source), used when a query declares no layer with group: "background": the platform then inserts this …
default_background_mapWritten as ExtjsUtils.default_background_map
Layer definition of the platform's default basemap (OpenStreetMap Mapnik, from the osm source), used when a query declares no layer with group: "background": the platform then inserts this definition at the bottom of the query's layer list while the query is loaded. To use another basemap, declare your own group: "background" layer in the query instead of changing this object — production queries that mutate it at runtime (e.g. from runNow) were verified to have no effect, because it is read before the query code runs.
// The declarative way to replace the default basemap
[
{
title: 'Basemaps',
elements: [
{ title: 'Google Hybrid', name: 'HYBRID', source: 'google', group: 'background', visibility: true }
]
}
]disableContextMenu
function(configObj) : Objecthelper# Disables the browser context menu (right click) on an Ext component by adding a DomObserver plugin that cancels the contextmenu event.
disableContextMenuWritten as ExtjsUtils.disableContextMenu
Disables the browser context menu (right click) on an Ext component by adding a DomObserver plugin that cancels the contextmenu event. Apply it to the component's config object before the component is created; it does nothing on an already built component (one that has on).
- configObj Object
- Config object of the Ext component to be created.
Returns The same config object, with the context-menu-cancelling plugin added.
var panel = new Ext.Panel(ExtjsUtils.disableContextMenu({ html: 'No right click here' }));getBodyHeight
function() : Numberhelper# Returns the full height of the page document in pixels (the largest of the body/document scroll, offset and client heights), including the part that is scrolled out of view.
getBodyHeightWritten as ExtjsUtils.getBodyHeight
Returns the full height of the page document in pixels (the largest of the body/document scroll, offset and client heights), including the part that is scrolled out of view.
Returns The document height in pixels.
var pageHeight = ExtjsUtils.getBodyHeight();getButtonScale
function(strict) : Stringhelper# Returns the Ext button scale to use so buttons are usable both on desktop and on touch devices: 'large' on mobile (CHECK.isMobile()), 'medium' otherwise.
getButtonScaleWritten as ExtjsUtils.getButtonScale
Returns the Ext button scale to use so buttons are usable both on desktop and on touch devices: 'large' on mobile (CHECK.isMobile()), 'medium' otherwise.
- strict Boolean
- Currently unused; the check always uses the non-strict
CHECK.isMobile().
Returns 'large' or 'medium', ready for an Ext button scale config.
new Ext.Button({ text: 'Apply', scale: ExtjsUtils.getButtonScale() });getDesiredProjection
function() : Stringhelper# Returns the "desired" output projection for coordinates shown to users: longitude/latitude, "EPSG:4326".
getDesiredProjectionWritten as ExtjsUtils.getDesiredProjection
Returns the "desired" output projection for coordinates shown to users: longitude/latitude, "EPSG:4326". Use it as the target projection when converting a clicked map position into coordinates a person will read. It is not the map projection — see getFromProjection.
Returns The projection code "EPSG:4326".
// Longitude/latitude of a map click, ready to be displayed
var lonLat = ExtjsUtils.COORDINATE.getLatLong(evt, ExtjsUtils.getDesiredProjection());getElementsByClassName
function(className, tag, elm) : Array.<HTMLElement>helper# Cross-browser getElementsByClassName: returns the elements carrying all the given class names (space separated), optionally restricted to a tag name and to the descendants of an element.
getElementsByClassNameWritten as ExtjsUtils.getElementsByClassName
Cross-browser getElementsByClassName: returns the elements carrying all the given class names (space separated), optionally restricted to a tag name and to the descendants of an element. Uses the native method, querySelectorAll, XPath or a manual scan depending on the browser, and always returns a real array. Original polyfill by Robert Nyman, refactored by Tubal Martin.
- className String
- One or more class names, separated by spaces (all must be present).
- tag String
- Tag name to restrict the result to (e.g.
'div'); any tag when omitted. - elm HTMLElement
- Element to search under; the whole document when omitted.
Returns The matching elements (empty when none).
ExtjsUtils.getElementsByClassName('legend-entry selected', 'div').forEach(function(el) {
el.style.fontWeight = 'bold';
});getFromProjection
function() : Stringhelper# Returns the map projection code, "900913" (Spherical Mercator, the projection every layer is rendered in).
getFromProjectionWritten as ExtjsUtils.getFromProjection
Returns the map projection code, "900913" (Spherical Mercator, the projection every layer is rendered in). This is a different concept from CONFIGURATION.DEFAULT_FROM_PROJ — the projection assumed for vector/GeoJSON input that declares no CRS — even though both happen to be the same projection.
Returns The map projection code "900913".
// Reproject a lon/lat bounding box into map units
var bounds = ExtjsUtils.bboxTransform([-50, -20, -40, -10], "EPSG:4326", ExtjsUtils.getFromProjection());getFunction
function(definition) : functionhelper# Always returns a callable function from a "function definition".
getFunctionWritten as ExtjsUtils.getFunction
Always returns a callable function from a "function definition". A function is returned as is (its closure is kept); a string is resolved first as the name of a global function (window[name]) and, failing that, evaluated as function source (a function(...) {...} literal or a statement body) through Mark.getFunction; anything else yields a no-op function. This is the resolution the markup widgets apply to string parameters such as handler= in {{button|handler=myGlobalFunction}}.
- definition function|String|*
- A function, the name of a global function, function source code, or anything else (no-op).
Returns The resolved function; never undefined.
window.sayHi = function() { ExtjsUtils.ALERTIFY.log("Hi"); };
ExtjsUtils.getFunction("sayHi")(); // calls window.sayHi
ExtjsUtils.getFunction("function() { return 42; }")(); // 42
ExtjsUtils.getFunction(undefined)(); // does nothinggetLayerExtent
function(layer) : OpenLayers.Boundshelper# Deprecated alias of ExtjsUtils.LAYER.getLayerExtent: returns the extent of a layer in the map projection (its WMS lon/lat bounding box reprojected), falling back to the layer's or the map's maxExtent.
getLayerExtentWritten as ExtjsUtils.getLayerExtent
Deprecated alias of ExtjsUtils.LAYER.getLayerExtent: returns the extent of a layer in the map projection (its WMS lon/lat bounding box reprojected), falling back to the layer's or the map's maxExtent. Kept because many queries still call it; new code should call ExtjsUtils.LAYER.getLayerExtent directly.
- layer OpenLayers.Layer
- The layer whose extent is wanted.
Returns The layer extent in the map projection.
// Zoom the map to a layer (e.g. from a layer's onVisibilityChange)
app.mapPanel.map.zoomToExtent(ExtjsUtils.getLayerExtent(layer), true);getRandomColor
function(asArray) : String|Array.<Number>helper# Generates a random colour, either as an HTML hex string ("#rrggbb") or as an [r, g, b] array.
getRandomColorWritten as ExtjsUtils.getRandomColor
Generates a random colour, either as an HTML hex string ("#rrggbb") or as an [r, g, b] array. Handy as a fallback colour when a legend value has no colour of its own.
- asArray Boolean
trueto get the colour as an[r, g, b]array (0-255 components) instead of a hex string.
Returns The generated colour: a "#rrggbb" string, or [r, g, b] when asArray is true.
var hex = ExtjsUtils.getRandomColor(); // "#3fa2c1"
var rgb = ExtjsUtils.getRandomColor(true); // [63, 162, 193]invertArray
function(arr) : Arrayhelper# Returns a new array with the elements of arr in reverse order.
invertArrayWritten as ExtjsUtils.invertArray
Returns a new array with the elements of arr in reverse order. Note that the input array is consumed in the process (its elements are popped one by one), so it is left empty afterwards — pass a copy (arr.slice()) when you still need the original.
- arr Array
- The array to reverse; emptied by the call.
Returns A new array with the elements in reverse order.
var reversed = ExtjsUtils.invertArray(names.slice()); // 'names' is kept intactisLittleEndian
Boolean# true when the machine is little-endian, false when big-endian.
isLittleEndianWritten as ExtjsUtils.isLittleEndian
true when the machine is little-endian, false when big-endian. Computed once at load time (through a typed-array check); relevant when reading raw pixel/typed-array data.
var byteOrder = ExtjsUtils.isLittleEndian ? "little-endian" : "big-endian";isValidBBox
function(BBox) : Booleanhelper# Tells whether a bounds object is usable: its width and height are numbers (not NaN), which is what a failed reprojection or a malformed capabilities bounding box produces.
isValidBBoxWritten as ExtjsUtils.isValidBBox
Tells whether a bounds object is usable: its width and height are numbers (not NaN), which is what a failed reprojection or a malformed capabilities bounding box produces.
- BBox OpenLayers.Bounds
- The bounds to validate.
Returns true when width and height are valid numbers, false otherwise.
var bounds = ExtjsUtils.bboxTransform(layer.llbbox, undefined, app.mapPanel.map.getProjection());
if (ExtjsUtils.isValidBBox(bounds)) app.mapPanel.map.zoomToExtent(bounds);latinLowerString
function(s) : Stringhelper# Lower-cases a string and strips Latin accents (á→a, ç→c, ã→a, æ→ae, ...).
latinLowerStringWritten as ExtjsUtils.latinLowerString
Lower-cases a string and strips Latin accents (á→a, ç→c, ã→a, æ→ae, ...). Useful to compare or search user text and layer titles regardless of accents and case.
- s String
- The string to normalise.
Returns The string in lower case without accented characters.
ExtjsUtils.latinLowerString("Mata Atlântica"); // "mata atlantica"layerBoundsIsVisible
function(layer) : Booleanhelper# Tells whether any part of a layer's maximum extent (layer.getMaxExtent()) intersects the area currently shown by the map.
layerBoundsIsVisibleWritten as ExtjsUtils.layerBoundsIsVisible
Tells whether any part of a layer's maximum extent (layer.getMaxExtent()) intersects the area currently shown by the map.
- layer OpenLayers.Layer
- Layer to test.
Returns true when the layer extent intersects the current map view, false otherwise.
if (!ExtjsUtils.layerBoundsIsVisible(layer)) app.mapPanel.map.zoomToExtent(ExtjsUtils.LAYER.getLayerExtent(layer));removeDomListener
function(domObj, evtName, fn)helper# Removes a DOM event listener previously added with addDomListener (removeEventListener or detachEvent, whichever the browser supports).
removeDomListenerWritten as ExtjsUtils.removeDomListener
Removes a DOM event listener previously added with addDomListener (removeEventListener or detachEvent, whichever the browser supports). The callback must be the exact function reference that was registered.
- domObj EventTarget
- DOM object the listener was added to.
- evtName String
- DOM event name, without the
onprefix. - fn function
- The callback to remove (must be the same function passed to
addDomListener).
function onMove(evt) { console.log(evt.pageX, evt.pageY); }
ExtjsUtils.addDomListener(window, 'mousemove', onMove);
// ...later
ExtjsUtils.removeDomListener(window, 'mousemove', onMove);scrollIntoView
function(container, item, padding)helper# Scrolls an Ext container so that item becomes visible, keeping padding pixels between the item and the top border of the scrollable area instead of leaving it glued to the edge.
scrollIntoViewWritten as ExtjsUtils.scrollIntoView
Scrolls an Ext container so that item becomes visible, keeping padding pixels between the item and the top border of the scrollable area instead of leaving it glued to the edge. Inspired by Ext's Element.scrollIntoView.
- container Ext.Panel
- Scrollable Ext container; its
bodyelement is the one scrolled. - item HTMLElement|Ext.Element|String
- Element (or element id) inside the container to bring into view.
- padding Number
- Distance in pixels to keep between the item and the container's top edge.
ExtjsUtils.scrollIntoView(legendPanel, 'legend-entry-12', 20);toBounds
function(extent) : OpenLayers.Boundshelper# Turns any of the usual extent shapes into an OpenLayers.Bounds, without reprojecting: an OpenLayers.Bounds comes back as is, a [left, bottom, right, top] array (Bounds#toArray() order, what …
toBoundsWritten as ExtjsUtils.toBounds
Turns any of the usual extent shapes into an OpenLayers.Bounds, without reprojecting: an OpenLayers.Bounds comes back as is, a [left, bottom, right, top] array (Bounds#toArray() order, what offline area records and postMessage payloads carry) or a {left, bottom, right, top} object becomes a new one. Use it at the edge where an extent arrives from outside (a message, a stored record) before calling map functions.
- extent OpenLayers.Bounds|Array.<Number>|Object
- The extent, in any of the three shapes.
Returns The bounds, or null when extent is missing or lacks a side.
// an extent received from the parent page
var bounds = ExtjsUtils.toBounds(msg.message.extent); // [-5179428, -2460070, -5171880, -2455780]
if (bounds) ExtjsUtils.ZOOM.zoomToExtent(bounds);touchDispatchMouseEvents
function(event, bubbleEvnt)helper# Turns a single-touch event (native touch or HammerJS pan/tap) into the equivalent mouse event — touchstart/panstart/tap → mousedown, touchmove/panmove → mousemove, …
touchDispatchMouseEventsWritten as ExtjsUtils.touchDispatchMouseEvents
Turns a single-touch event (native touch or HammerJS pan/tap) into the equivalent mouse event — touchstart/panstart/tap → mousedown, touchmove/panmove → mousemove, touchend/panend → mouseup — and dispatches it on the touched element, so code written for the mouse also reacts to touch. The original touch event is cancelled and stopped. Multi-touch gestures and events coming from a real mouse are left untouched.
- event TouchEvent|Object
- The touch (or HammerJS) event to convert.
- bubbleEvnt Boolean
trueto let the simulated mouse event bubble up towindow,falseto dispatch it on the target only.
ExtjsUtils.addDomListener(panelEl, 'touchstart', function(evt) {
ExtjsUtils.touchDispatchMouseEvents(evt, true);
});unifyHammerEvent
function(hammerJsEvt) : Objecthelper# Normalises a HammerJS (or native touch) event in place so it can be handled like an Ext/ OpenLayers pointer event: fills touches/changedTouches from pointers/changedPointers, renames pinch* …
unifyHammerEventWritten as ExtjsUtils.unifyHammerEvent
Normalises a HammerJS (or native touch) event in place so it can be handled like an Ext/ OpenLayers pointer event: fills touches/changedTouches from pointers/changedPointers, renames pinch* types to touch*, sets srcElement, computes the page position xy ([x, y], with an equals helper) and adds getXY() to the event and to its srcEvent.
- hammerJsEvt Object
- HammerJS event (or a native touch event) to normalise.
Returns The same event object, with the unified properties added.
hammer.on('panmove', function(evt) {
var xy = ExtjsUtils.unifyHammerEvent(evt).getXY(); // [pageX, pageY]
});ALERTIFY · messages and questions
Alertify10 entriesDISABLE_ALERT_NAME
String# Name of the stored option (COOKIE) that disables the notifications shown by Alertify.log; the "stop notifications" checkbox of the notification writes it and isEnabled/toggle read and write it.
DISABLE_ALERT_NAMEWritten as ExtjsUtils.ALERTIFY.DISABLE_ALERT_NAME
Name of the stored option (COOKIE) that disables the notifications shown by Alertify.log; the "stop notifications" checkbox of the notification writes it and isEnabled/toggle read and write it.
var muted = !!ExtjsUtils.COOKIE.readOption(ExtjsUtils.ALERTIFY.DISABLE_ALERT_NAME);SPAM
Object# Spam filter used by Alertify.log: a message shown recently is not shown again until its spam time expires.
SPAMWritten as ExtjsUtils.ALERTIFY.SPAM
Spam filter used by Alertify.log: a message shown recently is not shown again until its spam time expires. Members: isSpamMsg(msg) returns true when msg was shown within its spam window; addMsgToSpam(msg, time) registers a message for time milliseconds (log uses config.spamTime, default 10 s); EXPIRE_DATE maps the md5 of each message to its expiry timestamp. Messages are keyed by md5, so the same text counts as the same message. (Alertify.alert also calls it, but without a time, so alerts are effectively never muted.)
if (!ExtjsUtils.ALERTIFY.SPAM.isSpamMsg(msg)) {
alertify.log(msg);
ExtjsUtils.ALERTIFY.SPAM.addMsgToSpam(msg, 30000); // mute repeats for 30 s
}alert
function(msg)helper# Shows an user non blocking alert.
alertWritten as ExtjsUtils.ALERTIFY.alert
Shows an user non blocking alert.
PS: If layer is loading only the last message will be shown after load end.
- msg String
- Notification HTML content.
confirmChoice
function(html, choices, onChoice, config)helper# Modal for one or more labeled choices.
confirmChoiceWritten as ExtjsUtils.ALERTIFY.confirmChoice
Modal for one or more labeled choices.
- 1 choice: invokes callback immediately (no modal).
- 2 choices: alertify.confirm with custom ok/cancel labels; both invoke onChoice.
- 3+ choices: alertify.confirm with a <select>; OK confirms selection;
Cancel invokes config.onCancel when provided. Selecting an option auto-clicks OK
when config.autoConfirmOnSelect is not false (default true).
- html String
- Message HTML.
- choices Array.<(String|{label:String, value: *})>
- Option labels or {label,value} objects.
- onChoice function
- function(value, index, choice) for a picked option.
- config Object
- Optional: okLabel, cancelLabel, onCancel, autoConfirmOnSelect.
isEnabled
function() : Booleanhelper# Tells whether notifications (Alertify.log) are enabled for this browser, i.e. the user has not ticked "stop notifications" (stored under DISABLE_ALERT_NAME).
isEnabledWritten as ExtjsUtils.ALERTIFY.isEnabled
Tells whether notifications (Alertify.log) are enabled for this browser, i.e. the user has not ticked "stop notifications" (stored under DISABLE_ALERT_NAME).
Returns True when notifications are enabled, false when the user disabled them.
if (!ExtjsUtils.ALERTIFY.isEnabled()) ExtjsUtils.ALERTIFY.log("Important!", {force: true});isMapLoaded
function() : Booleanhelper# Tells whether the map has finished loading, i.e. whether log shows notifications immediately instead of queueing them.
isMapLoadedWritten as ExtjsUtils.ALERTIFY.isMapLoaded
Tells whether the map has finished loading, i.e. whether log shows notifications immediately instead of queueing them.
Returns True once setMapLoaded was called, false before.
if (ExtjsUtils.ALERTIFY.isMapLoaded()) ExtjsUtils.ALERTIFY.log("Data refreshed.");log
function(msg, config)helper# Shows an user notification (if enabled).
logWritten as ExtjsUtils.ALERTIFY.log
Shows an user notification (if enabled).
PS: The messages before layer loading are delayed, when it finishes only the last message will be shown.
- msg String
- The message that will be displayed in the alert. It can be in HTML format.
- config Object
- Configuration parameters for the message. { force: {Boolean} Force to show notification even when disabled. func: {Callback} Callback function when the notification is clicked. onlyMsg: {Boolean} True to only show message and hide the close and the stop notifications, False otherwise. delay: {Numeric} Amout of time in milisseconds before the message hide. spamTime: {Numeric} Time the same message to be shown again is considered spam. (even with force = true). }
removePageLoader
function()helper# Fades out and removes the page loading overlay (#loader-container).
removePageLoaderWritten as ExtjsUtils.ALERTIFY.removePageLoader
Fades out and removes the page loading overlay (#loader-container). Called by setMapLoaded; call it directly only when the platform's own loading flow is bypassed.
ExtjsUtils.ALERTIFY.removePageLoader();setMapLoaded
function()helper# Marks the map as loaded: flushes the notifications queued by log while the map was loading (only the last one is effectively visible, as one notification is shown at a time) and removes the page loader.
setMapLoadedWritten as ExtjsUtils.ALERTIFY.setMapLoaded
Marks the map as loaded: flushes the notifications queued by log while the map was loading (only the last one is effectively visible, as one notification is shown at a time) and removes the page loader. The platform calls it when the query finishes loading; query code does not normally need to.
ExtjsUtils.ALERTIFY.setMapLoaded();toggle
function(state)helper# Enables or disables the notifications shown by Alertify.log for this browser (the setting is persisted with COOKIE).
toggleWritten as ExtjsUtils.ALERTIFY.toggle
Enables or disables the notifications shown by Alertify.log for this browser (the setting is persisted with COOKIE). Without an argument the current state is inverted. Messages logged with {force: true} are still shown when disabled.
- state Boolean
- True to enable, false to disable; omit to invert.
ExtjsUtils.ALERTIFY.toggle(false); // silence the platform notifications in this queryASSYNC · async loops
ASSYNC3 entriesUsage: ExtjsUtils.ASSYNC
filter
function(arrayLike, asyncFunction) : Promise.<Array>helper# Array.filter for async predicates, run sequentially: the predicate of each element is awaited before the next element is tested.
filterWritten as ExtjsUtils.ASSYNC.filter
Array.filter for async predicates, run sequentially: the predicate of each element is awaited before the next element is tested.
- arrayLike Array
- Array (or array-like) to iterate.
- asyncFunction function
async function(element, index)resolving to a truthy value to keep the element.
Returns Resolves to the elements that passed the predicate, in order.
var valid = await ExtjsUtils.ASSYNC.filter(layers, async function(layer) {
return await layerHasData(layer);
});map
function(arrayLike, asyncFunction) : Promise.<Array>helper# Array.map for async callbacks, run sequentially: each element waits for the previous callback's promise before the next one starts (unlike Promise.all(map(...)), which starts them all at once).
mapWritten as ExtjsUtils.ASSYNC.map
Array.map for async callbacks, run sequentially: each element waits for the previous callback's promise before the next one starts (unlike Promise.all(map(...)), which starts them all at once). Use it to process items one at a time, e.g. a request per element.
- arrayLike Array
- Array (or array-like) to iterate.
- asyncFunction function
async function(element, index)returning the mapped value (or a promise of it).
Returns Resolves to the mapped values, in order.
var areas = await ExtjsUtils.ASSYNC.map(features, async function(f) {
return await fetchAreaFor(f.attributes.code);
});reduce
function(arrayLike, asyncFunction, defaultVal) : Promise.<*>helper# Array.reduce for async reducers, run sequentially: each call receives the awaited result of the previous one.
reduceWritten as ExtjsUtils.ASSYNC.reduce
Array.reduce for async reducers, run sequentially: each call receives the awaited result of the previous one.
- arrayLike Array
- Array (or array-like) to iterate.
- asyncFunction function
async function(accumulator, element, index)returning the next accumulator.- defaultVal *
- Initial accumulator value.
Returns Resolves to the final accumulator.
var total = await ExtjsUtils.ASSYNC.reduce(codes, async function(sum, code) {
return sum + await fetchAreaFor(code);
}, 0);CHECK · type and browser checks
CHECK13 entriesUsage: ExtjsUtils.CHECK
browserSupported
function() : Booleanhelper# Tells whether the browser has everything the map calculations need: Web Workers, typed arrays (Uint8Array) and a WebGL context.
browserSupportedWritten as ExtjsUtils.CHECK.browserSupported
Tells whether the browser has everything the map calculations need: Web Workers, typed arrays (Uint8Array) and a WebGL context.
Returns True on a supported browser, false otherwise.
if (!ExtjsUtils.CHECK.browserSupported()) ExtjsUtils.ALERTIFY.alert("Your browser cannot run this map.");hasWebWorker
function() : Booleanhelper# Tells whether the browser supports Web Workers.
hasWebWorkerWritten as ExtjsUtils.CHECK.hasWebWorker
Tells whether the browser supports Web Workers.
Returns True when window.Worker exists, false otherwise.
if (!ExtjsUtils.CHECK.hasWebWorker()) ExtjsUtils.ALERTIFY.log("Calculations will run in the main thread.");isArray
function(arg) : Booleanhelper# Tells whether a value is an array (Ext.isArray).
isArrayWritten as ExtjsUtils.CHECK.isArray
Tells whether a value is an array (Ext.isArray).
- arg *
- Value to check.
Returns True when arg is an array, false otherwise.
var list = ExtjsUtils.CHECK.isArray(value) ? value : [value];isChrome
function() : Booleanhelper# Tells whether the browser is Google Chrome (Ext.isChrome).
isChromeWritten as ExtjsUtils.CHECK.isChrome
Tells whether the browser is Google Chrome (Ext.isChrome).
Returns True on Chrome, false otherwise.
if (ExtjsUtils.CHECK.isChrome()) enableWebGLExtras();isColor
function(arg) : Booleanhelper# Tells whether a string is a valid CSS colour (#rgb, rgb(...), a colour name, ...), using the browser's own parser.
isColorWritten as ExtjsUtils.CHECK.isColor
Tells whether a string is a valid CSS colour (#rgb, rgb(...), a colour name, ...), using the browser's own parser.
- arg String
- Colour to validate.
Returns True when the browser accepts the string as a colour.
ExtjsUtils.CHECK.isColor("#ff8800"); // trueisFunction
function(obj) : Booleanhelper# Tells whether a value is a function.
isFunctionWritten as ExtjsUtils.CHECK.isFunction
Tells whether a value is a function.
- obj *
- Value to check.
Returns True when obj is a function, false otherwise.
if (ExtjsUtils.CHECK.isFunction(config.onClick)) config.onClick(feature);isFunctionString
function(str) : Booleanhelper# Tells whether a string holds JavaScript source that evaluates to a function (e.g. "function(a) { return a; }" or "a => a"), as stored in serialized layer definitions.
isFunctionStringWritten as ExtjsUtils.CHECK.isFunctionString
Tells whether a string holds JavaScript source that evaluates to a function (e.g. "function(a) { return a; }" or "a => a"), as stored in serialized layer definitions. The string is evaluated with new Function, so only pass trusted text.
- str String
- Source text to test.
Returns True when the text evaluates to a function, false otherwise (including syntax errors).
ExtjsUtils.CHECK.isFunctionString("function(inputs) { return 1; }"); // trueisMobile
function(strict) : Booleanhelper# Device-based mobile test: true when the browser exposes window.orientation (phones and tablets), optionally restricted to small screens.
isMobileWritten as ExtjsUtils.CHECK.isMobile
Device-based mobile test: true when the browser exposes window.orientation (phones and tablets), optionally restricted to small screens. It does not change when the window is resized. This is different from MOBILE_UTILS.isMobile(), which follows the responsive CSS media query (viewport narrower than 768px) and therefore tells whether the mobile layout is currently active — use that one for layout decisions. Idea taken from Leaflet's Browser.js.
- strict Boolean
- True to also require a small screen (
screen.width + screen.height < 800).
Returns True on a mobile device, false otherwise.
var touchDevice = ExtjsUtils.CHECK.isMobile();
var mobileLayout = MOBILE_UTILS.isMobile();isObject
function(obj, acceptNullAsObject) : Booleanhelper# Tells whether a value is of type "object" (plain objects, arrays, dates...).
isObjectWritten as ExtjsUtils.CHECK.isObject
Tells whether a value is of type "object" (plain objects, arrays, dates...). null also has type "object" in JavaScript, so it is rejected unless acceptNullAsObject is true.
- obj *
- Value to check.
- acceptNullAsObject Boolean
- True to also accept
null.
Returns True when obj is an object (and not null, unless accepted).
if (ExtjsUtils.CHECK.isObject(config)) Ext.apply(defaults, config);isOlderBrowser
function() : Booleanhelper# Tells whether the browser is an old one (roughly before 2014) by checking for Element.prototype.remove.
isOlderBrowserWritten as ExtjsUtils.CHECK.isOlderBrowser
Tells whether the browser is an old one (roughly before 2014) by checking for Element.prototype.remove. Returns false on Chrome 23+, Edge 12+, Firefox 23+, Opera 15+ and Safari 7+; a false result does not guarantee full support (see browserSupported).
Returns True on an old browser, false otherwise.
if (ExtjsUtils.CHECK.isOlderBrowser()) ExtjsUtils.ALERTIFY.alert("Please update your browser.");isString
function(arg) : Booleanhelper# Tells whether a value is a string (primitive or String object).
isStringWritten as ExtjsUtils.CHECK.isString
Tells whether a value is a string (primitive or String object).
- arg *
- Value to check.
Returns True when arg is a string, false otherwise.
var col = ExtjsUtils.CHECK.isString(column) ? csv.columnNameToInd(column) : column;isWebkit
function() : Booleanhelper# Tells whether the browser is WebKit based (Chrome, Safari...; Ext.isWebKit).
isWebkitWritten as ExtjsUtils.CHECK.isWebkit
Tells whether the browser is WebKit based (Chrome, Safari...; Ext.isWebKit).
Returns True on a WebKit browser, false otherwise.
var cssPrefix = ExtjsUtils.CHECK.isWebkit() ? "-webkit-" : "";msieversion
function() : Booleanhelper# Tells whether the browser is Internet Explorer (any version, including IE 11).
msieversionWritten as ExtjsUtils.CHECK.msieversion
Tells whether the browser is Internet Explorer (any version, including IE 11).
Returns Truthy on Internet Explorer, false otherwise.
if (ExtjsUtils.CHECK.msieversion()) ExtjsUtils.ALERTIFY.alert("Please use a modern browser.");COMPONENTS · row button builders
COMPONENTS1 entrycreateAssociatedButton
function(btnConfig, defaultProperties) : Ext.Buttonhelper# Creates an Ext.Button that mirrors another button or checkbox of the interface — the "associated button" behind paramsButtonConfig entries with an associatedButtonID.
createAssociatedButtonWritten as ExtjsUtils.COMPONENTS.createAssociatedButton
Creates an Ext.Button that mirrors another button or checkbox of the interface — the "associated button" behind paramsButtonConfig entries with an associatedButtonID. The original component is looked up by id (btnConfig.associatedButtonID, a string or a function returning it) after render; when it is a toggle button or a checkbox the new button becomes a toggle kept in sync both ways, otherwise clicking the new button triggers the original's handler/click. Your own toggleHandler/handler in btnConfig replace the syncing ones. The platform calls this for the legend window; a query may call it to place such a button in its own HTML.
- btnConfig Object
Ext.Buttonconfig:associatedButtonIDplus any button option (text,iconCls,tooltip,pressed,enableToggle,handler,toggleHandler...). Its values win overdefaultProperties.- defaultProperties Object
- Defaults applied before
btnConfig(typicallypressed,toggleGroup,cls,iconCls); any key present inbtnConfigoverrides them.
Returns The new button, not yet rendered; add it to a container or call render.
var mirror = ExtjsUtils.COMPONENTS.createAssociatedButton({
associatedButtonID: 'property_pick', // id of an existing toggle button
text: 'Pick a point'
}, { iconCls: 'gxp-icon-getfeatureinfo' });
mirror.render('my-toolbar-div');COOKIE · saved user options
COOKIE7 entriesUsage: ExtjsUtils.COOKIE
INTRO_START
String# Reserved option name ("mp_intro") for remembering that the intro tour was already shown in this browser.
INTRO_STARTWritten as ExtjsUtils.COOKIE.INTRO_START
Reserved option name ("mp_intro") for remembering that the intro tour was already shown in this browser. The platform does not set it by itself; use it from query code to show a tour only once.
if (!ExtjsUtils.COOKIE.readOption(ExtjsUtils.COOKIE.INTRO_START)) {
ExtjsUtils.INTROJS.loadAndRun();
ExtjsUtils.COOKIE.saveOption(ExtjsUtils.COOKIE.INTRO_START, 1);
}NAME
String# Store name derived from the page path ("MAPSERVER_" + pathname without slashes), a ready-made prefix for options that must not be shared between pages of the same host.
NAMEWritten as ExtjsUtils.COOKIE.NAME
Store name derived from the page path ("MAPSERVER_" + pathname without slashes), a ready-made prefix for options that must not be shared between pages of the same host. The platform itself does not read it: options are stored under the names given to saveOption.
ExtjsUtils.COOKIE.saveOption(ExtjsUtils.COOKIE.NAME + "_seen_tip", 1);TRY_HTTPS
String# Option name ("mp_no_https") under which REQUEST.tryHttps records that the HTTPS redirect was already attempted in this browser.
TRY_HTTPSWritten as ExtjsUtils.COOKIE.TRY_HTTPS
Option name ("mp_no_https") under which REQUEST.tryHttps records that the HTTPS redirect was already attempted in this browser.
deleteOption
function(cname)helper# Removes a stored option.
deleteOptionWritten as ExtjsUtils.COOKIE.deleteOption
Removes a stored option. Fires COOKIE.events change (with value: null) when there was a non-empty value to remove.
- cname String
- Name of the option to remove.
ExtjsUtils.COOKIE.deleteOption("myquery_hide_welcome");events
Ext.util.Observable# Observable that fires change after an option is saved or deleted.
eventsWritten as ExtjsUtils.COOKIE.events
Observable that fires change after an option is saved or deleted. The listener receives {type: 'save', name, value} (value is null on delete). Use it to react to settings changed elsewhere in the interface, e.g. the notifications toggle.
ExtjsUtils.COOKIE.events.on("change", function(evt) {
if (evt.name === ExtjsUtils.ALERTIFY.DISABLE_ALERT_NAME) console.log("alerts toggled");
});readOption
function(cname) : String|nullhelper# Reads a stored option.
readOptionWritten as ExtjsUtils.COOKIE.readOption
Reads a stored option. Values always come back as strings: a "false" saved through saveOption is the empty string "" and a "true" is "1", so if (readOption(name)) works; avoid storing a literal "0", which is truthy as a string.
- cname String
- Name of the option to read.
Returns The stored string, or null/undefined when the option was never saved.
if (!ExtjsUtils.COOKIE.readOption("myquery_hide_welcome")) {
ExtjsUtils.ALERTIFY.log("Welcome! Click a municipality to see its fire history.");
}saveOption
function(cname, cvalue)helper# Persists a user option in the browser (localStorage) under cname, replacing any previous value, and fires COOKIE.events change when the value actually changed.
saveOptionWritten as ExtjsUtils.COOKIE.saveOption
Persists a user option in the browser (localStorage) under cname, replacing any previous value, and fires COOKIE.events change when the value actually changed. Booleans are normalized: true/1 are stored as "1" and false/0 as "", so readOption can be used directly in a condition. null/undefined are not allowed. Typical use: "don't show this again" preferences.
- cname String
- Option name.
- cvalue String|Number|Boolean
- Value to store (kept as a string).
ExtjsUtils.COOKIE.saveOption("myquery_hide_welcome", true);COORDINATE · mouse position to lon/lat
COORDINATE2 entriesUsage: ExtjsUtils.COORDINATE
getLatLong
function(xy, fromProj) : OpenLayers.LonLathelper# Converts a pixel position on the map viewport into a map coordinate (OpenLayers.LonLat).
getLatLongWritten as ExtjsUtils.COORDINATE.getLatLong
Converts a pixel position on the map viewport into a map coordinate (OpenLayers.LonLat). Accepts either an OpenLayers/Ext mouse event (its xy pixel is used) or a plain {x, y} pixel object. The result is in the map projection; pass fromProj to get it transformed into that projection instead (e.g. "EPSG:4326" for longitude/latitude).
- xy MouseEvent|Object
- A mouse event carrying an
xypixel, or a{x, y}pixel position relative to the map viewport. - fromProj String|OpenLayers.Projection
- Projection to transform the result into; omit to keep the map projection.
Returns The map coordinate under the pixel.
// Longitude/latitude under the mouse, from an OpenLayers click event
app.mapPanel.map.events.register('click', null, function(evt) {
var lonLat = ExtjsUtils.COORDINATE.getLatLong(evt, "EPSG:4326");
console.log(lonLat.lon, lonLat.lat);
});getLineEquations
function(polygonFeature) : Array.<Object>helper# Computes the line equation of every edge of a polygon feature (each consecutive pair of vertices, closing back to the first).
getLineEquationsWritten as ExtjsUtils.COORDINATE.getLineEquations
Computes the line equation of every edge of a polygon feature (each consecutive pair of vertices, closing back to the first). Each edge is described as y = A*x + B by an object {A, B, x, y} — A the slope, B the intercept, x and y the [start, end] coordinates of the segment. The returned array also carries two helpers: getLineX(y, edge) and getLineY(x, edge), which solve the equation for one edge and handle vertical (A === Infinity) and horizontal (A === 0) segments. Used by the polygon rasterisation that finds the pixels of a layer inside a drawn area.
- polygonFeature OpenLayers.Feature.Vector
- Feature whose polygon geometry is processed.
Returns One {A, B, x, y} object per edge, plus the getLineX/getLineY helper functions attached to the array.
var edges = ExtjsUtils.COORDINATE.getLineEquations(drawnFeature);
var xAtY = edges.getLineX(-2300000, edges[0]); // x where the first edge crosses that yCSS · query stylesheet rules
CSS6 entriesUsage: ExtjsUtils.CSS
defineClass
function(selector, rules)helper# Adds a CSS rule to the query's dynamic stylesheet — the main way a query restyles the interface (hide the top bar, recolour the legend, style its own HTML).
defineClassWritten as ExtjsUtils.CSS.defineClass
Adds a CSS rule to the query's dynamic stylesheet — the main way a query restyles the interface (hide the top bar, recolour the legend, style its own HTML). The selector is any CSS selector and doubles as the rule's unique key: defining the same selector again replaces the previous rule. The rule is tracked and removed when another query loads, so the styling never leaks between queries; the page's static CSS is only overridden, never changed. Does nothing while the query is only being evaluated (justEval mode). QUERY.decorate forwards every key that is not header, footer or run to this function, so decorate({ '#topbar': 'display: none;' }) is the same call.
- selector String
- CSS selector the rule applies to, e.g.
'#topbar'or'.legend-title, .legend-value'. Treated as an opaque key: no lookup is performed. - rules String|Object
- The declarations only (no braces): a string such as
"background-color: green; color: white;", or an object{ 'background-color': 'green', color: 'white' }.
ExtjsUtils.CSS.defineClass('#topbar', 'background-color: #1a4d2e;');
ExtjsUtils.CSS.defineClass('.my-popup', { position: 'absolute', 'z-index': 10000, padding: '8px' });hasClass
function(selector) : Booleanhelper# Tells whether a rule with exactly this selector exists in the query's dynamic stylesheet (i.e. was added with defineClass and not removed).
hasClassWritten as ExtjsUtils.CSS.hasClass
Tells whether a rule with exactly this selector exists in the query's dynamic stylesheet (i.e. was added with defineClass and not removed). The selector is compared as a whole string; a comma-separated selector list is not split.
- selector String
- The selector used in
defineClass.
Returns true when the rule exists, false otherwise.
if (!ExtjsUtils.CSS.hasClass('#topbar')) ExtjsUtils.CSS.defineClass('#topbar', 'display: none;');importExternalCss
function(cssFile, id, shouldClear)helper# Loads an external stylesheet by appending a <link rel="stylesheet"> to the page head — for instance a font or an icon set the query's HTML needs.
importExternalCssWritten as ExtjsUtils.CSS.importExternalCss
Loads an external stylesheet by appending a <link rel="stylesheet"> to the page head — for instance a font or an icon set the query's HTML needs. By default the link is tagged so it is removed when another query loads (like the rules of defineClass); pass shouldClear = false to keep it. Does nothing while the query is only being evaluated.
- cssFile String
- URL of the CSS file.
- id String
idto give the generated<link>element.- shouldClear Boolean
trueto remove the stylesheet when another query loads;falseto keep it permanently.
ExtjsUtils.CSS.importExternalCss('https://fonts.googleapis.com/css?family=Roboto', 'roboto-font');removeAllClasses
function()helper# Removes every dynamic CSS rule (defineClass) and every stylesheet imported with importExternalCss that was left removable.
removeAllClassesWritten as ExtjsUtils.CSS.removeAllClasses
Removes every dynamic CSS rule (defineClass) and every stylesheet imported with importExternalCss that was left removable. The platform calls it when another query loads (QUERY.clearQueryGlobalProperties); a query may call it to reset its own styling.
ExtjsUtils.CSS.removeAllClasses();removeClass
function(selector)helper# Removes the rule(s) with exactly this selector from the query's dynamic stylesheet, undoing a defineClass.
removeClassWritten as ExtjsUtils.CSS.removeClass
Removes the rule(s) with exactly this selector from the query's dynamic stylesheet, undoing a defineClass. The selector is the rule's key (compared as a whole string). Only dynamic rules are affected — the page's static CSS is never changed. Does nothing when the selector is not defined.
- selector String
- The selector used in
defineClass.
ExtjsUtils.CSS.defineClass('#topbar', 'display: none;');
// ...later, show the top bar again
ExtjsUtils.CSS.removeClass('#topbar');runAnimation
function(elm, animationCls, callback, scope)helper# Starts a CSS animation on an element by adding the class that defines it, then forces a redraw so the animation actually plays, and runs an optional callback right after it starts (about 10 ms later).
runAnimationWritten as ExtjsUtils.CSS.runAnimation
Starts a CSS animation on an element by adding the class that defines it, then forces a redraw so the animation actually plays, and runs an optional callback right after it starts (about 10 ms later). The class stays on the element; running different animations with the same class gives unexpected results.
- elm Ext.Element
- Element to animate (an
Ext.Element, e.g.Ext.get('id')). - animationCls String
- CSS class whose rules define the animation.
- callback function
- Called once the animation has started.
- scope Object
thisfor the callback.
ExtjsUtils.CSS.defineClass('.blink', 'animation: blink 1s 3;');
ExtjsUtils.CSS.runAnimation(Ext.get('legend-entry-3'), 'blink');CSV · read and join tables
CSV3 entriesUsage: ExtjsUtils.CSV
CsvTable
function(matrix)helper# Constructor of the table object that wraps a parsed CSV matrix (header row first) and offers lookups by column name, filtering and indexing: new ExtjsUtils.CSV.CsvTable(matrix).
CsvTableWritten as ExtjsUtils.CSV.CsvTable
Constructor of the table object that wraps a parsed CSV matrix (header row first) and offers lookups by column name, filtering and indexing: new ExtjsUtils.CSV.CsvTable(matrix). The {{loadcsv|id=x|url=...}} widget returns one of these at inputs.id["x"]; its methods (getLines, getValue, columnNameToInd, createIndexes, getColunsInd, ...) are documented under Tools > LoadCsv. Build one yourself to wrap a CSV you fetched or joined with CSV.joinCSV.
- matrix Array.<Array.<String>>
- Rows of the CSV, the first row being the header (e.g. the output of
ParseCSV).
var table = new ExtjsUtils.CSV.CsvTable(ParseCSV(xhr.responseText));
var iYear = table.columnNameToInd("Year");
var rows2024 = table.getLines([iYear], [2024]);joinCSV
function(csvA, csvB, columnsA, columnsB) : Array.<Array.<String>>helper# Joins two CSV matrices (arrays of rows) on the values of the given key columns: every row of A is kept, in order, followed by the columns of its matching B row minus the key columns of B.
joinCSVWritten as ExtjsUtils.CSV.joinCSV
Joins two CSV matrices (arrays of rows) on the values of the given key columns: every row of A is kept, in order, followed by the columns of its matching B row minus the key columns of B. Example: A ["title", "value", "index"] and B ["Total", "Category", "Data"] joined with [2], [1] give ["title", "value", "index", "Total", "Data"]. Rows of A without a match are not padded reliably (they receive the cells of the previously matched row, or a single undefined cell for the first row), so make sure every key of A exists in B — header rows included, when both matrices carry one. Wrap the result in new ExtjsUtils.CSV.CsvTable(...) to query it.
- csvA Array.<Array.<String>>
- Rows of table A (header included when both tables have one).
- csvB Array.<Array.<String>>
- Rows of table B.
- columnsA Array.<Number>
- Indexes of the key columns of A.
- columnsB Array.<Number>
- Indexes of the matching key columns of B (same order as
columnsA).
Returns The joined rows.
var legend = inputs.id["legend_csv"].getLines(undefined, undefined, true); // with header
var areas = inputs.id["area_csv"].getLines(undefined, undefined, true);
var joined = new ExtjsUtils.CSV.CsvTable(ExtjsUtils.CSV.joinCSV(legend, areas, [0], [1]));readMapCsvToMatrix
function(csvContent, qntMaps) : Array.<Array.<Number>>helper# Parses a "category, value" CSV produced by a cross-tabulation of maps into a nested numeric matrix.
readMapCsvToMatrixWritten as ExtjsUtils.CSV.readMapCsvToMatrix
Parses a "category, value" CSV produced by a cross-tabulation of maps into a nested numeric matrix. Each pair of digits of the category code is one (1-based) map class index, read from the right: 201 is [02, 01], 1001 is [10, 01], so the value of line 201, 166311249 ends up at matrix[0][1] (class 1 of the last map, class 2 of the previous one). The header line is skipped. CSV format:
Category, Value
201, 166311249
205, 12311
1001, 83696
- csvContent String
- Raw CSV text.
- qntMaps Number
- Number of maps (digit pairs) in the category code; when omitted, the number of non-empty columns of the header line.
Returns Nested matrix indexed by the class of each map (0-based).
var matrix = ExtjsUtils.CSV.readMapCsvToMatrix(xhr.responseText, 2);
var area = matrix[0][1]; // value of category "0201" (last map class 1, first map class 2)DOMHelper · page elements
DOMHelper2 entriesUsage: ExtjsUtils.DOMHelper
isDescendant
function(parent, child) : Booleanhelper# Tells whether the DOM element child is inside parent (at any depth).
isDescendantWritten as ExtjsUtils.DOMHelper.isDescendant
Tells whether the DOM element child is inside parent (at any depth). Typical use: in a timer that auto-closes a floating popup, check whether the element last hovered by the mouse is still part of the popup before hiding it.
- parent HTMLElement
- Candidate ancestor element.
- child HTMLElement
- Element to test.
Returns true when child is contained in parent, false otherwise.
var popup = document.getElementById('info-popup');
if (!ExtjsUtils.DOMHelper.isDescendant(popup, window.lastHoveredElement)) {
popup.style.display = 'none';
}removeElement
function(element)helper# Removes an element from the DOM together with all its children (old IE left the children behind).
removeElementWritten as ExtjsUtils.DOMHelper.removeElement
Removes an element from the DOM together with all its children (old IE left the children behind). Accepts a plain DOM element or an Ext.Element (its dom is used). Does nothing when the element is not attached to the document.
- element HTMLElement|Ext.Element
- Element to remove completely.
ExtjsUtils.DOMHelper.removeElement(document.getElementById('my-popup'));EVENTS · event lifecycles
EVENTS1 entryUsage: ExtjsUtils.EVENTS
monExtOL
function(extObject, openlayersObj, evtNameOL, callback, scope)helper# Registers a listener on an OpenLayers object (map, layer, control...) that is automatically unregistered when the given Ext component is destroyed — the OpenLayers counterpart of Ext's mon, which …
monExtOLWritten as ExtjsUtils.EVENTS.monExtOL
Registers a listener on an OpenLayers object (map, layer, control...) that is automatically unregistered when the given Ext component is destroyed — the OpenLayers counterpart of Ext's mon, which does not work with OpenLayers event objects. Use it when a window or panel you create reacts to map events, so the handler does not outlive the component.
- extObject Ext.Component
- Ext component whose
destroyevent removes the listener. - openlayersObj Object
- OpenLayers object exposing
events(e.g. the map or a layer). - evtNameOL String
- OpenLayers event name (e.g.
'moveend','visibilitychanged'). - callback function
- Listener called with the OpenLayers event.
- scope Object
thisfor the callback.
var win = new Ext.Window({ title: 'Map info', html: '' });
ExtjsUtils.EVENTS.monExtOL(win, app.mapPanel.map, 'moveend', function() {
win.body.update('Zoom: ' + app.mapPanel.map.getZoom());
});FEATURE · build vector features
FEATURE1 entryUsage: ExtjsUtils.FEATURE
fromGeometry
function(geometry, attrSource, options) : OpenLayers.Feature.Vectorhelper# Build a Vector from a geometry, taking user attributes from sourceFeature.
fromGeometryWritten as ExtjsUtils.FEATURE.fromGeometry
Build a Vector from a geometry, taking user attributes from sourceFeature. Optionally copies OpenLayers id / fid so list↔map identity survives rebuilds.
- geometry OpenLayers.Geometry
- Geometry of the new feature.
- attrSource OpenLayers.Feature.Vector
- Attr (and id) source; omit for a brand-new feature.
- options Object
- Optional behaviour switches.
- options.attributes Object
- Explicit attrs (skips cloning from source).
- options.copyId Boolean
- Copy id/fid when
sourceFeatureis set.
Returns The new feature.
layer.addFeatures([ExtjsUtils.FEATURE.fromGeometry(newGeom, oldFeature)]);
ExtjsUtils.FEATURE.fromGeometry(newGeom, oldFeature, { copyId: false });GEOJSON · GeoJSON and shapefiles
GEOJSON3 entriesgeojson2Features
function(geojson, fromProj, toProj) : Array.<OpenLayers.Feature>helper# Parse Geojson to Layer.Feature.
geojson2FeaturesWritten as ExtjsUtils.GEOJSON.geojson2Features
Parse Geojson to Layer.Feature.
PS: fromProj is resolved by GEOJSON.getGeojsonProjection (GeoJSON crs, then
the query/URL defaultFromProj, then CONFIGURATION.DEFAULT_FROM_PROJ). PS2: toProj defaults to the map projection (EPSG:900913). PS3: CRS outside EPSG:4326 / EPSG:3857 (e.g. SIRGAS EPSG:4674) requires
PROJECTION.setProjectionOptions().
- geojson Object|Array.<Object>
- Geojson object or array of objects.
- fromProj String
- Original projection of Geojson object.
- toProj String
- To projection of Geojson object.
Returns Returns the array of parsed Features.
getGeojsonProjection
function(geojson, defaultFromProj) : String|nullhelper# Resolve source projection from a parsed GeoJSON object.
getGeojsonProjectionWritten as ExtjsUtils.GEOJSON.getGeojsonProjection
Resolve source projection from a parsed GeoJSON object. OpenLayers.Format.GeoJSON.read does not read crs; geojson2Features only consults crs when fromProj is omitted. Checks top-level crs, then defaultFromProj, then the query/URL defaultFromProj setting, then CONFIGURATION.DEFAULT_FROM_PROJ (EPSG:900913) unless disabled.
- geojson Object
- Parsed GeoJSON
- defaultFromProj String
- Fallback when crs is absent
Returns EPSG code, or null when the default is disabled.
shapefile2GeojsonAsync
function(shpFile, paramOptions)helper# Parse shapefile to compatible Layer features.
shapefile2GeojsonAsyncWritten as ExtjsUtils.GEOJSON.shapefile2GeojsonAsync
Parse shapefile to compatible Layer features. DBF file is optional.
PS:ParamOptions
{
callback: {Function} called when the shapefile is parsed, as function(geojson, data) with this = paramOptions.layer (geojson: the parsed GeoJSON; data: the whole parse result),
fromProj: {String?} 'Projection name.' (EPSG:4326 or EPSG:900913),
dbf: (Optional?)'DBF file to load along with shapefile.',
limitCount: (Optional?)'Limit the amount of processed geometries'
}
- shpFile File
- Shapefile content (Needs to be in projection EPSG:4326 or EPSG:900913.
- paramOptions ParamOptions
- Additional configuration for handling shapefile. ParamOptions { callback: {Function} called when the shapefile is parsed, as function(geojson, data) with
this= paramOptions.layer (geojson: the parsed GeoJSON; data: the whole parse result), fromProj: {String?} 'Projection name.' (EPSG:4326 or EPSG:900913), dbf: (Optional?)'DBF file to load along with shapefile.', limitCount: (Optional?)'Limit the amount of processed geometries' }
GEOMETRY · union, intersection, validation
GEOMETRY45 entriescontains
function(aGeom, bGeom) : Booleanhelper# Tells whether aGeom contains bGeom entirely (no point of bGeom lies outside aGeom, and their interiors share at least one point).
containsWritten as ExtjsUtils.GEOMETRY.contains
Tells whether aGeom contains bGeom entirely (no point of bGeom lies outside aGeom, and their interiors share at least one point). A polygon does not contain a point on its own boundary — use covers for that. Both geometries are required. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Container geometry.
- bGeom OpenLayers.Geometry
- Geometry to test.
Returns True when aGeom contains bGeom.
var inside = ExtjsUtils.GEOMETRY.contains(municipality.geometry, clickedPoint);convexHull
function(aGeom) : OpenLayers.Geometryhelper# Smallest convex polygon containing the geometry.
convexHullWritten as ExtjsUtils.GEOMETRY.convexHull
Smallest convex polygon containing the geometry. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The convex hull (a Polygon; a Point/LineString for degenerate input).
var hull = ExtjsUtils.GEOMETRY.convexHull(multiPoint);coveredBy
function(aGeom, bGeom) : Booleanhelper# Tells whether aGeom is covered by bGeom (every point of aGeom lies inside or on the boundary of bGeom); the inverse of covers.
coveredByWritten as ExtjsUtils.GEOMETRY.coveredBy
Tells whether aGeom is covered by bGeom (every point of aGeom lies inside or on the boundary of bGeom); the inverse of covers. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry to test.
- bGeom OpenLayers.Geometry
- Covering geometry.
Returns True when bGeom covers aGeom.
var fullyInside = ExtjsUtils.GEOMETRY.coveredBy(property.geometry, biome.geometry);covers
function(aGeom, bGeom) : Booleanhelper# Tells whether aGeom covers bGeom: every point of bGeom lies inside or on the boundary of aGeom.
coversWritten as ExtjsUtils.GEOMETRY.covers
Tells whether aGeom covers bGeom: every point of bGeom lies inside or on the boundary of aGeom. Like contains, but true as well for a point on the boundary. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Covering geometry.
- bGeom OpenLayers.Geometry
- Geometry to test.
Returns True when aGeom covers bGeom.
var onOrInside = ExtjsUtils.GEOMETRY.covers(municipality.geometry, clickedPoint);crosses
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries cross: they share some but not all interior points and the intersection has a lower dimension than at least one of them (e.g. a line crossing a polygon boundary, two …
crossesWritten as ExtjsUtils.GEOMETRY.crosses
Tells whether the geometries cross: they share some but not all interior points and the intersection has a lower dimension than at least one of them (e.g. a line crossing a polygon boundary, two lines crossing at a point). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries cross.
var roadCrossesRiver = ExtjsUtils.GEOMETRY.crosses(road.geometry, river.geometry);difference
function(aGeom, bGeom) : OpenLayers.Geometry|nullhelper# Part of aGeom that is not covered by bGeom (A minus B).
differenceWritten as ExtjsUtils.GEOMETRY.difference
Part of aGeom that is not covered by bGeom (A minus B). Invalid polygons may throw a topology error — fix them with validate first. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry to subtract from.
- bGeom OpenLayers.Geometry
- Geometry to subtract.
Returns The difference, or null when nothing remains.
var outsideReserve = ExtjsUtils.GEOMETRY.difference(property.geometry, reserve.geometry);disjoint
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries have no point in common (the opposite of intersects).
disjointWritten as ExtjsUtils.GEOMETRY.disjoint
Tells whether the geometries have no point in common (the opposite of intersects). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries are disjoint.
var farApart = ExtjsUtils.GEOMETRY.disjoint(a.geometry, b.geometry);distance
function(aGeom, bGeom) : Numberhelper# Shortest distance between the two geometries (0 when they touch or intersect), in the units of their projection — map units for map geometries.
distanceWritten as ExtjsUtils.GEOMETRY.distance
Shortest distance between the two geometries (0 when they touch or intersect), in the units of their projection — map units for map geometries. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns The minimum distance in projection units.
var d = ExtjsUtils.GEOMETRY.distance(clickedPoint, river.geometry);equalsExact
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries are exactly equal: same type, same vertices in the same order (a strict, structural comparison).
equalsExactWritten as ExtjsUtils.GEOMETRY.equalsExact
Tells whether the geometries are exactly equal: same type, same vertices in the same order (a strict, structural comparison). Use equalsTopo for "same shape" and equalsNorm to ignore vertex order. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries are structurally identical.
var unchanged = ExtjsUtils.GEOMETRY.equalsExact(original.geometry, edited.geometry);equalsNorm
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries are exactly equal after normalizing both (canonical ring orientation, start vertex and part order), i.e. the same vertices regardless of their order.
equalsNormWritten as ExtjsUtils.GEOMETRY.equalsNorm
Tells whether the geometries are exactly equal after normalizing both (canonical ring orientation, start vertex and part order), i.e. the same vertices regardless of their order. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the normalized geometries are identical.
var sameRing = ExtjsUtils.GEOMETRY.equalsNorm(a.geometry, b.geometry);equalsTopo
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries are topologically equal — they cover the same set of points, even with different vertices (e.g. a square and the same square with an extra collinear vertex).
equalsTopoWritten as ExtjsUtils.GEOMETRY.equalsTopo
Tells whether the geometries are topologically equal — they cover the same set of points, even with different vertices (e.g. a square and the same square with an extra collinear vertex). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries represent the same shape.
var sameShape = ExtjsUtils.GEOMETRY.equalsTopo(a.geometry, b.geometry);findIntersecting
function(editedGeoms, candidateGeoms) : Array.<OpenLayers.Geometry>helper# Returns the candidates that intersect at least one of the edited geometries — e.g. to find which existing polygons a freshly drawn one overlaps before merging them.
findIntersectingWritten as ExtjsUtils.GEOMETRY.findIntersecting
Returns the candidates that intersect at least one of the edited geometries — e.g. to find which existing polygons a freshly drawn one overlaps before merging them. The check is safeIntersects (topology errors are tolerated); null entries are ignored and the original OpenLayers objects are returned. Requires the JSTS library.
- editedGeoms Array.<OpenLayers.Geometry>
- Geometries to test against (e.g. the ones just drawn or modified).
- candidateGeoms Array.<OpenLayers.Geometry>
- Geometries to filter.
Returns The entries of candidateGeoms intersecting any of editedGeoms.
var touched = ExtjsUtils.GEOMETRY.findIntersecting([drawnFeature.geometry],
layer.features.map(function(f) { return f.geometry; }));geomJstsToOl2
function(jstsGeoms) : OpenLayers.Geometry|Array.<OpenLayers.Geometry>helper# Converts a JSTS geometry (or array of geometries) back to its OpenLayers equivalent, via a WKT round-trip.
geomJstsToOl2Written as ExtjsUtils.GEOMETRY.geomJstsToOl2
Converts a JSTS geometry (or array of geometries) back to its OpenLayers equivalent, via a WKT round-trip. Empty JSTS geometries convert to null.
- jstsGeoms Object|Array.<Object>
- JSTS geometry or array of geometries to convert.
Returns The converted geometry (or array, matching the input shape); array entries are null for empty input geometries.
geomOl2ToJsts
function(olGeoms) : Object|Array.<Object>|nullhelper# Converts an OpenLayers geometry (or array of geometries) to its JSTS equivalent, via a WKT round-trip.
geomOl2ToJstsWritten as ExtjsUtils.GEOMETRY.geomOl2ToJsts
Converts an OpenLayers geometry (or array of geometries) to its JSTS equivalent, via a WKT round-trip. Requires the JSTS library to already be loaded (see GEOMETRY.loadAdvancedGeometryLibrary / the ?options=geom URL option).
- olGeoms OpenLayers.Geometry|Array.<OpenLayers.Geometry>
- Geometry or array of geometries to convert.
Returns The converted JSTS geometry (or array, matching the input shape), or null if conversion failed.
getArea
function(aGeom) : Numberhelper# Area of a geometry (0 for points and lines), computed by JTS in the units of the geometry's projection — squared map units (Web Mercator meters, distorted away from the equator) for geometries taken from the map.
getAreaWritten as ExtjsUtils.GEOMETRY.getArea
Area of a geometry (0 for points and lines), computed by JTS in the units of the geometry's projection — squared map units (Web Mercator meters, distorted away from the equator) for geometries taken from the map. Requires the JSTS library (see loadGeometryLibrary).
- aGeom OpenLayers.Geometry
- Geometry to measure.
Returns The area in squared projection units.
var areaM2 = ExtjsUtils.GEOMETRY.getArea(feature.geometry);getCentroid
function(aGeom) : OpenLayers.Geometryhelper# Centroid (center of mass) of a geometry — may fall outside a concave polygon; use getInteriorPoint for a point guaranteed to be inside.
getCentroidWritten as ExtjsUtils.GEOMETRY.getCentroid
Centroid (center of mass) of a geometry — may fall outside a concave polygon; use getInteriorPoint for a point guaranteed to be inside. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The centroid as an OpenLayers.Geometry.Point.
var center = ExtjsUtils.GEOMETRY.getCentroid(feature.geometry); // center.x, center.ygetEnvelope
function(aGeom) : OpenLayers.Geometryhelper# Bounding box of a geometry as a geometry: a rectangular Polygon (a Point or LineString for degenerate boxes).
getEnvelopeWritten as ExtjsUtils.GEOMETRY.getEnvelope
Bounding box of a geometry as a geometry: a rectangular Polygon (a Point or LineString for degenerate boxes). Use getEnvelopeInternal for the numeric bounds. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The envelope geometry.
var bboxPolygon = ExtjsUtils.GEOMETRY.getEnvelope(feature.geometry);getEnvelopeInternal
function(aGeom) : Objecthelper# Numeric bounding box of a geometry.
getEnvelopeInternalWritten as ExtjsUtils.GEOMETRY.getEnvelopeInternal
Numeric bounding box of a geometry. Unlike the other operations this returns the raw JTS object, a jsts.geom.Envelope with getMinX(), getMinY(), getMaxX(), getMaxY(), getWidth(), getHeight(); for an OpenLayers bounds object use geometry.getBounds() instead. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns A jsts.geom.Envelope.
var env = ExtjsUtils.GEOMETRY.getEnvelopeInternal(feature.geometry); // env.getMinX()getInteriorPoint
function(aGeom) : OpenLayers.Geometryhelper# A point guaranteed to lie inside the geometry (inside a polygon, on a line, one of the points of a multipoint) — the right anchor for a label or a popup, unlike the centroid.
getInteriorPointWritten as ExtjsUtils.GEOMETRY.getInteriorPoint
A point guaranteed to lie inside the geometry (inside a polygon, on a line, one of the points of a multipoint) — the right anchor for a label or a popup, unlike the centroid. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns An OpenLayers.Geometry.Point inside the geometry.
var anchor = ExtjsUtils.GEOMETRY.getInteriorPoint(feature.geometry);getLength
function(aGeom) : Numberhelper# Length of a line, or perimeter of a polygon (0 for points), in the units of the geometry's projection.
getLengthWritten as ExtjsUtils.GEOMETRY.getLength
Length of a line, or perimeter of a polygon (0 for points), in the units of the geometry's projection. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry to measure.
Returns The length in projection units.
var perimeter = ExtjsUtils.GEOMETRY.getLength(feature.geometry);getNumGeometries
function(aGeom) : Numberhelper# Number of component geometries: the parts of a multi-geometry or collection, 1 for a simple geometry.
getNumGeometriesWritten as ExtjsUtils.GEOMETRY.getNumGeometries
Number of component geometries: the parts of a multi-geometry or collection, 1 for a simple geometry. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns How many parts the geometry has.
var parts = ExtjsUtils.GEOMETRY.getNumGeometries(multiPolygon);getSRID
function(aGeom) : Numberhelper# Spatial reference id stored on the JTS geometry.
getSRIDWritten as ExtjsUtils.GEOMETRY.getSRID
Spatial reference id stored on the JTS geometry. Because every operation rebuilds the JTS geometry from WKT, this is always the JTS default (0): OpenLayers geometries carry no SRID and there is no way to set one through this API.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The SRID (0).
ExtjsUtils.GEOMETRY.getSRID(feature.geometry); // 0getUserData
function(aGeom) : *helper# User data stored on the JTS geometry.
getUserDataWritten as ExtjsUtils.GEOMETRY.getUserData
User data stored on the JTS geometry. Because every operation rebuilds the JTS geometry from WKT, this is always null: keep your data on the OpenLayers feature (feature.attributes) instead.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The user data (null).
ExtjsUtils.GEOMETRY.getUserData(feature.geometry); // nullintersection
function(aGeom, bGeom) : OpenLayers.Geometry|nullhelper# Common part of the two geometries (A and B).
intersectionWritten as ExtjsUtils.GEOMETRY.intersection
Common part of the two geometries (A and B). Invalid polygons may throw a topology error — fix them with validate first. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns The intersection, or null when the geometries do not overlap.
var overlap = ExtjsUtils.GEOMETRY.intersection(property.geometry, reserve.geometry);intersects
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries share at least one point (touching counts).
intersectsWritten as ExtjsUtils.GEOMETRY.intersects
Tells whether the geometries share at least one point (touching counts). Throws a topology error on invalid input — safeIntersects (on JSTS geometries) or findIntersecting tolerate that. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries intersect.
var hit = ExtjsUtils.GEOMETRY.intersects(drawnPolygon, feature.geometry);isGeometryCollection
function(aGeom) : Booleanhelper# Tells whether the geometry is a heterogeneous GeometryCollection (not a MultiPolygon/ MultiLineString/MultiPoint).
isGeometryCollectionWritten as ExtjsUtils.GEOMETRY.isGeometryCollection
Tells whether the geometry is a heterogeneous GeometryCollection (not a MultiPolygon/ MultiLineString/MultiPoint). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns True for a GeometryCollection.
if (ExtjsUtils.GEOMETRY.isGeometryCollection(geom)) geom = geom.components[0];isJstsGeometry
function(obj) : Booleanhelper# Tells whether a value is a JSTS geometry (duck-typed on getGeometryType, getBoundary and getEnvelopeInternal), as opposed to an OpenLayers geometry.
isJstsGeometryWritten as ExtjsUtils.GEOMETRY.isJstsGeometry
Tells whether a value is a JSTS geometry (duck-typed on getGeometryType, getBoundary and getEnvelopeInternal), as opposed to an OpenLayers geometry. Useful when a function accepts both, e.g. before deciding whether to call geomJstsToOl2.
- obj *
- Value to check.
Returns True for a JSTS geometry object.
var ol = ExtjsUtils.GEOMETRY.isJstsGeometry(g) ? ExtjsUtils.GEOMETRY.geomJstsToOl2(g) : g;isRectangle
function(aGeom) : Booleanhelper# Tells whether the geometry is an axis-aligned rectangle (a polygon with 5 vertices matching its envelope).
isRectangleWritten as ExtjsUtils.GEOMETRY.isRectangle
Tells whether the geometry is an axis-aligned rectangle (a polygon with 5 vertices matching its envelope). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns True for a rectangle.
var isBox = ExtjsUtils.GEOMETRY.isRectangle(drawnPolygon);isSimple
function(aGeom) : Booleanhelper# Tells whether the geometry is simple in the OGC sense — no self-intersections or repeated points (a line that crosses itself is not simple).
isSimpleWritten as ExtjsUtils.GEOMETRY.isSimple
Tells whether the geometry is simple in the OGC sense — no self-intersections or repeated points (a line that crosses itself is not simple). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns True when the geometry is simple.
if (!ExtjsUtils.GEOMETRY.isSimple(line)) ExtjsUtils.ALERTIFY.log("The line crosses itself.");isTopologyError
function(ex) : Booleanhelper# Tells whether an exception thrown by a geometry operation is a JTS TopologyException (invalid ring, self-intersection...), the kind of error that a zero-width buffer or validate usually fixes, as …
isTopologyErrorWritten as ExtjsUtils.GEOMETRY.isTopologyError
Tells whether an exception thrown by a geometry operation is a JTS TopologyException (invalid ring, self-intersection...), the kind of error that a zero-width buffer or validate usually fixes, as opposed to a programming error that should propagate.
- ex Error|Object
- The caught exception (anything falsy returns false).
Returns True when the exception is a topology error.
try {
result = ExtjsUtils.GEOMETRY.intersection(a, b);
} catch (ex) {
if (!ExtjsUtils.GEOMETRY.isTopologyError(ex)) throw ex;
result = ExtjsUtils.GEOMETRY.intersection(ExtjsUtils.GEOMETRY.validate(a, false), ExtjsUtils.GEOMETRY.validate(b, false));
}isValid
function(aGeom) : Booleanhelper# Tells whether the geometry is valid in the OGC sense (closed rings, no self-intersecting rings, holes inside the shell...).
isValidWritten as ExtjsUtils.GEOMETRY.isValid
Tells whether the geometry is valid in the OGC sense (closed rings, no self-intersecting rings, holes inside the shell...). Invalid polygons make the set operations throw topology errors — fix them with validate. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns True when the geometry is valid.
var geom = ExtjsUtils.GEOMETRY.isValid(drawn) ? drawn : ExtjsUtils.GEOMETRY.validate(drawn, false);loadAdvancedGeometryLibrary
function(callback) : Promise.<Boolean>helper# Loads the JSTS geometry library (/theme/app/js/jsts.min.js) once and resolves when it is available; every other GEOMETRY operation throws until it is loaded (the ?options=geom URL option loads it at startup).
loadAdvancedGeometryLibraryWritten as ExtjsUtils.GEOMETRY.loadAdvancedGeometryLibrary
Loads the JSTS geometry library (/theme/app/js/jsts.min.js) once and resolves when it is available; every other GEOMETRY operation throws until it is loaded (the ?options=geom URL option loads it at startup). An optional callback runs right after the load; when it returns a promise the returned promise waits for it. Safe to call several times.
- callback function
- Function to run once the library is loaded (may be async).
Returns Resolves to true when the library (and the callback) finished; rejects when the script cannot be loaded.
await ExtjsUtils.GEOMETRY.loadAdvancedGeometryLibrary();
var merged = ExtjsUtils.GEOMETRY.unionAll(features.map(function(f) { return f.geometry; }));loadGeometryLibrary
function(callback) : Promise.<Boolean>helper# Alias of GEOMETRY.loadAdvancedGeometryLibrary: loads the JSTS library once and resolves when the geometry operations can be used.
loadGeometryLibraryWritten as ExtjsUtils.GEOMETRY.loadGeometryLibrary
Alias of GEOMETRY.loadAdvancedGeometryLibrary: loads the JSTS library once and resolves when the geometry operations can be used.
- callback function
- Function to run once the library is loaded (may be async).
Returns Resolves to true when the library is loaded; rejects on a load failure.
ExtjsUtils.GEOMETRY.loadGeometryLibrary(function() {
var hull = ExtjsUtils.GEOMETRY.convexHull(feature.geometry);
});merge_intersects
function(ol2Geometries, mergeInvalid) : Array.<OpenLayers.Geometry>helper# Merges every set of mutually-intersecting geometries in the input array into a single geometry each, leaving non-intersecting geometries untouched.
merge_intersectsWritten as ExtjsUtils.GEOMETRY.merge_intersects
Merges every set of mutually-intersecting geometries in the input array into a single geometry each, leaving non-intersecting geometries untouched. Geometries are first clustered by bounding-box overlap (cheap) before the exact JSTS intersection/union work runs only within each cluster.
- ol2Geometries Array.<OpenLayers.Geometry>
- Geometries to merge.
- mergeInvalid Boolean
- When false, two invalid geometries in the same cluster are not merged with each other.
Returns The input geometries, with intersecting groups replaced by their union.
overlaps
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries overlap: same dimension, they share some interior points but neither contains the other (two partially overlapping polygons).
overlapsWritten as ExtjsUtils.GEOMETRY.overlaps
Tells whether the geometries overlap: same dimension, they share some interior points but neither contains the other (two partially overlapping polygons). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries partially overlap.
var partial = ExtjsUtils.GEOMETRY.overlaps(property.geometry, reserve.geometry);safeIntersects
function(jstsA, jstsB) : Booleanhelper# Checks whether two JSTS geometries intersect, retrying with a zero-width buffer if the direct check throws a topology error.
safeIntersectsWritten as ExtjsUtils.GEOMETRY.safeIntersects
Checks whether two JSTS geometries intersect, retrying with a zero-width buffer if the direct check throws a topology error. Returns false (instead of throwing) if the retry also fails.
- jstsA Object
- First JSTS geometry.
- jstsB Object
- Second JSTS geometry.
Returns True if the geometries intersect.
safeSymDifference
function(jstsA, jstsB) : Objecthelper# Symmetric difference of two JSTS geometries (the area covered by exactly one of the two, i.e. union minus intersection), retrying with a zero-width buffer if the direct operation throws a topology error.
safeSymDifferenceWritten as ExtjsUtils.GEOMETRY.safeSymDifference
Symmetric difference of two JSTS geometries (the area covered by exactly one of the two, i.e. union minus intersection), retrying with a zero-width buffer if the direct operation throws a topology error.
- jstsA Object
- First JSTS geometry.
- jstsB Object
- Second JSTS geometry.
Returns The symmetric-difference JSTS geometry.
safeUnion
function(jstsA, jstsB) : Objecthelper# Union of two JSTS geometries, retrying with a zero-width buffer (a common fix for self-intersecting/invalid rings) if the direct union throws a topology error.
safeUnionWritten as ExtjsUtils.GEOMETRY.safeUnion
Union of two JSTS geometries, retrying with a zero-width buffer (a common fix for self-intersecting/invalid rings) if the direct union throws a topology error.
- jstsA Object
- First JSTS geometry.
- jstsB Object
- Second JSTS geometry.
Returns The unioned JSTS geometry.
symDifference
function(aGeom, bGeom) : OpenLayers.Geometry|nullhelper# Symmetric difference of the two geometries: the parts covered by exactly one of them (union minus intersection).
symDifferenceWritten as ExtjsUtils.GEOMETRY.symDifference
Symmetric difference of the two geometries: the parts covered by exactly one of them (union minus intersection). Invalid polygons may throw a topology error — fix them with validate first. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns The symmetric difference, or null when the geometries are equal.
var changed = ExtjsUtils.GEOMETRY.symDifference(before.geometry, after.geometry);toText
function(aGeom) : Stringhelper# WKT (Well-Known Text) representation of the geometry, e.g. POLYGON ((...)), as written by JTS.
toTextWritten as ExtjsUtils.GEOMETRY.toText
WKT (Well-Known Text) representation of the geometry, e.g. POLYGON ((...)), as written by JTS. Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry.
Returns The WKT text.
var wkt = ExtjsUtils.GEOMETRY.toText(feature.geometry);touches
function(aGeom, bGeom) : Booleanhelper# Tells whether the geometries touch: they share boundary points only, with no interior point in common (two neighbouring polygons sharing an edge).
touchesWritten as ExtjsUtils.GEOMETRY.touches
Tells whether the geometries touch: they share boundary points only, with no interior point in common (two neighbouring polygons sharing an edge). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns True when the geometries touch without overlapping.
var neighbours = ExtjsUtils.GEOMETRY.touches(a.geometry, b.geometry);union
function(aGeom, bGeom) : OpenLayers.Geometryhelper# Union of two geometries.
unionWritten as ExtjsUtils.GEOMETRY.union
Union of two geometries. Accepts and returns OpenLayers geometries (JSTS conversion is handled internally).
- aGeom OpenLayers.Geometry
- First geometry.
- bGeom OpenLayers.Geometry
- Second geometry.
Returns The unioned geometry.
unionAll
function(geometries, options) : OpenLayers.Geometry|Object|nullhelper# Unions many geometries at once (OpenLayers or JSTS objects, mixed), skipping null and empty entries.
unionAllWritten as ExtjsUtils.GEOMETRY.unionAll
Unions many geometries at once (OpenLayers or JSTS objects, mixed), skipping null and empty entries. Uses the JTS cascaded union, retrying with a zero-width buffer and then pairwise safeUnion when invalid geometries make it fail. Requires the JSTS library.
- geometries Array
- OL or JSTS geometry objects.
- options Object
{returnJsts: true}returns the JSTS geometry instead of converting it back to OpenLayers.
Returns The union (OpenLayers geometry, or JSTS when returnJsts), or null when there was nothing to union.
var merged = ExtjsUtils.GEOMETRY.unionAll(layer.features.map(function(f) { return f.geometry; }));
if (merged) layer.addFeatures([new OpenLayers.Feature.Vector(merged)]);validate
function(olGeom, splitMultipolygon) : OpenLayers.Geometry|Array.<OpenLayers.Geometry>|nullhelper# Fixes an invalid OpenLayers geometry (self-intersections, etc.) using JSTS, optionally splitting a fixed multipolygon back into separate polygon geometries.
validateWritten as ExtjsUtils.GEOMETRY.validate
Fixes an invalid OpenLayers geometry (self-intersections, etc.) using JSTS, optionally splitting a fixed multipolygon back into separate polygon geometries.
- olGeom OpenLayers.Geometry
- Geometry to validate/fix.
- splitMultipolygon Boolean
- Split a resulting MultiPolygon into individual Polygon geometries instead of returning it as one MultiPolygon.
Returns The original geometry if already valid, a fixed geometry otherwise, an array when split, or null if the geometry couldn't be fixed.
within
function(aGeom, bGeom) : Booleanhelper# Tells whether aGeom lies within bGeom (the inverse of contains: every point of aGeom is inside bGeom and their interiors share a point).
withinWritten as ExtjsUtils.GEOMETRY.within
Tells whether aGeom lies within bGeom (the inverse of contains: every point of aGeom is inside bGeom and their interiors share a point). Requires the JSTS library.
- aGeom OpenLayers.Geometry
- Geometry to test.
- bGeom OpenLayers.Geometry
- Container geometry.
Returns True when aGeom is within bGeom.
var insideState = ExtjsUtils.GEOMETRY.within(property.geometry, state.geometry);HideInterface · keep visible when hidden
HideInterface1 entryUsage: ExtjsUtils.HideInterface
add
function(comp) : *helper# Registers an Ext component (or config/element) with the "hide interface" tool — the button that hides the map's panels to leave only the image — so that the component is toggled together with the …
addWritten as ExtjsUtils.HideInterface.add
Registers an Ext component (or config/element) with the "hide interface" tool — the button that hides the map's panels to leave only the image — so that the component is toggled together with the platform's own interface. An id is assigned to the component when it has none. Returns the same object, so it can be used inline while building a config. Does nothing (returns undefined) when the HideInterface plugin is not loaded.
- comp Ext.Component|Ext.Element|Object
- Any Ext component, element or component config.
Returns The same comp, now with an id, or undefined when the tool is unavailable.
var panel = new Ext.Panel(ExtjsUtils.HideInterface.add({ html: "Legend", renderTo: Ext.getBody() }));HIGHCHART, REGEX · charts and strings
Extjs3 entries*Only the functions which where used in CSR projects are listed here.
escapeRegExp
function(str) : Stringhelper# Escapes the regular expression special characters of a string, so a user-typed value can be used inside new RegExp(...) literally.
escapeRegExpWritten as ExtjsUtils.REGEX.escapeRegExp
Escapes the regular expression special characters of a string, so a user-typed value can be used inside new RegExp(...) literally. The real call path is ExtjsUtils.REGEX.escapeRegExp(str). Escaped characters are '-', '[', ']', '/', '{', '}', '(', ')', '*', '+', '?', '.', '\', '^', '$', '|'.
- str String
- Expression to be escaped.
Returns String with all regex characters escaped.
var re = new RegExp(ExtjsUtils.REGEX.escapeRegExp("CSR:layer.name (v2)"), "i");getHighchartById
function(id) : Object# Gets a Highcharts chart instance by the id of the DOM element it was rendered into (renderTo), so query code can update a chart created in descriptionHtml after the data arrives.
getHighchartByIdGets a Highcharts chart instance by the id of the DOM element it was rendered into (renderTo), so query code can update a chart created in descriptionHtml after the data arrives. The real call path is ExtjsUtils.HIGHCHART.getById(id).
- id String
- Id of the DOM element the chart was rendered into.
Returns The Highcharts chart object, or null when no chart uses that element.
var chart = ExtjsUtils.HIGHCHART.getById("highchart-01");
if (chart) chart.series[0].setData([10, 20, 30]);replaceAll
function(str, search, replacement) : String|Array.<String>helper# Replaces every occurrence of the plain substring search (no regular expression) by replacement.
replaceAllWritten as ExtjsUtils.REGEX.replaceAll
Replaces every occurrence of the plain substring search (no regular expression) by replacement. When str is an array of strings every entry is replaced in place and the same array is returned. The real call path is ExtjsUtils.REGEX.replaceAll(...).
- str String|Array.<String>
- A string, or an array of strings, whose terms are replaced.
- search String
- Substring to search for (literal, not a regex).
- replacement String
- Text that replaces each occurrence.
Returns The replaced string, or the same array when str is an array.
ExtjsUtils.REGEX.replaceAll("a-b-c", "-", "_"); // "a_b_c"
ExtjsUtils.REGEX.replaceAll(["x.y", "z.w"], ".", "/"); // ["x/y", "z/w"]HTML · elements, colours, pixels
HTMLUtils18 entriesUsage: ExtjsUtils.HTML
cache
Object# Cache of image contents keyed by URL: each entry is the base64 data URL of an image already loaded once (filled by the onLoad handler getReusableImg writes).
cacheWritten as ExtjsUtils.HTML.cache
Cache of image contents keyed by URL: each entry is the base64 data URL of an image already loaded once (filled by the onLoad handler getReusableImg writes). Query code may also fill it directly with getImageBase64.
ExtjsUtils.HTML.cache['/theme/app/img/legend.png'] = ExtjsUtils.HTML.getImageBase64(imgElement);canvasWebGL
HTMLCanvasElement# The single off-screen <canvas> reused by every WebGL pixel read (getWebGLContext), so a context is not created per call.
canvasWebGLWritten as ExtjsUtils.HTML.canvasWebGL
The single off-screen <canvas> reused by every WebGL pixel read (getWebGLContext), so a context is not created per call.
var gl = ExtjsUtils.HTML.canvasWebGL.getContext('webgl');changeImgColor
function(img, fromColor, toColor, canvas, originalData)helper# Replaces one colour of an image by another and writes the result back into the image (img.src becomes a data URL drawn on canvas).
changeImgColorWritten as ExtjsUtils.HTML.changeImgColor
Replaces one colour of an image by another and writes the result back into the image (img.src becomes a data URL drawn on canvas). The originalData array keeps the untouched pixels: it is filled on the first call (pass an empty array) and, on later calls with the same array, the image is restored from it before the new colour is applied — so repeated calls with different toColors do not accumulate. Used to highlight a legend class in a legend image.
- img HTMLImageElement
- Image to modify (loaded and CORS-readable).
- fromColor Array.<Number>
[r, g, b]colour to replace (exact match).- toColor Array.<Number>
[r, g, b]replacement colour.- canvas HTMLCanvasElement
- Canvas used to redraw the image.
- originalData Array.<Number>
- Array holding the original pixel bytes; pass
[]on the first call and the same array afterwards.
var original = [];
var canvas = document.createElement('canvas');
ExtjsUtils.HTML.changeImgColor(legendImg, [0, 128, 0], [255, 0, 0], canvas, original); // green -> red
ExtjsUtils.HTML.changeImgColor(legendImg, [0, 128, 0], [0, 0, 255], canvas, original); // green -> blue (red is gone)colorStyleToRgb
function(color) : Array.<String>helper# Converts any colour the browser understands ("red", "#f80", "rgb(255, 136, 0)", "hsl(...)"...) into its RGB components, by letting the browser compute the style of a temporary element.
colorStyleToRgbWritten as ExtjsUtils.HTML.colorStyleToRgb
Converts any colour the browser understands ("red", "#f80", "rgb(255, 136, 0)", "hsl(...)"...) into its RGB components, by letting the browser compute the style of a temporary element. The components come back as strings (e.g. ["255", "136", "0"]).
- color String
- The colour in any CSS notation.
Returns The [r, g, b] components as strings (a fourth alpha component may be present for translucent colours).
ExtjsUtils.HTML.colorStyleToRgb('orange'); // ["255", "165", "0"]getAbsolutePointFromLatLong
function(lonLat) : Objecthelper# Returns the page position (pixels relative to the document) where a map coordinate is currently drawn: the map pixel of the coordinate plus the offset of the map viewport.
getAbsolutePointFromLatLongWritten as ExtjsUtils.HTML.getAbsolutePointFromLatLong
Returns the page position (pixels relative to the document) where a map coordinate is currently drawn: the map pixel of the coordinate plus the offset of the map viewport. The coordinate must be in the map projection. Use it to place HTML (a popup, a marker image) over a map location.
- lonLat OpenLayers.LonLat
- The map coordinate, in the map projection.
Returns {x, y} page position in pixels.
var lonLat = new OpenLayers.LonLat(-44.0, -19.9).transform("EPSG:4326", app.mapPanel.map.getProjection());
var point = ExtjsUtils.HTML.getAbsolutePointFromLatLong(lonLat);
popup.style.left = point.x + 'px';
popup.style.top = point.y + 'px';getAbsolutePointFromMouseEvent
function(mouseEvt) : Objecthelper# Returns the page position of a mouse event (pageX/pageY, or clientX/Y plus the body scroll on old IE), never negative.
getAbsolutePointFromMouseEventWritten as ExtjsUtils.HTML.getAbsolutePointFromMouseEvent
Returns the page position of a mouse event (pageX/pageY, or clientX/Y plus the body scroll on old IE), never negative. This is the absolutePoint expected by LAYER.getLayerColorAtPoint and getRelativePositionToPoint.
- mouseEvt MouseEvent
- The DOM mouse event.
Returns {x, y} page position in pixels.
ExtjsUtils.addDomListener(window, 'mousemove', function(evt) {
var point = ExtjsUtils.HTML.getAbsolutePointFromMouseEvent(evt);
popup.style.left = (point.x + 10) + 'px';
popup.style.top = (point.y + 10) + 'px';
});getImageBase64
function(img) : Stringhelper# Returns the content of a loaded image as a PNG data URL (data:image/png;base64,...), drawing it on a reused 2D canvas.
getImageBase64Written as ExtjsUtils.HTML.getImageBase64
Returns the content of a loaded image as a PNG data URL (data:image/png;base64,...), drawing it on a reused 2D canvas. The image must be loaded and CORS-readable.
- img HTMLImageElement
- Loaded image element.
Returns The image as a base64 PNG data URL.
var dataUrl = ExtjsUtils.HTML.getImageBase64(document.getElementById('legend-img'));getImageDataWithAlpha
function(img, fromX, fromY, width, height) : Uint8Arrayhelper# Copies a rectangle of an image as raw RGBA bytes through WebGL, keeping the exact alpha values (a 2D canvas returns alpha-premultiplied colours).
getImageDataWithAlphaWritten as ExtjsUtils.HTML.getImageDataWithAlpha
Copies a rectangle of an image as raw RGBA bytes through WebGL, keeping the exact alpha values (a 2D canvas returns alpha-premultiplied colours). Defaults to the whole image.
- img HTMLImageElement
- Loaded, CORS-readable image.
- fromX Number
- Column of the first pixel to copy.
- fromY Number
- Row of the first pixel to copy.
- width Number
- Width of the rectangle, in pixels.
- height Number
- Height of the rectangle, in pixels.
Returns 4 * width * height bytes: R, G, B, A per pixel, row by row.
var pixels = ExtjsUtils.HTML.getImageDataWithAlpha(tileImage); // whole tile
var transparentCount = 0;
for (var i = 3; i < pixels.length; i += 4) if (pixels[i] === 0) transparentCount++;getIntermediateColor
function(color1, color2, weight) : Array.<Number>helper# Blends two colours with a weighted average: weight goes to the first colour and 1 - weight to the second.
getIntermediateColorWritten as ExtjsUtils.HTML.getIntermediateColor
Blends two colours with a weighted average: weight goes to the first colour and 1 - weight to the second. Each colour may be an [r, g, b] array or any CSS colour string (converted with colorStyleToRgb). Handy to build a gradient between two legend colours.
- color1 Array.<Number>|String
- First colour.
- color2 Array.<Number>|String
- Second colour.
- weight Number
- Weight of the first colour, from 0 (only
color2) to 1 (onlycolor1).
Returns The blended colour as [r, g, b] (rounded 0-255 numbers).
var mid = ExtjsUtils.HTML.getIntermediateColor('#ff0000', '#0000ff', 0.5); // [128, 0, 128]
el.style.backgroundColor = ExtjsUtils.HTML.rgbToColorStyle(mid);getPixelColorAtWebGL
function(x, y, img, xWidth, yHeight) : Uint8Arrayhelper# Reads the pixels of an image through WebGL (so the RGBA values are not alpha-premultiplied as a 2D canvas would make them): a window of xWidth x yHeight pixels whose top-left corner is (x, y), …
getPixelColorAtWebGLWritten as ExtjsUtils.HTML.getPixelColorAtWebGL
Reads the pixels of an image through WebGL (so the RGBA values are not alpha-premultiplied as a 2D canvas would make them): a window of xWidth x yHeight pixels whose top-left corner is (x, y), defaulting to a single pixel. The image must be loaded and CORS-readable (map tiles are).
- x Number
- Column of the (first) pixel, relative to the image.
- y Number
- Row of the (first) pixel, relative to the image.
- img HTMLImageElement
- Image to read from.
- xWidth Number
- Width of the window to read, in pixels.
- yHeight Number
- Height of the window to read, in pixels.
Returns 4 * xWidth * yHeight bytes: R, G, B, A for each pixel, row by row.
var rgba = ExtjsUtils.HTML.getPixelColorAtWebGL(10, 20, tileImage); // Uint8Array [r, g, b, a]getPixelColorLimitsWebGL
function(img, limits, bbox) : Uint8Arrayhelper# Reads, through WebGL, only the pixels of an image that fall inside per-row x-spans — the limits/bounds produced by LAYER.getLayerTilesFeatureIntersects for a tile.
getPixelColorLimitsWebGLWritten as ExtjsUtils.HTML.getPixelColorLimitsWebGL
Reads, through WebGL, only the pixels of an image that fall inside per-row x-spans — the limits/bounds produced by LAYER.getLayerTilesFeatureIntersects for a tile. limits is indexed by row and holds the [start, end, start, end, ...] columns to keep (closed intervals); e.g. [[], [1, 3], [], [5, 5]] keeps columns 1-3 of row 1 and column 5 of row 3.
- img HTMLImageElement
- Image (tile) to read from.
- limits Array.<Array.<Number>>
- Per-row x-spans to keep, as described above.
- bbox OpenLayers.Bounds
- Row/column range to scan:
left/rightthe columns,top/bottomthe rows.
Returns The R, G, B, A bytes of the kept pixels, concatenated.
ExtjsUtils.LAYER.getLayerTilesFeatureIntersects(layer, feature).forEach(function(tile) {
var rgba = ExtjsUtils.HTML.getPixelColorLimitsWebGL(tile.img, tile.limits, tile.bounds);
console.log(rgba.length / 4, 'pixels inside the polygon on this tile');
});getRelativePositionToPoint
function(absolutePoint, element) : Array.<Number>helper# Converts a page position into a position relative to an element's top-left corner: x is positive to the right of the element's left edge (negative to the left), y is positive below its top edge (negative above).
getRelativePositionToPointWritten as ExtjsUtils.HTML.getRelativePositionToPoint
Converts a page position into a position relative to an element's top-left corner: x is positive to the right of the element's left edge (negative to the left), y is positive below its top edge (negative above). Defaults to the map viewport, which turns a mouse page position into a map pixel.
- absolutePoint Object
- Page position
{x, y}in pixels (seegetAbsolutePointFromMouseEvent). - element HTMLElement|Ext.Element
- Reference element; defaults to the map viewport
div.
Returns [x, y] relative to the element.
var point = ExtjsUtils.HTML.getAbsolutePointFromMouseEvent(evt);
var mapPixel = ExtjsUtils.HTML.getRelativePositionToPoint(point); // [x, y] inside the map
var lonLat = app.mapPanel.map.getLonLatFromPixel({ x: mapPixel[0], y: mapPixel[1] });getReusableImg
function(url, attributes) : Stringhelper# Builds the HTML of an <img> tag meant to be loaded only once: the src is the base64 content kept in HTML.cache when the URL was already loaded, otherwise the URL itself plus an onLoad handler …
getReusableImgWritten as ExtjsUtils.HTML.getReusableImg
Builds the HTML of an <img> tag meant to be loaded only once: the src is the base64 content kept in HTML.cache when the URL was already loaded, otherwise the URL itself plus an onLoad handler that stores the image in the cache for the next call. Extra attributes are appended verbatim. Note: the current implementation reads an undefined HTML.urlCache before appending the onLoad handler, so calling it throws a TypeError today; no production query uses it.
- url String
- URL of the image.
- attributes String
- Extra attributes to append to the tag, e.g.
' width="16" class="icon"'.
Returns The <img ...> HTML string.
var html = ExtjsUtils.HTML.getReusableImg('/theme/app/img/legend.png', ' class="legend-icon"');getWebGLContext
function() : WebGLRenderingContexthelper# Returns the WebGL rendering context of the shared canvasWebGL canvas (trying the "webgl" and then the legacy "experimental-webgl" context names).
getWebGLContextWritten as ExtjsUtils.HTML.getWebGLContext
Returns the WebGL rendering context of the shared canvasWebGL canvas (trying the "webgl" and then the legacy "experimental-webgl" context names). null when the browser has no WebGL support — see CHECK.browserSupported.
Returns The WebGL context, or null when unavailable.
var gl = ExtjsUtils.HTML.getWebGLContext();
if (!gl) ExtjsUtils.ALERTIFY.alert('This browser cannot read map pixels');hexToRgb
function(hex) : Array.<Number>|nullhelper# Converts a 6-digit hexadecimal colour ("#rrggbb", the # being optional) into an [r, g, b] array of 0-255 numbers.
hexToRgbWritten as ExtjsUtils.HTML.hexToRgb
Converts a 6-digit hexadecimal colour ("#rrggbb", the # being optional) into an [r, g, b] array of 0-255 numbers. Short (#rgb) or invalid strings give null.
- hex String
- The colour in hexadecimal notation.
Returns [r, g, b], or null when the string is not a 6-digit hex colour.
ExtjsUtils.HTML.hexToRgb('#ff8800'); // [255, 136, 0]isInsideIframe
function() : Booleanhelper# Tells whether the map page is embedded in another page (an iframe), which is how most tenant sites show a query.
isInsideIframeWritten as ExtjsUtils.HTML.isInsideIframe
Tells whether the map page is embedded in another page (an iframe), which is how most tenant sites show a query. Cross-origin embedding that blocks the check also counts as embedded. Use it to hide interface parts that only make sense when the map is opened on its own.
Returns true when running inside an iframe, false when opened directly.
if (ExtjsUtils.HTML.isInsideIframe()) ExtjsUtils.CSS.defineClass('#topbar', 'display: none;');offset
function(element) : Objecthelper# Returns the position of an element relative to the whole page (document), taking the current scroll into account — unlike getBoundingClientRect, which is relative to the viewport.
offsetWritten as ExtjsUtils.HTML.offset
Returns the position of an element relative to the whole page (document), taking the current scroll into account — unlike getBoundingClientRect, which is relative to the viewport. Accepts a DOM element or an Ext.Element.
- element HTMLElement|Ext.Element
- Element to measure.
Returns {top, left, right} — page offsets in pixels of the element's top, left and right edges.
var pos = ExtjsUtils.HTML.offset(app.mapPanel.map.viewPortDiv);
console.log('map starts at', pos.left, pos.top);rgbToColorStyle
function(color) : Stringhelper# Formats an [r, g, b] colour as the CSS string "rgb(r, g, b)".
rgbToColorStyleWritten as ExtjsUtils.HTML.rgbToColorStyle
Formats an [r, g, b] colour as the CSS string "rgb(r, g, b)". The usual companion of the legend entries (layer.getLegendEntries()[i].color is an [r, g, b] array) when painting HTML with a legend colour.
- color Array.<Number>
- The colour components
[r, g, b](a fourth element is ignored).
Returns The "rgb(r, g, b)" CSS colour.
var entry = layer.getLegendEntries()[0];
html += '<span style="color:' + ExtjsUtils.HTML.rgbToColorStyle(entry.color) + '">' + entry.title + '</span>';INTROJS · guided tours
INTROJS5 entriesUsage: ExtjsUtils.INTROJS
getStep
function(element, txt, position, step, tooltipClass, highlightClass, disableInteraction) : Objecthelper# Builds one Intro.js step object for loadAndRun.
getStepWritten as ExtjsUtils.INTROJS.getStep
Builds one Intro.js step object for loadAndRun. Only the fields that were given are set (position defaults to 'auto').
- element HTMLElement
- Element to highlight; omit for a step without a target (centered message).
- txt String
- Text/HTML shown in the step tooltip.
- position String
- Tooltip position:
top,left,right,bottom,bottom-left-aligned,bottom-middle-aligned,bottom-right-alignedorauto. - step Number
- Explicit step number (order);
0is accepted. - tooltipClass String
- Extra CSS class for the tooltip.
- highlightClass String
- Extra CSS class for the highlighted element.
- disableInteraction Boolean
- True to block clicks on the highlighted element during the step.
Returns The Intro.js step object.
var step = ExtjsUtils.INTROJS.getStep(document.getElementById("chart"), "Click a bar to filter the map.", "top");getStepsFromDOM
function(parent) : Array.<Object>helper# Collects tour steps from the DOM: every visible element (larger than 13x13 px) with a data-intro attribute becomes a step, reading data-position, data-step, data-tooltipClass and data-highlightClass as well.
getStepsFromDOMWritten as ExtjsUtils.INTROJS.getStepsFromDOM
Collects tour steps from the DOM: every visible element (larger than 13x13 px) with a data-intro attribute becomes a step, reading data-position, data-step, data-tooltipClass and data-highlightClass as well. This is what loadAndRun does when no steps are given.
- parent HTMLElement|Document
- Root element to search under.
Returns The step objects, in DOM order.
var steps = ExtjsUtils.INTROJS.getStepsFromDOM(document.getElementById("mypanel"));loadAndRun
function(steps, exitOnOverlayClick, startFunction)helper# Loads Intro.js (script and stylesheets, once) and starts a guided tour.
loadAndRunWritten as ExtjsUtils.INTROJS.loadAndRun
Loads Intro.js (script and stylesheets, once) and starts a guided tour. Without steps the tour is built from every visible element carrying a data-intro attribute (getStepsFromDOM), wrapped in a welcome and a completion step. Steps whose element is not visible are skipped automatically and the tooltip is kept inside the viewport.
- steps Array.<Object>
- Intro.js step objects (see
getStep); omit to build them from the DOM. - exitOnOverlayClick Boolean
- Whether clicking the dark overlay closes the tour.
- startFunction function
- Receives the configured introJs instance instead of starting it right away (call
intro.start()yourself).
ExtjsUtils.INTROJS.loadAndRun([
ExtjsUtils.INTROJS.getStep(null, "Welcome to the fire history map."),
ExtjsUtils.INTROJS.getStep(document.getElementById("legend"), "Colours show the number of fires.", "left")
]);setHelpDescriptionDOM
function(dom, txt, position, priority) : HTMLElementhelper# Marks a DOM element as a tour step by setting its data-intro, data-position and (optionally) data-step attributes, so getStepsFromDOM/loadAndRun pick it up.
setHelpDescriptionDOMWritten as ExtjsUtils.INTROJS.setHelpDescriptionDOM
Marks a DOM element as a tour step by setting its data-intro, data-position and (optionally) data-step attributes, so getStepsFromDOM/loadAndRun pick it up.
- dom HTMLElement
- Element to annotate.
- txt String
- Help text; nothing is set when empty.
- position String
- Tooltip position (see
getStep); invalid values fall back toauto. - priority Number
- Step order, stored as
data-step.
Returns The same element.
ExtjsUtils.INTROJS.setHelpDescriptionDOM(document.getElementById("legend"), "Colours show the number of fires.", "left", 1);setHelpDescriptionElement
function(cmpConfig, txt, position, priority) : Objecthelper# Attaches a help description to an Ext component config (not a rendered component): an afterrender listener is chained so that setHelpDescriptionDOM runs on the component element once it exists.
setHelpDescriptionElementWritten as ExtjsUtils.INTROJS.setHelpDescriptionElement
Attaches a help description to an Ext component config (not a rendered component): an afterrender listener is chained so that setHelpDescriptionDOM runs on the component element once it exists. Returns the same config, so it can be used inline. Throws when given an already rendered component.
- cmpConfig Object
- Ext component configuration object.
- txt String
- Help text; nothing is attached when empty.
- position String
- Tooltip position (see
getStep); invalid values fall back toauto. - priority Number
- Step order, stored as
data-step.
Returns The same cmpConfig.
var btn = ExtjsUtils.INTROJS.setHelpDescriptionElement({xtype: "button", text: "Export"},
"Downloads the current table as CSV.", "bottom", 3);JS · the map and the app
JS3 entriesUsage: ExtjsUtils.JS
getApp
function() : GeoExplorerhelper# Returns the application object (window.app, the GeoExplorer viewer): app.mapPanel holds the map and its layer store, app.layerSources the registered sources, app.tools the tools by id.
getAppWritten as ExtjsUtils.JS.getApp
Returns the application object (window.app, the GeoExplorer viewer): app.mapPanel holds the map and its layer store, app.layerSources the registered sources, app.tools the tools by id.
Returns The application instance.
var layerStore = ExtjsUtils.JS.getApp().mapPanel.layers;getLayerSource
function(sourceId) : gxp.plugins.LayerSource|nullhelper# Returns a registered layer source by id — "local" (the Mappia GeoServer), the built-in "osm"/"google", or an id registered with QUERY.addRemoteWMSServer — or null when it does not exist (or is still not created).
getLayerSourceWritten as ExtjsUtils.JS.getLayerSource
Returns a registered layer source by id — "local" (the Mappia GeoServer), the built-in "osm"/"google", or an id registered with QUERY.addRemoteWMSServer — or null when it does not exist (or is still not created). Sources expose createLayerRecord(cfg) and, for WMS sources, the capabilities store.
- sourceId String
- Source id as used in a layer's
sourceproperty.
Returns The source plugin, or null when unknown.
var src = ExtjsUtils.JS.getLayerSource("ibge");
if (src) console.log("IBGE source is registered");getMap
function() : OpenLayers.Maphelper# Returns the OpenLayers map of the page (window.map when defined, otherwise app.mapPanel.map).
getMapWritten as ExtjsUtils.JS.getMap
Returns the OpenLayers map of the page (window.map when defined, otherwise app.mapPanel.map). Prefer it over the bare globals in query code: it works in the viewer, the editor and embedded pages alike.
Returns The current map.
ExtjsUtils.JS.getMap().zoomTo(6);JSON · JSON that keeps functions
JSONUtils1 entryUsage: ExtjsUtils.JSON
stringify
function(obj, maxDeep, indent, clearDataCallback) : String|undefinedhelper# Serializes an object to JavaScript source text, keeping what JSON.stringify drops: functions are written with their source (toString()), and numbers, booleans, arrays and nested objects are kept.
stringifyWritten as ExtjsUtils.JSON.stringify
Serializes an object to JavaScript source text, keeping what JSON.stringify drops: functions are written with their source (toString()), and numbers, booleans, arrays and nested objects are kept. undefined/null values are omitted. The output is JavaScript (unquoted function bodies), meant to be evaluated again — it is how layer definitions with callbacks are stored — not strict JSON. Markup braces {{/}} inside strings are escaped.
- obj Object
- The object to serialize.
- maxDeep Number
- Maximum recursion depth, to stop on cyclic references.
- indent Number
- Number of spaces per indentation level (0 or omitted for none).
- clearDataCallback function
function(curObj, curKey)returning true to skip the propertycurKeyofcurObj.
Returns The source text, or undefined for a null/undefined input.
var src = ExtjsUtils.JSON.stringify({name: "CSR:example_layer", functions: {onClick: function(p) { alert(p); }}}, 7, 2,
function(obj, key) { return key === "cache"; });LAYER · find layers, extents, legends, pixels
Layer28 entriesfilterRecordsProperties
function(records, properties) : Array.<Object>|Array.<(String|Number)>helper# Extracts properties from an array of layer records (or plain objects).
filterRecordsPropertiesWritten as ExtjsUtils.LAYER.filterRecordsProperties
Extracts properties from an array of layer records (or plain objects). With a single property name the result is a flat array of values; with several names each element is an object holding those properties. A single record or a single property name (not wrapped in an array) is accepted too.
- records Array.<Ext.data.Record>|Ext.data.Record|Array.<Object>
- Records (or objects) to read; a record's
get(name)is used when available. - properties Array.<String>|String
- Property name(s) to extract.
Returns One entry per record: the value itself for a single property, an object for several.
var records = ExtjsUtils.LAYER.getLayersRecords();
var names = ExtjsUtils.LAYER.filterRecordsProperties(records, 'name'); // ["CSR:estados", ...]
var pairs = ExtjsUtils.LAYER.filterRecordsProperties(records, ['name', 'title']); // [{name, title}, ...]getActiveLayersDefinition
function() : Array.<GeoExt.data.LayerRecord>helper# Returns a copy of the layer records currently in the map (the map panel's layer store), in map order.
getActiveLayersDefinitionWritten as ExtjsUtils.LAYER.getActiveLayersDefinition
Returns a copy of the layer records currently in the map (the map panel's layer store), in map order. Each record's data/json carries the layer definition as the query declared it, after the interpreter filled in its defaults, and record.getLayer() gives the OpenLayers layer.
Returns A new array with all the layer records.
ExtjsUtils.LAYER.getActiveLayersDefinition().forEach(function(record) {
console.log(record.get('name'), record.get('group'));
});getAllBackgroundLayerRecords
function() : Array.<GeoExt.data.LayerRecord>helper# Returns the layer records of every background map currently in the map's layer store — the layers declared with group: "background" (or flagged isBaseLayer), including the platform default basemap.
getAllBackgroundLayerRecordsWritten as ExtjsUtils.LAYER.getAllBackgroundLayerRecords
Returns the layer records of every background map currently in the map's layer store — the layers declared with group: "background" (or flagged isBaseLayer), including the platform default basemap. Use it to toggle basemaps from query code.
Returns The background layer records (empty when there is none).
// Hide every basemap
ExtjsUtils.LAYER.getAllBackgroundLayerRecords().forEach(function(record) {
record.getLayer().setVisibility(false);
});getLayerByName
function(fullLayerName) : OpenLayers.Layer|undefinedhelper# Returns the OpenLayers layer currently in the map whose name equals the given name, or undefined when no such layer is loaded.
getLayerByNameWritten as ExtjsUtils.LAYER.getLayerByName
Returns the OpenLayers layer currently in the map whose name equals the given name, or undefined when no such layer is loaded. A calculated layer (source: "calculate") is named on the map by the name declared in the query ('CSR:altimetria'); a plain map layer is named by its title. To find a plain layer by the map it shows, filter ExtjsUtils.JS.getMap().layers on layer.params.LAYERS === 'CSR:estados'.
- fullLayerName String
- The layer's name on the map: the query
nameof a calculated layer, thetitleof a plain one.
Returns The layer object, or undefined when it is not in the map.
var layer = ExtjsUtils.LAYER.getLayerByName('CSR:altimetria'); // a calculated layer
if (layer) layer.setVisibility(true);getLayerColorAtPoint
function(layer, absolutePoint, layerOperation) : Uint8Array|nullhelper# Reads the colour a layer draws under a page position: looks through the layer's tile images for the one containing the point and reads that pixel through WebGL.
getLayerColorAtPointWritten as ExtjsUtils.LAYER.getLayerColorAtPoint
Reads the colour a layer draws under a page position: looks through the layer's tile images for the one containing the point and reads that pixel through WebGL. Returns null when the point falls outside every tile or the pixel is a "null" colour for the layer operation (transparent / no data). This is what isOnHover uses.
- layer OpenLayers.Layer
- Layer whose tiles are inspected (an inner layer, not the composed one).
- absolutePoint Object
- Page position
{x, y}in pixels (e.g. fromHTML.getAbsolutePointFromMouseEvent). - layerOperation Object
- The layer's
MapOperationsvalue, used to decide which colours mean "no data".
Returns The [R, G, B, A] pixel colour, or null when there is no colour at that point.
var point = ExtjsUtils.HTML.getAbsolutePointFromMouseEvent(evt);
var rgba = ExtjsUtils.LAYER.getLayerColorAtPoint(composedLayer.layers[0], point);
if (rgba) console.log('hovering colour', ExtjsUtils.HTML.rgbToColorStyle(rgba));getLayerExtent
function(layer) : OpenLayers.Boundshelper# Returns the extent of a layer in the map projection.
getLayerExtentWritten as ExtjsUtils.LAYER.getLayerExtent
Returns the extent of a layer in the map projection. A vector layer with features gives their bounds; any other layer its llbbox (the lon/lat bounding box read from the WMS capabilities) reprojected. When the layer has no llbbox, or the reprojected box is invalid, it falls back to the layer's maxExtent (or the inner layer's maxExtent for a composed layer) and finally to the map's maxExtent. The layer may be given by name (layer.name or getMapName). Typical use: zoom the map to a layer.
- layer OpenLayers.Layer|String
- The layer (a composed layer or one of its inner layers), or its name.
Returns The layer extent in the map projection; null for a name not on the map.
// Zoom to a layer when it becomes visible
onVisibilityChange: function(visible) {
if (visible) app.mapPanel.map.zoomToExtent(ExtjsUtils.LAYER.getLayerExtent(this), true);
}// the bounding box of a property drawn by a vector layer
var bounds = ExtjsUtils.LAYER.getLayerExtent("CSR:show_car");getLayerLegend
function(composedLayer, index) : Arrayhelper# Gets the associated layer legend content by its index.
getLayerLegendWritten as ExtjsUtils.LAYER.getLayerLegend
Gets the associated layer legend content by its index.
PS: The legend format is the same as expected by the composedLayer.setCalculateLegend function. Usage: this.setCalculateLegend(ExtjsUtils.LAYER.getLayerLegend(this, 0)); inside a calculated layer's beforeCalc.
- composedLayer OpenLayers.Layer.Composed
- Layer composed.
- index Numeric
- Index of the inside layer.
Returns Array with the legend entries [{color, value, title}, ...].
getLayerSource
function(layerName, onlyDescription) : Objecthelper# Finds the source (local, remote, a source registered by addRemoteWMSServer...) that serves a layer: first the source whose store contains a record with that name, then the source whose id …
getLayerSourceWritten as ExtjsUtils.LAYER.getLayerSource
Finds the source (local, remote, a source registered by addRemoteWMSServer...) that serves a layer: first the source whose store contains a record with that name, then the source whose id matches the name's workspace prefix (workspace:layer). Returns either the live source plugin or its description object.
- layerName String
- Full layer name, e.g.
'CSR:estados'. - onlyDescription Boolean
trueto get a copy of the source description (thesourcesconfig:url,ptype,cors...),false/omitted to get the source plugin instance.
Returns The source plugin (e.g. a gxp.plugins.WMSSource) or its description, or an empty object {} when no source contains the layer.
var wmsUrl = ExtjsUtils.LAYER.getLayerSource('CSR:estados', true).url;getLayerSourceNames
function() : Array.<String>helper# Returns the ids of every layer source currently registered in the application — the built-in ones (local, osm, google...) plus those added by the query (QUERY.addRemoteWMSServer).
getLayerSourceNamesWritten as ExtjsUtils.LAYER.getLayerSourceNames
Returns the ids of every layer source currently registered in the application — the built-in ones (local, osm, google...) plus those added by the query (QUERY.addRemoteWMSServer). These ids are the storeName accepted by getLayersRecords and getStoreLayersNames.
Returns The source ids (empty before the application is ready).
ExtjsUtils.LAYER.getLayerSourceNames(); // ["local", "osm", "google", "remote", ...]getLayerTilesFeatureIntersects
function(layer, feature) : Array.<Object>helper# Rasterises a polygon feature over the tiles of a layer and returns the tiles it intersects, each with the exact pixel spans inside the polygon (scan-line polygon fill, one entry per tile row).
getLayerTilesFeatureIntersectsWritten as ExtjsUtils.LAYER.getLayerTilesFeatureIntersects
Rasterises a polygon feature over the tiles of a layer and returns the tiles it intersects, each with the exact pixel spans inside the polygon (scan-line polygon fill, one entry per tile row). This is the basis of the "values inside a drawn area" calculations; pass the result rows to HTML.getPixelColorLimitsWebGL to read the pixels.
- layer OpenLayers.Layer
- Layer whose tile images are tested.
- feature OpenLayers.Feature.Vector
- Polygon feature, in the layer projection.
Returns One {img, limits, bounds} per intersecting tile: img the tile image, limits an array indexed by tile row holding the [start, end, start, end, ...] x-spans inside the polygon, bounds an OpenLayers.Bounds with the row/column range covered (closed interval).
var tiles = ExtjsUtils.LAYER.getLayerTilesFeatureIntersects(composedLayer.layers[0], drawnFeature);
tiles.forEach(function(tile) {
var pixels = ExtjsUtils.HTML.getPixelColorLimitsWebGL(tile.img, tile.limits, tile.bounds);
});getLayerTilesInArea
function(layer, minBBOXx, minBBOXy, maxBBOXx, maxBBOXy) : Array.<Object>helper# Returns the tile images of a layer that overlap a rectangle given in page pixels, together with the part of each tile that lies inside the rectangle.
getLayerTilesInAreaWritten as ExtjsUtils.LAYER.getLayerTilesInArea
Returns the tile images of a layer that overlap a rectangle given in page pixels, together with the part of each tile that lies inside the rectangle. Useful to read the pixels of a screen region (e.g. a dragged box) from the layer tiles.
- layer OpenLayers.Layer
- Layer whose tile images are tested.
- minBBOXx Number
- Left edge of the rectangle, in page pixels.
- minBBOXy Number
- Top edge of the rectangle, in page pixels.
- maxBBOXx Number
- Right edge of the rectangle, in page pixels.
- maxBBOXy Number
- Bottom edge of the rectangle, in page pixels.
Returns One {img, minXY, maxXY} per overlapping tile: img the tile image, minXY/maxXY the [x, y] corners of the overlap relative to the tile.
var tiles = ExtjsUtils.LAYER.getLayerTilesInArea(composedLayer.layers[0], 100, 100, 400, 300);
tiles.forEach(function(tile) {
var w = tile.maxXY[0] - tile.minXY[0], h = tile.maxXY[1] - tile.minXY[1];
var pixels = ExtjsUtils.HTML.getPixelColorAtWebGL(tile.minXY[0], tile.minXY[1], tile.img, w, h);
});getLayersRecords
function(layerName, storeName) : Array.<Ext.data.Record>|Ext.data.Record|nullhelper# Gets the store record of a layer from its full name ('CSR:estados'), searching every source store or only the one given by storeName.
getLayersRecordsWritten as ExtjsUtils.LAYER.getLayersRecords
Gets the store record of a layer from its full name ('CSR:estados'), searching every source store or only the one given by storeName. The record holds the layer's capabilities data (title, abstract, styles, llbbox...). Called without layerName it returns the records of all the layers the source(s) offer.
- layerName String
- Full layer name to look for; omit to get every record.
- storeName String
- Source id to restrict the search to (see
getLayerSourceNames); omit to search all sources.
Returns The record of layerName (null when not found in exactly one store), or the array of all records when layerName is omitted.
var record = ExtjsUtils.LAYER.getLayersRecords("CSR:estados");
if (record) console.log(record.get("title"), record.get("styles"));
// Every layer offered by the 'remote' source
var remoteRecords = ExtjsUtils.LAYER.getLayersRecords(undefined, "remote");getLocalLayers
function(layersArray) : Array.<OpenLayers.Layer>helper# Filters an array of layers down to the visible WMS layers.
getLocalLayersWritten as ExtjsUtils.LAYER.getLocalLayers
Filters an array of layers down to the visible WMS layers. Composed (calculation) layers that have no expression are replaced by their inner layers, which go through the same test. The input array is not modified.
- layersArray Array.<OpenLayers.Layer>
- Layers to filter, typically
app.mapPanel.map.layers.
Returns The visible WMS layers found.
var visibleWms = ExtjsUtils.LAYER.getLocalLayers(app.mapPanel.map.layers);getMapName
function(layer) : Stringhelper# The stable name of a map layer: the WMS LAYERS it requests (e.g. "CSR:cultivo_cafe_cafe"), or layer.name for layers without one (vector, XYZ/OSM — "OSM Mapnik").
getMapNameWritten as ExtjsUtils.LAYER.getMapName
The stable name of a map layer: the WMS LAYERS it requests (e.g. "CSR:cultivo_cafe_cafe"), or layer.name for layers without one (vector, XYZ/OSM — "OSM Mapnik"). A WMS layer's own name is replaced by its display title once its capabilities load, so it cannot identify the map; this can. Offline areas record their maps (layerNames) under this name.
- layer OpenLayers.Layer
- The layer.
Returns The map name.
var names = app.mapPanel.map.layers.map(ExtjsUtils.LAYER.getMapName);getPixelCoordinateSize
function(projection) : Objecthelper# Returns the size of one screen pixel in map units at the current zoom level, as the difference between the coordinates of pixels (0, 0) and (1, 1) expressed in the given projection.
getPixelCoordinateSizeWritten as ExtjsUtils.LAYER.getPixelCoordinateSize
Returns the size of one screen pixel in map units at the current zoom level, as the difference between the coordinates of pixels (0, 0) and (1, 1) expressed in the given projection. Only meaningful for projections where the pixel size is constant across the view.
- projection String|OpenLayers.Projection
- Projection to express the size in (e.g.
layer.projection); omit to use the map projection.
Returns {lon, lat} — width and height of a pixel in units of projection.
var px = ExtjsUtils.LAYER.getPixelCoordinateSize("EPSG:4326");
console.log("one pixel spans", px.lon, "degrees of longitude");getSourceByName
function(sourceName) : Objecthelper# Returns the source plugin instance registered under an id (e.g. 'local'), whose store holds one record per layer the source offers.
getSourceByNameWritten as ExtjsUtils.LAYER.getSourceByName
Returns the source plugin instance registered under an id (e.g. 'local'), whose store holds one record per layer the source offers. undefined for an unknown id.
- sourceName String
- Source id, one of
getLayerSourceNames().
Returns The source plugin (e.g. a gxp.plugins.WMSSource).
var localStore = ExtjsUtils.LAYER.getSourceByName('local').store;getStorageBaseUrl
function(storageLayer) : Stringhelper# Builds the base URL of the pre-computed ("storage") responses of a WMS layer and style: the layer source URL (without its getCapabilities.xml suffix) followed by /<layer name without workspace>/<style name or 1>/.
getStorageBaseUrlWritten as ExtjsUtils.LAYER.getStorageBaseUrl
Builds the base URL of the pre-computed ("storage") responses of a WMS layer and style: the layer source URL (without its getCapabilities.xml suffix) followed by /<layer name without workspace>/<style name or 1>/. Internal to the storage-backed calculations; listed for completeness.
- storageLayer OpenLayers.Layer.WMS
- WMS layer whose
params.LAYERSandparams.STYLESidentify the stored responses.
Returns The base URL, ending with /.
var base = ExtjsUtils.LAYER.getStorageBaseUrl(layer); // ".../estados/1/"getStoreLayerStylesFromName
function(layerName) : Array.<String>helper# Returns the names of the styles a layer is published with, read from the layer's store record (the WMS capabilities).
getStoreLayerStylesFromNameWritten as ExtjsUtils.LAYER.getStoreLayerStylesFromName
Returns the names of the styles a layer is published with, read from the layer's store record (the WMS capabilities). Empty when the layer is unknown.
- layerName String
- Full layer name, e.g.
'CSR:estados'.
Returns The style names of the layer.
// Add every style of a remote layer as its own map entry
ExtjsUtils.LAYER.getStoreLayerStylesFromName('remote:landuse').forEach(function(style) {
ExtjsUtils.QUERY.addLayer({ name: 'remote:landuse', title: style, styles: style, source: 'remote' });
});getStoreLayersNames
function(storeName) : Array.<String>helper# Returns the full names of all the layers offered by the sources — every source, or only the one given by storeName.
getStoreLayersNamesWritten as ExtjsUtils.LAYER.getStoreLayersNames
Returns the full names of all the layers offered by the sources — every source, or only the one given by storeName. Typical use: enumerate what a remote WMS server registered with QUERY.addRemoteWMSServer publishes, to add its layers to the map.
- storeName String
- Source id to restrict the listing to (see
getLayerSourceNames); omit for all sources.
Returns The layer names ('workspace:layer').
ExtjsUtils.LAYER.getStoreLayersNames('remote').forEach(function(name) {
ExtjsUtils.QUERY.addLayer({ name: name, title: name, source: 'remote', visibility: false });
});getVisibleLayers
function(mapStores, sortTop) : Array.<OpenLayers.Layer>helper# Returns the visible WMS layers of the map (see getLocalLayers), by default ordered from the topmost layer down — i.e. the order in which they may be under the mouse.
getVisibleLayersWritten as ExtjsUtils.LAYER.getVisibleLayers
Returns the visible WMS layers of the map (see getLocalLayers), by default ordered from the topmost layer down — i.e. the order in which they may be under the mouse.
- mapStores Array.<OpenLayers.Layer>
- Layers to search; defaults to all layers of the map.
- sortTop Boolean
true/omitted to sort the result from the highest to the lowestz-index;falseto keep the map order.
Returns The visible layers, topmost first unless sortTop is false.
var topLayer = ExtjsUtils.LAYER.getVisibleLayers()[0];isBackgroundLayerOrRecord
function(recordOrLayer) : Booleanhelper# Tells whether a layer or a layer record is a background map.
isBackgroundLayerOrRecordWritten as ExtjsUtils.LAYER.isBackgroundLayerOrRecord
Tells whether a layer or a layer record is a background map. Mappia basemaps are the layers declared with group: "background" (checked on the layer, on its json definition and on the record data); plain OpenLayers base layers (isBaseLayer) also count.
- recordOrLayer OpenLayers.Layer|GeoExt.data.LayerRecord
- The layer or layer record to test.
Returns true for a background map, false otherwise (also for null/undefined).
var overlays = app.mapPanel.map.layers.filter(function(layer) {
return !ExtjsUtils.LAYER.isBackgroundLayerOrRecord(layer);
});isOnHover
function(layer, mouseEvt) : Booleanhelper# Informs if the mouse is over the current layer.
isOnHoverWritten as ExtjsUtils.LAYER.isOnHover
Informs if the mouse is over the current layer.
- layer Layer|Composer
- Layer to check if the mouse is over.
- mouseEvt Event
- The mouse event.
Returns Returns true if the mouse is over the 'layer', False otherwise.
layerExists
function(layerName) : Booleanhelper# Tells whether some source offers a layer with the given full name — i.e. whether getLayersRecords(layerName) finds a record.
layerExistsWritten as ExtjsUtils.LAYER.layerExists
Tells whether some source offers a layer with the given full name — i.e. whether getLayersRecords(layerName) finds a record. Useful to guard QUERY.addLayer against a name that is not published by any server.
- layerName String
- Full layer name, e.g.
'CSR:estados'.
Returns true when a source has the layer, false otherwise.
if (ExtjsUtils.LAYER.layerExists('CSR:estados')) ExtjsUtils.QUERY.addLayer({ name: 'CSR:estados', title: 'States' });layerSourceRequireCORS
function(layerNameID) : Booleanhelper# Tells whether the source a layer comes from was registered with cors: true — i.e. its tiles must be fetched through the CORS proxy before their pixels can be read (remote WMS servers added with …
layerSourceRequireCORSWritten as ExtjsUtils.LAYER.layerSourceRequireCORS
Tells whether the source a layer comes from was registered with cors: true — i.e. its tiles must be fetched through the CORS proxy before their pixels can be read (remote WMS servers added with QUERY.addRemoteWMSServer).
- layerNameID String
- Full layer name (
'workspace:layer').
Returns true when the layer source requires CORS, false otherwise (also when the layer is in no source).
// 'myserver' being a source registered with QUERY.addRemoteWMSServer
if (ExtjsUtils.LAYER.layerSourceRequireCORS('myserver:landuse')) console.log('tiles go through the CORS proxy');loadWait
function(layer, url, success, failure, useCors)helper# Loads a URL while making a layer wait for it: the layer's startLoadingResource event is fired before the request and endLoadingResource after it, so the layer's calculations are on hold until the resource arrives.
loadWaitWritten as ExtjsUtils.LAYER.loadWait
Loads a URL while making a layer wait for it: the layer's startLoadingResource event is fired before the request and endLoadingResource after it, so the layer's calculations are on hold until the resource arrives. The success/failure callbacks run before the layer is notified. Use it from a layer's beforeCalc (or similar hooks) to fetch data the layer expression depends on.
- layer OpenLayers.Layer
- Layer that must wait for the resource.
- url String
- URL to load.
- success function
- Called with the response (
XMLHttpRequest) on success. - failure function
- Called on failure (no arguments).
- useCors Boolean
truewhen the URL is on another host, to fetch it through the CORS proxy (REQUEST.getCORS) instead ofREQUEST.get.
ExtjsUtils.LAYER.loadWait(this, '/wmtp/data/thresholds.json', function(resp) {
window.thresholds = JSON.parse(resp.responseText);
}, function() {
ExtjsUtils.ALERTIFY.log('Could not load the thresholds');
});sortTopLayers
function(layersArray) : Array.<OpenLayers.Layer>helper# Sorts an array of layers so the ones drawn on top come first (decreasing z-index of the layer div).
sortTopLayersWritten as ExtjsUtils.LAYER.sortTopLayers
Sorts an array of layers so the ones drawn on top come first (decreasing z-index of the layer div). The array is sorted in place and also returned.
- layersArray Array.<OpenLayers.Layer>
- Layers to sort, e.g. the result of
getLocalLayers.
Returns The same array, ordered from the topmost layer to the bottom one.
var topFirst = ExtjsUtils.LAYER.sortTopLayers(ExtjsUtils.LAYER.getLocalLayers(app.mapPanel.map.layers));tileSize
Number# Expected size, in pixels, of the square tiles a WMS layer is drawn with (256).
tileSizeWritten as ExtjsUtils.LAYER.tileSize
Expected size, in pixels, of the square tiles a WMS layer is drawn with (256). Used by the pixel-reading helpers (getLayerTilesFeatureIntersects) to walk a layer's tile images.
var pixelsPerTile = ExtjsUtils.LAYER.tileSize * ExtjsUtils.LAYER.tileSize;zoomMapsExtents
function(includeHidden, closest) : Array.<Number>helper# Zooms the map to the smallest extent containing every query layer: the union of the extents (getLayerExtent) of the local, file and remote layers that have a bounding box, skipping background …
zoomMapsExtentsWritten as ExtjsUtils.LAYER.zoomMapsExtents
Zooms the map to the smallest extent containing every query layer: the union of the extents (getLayerExtent) of the local, file and remote layers that have a bounding box, skipping background layers and — unless includeHidden is true — hidden layers. Nothing happens when no layer qualifies. Commonly called from onToggleViewGroup to re-frame the map when a group is expanded.
- includeHidden Boolean
trueto also count layers that are not visible.- closest Boolean
trueto zoom as close as possible even if parts of the extent fall outside the viewport;false/omitted to fit the whole extent on screen.
Returns The union extent as [left, bottom, right, top] in the map projection (all zeros when no layer qualified).
// In a group definition: re-frame the map on the visible layers when the group opens
onToggleViewGroup: function(view) {
if (view.expanded) ExtjsUtils.LAYER.zoomMapsExtents(false);
}LEGENDS · legend lookup
LEGENDS1 entryUsage: ExtjsUtils.LEGENDS
getColorTitle
function(layer, r, g, b) : String|nullhelper# Finds the legend entry of a layer whose colour is exactly (r, g, b) and returns its title — the way to map a pixel colour read from the map back to the legend class it represents.
getColorTitleWritten as ExtjsUtils.LEGENDS.getColorTitle
Finds the legend entry of a layer whose colour is exactly (r, g, b) and returns its title — the way to map a pixel colour read from the map back to the legend class it represents. Works on layers exposing getLegendEntries() (composed/calculation layers).
- layer OpenLayers.Layer
- Layer whose legend entries are searched.
- r Number
- Red component of the colour (0-255).
- g Number
- Green component of the colour (0-255).
- b Number
- Blue component of the colour (0-255).
Returns The title of the legend entry with that colour, or null when no entry matches.
var rgba = ExtjsUtils.LAYER.getLayerColorAtPoint(layer.layers[0], ExtjsUtils.HTML.getAbsolutePointFromMouseEvent(evt));
if (rgba) console.log('Class under the mouse:', ExtjsUtils.LEGENDS.getColorTitle(layer, rgba[0], rgba[1], rgba[2]));NUMBER · format numbers
Number2 entriesabbreviateNumber
function(value, useFixed, abbreviateNumbers) : Number|Stringhelper# Auxiliary function to shorten the display of numbers.
abbreviateNumberWritten as ExtjsUtils.NUMBER.abbreviateNumber
Auxiliary function to shorten the display of numbers.
PS: The number loses a little precision but becomes more meaningful.
- value Number
- Value to be displayed.
- useFixed Number
- If set it will limit the number of decimal places, otherwise it will use the default value.
- abbreviateNumbers Array.<Number>
- Number suffix name.
Returns Simplified value to be displayed. Can return a number or a string.
numericToString
function(value) : Stringhelper# Formats a number for display with toLocaleString() (thousands separator and decimal mark).
numericToStringWritten as ExtjsUtils.NUMBER.numericToString
Formats a number for display with toLocaleString() (thousands separator and decimal mark). It was written to follow the interface language (pt-br or en-IN), but the current implementation compares the value itself with the language codes, so for a number it always falls back to the browser's default locale.
- value Number
- Value to be represented as a string.
Returns The localized string representation of the value.
ExtjsUtils.NUMBER.numericToString(1234567.5); // "1.234.567,5" in a pt-BR browserOBSERVABILITY · console events
OBSERVABILITY2 entriesUsage: ExtjsUtils.OBSERVABILITY
event
function(eventName, payload, level)helper# Logs a structured diagnostic event to the console as [MappiaObservability] {event, ts, page_origin, payload} — with console.error when level is "error", console.warn otherwise — and …
eventWritten as ExtjsUtils.OBSERVABILITY.event
Logs a structured diagnostic event to the console as [MappiaObservability] {event, ts, page_origin, payload} — with console.error when level is "error", console.warn otherwise — and forwards the same entry to window.__mappiaObservabilityHook(entry) when the host page defines that function. Useful to report tenant-side failures in a way the embedding site can collect.
- eventName String
- Dotted event name, e.g.
"mappia.fetch.cors_blocked". - payload Object
- Extra data attached to the entry (defaults to
{}). - level String
"error"to log withconsole.error; anything else logs a warning.
ExtjsUtils.OBSERVABILITY.event("myquery.csv.load_failed", { url: csvUrl }, "error");installFetchFailureHook
function()helper# Installs (once) a window "unhandledrejection" listener that turns unhandled fetch failures whose message mentions "failed to fetch", "cors" or "network error" into an …
installFetchFailureHookWritten as ExtjsUtils.OBSERVABILITY.installFetchFailureHook
Installs (once) a window "unhandledrejection" listener that turns unhandled fetch failures whose message mentions "failed to fetch", "cors" or "network error" into an OBSERVABILITY.event("mappia.fetch.cors_blocked", {message, page_origin, hint}, "error") entry, so CORS/network problems of cross-origin requests show up with a hint instead of a silent rejection. The platform calls it at start-up; calling it again is a no-op.
ExtjsUtils.OBSERVABILITY.installFetchFailureHook();REQ_PARAMS · URL parameter parsers
REQ_PARAMS1 entryUsage: ExtjsUtils.REQ_PARAMS
getQntVisibleLayers
function() : Number|nullhelper# Reads the visiblelayers URL parameter, which overrides how many layers of the query start visible (see URLProperties.visiblelayers).
getQntVisibleLayersWritten as ExtjsUtils.REQ_PARAMS.getQntVisibleLayers
Reads the visiblelayers URL parameter, which overrides how many layers of the query start visible (see URLProperties.visiblelayers). Values: a positive N shows the first N layers in query order (the top of the layer list); a negative -N shows the last N (the bottom of the list); 0 shows none; custom keeps the visibility each layer defines in the query (returns null). When the parameter is omitted the result is 1 if the URL has options=onlyfirstvisible, otherwise null (the query's own visibilities apply).
Returns Number of layers to show (positive from the top, negative from the bottom), or null to keep the query's own visibilities.
// ?visiblelayers=-2 -> the last two layers of the query start visible
var qnt = ExtjsUtils.REQ_PARAMS.getQntVisibleLayers(); // -2REQUEST · page address and network
Request29 entriesCORS_URL
String# Path of the server-side CORS proxy without caching (/cors/direct/).
CORS_URLWritten as ExtjsUtils.REQUEST.CORS_URL
Path of the server-side CORS proxy without caching (/cors/direct/). Prefix a cross-origin URL with it when the response must always be fresh.
ExtjsUtils.REQUEST.get(ExtjsUtils.REQUEST.CORS_URL + "https://example.org/live.json", onOk, onFail);CORS_URL_CACHED
String# Path of the server-side CORS proxy with caching (/cors/); getCORS prefixes the target URL with it.
CORS_URL_CACHEDWritten as ExtjsUtils.REQUEST.CORS_URL_CACHED
Path of the server-side CORS proxy with caching (/cors/); getCORS prefixes the target URL with it. Use it to fetch a cross-origin resource that may be cached.
ExtjsUtils.REQUEST.get(ExtjsUtils.REQUEST.CORS_URL_CACHED + "https://example.org/data.json", onOk, onFail);Response
function(success, url)helper# Constructor of the small object a file layer passes to its endLoadingLayer event (new ExtjsUtils.REQUEST.Response(success, url)), wrapping the outcome of the data request.
ResponseWritten as ExtjsUtils.REQUEST.Response
Constructor of the small object a file layer passes to its endLoadingLayer event (new ExtjsUtils.REQUEST.Response(success, url)), wrapping the outcome of the data request. Instances expose getSuccess() (Boolean, true when the request succeeded) and getUrl() (String, the requested URL). Tenant code normally only reads it in the event listener.
- success Boolean
- True when the request succeeded, false on error.
- url String
- URL of the request.
layer.events.on({endLoadingLayer: function(response) {
if (!response.getSuccess()) ExtjsUtils.ALERTIFY.log("Failed to load " + response.getUrl());
}});abort
function(scope) : Numberhelper# Aborts every unfinished abortable request (getAbortable/getAbortables) started with the given scope.
abortWritten as ExtjsUtils.REQUEST.abort
Aborts every unfinished abortable request (getAbortable/getAbortables) started with the given scope. The failed callback of each aborted request is invoked with wasAborted = true.
- scope Object
- The scope object the requests were registered with.
Returns How many requests were aborted.
var owner = {};
ExtjsUtils.REQUEST.getAbortable("/theme/app/data/totals.csv", onOk, onFail, false, owner);
// later, e.g. when the user changes the selection:
ExtjsUtils.REQUEST.abort(owner);createRequestObject
function(url, success, failed, forceSynchronous, scope) : Objecthelper# Builds the request description consumed by getAbortables: an object exposing getURL(), getSuccess(), getFailed(), getForceSynchronous() and getScope().
createRequestObjectWritten as ExtjsUtils.REQUEST.createRequestObject
Builds the request description consumed by getAbortables: an object exposing getURL(), getSuccess(), getFailed(), getForceSynchronous() and getScope(). At least one of the two callbacks must be given.
- url String
- URL of the request.
- success function
- Success callback, called as
success.call(scope, xhr, wasAborted). - failed function
- Failure callback, called as
failed.call(scope, xhr, wasAborted). - forceSynchronous Boolean
- True (deprecated) to make the request synchronous.
- scope Object
thisfor the callbacks; also the scope used byabort.
Returns The request object to pass to getAbortables.
var req = ExtjsUtils.REQUEST.createRequestObject("/theme/app/data/totals.csv", function(xhr) {
this.totals = xhr.responseText;
}, null, false, this);downloadFile
function(fileUrl)helper# Triggers a browser download of a file: creates a temporary <a download target="_blank"> pointing at the URL, clicks it and removes it.
downloadFileWritten as ExtjsUtils.REQUEST.downloadFile
Triggers a browser download of a file: creates a temporary <a download target="_blank"> pointing at the URL, clicks it and removes it. The suggested file name is the last segment of the URL. Typical use is a "download the data" button in a query.
- fileUrl String
- URL of the file to download.
ExtjsUtils.REQUEST.downloadFile("/theme/app/data/example_fire_history.csv");get
function(url, success, failed, forceSynchronous, scope) : XMLHttpRequesthelper# Plain AJAX GET request.
getWritten as ExtjsUtils.REQUEST.get
Plain AJAX GET request. The usual way for query code to fetch a CSV/JSON/text resource from the Mappia server (/theme/app/data/..., a WFS GetFeature on the local GeoServer) or from any server that allows the page origin (CORS); cookies are sent on cross-origin calls. For servers without CORS headers use getCORS. Both callbacks receive the XMLHttpRequest as their only argument — read xhr.responseText.
- url String
- URL to load (relative to the page or absolute, including the protocol).
- success function
- Called with the XMLHttpRequest when the status is 200.
- failed function
- Called with the XMLHttpRequest on any other status.
- forceSynchronous Boolean
- True to make the request synchronous (deprecated), false for asynchronous.
- scope Object
thisfor thesuccessandfailedcallbacks.
Returns The request object (can be aborted with xhr.abort()).
var url = ExtjsUtils.REQUEST.getGeoserverBaseUrl() + "/wfs?service=WFS&version=1.0.0&request=GetFeature" +
"&typename=CSR:example_layer&outputFormat=json&CQL_FILTER=code='" + code + "'";
ExtjsUtils.REQUEST.get(url, function(xhr) {
var features = ExtjsUtils.GEOJSON.geojson2Features(JSON.parse(xhr.responseText));
ExtjsUtils.ZOOM.zoomToExtent(features[0].geometry.getBounds());
}, function(xhr) {
ExtjsUtils.ALERTIFY.alert("Request failed: " + xhr.status);
});getAbortable
function(url, success, failed, forceSynchronous, scope) : XMLHttpRequesthelper# Same as get, but the request is registered under scope so it can be cancelled later with abort(scope).
getAbortableWritten as ExtjsUtils.REQUEST.getAbortable
Same as get, but the request is registered under scope so it can be cancelled later with abort(scope). The callbacks receive (xhr, wasAborted); when the request is aborted the failed callback runs with wasAborted = true. A scope is mandatory.
- url String
- URL to load.
- success function
- Called as
success.call(scope, xhr, wasAborted)when the status is 200. - failed function
- Called as
failed.call(scope, xhr, wasAborted)on any other status or on abort. - forceSynchronous Boolean
- True (deprecated) to make the request synchronous.
- scope Object
- Object identifying the owner of the request (used by
abort) andthisfor the callbacks.
Returns The request object.
var owner = {};
ExtjsUtils.REQUEST.getAbortable("/theme/app/data/totals.csv", function(xhr) {
showTotals(xhr.responseText);
}, function(xhr, wasAborted) {
if (!wasAborted) ExtjsUtils.ALERTIFY.log("Could not load the totals.");
}, false, owner);
// ExtjsUtils.REQUEST.abort(owner) cancels it.getAbortables
function(requestObjects, afterAll, afterScope) : Array.<XMLHttpRequest>helper# Runs a group of abortable GET requests (built with createRequestObject) and calls afterAll once every one of them has finished (success, failure or abort).
getAbortablesWritten as ExtjsUtils.REQUEST.getAbortables
Runs a group of abortable GET requests (built with createRequestObject) and calls afterAll once every one of them has finished (success, failure or abort). Each request's own callbacks run first; afterAll receives the arguments of the last request to finish ([xhr, wasAborted]).
- requestObjects Array.<Object>|Object
- Request objects from
createRequestObject(a single object is accepted). - afterAll function
- Called after the last request finishes.
- afterScope Object
thisforafterAll; defaults to the scope of the last finished request.
Returns The request objects that were started.
var owner = {};
ExtjsUtils.REQUEST.getAbortables([
ExtjsUtils.REQUEST.createRequestObject("/theme/app/data/a.csv", function(xhr) { this.a = xhr.responseText; }, null, false, owner),
ExtjsUtils.REQUEST.createRequestObject("/theme/app/data/b.csv", function(xhr) { this.b = xhr.responseText; }, null, false, owner)
], function() {
buildChart(owner.a, owner.b);
});getBaseMappia
function() : Stringhelper# Returns the base URL of the Mappia server for platform endpoints such as /query/description/<id>/: an empty string (relative URLs) when the page is served from maps.csr.ufmg.br without a …
getBaseMappiaWritten as ExtjsUtils.REQUEST.getBaseMappia
Returns the base URL of the Mappia server for platform endpoints such as /query/description/<id>/: an empty string (relative URLs) when the page is served from maps.csr.ufmg.br without a ?geoserver= override, otherwise the absolute https://maps.csr.ufmg.br. Not configurable at the moment.
Returns "" or "https://maps.csr.ufmg.br".
ExtjsUtils.REQUEST.get(ExtjsUtils.REQUEST.getBaseMappia() + "/query/description/1/", onLoad);getCORS
function(url, success, failed, forceSynchronous) : XMLHttpRequesthelper# GET request to a cross-origin URL through the platform's cached CORS proxy (CORS_URL_CACHED + url), for servers that do not send CORS headers.
getCORSWritten as ExtjsUtils.REQUEST.getCORS
GET request to a cross-origin URL through the platform's cached CORS proxy (CORS_URL_CACHED + url), for servers that do not send CORS headers. Both callbacks receive the XMLHttpRequest (read responseText). Ext's Ajax cannot be used for this because it adds an X-Requested-With header that breaks such requests.
- url String
- Full URL to load, including the protocol (
https://...). - success function
- Called with the XMLHttpRequest when the status is 200.
- failed function
- Called with the XMLHttpRequest on any other status.
- forceSynchronous Boolean
- True to make the request synchronous (deprecated).
Returns The request object.
ExtjsUtils.REQUEST.getCORS("https://example.org/api/property?code=" + code, function(xhr) {
var data = JSON.parse(xhr.responseText);
}, function(xhr) {
ExtjsUtils.ALERTIFY.log("Could not load the property data.");
});getCommaSeparatedArguments
function(paramName) : Array.<String>helper# Reads a URL parameter that holds a comma-separated list and returns its items — the way ?options=, ?tools= and custom list parameters (?remotemap=a,b,c) are read.
getCommaSeparatedArgumentsWritten as ExtjsUtils.REQUEST.getCommaSeparatedArguments
Reads a URL parameter that holds a comma-separated list and returns its items — the way ?options=, ?tools= and custom list parameters (?remotemap=a,b,c) are read.
- paramName String
- Name of the URL parameter.
Returns The items of the list; an empty array when the parameter is absent or empty.
// page opened as /calculator/?queryid=1&points=A,B,C
ExtjsUtils.REQUEST.getCommaSeparatedArguments("points"); // ["A", "B", "C"]getGeoserverBaseUrl
function() : Stringhelper# Returns the GeoServer base URL in use by the local source (from the ?geoserver= URL parameter, default /geoserver), without a trailing slash — use it to build WFS/WMS requests against the same …
getGeoserverBaseUrlWritten as ExtjsUtils.REQUEST.getGeoserverBaseUrl
Returns the GeoServer base URL in use by the local source (from the ?geoserver= URL parameter, default /geoserver), without a trailing slash — use it to build WFS/WMS requests against the same server the map layers come from.
Returns The GeoServer base URL.
var wfs = ExtjsUtils.REQUEST.getGeoserverBaseUrl() + "/wfs?service=WFS&version=1.0.0&request=GetFeature&typename=CSR:example&outputFormat=json";getHost
function() : Stringhelper# Returns the origin of the current page — protocol plus host, without a trailing slash (e.g. 'https://maps.csr.ufmg.br') — for building absolute URLs to the same server.
getHostWritten as ExtjsUtils.REQUEST.getHost
Returns the origin of the current page — protocol plus host, without a trailing slash (e.g. 'https://maps.csr.ufmg.br') — for building absolute URLs to the same server.
Returns The page protocol and host.
var wfs = ExtjsUtils.REQUEST.getHost() + "/geoserver/wfs?service=WFS&request=GetFeature";getMapObject
function(curDefinition, source) : Objecthelper# Builds a layer configuration object from the compact name;style;opacity string used by the ?map= URL parameter (see URLProperties.map): {name, source, styles, opacity} with styles/opacity …
getMapObjectWritten as ExtjsUtils.REQUEST.getMapObject
Builds a layer configuration object from the compact name;style;opacity string used by the ?map= URL parameter (see URLProperties.map): {name, source, styles, opacity} with styles/opacity present only when given (both URL-decoded).
- curDefinition String
- Layer definition such as
CSR:example_layer;example_style;0.8. - source String
- Name of the layer source; the default
localsource when empty.
Returns A layer configuration ready for QUERY.addLayer.
ExtjsUtils.REQUEST.getMapObject("CSR:example_layer;example_style");
// {name: "CSR:example_layer", source: "local", styles: "example_style"}getParameterByName
function(name) : Stringhelper# Reads a parameter of the page URL query string (?name=value), URL-decoded, with + turned into spaces.
getParameterByNameWritten as ExtjsUtils.REQUEST.getParameterByName
Reads a parameter of the page URL query string (?name=value), URL-decoded, with + turned into spaces. This is the standard way for a query to receive external input (a property code, a language, a colour) from the embedding page. The name match is case-insensitive.
- name String
- Name of the URL parameter.
Returns The decoded value, or an empty string when the parameter is absent.
// page opened as /calculator/?queryid=1&car=MG-1234567-ABCD
var car = ExtjsUtils.REQUEST.getParameterByName("car"); // "MG-1234567-ABCD"
if (car) loadProperty(car);getProtocol
function() : Stringhelper# Returns the protocol of the current page, including the colon ('http:' or 'https:').
getProtocolWritten as ExtjsUtils.REQUEST.getProtocol
Returns the protocol of the current page, including the colon ('http:' or 'https:').
Returns The page protocol.
var url = ExtjsUtils.REQUEST.getProtocol() + "//maps.csr.ufmg.br/geoserver/wms";getRelativeRootUri
function(relativeUrl) : Stringhelper# Resolves a path against the application root: takes the current page URL, strips the /calculator/ or /editor/ segment (and any .html file name) and appends relativeUrl.
getRelativeRootUriWritten as ExtjsUtils.REQUEST.getRelativeRootUri
Resolves a path against the application root: takes the current page URL, strips the /calculator/ or /editor/ segment (and any .html file name) and appends relativeUrl. Use it to load platform assets (/theme/app/...) from a page that lives in a sub-folder or on another host.
- relativeUrl String
- Path relative to the application root (leading slash optional).
Returns The absolute URL of the resource.
ExtjsUtils.REQUEST.getRelativeRootUri("/theme/app/js/jsts.min.js"); // "https://maps.csr.ufmg.br/theme/app/js/jsts.min.js"isEditor
function() : Booleanhelper# Tells whether the current page is the query editor (/editor/) rather than the viewer (/calculator/), so query code can skip viewer-only decoration while being edited.
isEditorWritten as ExtjsUtils.REQUEST.isEditor
Tells whether the current page is the query editor (/editor/) rather than the viewer (/calculator/), so query code can skip viewer-only decoration while being edited.
Returns True when the page is the editor, false otherwise.
if (!ExtjsUtils.REQUEST.isEditor()) ExtjsUtils.QUERY.decorate({noTop: true});isHttps
function() : Booleanhelper# Tells whether the page is being served over HTTPS.
isHttpsWritten as ExtjsUtils.REQUEST.isHttps
Tells whether the page is being served over HTTPS.
Returns True when the page protocol is https:, false otherwise.
var scheme = ExtjsUtils.REQUEST.isHttps() ? "https://" : "http://";isLocalUrl
function(url) : Booleanhelper# Identify if the 'url' is from the localhost or is from the maps.csr.ufmg.br domain.
isLocalUrlWritten as ExtjsUtils.REQUEST.isLocalUrl
Identify if the 'url' is from the localhost or is from the maps.csr.ufmg.br domain.
PS: If url is left blank it uses the current site url.
- url String
- String with the url to be checked.
Returns Returns true if the url is from localhost, otherwise it returns false.
ExtjsUtils.REQUEST.isLocalUrl() // trueExtjsUtils.REQUEST.isLocalUrl("www.google.com") // falsemapHostGeoserverUrl
function(url) : Stringhelper# Forces a /geoserver/... GetMap (or similar) URL onto the map iframe's configured GeoServer (?geoserver= / getGeoserverBaseUrl(), default /geoserver on this origin).
mapHostGeoserverUrlWritten as ExtjsUtils.REQUEST.mapHostGeoserverUrl
Forces a /geoserver/... GetMap (or similar) URL onto the map iframe's configured GeoServer (?geoserver= / getGeoserverBaseUrl(), default /geoserver on this origin). Capabilities OnlineResource often names https://maps.csr.ufmg.br/geoserver/... even when the calculator runs on another host — live tiles and OfflineAreas cache keys must use the map host, not that external absolute URL. Non-/geoserver URLs (OSM, remote WMS, GitHub stores) are returned unchanged.
- url String
- Absolute or relative WMS URL.
Returns URL under the map's GeoServer base, or the original URL.
ExtjsUtils.REQUEST.mapHostGeoserverUrl("https://maps.csr.ufmg.br/geoserver/wms?REQUEST=GetMap");
// on https://localhost → "https://localhost/geoserver/wms?REQUEST=GetMap"mixedContentUrlFix
function(url) : Stringhelper# Rewrites an http://maps.csr.ufmg.br (or http://localhost) URL to the protocol and host of the current page, avoiding mixed-content and CORS errors when the page is served over HTTPS.
mixedContentUrlFixWritten as ExtjsUtils.REQUEST.mixedContentUrlFix
Rewrites an http://maps.csr.ufmg.br (or http://localhost) URL to the protocol and host of the current page, avoiding mixed-content and CORS errors when the page is served over HTTPS. Other URLs are returned unchanged.
- url String
- URL of the request.
Returns The URL using the same protocol/host as the page.
ExtjsUtils.REQUEST.mixedContentUrlFix("http://maps.csr.ufmg.br/geoserver/wms"); // "https://maps.csr.ufmg.br/geoserver/wms" on an https pageonRequestError
function(response)helper# Generic failure handler for requests: shows a modal Ext.Msg.alert with the server's responseText, or the "server unreachable" message when there is none.
onRequestErrorWritten as ExtjsUtils.REQUEST.onRequestError
Generic failure handler for requests: shows a modal Ext.Msg.alert with the server's responseText, or the "server unreachable" message when there is none. Pass it as the failed callback of get/post when a plain error dialog is enough.
- response Object
- Response object (XMLHttpRequest or Ext response) of the failed request, when available.
ExtjsUtils.REQUEST.get("/theme/app/data/totals.csv", onOk, ExtjsUtils.REQUEST.onRequestError);post
function(url, params, success, failed, forceSynchronous, scope)helper# AJAX POST of a form-encoded body: params is serialized with encodeURIComponent as application/x-www-form-urlencoded.
postWritten as ExtjsUtils.REQUEST.post
AJAX POST of a form-encoded body: params is serialized with encodeURIComponent as application/x-www-form-urlencoded. Cookies are sent on cross-origin calls. Both callbacks receive the XMLHttpRequest — typical use is sending a clicked coordinate or a form to an external report service from a layer onClick handler.
- url String
- URL to post to (relative or absolute, including the protocol).
- params Object
- Key/value pairs sent as the request body.
- success function
- Called with the XMLHttpRequest when the status is 200.
- failed function
- Called with the XMLHttpRequest on any other status.
- forceSynchronous Boolean
- True (deprecated) to make the request synchronous.
- scope Object
thisfor the callbacks.
ExtjsUtils.REQUEST.post("https://example.org/report.php", {lat: lonLat.lat, lon: lonLat.lon}, function(xhr) {
document.getElementById("report").innerHTML = xhr.responseText;
}, function(xhr) {
ExtjsUtils.ALERTIFY.log("Report service unavailable.");
}, false, this);removeHTTPProtocol
function(url) : Stringhelper# Strips a leading http: from a URL, turning it into a protocol-relative URL (//host/path) that follows the protocol of the page and avoids mixed-content blocks.
removeHTTPProtocolWritten as ExtjsUtils.REQUEST.removeHTTPProtocol
Strips a leading http: from a URL, turning it into a protocol-relative URL (//host/path) that follows the protocol of the page and avoids mixed-content blocks.
- url String
- URL to rewrite.
Returns The URL without the http: prefix (unchanged when it had none).
ExtjsUtils.REQUEST.removeHTTPProtocol("http://maps.csr.ufmg.br/geoserver/wms"); // "//maps.csr.ufmg.br/geoserver/wms"setGeoserverBaseUrl
function(url)helper# Sets the base URL of the GeoServer behind the local layer source (its WMS endpoint becomes url + "/wms").
setGeoserverBaseUrlWritten as ExtjsUtils.REQUEST.setGeoserverBaseUrl
Sets the base URL of the GeoServer behind the local layer source (its WMS endpoint becomes url + "/wms"). The platform calls it at startup with the ?geoserver= URL parameter, defaulting to /geoserver; query code rarely needs it. The URL must not end with a slash nor point at a service (.../wms), otherwise an error is logged.
- url String
- GeoServer base URL, absolute (
https://maps.csr.ufmg.br/geoserver) or relative to the root (/geoserver).
ExtjsUtils.REQUEST.setGeoserverBaseUrl("https://maps.csr.ufmg.br/geoserver");tryHttps
function()helper# Redirects the page to its HTTPS version once: the attempt is remembered in COOKIE.TRY_HTTPS, so when the browser cannot reach the HTTPS site and comes back over HTTP it is not redirected again.
tryHttpsWritten as ExtjsUtils.REQUEST.tryHttps
Redirects the page to its HTTPS version once: the attempt is remembered in COOKIE.TRY_HTTPS, so when the browser cannot reach the HTTPS site and comes back over HTTP it is not redirected again. Does nothing when already on HTTPS.
ExtjsUtils.REQUEST.tryHttps();urlOptions
function(property) : Boolean# Tells whether a token is present in the options URL parameter, the comma-separated list of advanced page options (?options=scale,startopened,hidestylechooser, see URLOptions).
urlOptionsTells whether a token is present in the options URL parameter, the comma-separated list of advanced page options (?options=scale,startopened,hidestylechooser, see URLOptions). The real call is ExtjsUtils.REQUEST.advToolsOptions("token"); query code uses it to react to custom tokens of its own.
- property String
- Option token to look for (exact, case-sensitive match).
Returns True when the token is present in ?options=, false otherwise.
// page opened as /calculator/?queryid=1&options=scale,startopened,compact
ExtjsUtils.REQUEST.advToolsOptions("startopened"); // true
if (ExtjsUtils.REQUEST.advToolsOptions("compact")) ExtjsUtils.QUERY.decorate({noTop: true});TooltipHelper · tooltips
TooltipHelper3 entriesUsage: ExtjsUtils.TooltipHelper
CreateTooltipOnPosition
function(title, contentHtml, position, additionalConfig) : Ext.Tooltiphelper# Create a tooltip at a fixed position.
CreateTooltipOnPositionWritten as ExtjsUtils.TooltipHelper.CreateTooltipOnPosition
Create a tooltip at a fixed position.
If the position is the mouse event, the tooltip will be at the right side and below the pointer. If the position is a array[x,y] will anchor the top left at this point.
- title String
- Tooltip title.
- contentHtml String
- Tooltip HTML content.
- position Event|Array.<Number>
- Defines the top left position of the tooltip. Can be either a mouse event at or an array [x:Number, y:Number] with the cursor position.
- additionalConfig Object
- Additional configuration for the tooltip.
Returns A tooltip anchored at the given position.
CreateTooltipThumb
function(title, description, target, thumbUrl, showDelay) : Ext.ToolTiphelper# Creates a mouse-tracking Ext.ToolTip on a DOM element with a title, a text description (rendered in a <pre>) and an optional thumbnail image.
CreateTooltipThumbWritten as ExtjsUtils.TooltipHelper.CreateTooltipThumb
Creates a mouse-tracking Ext.ToolTip on a DOM element with a title, a text description (rendered in a <pre>) and an optional thumbnail image. The tooltip ignores mouse events, so it never interferes with the hovered element, and is repositioned by onMoveFixPosition to stay beside the target and inside the viewport. The description is cut at the first sequence of three line breaks.
- title String
- Tooltip title (may be empty).
- description String
- Tooltip text.
- target HTMLElement
- Element that shows the tooltip on hover (the DOM element itself, not an id). Without it the tooltip is created unattached.
- thumbUrl String
- URL of an image shown above the text.
- showDelay Number
- Delay in milliseconds before the tooltip appears.
Returns The created tooltip.
var node = document.getElementById("field_area");
ExtjsUtils.TooltipHelper.CreateTooltipThumb("", "Area of the property in hectares.", node);onMoveFixPosition
function(ttip, x, y)helper# move listener for an Ext.ToolTip that keeps it usable: when the tooltip has a target, it is placed to the left or right of that element (whichever side has room, or the side nearer to the …
onMoveFixPositionWritten as ExtjsUtils.TooltipHelper.onMoveFixPosition
move listener for an Ext.ToolTip that keeps it usable: when the tooltip has a target, it is placed to the left or right of that element (whichever side has room, or the side nearer to the mouse), and in any case it is pushed back inside the page when it would overflow the bottom or right edge. CreateTooltipThumb wires it automatically; use it as listeners: {move: ExtjsUtils.TooltipHelper.onMoveFixPosition} on tooltips you build yourself.
- ttip Ext.ToolTip
- The tooltip being moved.
- x Number
- New absolute x position of the tooltip (page coordinates).
- y Number
- New absolute y position of the tooltip (page coordinates).
new Ext.ToolTip({target: node, html: "Details", trackMouse: true,
listeners: {move: ExtjsUtils.TooltipHelper.onMoveFixPosition}});ZOOM · zoom the map
ZOOM2 entrieslimitZoomLevel
function(zoomLvl)helper# Limits the map to a maximum zoom level: zooms out if the current zoom is above it and removes the deeper zoom levels from the map and its base layer.
limitZoomLevelWritten as ExtjsUtils.ZOOM.limitZoomLevel
Limits the map to a maximum zoom level: zooms out if the current zoom is above it and removes the deeper zoom levels from the map and its base layer. Typically called from the query runNow hook.
- zoomLvl Number
- Highest zoom level (integer) the user may reach.
ExtjsUtils.QUERY.setQueryGlobalProperties({ runNow: function() { ExtjsUtils.ZOOM.limitZoomLevel(17); } }) && QUERY_DESCRIPTIONzoomToExtent
function(bounds, closest, maxZoom) : Numberhelper# Zooms the map to the given bounds (shortcut for app.mapPanel.map.zoomToExtent).
zoomToExtentWritten as ExtjsUtils.ZOOM.zoomToExtent
Zooms the map to the given bounds (shortcut for app.mapPanel.map.zoomToExtent). The bounds must be in the map projection (EPSG:900913); use ExtjsUtils.bboxTransform or OpenLayers.Bounds.transform to convert lon/lat first. maxZoom keeps a small extent (one property, one point) from landing on a zoom deeper than useful — e.g. deeper than the zoom an offline area was downloaded to. Nothing happens when bounds is missing.
- bounds OpenLayers.Bounds|Array.<Number>|Object
- Extent to show, in the map projection (any shape
ExtjsUtils.toBoundsaccepts). - closest Boolean
- True to pick the zoom level closest to the extent even if it does not fully contain it.
- maxZoom Number
- Deepest zoom to end at; omitted ⇒ no limit.
Returns The map zoom after the call.
var bounds = new OpenLayers.Bounds(-48, -20, -40, -14).transform("EPSG:4326", "EPSG:900913");
ExtjsUtils.ZOOM.zoomToExtent(bounds);// fit a property, but not past zoom 16
ExtjsUtils.ZOOM.zoomToExtent(ExtjsUtils.LAYER.getLayerExtent("CSR:show_car"), false, 16);Offline maps
OFFLINE · offline areas
OFFLINE59 entriesUsage: ExtjsUtils.OFFLINE
CONCURRENCY
Number# Default number of tile requests downloadArea keeps in flight at once (6).
CONCURRENCYWritten as ExtjsUtils.OFFLINE.CONCURRENCY
Default number of tile requests downloadArea keeps in flight at once (6). Override per call with options.concurrency.
DB_NAME
String# Name of the IndexedDB database that keeps the offline area records: 'mappia_offline_areas'.
DB_NAMEWritten as ExtjsUtils.OFFLINE.DB_NAME
Name of the IndexedDB database that keeps the offline area records: 'mappia_offline_areas'. Informational — useful to find the records in the browser DevTools (Application → IndexedDB).
DB_VERSION
Number# Schema version of the area database (1).
DB_VERSIONWritten as ExtjsUtils.OFFLINE.DB_VERSION
Schema version of the area database (1). Bumped by the platform when the record layout changes; never set it yourself.
MAX_TILES_PER_AREA
Number# Default cap on the number of tiles a single area may enumerate (20000).
MAX_TILES_PER_AREAWritten as ExtjsUtils.OFFLINE.MAX_TILES_PER_AREA
Default cap on the number of tiles a single area may enumerate (20000). The tile count grows about 4x per zoom level, so this guardrail stops a pathological extent/zoom range before any tile is requested: downloadArea rejects with an "Area too large" error above it. Read it to show the limit in a UI, and pass options.maxTiles to downloadArea for a tighter or looser cap per call.
var count = ExtjsUtils.OFFLINE.estimateTileCountForLayers(extent, 10, 14);
if (count > ExtjsUtils.OFFLINE.MAX_TILES_PER_AREA) alert("Narrow the extent or the zoom range");STORE_NAME
String# Name of the object store (inside DB_NAME) that holds one record per area, keyed by the area id: 'areas'.
STORE_NAMEWritten as ExtjsUtils.OFFLINE.STORE_NAME
Name of the object store (inside DB_NAME) that holds one record per area, keyed by the area id: 'areas'.
activateLatestServiceWorker
function() : Promise.<Object>helper# Activates the newest installed service worker: asks a waiting/installing worker to skip waiting and the active one to claim the open pages, then waits (up to ~3 s) until none is left waiting.
activateLatestServiceWorkerWritten as ExtjsUtils.OFFLINE.activateLatestServiceWorker
Activates the newest installed service worker: asks a waiting/installing worker to skip waiting and the active one to claim the open pages, then waits (up to ~3 s) until none is left waiting. A page loaded under an older worker still needs a reload before its requests reach the new one (needsReload). Never rejects.
Returns getServiceWorkerStatus() plus {ok: true, activated}, or {ok: false, error}.
ExtjsUtils.OFFLINE.activateLatestServiceWorker().then(function(sw) {
if (sw.ok && sw.needsReload) location.reload();
});checkStorageQuota
function() : Promise.<Object>helper# Reports the browser's storage quota for this origin (navigator.storage.estimate): how much is used, how much the browser grants and the difference.
checkStorageQuotaWritten as ExtjsUtils.OFFLINE.checkStorageQuota
Reports the browser's storage quota for this origin (navigator.storage.estimate): how much is used, how much the browser grants and the difference. It says nothing about a particular area — compare available with estimateAreaBytes before a download. Older browsers without the Storage API report {unknown: true}.
Returns {unknown: false, usage, quota, available} in bytes, or {unknown: true}.
ExtjsUtils.OFFLINE.checkStorageQuota().then(function(q) {
if (!q.unknown) console.log(Math.round(q.available / 1048576) + " MB free of " + Math.round(q.quota / 1048576));
});collectDefinitionUrls
function(layers) : Array.<String>helper# The definition URLs (not tiles) the given layers need to be redrawn without the network: each WMS layer's legend JSON (/geolegend/?...&isjson=true) and the getCapabilities.xml of every remote …
collectDefinitionUrlsWritten as ExtjsUtils.OFFLINE.collectDefinitionUrls
The definition URLs (not tiles) the given layers need to be redrawn without the network: each WMS layer's legend JSON (/geolegend/?...&isjson=true) and the getCapabilities.xml of every remote layer store registered with addRemoteWMSServer (storage stores only; cors stores are skipped, they go through the online proxy). The local WMS GetCapabilities is NOT in the list — downloadDefinitions prunes and caches it separately. Mostly informational; downloadDefinitions calls it for you.
- layers Array.<Object>
- Targets from
getCacheableLayers.
Returns The URLs to cache as-is.
console.log(ExtjsUtils.OFFLINE.collectDefinitionUrls(ExtjsUtils.OFFLINE.getCacheableLayers()));createAreaId
function() : Stringhelper# Generates a new unique area id ("area_<time>_<random>").
createAreaIdWritten as ExtjsUtils.OFFLINE.createAreaId
Generates a new unique area id ("area_<time>_<random>"). downloadArea and importAreaFromZip call it when no id option is given; call it yourself when you need to know the id before starting a download (e.g. to report progress under it).
Returns A fresh area id.
var id = ExtjsUtils.OFFLINE.createAreaId();
ExtjsUtils.OFFLINE.downloadArea({id: id, name: "Fazenda", extent: extent, zoomMin: 10, zoomMax: 14});deleteAllAreas
function(options) : Promise.<Number>helper# Deletes every offline area (bucket + record) and the definitions buckets those areas downloaded (definitionsId), then — once the service worker confirms its index no longer lists them — reloads the …
deleteAllAreasWritten as ExtjsUtils.OFFLINE.deleteAllAreas
Deletes every offline area (bucket + record) and the definitions buckets those areas downloaded (definitionsId), then — once the service worker confirms its index no longer lists them — reloads the map's tiles once (not once per area). The "clear all" of an areas list: the capabilities caches saved by name (downloadDefinitions({name})) stay, for deleteDefinitions; and unlike resetAllOfflineData it keeps the serving policy and leaves the service worker registered.
- options Object
- How to delete.
- options.reloadTiles Boolean
falseto skip the tile reload.
Returns How many areas were deleted.
ExtjsUtils.OFFLINE.deleteAllAreas().then(function(count) { console.log(count + " areas deleted"); });deleteArea
function(id, options) : Promise.<undefined>helper# Deletes an area completely: its Cache Storage bucket (all its tiles) and its IndexedDB record, and tells the service worker.
deleteAreaWritten as ExtjsUtils.OFFLINE.deleteArea
Deletes an area completely: its Cache Storage bucket (all its tiles) and its IndexedDB record, and tells the service worker. The shared definitions bucket is not touched (other areas of the same query may use it; resetAllOfflineData clears it). Waits for the worker to confirm it rebuilt its index without the deleted bucket, then asks the map to request its tiles again (reloadMapTiles), so the screen shows the difference at once instead of at the next pan or zoom. Pass {reloadTiles: false} to skip that (e.g. deleting several areas right before an import replaces them — see importAreaFromZip's replaceAreaIds, which does this itself). Safe to call for an id that no longer exists.
- id String
- The area id.
- options Object
{reloadTiles}— defaults totrue.
Returns Resolves once both the cache and the record are gone.
ExtjsUtils.OFFLINE.deleteArea(areaId).then(function() { console.log("deleted"); });deleteAreaRecord
function(id) : Promise.<undefined>helper# Deletes only the IndexedDB record of an area, leaving its tile cache in place.
deleteAreaRecordWritten as ExtjsUtils.OFFLINE.deleteAreaRecord
Deletes only the IndexedDB record of an area, leaving its tile cache in place. Normally you want deleteArea, which removes both.
- id String
- The area id.
Returns Resolves once the record is gone.
ExtjsUtils.OFFLINE.deleteAreaRecord(areaId);deleteDefinitions
function(id) : Promise.<Boolean>helper# Deletes a definitions cache (its GetCapabilities and legends).
deleteDefinitionsWritten as ExtjsUtils.OFFLINE.deleteDefinitions
Deletes a definitions cache (its GetCapabilities and legends). A page still loading its catalog from it gets the live one from then on.
- id String
- The cache name or id (
listDefinitions).
Returns true when the cache existed.
ExtjsUtils.OFFLINE.deleteDefinitions("fazenda-42");describeCacheableLayers
function(layerNames) : Array.<Object>helper# One plain description per cacheable map — what a "which maps go offline" picker shows: {name, title, visible, kind, maxZoom, suggestedMaxZoom, metersPerCell, canLimitMaxZoom, llbbox}.
describeCacheableLayersWritten as ExtjsUtils.OFFLINE.describeCacheableLayers
One plain description per cacheable map — what a "which maps go offline" picker shows: {name, title, visible, kind, maxZoom, suggestedMaxZoom, metersPerCell, canLimitMaxZoom, llbbox}. name is the map name layerNames options take (ExtjsUtils.LAYER.getMapName); maxZoom the limit in force (getMaxZoom, null = none); suggestedMaxZoom/metersPerCell what suggestMaxZoom reads from the raster's cell size (null when it declares none); canLimitMaxZoom whether setMaxZoom applies (WMS maps, not XYZ/OSM basemaps); llbbox the lon/lat bounding box from the capabilities ([left, bottom, right, top], or null). Plain data, safe to postMessage. Call it after whenLayersReady.
- layerNames Array.<String>
- Only these maps (see
selectCacheableLayers).
Returns The descriptions, one per map.
ExtjsUtils.OFFLINE.whenLayersReady().then(function() {
ExtjsUtils.OFFLINE.describeCacheableLayers().forEach(function(map) {
console.log(map.name + ": max zoom " + (map.maxZoom === null ? "none" : map.maxZoom));
});
});downloadArea
function(options) : Promise.<Object>helper# Downloads (or resumes) one offline area: every tile of the chosen layers over the extent and zoom range, one HTTP request per tile with a bounded concurrency, into the area's own Cache Storage bucket …
downloadAreaWritten as ExtjsUtils.OFFLINE.downloadArea
Downloads (or resumes) one offline area: every tile of the chosen layers over the extent and zoom range, one HTTP request per tile with a bounded concurrency, into the area's own Cache Storage bucket — plus, unless includeDefinitions: false, the query's definitions (pruned GetCapabilities + legends) into their shared bucket, in parallel (see downloadDefinitions). The area record is saved as 'downloading' first and finished as 'ready', or 'partial' when aborted or when a tile/definition failed. Resumable: pass the same id again and tiles already in the cache are not re-fetched (with refresh: true they are, each replacing its stored copy — never a second one); with a different extent, zoom range or maps the area grows, and its record widens to cover both (e.g. one id per imóvel, downloaded again after it is re-drawn). The serving policy (see setServingPolicy) is forced to "NetworkOnly" for the download's duration — so every request really goes to the network, never gets answered by the worker from a bucket — and put back to whatever it was, once it settles. Rejects without any request when the estimated tile count exceeds maxTiles ("Area too large"). The engine works without a query id: queryId defaults to the page's ?queryid parameter and is only stored on the record. The service worker serves the cached tiles when the page is offline; use verifyAreaServed to check.
- options Object
- Area definition and download options.
- options.name String
- Display name of the area (defaults to the id).
- options.extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object (e.g.map.getExtent()). - options.zoomMin Number
- The first zoom level to download.
- options.zoomMax Number
- The last zoom level to download (inclusive).
- options.queryId String
- Query id recorded on the area; defaults to the
?queryidURL parameter (may be empty — not required). - options.id String
- Id of an existing area to resume/refresh; omitted ⇒
createAreaId(). - options.layers Array.<Object>
- Targets from
getCacheableLayersto include; omitted ⇒layerNames, or every cacheable map. Without it the download first waits for the query's layers (whenLayersReady). - options.layerNames Array.<String>
- Map names to include (WMS
LAYERS, or"OSM Mapnik") — seeselectCacheableLayers. Rejects, before any request, when one of them is not on the map. - options.maxTiles Number
- Tile-count cap for this call; defaults to
MAX_TILES_PER_AREA. - options.concurrency Number
- Parallel tile requests; defaults to
CONCURRENCY. - options.signal AbortSignal
- Aborts the download; what was fetched stays cached and the area ends
'partial'. - options.includeDefinitions Boolean
falseto download tiles only.- options.refresh Boolean
trueto fetch the tiles already stored again, overwriting them (e.g. updated imagery).- options.onProgress function
- Called after each tile with
{done, total, failed, bytes}(tiles only).
Returns The saved area record (see listAreas), with status 'ready' or 'partial'.
var map = ExtjsUtils.JS.getMap();
var controller = new AbortController();
ExtjsUtils.OFFLINE.downloadArea({
name: "Fazenda Santa Clara",
extent: map.getExtent(),
zoomMin: map.getZoom(),
zoomMax: map.getZoom() + 3,
layers: ExtjsUtils.OFFLINE.getCacheableLayers(),
signal: controller.signal,
onProgress: function(p) { console.log(p.done + "/" + p.total + " tiles, " + p.failed + " failed"); }
}).then(function(area) {
console.log("area " + area.id + " is " + area.status);
}).catch(function(err) {
alert(err.message); // e.g. "Area too large: ~35000 tiles exceeds the 20000 cap..."
});
// controller.abort() cancels; the partial area can be resumed later with {id: area.id}downloadAreaAsZip
function(options) : Promise.<Object>helper# Same result as downloadArea, but as ONE HTTP request instead of one per tile: POSTs the enumerated URL list ({urls: [...], entries: [{url, map}]}) to options.endpoint, a zip-building service …
downloadAreaAsZipWritten as ExtjsUtils.OFFLINE.downloadAreaAsZip
Same result as downloadArea, but as ONE HTTP request instead of one per tile: POSTs the enumerated URL list ({urls: [...], entries: [{url, map}]}) to options.endpoint, a zip-building service that fetches every tile server-side and answers with a single .zip (a manifest.json with {entries: [{url, path, contentType, status}]} plus one file per fetched URL), then unpacks it straight into the area's cache (JSZip is lazy-loaded on first use). There is no default endpoint and none built into the platform — it is infrastructure a deployment opts into (a reference implementation, mappia-offline-zip-server, lives next to the offline-areas demo). Not resumable mid-download: it either completes or is retried from scratch; a URL the service could not fetch is counted as failed. Definitions are never sent to the endpoint: they are fetched (and the capabilities pruned) by the client, in parallel, unless includeDefinitions: false. Same NetworkOnly-for-the-duration policy switch as downloadArea (see its doc comment).
- options Object
- The same options as
downloadArea(name,extent,zoomMin,zoomMax,queryId,id,layers,layerNames,maxTiles,signal,includeDefinitions,onProgress) plus the endpoint. - options.endpoint String
- URL of the zip-building service (required; rejects without it).
- options.onProgress function
- Called with
{phase, done, total, failed, bytes}:phaseis'requesting'while the POST is in flight (donestays 0), then'unpacking'once per entry written to the cache.
Returns The saved area record (see listAreas), with status 'ready' or 'partial'.
ExtjsUtils.OFFLINE.downloadAreaAsZip({
name: "Fazenda Santa Clara",
extent: ExtjsUtils.JS.getMap().getExtent(),
zoomMin: 11, zoomMax: 14,
endpoint: "https://offline-zip.example.org/zip",
onProgress: function(p) { console.log(p.phase, p.done + "/" + p.total); }
}).then(function(area) { console.log(area.status); });downloadDefinitions
function(options) : Promise.<Object>helper# Downloads the "definitions" (not tiles) the query needs to redraw without the network: the local WMS GetCapabilities — pruned to the maps actually on the map with ExtjsUtils.CAPABILITIES.filterText …
downloadDefinitionsWritten as ExtjsUtils.OFFLINE.downloadDefinitions
Downloads the "definitions" (not tiles) the query needs to redraw without the network: the local WMS GetCapabilities — pruned to the maps actually on the map with ExtjsUtils.CAPABILITIES.filterText before it is cached (the full catalog is ~2500 layers; the pruned copy is the handful in use) — plus each layer's legend and every registered remote store's capabilities (collectDefinitionUrls, cached as-is). They go into their own shared cache bucket, separate from any area's tiles, because which maps the filter keeps depends on the whole active query, not on one area: several areas of the same query share one copy. The bucket id is derived from the in-use map names, so no queryid is required — the engine works without one. downloadArea and downloadAreaAsZip call it in parallel with the tiles unless includeDefinitions: false; call it directly to refresh definitions alone or to get their own progress.
Everything it downloads comes from the server, whatever the serving mode (setServingPolicy) — never from a cache, its own included — and while offline (navigator.onLine false, or the Offline preset's forceOffline) it rejects at once instead of trying.
Give it a name to keep a named capabilities cache the user controls: calling it again with the same name updates that cache; layerNames (or full: true) picks which catalog it keeps. A cached catalog is never used on its own: a page loads its catalog from it only when it asks — useDefinitions(name), or ?definitions=<name> on the map page URL — so different Mappia instances can use different caches, or the live catalog, side by side.
- options Object
- Download options.
- options.name String
- Name of the cache to create or update (see
listDefinitions) — any name but"live", which means the live catalog; omitted ⇒ an id derived from the map names in use. - options.layerNames Array.<String>
- Maps the cached GetCapabilities keeps; omitted ⇒ the maps on the map now.
- options.full Boolean
trueto keep the whole GetCapabilities, unfiltered (the full catalog, a few MB).- options.legends Boolean
falseto skip the legends.- options.layers Array.<Object>
- Targets from
getCacheableLayers, scoping the legend/remote-capabilities list only (the GetCapabilities filter always covers the whole map); omitted ⇒ every cacheable layer. - options.signal AbortSignal
- Aborts the pending requests; what was already cached stays.
- options.requestTimeoutMs Number
- Longest wait for each request; one that takes longer counts as failed and the rest go on.
- options.onProgress function
- Called after each request with
{id, done, total, failed, bytes}.
Returns {id, name, full, cacheName, mapNames, done, failed, total, bytes} — id is the definitions bucket id also stored on the area as definitionsId.
ExtjsUtils.OFFLINE.downloadDefinitions({
onProgress: function(p) { console.log("definitions " + p.done + "/" + p.total); }
}).then(function(result) {
console.log(result.mapNames, result.failed === 0 ? "complete" : "partial");
});// a named cache of this query's maps, then this page loads its catalog from it
ExtjsUtils.OFFLINE.downloadDefinitions({ name: "fazenda-42" }).then(function() {
return ExtjsUtils.OFFLINE.useDefinitions("fazenda-42");
});downloadLayers
function(layers, options) : Promise.<Object>helper# downloadArea from a list of layers: the area is worked out by planArea (maps, extent, zoom range and name derived from the layers, each overridable in options), then downloaded tile by tile — …
downloadLayersWritten as ExtjsUtils.OFFLINE.downloadLayers
downloadArea from a list of layers: the area is worked out by planArea (maps, extent, zoom range and name derived from the layers, each overridable in options), then downloaded tile by tile — or, with options.endpoint, by downloadAreaAsZip. Every other option goes through as is (id, signal, onProgress, includeDefinitions, maxTiles, concurrency, …).
- layers Array.<(String|OpenLayers.Layer)>
- Layers by name or the layers themselves (see
planArea). - options Object
planAreaoverrides (extent,zoomMin,zoomMax,name) plus anydownloadAreaoption.- options.endpoint String
- URL of a zip-building service: download with
downloadAreaAsZipinstead.
Returns The saved area record (see listAreas).
// one imóvel, ready for offline editing
ExtjsUtils.OFFLINE.downloadLayers(["CSR:show_car", "CSR:planet_brasil_2024", "CSR:cultivo_cafe_cafe"], {
id: "imovel_" + imovelId
}).then(function(area) { console.log(area.name + " is " + area.status); });// the same, but no deeper than zoom 15 and over an extent of your own
ExtjsUtils.OFFLINE.downloadLayers(["CSR:planet_brasil_2024"], { extent: [-5179428, -2460070, -5171880, -2455780], zoomMax: 15 });effectiveZoom
function(target, z) : Numberhelper# The zoom a layer really requests tiles at when the map is at zoom z: z itself, unless the layer has a maxZoom limit it honours (ConfigLayer.maxZoom or layer.setMaxZoom), in which case every …
effectiveZoomWritten as ExtjsUtils.OFFLINE.effectiveZoom
The zoom a layer really requests tiles at when the map is at zoom z: z itself, unless the layer has a maxZoom limit it honours (ConfigLayer.maxZoom or layer.setMaxZoom), in which case every zoom above the limit collapses onto it — the map keeps asking for the max-zoom tile and stretches it. The estimate and the enumeration both go through this, which is why a maxZoom makes an offline area so much smaller.
- target Object
- A
{layer, kind}entry fromgetCacheableLayers. - z Number
- The map zoom level.
Returns The effective zoom, <= z.
var target = ExtjsUtils.OFFLINE.getCacheableLayers()[0];
console.log(ExtjsUtils.OFFLINE.effectiveZoom(target, 16)); // 13 for a layer limited to maxZoom 13enumerateTileEntries
function(extent, zoomMin, zoomMax, layers) : Array.<Object>helper# enumerateTileUrls() with the map each tile belongs to: [{url, map}], where map is the layer's WMS LAYERS name (or its name for XYZ/OSM) — the folder the tile lands in when the area is exported as a zip.
enumerateTileEntriesWritten as ExtjsUtils.OFFLINE.enumerateTileEntries
enumerateTileUrls() with the map each tile belongs to: [{url, map}], where map is the layer's WMS LAYERS name (or its name for XYZ/OSM) — the folder the tile lands in when the area is exported as a zip. A URL two layers share (a query listing the same map twice) appears once, under the first layer.
- extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object. - zoomMin Number
- The first zoom level to cover.
- zoomMax Number
- The last zoom level to cover (inclusive).
- layers Array.<Object>
- Targets from
getCacheableLayers; omitted ⇒ every cacheable layer on the map.
Returns Entries {url: String, map: String}; [] without a map.
var perMap = {};
ExtjsUtils.OFFLINE.enumerateTileEntries(extent, 10, 14).forEach(function(entry) {
perMap[entry.map] = (perMap[entry.map] || 0) + 1;
});
console.log(perMap); // {"CSR:cultivo_cafe_cafe": 340, "mapnik": 340}enumerateTileUrls
function(extent, zoomMin, zoomMax, layers) : Array.<String>helper# The unique tile URLs an area needs: every tile of every given layer, for every zoom in range, covering extent.
enumerateTileUrlsWritten as ExtjsUtils.OFFLINE.enumerateTileUrls
The unique tile URLs an area needs: every tile of every given layer, for every zoom in range, covering extent. Each URL is asked from the live layer object (its own getURL), so it is byte-identical to what the map requests on its own; zooms above a layer's maxZoom are enumerated at the limit, exactly like the map behaves. This is the list estimateAreaBytes samples and downloadArea fetches; a large extent/zoom range makes it long, so check estimateTileCountForLayers first.
- extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object. - zoomMin Number
- The first zoom level to cover.
- zoomMax Number
- The last zoom level to cover (inclusive).
- layers Array.<Object>
- Targets from
getCacheableLayers; omitted ⇒ every cacheable layer on the map.
Returns The tile URLs, without duplicates; [] without a map.
var urls = ExtjsUtils.OFFLINE.enumerateTileUrls(extent, 10, 14, selectedLayers);
ExtjsUtils.OFFLINE.estimateAreaBytes(urls).then(function(estimate) {
console.log(urls.length + " tiles, ~" + Math.round(estimate.estimatedBytes / 1048576) + " MB");
});estimateArea
function(options) : Promise.<Object>helper# Everything to show before downloading an area, in one call, with the same map selection and cap downloadArea applies: first the rough tile count (estimateTileCountForLayers, pure arithmetic — an …
estimateAreaWritten as ExtjsUtils.OFFLINE.estimateArea
Everything to show before downloading an area, in one call, with the same map selection and cap downloadArea applies: first the rough tile count (estimateTileCountForLayers, pure arithmetic — an oversized area costs no request) checked against the cap; then, under the cap, the exact tile count, a size estimated from a sample of real tile requests (estimateAreaBytes) and the storage quota (checkStorageQuota). Waits for the query's layers (whenLayersReady). Rejects, before any request, when one of layerNames is not on the map.
- options Object
- The area, as
downloadAreatakes it. - options.extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object. - options.zoomMin Number
- The first zoom level.
- options.zoomMax Number
- The last zoom level (inclusive).
- options.layerNames Array.<String>
- Maps to include (see
selectCacheableLayers); omitted ⇒ every cacheable map. - options.layers Array.<Object>
- Targets from
getCacheableLayers, instead oflayerNames. - options.maxTiles Number
- The cap; defaults to
MAX_TILES_PER_AREA.
Returns {layerNames, roughTileCount, tileCountWithoutMaxZoom, maxTiles, overCap}, plus — when not over the cap — {tileCount, sampledCount, estimatedBytes, quota}. tileCountWithoutMaxZoom is what the same area would cost if no map had a maxZoom limit: the difference to roughTileCount is what the limits save.
ExtjsUtils.OFFLINE.estimateArea({ extent: map.getExtent(), zoomMin: 12, zoomMax: 16 }).then(function(estimate) {
if (estimate.overCap) alert("~" + estimate.roughTileCount + " tiles: narrow the area");
else console.log(estimate.tileCount + " tiles, ~" + Math.round(estimate.estimatedBytes / 1048576) + " MB");
});estimateAreaBytes
function(urls, sampleSize) : Promise.<Object>helper# Estimates an area's download size in bytes by really fetching a small sample of its tile URLs, measuring them and extrapolating by the total count — tile weight varies by imagery, zoom and source, so …
estimateAreaBytesWritten as ExtjsUtils.OFFLINE.estimateAreaBytes
Estimates an area's download size in bytes by really fetching a small sample of its tile URLs, measuring them and extrapolating by the total count — tile weight varies by imagery, zoom and source, so nothing short of asking the network is an estimate. Costs sampleSize requests. Distinct from checkStorageQuota, which reports the browser's free storage, not anything about this area; label the two separately in a UI.
- urls Array.<String>
- The tile URLs of the area, from
enumerateTileUrls. - sampleSize Number
- How many of the URLs (from the start of the list) to fetch.
Returns {tileCount, sampledCount, averageBytes, estimatedBytes} — sampledCount is the number of sample fetches that succeeded (0 ⇒ estimate is 0).
var urls = ExtjsUtils.OFFLINE.enumerateTileUrls(extent, 10, 14, selectedLayers);
Promise.all([ExtjsUtils.OFFLINE.estimateAreaBytes(urls, 8), ExtjsUtils.OFFLINE.checkStorageQuota()])
.then(function(results) {
var needed = results[0].estimatedBytes, quota = results[1];
if (!quota.unknown && needed > quota.available) alert("Not enough storage for this area");
});estimateTileCount
function(extent, zoomMin, zoomMax) : Numberhelper# Number of tile-grid cells covering extent across the zoom range for ONE layer with NO zoom limit — pure arithmetic, no layer involved.
estimateTileCountWritten as ExtjsUtils.OFFLINE.estimateTileCount
Number of tile-grid cells covering extent across the zoom range for ONE layer with NO zoom limit — pure arithmetic, no layer involved. Use it for the raw grid size (e.g. to show how much a maxZoom saves); estimateTileCountForLayers is the one to use for the real cost, since it knows about each layer's limit.
- extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object. - zoomMin Number
- The first zoom level to cover.
- zoomMax Number
- The last zoom level to cover (inclusive).
Returns The cell count, 0 without a map.
var extent = ExtjsUtils.JS.getMap().getExtent();
console.log(ExtjsUtils.OFFLINE.estimateTileCount(extent, 10, 14) + " cells per unlimited layer");estimateTileCountForLayers
function(extent, zoomMin, zoomMax, layers) : Numberhelper# Upper bound on the tile requests an area would need for these layers over the zoom range, honouring each layer's maxZoom (zooms above it count once, at the limit).
estimateTileCountForLayersWritten as ExtjsUtils.OFFLINE.estimateTileCountForLayers
Upper bound on the tile requests an area would need for these layers over the zoom range, honouring each layer's maxZoom (zooms above it count once, at the limit). Still pure arithmetic — no URL is built — so run it first, before enumerating or fetching anything, to reject an oversized area cheaply: it is the same number downloadArea compares against MAX_TILES_PER_AREA.
- extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units: an
OpenLayers.Bounds, a[left, bottom, right, top]array or any{left, bottom, right, top}object. - zoomMin Number
- The first zoom level to cover.
- zoomMax Number
- The last zoom level to cover (inclusive).
- layers Array.<Object>
- Targets from
getCacheableLayers; omitted ⇒ every cacheable layer on the map.
Returns The estimated tile count, 0 without a map.
var extent = ExtjsUtils.JS.getMap().getExtent();
var rough = ExtjsUtils.OFFLINE.estimateTileCountForLayers(extent, 10, 14, selectedLayers);
if (rough > ExtjsUtils.OFFLINE.MAX_TILES_PER_AREA) {
alert("Too large: ~" + rough + " tiles. Narrow the extent or the zoom range.");
}exportAreaAsZip
function(id, options) : Promise.<Blob>helper# Packs an existing area — every tile currently in its cache — into one .zip Blob that is self-describing: a manifest.json (entries {url, path, map, contentType, status} plus an area block with …
exportAreaAsZipWritten as ExtjsUtils.OFFLINE.exportAreaAsZip
Packs an existing area — every tile currently in its cache — into one .zip Blob that is self-describing: a manifest.json (entries {url, path, map, contentType, status} plus an area block with the record's id, name, extent, zoom range, layer names and query id) and one file per tile, laid out one folder per map (<map>/<host>/<path>, e.g. mapnik/tile.openstreetmap.org/16/23456/37891.png). importAreaFromZip/importAreaFromUrl rebuild the area from it on another device without re-downloading a single tile — host the file anywhere. Tiles are stored uncompressed (they are PNG/JPEG already) and the zip is assembled in memory: fine for the thousands of tiles an area holds, not for hundreds of MB. Pair it with exportAreaFilename and saveBlobAsFile to hand the pack to the user.
- id String
- The area id.
- options Object
- Export options.
- options.onProgress function
- Called per tile with
{phase: 'packing', done, total, failed, bytes}.
Returns The zip file; rejects when no area has that id.
ExtjsUtils.OFFLINE.getArea(areaId).then(function(area) {
return ExtjsUtils.OFFLINE.exportAreaAsZip(areaId).then(function(blob) {
ExtjsUtils.OFFLINE.saveBlobAsFile(blob, ExtjsUtils.OFFLINE.exportAreaFilename(area));
});
});exportAreaFilename
function(area) : Stringhelper# The file name a pack from exportAreaAsZip should be saved under: mappia-offline-area-<slug>.zip, where the slug is the area name (falling back to its id) lower-cased, accents stripped and …
exportAreaFilenameWritten as ExtjsUtils.OFFLINE.exportAreaFilename
The file name a pack from exportAreaAsZip should be saved under: mappia-offline-area-<slug>.zip, where the slug is the area name (falling back to its id) lower-cased, accents stripped and non-alphanumerics replaced by -.
- area Object
- The area record (only
name/idare read).
Returns The file name, e.g. "mappia-offline-area-fazenda-santa-clara.zip".
ExtjsUtils.OFFLINE.exportAreaFilename({name: "Fazenda São João"}); // "mappia-offline-area-fazenda-sao-joao.zip"exportDefinitionsAsZip
function(id) : Promise.<Blob>helper# Packs a definitions cache (listDefinitions) — its GetCapabilities and legends — into one .zip Blob: a manifest.json (format: 'mappia-offline-definitions', the cache's metadata as definitions, …
exportDefinitionsAsZipWritten as ExtjsUtils.OFFLINE.exportDefinitionsAsZip
Packs a definitions cache (listDefinitions) — its GetCapabilities and legends — into one .zip Blob: a manifest.json (format: 'mappia-offline-definitions', the cache's metadata as definitions, and entries {url, path, contentType}) plus one file per entry. importDefinitionsFromZip saves it back on any device, where ?definitions=<id> or useDefinitions then loads the map's catalog from it without the server.
- id String
- The cache name or id.
Returns The zip file; rejects when no cache has that id.
ExtjsUtils.OFFLINE.exportDefinitionsAsZip("fazenda-42").then(function(blob) {
ExtjsUtils.OFFLINE.saveBlobAsFile(blob, "mappia-capabilities-fazenda-42.zip");
});getArea
function(id) : Promise.<(Object|null)>helper# Reads one area record by id (see listAreas for the record shape).
getAreaWritten as ExtjsUtils.OFFLINE.getArea
Reads one area record by id (see listAreas for the record shape).
- id String
- The area id.
Returns The record, or null when no area has that id.
ExtjsUtils.OFFLINE.getArea(areaId).then(function(area) {
if (!area) throw new Error("area not found: " + areaId);
console.log(area.status);
});getCacheableLayers
function() : Array.<Object>helper# Lists the layers currently on the map whose tiles can be cached for offline use, as {layer, kind} "targets" — the objects every other function here accepts as layers.
getCacheableLayersWritten as ExtjsUtils.OFFLINE.getCacheableLayers
Lists the layers currently on the map whose tiles can be cached for offline use, as {layer, kind} "targets" — the objects every other function here accepts as layers. Two kinds: 'storage' (a CustomWMS layer served from a hosted layer store — addRemoteWMSServer with storage — recursing into a Composed layer's inner layers) and 'grid' (any other tiled OpenLayers.Layer.Grid: XYZ/OSM basemaps and plain named WMS layers such as CSR:cultivo_cafe_cafe). Excluded: calculate layers with an operation but no store (their requests depend on the viewport, not on a tile grid) and Google/Bing basemaps (their terms forbid caching). Filter the result to let the user pick which maps to include; the WMS name of a target is target.layer.params.LAYERS (target.layer.name for XYZ/OSM). Wait for whenLayersReady before calling it, or a {name: "CSR:..."} layer may not be on the map yet; selectCacheableLayers picks maps by name.
Returns Targets {layer: OpenLayers.Layer, kind: 'storage'|'grid'}, or [] without a map.
var targets = ExtjsUtils.OFFLINE.getCacheableLayers();
var selected = targets.filter(function(t) {
var key = (t.layer.params && t.layer.params.LAYERS) || t.layer.name;
return ["CSR:cultivo_cafe_cafe", "mapnik"].indexOf(key) !== -1;
});getDefinitionsInUse
function() : String|nullhelper# The definitions cache this page loads its catalog from (useDefinitions or ?definitions=<name>), "" for the empty catalog it started with (?definitions=), or null for the live catalog.
getDefinitionsInUseWritten as ExtjsUtils.OFFLINE.getDefinitionsInUse
The definitions cache this page loads its catalog from (useDefinitions or ?definitions=<name>), "" for the empty catalog it started with (?definitions=), or null for the live catalog.
Returns The cache id, "", or null.
console.log(ExtjsUtils.OFFLINE.getDefinitionsInUse() || "live catalog");getMaxZoom
function(target) : Number|nullhelper# The zoom limit a layer currently honours (see effectiveZoom), or null when it has none.
getMaxZoomWritten as ExtjsUtils.OFFLINE.getMaxZoom
The zoom limit a layer currently honours (see effectiveZoom), or null when it has none. Shows the "real max zoom" in force for a layer — set in the query with ConfigLayer.maxZoom or at runtime with layer.setMaxZoom(n) on CustomWMS layers.
- target Object
- A
{layer, kind}entry fromgetCacheableLayers.
Returns The max zoom, or null.
ExtjsUtils.OFFLINE.getCacheableLayers().forEach(function(t) {
console.log(t.layer.name, ExtjsUtils.OFFLINE.getMaxZoom(t));
});getOfflineReadiness
function(options) : Promise.<Object>helper# Whether this page is ready to work offline, as four checks, each {ok, ...}:
getOfflineReadinessWritten as ExtjsUtils.OFFLINE.getOfflineReadiness
Whether this page is ready to work offline, as four checks, each {ok, ...}:
worker: the current service worker controls the page (reasonwhen not:
'not-controlled','outdated'— reload the page, or'disabled');tiles: an area that is switched on and fully downloaded (status: 'ready')
coversoptions.extent(any such area without one) —areaIds;catalog: the map's catalog comes from a saved capabilities cache that exists
(inUse, fromgetDefinitionsInUse;saved, the cache ids oflistDefinitions);serving: the serving policy answers from the downloads (any mode but
NetworkOnly) —mode,forceOffline.readyistruewhen all four are;missinglists the keys that are not. Built fromgetServiceWorkerStatus,listAreas,listDefinitions,getDefinitionsInUseandgetServingPolicy. Plain data, safe topostMessage.
- options Object
- What to check.
- options.extent OpenLayers.Bounds|Array.<Number>|Object
- The area that must be covered, in map units.
Returns {ready, missing, worker, tiles, catalog, serving}.
ExtjsUtils.OFFLINE.getOfflineReadiness({ extent: ExtjsUtils.LAYER.getLayerExtent("CSR:show_car") }).then(function(r) {
console.log(r.ready ? "ready offline" : "missing: " + r.missing.join(", "));
});getServiceWorkerStatus
function() : Promise.<Object>helper# The state of the page's service worker, for a status panel.
getServiceWorkerStatusWritten as ExtjsUtils.OFFLINE.getServiceWorkerStatus
The state of the page's service worker, for a status panel. registered, controlled (a worker answers this page's requests), controllerScriptURL, controllerIsCurrent (the controller is the active worker), the registration slots active/waiting/installing (their state, or null) with activeMeta/ waitingMeta/installingMeta ({state, scriptURL}), hasWaiting, needsReload (a newer worker waits, or an older one still controls the page — reload the page or iframe to run the newest), and from the worker's own answer: build (its build label, a hash of its code), offlineBuckets, servingPolicy, recentDebugEvents, workerScriptURL. Also carries the page's registration outcome (window.MappiaServiceWorkerSetup: enabled, localhost, error). Plain data, safe to postMessage. Never rejects.
Returns The status.
ExtjsUtils.OFFLINE.getServiceWorkerStatus().then(function(sw) {
console.log(sw.controlled ? "worker " + sw.build : "no worker controls this page");
if (sw.needsReload) console.log("reload to run the newest worker");
});getServingPolicy
function() : Promise.<Object>helper# How the service worker answers map requests that hit (or miss) an offline bucket: {mode} with one of "CacheFirst" (default: bucket first, network on miss), "NetworkFirst" (live first, bucket …
getServingPolicyWritten as ExtjsUtils.OFFLINE.getServingPolicy
How the service worker answers map requests that hit (or miss) an offline bucket: {mode} with one of "CacheFirst" (default: bucket first, network on miss), "NetworkFirst" (live first, bucket when the network fails), "CacheOnly" (bucket / soft crop only — never the network), "NetworkOnly" (live only — never the bucket). Legacy kebab-case values (cache-first, …) are accepted and normalized. forceOffline: true makes the worker treat the network as down no matter what navigator.onLine says — every mode then behaves as it would with no network at all (an "Offline" preset is {mode: "CacheOnly", forceOffline: true}). Stored in Cache Storage (OfflineCacheKey.SETTINGS_CACHE_NAME); resetAllOfflineData clears it.
Returns {mode, forceOffline, updatedAt} — the default (forceOffline: false, updatedAt: null) when nothing was set yet.
ExtjsUtils.OFFLINE.getServingPolicy().then(function(policy) { console.log(policy.mode); });importAreaFromUrl
function(url, options) : Promise.<Object>helper# importAreaFromZip for a pack hosted at a URL (a GitHub release asset, a raw file in a repository, any static host): one GET, then the unpack — zero tile requests.
importAreaFromUrlWritten as ExtjsUtils.OFFLINE.importAreaFromUrl
importAreaFromZip for a pack hosted at a URL (a GitHub release asset, a raw file in a repository, any static host): one GET, then the unpack — zero tile requests. The host must allow cross-origin reads (CORS) when it is not the platform's own origin; raw.githubusercontent.com and GitHub release assets do. The pack URL is recorded on the area as importedFrom.
- url String
- The pack URL.
- options Object
- The same options as
importAreaFromZip(id,name,extent,zoomMin,zoomMax,layerNames,queryId,replaceAreaIds,signal,onProgress). - options.onProgress function
- Called with
{phase, done, total, failed, bytes}:phaseis'requesting'while the GET is in flight, then'unpacking'per entry.
Returns The saved area record (see listAreas).
// step through properties one at a time, never keeping more than one area's tiles on disk
ExtjsUtils.OFFLINE.importAreaFromUrl("https://github.com/org/packs/releases/download/v1/fazenda-42.zip", {
id: "current",
replaceAreaIds: ["current"],
onProgress: function(p) { console.log(p.phase, p.done + "/" + p.total); }
}).then(function(area) {
ExtjsUtils.JS.getMap().zoomToExtent(OpenLayers.Bounds.fromArray(area.extent));
});importAreaFromZip
function(zipBlob, options) : Promise.<Object>helper# Rebuilds an offline area from a pack produced by exportAreaAsZip (or any zip following the manifest contract) — "load the tile cache from this file instead of downloading every tile".
importAreaFromZipWritten as ExtjsUtils.OFFLINE.importAreaFromZip
Rebuilds an offline area from a pack produced by exportAreaAsZip (or any zip following the manifest contract) — "load the tile cache from this file instead of downloading every tile". The area record comes from the pack's manifest.area and can be overridden by options; a pack without an area block still imports with whatever the options give. Re-importing a pack with the same id refreshes that area in place (entries are overwritten, never duplicated). Definitions are not part of a pack; run downloadDefinitions separately when the device needs them. See importAreaFromUrl for packs hosted on a server.
- zipBlob Blob
- The pack, e.g. from an
<input type="file">or afetch().blob(). - options Object
- Import options.
- options.id String
- Area id to create/refresh; defaults to the pack's, else a new id.
- options.name String
- Area name; defaults to the existing/packed name, else the id.
- options.extent Array.<Number>
[left, bottom, right, top]in map units; defaults to the packed extent.- options.zoomMin Number
- Defaults to the packed value.
- options.zoomMax Number
- Defaults to the packed value.
- options.layerNames Array.<String>
- Map names the pack covers; defaults to the packed list.
- options.queryId String
- Defaults to the packed value.
- options.replaceAreaIds Array.<String>
- Ids of other areas to delete (cache + record) BEFORE unpacking — the "one property open at a time" tool:
{id: 'current', replaceAreaIds: ['current']}never keeps more than one area's tiles on disk, freeing space before the new pack lands. - options.signal AbortSignal
- Aborts the unpacking; the area ends
'partial'. - options.onProgress function
- Called per entry with
{phase: 'unpacking', done, total, failed, bytes}. - options.sourceUrl String
- Recorded as
importedFrom(set automatically byimportAreaFromUrl).
Returns The saved area record (see listAreas).
// <input type="file" id="pack"> in the host page, forwarded as a Blob
ExtjsUtils.OFFLINE.importAreaFromZip(fileBlob, {
name: "Fazenda Santa Clara",
onProgress: function(p) { console.log(p.done + "/" + p.total); }
}).then(function(area) { console.log("imported", area.id, area.tileCount + " tiles"); });importDefinitionsFromZip
function(zipBlob, options) : Promise.<Object>helper# Saves a capabilities pack from exportDefinitionsAsZip as a definitions cache, under its packed id or options.name (an existing cache of that id is replaced).
importDefinitionsFromZipWritten as ExtjsUtils.OFFLINE.importDefinitionsFromZip
Saves a capabilities pack from exportDefinitionsAsZip as a definitions cache, under its packed id or options.name (an existing cache of that id is replaced). Then ?definitions=<id> or useDefinitions(id) loads the map's catalog from it.
- zipBlob Blob
- The pack, e.g. from an
<input type="file">. - options Object
- Import options.
- options.name String
- The cache name; defaults to the packed one.
Returns The cache's metadata, as listDefinitions lists it.
ExtjsUtils.OFFLINE.importDefinitionsFromZip(fileBlob).then(function(definitions) {
return ExtjsUtils.OFFLINE.useDefinitions(definitions.id);
});listAreas
function() : Promise.<Array.<Object>>helper# Lists every offline area saved on this browser, as area records.
listAreasWritten as ExtjsUtils.OFFLINE.listAreas
Lists every offline area saved on this browser, as area records. An area record is a plain object with id, name, extent ([left, bottom, right, top] in map units), zoomMin, zoomMax, layerNames (the WMS map names / basemap names it covers), queryId, status ('downloading', 'ready' or 'partial' — partial means aborted or some tile/definition failed), tileCount, failedCount, bytes, createdAt, updatedAt and, when definitions were downloaded, definitionsId, definitionsBytes, definitionsFailedCount; imported packs also carry importedFrom. This is what an "offline areas" list in a host page shows.
Returns The area records, in store order.
ExtjsUtils.OFFLINE.listAreas().then(function(areas) {
areas.forEach(function(area) {
console.log(area.name, area.status, area.tileCount + " tiles", Math.round(area.bytes / 1048576) + " MB");
});
});listDefinitions
function() : Promise.<Array.<Object>>helper# The definitions caches kept in this browser (see downloadDefinitions), each as its metadata: {id, name, full, mapNames, capabilitiesUrl, done, failed, bytes, updatedAt} (full: the whole …
listDefinitionsWritten as ExtjsUtils.OFFLINE.listDefinitions
The definitions caches kept in this browser (see downloadDefinitions), each as its metadata: {id, name, full, mapNames, capabilitiesUrl, done, failed, bytes, updatedAt} (full: the whole GetCapabilities, else only mapNames). Pass the id to useDefinitions, deleteDefinitions, or downloadDefinitions({name}) to update it.
Returns The caches, by name.
ExtjsUtils.OFFLINE.listDefinitions().then(function(list) {
list.forEach(function(d) { console.log(d.name, d.full ? "full catalog" : d.mapNames.join(", ")); });
});onMapCacheEvent
function(callback) : functionhelper# Subscribes to the service worker's live feed of how it answered the map's tile requests: one event per cache hit, coarser-zoom crop or miss ({build, mode, layers, requestZoom, cachedZoom, ...}, …
onMapCacheEventWritten as ExtjsUtils.OFFLINE.onMapCacheEvent
Subscribes to the service worker's live feed of how it answered the map's tile requests: one event per cache hit, coarser-zoom crop or miss ({build, mode, layers, requestZoom, cachedZoom, ...}, sent by ServiceWorker.js), completed with what only the page knows — mapZoom, the map's current zoom, and layerMaxZoom, the layer's max-zoom limit when it has one (a layer limited to 15 asks for zoom-15 tiles while the map sits at 17). For a debug panel or a log. Nothing arrives while no worker controls the page.
- callback function
- Called with each event.
Returns Call it to unsubscribe.
var stop = ExtjsUtils.OFFLINE.onMapCacheEvent(function(event) {
console.log(event.layers + " z" + event.requestZoom + " served from z" + event.cachedZoom);
});openDb
function() : Promise.<IDBDatabase>helper# Opens (and on first use creates) the IndexedDB database of area records, caching the connection for the page.
openDbWritten as ExtjsUtils.OFFLINE.openDb
Opens (and on first use creates) the IndexedDB database of area records, caching the connection for the page. The record functions below call it for you; use it directly only for custom queries on the store.
Returns The open database.
ExtjsUtils.OFFLINE.openDb().then(function(db) { console.log(db.objectStoreNames.contains("areas")); });planArea
function(layers, options) : Promise.<Object>helper# Works an offline area out from a list of layers — name what goes offline, and the rest is derived:
planAreaWritten as ExtjsUtils.OFFLINE.planArea
Works an offline area out from a list of layers — name what goes offline, and the rest is derived:
- the maps to download: the cacheable layers in the list (WMS, XYZ/OSM); when the
list has none, every cacheable map on the map; extent: the bounds of the features of the vector layers in the list (the
imóvel drawn byCSR:show_car, say); without any, the current map view;zoomMin: 0, so the area also shows zoomed out (the levels above the extent
cost a few tiles each);zoomMax: the deepestmaxZoomamong those maps (their detail ends there —
getMaxZoom), or 2 levels below the zoom at which the extent fits the map when
none has a limit;name: the title of the first vector layer, else the map names. Any of them can be given inoptionsinstead (a missing,nullor""value is derived), e.g. a smallerzoomMaxto limit the zoom or anextentof your own. Waits for the query's layers. Rejects when a listed layer is not on the map, or is neither cacheable nor a vector layer. The result is plain data (postMessage-safe) and is whatdownloadArea/estimateAreatake —downloadLayersdoes both steps.
- layers Array.<(String|OpenLayers.Layer)>
- Layers by name (
LAYER.getMapNameorlayer.name), or the layers themselves. - options Object
- Values to use instead of the derived ones.
- options.extent OpenLayers.Bounds|Array.<Number>|Object
- The area, in map units.
- options.zoomMin Number
- The first zoom level.
- options.zoomMax Number
- The last zoom level (inclusive) — the zoom limit.
- options.name String
- Display name of the area.
Returns {layerNames, extent: [left, bottom, right, top], zoomMin, zoomMax, name}.
// the imóvel's maps, its extent, down to the maps' own max zoom
ExtjsUtils.OFFLINE.planArea(["CSR:show_car", "CSR:planet_brasil_2024", "CSR:cultivo_cafe_cafe"]).then(function(plan) {
console.log(plan.name + ": zoom " + plan.zoomMin + "-" + plan.zoomMax + ", " + plan.layerNames.join(", "));
return ExtjsUtils.OFFLINE.estimateArea(plan);
});prepareOffline
function(layers, options) : Promise.<Object>helper# Gets this page ready to work offline over an area in one call — the steps getOfflineReadiness checks, in order: downloads the tiles of the area worked out from layers (downloadLayers, …
prepareOfflineWritten as ExtjsUtils.OFFLINE.prepareOffline
Gets this page ready to work offline over an area in one call — the steps getOfflineReadiness checks, in order: downloads the tiles of the area worked out from layers (downloadLayers, planArea overrides in options), saves the map's catalog under a name (downloadDefinitions: the maps in use, so the map can be rebuilt from it), switches this page to it (useDefinitions) and, when the serving policy is NetworkOnly, sets CacheFirst so the downloads are used. Needs the network; rejects at once offline. To open the map with the catalog next time, use ?definitions=<catalogName>.
- layers Array.<(String|OpenLayers.Layer)>
- Layers by name or the layers themselves (see
planArea). - options Object
downloadLayersoptions (id,name,extent,zoomMin,zoomMax, …) plus:- options.catalogName String
- The catalog's cache name; defaults to the area id.
- options.onProgress function
- Called with
{phase: 'tiles'|'catalog'|'switching', ...}(done,total,failed,byteswhile downloading).
Returns {area, catalog, readiness}: the area record, the downloadDefinitions result and getOfflineReadiness({extent}) at the end.
// the imóvel and its maps, ready for the field
ExtjsUtils.OFFLINE.prepareOffline(["CSR:show_car", "CSR:planet_brasil_2024", "CSR:cultivo_cafe_cafe"], {
id: "imovel_42",
onProgress: function(p) { console.log(p.phase, p.done, p.total); }
}).then(function(result) {
console.log(result.readiness.ready ? "ready offline" : "missing: " + result.readiness.missing.join(", "));
});reloadMapTiles
function(options) : Numberhelper# Asks the tiled layers on the map for their tiles again, so what the screen shows follows the current serving policy and bucket contents right away instead of at the next pan or zoom.
reloadMapTilesWritten as ExtjsUtils.OFFLINE.reloadMapTiles
Asks the tiled layers on the map for their tiles again, so what the screen shows follows the current serving policy and bucket contents right away instead of at the next pan or zoom. Every tile URL gets a fresh _dc value, so the browser cannot answer from its own memory/HTTP cache and the service worker sees each request; OfflineCacheKey.normalize drops _dc, so the offline buckets still match. WMS layers (and the maps inside a Composed layer) carry it as a request parameter, XYZ/OSM basemaps on their URL template. Hidden layers only get the new URLs (they request them when shown). setServingPolicy calls this for you.
- options Object
{layers}— theOpenLayers.Layers, orgetCacheableLayers()targets, to reload; default: every layer on the map.
Returns How many layers were asked to reload.
ExtjsUtils.OFFLINE.reloadMapTiles();// only the downloaded-area layers
ExtjsUtils.OFFLINE.reloadMapTiles({ layers: ExtjsUtils.OFFLINE.getCacheableLayers() });resetAllOfflineData
function() : Promise.<undefined>helper# Full reset ("Reset offline data"): deletes every offline area (cache + record), every shared definitions bucket and — when a service worker controls the page — the app-shell/dynamic caches and the …
resetAllOfflineDataWritten as ExtjsUtils.OFFLINE.resetAllOfflineData
Full reset ("Reset offline data"): deletes every offline area (cache + record), every shared definitions bucket and — when a service worker controls the page — the app-shell/dynamic caches and the worker registration itself (the worker's self-destruct path, waited for up to 3 s). The page keeps working online; reload it to register the worker again. Use it for a "clear all offline data" button.
Returns Resolves once everything is cleared.
ExtjsUtils.OFFLINE.resetAllOfflineData().then(function() { location.reload(); });sanitizeAreaId
function(raw) : String|nullhelper# Turns a user/host-provided cache id into a safe Cache Storage / IndexedDB key segment ([a-z0-9_-], max 80).
sanitizeAreaIdWritten as ExtjsUtils.OFFLINE.sanitizeAreaId
Turns a user/host-provided cache id into a safe Cache Storage / IndexedDB key segment ([a-z0-9_-], max 80). Empty input ⇒ null (caller should use createAreaId). The Cache Storage bucket is always OfflineCacheKey.areaCacheName(id) = mappia_offline_area_<id>; the same id is the IndexedDB record key.
- raw String
- Proposed id (e.g.
"fazenda-santa-clara").
Returns Sanitized id, or null when nothing usable remains.
ExtjsUtils.OFFLINE.sanitizeAreaId("Fazenda Santa Clara!"); // "fazenda_santa_clara"saveAreaRecord
function(area) : Promise.<Object>helper# Inserts or replaces an area record (keyed by area.id), stamping updatedAt.
saveAreaRecordWritten as ExtjsUtils.OFFLINE.saveAreaRecord
Inserts or replaces an area record (keyed by area.id), stamping updatedAt. The download/import functions save the record themselves; call it to persist your own edits to a record, e.g. a renamed area.
- area Object
- The area record to store (see
listAreasfor its shape); mutated to setupdatedAt.
Returns The same record, once written.
ExtjsUtils.OFFLINE.getArea(areaId).then(function(area) {
area.name = "Talhão norte";
return ExtjsUtils.OFFLINE.saveAreaRecord(area);
});saveBlobAsFile
function(blob, filename)helper# Hands a Blob to the browser as a file download (a programmatic <a download> click).
saveBlobAsFileWritten as ExtjsUtils.OFFLINE.saveBlobAsFile
Hands a Blob to the browser as a file download (a programmatic <a download> click). Works from inside the embedding iframe as long as it is not sandboxed without allow-downloads; the Blob never has to cross postMessage.
- blob Blob
- The file content, e.g. the zip from
exportAreaAsZip. - filename String
- The suggested file name.
ExtjsUtils.OFFLINE.saveBlobAsFile(blob, "mappia-offline-area-fazenda.zip");selectCacheableLayers
function(layerNames) : Array.<Object>helper# getCacheableLayers, one target per map name and optionally only the named maps — the selection downloadArea's layerNames makes.
selectCacheableLayersWritten as ExtjsUtils.OFFLINE.selectCacheableLayers
getCacheableLayers, one target per map name and optionally only the named maps — the selection downloadArea's layerNames makes. The map name is the WMS LAYERS (e.g. "CSR:planet_brasil_2024"), or layer.name for XYZ/OSM ("OSM Mapnik"); it is what an area's layerNames record. When a map is on the map twice (a query adding an OSM basemap the platform already shows), the visible copy is kept. Names not on the map are left out — compare the lengths to detect them.
- layerNames Array.<String>
- Map names to keep, in this order; omitted ⇒ every cacheable map.
Returns Targets {layer, kind} as getCacheableLayers returns them.
var targets = ExtjsUtils.OFFLINE.selectCacheableLayers(["CSR:planet_brasil_2024", "CSR:cultivo_cafe_cafe"]);setAreaEnabled
function(id, enabled, options) : Promise.<Object>helper# Switches one downloaded area on or off for serving, keeping its tiles: off, the worker leaves that bucket out of its index, so nothing in it is answered from the cache (nor used for the coarser-zoom …
setAreaEnabledWritten as ExtjsUtils.OFFLINE.setAreaEnabled
Switches one downloaded area on or off for serving, keeping its tiles: off, the worker leaves that bucket out of its index, so nothing in it is answered from the cache (nor used for the coarser-zoom crop) until it is switched on again — the way to keep several areas downloaded (e.g. the same extent at zoom 14-16 and at 11-13, as two areas) and choose which one is live to test. Stored on the record (area.enabled, undefined = on) and in the bucket's own metadata entry, where the worker reads it. Waits for the worker to confirm it rebuilt its index under the new state, then asks the map to request its tiles again (reloadMapTiles), so the screen shows the difference at once instead of at the next pan or zoom. Pass {reloadTiles: false} to only store the toggle.
- id String
- The area id.
- enabled Boolean
trueto serve it,falseto switch it off.- options Object
{reloadTiles}— defaults totrue.
Returns The saved record.
ExtjsUtils.OFFLINE.setAreaEnabled(areaId, false);setMaxZoom
function(target, zoom) : Number|nullhelper# Sets — or, with null, clears — the "real max zoom" of a WMS map at runtime: past it the map keeps requesting the max-zoom tile and stretches it, so what the user sees and what an offline area …
setMaxZoomWritten as ExtjsUtils.OFFLINE.setMaxZoom
Sets — or, with null, clears — the "real max zoom" of a WMS map at runtime: past it the map keeps requesting the max-zoom tile and stretches it, so what the user sees and what an offline area downloads (zooms above the limit collapse onto it) change at once. A raster whose detail ends at some zoom (suggestMaxZoom) downloads far fewer tiles this way. XYZ/OSM basemaps cannot be limited (describeCacheableLayers → canLimitMaxZoom).
- target Object|String
- A
{layer, kind}entry fromgetCacheableLayers, or the map name. - zoom Number|null
- The deepest zoom to request, or
nullfor no limit.
Returns The limit now in force (getMaxZoom).
ExtjsUtils.OFFLINE.setMaxZoom("CSR:planet_brasil_2024", 15);setServingPolicy
function(policy) : Promise.<Object>helper# Sets the serving policy (see getServingPolicy), tells the worker — which applies it from the next request on, no page reload — and then asks the map to request its tiles again (reloadMapTiles), …
setServingPolicyWritten as ExtjsUtils.OFFLINE.setServingPolicy
Sets the serving policy (see getServingPolicy), tells the worker — which applies it from the next request on, no page reload — and then asks the map to request its tiles again (reloadMapTiles), so the screen shows the new mode at once instead of at the next pan or zoom. Pass reloadTiles: false to only store the policy (e.g. right before a download).
- policy Object
{mode, forceOffline, reloadTiles}—modeis"CacheFirst","NetworkFirst","CacheOnly"or"NetworkOnly"(legacy kebab-case accepted);forceOffline(defaultfalse) makes the worker treat the network as down regardless ofnavigator.onLine— any call without it turns simulated offline back off;reloadTilesdefaults totrue.
Returns The stored policy {mode, forceOffline, updatedAt}.
ExtjsUtils.OFFLINE.setServingPolicy({ mode: "CacheFirst" });// store only; the tiles on screen keep what they show
ExtjsUtils.OFFLINE.setServingPolicy({ mode: "NetworkOnly", reloadTiles: false });// simulate being offline, without DevTools throttling
ExtjsUtils.OFFLINE.setServingPolicy({ mode: "CacheOnly", forceOffline: true });showAreaOutline
function(extent) : Booleanhelper# Outlines an area on the map — a dashed rectangle, e.g. the extent about to be downloaded — or, with no extent, removes the outline.
showAreaOutlineWritten as ExtjsUtils.OFFLINE.showAreaOutline
Outlines an area on the map — a dashed rectangle, e.g. the extent about to be downloaded — or, with no extent, removes the outline. One outline at a time, on a vector layer of its own kept out of the layer list.
- extent OpenLayers.Bounds|Array.<Number>|Object|null
- The area, in map units;
nullremoves the outline.
Returns true when an outline is shown.
ExtjsUtils.OFFLINE.showAreaOutline(ExtjsUtils.LAYER.getLayerExtent("CSR:show_car"));suggestMaxZoom
function(target) : Object|nullhelper# Suggests the finest zoom at which a raster layer still adds real detail, from the pixel size its GetCapabilities abstract declares (the platform's rasters carry a generated "Cell Width : N" line; …
suggestMaxZoomWritten as ExtjsUtils.OFFLINE.suggestMaxZoom
Suggests the finest zoom at which a raster layer still adds real detail, from the pixel size its GetCapabilities abstract declares (the platform's rasters carry a generated "Cell Width : N" line; e.g. a 29.04 m cell size gives zoom 13 on the Web Mercator series, so zoom 14+ is pure upsampling). Cell sizes below 1 are read as degrees and converted at the equator. It is a suggestion, not a setting: pass result.maxZoom to layer.setMaxZoom() (or put maxZoom in the layer config) to actually apply it, which shrinks the offline area (see effectiveZoom). The layer's capabilities record must be loaded (wait for the "local" source).
- target Object|OpenLayers.Layer
- A
{layer, kind}entry fromgetCacheableLayers, or the layer itself.
Returns {cellSize, metersPerCell, maxZoom}, or null when the abstract declares no cell size.
ExtjsUtils.OFFLINE.getCacheableLayers().forEach(function(t) {
var suggestion = ExtjsUtils.OFFLINE.suggestMaxZoom(t);
if (suggestion && typeof t.layer.setMaxZoom === "function") t.layer.setMaxZoom(suggestion.maxZoom);
});updateServiceWorker
function() : Promise.<Object>helper# Asks the server for a newer service worker script (registration.update()) and activates it (activateLatestServiceWorker).
updateServiceWorkerWritten as ExtjsUtils.OFFLINE.updateServiceWorker
Asks the server for a newer service worker script (registration.update()) and activates it (activateLatestServiceWorker). Never rejects.
Returns The activateLatestServiceWorker result plus {updated: true}, or {ok: false, error}.
ExtjsUtils.OFFLINE.updateServiceWorker().then(function(sw) {
console.log(sw.ok ? "now on " + sw.build : sw.error);
});useDefinitions
function(name) : Promise.<(String|null)>helper# Chooses where THIS page loads its catalog (the WMS GetCapabilities) from: a named definitions cache, or — with null or "live" — the live server.
useDefinitionsWritten as ExtjsUtils.OFFLINE.useDefinitions
Chooses where THIS page loads its catalog (the WMS GetCapabilities) from: a named definitions cache, or — with null or "live" — the live server. Only this page is affected: every other Mappia instance keeps its own choice. The catalog is reloaded at once, and the query's layers wait for it (QUERY.sourceLoading), so a query can make the choice in its && chain before its layer list — e.g. to start from a cached catalog when the map server is unreachable. To choose before the page's first catalog load, open the map page with ?definitions=<name> instead. Only the service worker answers from a cache, so a cache needs this page controlled by it.
- name String|null
- The cache name or id (
listDefinitions), ornull/"live"for the live catalog.
Returns Resolves with the choice once the catalog has reloaded; rejects, changing nothing, for a cache when no service worker controls this page.
// in a query: layers built from the cached catalog "fazenda-42"
ExtjsUtils.OFFLINE.useDefinitions("fazenda-42") && [
{ name: "CSR:cultivo_cafe_cafe", title: "Café", visibility: true }
]verifyAreaServed
function(id, options) : Promise.<Object>helper# Proves an area is really served offline.
verifyAreaServedWritten as ExtjsUtils.OFFLINE.verifyAreaServed
Proves an area is really served offline. It re-requests a sample of the URLs in the area's cache through the page's normal fetch path (bypassing the HTTP cache), so the service worker sees them like any tile request, and counts the responses the worker stamped as coming from this area's bucket. Without a controlling worker nothing can be served from the cache at all — controlled: false says so (on localhost the worker is off unless the service-worker config enables it, and a freshly registered worker only controls the page from its next load). It also checks coverage against the bucket's own metadata: re-enumerates the tiles the recorded extent, zoom range and layers imply — with the live layers, so the same query must be loaded — and reports which are missing from the cache.
- id String
- The area id.
- options Object
- Verification options.
- options.sampleSize Number
- How many cached URLs to re-request;
0checks every entry. - options.signal AbortSignal
- Aborts the sample requests.
- options.coverage Boolean
falseto skip the coverage re-enumeration.
Returns {id, cacheName, controlled, metadata, cachedEntries, checked, servedFromCache, servedByNetwork, failed, entries: [{url, status, servedFrom}], coverage: {layersFound, expected, present, missing, missingSample} | null}.
ExtjsUtils.OFFLINE.verifyAreaServed(areaId, {sampleSize: 30}).then(function(result) {
if (!result.controlled) console.warn("no service worker controls this page yet");
console.log(result.servedFromCache + "/" + result.checked + " served from the area cache");
if (result.coverage) console.log(result.coverage.missing + " expected tiles missing");
});whenLayersReady
function(timeoutMs) : Promisehelper# Resolves once the query's layers are on the map: the remote WMS sources the query registered have loaded their capabilities (QUERY.sourceLoading) and the layer files have loaded (QUERY.layerLoading).
whenLayersReadyWritten as ExtjsUtils.OFFLINE.whenLayersReady
Resolves once the query's layers are on the map: the remote WMS sources the query registered have loaded their capabilities (QUERY.sourceLoading) and the layer files have loaded (QUERY.layerLoading). The page's own sources (the "local" catalog) are already loaded by then — the platform applies a query only after every source is ready. Call it before getCacheableLayers/selectCacheableLayers in code that runs right after a query is applied — earlier, a {name: "CSR:..."} layer may simply not be on the map yet and an area downloaded then would silently miss it. downloadArea and downloadAreaAsZip wait for it themselves unless given layers. Never rejects: after timeoutMs it resolves with whatever loaded.
- timeoutMs Number
- Longest wait, in milliseconds.
Returns Resolves (with no value) when the layers are ready or the time is up.
ExtjsUtils.OFFLINE.whenLayersReady().then(function() {
console.log(ExtjsUtils.OFFLINE.getCacheableLayers().length + " cacheable layers");
});CAPABILITIES · catalogue filter (options=capabilities)
CAPABILITIES3 entriesUsage: ExtjsUtils.CAPABILITIES
filterDocument
function(xmlDoc, mapNames, projectionCode) : Documenthelper# Prunes a parsed WMS GetCapabilities Document in place so it only describes mapNames: every nested <Layer> not in the list is dropped (the kept ones are re-appended in the list's order), then …
filterDocumentWritten as ExtjsUtils.CAPABILITIES.filterDocument
Prunes a parsed WMS GetCapabilities Document in place so it only describes mapNames: every nested <Layer> not in the list is dropped (the kept ones are re-appended in the list's order), then every WMS-C <TileSet> of another layer, then every top-level <SRS> no remaining layer (nor the map) uses. This is the same pruning the editor applies when a query is saved, and what the offline engine applies before caching the live capabilities.
- xmlDoc Document
- The parsed GetCapabilities XML document; it is mutated.
- mapNames Array.<String>
- WMS layer names to keep (see
getMapNamesInUse). - projectionCode String
- Map projection (e.g.
"EPSG:900913"), kept in the SRS list even if no layer declares it.
Returns The same document, pruned.
var map = ExtjsUtils.JS.getMap();
var xmlDoc = new OpenLayers.Format.XML().read(capabilitiesXmlText);
ExtjsUtils.CAPABILITIES.filterDocument(xmlDoc, ExtjsUtils.CAPABILITIES.getMapNamesInUse(map), map.projection);filterText
function(xmlText, mapNames, projectionCode) : Stringhelper# filterDocument() for XML text in and text out: parses xmlText, prunes it to mapNames and serializes the result back to a string.
filterTextWritten as ExtjsUtils.CAPABILITIES.filterText
filterDocument() for XML text in and text out: parses xmlText, prunes it to mapNames and serializes the result back to a string. Handy when the capabilities came from a fetch/XHR response and must be stored or served as text again.
- xmlText String
- The raw GetCapabilities XML text.
- mapNames Array.<String>
- WMS layer names to keep (see
getMapNamesInUse). - projectionCode String
- Map projection (e.g.
"EPSG:900913"), kept in the SRS list even if no layer declares it.
Returns The serialized, pruned document.
var map = ExtjsUtils.JS.getMap();
fetch(ExtjsUtils.REQUEST.getGeoserverBaseUrl() + "/wms?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1")
.then(function(response) { return response.text(); })
.then(function(xmlText) {
var pruned = ExtjsUtils.CAPABILITIES.filterText(xmlText,
ExtjsUtils.CAPABILITIES.getMapNamesInUse(map), map.projection);
console.log(pruned.length + " bytes after pruning");
});getMapNamesInUse
function(map) : Array.<String>helper# Lists the WMS map names a map currently uses: each layer's LAYERS parameter (comma-separated, e.g. "CSR:a,CSR:b") plus its otherNames (LayersProperties.otherNames — maps the query needs at …
getMapNamesInUseWritten as ExtjsUtils.CAPABILITIES.getMapNamesInUse
Lists the WMS map names a map currently uses: each layer's LAYERS parameter (comma-separated, e.g. "CSR:a,CSR:b") plus its otherNames (LayersProperties.otherNames — maps the query needs at runtime but does not draw initially). Layers without a LAYERS parameter (XYZ/OSM/vector) contribute nothing. The result is unique, in first-seen order. Use it to know which maps a capabilities document must keep, or simply to enumerate the WMS maps on screen.
- map OpenLayers.Map
- The map whose layers are inspected (normally
ExtjsUtils.JS.getMap()).
Returns Unique WMS layer names, e.g. ["CSR:estados", "CSR:cultivo_cafe_cafe"].
var names = ExtjsUtils.CAPABILITIES.getMapNamesInUse(ExtjsUtils.JS.getMap());
console.log(names); // ["CSR:estados", "CSR:cultivo_cafe_cafe"]Other globals and libraries
Ext.LayerAdditional · overlay layer built from code
LayerAdditional16 entriesUsage: var overlay = new Ext.LayerAdditional({}, ExtjsUtils.JS.getMap()); overlay.createLayer(); overlay.addFeatures(features);
LayerAdditional
function(config, map)# new Ext.LayerAdditional(config, map) — a private vector overlay: an OpenLayers.Layer.Vector that is added to the map but deliberately kept out of the layer tree (displayInLayerSwitcher: false), …
LayerAdditionalWritten as Ext.LayerAdditional
new Ext.LayerAdditional(config, map) — a private vector overlay: an OpenLayers.Layer.Vector that is added to the map but deliberately kept out of the layer tree (displayInLayerSwitcher: false), for markers, highlights, search results and geometry pushed in from a parent page. Use it when something must render on the map without becoming a user-visible, toggleable tree entry; for ordinary user-facing data prefer a declarative source: "file" layer. The backing layer is created lazily by createLayer() (or by drawFeature()), and features added before that are buffered and flushed on creation. It does not follow the visibility of any other layer on its own.
Constructor arguments: config — an object with the optional keys listeners (an Ext listeners object for the events below) and layerConfig (when given, the layer is created immediately with createLayer(layerConfig, layerConfig.async)); map — the OpenLayers.Map to draw on, normally ExtjsUtils.JS.getMap() / app.mapPanel.map.
Events (Ext.util.Observable): addedLayer — fired with {layer} right after the vector layer is created and added to the map; removedLayer — fired with {layer} by removeLayer() right after the layer is removed from the map.
Public properties: vectorLayer — the OpenLayers.Layer.Vector, null until created; map — the map given to the constructor.
- config Object
- Optional configuration:
listenersand/orlayerConfigas described above; pass{}for none. - map OpenLayers.Map
- The map the overlay is drawn on.
// a reusable highlight overlay driven by parent-page messages
ExtjsUtils.QUERY.setQueryGlobalProperties({
highlightLayer: null,
ensureHighlightLayer: function() {
if (!window.highlightLayer) {
window.highlightLayer = new Ext.LayerAdditional({}, ExtjsUtils.JS.getMap());
window.highlightLayer.createLayer({
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style({fillColor: "#ffcc33", fillOpacity: 0.35, strokeColor: "#ff6600", strokeWidth: 2, pointRadius: 6, graphicName: "circle"})
})
});
}
return window.highlightLayer;
},
showHighlight: function(geojson) {
var overlay = window.ensureHighlightLayer();
overlay.removeFeatures(); // no argument: clear everything
overlay.addFeatures(ExtjsUtils.GEOJSON.geojson2Features(geojson));
}
}) && ExtjsUtils.QUERY.setMappiaIoCallback(function(message) {
if (message && message.type === "geojson") window.showHighlight(message.msg);
}) && [
{ name: "CSR:estados", title: "Estados", visibility: true }
]// listen to the layer lifecycle
var overlay = new Ext.LayerAdditional({
listeners: { addedLayer: function(evt) { console.log("created", evt.layer.id); } }
}, ExtjsUtils.JS.getMap());addFeatures
function(features)# Adds one feature or an array of features to the overlay.
addFeaturesAdds one feature or an array of features to the overlay. When the layer does not exist yet the features are buffered and added as soon as createLayer runs, so it is safe to call in any order. Features must be in the map projection — build them with createPoint/createFeature, or convert GeoJSON with ExtjsUtils.GEOJSON.geojson2Features.
- features OpenLayers.Feature.Vector|Array.<OpenLayers.Feature.Vector>
- The feature(s) to add.
overlay.addFeatures(new OpenLayers.Feature.Vector(overlay.createPoint(-44.0, -20.5, "EPSG:4326"), {name: "Fazenda"}));createFeature
function(geometries) : OpenLayers.Feature.Vector# Wraps one geometry, or an array of geometries (combined into an OpenLayers.Geometry.Collection), in a vector feature you can then style and add with drawFeature/addFeatures.
createFeatureWraps one geometry, or an array of geometries (combined into an OpenLayers.Geometry.Collection), in a vector feature you can then style and add with drawFeature/addFeatures.
- geometries OpenLayers.Geometry|Array.<OpenLayers.Geometry>
- The geometry, or several geometries drawn as one feature.
Returns The new feature (no attributes, no style).
var feature = overlay.createFeature(overlay.createPoint(-44.0, -20.5, "EPSG:4326"));
feature.attributes.name = "Fazenda";
overlay.addFeatures(feature);createImageTile
function(bbox, projection) : OpenLayers.Feature.Vector|undefined# Builds a feature representing an image tile: a rectangle covering bbox plus a point at its centre, combined in one geometry collection.
createImageTileBuilds a feature representing an image tile: a rectangle covering bbox plus a point at its centre, combined in one geometry collection. Style it with externalGraphic (the image URL) and pointRadius (half the image size) to draw a picture at the centre of the box, e.g. a thumbnail or a symbol over an area. Returns undefined (and logs) when bbox does not have exactly four numbers.
- bbox Array.<Number>
- The tile bounds as
[left, bottom, right, top]. - projection String|OpenLayers.Projection
- The projection
bboxis expressed in.
Returns The tile feature, or undefined for an invalid bbox.
var tile = overlay.createImageTile([-44.1, -20.6, -43.9, -20.4], "EPSG:4326");
overlay.drawFeature(tile, {externalGraphic: "/theme/app/img/logo.png", pointRadius: 24, strokeColor: "#666666", fillOpacity: 0});createLayer
function(layerConfig, async)# Creates the backing vector layer, once: the call is ignored when the layer already exists or its creation is pending, and the configuration of an existing layer is not updated.
createLayerCreates the backing vector layer, once: the call is ignored when the layer already exists or its creation is pending, and the configuration of an existing layer is not updated. The layer gets a generated id, displayInLayerSwitcher: false and the initialVisibility, is added to the map, addedLayer is fired and the features buffered by addFeatures are flushed into it. When layerConfig is omitted a built-in grey/white styleMap for points, lines and polygons is used. Creation is synchronous by default; pass async: true to defer it to a short timeout (useful when called from inside another map event).
- layerConfig Object
OpenLayers.Layer.Vectoroptions — typically{styleMap: new OpenLayers.StyleMap({...})}; omitted ⇒ the default style.- async Boolean
trueto create the layer asynchronously (viasetTimeout);false, the default, creates it immediately.
var overlay = new Ext.LayerAdditional({}, ExtjsUtils.JS.getMap());
overlay.createLayer({
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style({fillColor: "${color}", fillOpacity: 0.4, strokeColor: "#333333", strokeWidth: 1}),
"select": new OpenLayers.Style({strokeColor: "#ff0000", strokeWidth: 3})
})
});createPoint
function(x, y, projection) : OpenLayers.Geometry.Point# Creates a point geometry from coordinates given in projection and transforms it into the map projection, ready to be wrapped in a feature or used as a polygon vertex.
createPointCreates a point geometry from coordinates given in projection and transforms it into the map projection, ready to be wrapped in a feature or used as a polygon vertex. For a longitude/latitude pair pass "EPSG:4326".
- x Number
- The horizontal coordinate (longitude for EPSG:4326).
- y Number
- The vertical coordinate (latitude for EPSG:4326).
- projection String|OpenLayers.Projection
- The projection
x/yare expressed in (seeresolveProjection).
Returns The point, in the map projection.
var marker = new OpenLayers.Feature.Vector(overlay.createPoint(-46.63, -23.55, "EPSG:4326"));
overlay.addFeatures(marker);createPolygon
function(points) : OpenLayers.Geometry.Polygon# Creates a polygon geometry with a single ring whose vertices are the given points (in order; the ring is closed automatically).
createPolygonCreates a polygon geometry with a single ring whose vertices are the given points (in order; the ring is closed automatically).
- points Array.<OpenLayers.Geometry.Point>
- The vertices, already in the map projection (e.g. from
createPoint).
Returns The polygon.
var square = overlay.createPolygon([
overlay.createPoint(-44.1, -20.4, "EPSG:4326"), overlay.createPoint(-43.9, -20.4, "EPSG:4326"),
overlay.createPoint(-43.9, -20.6, "EPSG:4326"), overlay.createPoint(-44.1, -20.6, "EPSG:4326")
]);
overlay.drawFeature(overlay.createFeature(square), {fillColor: "#00ff00", fillOpacity: 0.2});drawFeature
function(feature, style)# Styles and draws a feature in one call: creates the layer if needed (createLayer() with the default style), sets feature.style to style completed with OpenLayers' default symbolizer, and adds the feature.
drawFeatureStyles and draws a feature in one call: creates the layer if needed (createLayer() with the default style), sets feature.style to style completed with OpenLayers' default symbolizer, and adds the feature. A per-feature style set this way takes precedence over the layer's styleMap.
- feature OpenLayers.Feature.Vector
- The feature to draw (see
createFeature). - style Object
- OpenLayers symbolizer properties (
fillColor,fillOpacity,strokeColor,strokeWidth,pointRadius,externalGraphic,label, ...); omitted ⇒ the layer's styleMap applies.
var point = overlay.createFeature(overlay.createPoint(-44.0, -20.5, "EPSG:4326"));
overlay.drawFeature(point, {pointRadius: 8, fillColor: "#ff0000", strokeColor: "#ffffff", strokeWidth: 2});drawLatLongExtents
function(llbbox, color)# Draws a highlighted rectangle for a lon/lat bounding box — the way the interface outlines a layer's extent: two stacked rectangles, a wide white border with a translucent fill under a thin coloured border.
drawLatLongExtentsDraws a highlighted rectangle for a lon/lat bounding box — the way the interface outlines a layer's extent: two stacked rectangles, a wide white border with a translucent fill under a thin coloured border. Creates the layer if needed. Logs and does nothing when llbbox does not have exactly four numbers.
- llbbox Array.<Number>
- The bounds in EPSG:4326 as
[left, bottom, right, top](west, south, east, north), e.g. a record'sllbbox. - color String
- Fill colour (and, by default, the thin border colour
#FFC000is used).
var record = ExtjsUtils.LAYER.getLayersRecord("CSR:estados");
overlay.drawLatLongExtents(record.get("llbbox"), "#ff8800");map
OpenLayers.Map# The OpenLayers.Map the overlay draws on, as given to the constructor.
mapThe OpenLayers.Map the overlay draws on, as given to the constructor.
removeFeatures
function(features)# Removes features from the overlay — the given feature or array of features, or every feature when the argument is omitted (the usual "clear the highlight" call).
removeFeaturesRemoves features from the overlay — the given feature or array of features, or every feature when the argument is omitted (the usual "clear the highlight" call). Works before the layer exists too, by dropping them from the pending buffer.
- features OpenLayers.Feature.Vector|Array.<OpenLayers.Feature.Vector>
- The feature(s) to remove; omit to remove all.
overlay.removeFeatures(); // clear everything
overlay.removeFeatures(oneFeature); // remove a single featureremoveLayer
function()# Removes the vector layer from the map (firing removedLayer), cancels a pending async creation and forgets the layer, so the next createLayer/drawFeature creates a fresh one.
removeLayerRemoves the vector layer from the map (firing removedLayer), cancels a pending async creation and forgets the layer, so the next createLayer/drawFeature creates a fresh one. To only clear the drawn features and keep the layer, use removeFeatures() instead.
overlay.removeLayer();resolveProjection
function(projection) : OpenLayers.Projection# Normalizes a projection given as an EPSG string ("EPSG:4326"), an OpenLayers.Projection or any object with getCode() into an OpenLayers.Projection, falling back to the map projection when it is missing.
resolveProjectionNormalizes a projection given as an EPSG string ("EPSG:4326"), an OpenLayers.Projection or any object with getCode() into an OpenLayers.Projection, falling back to the map projection when it is missing. Delegates to ExtjsUtils.PROJECTION.resolveProjectionObject; createPoint uses it, so you rarely need to call it yourself.
- projection String|OpenLayers.Projection|Object
- The projection to resolve; falsy ⇒ the map projection.
Returns The resolved projection object.
var proj = overlay.resolveProjection("EPSG:4326");
console.log(proj.getCode()); // "EPSG:4326"setOverLayer
function(baseLayer)# Makes sure the overlay is stacked above baseLayer: moves the vector layer's index to at least that layer's index (map.setLayerIndex).
setOverLayerMakes sure the overlay is stacked above baseLayer: moves the vector layer's index to at least that layer's index (map.setLayerIndex). Call it after createLayer (or after starting an async creation); the reorder happens on a short timeout to work around an OpenLayers/Ext re-entrancy bug when called from inside an event, so it is not effective synchronously.
- baseLayer OpenLayers.Layer
- The layer that must end up below the overlay.
overlay.createLayer();
overlay.setOverLayer(ExtjsUtils.LAYER.getLayerByName("CSR:estados"));setVisibility
function(state)# Shows or hides the overlay.
setVisibilityShows or hides the overlay. Before the layer is created it only records the initial visibility the layer will be created with; afterwards it calls vectorLayer.setVisibility(state).
- state Boolean
trueto show the overlay,falseto hide it.
overlay.setVisibility(!MOBILE_UTILS.isMobile());vectorLayer
OpenLayers.Layer.Vector|null# The backing OpenLayers.Layer.Vector where the features are drawn.
vectorLayerThe backing OpenLayers.Layer.Vector where the features are drawn. null until createLayer runs, then a real OpenLayers vector layer you may hand to other controls, e.g. new OpenLayers.Control.CustomSelectFeature(overlay.vectorLayer, {...}).
overlay.createLayer();
overlay.vectorLayer.events.register("featureselected", null, function(evt) { console.log(evt.feature); });AsyncLoader · load scripts once
AsyncLoader1 entryarray: {Array} A array of resource urls to load.
callback: Function that will be called when the load ends.
Usage: AsyncLoader.loadScriptOnce({Array}, {Function}}
loadScriptOnce
function(src, callback)# Loads one or more external resources by URL, each of them only once per page, and calls callback after every URL of the set has finished loading.
loadScriptOnceLoads one or more external resources by URL, each of them only once per page, and calls callback after every URL of the set has finished loading. A URL ending in .css is inserted as a <link rel="stylesheet">; any other URL is inserted as an async <script> tag (placed before the first script of the page). Use it inside a query to lazy-load libraries or data files (Highcharts modules, PapaParse, a pre-baked JS data file) right before the code that needs them.
Rules worth knowing: a URL that already finished loading is skipped, so repeated calls are cheap and safe; when nothing in the set still needs loading the callback runs synchronously, before this function returns; calls made with the same set of pending URLs share one loading queue, and all their callbacks run once that set completes; the callback receives no arguments.
- src String|Array.<String>
- A resource URL, or an array of URLs to load together.
- callback function
- Called (with no arguments) once every URL in
srcis loaded.
AsyncLoader.loadScriptOnce(["/theme/app/js/papaparse.min.js", "/theme/app/js/highcharts/latest/sankey.js"], function() {
// both files are loaded (or were already loaded): safe to use Papa and Highcharts.seriesTypes.sankey
drawSankeyChart();
});AsyncLoader.loadScriptOnce("/theme/app/css/my-query-styles.css");Lang · interface texts
Lang7 entriesLIST
Array.<String># The language codes the interface supports, in order: ['ptbr', 'eng'].
LISTWritten as Lang.LIST
The language codes the interface supports, in order: ['ptbr', 'eng']. The first one is the default when ?lang= is absent or unknown; the others are the accepted values of the lang URL parameter.
Lang.LIST.indexOf(ExtjsUtils.REQUEST.getParameterByName("lang")) !== -1Lang
Object# The interface translation dictionary, a global object whose keys are the strings the interface shows (Lang.maps, Lang.showLayerLegend, Lang.clearTransition, Lang.expandChart, …
LangWritten as Lang
The interface translation dictionary, a global object whose keys are the strings the interface shows (Lang.maps, Lang.showLayerLegend, Lang.clearTransition, Lang.expandChart, Lang.layerDetails, Lang.yes, Lang.cancel, ...). The values are Brazilian Portuguese by default; when the page is opened with ?lang=eng the entries of Lang.languages.eng are applied over them at load time (Lang.updateLang()), so a query that reads Lang.<key> gets the same wording the interface is using and follows the language switch for free. The key list is the object itself (this file); read a key, do not assign to it.
// a tenant button whose caption follows the interface language
descriptionHtml: '{{button|id=legendBtn|text=' + Lang.showLayerLegend + '}}'var caption = Lang.getLang() === "eng" ? "Coffee area" : "Área de café";formatMessage
function(content, params) : String# Fills the {placeholder} slots of a message template with the values of params: every {name} in content is replaced by params.name; a placeholder without a matching key is left as it is.
formatMessageWritten as Lang.formatMessage
Fills the {placeholder} slots of a message template with the values of params: every {name} in content is replaced by params.name; a placeholder without a matching key is left as it is. Several Lang messages are templates (e.g. Lang.invalidLayerName contains {layerName}), and a query can use the same mechanism for its own messages.
- content String
- The template text containing
{name}placeholders (typically aLangmessage). - params Object
- Values keyed by placeholder name.
Returns The template with the placeholders replaced.
Lang.formatMessage(Lang.invalidLayerName, {layerName: "CSR:estados"});
// 'O nome do mapa "CSR:estados" é inválido ou o mapa não foi carregado corretamente.'Lang.formatMessage("{count} features selected in {name}", {count: 3, name: "Minas Gerais"});getLang
function() : String# Returns the language code the interface is currently using: "ptbr" (default) or "eng" when the page was opened with ?lang=eng.
getLangWritten as Lang.getLang
Returns the language code the interface is currently using: "ptbr" (default) or "eng" when the page was opened with ?lang=eng. Use it to pick language-specific content of your own (labels, URLs, number formats) consistently with the interface.
Returns The current language code, one of Lang.LIST.
var chartTitle = Lang.getLang() === "eng" ? "Deforestation by year" : "Desmatamento por ano";lang
String# The language code currently applied, "ptbr" or "eng"; set by updateLang() at load time from the ?lang= URL parameter.
langWritten as Lang.lang
The language code currently applied, "ptbr" or "eng"; set by updateLang() at load time from the ?lang= URL parameter. Read it through Lang.getLang().
if (Lang.lang === "eng") { ... }updateLang
function()# Applies the language requested by the ?lang= URL parameter: when it names a known translation (Lang.languages.eng) its entries are copied over the Lang keys, and Lang.lang is set to it; …
updateLangWritten as Lang.updateLang
Applies the language requested by the ?lang= URL parameter: when it names a known translation (Lang.languages.eng) its entries are copied over the Lang keys, and Lang.lang is set to it; otherwise the default ptbr stays and Lang.lang is "ptbr". The platform calls it once at load time, before any interface text is rendered; a query does not need to call it, but calling it again is harmless.
Lang.updateLang();
console.log(Lang.getLang()); // "eng" when the URL has ?lang=engverifySupportedBrowser
function()# Shows the platform's "browser not supported" alert (Lang.browserNotSupported, via ExtjsUtils.ALERTIFY.alert) when ExtjsUtils.CHECK.browserSupported() says the current browser is too old; does nothing otherwise.
verifySupportedBrowserWritten as Lang.verifySupportedBrowser
Shows the platform's "browser not supported" alert (Lang.browserNotSupported, via ExtjsUtils.ALERTIFY.alert) when ExtjsUtils.CHECK.browserSupported() says the current browser is too old; does nothing otherwise. The interface calls it at startup; a query may call it again before enabling a feature that needs a modern browser.
Lang.verifySupportedBrowser();MOBILE_UTILS · mobile layout
MobileUtils1 entryUsage: MOBILE_UTILS.isMobile()
isMobile
function() : Boolean# Tells whether the interface is currently rendered in its mobile layout.
isMobileWritten as MOBILE_UTILS.isMobile
Tells whether the interface is currently rendered in its mobile layout. It reads the --is-mobile CSS variable that the responsive stylesheet sets from a media query (1 when the viewport is narrower than 768px, 0 otherwise), so the answer follows the viewport size and changes when the window is resized — re-check it inside a resize handler when a layout decision depends on it. This is distinct from ExtjsUtils.CHECK.isMobile(), which is device based (user agent / orientation).
Returns true when the mobile layout is active.
function layoutCharts() {
if (MOBILE_UTILS.isMobile()) {
// narrow screen: stack the chart under the map
} else {
// wide screen: keep the chart beside the map
}
}
layoutCharts();
ExtjsUtils.addDomListener(window, "resize", layoutCharts);Highcharts · charts
Highcharts1 entryUsage: (Highcharts.chart(DOM_ID, {});)
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 …
chartWritten 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 }]
});
}
}Sankey · flow charts (Highcharts module)
Sankey1 entryload
function() : undefined# A Sankey diagram - transitions between categories drawn as flows - is a Highcharts module rather than part of the bundled build, so it is loaded on demand before the chart is created.
loadA Sankey diagram - transitions between categories drawn as flows - is a Highcharts module rather than part of the bundled build, so it is loaded on demand before the chart is created. Once the module is in place, a Sankey is an ordinary Highcharts chart with type: 'sankey', whose data is a list of [from, to, weight] rows: one row per transition, which is exactly the shape a transition matrix produces.
Load it once, when the panel is ready, and draw inside the callback - the module is shared, so a second call with the same URL is free.
Returns Nothing; the chart is created in the callback.
AsyncLoader.loadScriptOnce('/theme/app/js/highcharts/latest/sankey.js', function () {
Highcharts.chart('transitions_chart', {
title: { text: 'Land use transitions' },
series: [{
type: 'sankey',
keys: ['from', 'to', 'weight'],
data: [['Forest', 'Pasture', 120], ['Pasture', 'Crop', 45]]
}]
});
});