Category: HowTo

Processing compressed OpenStreetMap Data with Java

This blog post contains a summary on how you can write your own Java classes to process OpenStreetMap (OSM) pbf files. PBF is a compression format, which is nowadays more or less the standard utilized for reading and writing OSM data quickly. In the OSM world, many tools and programs implemented this file format (you can find additional information here). However, I think the following samples for reading and writing such compressed OSM data can be very helpful. In particular, if someone has to create some sort of test data or has to read some specific mapped objects of interest for her/his own project. The well-known Java Osmosis tool (command line application for processing OSM data), provides several libraries that are the basis for this brief tutorial.

Step 1: Maven is the key – If your Java project is already managed by Maven, you can just add the following lines to your pom.xml. It downloads and adds the required jar-files that are needed to process compressed OSM data to your project.

<dependency>
	<groupId>org.openstreetmap.osmosis</groupId>
	<artifactId>osmosis-pbf</artifactId>
	<version>0.46</version>
</dependency>

If you don’t use Maven, you can download the aforementioned dependencies here and add the jars as described here to your eclipse build path.

Step 2: Implementing the Sink interface for reading OSM data – Now, after you added the required libraries to your project, you can create your own class to read compressed OSM data. The following MyOSMReader class is an easy example for that scenario: It reads an OSM pbf files and prints all Ids of ‘ways’ with a ‘highway’ key.

package org.neis_one.osm.examples;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Map;

import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer;
import org.openstreetmap.osmosis.core.container.v0_6.RelationContainer;
import org.openstreetmap.osmosis.core.container.v0_6.WayContainer;
import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
import org.openstreetmap.osmosis.core.domain.v0_6.Way;
import org.openstreetmap.osmosis.core.task.v0_6.Sink;

import crosby.binary.osmosis.OsmosisReader;

/**
 * Receives data from the Osmosis pipeline and prints ways which have the
 * 'highway key.
 * 
 * @author pa5cal
 */
public class MyOsmReader implements Sink {

	@Override
	public void initialize(Map<String, Object> arg0) {
	}

	@Override
	public void process(EntityContainer entityContainer) {
		if (entityContainer instanceof NodeContainer) {
			// Nothing to do here
		} else if (entityContainer instanceof WayContainer) {
			Way myWay = ((WayContainer) entityContainer).getEntity();
			for (Tag myTag : myWay.getTags()) {
				if ("highway".equalsIgnoreCase(myTag.getKey())) {
					System.out.println(" Woha, it's a highway: " + myWay.getId());
					break;
				}
			}
		} else if (entityContainer instanceof RelationContainer) {
			// Nothing to do here
		} else {
			System.out.println("Unknown Entity!");
		}
	}

	@Override
	public void complete() {
	}

	@Override
	public void close() {
	}

	public static void main(String[] args) throws FileNotFoundException {
		InputStream inputStream = new FileInputStream("/Path/To/Your/read.osm.pbf");
		OsmosisReader reader = new OsmosisReader(inputStream);
		reader.setSink(new MyOsmReader());
		reader.run();
	}
}

Step 3: Implementing the Source Interface for writing OSM data – Similarly to Step 1 to read an OSM file, you will have to implement again an interface to write data as well. This time the Osmosis core task Source interface is being utilized. The following example class writes 10 Nodes to a new OSM pbf file.

package org.neis_one.osm.examples;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Date;

import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer;
import org.openstreetmap.osmosis.core.domain.v0_6.CommonEntityData;
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
import org.openstreetmap.osmosis.core.domain.v0_6.OsmUser;
import org.openstreetmap.osmosis.core.task.v0_6.Sink;
import org.openstreetmap.osmosis.core.task.v0_6.Source;
import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream;

import crosby.binary.osmosis.OsmosisSerializer;

/**
 * Writes OSM data to the output task.
 * 
 * @author pa5cal
 */
public class MyOsmWriter implements Source {

	private Sink sink;

