Index: .classpath
===================================================================
--- .classpath	(Revision 1114)
+++ .classpath	(Arbeitskopie)
@@ -1,11 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="src" path="resources"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="test"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/junit"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/resource"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="classes" path="src"/>
+	<classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
+	<classpathentry kind="con" path="D:/Software/mkgmap-svn/build/classes"/>
+	<classpathentry kind="lib" path="D:/Software/mkgmap-svn/jai_codec.jar"/>
+	<classpathentry kind="lib" path="D:/Software/mkgmap-svn/jai_core.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: .project
===================================================================
--- .project	(Revision 1114)
+++ .project	(Arbeitskopie)
@@ -1,16 +1,24 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-    <name>mkgmap</name>
-    <comment />
-    <projects />
-    <buildSpec>
-        <buildCommand>
-            <name>org.eclipse.jdt.core.javabuilder</name>
-            <arguments />
-        </buildCommand>
-    </buildSpec>
-    <natures>
-        <nature>org.eclipse.jdt.core.javanature</nature>
-    </natures>
-</projectDescription>
-
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mkgmap-svn</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+	<linkedResources>
+		<link>
+			<name>classes</name>
+			<type>2</type>
+			<location>D:/Software/mkgmap-svn/build/classes</location>
+		</link>
+	</linkedResources>
+</projectDescription>
Index: build.xml
===================================================================
--- build.xml	(Revision 1114)
+++ build.xml	(Arbeitskopie)
@@ -72,7 +72,7 @@
       <include name="**/*.java" />
       <classpath refid="main"/>
       <!-- <compilerarg value="-Xlint:unchecked"/> -->
-      <exclude name="**/reader/dem/optional/*.java"/>
+      <exclude name="**/reader/dem/optionalx/*.java"/>
     </javac>
   </target>
 
