Vaadin Maps Example
Google Maps is a Web-based service that provides information about geographical regions and sites around the world.
Table Of Contents
1. The tools
- Java JDK 8
- Latest Eclipse Mars
- Vaadin 7.6.8
- Tomcat Server 8
2. Introduction
In this example we are going to use Google maps from our Vaadin application.We are also going to use an add-on to make Google maps available in our application.
The application is going to load Google maps and then go to a specific location in the world. We are going to create a window with a few widgets to navigate in Google maps using Vaadin.
With the controls we can introduce the latitude and the longitude and then navigate to that place in the map. You can set markers to a specific location and delete these markers.
3. Prerequisites
- JDK installed
- Eclipse Mars installed and working
- Vaadin plug-in installed
- Tomcat 8 installed and running
4. Set up the project
In the file menu choose File -> New -> Other
Now from the list choose Vaadin 7 project
Click next and name your project then click finish.
5. The example
5.1 Configure the add-on
We are going to use this wonderful add-on from here.
To configure the add-on we are using Ivy, but you can use Maven or configure the add-on manually.
5.1.1 Edit ivy.xml
Edit the file ivy.xml
in the project root. Then add the following lines inside the dependencies tag.
dependencies
<!-- Google Maps Addon --> <dependency org="com.vaadin.tapio" name="googlemaps" rev="1.3.2" />
This tells ivy what is the name of the plugin.
5.1.2 Edit ivysettings.xml
Edit the file ivysettings.xml
in the project root, and add the following lines inside the resolvers tag.
resolvers
<!-- Vaadin Google Maps Add On --> <ibiblio name="vaadin-addons" usepoms="true" m2compatible="true" root="http://maven.vaadin.com/vaadin-addons" />
This tells ivy where to find the plugin. Now ivy is going to download all dependencies needed by the add-on.
5.2 Edit the styles
We are going to use some custom styles in our application.
Open the styles file:
[PROJECT_ROOT]/WebContent/VAADIN/Themes/[PROJECT_NAME]/[PROJECT_NAME].scss
5.2.1 Windows contents
The window’s contents is the client area of the window widget.
Windows contents
.v-window-mywindowstyle .v-window-contents { background: #f8f8cd; }
We set the color to a light yellow.
5.2.2 Windows header
The header is the top of the window when we put the title.
Header
.v-window-mywindowstyle .v-window-outerheader { background: #0c2640; } .v-window-mywindowstyle .v-window-header { font-weight: bold; color: white; }
We set the background color to a dark blue and the text white with a bold font.
5.2.3 Error labels
We are going to create two labels to show the input errors.
Error labels
.v-label-mylabelstyle { color: white; text-align: center; background-color: red; border-color: white; font-weight: bold; }
We set the background color of the label to red and center the text. We also set the text bold and add a border to the label.
5.3 Main Class
5.3.1 Local Variables
We are going to use two local variables in our application. The variable for the map itself and a variable for the api key.
Local variables
private GoogleMap googleMap; private final String apiKey = "api-key";
private GoogleMap googleMap;
A local variable to the map instance.
private final String apiKey = "api-key";
The api key from Google.
The Api key is a key that allows you to use the Google Maps product. To obtain this key you need to log in, in Google developers and create a new project, generate the key for Google maps and activate the project.
5.3.2 The layout
We are going to use a vertical layout as our main layout.
Create the layout
VerticalLayout rootLayout = new VerticalLayout(); rootLayout.setSizeFull(); setContent(rootLayout);
VerticalLayout rootLayout = new VerticalLayout();
Creates a vertical layout.
rootLayout.setSizeFull();
Sets the size of the layout to full.
setContent(rootLayout);
Sets the vertical layout as our main content layout.
5.3.3 Create the map
We are going to initialize the map.
Create the map
googleMap = new GoogleMap(apiKey, null, null); googleMap.setZoom(10); googleMap.setSizeFull(); googleMap.setMinZoom(4); googleMap.setMaxZoom(16); Panel mapsPanel = new Panel(); mapsPanel.setSizeFull(); mapsPanel.setContent(googleMap); rootLayout.addComponent(mapsPanel);
googleMap = new GoogleMap(apiKey, null, null);
Initializes the instance of the map using the api key.
googleMap.setZoom(10);
Sets the default zoom.
googleMap.setSizeFull();
Sets the size of the map to fill all the client area.
googleMap.setMinZoom(4);
Sets the minimum zoom of the map.
googleMap.setMaxZoom(16);
Sets the maximum zoom of the map.
Panel mapsPanel = new Panel();
Creates a panel to put the map.
mapsPanel.setSizeFull();
Fills the entite client area.
mapsPanel.setContent(googleMap);
Sets the content of the panel to the map.
rootLayout.addComponent(mapsPanel);
Adds the map to the layout.
5.3.4 Create the tool box window
To control the map we are going to create a floating window. You can move this window to view behind it.
Create the window
Window mapToolBox = new Window("Map Tool Box"); mapToolBox.setClosable(false); mapToolBox.setResizable(false); mapToolBox.setPosition(10, 100); mapToolBox.setWidth("350px"); mapToolBox.setHeight("520px"); mapToolBox.addStyleName("mywindowstyle"); UI.getCurrent().addWindow(mapToolBox);
Window mapToolBox = new Window("Map Tool Box");
Creates the new window.
mapToolBox.setClosable(false);
Disables the close button of the window.
mapToolBox.setResizable(false);
Disables resize on the window.
mapToolBox.setPosition(10, 100);
Sets the initial position of the window.
mapToolBox.setWidth("350px");
Sets the width of the window.
mapToolBox.setHeight("520px");
Sets the height of the window.
mapToolBox.addStyleName("mywindowstyle");
Assigns the style to the window.
UI.getCurrent().addWindow(mapToolBox);
Adds the window to the UI.
5.3.5 Add the widgets to the window
The window contents
HorizontalLayout latlonLayout = new HorizontalLayout(); latlonLayout.setSpacing(true); TextField latitude = new TextField("Lat"); latitude.setWidth("100px"); latitude.setNullSettingAllowed(true); latitude.setNullRepresentation("0.0"); TextField longitude = new TextField("Long"); longitude.setWidth("100px"); longitude.setNullSettingAllowed(true); longitude.setNullRepresentation("0.0"); latlonLayout.addComponent(latitude); latlonLayout.addComponent(longitude); HorizontalLayout infoLayout = new HorizontalLayout(); infoLayout.setSpacing(true); Label currentLat = new Label(); currentLat.setCaption("Current Latitude"); Label currentLon = new Label(); currentLon.setCaption("Current Longitude"); infoLayout.addComponent(currentLat); infoLayout.addComponent(currentLon); TextField markerName = new TextField("Marker Name"); Label latErrMsg = new Label(); latErrMsg.addStyleName("mylabelstyle"); Label lonErrMsg = new Label(); lonErrMsg.addStyleName("mylabelstyle");
HorizontalLayout latlonLayout = new HorizontalLayout();
Creates a layout for the latitude and longitude inputs.
latlonLayout.setSpacing(true);
Sets the space of the layout.
TextField latitude = new TextField("Lat");
Create a text field to input the latitude.
latitude.setWidth("100px");
Sets the width of the text field.
latitude.setNullSettingAllowed(true);
Allows null into the text field.
latitude.setNullRepresentation("0.0");
Sets the null representation of the text field.
TextField longitude = new TextField("Long");
Creates a text field to input the longitude.
longitude.setWidth("100px");
Sets the width of the longitude text input.
longitude.setNullSettingAllowed(true);
Allows null into the text field.
longitude.setNullRepresentation("0.0");
Sets the null representation of the text field.
latlonLayout.addComponent(latitude);
Adds the latitude text field to the layout.
latlonLayout.addComponent(longitude);
Adds the longitude text field to the layout.
HorizontalLayout infoLayout = new HorizontalLayout();
Creates a layout for the info labels.
infoLayout.setSpacing(true);
Sets the spacing of the layout.
Label currentLat = new Label();
Creates a new label to show the current latitude.
currentLat.setCaption("Current Latitude");
Sets the caption of the label.
Label currentLon = new Label();
Creates a label to show the current longitude.
currentLon.setCaption("Current Longitude");
Sets the caption of the current longitude label.
infoLayout.addComponent(currentLat);
Adds the latitude label to the info layout.
infoLayout.addComponent(currentLon);
Adds the longitude label to the info layout.
TextField markerName = new TextField("Marker Name");
Creates a text field to input marker names.
Label latErrMsg = new Label();
Creates a label to show latitude input errors.
latErrMsg.addStyleName("mylabelstyle");
Adds a style to the label.
Label lonErrMsg = new Label();
Creates a label to show longitude input errors.
lonErrMsg.addStyleName("mylabelstyle");
Adds the style to the error label.
5.3.6 Button to add markers
We are going to create a button to add a marker to the current location.
Add markers
Button.ClickListener addMarkerListener = new ClickListener() { @Override public void buttonClick(ClickEvent event) { String mName = markerName.getValue(); if(mName.isEmpty()){ mName = "Marker"; } Double dLat = 0.0; Double dLon = 0.0; dLat = Double.valueOf(currentLat.getValue()); dLon = Double.valueOf(currentLon.getValue()); GoogleMapMarker customMarker = new GoogleMapMarker(mName, new LatLon(dLat, dLon),true, null); googleMap.addMarker(customMarker); } }; Button addMarker = new Button("Add Marker", FontAwesome.ANCHOR); addMarker.addClickListener(addMarkerListener);
Button.ClickListener addMarkerListener = new ClickListener()
Creates a click listener.
String mName = markerName.getValue();
Gets the value of the markers text field.
if(mName.isEmpty())
Checks if the name of the marker id empty.
mName = "Marker";
If the name of the marker id is empty it adds a default name.
Double dLat = 0.0;
Creates a variable to store the latitude.
Double dLon = 0.0;
Creates a variable to store the longitude.
dLat = Double.valueOf(currentLat.getValue());
Gets the value of the current latitude into the variable.
dLon = Double.valueOf(currentLon.getValue());
Gets tha value of the current longitude into the variable.
GoogleMapMarker customMarker = new GoogleMapMarker(mName, new LatLon(dLat, dLon),true, null);
Creates a new marker with the name, the latitude and the longitude supplied.
googleMap.addMarker(customMarker);
Adds the marker to the map.
Button addMarker = new Button("Add Marker", FontAwesome.ANCHOR);
Creates the button to add the marker.
addMarker.addClickListener(addMarkerListener);
Assigns the listener to the button.
5.3.7 Button to move the view
We are going to create a button to move the view of the map to a fixed latitude and longitude coordinates.
Move view
Button.ClickListener moveView = new ClickListener() { @Override public void buttonClick(ClickEvent event) { Boolean val = true; Double dLat = 0.0; Double dLon = 0.0; try { dLat = Double.valueOf(latitude.getValue()); } catch (Exception e) { val = false; latErrMsg.setValue("Latitude is not a valid number"); } try { dLon = Double.valueOf(longitude.getValue()); } catch (Exception e) { val = false; lonErrMsg.setValue("Longitude is not a valid number"); } if(val){ latErrMsg.setValue(""); lonErrMsg.setValue(""); if((dLat= 85.0)){ val = false; latErrMsg.setValue("Latitude must be between -85.0 and 85.0"); } if((dLon= 180.0)){ val = false; lonErrMsg.setValue("Longitude must be between -180.0 and 180.0"); } } if(val){ latErrMsg.setValue(""); lonErrMsg.setValue(""); googleMap.setCenter(new LatLon(dLat, dLon)); googleMap.setZoom(12); currentLat.setValue(latitude.getValue()); currentLon.setValue(longitude.getValue()); } } }; Button moveButton = new Button("Move", FontAwesome.BULLSEYE); moveButton.addClickListener(moveView);
Button.ClickListener moveView = new ClickListener()
Creates a click listener for the move view button.
Boolean val = true;
Creates a boolean val to validate the input.
Double dLat = 0.0;
Creates a double value to store the latitude.
Double dLon = 0.0;
Creates a double value to stores the longitude.
dLat = Double.valueOf(latitude.getValue());
Tries to convert the latitude input field to double.
val = false;
If we cannot convert the latitude value, we set the val boolean to false.
latErrMsg.setValue("Latitude is not a valid number");
sets the latitude error message.
dLon = Double.valueOf(longitude.getValue());
Tries to convert the longitude input field.
val = false;
If the conversion fail, sets the value of val to false.
lonErrMsg.setValue("Longitude is not a valid number");
Sets the error label for longitude.
if(val)
We check that the conversion was done.
latErrMsg.setValue("");
Clears the latitude error message.
lonErrMsg.setValue("");
Clears the longitude error message.
if((dLat= 85.0)){
Checks the range of the latitude.
val = false;
If the range is invalid sets the validation to false.
latErrMsg.setValue("Latitude must be between -85.0 and 85.0");
Sets the latitude error label.
if((dLon= 180.0)){
Checks the range of the longitude.
val = false;
Sets the validation to false.
lonErrMsg.setValue("Longitude must be between -180.0 and 180.0");
Sets the error label.
if(val)
Checks the validation.
latErrMsg.setValue("");
Clears the latitude error label.
lonErrMsg.setValue("");
Clears the longitude error label.
googleMap.setCenter(new LatLon(dLat, dLon));
Moves the map to the fixed position.
googleMap.setZoom(12);
Sets the zoom level of the map.
currentLat.setValue(latitude.getValue());
Sets the current latitude label.
currentLon.setValue(longitude.getValue());
Sets the current longitude label.
Button moveButton = new Button("Move", FontAwesome.BULLSEYE);
Creates a button to move the view.
moveButton.addClickListener(moveView);
Adds the click listener to the button.
5.3.8 Button to clear the markers
We are going to create a button that clears all the markers in the map.
java
Button.ClickListener clearMarkerListener = new ClickListener() { @Override public void buttonClick(ClickEvent event) { googleMap.clearMarkers(); } }; Button clearMarkersButton = new Button("Clear markers", FontAwesome.REMOVE); clearMarkersButton.addClickListener(clearMarkerListener);
Button.ClickListener clearMarkerListener = new ClickListener()
Creates a listener to the clear markers button.
googleMap.clearMarkers();
Clears all the markers in the map.
Button clearMarkersButton = new Button("Clear markers", FontAwesome.REMOVE);
Creates a button to clear the markers.
clearMarkersButton.addClickListener(clearMarkerListener);
Add the listener to the button.
5.3.9 Add a default marker
We are going to add a marker to New York as example.
Default marker
Double newyorkLat = 40.7128; Double newyorkLon = -74.0059; googleMap.setCenter(new LatLon(40.7128, -74.0059)); GoogleMapMarker newyorkMarker = new GoogleMapMarker("New York", new LatLon(newyorkLat, newyorkLon),true, null); googleMap.addMarker(newyorkMarker); latitude.setValue(newyorkLat.toString()); longitude.setValue(newyorkLon.toString()); currentLat.setValue(latitude.getValue()); currentLon.setValue(longitude.getValue());
Double newyorkLat = 40.7128;
Defines a double with the New York Latitude.
Double newyorkLon = -74.0059;
Defines a double with the New York Longitude.
googleMap.setCenter(new LatLon(40.7128, -74.0059));
Center the map in New Your.
GoogleMapMarker newyorkMarker = new GoogleMapMarker("New York", new LatLon(newyorkLat, newyorkLon),true, null);
Creates a marker in New York.
googleMap.addMarker(newyorkMarker);
Adds the marker to the map.
latitude.setValue(newyorkLat.toString());
Sets the latitude text field value to the New York latitude.
longitude.setValue(newyorkLon.toString());
Sets the longitude text field value to the New York longitude.
currentLat.setValue(latitude.getValue());
Sets the latitude current value to the New York latitude.
currentLon.setValue(longitude.getValue());
Sets the longitude current value to the New York longitude.
5.3.10 Add the window contents
Fill the window
VerticalLayout toolLayout = new VerticalLayout(); toolLayout.setMargin(true); toolLayout.setSpacing(true); mapToolBox.setContent(toolLayout); toolLayout.addComponent(clearMarkersButton); toolLayout.addComponent(latlonLayout); toolLayout.addComponent(moveButton); toolLayout.addComponent(infoLayout); toolLayout.addComponent(markerName); toolLayout.addComponent(addMarker); toolLayout.addComponent(latErrMsg); toolLayout.addComponent(lonErrMsg);
VerticalLayout toolLayout = new VerticalLayout();
Creates a vertical layout to the window.
toolLayout.setMargin(true);
Sets the margin of the window layout.
toolLayout.setSpacing(true);
Sets the spacing to the window layout.
mapToolBox.setContent(toolLayout);
Sets the layout to the map panel.
toolLayout.addComponent(clearMarkersButton);
Adds the clear markers button.
toolLayout.addComponent(latlonLayout);
Adds the text field layout to the window layout.
toolLayout.addComponent(moveButton);
Adds the move button to the layout.
toolLayout.addComponent(infoLayout);
Adds the info layout to the window layout.
toolLayout.addComponent(markerName);
Adds the marker input box to the window layout.
toolLayout.addComponent(addMarker);
Adds the add marker button to the layout.
toolLayout.addComponent(latErrMsg);
Adds the latitude error label to the layout.
toolLayout.addComponent(lonErrMsg);
Adds the longitude error label to the layout.
6. The complete source code
6.1 Main class
VaadinmapsUI.java
package com.example.vaadinmaps; import javax.servlet.annotation.WebServlet; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.data.util.PropertysetItem; import com.vaadin.data.validator.DoubleRangeValidator; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.util.ObjectProperty; import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.tapio.googlemaps.GoogleMap; import com.vaadin.tapio.googlemaps.client.LatLon; import com.vaadin.tapio.googlemaps.client.overlays.GoogleMapInfoWindow; import com.vaadin.tapio.googlemaps.client.overlays.GoogleMapMarker; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; @SuppressWarnings("serial") @Theme("vaadinmaps") public class VaadinmapsUI extends UI { private GoogleMap googleMap; private final String apiKey = "api-key"; @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadinmapsUI.class, widgetset = "com.example.vaadinmaps.widgetset.VaadinmapsWidgetset") public static class Servlet extends VaadinServlet { } @Override protected void init(VaadinRequest request) { VerticalLayout rootLayout = new VerticalLayout(); rootLayout.setSizeFull(); setContent(rootLayout); googleMap = new GoogleMap(apiKey, null, null); googleMap.setZoom(10); googleMap.setSizeFull(); googleMap.setMinZoom(4); googleMap.setMaxZoom(16); Panel mapsPanel = new Panel(); mapsPanel.setSizeFull(); mapsPanel.setContent(googleMap); rootLayout.addComponent(mapsPanel); Window mapToolBox = new Window("Map Tool Box"); mapToolBox.setClosable(false); mapToolBox.setResizable(false); mapToolBox.setPosition(10, 100); mapToolBox.setWidth("350px"); mapToolBox.setHeight("520px"); mapToolBox.addStyleName("mywindowstyle"); UI.getCurrent().addWindow(mapToolBox); HorizontalLayout latlonLayout = new HorizontalLayout(); latlonLayout.setSpacing(true); TextField latitude = new TextField("Lat"); latitude.setWidth("100px"); latitude.setNullSettingAllowed(true); latitude.setNullRepresentation("0.0"); TextField longitude = new TextField("Long"); longitude.setWidth("100px"); longitude.setNullSettingAllowed(true); longitude.setNullRepresentation("0.0"); latlonLayout.addComponent(latitude); latlonLayout.addComponent(longitude); HorizontalLayout infoLayout = new HorizontalLayout(); infoLayout.setSpacing(true); Label currentLat = new Label(); currentLat.setCaption("Current Latitude"); Label currentLon = new Label(); currentLon.setCaption("Current Longitude"); infoLayout.addComponent(currentLat); infoLayout.addComponent(currentLon); TextField markerName = new TextField("Marker Name"); Label latErrMsg = new Label(); latErrMsg.addStyleName("mylabelstyle"); Label lonErrMsg = new Label(); lonErrMsg.addStyleName("mylabelstyle"); Button.ClickListener addMarkerListener = new ClickListener() { @Override public void buttonClick(ClickEvent event) { String mName = markerName.getValue(); if(mName.isEmpty()){ mName = "Marker"; } Double dLat = 0.0; Double dLon = 0.0; dLat = Double.valueOf(currentLat.getValue()); dLon = Double.valueOf(currentLon.getValue()); GoogleMapMarker customMarker = new GoogleMapMarker(mName, new LatLon(dLat, dLon),true, null); googleMap.addMarker(customMarker); } }; Button addMarker = new Button("Add Marker", FontAwesome.ANCHOR); addMarker.addClickListener(addMarkerListener); Button.ClickListener moveView = new ClickListener() { @Override public void buttonClick(ClickEvent event) { Boolean val = true; Double dLat = 0.0; Double dLon = 0.0; try { dLat = Double.valueOf(latitude.getValue()); } catch (Exception e) { val = false; latErrMsg.setValue("Latitude is not a valid number"); } try { dLon = Double.valueOf(longitude.getValue()); } catch (Exception e) { val = false; lonErrMsg.setValue("Longitude is not a valid number"); } if(val){ latErrMsg.setValue(""); lonErrMsg.setValue(""); if((dLat= 85.0)){ val = false; latErrMsg.setValue("Latitude must be between -85.0 and 85.0"); } if((dLon= 180.0)){ val = false; lonErrMsg.setValue("Longitude must be between -180.0 and 180.0"); } } if(val){ latErrMsg.setValue(""); lonErrMsg.setValue(""); googleMap.setCenter(new LatLon(dLat, dLon)); googleMap.setZoom(12); currentLat.setValue(latitude.getValue()); currentLon.setValue(longitude.getValue()); } } }; Button moveButton = new Button("Move", FontAwesome.BULLSEYE); moveButton.addClickListener(moveView); Button.ClickListener clearMarkerListener = new ClickListener() { @Override public void buttonClick(ClickEvent event) { googleMap.clearMarkers(); } }; Button clearMarkersButton = new Button("Clear markers", FontAwesome.REMOVE); clearMarkersButton.addClickListener(clearMarkerListener); Double newyorkLat = 40.7128; Double newyorkLon = -74.0059; googleMap.setCenter(new LatLon(40.7128, -74.0059)); GoogleMapMarker newyorkMarker = new GoogleMapMarker("New York", new LatLon(newyorkLat, newyorkLon),true, null); googleMap.addMarker(newyorkMarker); latitude.setValue(newyorkLat.toString()); longitude.setValue(newyorkLon.toString()); currentLat.setValue(latitude.getValue()); currentLon.setValue(longitude.getValue()); VerticalLayout toolLayout = new VerticalLayout(); toolLayout.setMargin(true); toolLayout.setSpacing(true); mapToolBox.setContent(toolLayout); toolLayout.addComponent(clearMarkersButton); toolLayout.addComponent(latlonLayout); toolLayout.addComponent(moveButton); toolLayout.addComponent(infoLayout); toolLayout.addComponent(markerName); toolLayout.addComponent(addMarker); toolLayout.addComponent(latErrMsg); toolLayout.addComponent(lonErrMsg); } }
6.2 Styles
vaadinmaps.scss
@import "../valo/valo.scss"; @mixin vaadinmaps { @include valo; .v-window-mywindowstyle .v-window-contents { background: #f8f8cd; } .v-window-mywindowstyle .v-window-outerheader { background: #0c2640; } .v-window-mywindowstyle .v-window-header { font-weight: bold; color: white; } .v-label-mylabelstyle { color: white; text-align: center; background-color: red; border-color: white; font-weight: bold; } }
7. Running the example
Right click on the project folder and choose Run as -> Run on server choose Tomcat 8 server and press finish.
8. Results
8.1 Start application
When you first start the application you get the following screen.
8.2 Input error
If your input is invalid you get the errors in the image.
8.3 Range error
If your range is invalid you get the following errors.
8.4 Move view
If you input the right coordinates, you can move the view. Input the coordinates of Oslo and click on the button move. Your view moves to Oslo.
8.5 Add Marker
You can add a marker to your current center position. Write a name and click on add marker. A marker in Oslo was added.
9. Download the Source Code
This was an example of: Vaadin Maps.