	@Override
	public void setSink(Sink sink) {
		this.sink = sink;
	}

	public void write() {
		for (int idx = 1; idx <= 10; idx++) {
			sink.process(new NodeContainer(new Node(createEntity(idx), 0, 0)));
		}
	}

	public void complete() {
		sink.complete();
	}

	private CommonEntityData createEntity(int idx) {
		return new CommonEntityData(idx, 1, new Date(), new OsmUser(idx, "User"), idx);
	}

	public static void main(String[] args) throws FileNotFoundException {
		OutputStream outputStream = new FileOutputStream("/Path/To/Your/write.osm.pbf");
		MyOsmWriter writer = new MyOsmWriter();
		writer.setSink(new OsmosisSerializer(new BlockOutputStream(outputStream)));
		writer.write();
		writer.complete();
	}
}

Step 4: That’s it – You should now be able to write your own classes that allow you to process compressed OSM data.

One last thing: When writing your own Java classes to process OSM data, you should always keep in mind, that the PBF file has it’s own object ordering format of the OSM objects: Each file first contains Nodes, then Ways and at the end Relations. That means, a Way element only contains references to Node ids. It doesn’t contain the coordinates or any tags of the actual nodes that are used for the Way. Thus, if you want a complete Way element with its geometry, you have two options: Store all Nodes in some kind of map or read the entire OSM file twice. Furthermore, if you’re interested in additional compressing options during writing a compressed OSM file, you should have a look at this class.

Thanks to maɪˈæmɪ Dennis.

I Like OpenStreetMap (OpenLayers Plugin)

A few months ago, Frederik Ramm posted an idea on the German OpenStreetMap mailing list about a new (stochastic) approach to OSM data quality assurance. You can find his original German post here. His idea was to create a way to allow users to “like” or “dislike” a specific region on the OSM map, a function that other popular websites such as YouTube or Facebook implemented to allow users to provide feedback to videos or status updates. For OSM this particular function could give some indicators or trends about the OSM map data.

I really liked his idea and in collaboration with Frederik I created an Open Source OpenLayers plugin. For all new readers: OpenLayers is an Open Source library which can implement a dynamic (OSM) map into more or less any webpage. One of our goals was to make the integration of the ILikeOSM plugin as easy as adding a tile server to your OpenLayers map.

The following image shows the plugin in more detail, including the “like” and “dislike” buttons to provide feedback about the area on the map.

An additional feature of the plugin shows how many users have been viewing the same area of the map that the current user is taking a look at. More precisely: How many other users have been viewing a similar area of the map within the past two minutes with a zoom level of +-3 to yours. All components of the plugin are Open Source and available on github. The database which saves the likes and dislikes is running on a German OSM Dev server. A database dump file can be downloaded on a daily basis. It is important to note at this point that no private data is saved in the database when a user leaves his or her feedback. The plugin only saves an independent, randomly generated user ID, the feedback type i.e. thumbs up/down, the zoom level, the layer name and the bounding box of the map section. A map view is generally not saved to the database until the user accepts to do so via a pop up window.

Do you like this feature?
It is quite easy to integrate it into your own webpage. Here is how it works:
1. Add the following line below your OpenLayers script-tag:
<script src=”http://ilike.openstreetmap.de/ILikeOSM.min.js” type=”text/javascript”></script>
2. Then add the following lines to your OpenLayers Controls:
new OpenLayers.ILikeOSM()
3. Styling
<style type="text/css">
div.olILikeOSM { position: absolute; top: 15px; left: 50px; padding: 7px; color:white; border-radius: 10px; background: rgba(0, 0, 0, 0.6); }
div.olILikeOSM a { color: white; font-size:12px; text-decoration: underline; }
</style>
4. That’s it!

What is the benefit of this plugin or of the saved ILikeOSM data?
Based on the saved likes, dislikes and map views we can generate some statistics to provide you with information about the number of people who like or dislike your particular area of interest. Maybe we can even see some prove of Linu’s law “given enough eyeballs, all bugs are shallow”; meaning in this case, that a larger number of users that check a certain region of the map, results in “better” OSM data quality. As a first prototype, I generated a static webpage which shows an example result map.

