Popups
In this chapter we want to add short informative popups on the map. We will open the popup when the mouse lasts for a certain amount of time at a specific location. Inside the popup we show the formatted coordinates of the hover-location. To do this we will make use of a GeoExt event on the GeoExt.component.Map
and of the class GeoExt.component.Popup
.
Exercises
- Prepare the
map.html
file to contain the following code. This is basically the result of the previous chapters:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Exercise | GeoExt Workshop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/classic/theme-triton/resources/theme-triton-all.css" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/ext-all.js" type="text/javascript"></script>
<link rel="stylesheet" href="./lib/ol/ol.css" type="text/css">
<script src="./lib/ol/ol.js" type="text/javascript"></script>
<script src="https://geoext.github.io/geoext3/master/GeoExt.js" type="text/javascript"></script>
</head>
<body>
<script>
var map;
Ext.onReady(function(){
var redStyle = new ol.style.Style({
image: circle = new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(220, 0, 0, 0.5)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(220, 0, 0, 0.8)',
width: 3
}),
radius: 8
})
});
var blueStyle = new ol.style.Style({
image: circle = new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(0, 0, 220, 0.5)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 220, 0.8)',
width: 3
}),
radius: 8
})
})
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'data/aimag-centers.json',
format: new ol.format.GeoJSON()
}),
name: 'Aimag',
style: redStyle
});
// 1) OpenLayers
//
// Create an instance of an OpenLayers map:
map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
name: 'OpenStreetMap'
}),
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://ows.terrestris.de/osm/service',
params: {
layers: 'OSM-WMS'
}
}),
name: 'OSM WMS (terrestris)'
}),
vectorLayer
],
view: new ol.View({
center: ol.proj.fromLonLat( [106.92, 47.92] ),
zoom: 4
})
});
// 2) GeoExt
//
// Create an instance of the GeoExt map component with that map:
var mapComponent = Ext.create('GeoExt.component.Map', {
map: map,
region: 'center'
});
var treeStore = Ext.create('GeoExt.data.store.LayersTree', {
layerGroup: map.getLayerGroup()
});
var layerTreePanel = Ext.create('Ext.tree.Panel', {
title: 'Layers of the application',
width: 300,
region: 'west',
store: treeStore,
rootVisible: false,
viewConfig: {
plugins: { ptype: 'treeviewdragdrop' }
}
});
var featureStore = Ext.create('GeoExt.data.store.Features', {
layer: vectorLayer,
map: map
});
var featureGrid = Ext.create('Ext.grid.Panel', {
store: featureStore,
region: 'south',
title: 'Centers of Mongolian Aimag',
columns: [
{xtype: 'gx_symbolizercolumn', width: 30},
{text: 'Name', dataIndex: 'NAME', flex: 3},
{text: 'Population', dataIndex: 'POP', flex: 1},
{text: 'AIMAG_ID', dataIndex: 'AIMAG_ID', flex: 1}
],
listeners: {
selectionchange: function(sm, selected) {
// reset all selections
featureStore.each(function(rec) {
rec.getFeature().setStyle(null);
});
// highlight grid selection in map
Ext.each(selected, function(rec) {
rec.getFeature().setStyle(blueStyle);
});
// update the grid rendering of the geometry
sm.view.refresh();
}
},
height: 300
});
// 3) Ext JS
//
// Create a viewport
var vp = Ext.create('Ext.container.Viewport', {
layout: 'border',
items: [
mapComponent,
layerTreePanel,
featureGrid
]
});
});
</script>
</body>
</html>
- If you open this file in a browser (/map.html), the application should look like in the following image:
- For popups to look right, we need some CSS. Include the following in the
<head>
of the page:
<link rel="stylesheet" href="http://geoext.github.io/geoext3/master/resources/css/gx-popup.css" type="text/css">
<style>
.gx-popup p {
padding: 5px 5px 0 5px;
border-radius: 7px;
background-color: rgba(255,255,255,0.85);
border: 3px solid white;
margin: 0;
text-align: center;
}
</style>
- Configure the existing
GeoExt.component.Map
withpointerRest: true
. Only if this configuration istrue
, the map-component will emit thepointerrest
&pointerrestout
events. - Read the documentation for
pointerrest
&pointerrestout
- Register an event-listener on
pointerrest
that logs the hovered coordinate. Use the OpenLayers utility methodsol.coordinate.toStringHDMS
andol.proj.transform
on theevt.coordinate
to format the coordinate.
- Once you have the above logging of the coordinate in place, we can now create a popup.
- Instantiate the class
GeoExt.component.Popup
and configure it with your map. You should also provide awidth
. Store the popup in an accessible variable;var popup
is a good choice. - Inside of the configured callback on
pointerrest
we now want to update the HTML of the popup (methodsetHtml
) and reposition it at the coordinate (methodposition
, pass the coordinates in the view projection). Finally,show
the popup.
- You may notice that the popup stays in place if the mouse leaves the map viewport, which is undesired in most of the cases. Use the event
pointerrestout
tohide
the popup whenever the mouse leaves the map.
- Congratulations, you can now happily hover anywhere on the map and be greeted with the hovered coordinate: