Index: resources/help/en/options
===================================================================
--- resources/help/en/options	(revision 2277)
+++ resources/help/en/options	(working copy)
@@ -16,6 +16,11 @@
 	Read input data from the give file.  This option (or just a
 	filename) may be given more than once.
 
+--precomp-sea=directoryname
+    Defines the directory that contains the precompiled sea tiles.
+	When this option is defined all natural=coastline tags from the
+	input OSM tiles are removed and this data is used instead.      
+
 --coastlinefile=filename[,filename]
 	Defines a comma separated list of files that contain coastline 
 	data. The coastline data from the input files are removed if 
Index: src/uk/me/parabola/mkgmap/reader/osm/PrecompSeaElementSaver.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/PrecompSeaElementSaver.java	(revision 0)
+++ src/uk/me/parabola/mkgmap/reader/osm/PrecompSeaElementSaver.java	(revision 0)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+package uk.me.parabola.mkgmap.reader.osm;
+
+import uk.me.parabola.util.EnhancedProperties;
+
+/**
+ * This saver does not convert the elements. 
+ * @author WanMil
+ */
+public class PrecompSeaElementSaver extends ElementSaver {
+
+	public PrecompSeaElementSaver(EnhancedProperties args) {
+		super(args);
+	}
+
+	public void convert(OsmConverter converter) {
+	}
+}
\ No newline at end of file
Index: src/uk/me/parabola/mkgmap/reader/osm/CoastlineElementSaver.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/CoastlineElementSaver.java	(revision 2277)
+++ src/uk/me/parabola/mkgmap/reader/osm/CoastlineElementSaver.java	(working copy)
@@ -1,3 +1,15 @@
+/*
+ * Copyright (C) 2010, 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
 package uk.me.parabola.mkgmap.reader.osm;
 
 import uk.me.parabola.util.EnhancedProperties;
Index: src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinPrecompSeaDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinPrecompSeaDataSource.java	(revision 0)
+++ src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinPrecompSeaDataSource.java	(revision 0)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+package uk.me.parabola.mkgmap.reader.osm.bin;
+
+import java.util.Collections;
+import java.util.Set;
+
+import uk.me.parabola.mkgmap.reader.osm.OsmReadingHooks;
+
+public class OsmBinPrecompSeaDataSource extends OsmBinMapDataSource {
+	
+	private static final Set<String> coastlineTags = Collections.singleton("natural");
+
+	protected void addBackground(boolean mapHasPolygon4B) {
+		// do not add a background polygon
+	}
+
+	protected OsmReadingHooks[] getPossibleHooks() {
+		// no hooks
+		return new OsmReadingHooks[] {};
+	}
+
+	public Set<String> getUsedTags() {
+		return coastlineTags;
+	}
+}
Index: src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinCoastDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinCoastDataSource.java	(revision 2277)
+++ src/uk/me/parabola/mkgmap/reader/osm/bin/OsmBinCoastDataSource.java	(working copy)
@@ -1,10 +1,22 @@
+/*
+ * Copyright (C) 2010, 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
 package uk.me.parabola.mkgmap.reader.osm.bin;
 
 import java.util.Collections;
 import java.util.Set;
 
-import uk.me.parabola.mkgmap.reader.osm.CoastlineElementSaver;
 import uk.me.parabola.mkgmap.reader.osm.OsmReadingHooks;
+import uk.me.parabola.mkgmap.reader.osm.PrecompSeaElementSaver;
 
 public class OsmBinCoastDataSource extends OsmBinMapDataSource {
 	
@@ -19,11 +31,11 @@
 		return new OsmReadingHooks[] {};
 	}
 
-	protected void createElementSaver() {
-		elementSaver = new CoastlineElementSaver(getConfig());
-	}
-
 	public Set<String> getUsedTags() {
 		return coastlineTags;
 	}
+
+	protected void createElementSaver() {
+		elementSaver = new PrecompSeaElementSaver(getConfig());
+	}	
 }
Index: src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java	(revision 2277)
+++ src/uk/me/parabola/mkgmap/reader/osm/SeaGenerator.java	(working copy)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010.
+ * Copyright (C) 2010-2012.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 3 or
@@ -12,7 +12,12 @@
  */
 package uk.me.parabola.mkgmap.reader.osm;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -24,13 +29,17 @@
 import java.util.NavigableSet;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.regex.Pattern;
+import java.util.zip.GZIPInputStream;
 
 import uk.me.parabola.imgfmt.MapFailedException;
 import uk.me.parabola.imgfmt.app.Area;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.general.LineClipper;