Further ideas?
The plugin could potentially be expanded with an additional textbox in which a user could leave a comment why the area is not well represented in OSM. This information could then be saved e.g. in OpenStreetBugs. Anyway, we think that the current version of the plugin could provide some very useful information. You will find a webpage with all information, examples and downloads here: http://ilike.openstreetmap.de As a first step we integrated the plugin into the OpenStreetMap Germany webpage.

Frederik will give a short talk about the ILikeOSM plugin at the upcoming State of the Map 2012 in Tokyo. If our proposed session abstract about another topic for the State of the Map 2012 US gets accepted, Dennis will try to present it there too.

Thank you very much for your feedback: Frederik, Jonas, Dennis, Sven & Marc

“My Way” to cross Dublin without a Pub

First of all, I really like the following blog post and the idea behind it: “Yes! It is possible to cross Dublin without passing a pub

It shows the power of crowd sourced geodata (OpenStreetMap) and the skills of some individuals. In the following steps I am going to show you a different way to get to the same result.

The website OpenRouteService.org offers the same functionality to calculate a route. You can avoid certain areas by defining them (just simply draw them) on the map. However, your first step would be to “Search for Points of Interest (POI)” (PUBS), for example in Dublin within a distance of 10 km. The following picture shows the result:

After that you can create several polygons around your pubs resulting in a map with several, “red” areas:

And finally you can calculate a route from almost any point in Dublin. The last image show such a route without crossing a red area or Pub:

However, the original blog post is brilliant !
Or do you want it the opposite way: Search all pubs *along* my route? 😉

thx @ maɪˈæmɪ Dennis 🙂

Web-GUI for OS Routing Machine