Index: src/uk/me/parabola/mkgmap/reader/dem/DEM.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/dem/DEM.java	(Revision 1114)
+++ src/uk/me/parabola/mkgmap/reader/dem/DEM.java	(Arbeitskopie)
@@ -670,7 +670,7 @@
 		}
 
 		public Isolines(DEM data, double minLat, double minLon, double maxLat, double maxLon) {
-			System.out.printf("init: %f %f %f %f\n", minLat, minLon, maxLat, maxLon);
+			//System.out.printf("init: %f %f %f %f\n", minLat, minLon, maxLat, maxLon);
 
 			this.data = data;
 			this.minX = (int) ((minLon - data.lon) / data.res);
@@ -682,15 +682,16 @@
 		}
 
 		private void init() {
-			System.out.printf("init: %d %d %d %d\n", minX, minY, maxX, maxY);
+			//System.out.printf("init: %d %d %d %d\n", minX, minY, maxX, maxY);
 			data.read(minX - 2, minY - 2, maxX + 2, maxY + 2);
 			// we need some overlap for bicubic interpolation
 			max = -1000;
 			min = 10000;
 			for (int i = minX; i < maxX; i++)
 				for (int j = minY; j < maxY; j++) {
-					if (data.elevation(i, j) < min) min = data.elevation(i, j);
-					if (data.elevation(i, j) > max) max = data.elevation(i, j);
+					double elevation = data.elevation(i, j);
+					if (elevation < min && elevation > -10000) min = elevation;
+					if (elevation > max && elevation <  10000) max = elevation;
 				}
 
 			debug("min: %f, max: %f\n", min, max);
@@ -768,7 +769,7 @@
 			if (level < min || level > max)
 				return;
 
-			System.out.printf("addLevel: %f\n", level);
+			System.out.printf("%dm ", (int)level);
 			java.util.Arrays.fill(visited, (byte) 0);
 
 			for (int y = minY; y < maxY; y++) {
Index: src/uk/me/parabola/mkgmap/reader/dem/optional/GeoTiffDEM.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/dem/optional/GeoTiffDEM.java	(Revision 1114)
+++ src/uk/me/parabola/mkgmap/reader/dem/optional/GeoTiffDEM.java	(Arbeitskopie)
@@ -16,18 +16,21 @@
  */
 package uk.me.parabola.mkgmap.reader.dem.optional;
 
+import java.awt.image.Raster;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.media.jai.JAI;
+import javax.media.jai.PlanarImage;
+import javax.media.jai.RenderedOp;
+
 import uk.me.parabola.mkgmap.reader.dem.DEM;
 
-import java.awt.image.renderable.ParameterBlock;
-import java.awt.image.Raster;
-import java.awt.image.DataBuffer;
-import java.io.*;
-import java.nio.channels.FileChannel;
-import java.nio.MappedByteBuffer;
+import com.sun.media.jai.codec.FileSeekableStream;
+import com.sun.media.jai.codec.SeekableStream;
+import com.sun.media.jai.codec.TIFFDecodeParam;
 
-import com.sun.media.jai.codec.*;
-import javax.media.jai.*;
-
 public abstract class GeoTiffDEM extends DEM
 {
     Raster raster;
Index: src/uk/me/parabola/mkgmap/reader/osm/Element.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Element.java	(Revision 1114)
+++ src/uk/me/parabola/mkgmap/reader/osm/Element.java	(Arbeitskopie)
@@ -86,6 +86,7 @@
 	 * element.
 	 */
 	public void copyTags(Element other) {
+		if (other.tags != null)
 		tags = other.tags.copy();
 	}
 
@@ -97,4 +98,8 @@
 		if (this.name == null)
 			this.name = name;
 	}
+
+	public Tags getTags() {
+		return tags;
+	}
 }
Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(Revision 1114)
+++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java	(Arbeitskopie)
@@ -1,11 +1,10 @@
 package uk.me.parabola.mkgmap.reader.osm;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Coord;
 
 /**
@@ -16,15 +15,19 @@
  */
 public class MultiPolygonRelation extends Relation {
 	private Way outer;
-	private final Collection<Way> inners = new ArrayList<Way>();
+	private List<Way> outers = new ArrayList<Way>();
+	private List<Way> inners = new ArrayList<Way>();
+	private Map<Long, Way> myWayMap;
 
 	/**
 	 * Create an instance based on an exsiting relation.  We need to do
 	 * this because the type of the relation is not known until after all
 	 * its tags are read in.
 	 * @param other The relation to base this one on.
+	 * @param wayMap Map of all ways.
 	 */
-	public MultiPolygonRelation(Relation other) {
+	public MultiPolygonRelation(Relation other, Map<Long, Way> wayMap) {
+		myWayMap = wayMap;
 		setId(other.getId());
 		for (Map.Entry<Element, String> pairs: other.getRoles().entrySet()){
 			addElement(pairs.getValue(), pairs.getKey());
@@ -33,10 +36,12 @@
 
 			if (value != null && pairs.getKey() instanceof Way) {
 				Way way = (Way) pairs.getKey();
-				if (value.equals("outer"))
-					outer = way;
-				else if (value.equals("inner"))
+				if (value.equals("outer")){
+					outers.add(way);
+				}
+				else if (value.equals("inner")){
 					inners.add(way);
+				}
 			}
 		}
 
@@ -45,18 +50,63 @@
 	}
 
 	/** Process the ways in this relation.
+	 * Joins way with the role "outer"
 	 * Adds ways with the role "inner" to the way with the role "outer"
 	 */
 	public void processElements() {
-		if (outer != null)
-		{   
+
+		if (outers != null)
+		{
+			// copy first outer way
+			Iterator<Way> it = outers.iterator();
+			if (it.hasNext()){
+				// duplicate outer way and remove tags for cascaded multipolygons
+				Way tempWay = it.next();
+				outer = new Way(-tempWay.getId());
+				outer.copyTags(tempWay);
+				for(Coord point: tempWay.getPoints()){
+					outer.addPoint(point);
+				}
+				myWayMap.put(outer.getId(), outer);
+				if (tempWay.getTags() != null){
+					tempWay.getTags().removeAll();
+				}
+				it.remove();
+			}
+			
+			// if we have more than one outer way, we join them if they are parts of a long way
+			it = outers.iterator();
+			while (it.hasNext()){
+				Way tempWay = it.next();
+				if (tempWay.getPoints().get(0) == outer.getPoints().get(outer.getPoints().size()-1)){
+					for(Coord point: tempWay.getPoints()){
+						outer.addPoint(point);
+					}
+					if (tempWay.getTags() != null){
+						tempWay.getTags().removeAll();
+					}
+					it.remove();
+					it = outers.iterator();
+				}
+			}
+		
 			for (Way w: inners) {	
-				if (w != null) {
-					List<Coord> pts = w.getPoints();
-					int[] insert = findCpa(outer.getPoints(), pts);
-					if (insert[0] > 0)
-						insertPoints(pts, insert[0], insert[1]);				
-					pts.clear();
+				if (w != null && outer!= null) {
+					int[] insert = findCpa(outer.getPoints(), w.getPoints());
+					insertPoints(w, insert[0], insert[1]);
+
+					// remove tags from inner way that are available in the outer way
+					if (outer.getTags() != null){
+						for (Map.Entry<String, String> mapTags: outer.getTags().getKeyValues().entrySet()){
+							String key = mapTags.getKey();
+							String value = mapTags.getValue();
+							if (w.getTag(key) != null){
+								if (w.getTag(key).equals(value)){
+									w.deleteTag(key);
+								}
+							}
+						}
+					}
 				}
 			}
 		}
@@ -64,22 +114,43 @@
 	
 	/**
 	 * Insert Coordinates into the outer way.
-	 * @param inList List of Coordinates to be inserted
+	 * @param way Way to be inserted
 	 * @param out Coordinates will be inserted after this point in the outer way.
 	 * @param in Points will be inserted starting at this index, 
 	 *    then from element 0 to (including) this element;
 	 */
-	private void insertPoints(List<Coord> inList, int out, int in){
+	private void insertPoints(Way way, int out, int in){
 		List<Coord> outList = outer.getPoints();
+		List<Coord> inList = way.getPoints();
 		int index = out+1;
-		for (int i = in; i < inList.size(); i++)
+		for (int i = in; i < inList.size(); i++){
 			outList.add(index++, inList.get(i));
-		for (int i = 0; i <= in; i++)
+		}
+		for (int i = 0; i < in; i++){
 			outList.add(index++, inList.get(i));
-
-		//with this line commented we get triangles, when uncommented some areas disappear
-		// at least in mapsource, on device itself looks OK.
-		outList.add(index,outList.get(out));  
+		}
+		
+		if (outer.getPoints().size() < 32){
+			outList.add(index++, inList.get(in));
+			outList.add(index, outList.get(out));
+		}
+		else{
+			// we shift the nodes to avoid duplicate nodes (large areas only)
+			int oLat = outList.get(out).getLatitude();
+			int oLon = outList.get(out).getLongitude();
+			int iLat = inList.get(in).getLatitude();
+			int iLon = inList.get(in).getLongitude();
+			if (Math.abs(oLat - iLat) > Math.abs(oLon - iLon)){
+				int delta = (oLon > iLon)? -1 : 1;
+				outList.add(index++, new Coord(iLat + delta, iLon));
+				outList.add(index, new Coord(oLat + delta, oLon));
+				}
+			else{
+				int delta = (oLat > iLat)? 1 : -1;
+				outList.add(index++, new Coord(iLat, iLon + delta));
+				outList.add(index, new Coord(oLat, oLon + delta));
+			}
+		}
 	}
 	
 	/**
Index: src/uk/me/parabola/mkgmap/reader/osm/Tags.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/Tags.java	(Revision 1114)
+++ src/uk/me/parabola/mkgmap/reader/osm/Tags.java	(Arbeitskopie)
@@ -16,7 +16,9 @@
  */
 package uk.me.parabola.mkgmap.reader.osm;
 
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
 /**
  * Store the tags that belong to an Element.
@@ -110,7 +112,7 @@
 		}
 		return null;
 	}
-
+	
 	/**
 	 * Make a deep copy of this object.
 	 * @return A copy of this object.
@@ -261,4 +263,24 @@
 					put(e.key, e.value);
 		}
 	}
-}
+	
+	public void removeAll() {
+		for (int i = 0; i < capacity; i++){
+			keys[i] = null;
+			values[i] = null;
+		}
+		size = 0;
+	}
+
+	public Map<String, String> getKeyValues() {
+		Map<String, String> tagMap = new HashMap<String, String>();
+		for (int i = 0; i < capacity; i++){
+			if (keys[i] != null && values[i] != null){
+				tagMap.put(keys[i], values[i]);
+			}
+		}
+		return tagMap;
+	}
+
+
+}
\ No newline at end of file
