Re: [mkgmap-dev] Really Serious bug when not using --route
Maybe it's this bit in the TDB-Header (HeaderBlock.java): os.write(1);// map is routable At least it looks strange that this bit is set regardless of the --route option, and there are similar flags related to DEM info in this block as well ... Best wishes Christian Felix Hartmann schrieb: On 23.05.2010 18:24, Felix Hartmann wrote: There is a serious bug that breaks routable maps when --route is NOT given. This bug will in future break routing on most GPS devices and is already inflicting Mapsource 6.16.1 and Basecamp 3. This means that also if you compile maps that are not routable, you have to pass the --route parameter. Else the GPS / Mapsource looks into an empty NOD table and may crash. This will happen as soon as you mix routable maps with the non routable mkgmap created maps. The problem is that Mapsource and the GPS search for 6344.NOD data (6344 as an example placeholder for the mapname). Falagar, a developer at Garmin said to release a fix for this bug in Mapsource 6.16.2 however mentioned that this fix will not be carried on to GPS devices and will still mean a deterioration of overall routing. I'm not sure what the exact problem for this is (I just tried even very old mkgmap versions like 858 and also there the problem arises) but currently this means that --route should be the compulsory for all map creation, also not routable ones. If you have old maps (eg transparent contourline maps) that are troublesome to rebuilt, then opening with gpsmapedit, saving as mp and recompiling passing --route parameter is enough to solve the problem. I think that until the bug is found, mkgmap should adopt --route as standard, because it may happen that if users put an mkgmap created without --route onto their GPS besides other routable maps, these maps might impact autorouting for the other routable maps (except if deactivated on the GPS). Just as an update. I got the following answer from Falagar, concerning creating all maps with --route parameter: /Naja, das ist halt nur ein Trick. Am besten waere es, die NOD-Flag zu entfernen, aber ich weiss nicht, ob ihr wisst, wo die ist. Ich weiss es leider auch nicht. Es koennte evtl. ein wenig langsamer sein, wenn MS Geraet die Routinginformationen erst oeffnen muessen, bevor wir feststellen, dass da keine Info drin ist. Aber ich denke, das sollte erst einmal funktionieren. / Translation. This is only a trick. Best would be to completly remove the NOD-Flag, but I don't know whether you know where it is. Actually, I don't know it either. Eventually it could be a little bit slower if Mapsource GPS first has to open the routing information, until it notices that there is no info inside. But I think this would do if for a beginning. So either someone finds the NOD flag (gmaptool also knows nothing about it, removing NOD data with gmaptool does not clear the NOD flag, ) and it will be deactivated when --route is not given, or we pass --route as mandatory, as we obviously miss something in the implementation. I will give some really old versions a go to see if they did it correctly and the bug got introduced with the advent of routing in mkgmap, and send a message if they worked correctly. If not then we probably set this flag since the beginning (but until recently this was no problem). ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] New mkgmap styles
Hi all, mkgmap already contains a class uk.me.parabola.imgfmt.app.typ.TYPFile (written by Thomas Lußnig) which has a method setFamilyId(). I have not tested it yet, but I suppose this method just changes the family id of the TYP file. Is there any reason why mkgmap should not use this method to adjust the family id of an included TYP file? Best wishes Christian Daniela Duerbeck schrieb: Clinton Gladstone wrote: 3. A Perl script then adjusts the TYP file family and product IDs to match that of the map being generated. Aahh. :-) I made a program that patches this number. Oops, I think, I patch just the family-id, not the product-id. Is this necessary? 4. The adjusted TYP file is then passed as a parameter to mkgmap as the map is generated. So do I. But I need nevertheless two typ files and two style files (for the Oregon and the Etrex). When I use certain numbers they can be good for the Etrex but harmful for the Oregon. (The Oregon gets lost in a boot up and crash cycle) Therefore, I would suggest that you think about distributing your TYP file, potentially with the style files, but note that users will have to adjust the name and IDs when they generate their own maps. And a certain note would also not be wrong: Use it at your own risk. If you have a sd-Card inside your unit use it rather on the sd card than on the flash space of your unit. This file is tested on a Garmin whatever, so I am pretty sure, that it workes for Garmin devices of this type. Dani (just to be sure ...) ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] DEM subfile
Ronny Klier schrieb: A friend and I spend some time on research the DEM subfile too. While still not knowing the real data encoding, I think we found some additional information about the structure. thank you very much for sharing your results! In general a DEM subfile consists of a common header, a specific header (so far as all subfiles), a block of two data sections per zoom level and a block of descriptions for each zoom level: Header - Common - Specific Zoom level data block - Block 1 -- Data 1 -- Data 2 - Block 2 -- Data 1 -- Data 2 Zoom level description block - Description 1 - Description 2 There exist at least to versions of the specific header (0x25 byte - old version? - and 0x29 byte). The headers differ only slightly, the additional bytes are (always?) zero. Offset Length 0x00 0x15 common header 0x15 1 different values (MapSource crashes if second bit is set) 0x16 3 all 0 for 0x29 version, different for 0x25 version 0x19 2 number of zoom levels 0x1B 4 0 0x1F 2 size of single description (seen only 3c00 = 60 byte) 0x21 4 Offset of first description block (0x25) 4 All zero The single description blocks describe the structure and position of Data blocks. Offset Length 0x002 Index of description block, starting with . This differs between both versions: While 0x25 version counts in high byte (0001), 0x29 version increments lower byte (0100). Maybe this has different meaning. 0x024 Unknown (seems to be always 4000) 0x064 Unknown (seems to be always 4000) 0x0A4 Values in latitude dimension (vy) 0x0E4 Values in longitude dimension (vx) 0x122 Unknown (always 0) 0x142 Block size in data section 1 (add 1) 0x162 Unknown (always 0) 0x182 Block count in data section 1 (add 1) 0x1A4 Unknown value (Last byte not zero) 0x1E2 Record size in data section 1 0x204 Offset of data section 1 0x244 Offset of data section 2 0x284 western boundary (I know this is unusual but non of the bytes has to be zero and the result still fits) In the files I analyzed the western/northern boundaries are coded with 3 bytes (as usual) and the first byte of these fields look like a separate field to me. Or are you saying the map unit is 360/232 in the DEM file? 0x2C4 northern boundary 0x304 Pixel resolution latitude (py) 0x344 Pixel resolution longitude (px) Are you sure these values are four bytes long? 0x38 2 Minimum height in feet? (0x8e18=-29160 for files with sea/-m) 0x3A 2 Maximum height in feet? (always larger than the previous fields) Using these values the size of data section could be calculated as Block size * Block count * Record size Data section 1 could be read as having Block count blocks. Each of them containing Block size records of Record size. In our opinion the records don't hold offset to data section 2: They are often zero and not continuosly growing, which I would expect them to do. I analyzed mostly tiles with much sea (shown with elevation -m in Basecamp) and I think the offset zero is used for empty block (with no corresponding data in section 2). If you ignore the zeros, the values are indeed continuously growing. Did you see record sizes other than 7 or 8? The variation in size me be due to the fact that for smaller files the offset into section 2 fits into 2 bytes. My guess is that the first 2 (size 7) or 3 (size 8) bytes of the records are an offset and the next two bytes are a base height. For the two lowest zoom levels the bounding box/size for the covered area could be calculated by (vx * px, vy * py) For the empty DEM files generated by GMapTool this is correct (px and py just contain the width/height in map units). However, for other files I analyzed the values of px/py are too large. We don't have any glue what to do with data section 2. But this has to be some picture format, because through removing some layers you will get a lower resolution elevation shading in MapSource. Not knowing much about picture formats, data section 2 (in
Re: [mkgmap-dev] Process for Creating Contour Maps?
Dave F. schrieb: Hi Christain Could you expand on what this means please: ~ '\d*[02468]00' ~ '\d+[05]0' The first line matches multiples of 200m, the second one multiples of 50m. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] DEM subfile
Hi, based on some freely(?) available maps with DEM data and on empty DEM files created by GMapTool I started to analyze the DEM subfile format. With the little information I got so far (see http://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/DEM_Subfile_Format) I managed to write some rudimentary code to create empty DEM files with mkgmap (just the same as GMapTool can do). If anybody has more information on the DEM format, I would be very happy to hear about it. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] Process for Creating Contour Maps?
Jeffrey Ollie schrieb: Does someone have wiki pages describing the best procedure to create contour maps for Garmins? It seems like a number of people are having some success but it doesn't seem to be very well documented. I'm working though trying to get groundtruth to generate .osm files with contours in them and then using mkgmap to create an .img file but mkgmap is segfaulting. In any case though, I'd like to get contour maps using better data than the STRM that groundtruth uses. My ultimate goal is to generate contour maps for a trip out to the Grand Canyon this summer. Dear Jeffrey, there are two different approaches: - Using srtm2osm to generate contour lines as osm files. - Using mkgmap to generate the contour lines directly. In both cases you'll need appropriate entries in your style file to determine which contour lines are mapped to major/medium/minor contours (0x22, 0x21, 0x20). I use # Contours take their name from the elevation setting. contour=elevation ele ~ '\d*[02468]00' { name '${ele|conv:m=ft}'; } [0x22 resolution 18] contour=elevation ele ~ '\d+[05]0' { name '${ele|conv:m=ft}'; } [0x21 resolution 21] contour=elevation { name '${ele|conv:m=ft}'; } [0x20 resolution 23] for this purpose. Currently, the internal generation of contour lines can only cope with maps fitting into a single data tile. It can read SRTM geotiffs, ASTER geotiffs and HGT files. I use the following options: --contours --dem-type=ASTER --dem-increment=20 --dem-maxlevels=200 --dem-path=ASTER Hope that helps Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] Baltic map installer test
Am 03.01.2010 11:05, schrieb Mark Burton: Hi, If anyone cares to test the installer for the demo Baltic map, I have uploaded it to a temporary location: http://www.smartavionics.com/download/OSM-Baltic.exe It's not huge, about 30MB. The family ID is 909. I haven't made any attempt to distinguish the country names in the map so as it includes regions from various countries, the regions/countries for cities will be odd. Any feedback is welcome. Mark Dear Mark, the installer works fine for me (Mapsource running on Windows XP Tablet Edition). Just one remark: The map shows as OSM Map - it would be easier to find it if it would set a less generic name. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] patch v1: Multipolygons: Polygon decomposition
()) { + way.addTag(outSegmentTag.getKey(), + outSegmentTag.getValue()); + } } + } + polygonResults.add(way); } - - polygonResults.add(outerRing); } } @@ -601,11 +595,11 @@ * This is a helper class that stores that gives access to the original segments * of a joined way. */ - private static class JoinedWay extends Way { + private static class JoinedWay extends Way { private final ListWay originalWays; public JoinedWay(Way originalWay) { - super(-originalWay.getId(), new ArrayListCoord(originalWay + super(originalWay.getId(), new ArrayListCoord(originalWay .getPoints())); this.originalWays = new ArrayListWay(); this.originalWays.add(originalWay); Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (Revision 1457) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (Arbeitskopie) @@ -91,7 +91,7 @@ public void reverse() { int numPoints = points.size(); - for(int i = 0; i numPoints/2; ++i) { + for (int i = 0; i numPoints/2; ++i) { Coord t = points.get(i); points.set(i, points.get(numPoints - 1 - i)); points.set(numPoints - 1 - i, t); @@ -102,7 +102,21 @@ return !points.isEmpty() points.get(0).equals(points.get(points.size()-1)); } +/** Check wether a (closed) way is ordered clockwise. +* @return true, if the way is ordered clockwise. +*/ +public boolean isClockwise() { + double sum = 0; + int numPoints = points.size(); + for (int i=0; i numPoints-1; i++) { + Coord p1 = points.get(i); + Coord p2 = points.get(i+1); + sum += p2.getLongitude()*p1.getLatitude() - p1.getLongitude()*p2.getLatitude(); + } + return sum 0; + } + /** * A simple representation of this way. * @return A string with the name and start point /* * Copyright (C) 2010 Christian Gawron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License 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. * * * Author: Christian Gawron * Create date: Jan 1, 2010 */ package uk.me.parabola.mkgmap.reader.osm; import java.util.List; import java.util.Map; import uk.me.parabola.imgfmt.app.Coord; import uk.me.parabola.log.Logger; /** Decompose a polygon (with holes) into simple components */ public class PolygonDecomposer { private static final Logger log = Logger.getLogger(PolygonDecomposer.class); /** * Decompose the given polygon and place the resulting shapes in the outputs list. * @param shape The original shape (with holes). * @param outputs The output list consisting of polygons without holes. */ public static ListWay decompose(Way outer, List? extends Way inners) { /* * Idea: * * while there is outer way with an inner way do * choose an inner way * find the closest points of approach between inner and outer (Pi and Po) * connect a segment of the outer ring at Po to a segment at Pi to create a quadrilateral shape, add it to the result * merge the rest of the hole into the outer way (this removes the hole) * remove the inner way from the list * * This basic approach has to be refined somewhat: * - The quadrilateral could in principle contain or even intersect some of the remaining holes. */ log.info(String.format(polygon decomposer: %d inner ways, inners.size())); ListWay result = new java.util.ArrayListWay(); MapWay, Way isInMap = new java.util.HashMapWay, Way(); ListWay outers = new java.util.ArrayListWay(); if (!outer.isClockwise()) { log.warn(outer way not clockwise, reversing it); outer.reverse(); } outers.add(outer); result.add(outer); for (Way inner : inners
Re: [mkgmap-dev] Multipolygons and basic question on polygons with holes
Am 02.01.2010 22:32, schrieb Johann Gail: Point 3 is illustrated by the second diagram, where a sea polygon is split into X and Y and avoids the need for a DABC cut as in the first. It may not be easy to take advantage of this with an algorithm, but I'd probably make use of that a lot if doing it by hand. Sorry, but I can't see the difference. The picture on the right side shows a splitted polygon, but there are two places with parallel lines. Both polygons have concave segments too. So there is the same need for a DABC cut. Where is my misunderstanding? Dear Johann, the problem in the splitter does AFAIK only occur when the overlapping segments are in the _same_ polygon. So the second diagram should (hopefully) be handled correctly by the splitter. The splitter uses java.awt.geom.Area to do the hard stuff, so I think it's not so easy to fix it. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] Sea tiles problem
Toby Speight schrieb: I've just started using the --generate-sea option, and it almost works. The problem is that of the UK, the whole of northern Scotland (north of a line through Stirling) is inverted - i.e. the land is blue and the sea is light yellow (black at night). This is inconvenient, as that's where I live. What's the likely cause? Could it be due to an island that's tagged in the wrong direction? I've checked the most northerly and most westerly islands and they all look okay to me. GeoFabrik's OSM Inspector doesn't flag up any coastline errors in that area, so that's no help. Could you provide me a download link for the offending tile? Did mkgmap print a warning message Non-closed coastline segment does not hit bounding box: ...? The algorithm I implemented handles two cases of land masses: - closed shoreline segments (aka islands) - shoreline segments which are not closed but extend to the border of the tile (i.e. the intersection of a closed shoreline with the bounding box) In the latter case the shoreline is closed along the tile border. The algorithm then generates a sea background and a multipolygon relation which adds a hole for each landmass. Obviously a landmass with a non-closed boundary will be drowned by that approach :-) One limitation I know of arises with country extracts from geofabrik - they have shorelines cut-off at the country border. As UK is a big island, this should not be the cause of your problem, though. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v5] sea polygons
Dear Robert, thank you for the feedback! Can you send me one of the input tiles (or a download link) where sea and land are flipped? Best wishes Christian Robert Joop schrieb: christian, thank you very much for working on this! here are some current observations with my big bbox cut from the planet: - there were no SEVERE warnings as with prior sea patches. - the main-land in general is not flooded (as with patch 4a) - at the baltic sea, most islands and the northern part of the main-land are flooded and the sea is dry - similar situation at the adriatic sea: the part of italy that is inside the bbox is flooded, as is venice. its laguna comes out as lake. the adriatic sea there is dry. - east of some virtual north south line the situation flips: croatien islands such as krk and the main-land are dry, the sea is flooded. but islands such as lastovo (at 42.75/16.85) are still flooded. btw, the command run was: java -Xmx1300M -enableassertions -jar /[...]/mkgmap-1144+sea5/dist/mkgmap.jar --generate-sea --style-file=../styles/masterstyle --description=OSM cw+rj1 1144+sea5 0826T0059 --family-id=3 --product-id=45 --series-name=master-edition --family-name=OSM--mapname=63250345 --draw-priority=10 --add-pois-to-areas --net --route --remove-short-arcs --gmapsupp ../090819-berlin_HR-tiles/*.osm.gz /[...]/styles/master.TYP rj ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v5] sea polygons
Dear Chris, I also get similar problems for some tiles (the result may depend on the splitter parameters). The problem is that there are several shoreline segments that do not end at the map boundary. Two examples are: - Rügen: The shoreline ends at the border to Poland. The current patch closes this segment since it's nearly closed (the distance between start and end is less than 0.1 * segment-length). This should result in the Polish part of the island (Swinoujscie) beeing flooded. This seems to be the best the algorithm can do since he doesn't know the Polish part of the shoreline cut off by osmosis. - At the border to the Netherlands, the shoreline is also cut off. Currently the algorithm tries to create sea polygons for this shoreline segments by adding a corner point on the boundary of the map. However, this seems not to produce good results in all cases. - I have noticed problems due to partly missing shoreline segments for example at the Elbe. This, however, seems to be a problem in the splitting of the data. If anyone has a good idea how to handle an incomplete shoreline, please let me know. Right know, it might be best to do the following: - get a country extract like germany.osm.bz2 from geofabrik, - calculate the boundary box, - use xapi or same other source to get the complete shoreline in this boundary box, - mix in the shoreline using osmosis, - use the result as input for splitter and mkgmap. I have not tested this yet, but it should give better results. Best wishes Christian Chris-Hein Lunkhusen schrieb: Robert Joop schrieb: christian, thank you very much for working on this! Yes, great to see that the sea is going blue. here are some current observations with my big bbox cut from the planet: For germany (geofabrik extract) : Inner Land tiles w/o coast are ok. The northern sea area is inverted, so islands are blue. The algorithms don't seems to get the water is on the right side rule right. Chris ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] Algorithm for rendering sea
Dear Clifford, in the standard case, the algorithm does the following: - Generate a background sea rectangle which covers the bounding box of the map - Connect the coastline segments wherever possible. The resulting segments should be either closed (= islands) or hit the boundary. - Build a multipolygon relation with - the background as outer element, - the islands as inner elements, - additional inner elements which are built from the coastline segments hitting the boundary by connecting them along the boundary. The multipolygon relation then describes the sea with holes for the land. Unfortunately, sometimes there are non-closed coastline segments not hitting the boundary (e.g. in the country extracts from geofabrik the shore ends at the country border which usually does not coincide with the bounding box). Best wishes Christian Clifford Nolan schrieb: I was wondering how the sea is generated in those recent sea polygon patches. Since I don't understand Java I haven't a clue! Even so, I was thinking of what might be a reasonable way to do it. If there is coastline present within the bounding box then rapidly grow the coastline from the bounding box until you are close to coastline. Then grow the coastline more slowly (smaller overlapping polygons). At this point maybe a test could be done to see if a closed coastline way will end up completely inside a proposed polygon and if it will it's time to make the polygons (temporarily) smaller. In this way the sea should end up shrink wrapping itself around land. Maybe it's already done in a way like this but as I say I wouldn't know. I also thought it might be an idea to build a convex hull of the coastline whereby a a rough outline of the coast is built first so that all land lies on one side of this outline. This could be done by sampling the coast and checking no lines joining pairs of coastline points intersect with another coastline point (which would mean the possibility of coastline on both sides of the line segment). That could be a way to rapidly fill in most of the sea area. All the best, Cliff ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH v5] sea polygons
This version of the patch fixes a bug in the previous version which caused tiles with no shoreline to be flooded. Other improvements are - Shorelines are clipped at the boundary prior to the processing (may fix some problems related to input data) - Somewhat improved handling of non-closed shoreline segments (s. below) The main remaining problems are: - Flooded islands (problem in MultiPolygonRelation?) - Handling of non-closed shoreline segments not ending at the map boundary, usually a result of cutting the shoreline with osmosis (e.g. country-extracts from geofabrik) There are two possibilities to solve this problem: 1. Close the way and treat it as an island. This is sometimes the best solution (Germany: Usedom at the border to Poland) 2. Create a sea sector only for this shoreline segment. In some cases this seems to be the best solution (see German border to the Netherlands where the shoreline continues in the Netherlands) The first choice may lead to flooded areas, the second may lead to triangles. Right now, the first choice is used for nearly closed segments. Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (Revision 1144) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (Arbeitskopie) @@ -76,6 +76,10 @@ } } +public boolean isClosed() { + return points.size() 0 points.get(0).equals(points.get(points.size()-1)); +} + /** * A simple representation of this way. * @return A string with the name and start point Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1144) +++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Arbeitskopie) @@ -1,12 +1,12 @@ 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; +import uk.me.parabola.mkgmap.general.MapShape; /** * Representation of an OSM Multipolygon Relation. @@ -16,15 +16,19 @@ */ public class MultiPolygonRelation extends Relation { private Way outer; - private final CollectionWay inners = new ArrayListWay(); + private ListWay outers = new ArrayListWay(); + private ListWay inners = new ArrayListWay(); + private MapLong, 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, MapLong, Way wayMap) { + myWayMap = wayMap; setId(other.getId()); for (Map.EntryElement, String pairs: other.getRoles().entrySet()){ addElement(pairs.getValue(), pairs.getKey()); @@ -33,10 +37,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); + } } } @@ -44,19 +50,62 @@ copyTags(other); } - /** Process the ways in this relation. -* 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 + IteratorWay 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); +
Re: [mkgmap-dev] [PATCH v4] sea polygons
Thanks for the feedback! One trivial bug in the patch was that a tile with no shoreline at all got a sea polygon as background. This can be fixed by adding // don't do anything if there is no shoreline if (shoreline.size() == 0) return; at the begin of generateSeaPolygon(). Am just testing with germany to see wether there are other problems with cut-off shorelines and will post an improved patch this weekend. Best wishes Christian Clinton Gladstone schrieb: On Sun, Aug 16, 2009 at 12:49 AM, Christian Gawronchristian.gaw...@gmx.de wrote: With this version of the patch, the intersection of the bounding box and the landmass does not have to be simply connected as in version 3 of the patch. Hm... I tried out this patch with a tiled map of Germany. The results were kind of amusing: pretty much all of Germany was flooded, with the exception of some areas around Lübeck. I suppose this is because I am using an extract (from Geofabrik) which cuts off coastline at the country border. Creating automatic sea polygons which will work in practice appears to be a rather non-trivial problem. Cheers and thanks for your work on this. ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH v4] sea polygons
With this version of the patch, the intersection of the bounding box and the landmass does not have to be simply connected as in version 3 of the patch. There are still some flooded island in ireland, but I'm pretty sure this is a problem in the multipolygon code this patch relies on (it just add one sea polygon and constructs a multipolygon with all land components as inner ways). Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1135) +++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Arbeitskopie) @@ -1,12 +1,13 @@ 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; +import uk.me.parabola.mkgmap.general.MapShape; +import uk.me.parabola.mkgmap.general.MultiShapeMerger; /** * Representation of an OSM Multipolygon Relation. @@ -16,15 +17,19 @@ */ public class MultiPolygonRelation extends Relation { private Way outer; - private final CollectionWay inners = new ArrayListWay(); + private ListWay outers = new ArrayListWay(); + private ListWay inners = new ArrayListWay(); + private MapLong, 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, MapLong, Way wayMap) { + myWayMap = wayMap; setId(other.getId()); for (Map.EntryElement, String pairs: other.getRoles().entrySet()){ addElement(pairs.getValue(), pairs.getKey()); @@ -33,10 +38,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 +52,120 @@ } /** 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 processElementsNew() { + if (outers != null) + { + // copy first outer way + IteratorWay 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(); + } +
Re: [mkgmap-dev] Multipolygons
Dear Steve, I just tried the patch. Apart from test 3 not working, the modified PolygonSplitterBase seems not to improve the flooded island problem. Best wishes Christian Steve Ratcliffe schrieb: Hi So test 3 still fails, even after applying the patch, or did I do something wrong applying the patch? No test 3 still failing was a known problem, there are still cases where it was known not to work. ..Steve ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] Commit: r1125: Ant task for mkgmap
svn commit schrieb: Version 1125 was commited by steve on 2009-08-09 13:10:22 +0100 (Sun, 09 Aug 2009) Ant task for mkgmap. As submitted by Christian Gawron. ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev Thanks for adding the Ant task! The Readme says This directory contains code that requires external libraries to work and so is not part of the core code. Maybe it's a good idea to move the GeoTIFF stuff in the extra-dir, too. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v3] sea polygons
Dear Maning, the problem is most probably that I assumed that the intersection between the land mass and the bounding box is simply connected. I won't be able to fix this today, but you could add if (!it1.hasNext()) break; before the offending line 860 EdgeHit h1 = it1.next(); to get at least the code running again. Best wishes Christian maning sambale schrieb: Another test using he new splitter: SEVERE (Main): java.util.concurrent.ExecutionException: java.util.NoSuchElementException java.util.concurrent.ExecutionException: java.util.NoSuchElementException at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252) at java.util.concurrent.FutureTask.get(FutureTask.java:111) at uk.me.parabola.mkgmap.main.Main.endOptions(Main.java:289) at uk.me.parabola.mkgmap.CommandArgsReader.readArgs(CommandArgsReader.java:124) at uk.me.parabola.mkgmap.main.Main.main(Main.java:100) Caused by: java.util.NoSuchElementException at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1115) at java.util.TreeMap$KeyIterator.next(TreeMap.java:1171) at uk.me.parabola.mkgmap.reader.osm.xml.Osm5XmlHandler.generateSeaPolygon(Osm5XmlHandler.java:860) ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v3] sea polygons
Dear Dermot, the triangle artifacts have to do with the multipolygon code. There is a comment by someone saying //with this line commented we get triangles, when uncommented some areas disappear // at least in mapsource, on device itself looks OK. The multiploygon code connects the inner ways with the outer way by two additional ways. These should in theory be two identical ways of opposite direction, but it seems that something breaks in the display on the device unless these ways differ slightly. The slight difference shows up as triangles ... I'm still searching the cause of the flooded islands ... Best wishes Christian Dermot McNally schrieb: OK, I've located a flooded island, I've grabbed a screenshot to illustrate the artefacts I described in my last mail. This is all fairly tolerable stuff, so I'm going to keep using the patched version. Dermot ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH v3] sea polygons
Here is an improved version of the sea polygon patch which also handles shorelines intersecting the boundary of the map (set by the bounds element). I have tested it with Ireland - there are still some islands which are flooded, so the patch should not be considered final. Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (Revision 1124) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (Arbeitskopie) @@ -76,6 +76,10 @@ } } +public boolean isClosed() { + return points.get(0).equals(points.get(points.size()-1)); +} + /** * A simple representation of this way. * @return A string with the name and start point Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1124) +++ 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 CollectionWay inners = new ArrayListWay(); + private ListWay outers = new ArrayListWay(); + private ListWay inners = new ArrayListWay(); + private MapLong, 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, MapLong, Way wayMap) { + myWayMap = wayMap; setId(other.getId()); for (Map.EntryElement, 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 + IteratorWay 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); + } +
Re: [mkgmap-dev] Styling for the power user: filtering contour lines
Hi Daniel, you can use regular expressions to filter contour lines by elevation - here is what I do in my style file: # Contours take their name from the elevation setting. # multiples of 200m contour=elevation ele ~ '\d*[02468]00' { name '${ele|conv:m=ft}'; } [0x22 resolution 18] # multiples of 50m contour=elevation ele ~ '\d+[05]0' { name '${ele|conv:m=ft}'; } [0x21 resolution 21] contour=elevation { name '${ele|conv:m=ft}'; } [0x20 resolution 23] You could use '\d+[27]5' for your purpose. Best wishes Christian David schrieb: To Mark Burton, The new features you added for styling is a great step for my map. The last step is how to filter each contour line which height finishes by 25 or 75 (I don't know how to do it with style rules). These contours are only used for low level of details. At higher LOD, contours with a step of 10m are displayed (to build such a layer I need cgpsmapper). Thank you for your work, David ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] complete list of all mkgmap options
Sounds good to me! Maybe there is an open source framework we could use: http://www.cyclopsgroup.org/projects/jcli/ Best wishes Christian Chris Miller schrieb: Something we've done at my current job is to write a CLI framework that makes managing command line params very very easy. I think this project could benefit greatly from this approach due to its large number of (frequently changing?) parameters. Unfortunately I can't contribute our code, however I can describe in detail what we did and help with the implementation. Basically each application that uses command line params defines an interface that looks something like this: public interface MkGMapParams { @Option(defaultValue = 0, description = The Family ID for the generated map) int getFamilyId(); @Option(defaultValue = Option.REQUIRED, description = The Product ID for the generated map) int getProductId(); @Option(defaultValue = Option.OPTIONAL, description = The country the map represents) String getCountryName(); @Option(description = Specify this to make cycleways) boolean isMakeCycleways(); enum MyEnum { One, Two } @Option(name = custom-enum, defaultValue = One, description = My custom enum) MyEnum getEnum(); // etc } To parse the parameters in code, we basically just make a call to our parser as follows: MkGMapParams params = CliParser.parse(MkGMapParams.class, arguments); // where arguments is a String... parameter That's it, the 'params' object now has all our command line params, parsed into the correct type. If any of the parsing failed, error(s) explaining what was wrong, along with a list of valid options and descriptions, are displayed to the user. Some valid usage examples: java -jar mkgmap --product-id 99 --country-name bhutan --make-cycleways java -jar mkgmap --product-id 99 --custom-enum Two Some invalid usage examples: java -jar mkgmap --family-id 99 --country-name bhutan --make-cycleways (fails because --product-id is a required parameter) java -jar mkgmap --product-id 99 --enum One(fails because the 'enum' parameter must be specified as --custom-enum, not --enum) java -jar mkgmap --product-id abc(fails because --product-id is not an integer) java -jar mkgmap --product-id 11 --family-id --make-cycleways (fails because no value was specified for --family-id) Here's how it works under the hood: We have a converter interface defined as follows: interface ConverterT { T convert(String param) throws Exception; // Convert from the string provided on the command line to a typesafe object. ListString getValidValues() throws Exception; // Provide a list of valid options (optional). eg a list of enum values. String getDefaultValue() throws Exception;// Returns the default value (or null if the parameter is required). } We then have a map from type to converter class, eg: defaultConverters.put(String.class, StringConverter.class); defaultConverters.put(Integer.class, IntegerConverter.class); defaultConverters.put(Integer.type, IntegerConverter.class); We then use reflection (and the annotation info) to examine the interface and determine what the valid parameters are, whether they're required, what type they are etc. For each parameter we parse we convert the string to the appropriate type using the above map. Once that's done and no errors were found, we use Proxy.newProxyInstance() to create an instance of the parameter interface for the client application. Note that we have a lot of additional functionality too like list handling, custom converters, inter-parameter dependency handling, custom validation, Guice support etc but the above is the guts of it. I hope it doesn't sound like too much work - it's really not! The best thing is it will force people to clearly define their parameters in the MkGMapParams interface since that's the only thing that'll be available anywhere beyond the main() method. It's very easy to use once the scaffolding is in place and it makes for nice centralised management of params and user friendly help and error messages. Chris ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v1] sea polygons
Dermot McNally schrieb: This exhausted the 2G of heap space I had allocated when I tried it on a map of Ireland. Are there known practical limits I should try to stay within? Dermot I'm afraid the reason is the code which joins the shoreline segments. The code constructs a new way when two ways are joined (because the shoreline may be used in other relations, e.g. a state border). This may use large amounts of memory. The obvious optimization is to create a new way only when original ways are joined. I will post an optimized patch later. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v1] sea polygons
(SAXParser.java:392) at javax.xml.parsers.SAXParser.parse(SAXParser.java:195) at uk.me.parabola.mkgmap.reader.osm.xml.Osm5MapDataSource.load(Osm5MapDataSource.java:80) at uk.me.parabola.mkgmap.main.MapMaker.loadFromFile(MapMaker.java:148) at uk.me.parabola.mkgmap.main.MapMaker.makeMap(MapMaker.java:56) at uk.me.parabola.mkgmap.main.Main$1.call(Main.java:168) at uk.me.parabola.mkgmap.main.Main$1.call(Main.java:166) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:636) Exiting - if you want to carry on regardless, use the --keep-going option On Sun, Aug 2, 2009 at 3:56 PM, Dermot McNallyderm...@gmail.com wrote: This exhausted the 2G of heap space I had allocated when I tried it on a map of Ireland. Are there known practical limits I should try to stay within? Dermot 2009/8/1 Christian Gawron christian.gaw...@gmx.de: Hi, the attached patch adds a sea polygon (based on the bounding box of the map) and a multipolygon relation with all lines tagged as natural=coastline as inner elements. The code merges coastline components as far as possible. The patch also contains the multipolygon patch by Rudi which wasn't commited so far (without this patch, the rendering fails). The sea polygon is created as natural=sea, for which I added a mapping to garmin type 0x32. Caveat: I have only tested this for islands (Corsica) so far. Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (Revision 1115) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (Arbeitskopie) @@ -76,6 +76,10 @@ } } +public boolean isClosed() { + return points.get(0).equals(points.get(points.size()-1)); +} + /** * A simple representation of this way. * @return A string with the name and start point Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1115) +++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Arbeitskopie) @@ -5,7 +5,6 @@ import java.util.List; import java.util.Map; -import uk.me.parabola.imgfmt.Utils; import uk.me.parabola.imgfmt.app.Coord; /** @@ -23,8 +22,9 @@ * 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, MapLong, Way wayMap) { setId(other.getId()); for (Map.EntryElement, String pairs: other.getRoles().entrySet()){ addElement(pairs.getValue(), pairs.getKey()); @@ -33,8 +33,16 @@ if (value != null pairs.getKey() instanceof Way) { Way way = (Way) pairs.getKey(); - if (value.equals(outer)) - outer = way; + if (value.equals(outer)){ + // duplicate outer way and remove tags for cascaded multipolygons + outer = new Way(-way.getId()); + outer.copyTags(way); + for(Coord point: way.getPoints()) + outer.addPoint(point); + wayMap.put(outer.getId(), outer); + if (way.getTags() != null) + way.getTags().removeAll(); + } else if (value.equals(inner)) inners.add(way); } @@ -52,11 +60,20 @@ { for (Way w: inners) { if (w != null) { - ListCoord pts = w.getPoints(); - int[] insert = findCpa(outer.getPoints(), pts); - if (insert[0] 0) - insertPoints(pts, insert[0], insert[1]); - pts.clear
[mkgmap-dev] [PATCH v2] sea polygons
This improved version should fix an OutOfMemoryError reported by maning sambale and Dermot McNally. It also contains an update of the multipolygon patch by Rudi (which seems to produce better results fo Corsica). Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1115) +++ 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 CollectionWay inners = new ArrayListWay(); + private ListWay outers = new ArrayListWay(); + private ListWay inners = new ArrayListWay(); + private MapLong, 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, MapLong, Way wayMap) { + myWayMap = wayMap; setId(other.getId()); for (Map.EntryElement, 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 + IteratorWay 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) { - ListCoord pts = w.getPoints(); - int[] insert =
Re: [mkgmap-dev] [PATCH v2] sea polygons
Dermot McNally schrieb: 2009/8/2 Christian Gawron christian.gaw...@gmx.de: This improved version should fix an OutOfMemoryError reported by maning sambale and Dermot McNally. It also contains an update of the multipolygon patch by Rudi (which seems to produce better results fo Corsica). OK... Again, based on the Geofabrik Ireland extract, this now runs to completion - though very slowly. And indeed, I now have sea polygons in the sea. The drawback is that I also have them on land, so it seems like the coastline detection must be breaking down somewhere (Ireland has a _very_ complex coastline in places). I can reproduce this problem and will have a look at it. My first guess is that either the shoreline is not closed or that there is still a problem with the multipolygon code. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v2] sea polygons
Dear Apollinaris, this is a misunderstanding. I use the relation internally: The code right now creates a relation with the sea as outer and the (closed) coastline segments as inner members. This way I don't have to think about how to punch the holes into the sea. What is still missing is the handling of non-closed coastline segments - these have to be added to the outer polygon. There is no need for a relation in the raw data. Best wishes Christian Apollinaris Schoell schrieb: this is really great to get sea polygons. makes maps really much better Don't understand why is there a need for relations? is it common to have relations for coastline? have never seen it. my understanding is the right side of the way is sea, left side is land. how can the knowledge of inner way help here except in the case of an island where you have the whole closed polygon available to make a decision. it's nearly impossible to build a relation for a whole continent. due to restriction in relation members you would need parent relations collecting all pieces. and when done all coastlines will be inner elements. there can't be an outer element except you extend the definition to leave earth ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH v1] sea polygons
Hi, the attached patch adds a sea polygon (based on the bounding box of the map) and a multipolygon relation with all lines tagged as natural=coastline as inner elements. The code merges coastline components as far as possible. The patch also contains the multipolygon patch by Rudi which wasn't commited so far (without this patch, the rendering fails). The sea polygon is created as natural=sea, for which I added a mapping to garmin type 0x32. Caveat: I have only tested this for islands (Corsica) so far. Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (Revision 1115) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (Arbeitskopie) @@ -76,6 +76,10 @@ } } +public boolean isClosed() { + return points.get(0).equals(points.get(points.size()-1)); +} + /** * A simple representation of this way. * @return A string with the name and start point Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1115) +++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Arbeitskopie) @@ -5,7 +5,6 @@ import java.util.List; import java.util.Map; -import uk.me.parabola.imgfmt.Utils; import uk.me.parabola.imgfmt.app.Coord; /** @@ -23,8 +22,9 @@ * 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, MapLong, Way wayMap) { setId(other.getId()); for (Map.EntryElement, String pairs: other.getRoles().entrySet()){ addElement(pairs.getValue(), pairs.getKey()); @@ -33,8 +33,16 @@ if (value != null pairs.getKey() instanceof Way) { Way way = (Way) pairs.getKey(); - if (value.equals(outer)) - outer = way; + if (value.equals(outer)){ + // duplicate outer way and remove tags for cascaded multipolygons + outer = new Way(-way.getId()); + outer.copyTags(way); + for(Coord point: way.getPoints()) + outer.addPoint(point); + wayMap.put(outer.getId(), outer); + if (way.getTags() != null) + way.getTags().removeAll(); + } else if (value.equals(inner)) inners.add(way); } @@ -52,11 +60,20 @@ { for (Way w: inners) { if (w != null) { - ListCoord pts = w.getPoints(); - int[] insert = findCpa(outer.getPoints(), pts); - if (insert[0] 0) - insertPoints(pts, insert[0], insert[1]); - pts.clear(); + int[] insert = findCpa(outer.getPoints(), w.getPoints()); + //if (insert[0] 0) + insertPoints(w, insert[0], insert[1]); + + // remove tags from inner way that are available in the outer way + if (outer.getTags() != null){ + for (Map.EntryString, 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 +81,39 @@
Re: [mkgmap-dev] [PATCH v1] sea polygons
I forgot to mention that you have to add --generate-sea if you want to have the sea polygon added. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH] multipolygons not showing
The attached patch (which changes just one line) fixes a problem with multipolygons sometimes not showing. Best wishes Christian Index: src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java === --- src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Revision 1115) +++ src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java (Arbeitskopie) @@ -54,8 +54,7 @@ if (w != null) { ListCoord pts = w.getPoints(); int[] insert = findCpa(outer.getPoints(), pts); - if (insert[0] 0) - insertPoints(pts, insert[0], insert[1]); + insertPoints(pts, insert[0], insert[1]); pts.clear(); } } ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] Large multipolygons not working?
Attached are two very simple osm files which show an island in a water polygon added by hand. Both are connected with a multipolygon relation. The difference between the to files is just the size of the island. The multipolygon is rendered correctly in the map resulting from test1.osm but not in the one resulting from test2.osm. This may be the result of a bug in the polygon splitting algorithm. This problem also occurs when I try to create a map of Corsica with the sea added by hand. Best wishes Christian ?xml version='1.0' encoding='UTF-8'? osm version='0.6' generator='JOSM' node id='-1' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='1.328294567641478' lon='-2.068920196861403' /node node id='-2' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='1.2926712474982742' lon='1.6687906730978546' /node node id='-3' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='-1.8775212325182145' lon='1.353633180364' /node node id='-4' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='-1.6850843200487289' lon='-2.384020195235887' /node node id='-5' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.09817788158542985' lon='-0.09731501778753923' /node node id='-6' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.15908462832580553' lon='-0.36597376731440057' /node node id='-7' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.009121482824366194' lon='-0.7390730091385' /node node id='-8' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='0.09444607202636145' lon='-0.23319609540542952' /node way id='-9' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' nd ref='-1' / nd ref='-2' / nd ref='-3' / nd ref='-4' / nd ref='-1' / tag k='natural' v='water' / /way way id='-10' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' nd ref='-8' / nd ref='-5' / nd ref='-6' / nd ref='-7' / nd ref='-8' / tag k='natural' v='coastline' / /way relation id='-11' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' member type='way' ref='-10' role='inner' / member type='way' ref='-9' role='outer' / tag k='type' v='multipolygon' / /relation /osm ?xml version='1.0' encoding='UTF-8'? osm version='0.6' generator='JOSM' node id='-1' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='0.31721049494176823' lon='-0.7563216170034055' /node node id='-2' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='0.31490228987762625' lon='0.14821422215850844' /node node id='-3' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='-0.4239988681629339' lon='0.05969268066070854' /node node id='-4' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' lat='-0.43199518239302503' lon='-0.7252156866682496' /node node id='-5' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.09817788158542985' lon='-0.09731501778753923' /node node id='-6' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.15908462832580553' lon='-0.36597376731440057' /node node id='-7' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='-0.009121482824366194' lon='-0.7390730091385' /node node id='-8' action='modify' timestamp='2009-07-29T20:37:59Z' visible='true' version='0' lat='0.09444607202636145' lon='-0.23319609540542952' /node way id='-9' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' nd ref='-8' / nd ref='-5' / nd ref='-6' / nd ref='-7' / nd ref='-8' / tag k='natural' v='coastline' / /way way id='-10' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' nd ref='-1' / nd ref='-2' / nd ref='-3' / nd ref='-4' / nd ref='-1' / tag k='natural' v='water' / /way relation id='-11' action='modify' timestamp='2009-07-29T20:29:27Z' visible='true' version='0' member type='way' ref='-9' role='inner' / member type='way' ref='-10' role='outer' / tag k='type' v='multipolygon' / /relation /osm ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v4] contours
Dear Clinton, Clinton Gladstone schrieb: I was able to successfully compile a small area using ASTER tiles. The resulting map looked correct. However, I was not able to compile a larger area. I tried Rheinland-Pfalz as downloaded from Geofabrik. If I understood the error message and the coding correctly, this is because Rheinland-Pfalz crosses the 1x1 ASTER tile boundaries: a map tile compiled with your patch apparently must lie completely in the 1x1 ASTER boundary. Is this correct? yes, corrently the code has this restriction. If so, this would be an unfortunate limitation. It would require maps to be split at exactly the 1 degree lat/long boundaries. Or is this something that can be eventually coded around? I suppose that this is less of an issue with the 5 degree CGIAR data. There are several possibilities to code around this: - generate the contours separately for each DEM-tile (easy to implement, but wouldn't be nice at the border) - load DEM data from more than one DEM tile (nice contours, but more complicated to implement) - write a little utility to paste GeoTIFF files together This is actually one of the reasons I added support for CGIAR. Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v4] contours
Nop schrieb: But now the real problem starts: How do I use the contour functions? You say: - Now the OSM styling engine is used to set labels, types resolution of the contour lines. How does this work? What rules are required? How can I distinguish between minor and major lines, I did find some code that adds some tags and then does some conversion, but there is nothing there for minor/medium/major contour lines. The code just sets contour=elevation and ele=level in meter, so you can do the rest with the style, e.g. like this: # Contours take their name from the elevation setting. contour=elevation ele ~ '\d*[02468]00' { name '${ele|conv:m=ft}'; } [0x22 resolution 18] contour=elevation ele ~ '\d+00' { name '${ele|conv:m=ft}'; } [0x21 resolution 20] contour=elevation { name '${ele|conv:m=ft}'; } [0x20 resolution 22] How would I apply styles with --dem-maxlevels? When the levels increase, so must the major contour distances, otherwise more and more lines will be major while minor lines disappear from the map. Ok, that's a valid point - I have no answer yet. I also do not want all minor contour lines to be tagged with an elevation, that clutters up the map. But I see no way to suppress this. I think there is a special character (like the one for the highway symbols) which hides the label unless you point on the line. I will have a look. Actually, with the styles above I have no problem with the labels cluttering the display. And eventually, how do I get the proper input data from CGIAR and ASTER? What does a proper input file look like that the contours function can process? I am only familiar with .hgt. The CGIAR files are GeoTIFF files which cover 5x5 degrees. You can get them from http://srtm.csi.cgiar.org/. The ASTER data (http://asterweb.jpl.nasa.gov/gdem.asp) also comes as GeoTIFF files (each covering 1x1 degrees as the SRTM HGT files). Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
Re: [mkgmap-dev] [PATCH v4] contours
Nop schrieb: Hi! Christian Gawron schrieb: This version of the patch (to be applied against rev. 1080) has a HGTDEM which reads SRTM .hgt files and an optional GeoTiffDEM which contains inner classes to read CGIAR and ASTER. I would like to try out this patch, but first I have to ask a very basic question: How do you apply this sort of patch? Sorry, I have no tool to generate a patch file which contains new files. You have to apply the contours_v4.patch with the patch command (patch contours_v4.patch) and copy the Java files by hand (HGTDEM.java to src/uk/me/parabola/mkgmap/reader/dem and GeoTiffDEM.java to src/uk/me/parabola/mkgmap/reader/dem/optional). Best wishes Christian ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev
[mkgmap-dev] [PATCH v4] contours
+ 1) + 1; -x = (x - 2) / x; -c = 1 - x; -c = (x * x / 4 + 1) / c; -d = (0.375 * x * x - 1) * x; -x = e * cy; -s = 1 - 2 * e; -s = sy * sy * 4 - 3) * s * cz * d / 6 - x) * d / 4 + cz) * sy * d + y) * c * R * semiMajorAxis; -return s; -} -} -final double LEPS = 1.0E-10; -if (Math.abs(x1 - x2) = LEPS Math.abs(y1 - y2) = LEPS) { -return 0; -} -if (Math.abs(y1) = LEPS Math.abs(y2) = LEPS) { -return Math.abs(x1 - x2) * semiMajorAxis; -} -throw new ArithmeticException(no convergence); -} private static class DEMMapDataSource extends MapperBasedMapDataSource implements LoadableMapDataSource { Index: src/uk/me/parabola/mkgmap/reader/MapperBasedMapDataSource.java === --- src/uk/me/parabola/mkgmap/reader/MapperBasedMapDataSource.java (revision 1080) +++ src/uk/me/parabola/mkgmap/reader/MapperBasedMapDataSource.java (working copy) @@ -27,12 +27,14 @@ import uk.me.parabola.imgfmt.app.Area; import uk.me.parabola.imgfmt.app.Coord; import uk.me.parabola.imgfmt.app.trergn.Overview; +import uk.me.parabola.mkgmap.general.LoadableMapDataSource; import uk.me.parabola.mkgmap.general.MapDataSource; import uk.me.parabola.mkgmap.general.MapDetails; import uk.me.parabola.mkgmap.general.MapLine; import uk.me.parabola.mkgmap.general.MapPoint; import uk.me.parabola.mkgmap.general.MapShape; import uk.me.parabola.mkgmap.general.RoadNetwork; +import uk.me.parabola.mkgmap.reader.dem.DEM; import uk.me.parabola.util.Configurable; import uk.me.parabola.util.EnhancedProperties; @@ -118,6 +120,11 @@ return configProps; } +public MapDetails getMapper() +{ + return mapper; + } + /** * We add the background polygons if the map is not transparent. */ @@ -146,5 +153,8 @@ // the overview section. mapper.addShape(background); } + if (getConfig().getProperty(contours, false)) { + DEM.createContours((LoadableMapDataSource) this, getConfig()); + } } } Index: src/uk/me/parabola/mkgmap/reader/osm/Way.java === --- src/uk/me/parabola/mkgmap/reader/osm/Way.java (revision 1080) +++ src/uk/me/parabola/mkgmap/reader/osm/Way.java (working copy) @@ -30,12 +30,18 @@ */ public class Way extends Element { - private final ListCoord points = new ArrayListCoord(); +private final ListCoord points; public Way(long id) { +points = new ArrayListCoord(); setId(id); } +public Way(long id, ListCoord points) { + this.points = points; + setId(id); + } + /** * Get the points that make up the way. We attempt to re-order the segments * and return a list of points that traces the route of the way. Index: build.xml === --- build.xml (revision 1080) +++ build.xml (working copy) @@ -72,7 +72,7 @@ include name=**/*.java / classpath refid=main/ !-- compilerarg value=-Xlint:unchecked/ -- - exclude name=**/reader/dem/*.java/ + exclude name=**/reader/dem/optional/*.java/ /javac /target /* * Copyright (C) 2009 Christian Gawron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License 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. * * * Author: Christian Gawron * Create date: 03-Jul-2009 */ package uk.me.parabola.mkgmap.reader.dem; import java.io.*; import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; import static java.nio.channels.FileChannel.MapMode.READ_ONLY; public class HGTDEM extends DEM { MappedByteBuffer buffer = null; public HGTDEM(String dataPath, double minLat, double minLon, double maxLat, double maxLon) { this.lat = (int) minLat; this.lon = (int) minLon; if (maxLat lat+1 || maxLon lon+1) throw new RuntimeException(Area too large (must not span more than one SRTM file)); String northSouth = lat 0 ? S : N; String eastWest = lon 0 ? E : W; String fileName = String.format(%s/%s%02d%s%03d.hgt, dataPath
[mkgmap-dev] [PATCH] Creating contour lines from DEM data
()); + } } } /* * Copyright (C) 2009 Christian Gawron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License 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. * * * Author: Christian Gawron * Create date: 03-Jul-2009 */ package uk.me.parabola.mkgmap.reader.dem; import java.io.*; import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; import java.util.Vector; import java.util.Locale; import com.sun.media.jai.codec.*; import javax.media.jai.*; import java.awt.image.renderable.ParameterBlock; import java.awt.image.Raster; import java.awt.image.DataBuffer; import uk.me.parabola.imgfmt.Utils; import uk.me.parabola.imgfmt.app.Area; import uk.me.parabola.imgfmt.app.Coord; import uk.me.parabola.mkgmap.general.MapDetails; import uk.me.parabola.mkgmap.general.MapPoint; import uk.me.parabola.mkgmap.general.MapLine; import uk.me.parabola.util.EnhancedProperties; import static java.nio.channels.FileChannel.MapMode.READ_ONLY; /** * Create contour lines using an algorithm similar to that described in * a href=http://mapcontext.com/autocarto/proceedings/auto-carto-5/pdf/an-adaptive-grid-contouring-algorithm.pdf;An Adaptive Grid Contouring Algorithm/a by Downing and Zoraster. */ public abstract class DEM { final static double epsilon = 1e-9; final static double delta = 1.5; final static int maxPoints=20; final static double minDist = 15; final static double maxDist = 21; final static double step = 0.01; final static double semiMajorAxis = 6378137.0; final static double inverseFlattening = 298.257223563; static int M=1200; static int N=M; static double res = 1.0/N; short values[] = null; int lat; int lon; abstract double ele(int x, int y); abstract void read(int minLon, int minLat, int maxLon, int maxLat); abstract void serializeCopyRight(Writer out) throws IOException; public static void createContours(MapDetails mapper, EnhancedProperties config) { Area bounds = mapper.getBounds(); double minLat = Utils.toDegrees(bounds.getMinLat()); double minLon = Utils.toDegrees(bounds.getMinLong()); double maxLat = Utils.toDegrees(bounds.getMaxLat()); double maxLon = Utils.toDegrees(bounds.getMaxLong()); System.out.printf(bounds: %f %f %f %f\n, minLat, minLon, maxLat, maxLon); DEM data; String demType = config.getProperty(dem-type, CGIAR); String dataPath; if (demType.equals(ASTER)) { dataPath = config.getProperty(dem-path, ASTER); data = new ASTERGeoTiff(dataPath, minLat, minLon, maxLat, maxLon); } else if (demType.equals(CGIAR)) { dataPath = config.getProperty(dem-path, CGIAR); data = new CGIARGeoTiff(dataPath, minLat, minLon, maxLat, maxLon); } else { dataPath = config.getProperty(dem-path, SRTM); data = new HGTDEM(dataPath, minLat, minLon, maxLat, maxLon); } Isolines lines = data.new Isolines(data, minLat, minLon, maxLat, maxLon); int increment = config.getProperty(dem-increment, 10); lines.addLevels(0, increment); for (Isolines.Isoline line : lines.isolines) { MapLine contour = new MapLine(); if ((line.level % 200) == 0) { contour.setType(0x22); // major contour contour.setMinResolution(18); } else if ((line.level % 50) == 0) { contour.setType(0x21); // major contour contour.setMinResolution(20); } else { contour.setType(0x20); // major contour contour.setMinResolution(22); } contour.setName(String.format(%.2f, line.level * 3.2808399)); contour.setPoints(line.points); mapper.addLine(contour); } } public static class HGTDEM extends DEM { MappedByteBuffer buffer = null; public HGTDEM(String dataPath, double minLat, double minLon, double maxLat, double maxLon) { this.lat = (int) minLat; this.lon = (int) minLon; if (maxLat lat+1 || maxLon lon+1) throw new RuntimeException(Area too large (must not span more than one SRTM file)); String northSouth = lat 0 ? S : N; String eastWest = lon 0 ? E : W; String fileName = String.format(%s/%s%02d%s%03d.hgt, dataPath, northSouth, lat 0 ? -lat : lat
Re: [mkgmap-dev] ASTER elevation data
Dear Marko, I already wrote a class to read SRTM data directly with mkgmap, i.e. without having to create the contours as separate (huge) files. Since I'm still testing it and I have to add some configuration stuff (path of directory containing data, distance between contour lines etc.), I have not posted it yet. It can already read the .hgt-format and the CGIAR GeoTIFFs (the latter requires java image io to be installed). Since the ASTER files come as GeoTIFFs, I think it will be easy for me to read them (I will only have to adjust the tile size from 5x5 degrees to 1x1). Best wishes Christian Marko Mäkelä schrieb: I came across this via Slashdot: http://asterweb.jpl.nasa.gov/ http://www.nasa.gov/home/hqnews/2009/jun/HQ_09-150_ASTER_Topographic_Map.html Quoting the press release above: Previously, the most complete topographic set of data publicly available was from NASA's Shuttle Radar Topography Mission. That mission mapped 80 percent of Earth's landmass, between 60 degrees north latitude and 57 degrees south. The new ASTER data expands coverage to 99 percent, from 83 degrees north latitude and 83 degrees south. Each elevation measurement point in the new data is 98 feet apart. This is good news for us North Europeans. The north limit of the SRTM is a few hundred meters north from my home, about 30 km north from the Helsinki coast. Can anyone who knows the topography business take a look at this data and write scripts for translating ASTER elevation data and OSM with mkgmap? At the end of the above press release, there are a few links that ought to be useful for us: For visualizations of the new ASTER topographic data, visit: http://www.nasa.gov/topics/earth/features/20090629.html Data users can download the ASTER global digital elevation model at: https://wist.echo.nasa.gov/~wist/api/imswelcome and http://www.gdem.aster.ersdac.or.jp Best regards, Marko ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev ___ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev