Index: src/uk/me/parabola/mkgmap/reader/osm/UnusedElementsRemoverHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/UnusedElementsRemoverHook.java	(revision 0)
+++ src/uk/me/parabola/mkgmap/reader/osm/UnusedElementsRemoverHook.java	(revision 0)
@@ -0,0 +1,101 @@
+package uk.me.parabola.mkgmap.reader.osm;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import uk.me.parabola.imgfmt.app.Area;
+import uk.me.parabola.imgfmt.app.Coord;
+import uk.me.parabola.log.Logger;
+import uk.me.parabola.util.EnhancedProperties;
+
+public class UnusedElementsRemoverHook extends OsmReadingHooksAdaptor {
+	private static final Logger log = Logger.getLogger(UnusedElementsRemoverHook.class);
+
+	private ElementSaver saver;
+
+	public UnusedElementsRemoverHook() {
+	}
+
+	public boolean init(ElementSaver saver, EnhancedProperties props) {
+		this.saver = saver;
+		return true;
+	}
+	
+	public void end() {
+		long t1 = System.currentTimeMillis();
+		log.error("Removing unused elements");
+		
+		final Area bbox = saver.getBoundingBox();
+		
+		long nodes = saver.getNodes().size();
+		for (Node node : new ArrayList<Node>(saver.getNodes().values())) {
+			if (node.getTagCount() == 0) {
+				saver.getNodes().remove(node.getId());
+				continue;
+			}
+			if (bbox.contains(node.getLocation()) == false) {
+				saver.getNodes().remove(node.getId());
+			}
+		}
+		
+		long tr1 = System.currentTimeMillis();
+		// store all way ids that are referenced by a relation
+		Set<Long> relationWays = new HashSet<Long>();
+		for (Relation rel : saver.getRelations().values()) {
+			for (Entry<String, Element> relEntry : rel.getElements()) {
+				if (relEntry.getValue() instanceof Way) {
+					relationWays.add(relEntry.getValue().getId());
+				}
+			}
+		}
+		log.error("Collecting way ids from relations took "+(System.currentTimeMillis()-tr1)+" ms");
+		
+		Rectangle bboxRect = new Rectangle(bbox.getMinLong(), bbox.getMinLat(), bbox.getWidth(), bbox.getHeight());
+		long relWays = 0;
+		long ways = saver.getWays().size();
+		for (Way way : new ArrayList<Way>(saver.getWays().values())) {
+			// check if a way has no tags and is not a member of a relation
+			// a relation might be used to add tags to the way using the style file
+			if (way.getTagCount() == 0) {
+				if (relationWays.contains(way.getId())) {
+					relWays++;
+				} else {
+					saver.getWays().remove(way.getId());
+					continue;
+				}
+			}
+			
+			// check if the way is completely outside the tile bounding box
+			boolean coordInBbox = false;
+			Coord prevC = null;
+			for (Coord c : way.getPoints()) {
+				if (bbox.contains(c)) {
+					coordInBbox = true;
+					break;
+				} else if (prevC != null) {
+					if (bboxRect.intersectsLine(prevC.getLongitude(), prevC.getLatitude(), c.getLongitude(), c.getLatitude())) {
+						log.error("Intersection!");
+						log.error(bbox.getMinLong()+" "+bbox.getMinLat()+" "+bbox.getMaxLat()+" "+bbox.getMaxLong());
+						log.error(prevC.getLongitude()+" "+prevC.getLatitude()+" "+c.getLongitude()+" "+c.getLatitude());
+						coordInBbox = true;
+						break;
+					}
+				}
+				prevC = c;
+			}
+			if (coordInBbox==false) {
+				saver.getWays().remove(way.getId());
+			}
+		}
+		
+		log.error("Relation referenced ways: "+relationWays.size()+ " Used: "+relWays);
+
+		log.error("Removing unused elements took "+(System.currentTimeMillis()-t1)+" ms");
+		log.error("Nodes: before "+nodes+" now "+saver.getNodes().size());	
+		log.error("Ways: before "+ways+" now "+saver.getWays().size());	
+		}
+
+}
Index: src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(revision 2159)
+++ src/uk/me/parabola/mkgmap/reader/osm/OsmMapDataSource.java	(working copy)
@@ -53,6 +53,7 @@
 	private final OsmReadingHooks[] POSSIBLE_HOOKS = {
 			new SeaGenerator(),
 			new MultiPolygonFinishHook(),
+			new UnusedElementsRemoverHook(),
 			new RoutingHook(),
 			new HighwayHooks(),
 			new LocationHook(),