During my Easter holidays I created a web-fronted for Dennis Luxen’s Open Source Routing Machine (OSRM Project). The OSRM project (http://project-osrm.org/) is in my opinion probably the fastest Open Source software which is using data from the OpenStreetMap project. “In contrast to most routing servers OSRM does not use an A* variant to compute shortest path, but Contraction Hierarchies.” You can read a little bit more about Contraction Hierarchies in Wikipedia.

The website that I created contains in its first version an address-search (geocoding) and of course routeplanning. For the geocoding I integrated the Nominatim search from OpenStreetMap. You can find a How-To on the MapQuest-site. Unfortunately the OSRM routing service covers only most parts of Europe for now. The current version of my web-fronted can be found here: http://map.project-osrm.org

Anyway, perhaps some of you would say: “A website with OSM routing? This is nothing new and we actually did have something like that before …” I agree, BUT I think none of them is as fast and can handle as many requests, try it out! Through its really good route calculation performance the route can also be changed or adjusted by dragging the start- and destination point (I think you know this from other websites). The following video shows the great functionality:

WebGUI for Project-OSRM from Pascal Neis

Further does the new website automatically generalize the desired route on the server side for smaller map scales. This reduces the traffic between server and client and less data needs to be visualized by the client which saves system resources. Additionally I created the following feature: If a calculated route contains a segment that has no name, it is going to be displayed in a different color. I think this is a great feature to map missed road names! The next picture shows such a route. You can find the complete sources of the website in the OSRM Sourceforge project folder.

There is a lot of discussion on OpenStreetMap.org about a Routing-Integration. In my opinion there should be two routing options available on the OSM start page. One option that provides a very fast routing such as OSRM and another option that is easy to adjust and configure and is able to work with different OSM tags. A combination of both will probably not be available soon. Bigger companies such as “G****E” offer high performance routing applications to their users. Thus it should also be a desirable goal for the new OSM software to get to the same performance level that the users are familiar with from other websites. I don’t think that an integration of ”Non-Open-Source Routing Software” such as provided by CloudMade or Mapquest is a good idea. It still should be an Open Source App after all. But this limits the selection to OSRM, YOURS, Routino and Roadeeno. For now OpenRouteService is not completely Open Source.

So *if* we add routing to the OSM main website I would vote for a fast-route-planning software e.g. by the OSRM project. Hence we must only search for a preferably configurable solution, what would be your suggestion?

thx @ Dennis L.: Continue with your great work!
thx @ Frederik (Geofabrik) for supporting the OSRM Project with a VM for hosting
thx @ *Fab* for the video
and finally: thx @ maɪˈæmɪ Dennis 🙂

*.osm or *.pbf ?

Since September 5 th Osmosis supports the new OSM binary fileformat. It sounds interesting, but where are the pros of this format?

I played a little bit with the OSM file of entire Europe. The europe (*.osm) file has an uncompressed format size of about 72.9 GB (compressed it is about 5.2 GB). The new OSM binary (*.pbf) file on the other hand has a size of 3.7 GB (compress=deflate) or 7.6 GB (compress=none).

With the help of Osmosis, it’s quite simple to update an OSM file daily via the “diff” files. You can find a good “how to” in the OSM wiki (here).

For the past 5 days, I collected the processing times that Osmosis (version 0.37) takes to update the europe *.osm file. The osmosis job contains the download of the change (*.osc) file and the cutting (bounding-polygon parameter) of Europe. Altogether the job runs at average in 56min. With the OSM *.pbf file the same task is completed in 14min. I think this is a big difference. So if you need an OSM file on your system, give the new binary OSM files a try! Really nice work Scott 🙂

Some system information: (i7-920) Quadcore with 4x 2667MHz, 1500GB HDD and 12GB RAM. thx @ dennis

Using OpenHeatMap

Nearly three months ago I saw a tweet by mapperz (here). The tweet introduced http://www.openheatmap.com (OHM) : “Turn your spreadsheet into a map” . A very interesting tool. Unfortunately I completely forgot about it in the past weeks until last night. I was looking for an easy method to present some data on a map.

Using OHM is really simple. Upload your CSV file, which suits a certain format, and your data is more or less presented on an OpenStreetMap basemap 🙂

In my case, I used the TMC data of Germany for one week (since 2010-09-12) to present it on a map. For each intersection I counted the number of traffic messages for that specific week. The red areas in the map represent those intersections with a high concentration of messages. My result-OHM-map can be found here: http://www.openheatmap.com/view.html?map=OverestimatedOdessasShevat

The visualization of the CSV file looks pretty cool, doesn’t it? Especially the Berlin area shows a very nice representation of TMC messages.

Generally speaking, Pete’s Projekt http://www.openheatmap.com is working very well. A few adjustments still need to be made though. It would be nice to include a zoom function that works with the mouse wheel. Probably this was one of the first problems you encountered too?! But still: Keep up the good work!

thx @ georg for supporting the TMC Database dump
and again thx @ dennis !

#OSM für die Feuerwehr 2.0

Im letzten Artikel mit ähnlicher Überschrift hatte ich ein kleines HowTo gezeigt wie man mit Hilfe von OpenStreetMap (OSM) eine Online-Karte mit den jeweiligen Erreichbarkeitspolygonen von Feuerwehrhäusern oder auch für andere Einsatzzentralen erstellen kann (siehe hier!). Das Polygon wurde dabei über eine Zeitangabe berechnet.

Neben dieser Variante könnte man das Polygon aber auch über eine Maximal zu erreichende Distanz bestimmen. Stephan (SB79) hat in seinem Kommentar zum letzten Post danach gefragt. Da der Web Service diese Funktionalität unterstützt habe ich sie auch in das Tool vom letzten Mal eingebaut.

Möchtet ihr das Erreichbarkeitspolygon für eine vorgegebene Zeit um eine Position (lon lat) haben, ändert sich an der Anfrage nichts: http://openls.geog.uni-heidelberg.de/connector/get/analysepolygon/4/7.967585 51.177403

Polygon nach Zeit

Polygon nach Distanz (*NEW*)

Wollt ihr aber zusätzlich für diese Position (lon lat) auch ein Polygon haben was die “Maximale” Distanz in die verschiedenen Richtungen zeigt, könnt ihr nun folgendes nutzen: http://openls.geog.uni-heidelberg.de/connector/get/analysepolygon/4000m/7.967585 51.177403

Die Anfragearten unterscheiden sich leicht. Wenn ihr nur eine Zahl zwischen 2 und 15 angebt, wird das Polygon für die Zeit ermittelt. Enthält die URL stattdessen neben der Zahl auch ein “m” wird das Polygon für die übergebene Distanz in Meter berechnet.

Ich hoffe das hilft … 🙂

Etwas #OSM für die Feuerwehr

Welches Gebiet kann von einer Einsatzzentrale der Polizei, der Feuerwehr oder von Ersthelfern in einer vorgegebenen Zeit abgedeckt werden? Andreas versucht gerade dies für die Feuerwehr seiner Gemeinde zu visualisieren. Das erste Ergebnis: Die Standorte der Löschgruppen und die Gebiete die erreicht werden können als Kreise auf einer OpenStreetMap Karte. Das folgende Bild zeigt das Resultat (Rote Marker = Feuerwehrhäuser, Gelbe Kreise = Erreichbarkeitsgebiet und Schwarze Linie = Grenze der Gemeinde):

Bei weiteren Recherchen ist er auf die OSM Erreichbarkeitsanalyse gestoßen (Accessibility Analysis Service). Dieser Dienst ermittelt ein Polygon, dass ein Gebiet repräsentiert was in einer vorgegebenen Zeit erreicht werden kann. Vor drei Tagen hat mich Andreas angeschrieben und gefragt ob ich ihn bei der Verwendung des Dienstes und der Realisierung etwas unterstützen könnte. Im folgenden Bild ist das Ergebnis mit den Polygonen (orange) der Erreichbarkeitsanalyse zu sehen:

Insgesamt finde ich ist dies wieder ein gutes Beispiel was mit OSM und den vorhandenen Diensten wie Mapnik und entsprechenden Programmen wie Openlayers möglich ist. Man muss sich lediglich etwas reinfuchsen und dann kann man so schöne Sachen machen wie Andreas … 🙂

Hier noch ein kleines HowTo

  1. Informationen wie ihr die OSM Map in euer Webseite integriert findet ihr hier: http://wiki.openstreetmap.org/wiki/OpenLayers – Bei Examples sind jede Menge Beispiele gelistet.
  2. Um ein Erreichbarkeitspolygon berechnen zu lassen und als KML File speichern zu können habe ich folgende Seite gebaut: http://openls.geog.uni-heidelberg.de/connector/get/analysepolygon/8/7.967585 51.177403 Sie kann nach dem REST-Prinzip verwendet werden. Ihr müsst lediglich die Minuten (hier 8 Minuten) und die Koordinate des Standpunkte (lon=7.967585 lat=51.177403) in die URL eintragen. Wichtig: Erst Longitude (Längengrad) und dann Latitude (Breitengrad) des Standpunktes! Danach erhält man ein KML File das gespeichert werden muss! ACHTUNG: verwendet dieses Tool bitte NUR zur Erstellung der KML Files, verwendet diese URL bitte NICHT direkt in eurer Webseite. Weiterhin habe ich ein Limit eingebaut, das lediglich ein Polygon für die Erreichbarkeit von 2 bis 15 Minuten erstellt werden kann.
  3. Das KML könnt ihr über folgende zwei Zeilen auf eurer Map anzeigen lassen:
    var myKML = new OpenLayers.Layer.GML(“myKML “, ” myKML.xml”, { format: OpenLayers.Format.KML, formatOptions: { extractStyles: false, extractAttributes: false }, projection: map.displayProjection });
    map.addLayer(myKML);
  4. Viel Spass … !