+import uk.me.parabola.mkgmap.general.LoadableMapDataSource;
 import uk.me.parabola.mkgmap.osmstyle.StyleImpl;
+import uk.me.parabola.mkgmap.reader.osm.xml.Osm5PrecompSeaDataSource;
 import uk.me.parabola.util.EnhancedProperties;
 
 /**
@@ -63,6 +72,40 @@
 	private String[] coastlineFilenames;
 	private StyleImpl fbRules;
 	
+	/** The size (lat and long) of the precompiled sea tiles */
+	private final static int PRECOMP_RASTER = 1 << 15;
+	/**
+	 * The directory of the precompiled sea tiles or <code>null</code> if
+	 * precompiled sea should not be used.
+	 */
+	private File precompSeaDir;
+	private static ThreadLocal<Map<String,String>> precompIndex = new ThreadLocal<Map<String,String>>();
+
+	private static final List<Class<? extends LoadableMapDataSource>> precompSeaLoader;
+
+	static {
+		String[] sources = {
+				"uk.me.parabola.mkgmap.reader.osm.bin.OsmBinPrecompSeaDataSource",
+				// must be last as it is the default
+				"uk.me.parabola.mkgmap.reader.osm.xml.Osm5PrecompSeaDataSource", };
+
+		precompSeaLoader = new ArrayList<Class<? extends LoadableMapDataSource>>();
+
+		for (String source : sources) {
+			try {
+				@SuppressWarnings({ "unchecked" })
+				Class<? extends LoadableMapDataSource> c = (Class<? extends LoadableMapDataSource>) Class
+						.forName(source);
+				precompSeaLoader.add(c);
+			} catch (ClassNotFoundException e) {
+				// not available, try the rest
+			} catch (NoClassDefFoundError e) {
+				// not available, try the rest
+			}
+		}
+	}
+	
+	
 	/**
 	 * Sort out options from the command line.
 	 * Returns true only if the option to generate the sea is active, so that
@@ -70,9 +113,65 @@
 	 */
 	public boolean init(ElementSaver saver, EnhancedProperties props) {
 		this.saver = saver;
+
+		String precompSea = props.getProperty("precomp-sea", null);
+		if (precompSea != null) {
+			precompSeaDir = new File(precompSea);
+			if (precompSeaDir.exists())
+			{
+				if (precompIndex.get() == null) {
+					final File indexFile = new File(precompSeaDir, "index.txt.gz");
+					if (indexFile.exists()) {
+						try {
+							LineNumberReader indexReader = new LineNumberReader(
+									new InputStreamReader(new GZIPInputStream(new FileInputStream(indexFile))));
+							Pattern csvSplitter = Pattern.compile(Pattern
+									.quote(";"));
+							String indexLine = null;
+							Map<String, String> indexItems = new HashMap<String, String>();
+							while ((indexLine = indexReader.readLine()) != null) {
+								String[] items = csvSplitter.split(indexLine);
+								if (items.length != 2) {
+									log.warn("Invalid format in index file: "
+											+ indexLine);
+									continue;
+								}
+								if (items[0].startsWith("#")) {
+									// comment
+									continue;
+								}
+								indexItems.put(items[0].trim().intern(),
+										items[1].trim().intern());
+							}
+							precompIndex.set(indexItems);
+						} catch (IOException exp) {
+							log.error("Cannot read index file " + indexFile,
+									exp);
+							precompIndex.set(null);
+							precompSea = null;
+						}
+					} else {
+						log.error("Disable precompiled sea due to missing index.txt file in precompiled sea directory "
+							+ precompSeaDir);
+						System.err.println("Disable precompiled sea due to missing index.txt file in precompiled sea directory "
+							+ precompSeaDir);
+						precompIndex.set(null);
+						precompSeaDir = null;
+					}
+				}
+			} else
+			{
+				log.error("Directory with precompiled sea does not exist: "
+						+ precompSeaDir);
+				System.err.println("Directory with precompiled sea does not exist: "
+						+ precompSeaDir);
+				precompSeaDir = null;
+			}
+		}
+		
 		String gs = props.getProperty("generate-sea", null);
-		boolean generateSea = gs != null;
-		if(generateSea) {
+		boolean generateSea = gs != null || precompSea != null;
+		if (gs != null) {
 			for(String o : gs.split(",")) {
 				if("no-mp".equals(o) ||
 						"polygon".equals(o) ||
@@ -80,26 +179,29 @@
 					generateSeaUsingMP = false;
 				else if("multipolygon".equals(o))
 					generateSeaUsingMP = true;
-				else if(o.startsWith("close-gaps="))
-					maxCoastlineGap = (int)Double.parseDouble(o.substring(11));
-				else if("no-sea-sectors".equals(o))
-					allowSeaSectors = false;
-				else if("extend-sea-sectors".equals(o)) {
-					allowSeaSectors = false;
-					extendSeaSectors = true;
-				}
 				else if(o.startsWith("land-tag="))
 					landTag = o.substring(9).split("=");
-				else if("floodblocker".equals(o)) 
-					floodblocker = true;
-				else if(o.startsWith("fbgap="))
-					fbGap = (int)Double.parseDouble(o.substring("fbgap=".length()));
-				else if(o.startsWith("fbratio="))
-					fbRatio = Double.parseDouble(o.substring("fbratio=".length()));
-				else if(o.startsWith("fbthres="))
-					fbThreshold = (int)Double.parseDouble(o.substring("fbthres=".length()));
-				else if("fbdebug".equals(o)) 
-					fbDebug = true;
+				else if (precompSea == null) {
+					// the other options are valid only if not using precompiled sea data
+					if(o.startsWith("close-gaps="))
+						maxCoastlineGap = (int)Double.parseDouble(o.substring(11));
+					else if("no-sea-sectors".equals(o))
+						allowSeaSectors = false;
+					else if("extend-sea-sectors".equals(o)) {
+						allowSeaSectors = false;
+						extendSeaSectors = true;
+					}
+					else if("floodblocker".equals(o)) 
+						floodblocker = true;
+					else if(o.startsWith("fbgap="))
+						fbGap = (int)Double.parseDouble(o.substring("fbgap=".length()));
+					else if(o.startsWith("fbratio="))
+						fbRatio = Double.parseDouble(o.substring("fbratio=".length()));
+					else if(o.startsWith("fbthres="))
+						fbThreshold = (int)Double.parseDouble(o.substring("fbthres=".length()));
+					else if("fbdebug".equals(o)) 
+						fbDebug = true;
+				}
 				else if(o.isEmpty())
 					continue;
 				else {
@@ -119,24 +221,28 @@
 				}
 			}
 			
-			if (floodblocker) {
-				try {
-					fbRules = new StyleImpl(null, "floodblocker");
-				} catch (FileNotFoundException e) {
-					log.error("Cannot load file floodblocker rules. Continue floodblocking disabled.");
-					floodblocker = false;
+			// init floodblocker and coastlinefile loader only 
+			// if precompSea is not set
+			if (precompSea == null) {
+				if (floodblocker) {
+					try {
+						fbRules = new StyleImpl(null, "floodblocker");
+					} catch (FileNotFoundException e) {
+						log.error("Cannot load file floodblocker rules. Continue floodblocking disabled.");
+						floodblocker = false;
+					}
 				}
-			}
 
-			String coastlineFileOpt = props.getProperty("coastlinefile", null);
-			if (coastlineFileOpt != null) {
-				coastlineFilenames = coastlineFileOpt.split(",");
-				CoastlineFileLoader.getCoastlineLoader().setCoastlineFiles(
-						coastlineFilenames);
-				CoastlineFileLoader.getCoastlineLoader().loadCoastlines();
-				log.info("Coastlines loaded");
-			} else {
-				coastlineFilenames = null;
+				String coastlineFileOpt = props.getProperty("coastlinefile", null);
+				if (coastlineFileOpt != null) {
+					coastlineFilenames = coastlineFileOpt.split(",");
+					CoastlineFileLoader.getCoastlineLoader().setCoastlineFiles(
+							coastlineFilenames);
+					CoastlineFileLoader.getCoastlineLoader().loadCoastlines();
+					log.info("Coastlines loaded");
+				} else {
+					coastlineFilenames = null;
+				}
 			}
 		}
 
@@ -168,7 +274,7 @@
 		if(natural != null) {
 			if("coastline".equals(natural)) {
 				way.deleteTag("natural");
-				if (coastlineFilenames == null)
+				if (coastlineFilenames == null && precompSeaDir == null)
 					shoreline.add(way);
 			} else if (natural.contains(";")) {
 				// cope with compound tag value
@@ -187,13 +293,200 @@
 					way.deleteTag("natural");
 					if(others != null)
 						way.addTag("natural", others);
-					if (coastlineFilenames == null)
+					if (coastlineFilenames == null && precompSeaDir == null)
 						shoreline.add(way);
 				}
 			}
 		}
-}
+	}
+
+	/**
+	 * Creates a reader for the given filename of the precomiled sea tile.
+	 * @param filename precompiled sea tile 
+	 * @return the reader for the tile
+	 */
+	private static OsmMapDataSource createTileReader(String filename) {
+		for (Class<? extends LoadableMapDataSource> loader : precompSeaLoader) {
+			try {
+				LoadableMapDataSource src = loader.newInstance();
+				if (filename != null && src instanceof OsmMapDataSource
+						&& src.isFileSupported(filename))
+					return (OsmMapDataSource) src;
+			} catch (InstantiationException e) {
+				// try the next one.
+			} catch (IllegalAccessException e) {
+				// try the next one.
+			} catch (NoClassDefFoundError e) {
+				// try the next one
+			}
+		}
+
+		// Give up and assume it is in the XML format. If it isn't we will get
+		// an error soon enough anyway.
+		return new Osm5PrecompSeaDataSource();
+	}
+	
+	/**
+	 * Loads the precomp sea tile with the given filename.
+	 * @param filename the filename of the precomp sea tile
+	 * @return all ways of the tile
+	 * @throws FileNotFoundException if the tile could not be found
+	 */
+	private Collection<Way> loadPrecompTile(String filename)
+			throws FileNotFoundException {
+		OsmMapDataSource src = createTileReader(filename);
+		src.config(new EnhancedProperties());
+		log.info("Started loading coastlines from", filename);
+		src.load(filename);
+		log.info("Finished loading coastlines from", filename);
+		return src.getElementSaver().getWays().values();
+	}
+
+	private int getRasterStart(int value) {
+		int rem = value % PRECOMP_RASTER;
+		if (rem == 0) {
+			return value;
+		} else if (value >= 0) {
+			return value - rem;
+		} else {
+			return value - PRECOMP_RASTER - rem;
+		}
+	}
+
+	private int getRasterEnd(int value) {
+		int rem = value % PRECOMP_RASTER;
+		if (rem == 0) {
+			return value;
+		} else if (value >= 0) {
+			return value + PRECOMP_RASTER - rem;
+		} else {
+			return value - rem;
+		}
+	}
+	
+	private List<String> getPrecompKeyNames() {
+		Area bounds = saver.getBoundingBox();
+		List<String> precompKeys = new ArrayList<String>();
+		for (int lat = getRasterStart(bounds.getMinLat()); lat < getRasterEnd(bounds
+				.getMaxLat()); lat += PRECOMP_RASTER) {
+			for (int lon = getRasterStart(bounds.getMinLong()); lon < getRasterEnd(bounds
+					.getMaxLong()); lon += PRECOMP_RASTER) {
+				precompKeys.add(lat+"_"+lon);
+			}
+		}
+		return precompKeys;
+	}
+	
+	/**
+	 * Loads the precompiled sea tiles and adds the data to the 
+	 * element saver.
+	 */
+	private void addPrecompSea() {
+		log.info("Load precompiled sea tiles");
 
+		// flag if all tiles contains sea or way only
+		// this is important for polygon processing
+		boolean distinctTilesOnly = true;
+		
+		List<Way> landWays = new ArrayList<Way>();
+		List<Way> seaWays = new ArrayList<Way>();
+		
+		Map<String,String> index = precompIndex.get();
+		for (String precompKey : getPrecompKeyNames()) {
+			String tileName = index.get(precompKey);
+			
+			if (tileName == null) {
+				log.error("Precompile sea tile "+tileName+" is missing in the index. Skipping.");
+				continue;
+			}
+			
+			if ("sea".equals(tileName) || "land".equals(tileName)) {
+				Way w = new Way(FakeIdGenerator.makeFakeId());
+				w.addTag("natural", tileName);
+				
+				String[] tileCoords = precompKey.split(Pattern.quote("_"));
+				int minLat = Integer.valueOf(tileCoords[0]);
+				int minLon = Integer.valueOf(tileCoords[1]);
+				int maxLat = minLat + PRECOMP_RASTER;
+				int maxLon = minLon + PRECOMP_RASTER;
+				w.addPoint(new Coord(minLat,minLon));
+				w.addPoint(new Coord(minLat,maxLon));
+				w.addPoint(new Coord(maxLat,maxLon));
+				w.addPoint(new Coord(maxLat,minLon));
+				w.addPoint(new Coord(minLat,minLon));
+				
+				if ("sea".equals(tileName)) {
+					seaWays.add(w);
+				} else {
+					landWays.add(w);
+				}
+				
+			} else {
+				distinctTilesOnly = false;
+				String precompTile = new File(precompSeaDir,tileName).getAbsolutePath();
+				try {
+					Collection<Way> seaPrecompWays = loadPrecompTile(precompTile);
+					log.info(seaPrecompWays.size(), "precomp sea ways from",
+							precompTile, "loaded.");
+
+					for (Way w : seaPrecompWays) {
+						// set a new id to be sure that the precompiled ids do not
+						// interfere with the ids of this run
+						w.setId(FakeIdGenerator.makeFakeId());
+					
+						if ("land".equals(w.getTag("natural"))) {
+							landWays.add(w);
+						} else {
+							seaWays.add(w);
+						}
+					}
+				} catch (FileNotFoundException exp) {
+					log.error("Preompiled sea tile " + precompTile + " not found.");
+				} catch (Exception exp) {
+					log.error(exp);
+					exp.printStackTrace();
+				}
+			}
+		}
+		
+		// check if the land tags need to be changed
+		if (landTag != null && ("natural".equals(landTag[0]) && "land".equals(landTag[1])) == false) {
+			for (Way w : landWays) {
+				w.deleteTag("natural");
+				w.addTag(landTag[0], landTag[1]);
+			}
+		}
+		
+		if (generateSeaUsingMP || distinctTilesOnly) {
+			// when using multipolygons use the data directly from the precomp files 
+			// also with polygons if all tiles are using either sea or land only
+			for (Way w : landWays) {
+				saver.addWay(w);
+			}
+			for (Way w : seaWays) {
+				saver.addWay(w);
+			}
+		} else {
+			// using polygons
+			
+			Area bounds = saver.getBoundingBox();
+			// first add the complete bounding box as sea
+			Way sea = new Way(FakeIdGenerator.makeFakeId());
+			sea.addPoint(new Coord(bounds.getMinLat(), bounds.getMinLong()));
+			sea.addPoint(new Coord(bounds.getMinLat(), bounds.getMaxLong()));
+			sea.addPoint(new Coord(bounds.getMaxLat(), bounds.getMaxLong()));
+			sea.addPoint(new Coord(bounds.getMaxLat(), bounds.getMinLong()));
+			sea.addPoint(new Coord(bounds.getMinLat(), bounds.getMinLong()));
+			sea.addTag("natural", "sea");
+			
+			for (Way w : landWays) {
+				saver.addWay(w);
+			}
+		}
+	}
+
+	
+	
 	/**
 	 * Joins the given segments to closed ways as good as possible.
 	 * @param segments a list of closed and unclosed ways
@@ -263,6 +556,13 @@
 	 * All done, process the saved shoreline information and construct the polygons.
 	 */
 	public void end() {
+		// precompiled sea has highest priority
+		// if it is set do not perform any other algorithm
+		if (precompSeaDir != null) {
+			addPrecompSea();
+			return;
+		}
+
 		Area seaBounds = saver.getBoundingBox();
 		if (coastlineFilenames == null) {
 			log.info("Shorelines before join", shoreline.size());
Index: src/uk/me/parabola/mkgmap/reader/osm/CoastlineFileLoader.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/CoastlineFileLoader.java	(revision 2277)
+++ src/uk/me/parabola/mkgmap/reader/osm/CoastlineFileLoader.java	(working copy)
@@ -1,3 +1,15 @@
+/*
+ * Copyright (C) 2010, 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
 package uk.me.parabola.mkgmap.reader.osm;
 
 import java.io.FileNotFoundException;
Index: src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5CoastDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5CoastDataSource.java	(revision 2277)
+++ src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5CoastDataSource.java	(working copy)
@@ -1,3 +1,15 @@
+/*
+ * Copyright (C) 2010, 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
 package uk.me.parabola.mkgmap.reader.osm.xml;
 
 import java.util.Collections;
Index: src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5PrecompSeaDataSource.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5PrecompSeaDataSource.java	(revision 0)
+++ src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5PrecompSeaDataSource.java	(revision 0)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 or
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+package uk.me.parabola.mkgmap.reader.osm.xml;
+
+import java.util.Collections;
+import java.util.Set;
+
+import uk.me.parabola.mkgmap.reader.osm.OsmReadingHooks;
+import uk.me.parabola.mkgmap.reader.osm.PrecompSeaElementSaver;
+
+public class Osm5PrecompSeaDataSource extends Osm5MapDataSource {
+
+	private static final Set<String> coastlineTags = Collections.singleton("natural");
+	
+	protected void addBackground(boolean mapHasPolygon4B) {
+		// do not add a background polygon
+	}
+	
+	protected OsmReadingHooks[] getPossibleHooks() {
+		// no hooks
+		return new OsmReadingHooks[] {};
+	}
+
+	public Set<String> getUsedTags() {
+		return coastlineTags;
+	}
+
+	protected void createElementSaver() {
+		elementSaver = new PrecompSeaElementSaver(getConfig());
+	}
+}
