GWT: TrafficMap – GWT & Leaflet Map Example

Here is a nice GWT and Leaflet map application I wrote to ease myself back into GWT again after not having written a line of GWT code since 2009. It is a classic map and list type site which displays some sample data I downloaded from the UK Highways Agency traffic RSS feed.

Trafficmap

Not content to knock something together just to get it working I have as usual done it the hard way by embarking on learning about GWT UIBinder and the MVP design pattern which Google are promoting in the latest version of GWT. My intention is to eventually write something bigger after getting up to speed on GWT again. The result is a simple MVP application which utilises composite binder xml views and the GWT Leaflet map component. All mavenized for an easy(ish) build and deploy process.

You can download the project from here.

Highlights

Data

The data comes from the Highways Agency RSS feed here. This was downloaded and processed by my RSS parser which you can find here.

I used the Google JSON library to convert one of the feeds to a JSON file which was my sample data.

Map

The map is the GWT Leaflet component. The component attaches itself to an g:HTMLPanel defined in the MapView.xml UIBinder template.

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
	xmlns:g="urn:import:com.google.gwt.user.client.ui">
	<ui:style>
	.mapViewPanel {
		padding-left: 10px;
		padding-right: 10px;
	}
	</ui:style>
	<g:HTMLPanel ui:field="mainPanel" addStyleNames="{style.mapViewPanel}" >
	</g:HTMLPanel>
</ui:UiBinder> 

You cannot instantiate the map control directly in the constructor of the binder. You won’t see anything. It has to be created and attached in the onLoad method of the composite view i.e.

@Override
protected void onLoad()
{
	super.onLoad();

	// ---------------------------------------------------------------
	// Map Widget
	// ---------------------------------------------------------------

	MapWidget mapWidget = new MapWidget(MAP_DIV);
	mainPanel.add(mapWidget);
	mapWidget.setHeight("100%");
	mapWidget.setWidth("100%");

	// ---------------------------------------------------------------
	// Map Configuration
	// ---------------------------------------------------------------

	// Create Map instance
	MapOptions loptions = new MapOptions();
	loptions.setCenter(new LatLng(55.864237000000000000, -4.251805999999988000));
	loptions.setZoom(13);

	Options tileOptions = new Options();
	tileOptions.setProperty("attribution", MAP_ATTRIBUTION);
	TileLayer tileLayer = new TileLayer(MAP_URL, tileOptions);

	myMap = new Map(MAP_DIV, loptions);

	myMap.addLayer(tileLayer);

	myMap.invalidateSize(true);
}

