Codebase list mkgmap / df97aff
New upstream version 0.0.0+svn4680 Bas Couwenberg 2 years ago
60 changed file(s) with 556 addition(s) and 338 deletion(s). Raw diff Collapse all Expand all
306306 <mkdir dir="test/resources/in/osm"/>
307307 <mkdir dir="test/resources/in/mp"/>
308308 <mkdir dir="test/resources/in/img"/>
309 <get src="http://www.mkgmap.org.uk/testinput/osm/lon1.osm.gz"
309 <get src="https://www.mkgmap.org.uk/testinput/osm/lon1.osm.gz"
310310 dest="test/resources/in/osm/lon1.osm.gz" usetimestamp="true"
311311 ignoreerrors="true"/>
312 <get src="http://www.mkgmap.org.uk/testinput/osm/uk-test-1.osm.gz"
312 <get src="https://www.mkgmap.org.uk/testinput/osm/uk-test-1.osm.gz"
313313 dest="test/resources/in/osm/uk-test-1.osm.gz" usetimestamp="true"
314314 ignoreerrors="true"/>
315 <get src="http://www.mkgmap.org.uk/testinput/osm/uk-test-2.osm.gz"
315 <get src="https://www.mkgmap.org.uk/testinput/osm/uk-test-2.osm.gz"
316316 dest="test/resources/in/osm/uk-test-2.osm.gz" usetimestamp="true"
317317 ignoreerrors="true"/>
318 <get src="http://www.mkgmap.org.uk/testinput/osm/is-in-samples.osm"
318 <get src="https://www.mkgmap.org.uk/testinput/osm/is-in-samples.osm"
319319 dest="test/resources/in/osm/is-in-samples.osm" usetimestamp="true"
320320 ignoreerrors="true"/>
321 <get src="http://www.mkgmap.org.uk/testinput/mp/test1.mp"
321 <get src="https://www.mkgmap.org.uk/testinput/mp/test1.mp"
322322 dest="test/resources/in/mp/test1.mp" usetimestamp="true"
323323 ignoreerrors="true"/>
324 <get src="http://www.mkgmap.org.uk/testinput/img/63240001.img"
324 <get src="https://www.mkgmap.org.uk/testinput/img/63240001.img"
325325 dest="test/resources/in/img/63240001.img" usetimestamp="true"
326326 ignoreerrors="true"/>
327 <get src="http://www.mkgmap.org.uk/testinput/img/63240002.img"
327 <get src="https://www.mkgmap.org.uk/testinput/img/63240002.img"
328328 dest="test/resources/in/img/63240002.img" usetimestamp="true"
329329 ignoreerrors="true"/>
330 <get src="http://www.mkgmap.org.uk/testinput/img/63240003.img"
330 <get src="https://www.mkgmap.org.uk/testinput/img/63240003.img"
331331 dest="test/resources/in/img/63240003.img" usetimestamp="true"
332332 ignoreerrors="true"/>
333 <get src="http://www.mkgmap.org.uk/testinput/hgt/N00W090.hgt.zip"
333 <get src="https://www.mkgmap.org.uk/testinput/hgt/N00W090.hgt.zip"
334334 dest="test/resources/in/hgt/N00W090.hgt.zip" usetimestamp="true"
335335 ignoreerrors="true"/>
336 <get src="http://www.mkgmap.org.uk/testinput/hgt/N00W091.hgt.zip"
336 <get src="https://www.mkgmap.org.uk/testinput/hgt/N00W091.hgt.zip"
337337 dest="test/resources/in/hgt/N00W091.hgt.zip" usetimestamp="true"
338338 ignoreerrors="true"/>
339 <get src="http://www.mkgmap.org.uk/testinput/hgt/S01W090.hgt.zip"
339 <get src="https://www.mkgmap.org.uk/testinput/hgt/S01W090.hgt.zip"
340340 dest="test/resources/in/hgt/S01W090.hgt.zip" usetimestamp="true"
341341 ignoreerrors="true"/>
342 <get src="http://www.mkgmap.org.uk/testinput/hgt/S01W091.hgt.zip"
342 <get src="https://www.mkgmap.org.uk/testinput/hgt/S01W091.hgt.zip"
343343 dest="test/resources/in/hgt/S01W091.hgt.zip" usetimestamp="true"
344344 ignoreerrors="true"/>
345 <get src="http://www.mkgmap.org.uk/testinput/hgt/S02W090.hgt.zip"
345 <get src="https://www.mkgmap.org.uk/testinput/hgt/S02W090.hgt.zip"
346346 dest="test/resources/in/hgt/S02W090.hgt.zip" usetimestamp="true"
347347 ignoreerrors="true"/>
348 <get src="http://www.mkgmap.org.uk/testinput/hgt/S02W091.hgt.zip"
348 <get src="https://www.mkgmap.org.uk/testinput/hgt/S02W091.hgt.zip"
349349 dest="test/resources/in/hgt/S02W091.hgt.zip" usetimestamp="true"
350350 ignoreerrors="true"/>
351351 </target>
1111 <pre>
1212 # The default level FINE, WARNING, INFO, SEVERE
1313 .level=SEVERE
14 #handlers: java.util.logging.ConsoleHandler
1514 handlers: java.util.logging.FileHandler java.util.logging.ConsoleHandler
1615 # package or class name with .level appended and then the level
1716 uk.me.parabola.imgfmt.level=INFO
3837 java.util.logging.FileHandler.append=false
3938 </pre>
4039
41 The above example enables certain informational messages and sends them to a
42 log file, with warning and error messages being also sent to stdout.
40 The above example enables certain informational messages and uses FileHandler to send
41 them to a log file, with warning and error messages being also sent to stderr via
42 ConsoleHandler.
43
44 Mkgmap provides UsefulFormatter to help format messages, but you can use the
45 standard Java SimpleFormatter if you prefer.
46
47 In addition to the standard Java levels, mkgmap uses three additional levels
48 DIAGNOSTIC (1100), ECHO (1200) and OVERRIDE (1300) for messages from its
49 diagnostic options, echo/echotags style compiler actions and to display
50 mkgmap startup and completion information. You can use the numeric values but
51 not the names to specify these levels in a logging configuration file.
4352
4453 Further information can be found at
4554 [https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html]
4655
56 If you see messages that contain non-ASCII characters which are not displaying
57 properly in the console, you may need to use the Java -Dfile.encoding=<codepage>
58 option and/or precede the mkgmap command line with a chcp command to make
59 sure that the Java environment has the same code page as the shell it is
60 being run from. This is especially likely on the Windows platform where the
61 Java environment uses the Windows default code page, but the Windows command
62 shell normally uses a different code page.
616616
617617 === Diagnostic options ===
618618
619 Messages produced by the diagnostic options are directed to stderr when no logging
620 configuration file is in use. When using a logging configuration file, they are logged
621 with custom level DIAGNOSTIC (1100).
622
619623 ;--check-roundabouts
620624 : Check that roundabouts have the expected direction (clockwise
621625 when vehicles drive on the left). Roundabouts that are complete
636640 problems. Default value is 0 (disabled) because it's not a
637641 completely reliable heuristic.
638642
639 ;--check-routing-island-len=INTEGER
643 ;--report-routing-islands
640644 : Routing islands are small road networks which are not connected to other
641645 roads. A typical case is a footway that is not connected to the main road
642646 network, or a small set of ways on the inner courtyard of a large building.
643647 : These islands can cause problems if you try to calculate a route and the GPS
644648 selects a point on the island as a start or end. It will fail to calculate the
645649 route even if a major road is only a few steps away. If this option is
646 specified, then mkgmap will detect these islands. If the value is set to zero,
647 mkgmap will simply report the islands (you will need to set
648 uk.me.parabola.imgfmt.app.net.RoadNetwork.level=INFO to activate logging of
649 the message). If the value is greater than zero, mkgmap will mark islands with
650 a total length less than the specified value in metres as not routable.
651 Reasonable values are 500 or higher. The default is for the check to not take
652 place. If any of the roads forming the island touches a tile boundary or a
653 country border the island is ignored, as it may be connected to other roads in
654 a different tile.
655 : See also option --add-boundary-nodes-at-admin-boundaries.
656 : This option seems to cause routing problems in BaseCamp.
650 specified, then mkgmap will report these islands.
651 : See also --max-routing-island-len.
657652
658653 ;--report-similar-arcs
659654 : Issue a warning when more than one arc connects two nodes and
660655 the ways that the arcs are derived from contain identical
661 points. It doesn't make sense to use this option at the same
662 time as using the cycleway creating options.
663
664 ;--report-dead-ends=LEVEL
665 : Set the dead end road warning level. The value of LEVEL (which
666 defaults to 1 if this option is not specified) determines
656 points.
657
658 ;--report-dead-ends[=LEVEL]
659 : Set the dead end road warning level. The value of LEVEL determines
667660 those roads to report:
668 :* 0 = none
669 :* 1 = report on connected one-way roads that go nowhere
661 :* 0 = none (the default)
662 :* 1 = report on connected one-way roads that go nowhere (default if no LEVEL specified)
670663 :* 2 = also report on individual one-way roads that go nowhere.
671664
672665 ;--dead-ends[=key[=value]][,key[=value]...]
980973 The tag mkgmap:drawLevel can be used to override the
981974 natural area of a polygon, so forcing changes to the rendering order.
982975
976 ;--max-routing-island-len=integer
977 : Routing islands are small road networks which are not connected to other
978 roads. A typical case is a footway that is not connected to the main road
979 network, or a small set of ways on the inner courtyard of a large building.
980 : These islands can cause problems if you try to calculate a route and the GPS
981 selects a point on the island as a start or end. It will fail to calculate the
982 route even if a major road is only a few steps away. If a positive value is
983 specified, then mkgmap will mark islands with a total length less than the
984 specified value in metres as not routable.
985 Reasonable values are 500 or higher. The default is to not to mark any islands
986 as unroutable. If any of the roads forming the island touches a tile boundary or a
987 country border the island is ignored, as it may be connected to other roads in
988 a different tile.
989 : See also options --add-boundary-nodes-at-admin-boundaries and
990 --report-routing-islands.
991 : This option seems to cause routing problems in BaseCamp.
992
983993 === Deprecated and Obsolete Options ===
994
995 ;--check-routing-island-len=integer
996 : Deprecated; use --report-routing-islands and --max-routing-island-len instead.
997 Translated to --report-routing-islands if info level logging is enabled, plus
998 --max-routing-island-len=integer.
984999
9851000 ;--drive-on-left
9861001 ;--drive-on-right
987 : Deprecated; use drive-on instead.
988 The options are translated to drive-on=left|right.
1002 : Deprecated; use --drive-on instead.
1003 The options are translated to --drive-on=left|right.
9891004
9901005 ;--make-all-cycleways
9911006 : Deprecated; use --make-opposite-cycleways instead. Former meaning:
524524 that the first member is the start of the route.
525525
526526 === echo ===
527 The echo action prints the element id plus a text to standard error. This can be
528 used for quality checks and debugging purposes.
527 The echo action prints the element id plus a text to stderr or to where directed by
528 a logging configuration file. This can be used for quality checks and debugging
529 purposes. When using a logging configuration file, the messages are logged
530 with custom level ECHO (1200).
529531 [source]
530532 highway=motorway_link & oneway!=* { echo "motorway_link without oneway tag" }
531533
532534 === echotags ===
533 The echotags action prints the element id, all tags and values plus a text to standard error.
534 This can be used for style debugging purposes.
535 The echotags action prints the element id, all tags and values plus a text to stderr
536 or to where directed by a logging configuration file. This can be used for style
537 debugging purposes. When using a logging configuration file, the messages are
538 logged with custom level ECHO (1200).
535539 [source]
536540 highway=living_street { echotags "This is a living_street" }
537541
00 <ivysettings>
1 <property name="mkgmap.ivy.repo" value="http://ivy.mkgmap.org.uk/repo" />
1 <property name="mkgmap.ivy.repo" value="https://ivy.mkgmap.org.uk/repo" />
22 <settings defaultResolver="custom" />
33
44 <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
2222 <ibiblio name="geotools-resolver" m2compatible="true" root="https://repo.osgeo.org/repository/release/" />
2323
2424 <url name="spring-resolver" >
25 <ivy pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
26 <artifact pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
25 <ivy pattern="https://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
26 <artifact pattern="https://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
2727 </url>
2828
2929 </resolvers>
607607
608608 === Diagnostic options ===
609609
610 Messages produced by the diagnostic options are directed to stderr when no
611 logging configuration file is in use. When using a logging configuration file,
612 they are logged with custom level DIAGNOSTIC (1100).
613
610614 --check-roundabouts
611615 Check that roundabouts have the expected direction (clockwise when vehicles
612616 drive on the left). Roundabouts that are complete loops and have the wrong
626630 problems. Default value is 0 (disabled) because it's not a completely
627631 reliable heuristic.
628632
629 --check-routing-island-len=INTEGER
633 --report-routing-islands
630634 Routing islands are small road networks which are not connected to other
631635 roads. A typical case is a footway that is not connected to the main road
632636 network, or a small set of ways on the inner courtyard of a large building.
633637 These islands can cause problems if you try to calculate a route and the
634638 GPS selects a point on the island as a start or end. It will fail to
635639 calculate the route even if a major road is only a few steps away. If this
636 option is specified, then mkgmap will detect these islands. If the value is
637 set to zero, mkgmap will simply report the islands (you will need to set
638 uk.me.parabola.imgfmt.app.net.RoadNetwork.level=INFO to activate logging of
639 the message). If the value is greater than zero, mkgmap will mark islands
640 with a total length less than the specified value in metres as not
641 routable. Reasonable values are 500 or higher. The default is for the check
642 to not take place. If any of the roads forming the island touches a tile
643 boundary or a country border the island is ignored, as it may be connected
644 to other roads in a different tile.
645 See also option --add-boundary-nodes-at-admin-boundaries.
646 This option seems to cause routing problems in BaseCamp.
640 option is specified, then mkgmap will report these islands.
641 See also --max-routing-island-len.
647642
648643 --report-similar-arcs
649644 Issue a warning when more than one arc connects two nodes and the ways that
650 the arcs are derived from contain identical points. It doesn't make sense
651 to use this option at the same time as using the cycleway creating options.
652
653 --report-dead-ends=LEVEL
654 Set the dead end road warning level. The value of LEVEL (which defaults to
655 1 if this option is not specified) determines those roads to report:
656 * 0 = none
657 * 1 = report on connected one-way roads that go nowhere
645 the arcs are derived from contain identical points.
646
647 --report-dead-ends[=LEVEL]
648 Set the dead end road warning level. The value of LEVEL determines those
649 roads to report:
650 * 0 = none (the default)
651 * 1 = report on connected one-way roads that go nowhere (default if no
652 LEVEL specified)
658653 * 2 = also report on individual one-way roads that go nowhere.
659654
660655 --dead-ends[=key[=value]][,key[=value]...]
964959 The tag mkgmap:drawLevel can be used to override the natural area of a
965960 polygon, so forcing changes to the rendering order.
966961
962 --max-routing-island-len=integer
963 Routing islands are small road networks which are not connected to other
964 roads. A typical case is a footway that is not connected to the main road
965 network, or a small set of ways on the inner courtyard of a large building.
966 These islands can cause problems if you try to calculate a route and the
967 GPS selects a point on the island as a start or end. It will fail to
968 calculate the route even if a major road is only a few steps away. If a
969 positive value is specified, then mkgmap will mark islands with a total
970 length less than the specified value in metres as not routable. Reasonable
971 values are 500 or higher. The default is to not to mark any islands as
972 unroutable. If any of the roads forming the island touches a tile boundary
973 or a country border the island is ignored, as it may be connected to other
974 roads in a different tile.
975 See also options --add-boundary-nodes-at-admin-boundaries and
976 --report-routing-islands.
977 This option seems to cause routing problems in BaseCamp.
978
967979 === Deprecated and Obsolete Options ===
980
981 --check-routing-island-len=integer
982 Deprecated; use --report-routing-islands and --max-routing-island-len
983 instead. Translated to --report-routing-islands if info level logging is
984 enabled, plus --max-routing-island-len=integer.
968985
969986 --drive-on-left
970987 --drive-on-right
971 Deprecated; use drive-on instead. The options are translated to
972 drive-on=left|right.
988 Deprecated; use --drive-on instead. The options are translated to
989 --drive-on=left|right.
973990
974991 --make-all-cycleways
975992 Deprecated; use --make-opposite-cycleways instead. Former meaning: Turn on
Binary diff not shown
0 # HGT files (SRTM) is not avalaible for areas in the ocean.
0 # HGT files (SRTM) are not avalaible for areas in the ocean.
11 # This is a list of all hgt files
22 # to compile it use
33 # java -cp mkgmap.jar uk.me.parabola.mkgmap.reader.hgt.HGTList compile known-hgt.txt
1039110391 N60E154
1039210392 N60E155
1039310393 N60E156
10394 N60E157
1039510394 N60E159
1039610395 N60E160
1039710396 N60E161
1166811667 N64W174
1166911668 N64W175
1167011669 N64W176
11671 N64W180
1167211670 N65E010
1167311671 N65E011
1167411672 N65E012
1362613624 N72E054
1362713625 N72E055
1362813626 N72E056
13629 N72E057
1363013627 N72E068
1363113628 N72E069
1363213629 N72E070
1440214399 N77E025
1440314400 N77E067
1440414401 N77E082
14405 N77E083
1440614402 N77E088
1440714403 N77E089
1440814404 N77E090
0 svn.version: 4620
1 build.timestamp: 2021-03-28T10:11:16+0100
0 svn.version: 4680
1 build.timestamp: 2021-04-26T19:34:28+0100
3030
3131 import uk.me.parabola.imgfmt.app.Coord;
3232 import uk.me.parabola.imgfmt.app.ImgFileWriter;
33 import uk.me.parabola.log.Logger;
3334 /**
3435 * Some miscellaneous functions that are used within the .img code.
3536 *
188189 try {
189190 f.close();
190191 } catch (IOException e) {
191 e.printStackTrace();
192 Logger.defaultLogger.error("Error closing file", e);
192193 }
193194 }
194195 }
2323 import uk.me.parabola.imgfmt.Sized;
2424 import uk.me.parabola.imgfmt.fs.ImgChannel;
2525 import uk.me.parabola.imgfmt.sys.FileLink;
26 import uk.me.parabola.log.Logger;
2627
2728 /**
2829 * Write img file data to a temporary file. On a call to sync() the data
6970 channel.transferTo(0, channel.size(), outputChan);
7071 } finally {
7172 if (!tmpFile.delete())
72 System.err.println("could not delete temporary file " + tmpFile.getPath());
73 Logger.defaultLogger.error("could not delete temporary file " + tmpFile.getPath());
7374 }
7475 }
7576
2828 import uk.me.parabola.imgfmt.app.labelenc.DecodedText;
2929 import uk.me.parabola.imgfmt.app.trergn.Subdivision;
3030 import uk.me.parabola.imgfmt.fs.ImgChannel;
31 import uk.me.parabola.log.Logger;
3132
3233 import static uk.me.parabola.imgfmt.app.Label.NULL_LABEL;
3334
443444 }
444445
445446 if (hasTides) {
446 System.out.println("Map has tide prediction, please implement!");
447 Logger.defaultLogger.warn("Map has tide prediction, please implement!");
447448 }
448449
449450 pois.put(poiOffset, poi);
2727 import uk.me.parabola.imgfmt.app.srt.Sort;
2828 import uk.me.parabola.imgfmt.app.trergn.Point;
2929 import uk.me.parabola.imgfmt.fs.ImgChannel;
30 import uk.me.parabola.log.Logger;
3031
3132 /**
3233 * The MDR file. This is embedded into a .img file, either its own
149150 Sort sort = mdrHeader.getSort();
150151
151152 if (sort.getCodepage() != codePage)
152 System.err.println("WARNING: input files have different code pages");
153 Logger.defaultLogger.warn("Input files have different code pages");
153154 }
154155
155156 public Mdr14Record addCountry(Country country) {
00 package uk.me.parabola.imgfmt.app.net;
1
2 import uk.me.parabola.log.Logger;
13
24 /**
35 * The number style down one side of a side of a road.
6264 case 'O': return ODD;
6365 case 'B': return BOTH;
6466 case '0':
65 System.err.println("zero instead of capital O in number spec");
67 Logger.defaultLogger.error("zero instead of capital O in number spec");
6668 return ODD;
6769 default: return NONE;
6870 }
6060 private int maxFlareLengthRatio ;
6161 private boolean reportSimilarArcs;
6262 private boolean routable;
63
64 private long maxSumRoadLenghts;
63 private boolean reportRoutingIslands;
64 private long maxSumRoadLengths;
6565 /** for route island search */
6666 private int visitId;
6767
7070 checkRoundaboutFlares = props.getProperty("check-roundabout-flares", false);
7171 maxFlareLengthRatio = props.getProperty("max-flare-length-ratio", 0);
7272 reportSimilarArcs = props.getProperty("report-similar-arcs", false);
73 maxSumRoadLenghts = props.getProperty("check-routing-island-len", -1);
73 int checkRoutingIslandLengths = props.getProperty("check-routing-island-len", -1);
74 if (checkRoutingIslandLengths >= 0) {
75 Logger.defaultLogger.warn("The --check-routing-island-len option is deprecated. Please use --report-routing-islands and/or max-routing-island-len");
76 maxSumRoadLengths = checkRoutingIslandLengths;
77 reportRoutingIslands = log.isInfoEnabled();
78 }
79 maxSumRoadLengths = props.getProperty("max-routing-island-len", -1);
80 reportRoutingIslands = props.getProperty("report-routing-islands", false);
7481 routable = props.containsKey("route");
7582 angleChecker.config(props);
7683 }
302309 * report routing islands and maybe remove them from NOD.
303310 */
304311 private void checkRoutingIslands() {
305 if (maxSumRoadLenghts < 0)
312 if (maxSumRoadLengths <= 0 && !reportRoutingIslands)
306313 return; // island check is disabled
314
307315 long t1 = System.currentTimeMillis();
308316
309317 // calculate all islands
313321 if (!islands.isEmpty()) {
314322 analyseIslands(islands);
315323 }
316 if (maxSumRoadLenghts > 0) {
324 if (maxSumRoadLengths > 0) {
317325 long t3 = System.currentTimeMillis();
318326 log.info("routing island removal took", (t3 - t2), "ms");
319327 }
349357 for (List<RouteNode> island : islands) {
350358 // compute size of island as sum of road lengths
351359 Set<RoadDef> visitedRoads = new HashSet<>();
352 long sumOfRoadLenghts = calcIslandSize(island, nodeToRoadMap, visitedRoads);
353 log.info("Routing island at", island.get(0).getCoord().toDegreeString(), "with", island.size(),
354 "routing node(s) and total length of", sumOfRoadLenghts, "m");
355 if (sumOfRoadLenghts < maxSumRoadLenghts) {
360 long sumOfRoadLengths = calcIslandSize(island, nodeToRoadMap, visitedRoads);
361 if (reportRoutingIslands)
362 log.diagnostic("Routing island " + visitedRoads.iterator().next() + " at " + island.get(0).getCoord().toDegreeString() + " with " + island.size() +
363 " routing node(s) and total length of " + sumOfRoadLengths + "m");
364 if (sumOfRoadLengths < maxSumRoadLengths) {
356365 // set discarded flag for all nodes of the island
357366 island.forEach(RouteNode::discard);
358367 visitedRoads.forEach(rd -> rd.skipAddToNOD(true));
320320 } else {
321321 writer.put(directionFromDegrees(initialHeading));
322322 }
323 } else {
324 // System.out.println("skipped writing of initial dir");
325323 }
326324 if (haveCurve) {
327325 int[] curvedat = encodeCurve();
387387 // non roundabout highway overlaps roundabout
388388 nonRoundaboutArcs.remove(ra1);
389389 if(!ra.getRoadDef().messagePreviouslyIssued("roundabout forks/overlaps"))
390 log.warn("Highway",ra1.getRoadDef(), "overlaps roundabout", ra.getRoadDef(), "at",coord.toOSMURL());
390 log.diagnostic("Highway " + ra1.getRoadDef() + " overlaps roundabout " + ra.getRoadDef() + " at " + coord.toOSMURL());
391391 break;
392392 }
393393 }
460460
461461 RouteArc roundaboutArc = roundaboutArcs.get(0);
462462 if (arcs.size() > 1 && roundaboutArcs.size() == 1)
463 log.warn("Roundabout",roundaboutArc.getRoadDef(),roundaboutArc.isForward() ? "starts at" : "ends at", coord.toOSMURL());
463 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + (roundaboutArc.isForward() ? " starts at " : " ends at ") + coord.toOSMURL());
464464 if (countNonRoundaboutRoads > 1)
465 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to more than one road at",coord.toOSMURL());
465 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to more than one road at " + coord.toOSMURL());
466466 else if (countNonRoundaboutRoads == 1) {
467467 if (countNonRoundaboutOtherHighways > 0) {
468468 if (countHighwaysInsideRoundabout > 0)
469 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to a road",countNonRoundaboutOtherHighways,"other highway(s) and",countHighwaysInsideRoundabout,"highways inside the roundabout at",coord.toOSMURL());
469 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to a road, " + countNonRoundaboutOtherHighways + " other highway(s) and " + countHighwaysInsideRoundabout + " highways inside the roundabout at " + coord.toOSMURL());
470470 else
471 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to a road and",countNonRoundaboutOtherHighways,"other highway(s) at",coord.toOSMURL());
471 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to a road and " + countNonRoundaboutOtherHighways + " other highway(s) at " + coord.toOSMURL());
472472 }
473473 else if (countHighwaysInsideRoundabout > 0)
474 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to a road and",countHighwaysInsideRoundabout,"highway(s) inside the roundabout at",coord.toOSMURL());
474 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to a road and " + countHighwaysInsideRoundabout + " highway(s) inside the roundabout at " + coord.toOSMURL());
475475 }
476476 else if (countNonRoundaboutOtherHighways > 0) {
477477 if (countHighwaysInsideRoundabout > 0)
478 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to",countNonRoundaboutOtherHighways,"highway(s) and",countHighwaysInsideRoundabout,"inside the roundabout at",coord.toOSMURL());
478 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to " + countNonRoundaboutOtherHighways+ " highway(s) and " + countHighwaysInsideRoundabout + " inside the roundabout at " + coord.toOSMURL());
479479 else if (countNonRoundaboutOtherHighways > 1)
480 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to",countNonRoundaboutOtherHighways,"highways at",coord.toOSMURL());
480 log.diagnostic("Roundabout " + roundaboutArc.getRoadDef() + " is connected to " + countNonRoundaboutOtherHighways + " highways at " + coord.toOSMURL());
481481 }
482482 else if (countHighwaysInsideRoundabout > 1)
483 log.warn("Roundabout",roundaboutArc.getRoadDef(),"is connected to",countHighwaysInsideRoundabout,"highways inside the roundabout at",coord.toOSMURL());
483 log.diagnostic("Roundabout " +roundaboutArc.getRoadDef() + " is connected to " + countHighwaysInsideRoundabout + " highways inside the roundabout at " + coord.toOSMURL());
484484 if(roundaboutArcs.size() > 2) {
485485 for(RouteArc fa : roundaboutArcs) {
486486 if(fa.isForward()) {
491491 ((fb.isForward() && fb.getDest() == fa.getDest()) ||
492492 (!fb.isForward() && fb.getSource() == fa.getDest()))) {
493493 if(!rd.messagePreviouslyIssued("roundabout forks/overlaps")) {
494 log.warn("Roundabout " + rd + " overlaps " + fb.getRoadDef() + " at " + coord.toOSMURL());
494 log.diagnostic("Roundabout " + rd + " overlaps " + fb.getRoadDef() + " at " + coord.toOSMURL());
495495 }
496496 }
497497 else if (fb.isForward()
498498 && !rd.messagePreviouslyIssued("roundabout forks/overlaps")) {
499 log.warn("Roundabout " + rd + " forks at " + coord.toOSMURL());
499 log.diagnostic("Roundabout " + rd + " forks at " + coord.toOSMURL());
500500 }
501501 }
502502 }
640640
641641 // only issue one warning per flare
642642 if(!fa.isForward())
643 log.warn("Outgoing roundabout flare road " + fa.getRoadDef() + " points in wrong direction? " + fa.getSource().coord.toOSMURL());
643 log.diagnostic("Outgoing roundabout flare road " + fa.getRoadDef() + " points in wrong direction? " + fa.getSource().coord.toOSMURL());
644644 else if(fb.isForward())
645 log.warn("Incoming roundabout flare road " + fb.getRoadDef() + " points in wrong direction? " + fb.getSource().coord.toOSMURL());
645 log.diagnostic("Incoming roundabout flare road " + fb.getRoadDef() + " points in wrong direction? " + fb.getSource().coord.toOSMURL());
646646 else if(!fa.getRoadDef().isOneway())
647 log.warn("Outgoing roundabout flare road " + fa.getRoadDef() + " is not oneway? " + fa.getSource().coord.toOSMURL());
647 log.diagnostic("Outgoing roundabout flare road " + fa.getRoadDef() + " is not oneway? " + fa.getSource().coord.toOSMURL());
648648
649649 else if(!fb.getRoadDef().isOneway())
650 log.warn("Incoming roundabout flare road " + fb.getRoadDef() + " is not oneway? " + fb.getDest().coord.toOSMURL());
650 log.diagnostic("Incoming roundabout flare road " + fb.getRoadDef() + " is not oneway? " + fb.getDest().coord.toOSMURL());
651651 else {
652652 // check that the flare road arcs are not
653653 // part of a longer way
654654 for(RouteArc a : fa.getDest().arcs) {
655655 if(a.isDirect() && a.getDest() != this && a.getDest() != nb) {
656656 if(a.getRoadDef() == fa.getRoadDef())
657 log.warn("Outgoing roundabout flare road " + fb.getRoadDef() + " does not finish at flare? " + fa.getDest().coord.toOSMURL());
657 log.diagnostic("Outgoing roundabout flare road " + fb.getRoadDef() + " does not finish at flare? " + fa.getDest().coord.toOSMURL());
658658 else if(a.getRoadDef() == fb.getRoadDef())
659 log.warn("Incoming roundabout flare road " + fb.getRoadDef() + " does not start at flare? " + fb.getDest().coord.toOSMURL());
659 log.diagnostic("Incoming roundabout flare road " + fb.getRoadDef() + " does not start at flare? " + fb.getDest().coord.toOSMURL());
660660 }
661661 }
662662 }
669669 public void reportSimilarArcs() {
670670 for(int i = 0; i < arcs.size(); ++i) {
671671 RouteArc arci = arcs.get(i);
672 if (!arci.isDirect())
672 RoadDef rdi = arci.getRoadDef();
673 if (!arci.isDirect() || rdi.isSynthesised())
673674 continue;
674675 for(int j = i + 1; j < arcs.size(); ++j) {
675676 RouteArc arcj = arcs.get(j);
676 if (!arcj.isDirect())
677 RoadDef rdj = arcj.getRoadDef();
678 if (!arcj.isDirect() || rdj.isSynthesised())
677679 continue;
678680 if(arci.getDest() == arcj.getDest() &&
679681 arci.getLength() == arcj.getLength() &&
680 arci.getPointsHash() == arcj.getPointsHash()) {
681 log.warn("Similar arcs (" + arci.getRoadDef() + " and " + arcj.getRoadDef() + ") from " + coord.toOSMURL());
682 arci.getPointsHash() == arcj.getPointsHash() &&
683 !rdi.messagePreviouslyIssued("Similar arcs")) {
684 log.diagnostic("Similar arcs " + rdi + " and " + rdj + " found at " + coord.toOSMURL());
682685 }
683686 }
684687 }
11141114 range = Double.parseDouble(parts[1]);
11151115 if(parts.length > 2)
11161116 angle = Double.parseDouble(parts[2]);
1117
1118 //System.err.println("light = " + this);
11191117 }
11201118
11211119 public String toString() {
7474 BitWriter bsBest = bsSimple;
7575 int xBestBase = xBase;
7676 int yBestBase = yBase;
77 if (xBase > 0 || yBase > 0 && log.isDebugEnabled()) {
77 if ((xBase > 0 || yBase > 0) && log.isDebugEnabled()) {
7878 log.debug("start opt:", xBase, yBase, xSameSign, xSignNegative, ySameSign, ySignNegative);
7979 }
8080 if (xBase > 0){
8181 int notBetter = 0;
82 int xTestBase = xBase-1;
8283 boolean xSameSignBak = xSameSign;
83 xSameSign = false;
84 for (int xTestBase = xBase-1; xTestBase >= 0; xTestBase--){
84 if (xSameSign) {
85 xSameSign = false;
86 --xTestBase; // changing to signed will add a bit to each node so xBase-1 can't give saving
87 }
88 for ( ; xTestBase >= 0; xTestBase--){
8589 BitWriter bstest = makeBitStream(minPointsRequired, xTestBase, yBase);
86 if (bstest.getBitPosition() >= bsBest.getBitPosition() ){
90 if (bstest.getBitPosition() >= bsBest.getBitPosition()){
8791 if (++notBetter >= 2)
8892 break; // give up
8993 } else {
96100 }
97101 if (yBase > 0){
98102 int notBetter = 0;
103 int yTestBase = yBase-1;
99104 boolean ySameSignBak = ySameSign;
100 ySameSign = false;
101 for (int yTestBase = yBase-1; yTestBase >= 0; yTestBase--){
105 if (ySameSign) {
106 ySameSign = false;
107 --yTestBase; // changing to signed will add a bit to each node so yBase-1 can't give saving
108 }
109 for ( ; yTestBase >= 0; yTestBase--){
102110 BitWriter bstest = makeBitStream(minPointsRequired, xBestBase, yTestBase);
103111 if (bstest.getBitPosition() >= bsBest.getBitPosition()){
104112 if (++notBetter >= 2)
111119 }
112120 ySameSign = ySameSignBak;
113121 }
114 if (xBase != xBestBase || yBestBase != yBase && log.isInfoEnabled()) {
122 if ((xBase != xBestBase || yBestBase != yBase) && log.isInfoEnabled()) {
115123 if (bsSimple.getLength() > bsBest.getLength())
116124 log.info("optimizer reduced bit stream byte length from",bsSimple.getLength(),"->",bsBest.getLength(),"(" + (bsSimple.getLength()-bsBest.getLength()), "byte(s)) for",polyline.getClass().getSimpleName(),"with",polyline.getPoints().size(),"points");
117125 else
251259 // OK go through the points
252260 int lastLat = 0;
253261 int lastLong = 0;
254 int minDx = Integer.MAX_VALUE, maxDx = 0;
255 int minDy = Integer.MAX_VALUE, maxDy = 0;
262 int minDx = 0, maxDx = 0;
263 int minDy = 0, maxDy = 0;
256264 // index of first point in a series of identical coords (after shift)
257265 int firstsame = 0;
258266 for (int i = 0; i < numPointsToUse; i++) {
135135 } catch (CharacterCodingException ignore) {
136136 //ignore.printStackTrace();
137137 String name = encoder.charset().name();
138 //System.out.println("cs " + name);
139138 log.warn("Cannot represent String", tl.getText(), "for language", tl.getLang(), "in CodePage", name);
140139 //throw new TypLabelException(name);
141140 }
2121 import java.nio.channels.WritableByteChannel;
2222 import java.util.ArrayList;
2323 import java.util.List;
24
25 import uk.me.parabola.log.Logger;
2426
2527 /**
2628 * The MDX index file. Used with the global index. This is located
102104 // Although its not necessarily wrong for them to be zero, it probably
103105 // sign that something is wrong.
104106 if (info.getHexMapname() == 0 || info.getMapname() == 0)
105 System.err.println("Invalid mapname for " + info.getFilename() + ", perhaps it is not a .img file");
107 Logger.defaultLogger.error("Invalid mapname for " + info.getFilename() + ", perhaps it is not a .img file");
106108
107109 buf.compact();
108110 info.write(buf);
100100 FileChannel chan = FileChannel.open(Paths.get(filename), OPEN_CREATE_RW);
101101 return createFs(chan, params);
102102 } catch (IOException e) {
103 throw new FileNotWritableException("Could not create file: " + params.getFilename(), e);
103 throw new FileNotWritableException("Could not create file", e);
104104 }
105105 }
106106
187187 */
188188 private void writeSizeValues(int blockSize) {
189189 int endSector = (int) (((numBlocks+1L) * blockSize + 511) / 512);
190 //System.out.printf("end sector %d %x\n", endSector, endSector);
191190
192191 // We have three maximum values for sectors, heads and cylinders. We attempt to find values
193192 // for them that are larger than the
204203 for (int s : asList(4, 8, 16, 32)) {
205204 for (int c : asList(0x20, 0x40, 0x80, 0x100, 0x200, 0x3ff)) {
206205 log.info("shc=", s + "," + h + "," + c, "end=", endSector);
207 //System.out.println("shc=" + s + "," + h + "," + c + "end=" + endSector);
208206 if (s * h * c > endSector) {
209207 headsPerCylinder = h;
210208 sectorsPerTrack = s;
0 package uk.me.parabola.log;
1
2 import java.util.logging.Level;
3
4 public class LogLevel extends Level {
5
6 public static final LogLevel DIAGNOSTIC = new LogLevel("DIAGNOSTIC", 1100);
7
8 public static final LogLevel ECHO = new LogLevel("ECHO", 1200);
9
10 public static final LogLevel OVERRIDE = new LogLevel("OVERRIDE", 1300);
11
12 protected LogLevel(String name, int value) {
13 super(name, value);
14 }
15
16 }
3434 */
3535 public class Logger {
3636 private final java.util.logging.Logger log;
37 private final boolean addPrefix;
38 public static final Logger defaultLogger = new Logger(java.util.logging.Logger.GLOBAL_LOGGER_NAME, false);
3739
3840 private static final ThreadLocal<String> threadTags = new ThreadLocal<>();
3941
4143 initLogging();
4244 }
4345
44 private Logger(String name) {
46 private Logger(String name, boolean addPrefix) {
4547 this.log = java.util.logging.Logger.getLogger(name);
48 this.addPrefix = addPrefix;
4649 }
4750
4851 /**
5457 * @return The logger.
5558 */
5659 public static Logger getLogger(String name) {
57 return new Logger(name);
60 return new Logger(name, true);
5861 }
5962
6063 /**
8285 else {
8386 staticSetup();
8487 }
88 if (!defaultLogger.isLoggable(Level.WARNING))
89 defaultLogger.log.setLevel(Level.WARNING);
8590 }
8691
8792 private static void initLoggingFromFile(String logconf) {
113118 f.setShowTime(false);
114119
115120 handler.setFormatter(f);
116 handler.setLevel(Level.SEVERE);
121 handler.setLevel(Level.FINE);
117122
118123 l.addHandler(handler);
119 l.setLevel(Level.WARNING);
124 l.setLevel(Level.SEVERE);
120125 }
121126
122127 public boolean isLoggable(Level level) {
176181 }
177182
178183 public void warn(Object o) {
179 log.warning(tagMessage(o == null? "null" : o.toString()));
184 if (log.isLoggable(Level.WARNING))
185 log.warning(tagMessage(o == null? "null" : o.toString()));
180186 }
181187
182188 public void warn(Object ... olist) {
194200 }
195201
196202 public void error(Object ... olist) {
197 arrayFormat(Level.SEVERE, olist);
198 }
203 arrayFormat(Level.SEVERE, olist);
204 }
205
199206 public void errorf(String fmt, Object... args) {
200207 printf(Level.SEVERE, fmt, args);
201208 }
203210 public void error(Object o, Throwable e) {
204211 log.log(Level.SEVERE, tagMessage(o == null? "null" : o.toString()), e);
205212 }
213
214 // output a requested diagnostic message
215 public void diagnostic(String msg) {
216 log.log(LogLevel.DIAGNOSTIC, tagMessage(msg));
217 }
218
219 // output an echo or echotags message
220 public void echo(String msg) {
221 log.log(LogLevel.ECHO, tagMessage(msg));
222 }
223
224 // an information message that is always output
225 public void write(String msg) {
226 log.log(LogLevel.OVERRIDE, tagMessage(msg));
227 }
206228
207229 public void log(Level level, Object o) {
208230 if (log.isLoggable(level))
225247 * @param olist The argument list as objects.
226248 */
227249 private void arrayFormat(Level type, Object... olist) {
228 StringBuilder sb = new StringBuilder();
229
230 for (Object o : olist) {
231 sb.append(o);
232 sb.append(' ');
233 }
234 sb.setLength(sb.length()-1);
235
236 log.log(type, tagMessage(sb.toString()));
250 if (log.isLoggable(type)) {
251 StringBuilder sb = new StringBuilder();
252 for (Object o : olist) {
253 sb.append(o);
254 sb.append(' ');
255 }
256 sb.setLength(sb.length()-1);
257 log.log(type, tagMessage(sb.toString()));
258 }
237259 }
238260
239261 private void printf(Level type, String fmt, Object... args) {
240 String msg = String.format(fmt, args);
241 log.log(type, tagMessage(msg));
242 }
243
244 private static String tagMessage(String message) {
262 if (log.isLoggable(type)) {
263 String msg = String.format(fmt, args);
264 log.log(type, tagMessage(msg));
265 }
266 }
267
268 private String tagMessage(String message) {
269 if (!addPrefix)
270 return message;
271
245272 String threadTag = threadTags.get();
246273 return (threadTag != null) ? threadTag + ": " + message : message;
247274 }
1919 import java.io.StringWriter;
2020 import java.util.Calendar;
2121 import java.util.logging.Formatter;
22 import java.util.logging.Level;
2223 import java.util.logging.LogRecord;
2324
2425 /**
3738 public String format(LogRecord record) {
3839 StringBuffer sb = new StringBuffer();
3940
40 if (showTime) {
41 long millis = record.getMillis();
42 Calendar cal = Calendar.getInstance();
43 cal.setTimeInMillis(millis);
44 sb.append(cal.get(Calendar.YEAR));
45 sb.append('/');
46 sb.append(fmt2(cal.get(Calendar.MONTH)+1));
47 sb.append('/');
48 sb.append(fmt2(cal.get(Calendar.DAY_OF_MONTH)));
49 sb.append(' ');
50 sb.append(fmt2(cal.get(Calendar.HOUR_OF_DAY)));
51 sb.append(':');
52 sb.append(fmt2(cal.get(Calendar.MINUTE)));
53 sb.append(':');
54 sb.append(fmt2(cal.get(Calendar.SECOND)));
55 sb.append(' ');
41 if (record.getLevel().intValue() <= Level.SEVERE.intValue()) {
42 if (showTime) {
43 long millis = record.getMillis();
44 Calendar cal = Calendar.getInstance();
45 cal.setTimeInMillis(millis);
46 sb.append(cal.get(Calendar.YEAR));
47 sb.append('/');
48 sb.append(fmt2(cal.get(Calendar.MONTH)+1));
49 sb.append('/');
50 sb.append(fmt2(cal.get(Calendar.DAY_OF_MONTH)));
51 sb.append(' ');
52 sb.append(fmt2(cal.get(Calendar.HOUR_OF_DAY)));
53 sb.append(':');
54 sb.append(fmt2(cal.get(Calendar.MINUTE)));
55 sb.append(':');
56 sb.append(fmt2(cal.get(Calendar.SECOND)));
57 sb.append(' ');
58 }
59
60 sb.append(record.getLevel().getLocalizedName());
61 sb.append(" (");
62 sb.append(shortName(record.getLoggerName()));
63 sb.append("): ");
5664 }
57
58 sb.append(record.getLevel().getLocalizedName());
59 sb.append(" (");
60 sb.append(shortName(record.getLoggerName()));
61 sb.append("): ");
62
6365 sb.append(record.getMessage());
6466
6567 sb.append(lineSeparator);
1010
1111 import uk.me.parabola.imgfmt.ExitException;
1212 import uk.me.parabola.imgfmt.app.srt.Sort;
13 import uk.me.parabola.log.Logger;
1314 import uk.me.parabola.util.EnhancedProperties;
1415
1516 public class CommandArgs {
9091 }
9192
9293 public String getOutputDir() {
93 final String DEFAULT_DIR = ".";
94 String fileOutputDir = currentOptions.getProperty("output-dir", DEFAULT_DIR);
95
94 String fileOutputDir = currentOptions.getProperty("output-dir");
95
96 if (fileOutputDir == null)
97 return ".";
98
9699 // Test if directory exists
97100 File outputDir = new File(fileOutputDir);
98101 if (!outputDir.exists()) {
99 System.out.println("Output directory not found. Creating directory '" + fileOutputDir + "'");
100 outputDir.mkdirs();
101 if (!outputDir.exists()) {
102 System.err.println("Unable to create output directory! Using default directory instead");
103 fileOutputDir = DEFAULT_DIR;
102 Logger.defaultLogger.info("Output directory not found. Creating directory '" + fileOutputDir + "'");
103 try {
104 if (!outputDir.mkdirs()) {
105 throw new ExitException("Unable to create output directory " + fileOutputDir);
106 }
107 } catch (SecurityException e) {
108 throw new ExitException("Error creating output directory " + fileOutputDir, e);
104109 }
105110 } else if (!outputDir.isDirectory()) {
106 System.err.println("The --output-dir parameter must specify a directory. The parameter is being ignored, writing to default directory instead.");
107 fileOutputDir = DEFAULT_DIR;
111 throw new ExitException("The --output-dir parameter must specify a directory.");
108112 }
109
113
110114 return fileOutputDir;
111115 }
112116
1616 package uk.me.parabola.mkgmap;
1717
1818 import java.io.File;
19 import java.io.IOException;
2019 import java.util.ArrayList;
2120 import java.util.Formatter;
2221 import java.util.Iterator;
4645 private final ArgumentProcessor proc;
4746
4847 private boolean mapnameWasSet;
48 private boolean hasFiles = false;
4949
5050 private final ArgList arglist = new ArgList();
5151
108108
109109 } else {
110110 log.debug("adding filename:", arg);
111 hasFiles = true;
111112 add(new Filename(arg));
112113 }
113114 }
124125 proc.endOptions(new CommandArgs(this.args));
125126 }
126127
128 public boolean getHasFiles() {
129 return hasFiles;
130 }
127131
128132 /**
129133 * Add an option based on the option and value separately.
201205 case "input-file":
202206 if (value != null){
203207 log.debug("adding filename", value);
208 hasFiles = true;
204209 add(new Filename(value));
205210 }
206211 break;
186186 {
187187 String[] cityList = p.getIsIn().split(",");
188188
189 //System.out.println(p.getIsIn());
190
191189 // is_in content is not well defined so we try our best to get some info out of it
192190 // Format 1 popular in Germany: "County,State,Country,Continent"
193191
179179 }
180180 else
181181 {
182 System.out.println(fileName + "contains invalid root tag " + rootNode.getNodeName());
183 }
184 }
182 log.error(fileName + "contains invalid root tag " + rootNode.getNodeName());
183 }
184 }
185185 catch (Exception ex)
186186 {
187 ex.printStackTrace();
188 //System.out.println("Something is wrong here");
187 Logger.defaultLogger.error("Unexpected error reading " + fileName, ex);
189188 }
190189 }
191190
2525 import java.util.Objects;
2626
2727 import uk.me.parabola.imgfmt.FileSystemParam;
28 import uk.me.parabola.imgfmt.MapFailedException;
2829 import uk.me.parabola.imgfmt.ReadFailedException;
2930 import uk.me.parabola.imgfmt.Utils;
3031 import uk.me.parabola.imgfmt.app.Area;
163164 info = new FileInfo(inputName, UNKNOWN_KIND);
164165 }
165166 } catch (AssertionError | ReadFailedException e) {
166 throw new ReadFailedException("Could not read file " + inputName, e);
167 throw new MapFailedException("Could not read file " + inputName, e);
167168 }
168169 return info;
169170 }
203204 fr.position(0x15);
204205 info.setCodePage(fr.get2u());
205206 } catch (IOException e) {
206 e.printStackTrace();
207 Logger.defaultLogger.error("Unexpected error reading " + filename, e);
207208 }
208209 }
209210
9898 typFile = info.getFilename();
9999
100100 } catch (IOException e) {
101 e.printStackTrace();
101 throw new ExitException("Error saving gmapi data", e);
102102 }
103103 }
104104
130130 writeXmlFile(gmapDir);
131131
132132 } catch (IOException e) {
133 e.printStackTrace();
133 throw new ExitException("Error building gmapi data", e);
134134 }
135135 }
136136
5959 * @author Steve Ratcliffe
6060 */
6161 public class GmapsuppBuilder implements Combiner {
62 private static final Logger log = Logger.getLogger(GmapsuppBuilder.class);
63
6462 private static final String GMAPSUPP = "gmapsupp.img";
6563
6664 private final Map<String, FileInfo> files = new LinkedHashMap<>();
120118 ImgChannel chan = imgFs.create(imgname);
121119 mdrBuilder.initForDevice(chan, sort, mdrConfig);
122120 } catch (FileExistsException e) {
123 System.err.println("Could not create duplicate MDR file");
121 Logger.defaultLogger.error("Could not create duplicate MDR file");
124122 }
125123
126124 mdrBuilderMap.put(familyId, mdrBuilder);
139137 }
140138 } else {
141139 if (prevSort.getCodepage() != sort.getCodepage())
142 System.err.printf("WARNING: input file '%s' has a different code page (%d rather than %d)\n",
143 info.getFilename(), sort.getCodepage(), prevSort.getCodepage());
140 Logger.defaultLogger.warn("Input file '" + info.getFilename() + "' has a different code page (" + sort.getCodepage() + " rather than " + prevSort.getCodepage() + ")");
144141 if (info.hasSortOrder() && prevSort.getSortOrderId() != sort.getSortOrderId())
145 System.err.printf("WARNING: input file '%s' has a different sort order (%x rather than %x\n",
146 info.getFilename(), sort.getSortOrderId(), prevSort.getSortOrderId());
142 Logger.defaultLogger.warn("Input file '" + info.getFilename() + "' has a different sort order (" + sort.getSortOrderId() + " rather than " + prevSort.getSortOrderId() + ")");
147143 }
148144 }
149145
185181 writeMpsFile();
186182
187183 } catch (FileNotWritableException e) {
188 log.warn("Could not create gmapsupp file");
189 System.err.println("Could not create gmapsupp file");
184 Logger.defaultLogger.error("Could not create gmapsupp file");
190185 } finally {
191186 Utils.closeFile(imgFs);
192187 }
214209 // Do not close srtFile here
215210 } catch (FileExistsException e) {
216211 // well it shouldn't exist!
217 log.error("could not create SRT file as it exists already");
212 Logger.defaultLogger.error("could not create SRT file as it exists already");
218213 throw new FileNotWritableException("already existed", e);
219214 }
220215 }
285280
286281 ((FileLink)chan).link(sf, sync);
287282 } catch (FileExistsException e) {
288 log.warn("Could not copy " + sf.getName(), e);
283 Logger.defaultLogger.warn("Could not copy " + sf.getName(), e);
289284 }
290285 }
291286 }
298293 ImgChannel chan = outfs.create(createImgFilename(filename));
299294 ((FileLink) chan).link(info.subFiles().get(0), fc.file(chan));
300295 } catch (FileExistsException e) {
301 log.warn("Counld not copy " + filename, e);
296 Logger.defaultLogger.warn("Could not copy " + filename, e);
302297 }
303298 }
304299
318313 mpsFile.addProduct(b);
319314 mr.close();
320315 } catch (IOException e) {
321 log.error("Could not read MPS file from gmapsupp", e);
316 Logger.defaultLogger.error("Could not read MPS file from gmapsupp", e);
322317 }
323318 }
324319
339334 return new MpsFile(channel);
340335 } catch (FileExistsException e) {
341336 // well it shouldn't exist!
342 log.error("could not create MPS file as it already exists");
337 Logger.defaultLogger.error("could not create MPS file as it already exists");
343338 throw new FileNotWritableException("already existed", e);
344339 }
345340 }
2626 import java.util.Map;
2727
2828 import uk.me.parabola.imgfmt.Utils;
29 import uk.me.parabola.log.Logger;
2930 import uk.me.parabola.mkgmap.CommandArgs;
3031 import uk.me.parabola.mkgmap.Version;
3132
9495 } catch (Exception ex) {
9596 inStream = this.getClass().getResourceAsStream("/installer/installer_template.nsi");
9697 if (inStream == null) {
97 System.err.println("Could not find the installer template.");
98 Logger.defaultLogger.error("Could not find the installer template.");
9899 return;
99100 }
100101 }
117118 }
118119
119120 } catch (IOException e) {
120 System.err.println("Could not write NSIS file");
121 Logger.defaultLogger.error("Could not write NSIS file");
121122 } finally {
122123 Utils.closeFile(inStream);
123124 }
181182 } catch (Exception ex) {
182183 inStream = this.getClass().getResourceAsStream("/installer/license_template.txt");
183184 if (inStream == null) {
184 System.err.println("Could not find the license template.");
185 Logger.defaultLogger.error("Could not find the license template.");
185186 return;
186187 }
187188 }
197198 }
198199
199200 } catch (IOException e) {
200 System.err.println("Could not write license file");
201 Logger.defaultLogger.error("Could not write license file");
201202 } finally {
202203 Utils.closeFile(inStream);
203204 }
214214 codepage = finfo.getCodePage();
215215 }
216216 if (codepage != finfo.getCodePage()){
217 System.err.println("WARNING: input file " + filename + " has different code page " + finfo.getCodePage());
217 Logger.defaultLogger.warn("Input file " + filename + " has different code page " + finfo.getCodePage());
218218 }
219219
220220 try {
224224 encodingType = mapReader.getEncodingType();
225225 }
226226 if (encodingType != mapReader.getEncodingType()){
227 System.err.println("WARNING: input file " + filename + " has different charset type " + encodingType);
227 Logger.defaultLogger.warn("Input file " + filename + " has different charset type " + encodingType);
228228 }
229229
230230 String[] msgs = mapReader.getCopyrights();
323323 int min = levels[l].getLevel();
324324 int res = levels[l].getResolution();
325325 List<Polyline> lineList = mapReader.linesForLevel(min);
326 //System.out.println(lineList.size() + " lines in lowest resolution " + levels[1].getResolution());
327326 for (Polyline line : lineList) {
328327 if (log.isDebugEnabled())
329328 log.debug("got line", line);
189189 try {
190190 tdb.write(Utils.joinPath(outputDir, overviewMapname, "tdb"));
191191 } catch (IOException e) {
192 log.error("tdb write", e);
193192 throw new ExitException("Could not write the TDB file", e);
194193 }
195194 }
8080 */
8181 public class Main implements ArgumentProcessor {
8282 private static final Logger log = Logger.getLogger(Main.class);
83 private static final Date StartTime = new Date();
8384
8485 // Final .img file combiners.
8586 private final List<Combiner> combiners = new ArrayList<>();
102103 private volatile int programRC = 0;
103104
104105 private final Map<String, Combiner> combinerMap = new HashMap<>();
106 private boolean informationDisplayed = false;
105107
106108 /**
107109 * Used for unit tests
125127 */
126128 private static int mainStart(String... args) {
127129 Instant start = Instant.now();
128 System.out.println("Time started: " + new Date());
130
129131 // We need at least one argument.
130132 if (args.length < 1) {
131133 printUsage();
136138 Main mm = new Main();
137139
138140 int numExitExceptions = 0;
141 CommandArgsReader commandArgs = new CommandArgsReader(mm);
139142 try {
140143 // Read the command line arguments and process each filename found.
141 CommandArgsReader commandArgs = new CommandArgsReader(mm);
142144 commandArgs.setValidOptions(getValidOptions(System.err));
143145 commandArgs.readArgs(args);
144146 } catch (OutOfMemoryError e) {
145147 ++numExitExceptions;
146 System.err.println(e);
148 String message = "Out of memory.\r\n";
147149 if (mm.maxJobs > 1)
148 System.err.println("Try using the mkgmap --max-jobs option with a value less than " + mm.maxJobs + " to reduce the memory requirement, or use the Java -Xmx option to increase the available heap memory.");
150 message += "Try using the mkgmap --max-jobs option with a value less than " + mm.maxJobs + " to reduce the memory requirement, or use the Java -Xmx option to increase the available heap memory.";
149151 else
150 System.err.println("Try using the Java -Xmx option to increase the available heap memory.");
152 message += "Try using the Java -Xmx option to increase the available heap memory.";
153 Logger.defaultLogger.error(message);
151154 } catch (MapFailedException | ExitException e) {
152155 // one of the combiners failed
153156 ++numExitExceptions;
157160 message += "\r\n" + cause.toString();
158161 cause = cause.getCause();
159162 }
160 System.err.println(message);
161 }
162
163 System.out.println("Number of ExitExceptions: " + numExitExceptions);
164
165 System.out.println("Time finished: " + new Date());
166 Duration duration = Duration.between(start, Instant.now());
167 long seconds = duration.getSeconds();
168 if (seconds > 0) {
169 long hours = seconds / 3600;
170 seconds -= hours * 3600;
171 long minutes = seconds / 60;
172 seconds -= minutes * 60;
173 System.out.println("Total time taken: " +
174 (hours > 0 ? hours + (hours > 1 ? " hours " : " hour ") : "") +
175 (minutes > 0 ? minutes + (minutes > 1 ? " minutes " : " minute ") : "") +
176 (seconds > 0 ? seconds + (seconds > 1 ? " seconds" : " second") : ""));
177 }
178 else
179 System.out.println("Total time taken: " + duration.getNano() / 1000000 + " ms");
180 if (numExitExceptions > 0 || mm.getProgramRC() != 0){
181 return 1;
182 }
183 return 0;
184 }
185
163 Logger.defaultLogger.error(message);
164 }
165
166 if(commandArgs.getHasFiles()) {
167 Logger.defaultLogger.write("Number of ExitExceptions: " + numExitExceptions);
168
169 Logger.defaultLogger.write("Time finished: " + new Date());
170 Duration duration = Duration.between(start, Instant.now());
171 long seconds = duration.getSeconds();
172 if (seconds > 0) {
173 long hours = seconds / 3600;
174 seconds -= hours * 3600;
175 long minutes = seconds / 60;
176 seconds -= minutes * 60;
177 Logger.defaultLogger.write("Total time taken: " +
178 (hours > 0 ? hours + (hours > 1 ? " hours " : " hour ") : "") +
179 (minutes > 0 ? minutes + (minutes > 1 ? " minutes " : " minute ") : "") +
180 (seconds > 0 ? seconds + (seconds > 1 ? " seconds" : " second") : ""));
181 }
182 else
183 Logger.defaultLogger.write("Total time taken: " + duration.getNano() / 1000000 + " ms");
184 }
185 else if (numExitExceptions == 0 && !mm.informationDisplayed)
186 System.err.println("The command line does not appear to require mkgmap to do anything.");
187 return (numExitExceptions > 0 || mm.getProgramRC() != 0) ? 1 : 0;
188 }
189
186190 private static void printUsage (){
187191 System.err.println("Usage: mkgmap [options...] <file.osm>");
188192 }
317321
318322 break;
319323 case "help":
324 informationDisplayed = true;
320325 printHelp(System.out, getLang(), (!val.isEmpty()) ? val : "help");
321326 break;
322327 case "style-file":
330335 verbose = true;
331336 break;
332337 case "list-styles":
338 informationDisplayed = true;
333339 listStyles();
334340 break;
335341 case "check-styles":
342 informationDisplayed = true;
336343 checkStyles();
337344 break;
338345 case "max-jobs":
341348 else {
342349 maxJobs = Integer.parseInt(val);
343350 if (maxJobs < 1) {
344 log.warn("max-jobs has to be at least 1");
351 Logger.defaultLogger.warn("max-jobs has to be at least 1");
345352 maxJobs = 1;
346353 }
347354 if (maxJobs > Runtime.getRuntime().availableProcessors())
348 log.warn("It is recommended that max-jobs be no greater that the number of processor cores");
355 Logger.defaultLogger.warn("It is recommended that max-jobs be no greater that the number of processor cores");
349356 }
350357 break;
351358 case "version":
359 informationDisplayed = true;
360 System.err.println("Mkgmap version " + Version.VERSION);
352361 System.err.println(Version.VERSION);
353362 System.exit(0);
354363 }
457466 try {
458467 style = new StyleImpl(styleFile, name, new EnhancedProperties(), performChecks);
459468 } catch (SyntaxException e) {
460 System.err.println("Error in style: " + e.getMessage());
469 Logger.defaultLogger.error("Error in style: " + e.getMessage());
461470 } catch (FileNotFoundException e) {
462471 log.debug("could not find style", name);
463472 try {
464473 searchedStyleName = new File(styleFile).getName();
465474 style = new StyleImpl(styleFile, null, new EnhancedProperties(), performChecks);
466475 } catch (SyntaxException e1) {
467 System.err.println("Error in style: " + e1.getMessage());
476 Logger.defaultLogger.error("Error in style: " + e1.getMessage());
468477 } catch (FileNotFoundException e1) {
469478 log.debug("could not find style", styleFile);
470479 }
484493 public void endOptions(CommandArgs args) {
485494 fileOptions(args);
486495
496 int taskCount = futures.size();
497 if (taskCount > 0) {
498 Logger.defaultLogger.write("Mkgmap version " + Version.VERSION);
499 Logger.defaultLogger.write("Time started: " + StartTime);
500 }
487501 log.info("Start tile processors");
488502 int threadCount = maxJobs;
489 int taskCount = futures.size();
490503 Runtime runtime = Runtime.getRuntime();
491504 if (threadPool == null) {
492505 if (threadCount == 0) {
510523 }
511524 threadCount = Math.max(threadCount, 1);
512525 threadCount = Math.min(threadCount, runtime.availableProcessors());
513 System.out.println("Setting max-jobs to " + threadCount);
526 Logger.defaultLogger.warn("Setting max-jobs to " + threadCount);
514527 }
515528 }
516529
565578 throw new ExitException("Exiting - if you want to carry on regardless, use the --keep-going option");
566579 }
567580 } catch (Exception e) {
568 e.printStackTrace();
581 Logger.defaultLogger.error("Unexpected error", e);
569582 throw new ExitException("Exiting due to unexpected error");
570583 }
571584 }
572585 }
573 System.out.println("Number of MapFailedExceptions: " + numMapFailedExceptions);
586 Logger.defaultLogger.write("Number of MapFailedExceptions: " + numMapFailedExceptions);
574587 if ((taskCount > threadCount + 1) && (maxJobs == 0) && (threadCount < runtime.availableProcessors())) {
575 System.out.println("To reduce the run time, consider increasing the amnount of memory available for use by mkgmap by using the Java -Xmx flag to set the memory to more than " + 100* (1 + ((runtime.maxMemory() * runtime.availableProcessors()) / (threadCount * 1024 * 1024 * 100))) + " MB, providing this is less than the amount of physical memory installed.");
588 Logger.defaultLogger.warn("To reduce the run time, consider increasing the amnount of memory available for use by mkgmap by using the Java -Xmx flag to set the memory to more than " + 100* (1 + ((runtime.maxMemory() * runtime.availableProcessors()) / (threadCount * 1024 * 1024 * 100))) + " MB, providing this is less than the amount of physical memory installed.");
576589 }
577590
578591 if (combiners.isEmpty())
588601 hasFiles = true;
589602 }
590603 if (!hasFiles){
591 log.warn("nothing to do for combiners.");
604 log.info("nothing to do for combiners.");
592605 return;
593606 }
594607 log.info("Combining maps");
678691 if (f.exists() && f.isFile()) {
679692 try {
680693 Files.delete(f.toPath());
681 log.warn("removed " + f);
694 log.info("removed " + f);
682695 } catch (IOException e) {
683696 log.warn("removing " + f + "failed with " + e.getMessage());
684697 }
5050
5151 public String makeMap(CommandArgs args, String filename) {
5252 if (new File(filename).isDirectory()) {
53 System.err.println("Need a single file, not a directory: " + filename);
53 Logger.defaultLogger.error("Need a single file, not a directory: " + filename);
5454 return filename;
5555 }
5656 try {
6868 }
6969 return makeMap(args, src, "");
7070 } catch (FormatException e) {
71 System.err.println("Bad file format: " + filename);
72 System.err.println(e.getMessage());
71 Logger.defaultLogger.error("Bad file format: " + filename);
7372 return filename;
7473 } catch (FileNotFoundException e) {
75 System.err.println("Could not open file: " + filename);
74 Logger.defaultLogger.error("Could not open file: " + filename);
7675 return filename;
7776 }
7877 }
119118 map.close();
120119 return outName;
121120 } catch (FileExistsException e) {
122 log.error("File exists already");
121 Logger.defaultLogger.error(e.getMessage());
123122 throw new MapFailedException("File exists already", e);
124123 } catch (FileNotWritableException e) {
125 log.error("Could not create or write to file");
124 Logger.defaultLogger.error(e.getMessage());
126125 throw new MapFailedException("Could not create or write to file", e);
127126 }
128127 catch (MapFailedException e) {
129 log.error(e.getMessage()); // make sure the filename is logged
128 Logger.defaultLogger.error(e.getMessage()); // make sure the filename is logged
130129 throw e;
131130 }
132131 }
4141 try (FileInputStream in = new FileInputStream(filename)) {
4242 byte[] buf = new byte[256];
4343 int n = in.read(buf);
44 if (n == -1)
45 throw new ExitException("TYP file is empty: " + filename);
4446
4547 ByteBuffer buffer = ByteBuffer.wrap(buf);
4648 buffer.order(ByteOrder.LITTLE_ENDIAN);
238238 try (InputStream is = this.getClass().getResourceAsStream("/styles/builtin-tag-list");) {
239239 if (is != null) {
240240 BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
241 // System.out.println("Got built in list");
242241 String line;
243242 while ((line = br.readLine()) != null) {
244243 line = line.trim();
245244 if (line.startsWith("#"))
246245 continue;
247 // System.out.println("adding " + line);
246
248247 set.add(line);
249248 }
250249 }
251250 } catch (IOException e) {
252251 // the file doesn't exist, this is ok but unlikely
253 System.err.println("warning: built in tag list not found");
252 Logger.defaultLogger.warn("built in tag list not found");
254253 }
255254 return set;
256255 }
261260 l = LevelInfo.DEFAULT_LEVELS;
262261 LevelInfo[] levels = LevelInfo.createFromString(l);
263262 if (performChecks && levels[0].getBits() <= 10) {
264 System.err.println("Warning: Resolution values <= 10 may confuse MapSource: " + l);
263 Logger.defaultLogger.warn("Resolution values <= 10 may confuse MapSource: " + l);
265264 }
266265 l = generalOptions.get("overview-levels");
267266 if (l != null){
269268 // TODO: make sure that the combination of the two level strings makes sense
270269 if (performChecks){
271270 if (ovLevels[0].getBits() <= 10){
272 System.err.println("Warning: Resolution values <= 10 may confuse MapSource: " + l);
271 Logger.defaultLogger.warn("Resolution values <= 10 may confuse MapSource: " + l);
273272 }
274273 if (levels[0].getLevel() >= ovLevels[ovLevels.length-1].getLevel()){
275 System.err.println("Warning: Overview level not higher than highest normal level. " + l);
274 Logger.defaultLogger.warn("Overview level not higher than highest normal level. " + l);
276275 }
277276 }
278277 List<LevelInfo> tmp = new ArrayList<>();
335334 String val = opt.getValue();
336335 if ("name-tag-list".equals(key)) {
337336 if (!"name".equals(val)) {
338 System.err.println("Warning: option name-tag-list used in the style options is ignored. "
337 Logger.defaultLogger.warn("Option name-tag-list used in the style options is ignored. "
339338 + "Please use only the command line option to specify this value.");
340339 }
341340 } else if (OPTION_LIST.contains(key)) {
409408 try {
410409 baseStyles.add(new StyleImpl(location, name, props, performChecks));
411410 } catch (SyntaxException e) {
412 System.err.println("Error in style: " + e.getMessage());
411 Logger.defaultLogger.error("Error in style: " + e.getMessage());
413412 } catch (FileNotFoundException e) {
414413 // not found, try on the classpath. This is the common
415414 // case where you have an external style, but want to
419418 try {
420419 baseStyles.add(new StyleImpl(null, name, props, performChecks));
421420 } catch (SyntaxException se) {
422 System.err.println("Error in style: " + se.getMessage());
421 Logger.defaultLogger.error("Error in style: " + se.getMessage());
423422 } catch (FileNotFoundException e1) {
424 log.error("Could not find base style", e);
423 Logger.defaultLogger.error("Could not find base style", e);
425424 }
426425 }
427426 }
477476 }
478477
479478 if (version > VERSION) {
480 System.err.println("Warning: unrecognised style version " + version +
479 Logger.defaultLogger.warn("Unrecognised style version " + version +
481480 ", but only versions up to " + VERSION + " are understood");
482481 }
483482 }
545544 try {
546545 style = new StyleImpl(loc, name, props, WITHOUT_CHECKS);
547546 } catch (SyntaxException e) {
548 System.err.println("Error in style: " + e.getMessage());
547 Logger.defaultLogger.error("Error in style: " + e.getMessage());
549548 throw new ExitException("Could not open style " + (name == null? "":name));
550549 } catch (FileNotFoundException e) {
551550 String msg = "Could not open style ";
164164
165165 private LineAdder lineAdder;
166166 private NearbyPoiHandler nearbyPoiHandler;
167
168 static List<String> unusedStyleOptions = new ArrayList<>();
169 static List<String> duplicateKeys = new ArrayList<>();
170 static List<String> unspecifiedStyleOptions = new ArrayList<>();
167171
168172 public StyledConverter(Style style, MapCollector collector, EnhancedProperties props) {
169173 this.collector = collector;
203207 countryAbbr = countryAbbr.toUpperCase();
204208
205209 checkRoundabouts = props.getProperty("check-roundabouts",false);
206 reportDeadEnds = props.getProperty("report-dead-ends", 1);
210 reportDeadEnds = (props.getProperty("report-dead-ends") != null) ? props.getProperty("report-dead-ends", 1) : 0;
207211 prefixSuffixFilter = new PrefixSuffixFilter(props);
208212
209213 lineAdder = line -> {
249253 String optionKey = pair[0];
250254 String tagKey = STYLE_OPTION_PREF + optionKey;
251255 if (!style.getUsedTags().contains(tagKey)) {
252 System.err.println("Warning: Option style-options sets tag not used in style: '"
253 + optionKey + "' (gives " + tagKey + ")");
254 } else {
255 String val = (pair.length == 1) ? "true" : pair[1];
256 String old = styleTags.put(tagKey, val);
257 if (old != null)
258 log.error("duplicate tag key", optionKey, "in style option", styleOption);
256 synchronized(unusedStyleOptions) {
257 if (!unusedStyleOptions.contains(optionKey)) {
258 unusedStyleOptions.add(optionKey);
259 Logger.defaultLogger.warn("Option style-options sets tag not used in style: '"
260 + optionKey + "' (gives " + tagKey + ")");
261 }
262 }
263 }
264 String val = (pair.length == 1) ? "true" : pair[1];
265 String old = styleTags.put(tagKey, val);
266 if (old != null) {
267 synchronized(duplicateKeys) {
268 if (!duplicateKeys.contains(optionKey)) {
269 duplicateKeys.add(optionKey);
270 Logger.defaultLogger.error("duplicate tag key", optionKey, "in style option", styleOption);
271 }
272 }
259273 }
260274 }
261275 }
263277 if (style.getUsedTags() != null) {
264278 for (String s : style.getUsedTags()) {
265279 if (s != null && s.startsWith(STYLE_OPTION_PREF) && styleTags.get(s) == null) {
266 System.err.println("Warning: Option style-options doesn't specify '"
267 + s.replaceFirst(STYLE_OPTION_PREF, "") + "' (for " + s + ")");
280 synchronized(unspecifiedStyleOptions) {
281 if (!unspecifiedStyleOptions.contains(s)) {
282 unspecifiedStyleOptions.add(s);
283 Logger.defaultLogger.warn("Option style-options doesn't specify '"
284 + s.replaceFirst(STYLE_OPTION_PREF, "") + "' (for " + s + ")");
285 }
286 }
268287 }
269288 }
270289 }
347366 numDriveOnSideUnknown++;
348367 }
349368 }
350 if (cw.isRoundabout() && wasReversed) {
351 log.warn("Roundabout", way.getId(),
352 "has reverse oneway tag (" + way.getFirstPoint().toOSMURL() + ")");
369 if (cw.isRoundabout() && wasReversed && checkRoundabouts) {
370 log.diagnostic("Roundabout " + way.getId() +
371 " has reverse oneway tag (" + way.getFirstPoint().toOSMURL() + ")");
353372 }
354373 lastRoadId = way.getId();
355374 } else {
10741093 if (points.get(0) == points.get(points.size() - 1)) {
10751094 // roundabout is a loop
10761095 if (dirIsWrong) {
1077 log.warn("Roundabout " + way.getId() + " direction is wrong - reversing it (see "
1096 log.diagnostic("Roundabout " + way.getId() + " direction is wrong - reversing it (see "
10781097 + centre.toOSMURL() + ")");
10791098 way.reverse();
10801099 }
10811100 } else if (dirIsWrong) {
10821101 // roundabout is a line
1083 log.warn("Roundabout segment " + way.getId() + " direction looks wrong (see "
1102 log.diagnostic("Roundabout segment " + way.getId() + " direction looks wrong (see "
10841103 + points.get(0).toOSMURL() + ")");
10851104 }
10861105 }
12311250 line.setType(replType);
12321251 line.setPoints(points);
12331252
1234
12351253 if (way.tagIsLikeYes(TK_ONEWAY))
12361254 line.setDirection(true);
12371255
22302248 }
22312249
22322250 if (isDeadEnd && (isDeadEndOfMultipleWays || reportDeadEnds > 1)) {
2233 log.warn("Oneway road " + way.getId() + " with tags " + way.toTagString()
2251 log.diagnostic("Oneway road " + way.getId() + " with tags " + way.toTagString()
22342252 + ((pos == 0) ? " comes from" : " goes to") + " nowhere at " + p.toOSMURL());
22352253 }
22362254 }
1515 package uk.me.parabola.mkgmap.osmstyle.actions;
1616
1717 import uk.me.parabola.mkgmap.reader.osm.Element;
18 import uk.me.parabola.log.Logger;
1819
1920 /**
20 * Sends a message to the console.
21 * Logs a message.
2122 *
2223 * @author Richard Fairhurst
2324 */
2930 }
3031
3132 public boolean perform(Element el) {
32 System.err.println(el.getBasicLogInformation() + " " + value.build(el, el));
33 Logger.defaultLogger.echo(el.getBasicLogInformation() + " " + value.build(el, el));
3334 return false;
3435 }
3536 }
1313 package uk.me.parabola.mkgmap.osmstyle.actions;
1414
1515 import uk.me.parabola.mkgmap.reader.osm.Element;
16 import uk.me.parabola.log.Logger;
1617
1718 /**
18 * Sends a message including the tags of an element to System.err.
19 * Logs a message including the tags of an element.
1920 *
2021 * @author WanMil
2122 */
2728 }
2829
2930 public boolean perform(Element el) {
30 System.err.println(el.getBasicLogInformation() + " " + el.toTagString() + " " + value.build(el, el));
31 Logger.defaultLogger.echo(el.getBasicLogInformation() + " " + el.toTagString() + " " + value.build(el, el));
3132 return false;
3233 }
3334
1919 import java.util.Set;
2020
2121 import uk.me.parabola.imgfmt.ExitException;
22 import uk.me.parabola.log.Logger;
2223 import uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction;
2324 import uk.me.parabola.mkgmap.reader.osm.Element;
2425 import uk.me.parabola.mkgmap.scan.SyntaxException;
209210 } else if (this.isType(NodeType.EXISTS) || this.isType(NodeType.NOT_EXISTS) || this.isType(NodeType.NOT)) {
210211 set.addAll(getFirst().getEvaluatedTagKeys());
211212 } else if (this.getFirst() != null) {
212 System.err.println("Unhandled type of Op");
213 Logger.defaultLogger.error("Unhandled type of Op");
213214 }
214215
215216 }
105105 if (n != nameSearchDepth) {
106106 nameSearchDepth = Math.min(25, Math.max(0, n));
107107 if (nameSearchDepth != n) {
108 System.err.println("name-service-roads=" + n + " was changed to name-service-roads=" + nameSearchDepth);
108 Logger.defaultLogger.warn("name-service-roads=" + n + " was changed to name-service-roads=" + nameSearchDepth);
109109 }
110110 }
111111 }
3737 try {
3838 knownHgt = loadConfig();
3939 } catch (IOException e) {
40 e.printStackTrace();
40 Logger.defaultLogger.error("Error reading hgt config", e);
4141 }
4242 }
4343
113113
114114 bs.set(getBitSetPos(lat, lon));
115115 } catch (NumberFormatException e) {
116 e.printStackTrace();
116 Logger.defaultLogger.error("Error reading latitude/longitude", e);
117117 }
118118 }
119119 return bs;
129129 HGTList hgtList = HGTList.get();
130130 if (hgtList != null) {
131131 if (hgtList.shouldExist(lat, lon))
132 System.err.println(this.getClass().getSimpleName() + ": file " + fileName + " not found but it should exist. Height values will be 0.");
132 Logger.defaultLogger.warn(this.getClass().getSimpleName() + ": file " + fileName + " not found but it should exist. Height values will be 0.");
133133 } else {
134134 log.warn("file " + fileName + " not found. Is expected to cover sea.");
135135 }
105105 } catch (FileNotFoundException exp) {
106106 log.error("Coastline file " + coastlineFile + " not found.");
107107 } catch (Exception exp) {
108 log.error(exp);
109 exp.printStackTrace();
108 log.error("Unexpected exception reading " + coastlineFile, exp);
110109 }
111110 }
112111 coastlinesLoaded.set(true);
456456 }
457457 }
458458 // try to connect ways lying outside or on the bbox
459 if (unclosed.size() >= 2) {
459 if (!unclosed.isEmpty()) {
460460 log.debug("Checking", unclosed.size(), "unclosed ways for connections outside the bbox");
461461 Map<Coord, JoinedWay> outOfBboxPoints = new IdentityHashMap<>();
462462
504504 if (!lineCutsBbox(cd.c1, edgePoint1) && !lineCutsBbox(edgePoint1, cd.c2)) {
505505 cd.imC = edgePoint1;
506506 } else if (!lineCutsBbox(cd.c1, edgePoint2) && !lineCutsBbox(edgePoint2, cd.c2)) {
507 cd.imC = edgePoint1;
507 cd.imC = edgePoint2;
508508 } else {
509509 // both endpoints are on opposite sides of the bounding box
510510 // automatically closing such points would create wrong polygons in most cases
544544 minCon.w1.getPoints().addAll(minCon.w2.getPoints());
545545 minCon.w1.addWay(minCon.w2);
546546 allWays.remove(minCon.w2);
547 return true;
548 }
547 }
548 return true;
549549 }
550550 }
551551 return false;
166166 break;
167167 } catch (InstantiationException | IllegalAccessException e) {
168168 // TODO Auto-generated catch block
169 e.printStackTrace();
169 log.error("Unexpected error", e);
170170 }
171171 }
172172 }
689689 } catch (FileNotFoundException exp) {
690690 log.error("Preompiled sea tile " + tileName + " not found.");
691691 } catch (Exception exp) {
692 log.error(exp);
693 exp.printStackTrace();
692 log.error("Unexpected error reading "+ tileName, exp);
694693 }
695694 }
696695
1717 import java.io.InputStream;
1818 import java.nio.charset.StandardCharsets;
1919
20 import uk.me.parabola.imgfmt.FormatException;
2021 import uk.me.parabola.imgfmt.app.Coord;
22 import uk.me.parabola.log.Logger;
2123 import uk.me.parabola.mkgmap.reader.osm.Element;
2224 import uk.me.parabola.mkgmap.reader.osm.GeneralRelation;
2325 import uk.me.parabola.mkgmap.reader.osm.Node;
106108 try {
107109 int start = is.read();
108110 ++countBytes;
109 if (start != RESET_FLAG)
110 throw new IOException("wrong header byte " + start);
111 if (start != RESET_FLAG) {
112 Logger.defaultLogger.error("wrong header byte " + start);
113 throw new FormatException("wrong header byte " + start);
114 }
111115 readFile();
112116 } catch (IOException e) {
113 System.err.println("exception after " + countBytes + " bytes");
114 e.printStackTrace();
117 Logger.defaultLogger.error("exception after " + countBytes + " bytes", e);
115118 }
116119 }
117120
220220 */
221221 @Override
222222 public void fatalError(SAXParseException e) throws SAXException {
223 System.err.println("Error at line " + e.getLineNumber() + ", col "
223 Logger.defaultLogger.error("Error at line " + e.getLineNumber() + ", col "
224224 + e.getColumnNumber());
225225 super.fatalError(e);
226226 }
1313
1414 import uk.me.parabola.imgfmt.app.CoordNode;
1515 import uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction;
16 import uk.me.parabola.log.Logger;
1617 import uk.me.parabola.mkgmap.general.MapDetails;
1718
1819 import java.util.ArrayList;
5556 if (restriction.isValid())
5657 allRestrictions.add(restriction);
5758 else {
58 System.err.println(restriction);
59 Logger.defaultLogger.warn("Invalid restriction " + restriction.toString());
5960 }
6061 }
6162 }
3737 public class ArgsTest extends Base {
3838 @Test
3939 public void testHelp() {
40 Outputs outputs = TestUtils.run("--help");
40 Outputs outputs = TestUtils.runAsProcess("--help");
4141 outputs.checkOutput("--help=options", "--help=links");
4242 outputs.checkNoError();
4343 checkNoStdFile();
4545
4646 @Test
4747 public void testHelpOptions() {
48 Outputs outputs = TestUtils.run("--help=options");
48 Outputs outputs = TestUtils.runAsProcess("--help=options");
4949 outputs.checkNoError();
5050 outputs.checkOutput("--mapname=name", "--latin1", "--list-styles");
5151 checkNoStdFile();
5353
5454 @Test
5555 public void testHelpUnknown() {
56 Outputs outputs = TestUtils.run("--help=unknown-help-option");
56 Outputs outputs = TestUtils.runAsProcess("--help=unknown-help-option");
5757 outputs.checkNoError();
5858 outputs.checkOutput("Could not find", "unknown-help-option");
5959 checkNoStdFile();
6161
6262 @Test
6363 public void testListStyles() {
64 Outputs op = TestUtils.run("--style-file=test/resources/teststyles", "--list-styles");
64 Outputs op = TestUtils.runAsProcess("--style-file=test/resources/teststyles", "--list-styles");
6565 op.checkNoError();
6666 op.checkOutput("empty", "main", "simple", "derived", "2.2: A simple test style");
6767 checkNoStdFile();
6969
7070 @Test
7171 public void testListStylesVerbose() {
72 Outputs op = TestUtils.run("--style-file=test/resources/teststyles",
72 Outputs op = TestUtils.runAsProcess("--style-file=test/resources/teststyles",
7373 "--verbose", "--list-styles");
7474 op.checkNoError();
7575 op.checkOutput("empty", "main", "simple", "derived",
8282 TestUtils.registerFile("osmmap.img");
8383
8484 int pri = 42;
85 Outputs op = TestUtils.run("--draw-priority=" + pri,
85 Outputs op = TestUtils.runAsProcess("--draw-priority=" + pri,
8686 Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz");
87 op.checkNoError();
87 op.checkError("Number of ExitExceptions: 0");
8888
8989 FileSystem fs = openFs(Args.DEF_MAP_FILENAME);
9090 ImgChannel chan = fs.open(Args.DEF_MAP_ID + ".TRE", "r");
9595
9696 @Test
9797 public void testNoDescription() {
98 Outputs op = TestUtils.run("--description", Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz");
99 op.checkNoError();
98 Outputs op = TestUtils.runAsProcess("--description", Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz");
99 op.checkError("Number of ExitExceptions: 0");
100100 }
101101 }
400400 "--latin1",
401401 Args.TEST_RESOURCE_OSM + "uk-test-2.osm.gz");
402402
403 Outputs outputs = TestUtils.run(Args.TEST_STYLE_ARG,
403 Outputs outputs = TestUtils.runAsProcess(Args.TEST_STYLE_ARG,
404404 "--gmapsupp",
405405 "--index",
406406
3535 f.delete();
3636 assertFalse("does not pre-exist", f.exists());
3737
38 Outputs outputs = TestUtils.run(
38 Outputs outputs = TestUtils.runAsProcess(
3939 Args.TEST_STYLE_ARG,
4040 "--index",
4141 "--latin1",
4444 Args.TEST_RESOURCE_IMG + "63240001.img",
4545 Args.TEST_RESOURCE_IMG + "63240002.img"
4646 );
47 outputs.checkNoError();
47 outputs.checkError("Number of ExitExceptions: 0");
4848
4949 TestUtils.registerFile(MDR_IMG);
5050 TestUtils.registerFile(OVERVIEW_NAME+".tdb");
1515 */
1616 package func.lib;
1717
18 import static org.junit.Assert.*;
18 import static org.junit.Assert.assertEquals;
19
20 import java.util.Arrays;
21 import java.util.stream.Collectors;
1922
2023 /**
2124 * Standard output and error as produced during a run.
3639 }
3740
3841 protected String getErr() {
39 return err;
42 // filter possible lines added by set JRE option _JAVA_OPTIONS=... which cases
43 // a line "Picked up _JAVA_OPTIONS:" in stderr
44 return Arrays.stream(err.split("\n"))
45 .filter(line -> !line.contains("_JAVA_OPTIONS"))
46 .collect(Collectors.joining("\n"));
4047 }
4148
4249 /**
1515 */
1616 package func.lib;
1717
18 import java.io.BufferedReader;
1819 import java.io.ByteArrayOutputStream;
1920 import java.io.Closeable;
2021 import java.io.File;
2122 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
2225 import java.io.OutputStream;
2326 import java.io.PrintStream;
2427 import java.util.ArrayDeque;
2730 import java.util.Collections;
2831 import java.util.Deque;
2932 import java.util.List;
33 import java.util.concurrent.TimeUnit;
3034
3135 import uk.me.parabola.imgfmt.Utils;
3236 import uk.me.parabola.mkgmap.general.LevelInfo;
135139 }
136140
137141 /**
142 * Run with the given args as a new process. Some standard arguments are added first.
143 *
144 * @param in The arguments to use.
145 */
146 public static Outputs runAsProcess(String ... in) {
147 List<String> args = new ArrayList<>(Arrays.asList(
148 "java",
149 "-classpath",
150 "build/classes" + File.pathSeparator + "lib/compile/*",
151 "uk.me.parabola.mkgmap.main.Main",
152 Args.TEST_STYLE_ARG
153 ));
154 args.addAll(Arrays.asList(in));
155 ProcessBuilder pb = new ProcessBuilder(args);
156 StringBuilder outBuilder = new StringBuilder();
157 StringBuilder errBuilder = new StringBuilder();
158 try {
159 Process process = pb.start();
160 try (BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
161 BufferedReader outputStream = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
162 while (true) {
163 getStreamOutput(outputStream, outBuilder);
164 getStreamOutput(errorStream, errBuilder);
165 if (process.waitFor(1, TimeUnit.MILLISECONDS)) {
166 getStreamOutput(outputStream, outBuilder);
167 getStreamOutput(errorStream, errBuilder);
168 break;
169 }
170 }
171 }
172 } catch (IOException e) {
173 // do nothing
174 } catch (InterruptedException e) {
175 Thread.currentThread().interrupt();
176 }
177 return new Outputs(outBuilder.toString(), errBuilder.toString());
178 }
179
180 private static void getStreamOutput(BufferedReader stream, StringBuilder stringBuilder) throws IOException {
181 char[] buff = new char[100000];
182 while (stream.ready()) {
183 int count = stream.read(buff);
184 if (count > 0)
185 stringBuilder.append(buff, 0, count);
186 }
187 }
188
189 /**
138190 * Create a rule set out of a string. The string is processed
139191 * as if it were in a file and the levels spec had been set.
140192 */
1111 */
1212 package main;
1313
14 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
15 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.AND;
16 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.EXISTS;
17 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.FUNCTION;
18 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.GTE;
19 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.NOT;
20 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.NOT_EQUALS;
21 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.NOT_EXISTS;
22 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.OR;
23 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.VALUE;
24
1425 import java.io.BufferedWriter;
1526 import java.io.ByteArrayOutputStream;
1627 import java.io.File;
2031 import java.io.PrintStream;
2132 import java.io.StringReader;
2233 import java.io.UnsupportedEncodingException;
34 import java.math.BigInteger;
2335 import java.nio.file.Files;
2436 import java.nio.file.Paths;
2537 import java.security.MessageDigest;
3951 import java.util.concurrent.TimeUnit;
4052 import java.util.concurrent.TimeoutException;
4153 import java.util.function.BiFunction;
42
43 import javax.xml.bind.DatatypeConverter;
4454
4555 import uk.me.parabola.imgfmt.app.Coord;
4656 import uk.me.parabola.mkgmap.main.StyleTester;
6676 import uk.me.parabola.mkgmap.reader.osm.Way;
6777 import uk.me.parabola.mkgmap.scan.SyntaxException;
6878 import uk.me.parabola.mkgmap.scan.TokenScanner;
69
70 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
71 import static uk.me.parabola.mkgmap.osmstyle.eval.NodeType.*;
7279
7380 public class RulesTest {
7481 private static final Random rand = new Random();
347354 try {
348355 MessageDigest md5 = MessageDigest.getInstance("md5");
349356 byte[] digest = md5.digest(rule.getBytes("utf-8"));
350 String s = DatatypeConverter.printHexBinary(digest).substring(0, 8);
357 String s = String.format("%032x", new BigInteger(1, digest)).substring(0, 8);
351358 fileName = String.format("t-%s.test", s);
352359 } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
353360 fileName = String.format("t-%06d.test", id);