Tag: 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.

Review requests of OpenStreetMap contributors
– How you can assist! –

The latest version of the OpenStreetMap editor iD has a new feature: “Allow user to request feedback when saving“. This idea has been mentioned in a diary post by Joost Schouppe about “Building local mapping communities” (at that time: “#pleasereview”) in 2016. The blog post also contains some other additional and good thoughts, definitely worth reading.

However, based on the newly implemented feature, any contributor can flag her/his changeset and ask for feedback. Now it’s your turn! How can you find and support those OSM’ers?

  • Step 1: Based on the “Find Suspicious OpenStreetMap Changesets” page you can search for flagged changesets, e.g. limited to your country only: Germany or UK.
  • Step 2: Leave a changeset comment where you e.g. welcome the contributor and (if necessary) give her/him some feedback about the map changes. You could also add some additional information, such as links to wiki pages of tags (map features), good mapping practices, the OSM forum, OSM help or mailing lists. Based on the changeset comment other contributors can see that the original contributor of this changeset already has been provided with some feedback.
  • Step 3: Finally you could create & save a feed URL of your changeset’s search. That’s it.

Personally, I really like this new feature. It provides an easy way to search for contributors who are asking for feedback about their map edits. Thanks to all iD developer’s for implementing this idea. What do you think? Should I add an extra score to “How did you contribute to OpenStreetMap” where every answer to a requested feedback changeset will be counted?

Some statistics? There you go: “OSM Changesets of the last 30 Days

Thanks to 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 … !