A few things to point out.

  • I couldn’t get the the ‘fitBounds’ method to work which I believe should set the view bounds and zoom to the data set.
  • You must call ‘invalidateSize’ to force the map to redraw otherwise the map is kind of half-drawn.
  • The whole view is actually a composite of the left, middle and right panels. I.e.

    <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
    <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    	xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:my="urn:import:com.netthreads.gwt.client.view">
    	<ui:style>
    	</ui:style>
    	<g:HTMLPanel ui:field="testLabel">
    		<my:TopView ui:field="topView" width="100%" height="100%"/>
    		<g:DockLayoutPanel width="100%" height="650px">
    			<g:west size="300.0">
    				<my:ListViewImpl ui:field="listView" width="100%" height="100%"/>
    			</g:west>
    			<g:center size="80.0">
    				<my:MapViewImpl ui:field="mapView" width="100%" height="100%" />
    			</g:center>
    			<g:east size="220.0">
    				<my:PropertiesViewImpl ui:field="propertiesView" width="100%" height="100%" />
    			</g:east>
    		</g:DockLayoutPanel>
    
    	</g:HTMLPanel>
    </ui:UiBinder>
    

    I had bit of trouble trying to get the data table to do a single selection when a row was clicked. After a fair bit of Googling and hunting around stackoverflow I found that you cannot define this in the binder template CSS. The only was to get this to work was to define a CSS resource and pass it into the constructor of the DataGrid.

    The css.

    .dataGridSelectedRowCell {
      border: selectionBorderWidth solid #ffffff; /*#628cd5;*/
    }
    
    /**
     * The keyboard selected cell is visible over selection.
     */
    .dataGridKeyboardSelectedCell {
      border: selectionBorderWidth solid #ffffff; /* #d7dde8;*/
    }
    

    The resource.

    package com.netthreads.gwt.client.view;
    
    import com.google.gwt.user.cellview.client.DataGrid;
    
    /**
     * Override the datagrid style resources.
     * 
     * http://stackoverflow.com/questions/7394151/datagrid-celltable-styling-frustration-overriding-row-styles
     *
     */
    public interface DataGridResource extends DataGrid.Resources
    {
    	@Source(
    	{
    	        DataGrid.Style.DEFAULT_CSS, "DataGridOverride.css"
    	})
    	DataGrid.Style dataGridStyle();
    };
    

    And the usage:

    	private DataGridResource resource = GWT.create(DataGridResource.class);
    	
    	@UiField(provided = true)
    	protected DataGrid<TrafficData> dataGrid = new DataGrid<TrafficData>(50, resource);
    

    I am going to write more GWT stuff again as I am heartily sick of javascript, css and html.

    Apache License 2.0

    JAVA: MAVENIZE – Update

    Whilst this component hasn’t exactly set the internets on fire can I give another shout out for my ‘mavenize‘ tool. This is a command line tool for ‘mavenizing’ java projects. I have found myself using this a fair bit when I am looking to bring older components into a existing maven java project and it can save a fair bit of faffing around.

    Using it is as simple as:

    java -jar mavenize-1.0.2.jar -iC:\Development\java\project\original -oC:\Development\java\project\mavenized

    I have made some minor recent fixes. If you are interested in looking for a good example of the use of the org.apache.commons.io.DirectoryWalker class then you should take a look at the source code.

    gTraffic: Down perhaps not out.

    Some of you may have come to this site from my UK road traffic site gTraffic.info. You will have noticed that there is no longer any traffic incidents available. This is because the TPEG feed which was the source of incident data has been cut by the BBC. I am fairly philosophical about this. It wasn’t like the feed was going to be there forever. I got about four years out of it which isn’t bad.

    I have just shifted the URL to a different provider so I am not quite ready to kill off the site just yet. Technically I could probably put a script together which generates data from the HA rss feed. I have other stuff to get on with so that may or may not happen.

     

     

    Flex: WMS with Google Map Flash Control

    Javier De La Torre has some really impressive examples of using a GeoServer WMS feed to generate overlays for Flash Google Maps. The custom WMS provider used in the WMS demos from this site is based originally on code very generously posted by Javier onto the UMap forum.

    WMS overlay for Google Map for Flash here.

    Heat maps over Google Map for Flash here.

    I have had a play around with the Flash Google Map API although I haven’t looked at it recently. It is certainly something I would use though. The UMap component is free to download but requires a license to use so the addition of WMS support for the Google map solution is a fantastic addition.

    Flex: Update – UMap WMS Provider UMap Traffic demo

    I have now updated the original WMS provider Traffic demo for AFComponents UMap Flex map control.

    IFrame Map App

    This uses the latest version as of today 2nd August 2008, version 1.1.

    Right click to view/download the source code.

    Flex: Update – UMap WMS Custom Provider demo

    I have updated the original WMS provider demo for AFComponents UMap Flex map control.

    IFrame Map App

    This uses the latest version as of today 2nd August 2008, version 1.1.

    There are a few changes to the demo.

    Right click to view/download the source code.

    GWT: gTraffic Usage

    I have Google stats activated for some of my websites including gTraffic the UK traffic Google map mashup. The site ticks over with fairly low stats of about 20 people a day (I salute you fellow traffic junkies). Occasionally when there is a bank weekend or a public holiday the stats jump to some fairly respectable figures. For example, there is a monday holiday coming up in the UK this weekend, check out the stats. Both spikes are holiday weekends:

    gTraffic usage

    This is interesting in all sorts of ways if you are into road traffic websites. Basically (and I can back this up from the commercial sites I have worked on), noone gives a hoot about the traffic on the road until they have to make a journey. Then they want to know if they are likely to get held up as the pack the kids into the 4×4 and make the journey down to Dover or north to the Lake District. For those of you who use gTraffic I thank you and have good holiday.

    Flex: UMap TerraServer Demo

    Yet another UMap demo. This is just a stripped version of the some of the code from a previous WMS demo. I have modified the WMS settings to point to the TerraServer WMS feed.

    IFrame Map App

    Right-click to view/download the source code.

    I am having a bit of a rest from developing for the moment. I will get round to peoples requests for updates in a week or so.

    GWT: gTraffic Timeline

    I occasionally have a look at my GWT traffic mashup to make sure it’s still working. I was looking at it again tonight and was struck by how many good ideas it seems to have. Good ideas that no one else seems to have bothered to pick up on. As an example take a look at the view (as of tonight) for the Berkshire area.

    gTraffic

    I was clicking around to make sure that the data seemed up to date and kept clicking on long running Roadworks. If you only had that view then it would be a chore to determine what was new and what was long running except that you have the ability to flick over to the time-line. Looking at that I could see right away what the latest events were. The time-line view is not perfect but I am still amazed no one else has copied this idea cos I think this is genuinely useful.

    gTraffic timeline

    Another one is the zoom-in/zoom-out buttons on the infowindow. My implementation jumps down to the street view and then back up to the last selected zoom level. I know this has been used elsewhere in sites connected to me but I would have thought this would be more widespread as, again, it’s a useful functionality.

    gTraffic zoom

    Maybe it’s just me but I think there are some good ideas here which are not represented in current traffic web sites.

    Flex: UMap WMS Custom Provider Traffic Demo

    Here is another UMap WMS Provider demo

    This is the Glasgow traffic data from here and applied to a WMS feed from here.

    This uses the UMap component from AFComponents.

    IFrame Map App

    Right-click to view the source.

    The WMS feed is defined in the ‘DataModel.as’ class.

    public static var WMS_TILE_URL:String = “http://www2.demis.nl/wms/wms.ashx”;

    public static var WMS_TILE_LAYERS:String =
    “Topography,Builtup%20areas,Coastlines,Waterbodies,Inundated,Rivers,Streams,
    Railroads,Highways,Roads,Trails,Borders,Cities,Settlements,
    Spot%20elevations,Airports,Ocean%20features”;

    public static var WMS_LAYER_FORMAT:String = “Image/png”;

    This doesn’t use the OSGR conversions of the previous demo and instead uses the straight WGS84 projection “EPSG:4326”.

    Update #1

    Updated to new version of UMap control 1.1 02/08/08. See here.

    Next Page →