New upstream version 0.0.0+svn4680
Bas Couwenberg
2 years ago
306 | 306 | <mkdir dir="test/resources/in/osm"/> |
307 | 307 | <mkdir dir="test/resources/in/mp"/> |
308 | 308 | <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" | |
310 | 310 | dest="test/resources/in/osm/lon1.osm.gz" usetimestamp="true" |
311 | 311 | 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" | |
313 | 313 | dest="test/resources/in/osm/uk-test-1.osm.gz" usetimestamp="true" |
314 | 314 | 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" | |
316 | 316 | dest="test/resources/in/osm/uk-test-2.osm.gz" usetimestamp="true" |
317 | 317 | 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" | |
319 | 319 | dest="test/resources/in/osm/is-in-samples.osm" usetimestamp="true" |
320 | 320 | 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" | |
322 | 322 | dest="test/resources/in/mp/test1.mp" usetimestamp="true" |
323 | 323 | 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" | |
325 | 325 | dest="test/resources/in/img/63240001.img" usetimestamp="true" |
326 | 326 | 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" | |
328 | 328 | dest="test/resources/in/img/63240002.img" usetimestamp="true" |
329 | 329 | 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" | |
331 | 331 | dest="test/resources/in/img/63240003.img" usetimestamp="true" |
332 | 332 | 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" | |
334 | 334 | dest="test/resources/in/hgt/N00W090.hgt.zip" usetimestamp="true" |
335 | 335 | 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" | |
337 | 337 | dest="test/resources/in/hgt/N00W091.hgt.zip" usetimestamp="true" |
338 | 338 | 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" | |
340 | 340 | dest="test/resources/in/hgt/S01W090.hgt.zip" usetimestamp="true" |
341 | 341 | 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" | |
343 | 343 | dest="test/resources/in/hgt/S01W091.hgt.zip" usetimestamp="true" |
344 | 344 | 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" | |
346 | 346 | dest="test/resources/in/hgt/S02W090.hgt.zip" usetimestamp="true" |
347 | 347 | 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" | |
349 | 349 | dest="test/resources/in/hgt/S02W091.hgt.zip" usetimestamp="true" |
350 | 350 | ignoreerrors="true"/> |
351 | 351 | </target> |
11 | 11 | <pre> |
12 | 12 | # The default level FINE, WARNING, INFO, SEVERE |
13 | 13 | .level=SEVERE |
14 | #handlers: java.util.logging.ConsoleHandler | |
15 | 14 | handlers: java.util.logging.FileHandler java.util.logging.ConsoleHandler |
16 | 15 | # package or class name with .level appended and then the level |
17 | 16 | uk.me.parabola.imgfmt.level=INFO |
38 | 37 | java.util.logging.FileHandler.append=false |
39 | 38 | </pre> |
40 | 39 | |
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. | |
43 | 52 | |
44 | 53 | Further information can be found at |
45 | 54 | [https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html] |
46 | 55 | |
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. |
616 | 616 | |
617 | 617 | === Diagnostic options === |
618 | 618 | |
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 | ||
619 | 623 | ;--check-roundabouts |
620 | 624 | : Check that roundabouts have the expected direction (clockwise |
621 | 625 | when vehicles drive on the left). Roundabouts that are complete |
636 | 640 | problems. Default value is 0 (disabled) because it's not a |
637 | 641 | completely reliable heuristic. |
638 | 642 | |
639 | ;--check-routing-island-len=INTEGER | |
643 | ;--report-routing-islands | |
640 | 644 | : Routing islands are small road networks which are not connected to other |
641 | 645 | roads. A typical case is a footway that is not connected to the main road |
642 | 646 | network, or a small set of ways on the inner courtyard of a large building. |
643 | 647 | : These islands can cause problems if you try to calculate a route and the GPS |
644 | 648 | selects a point on the island as a start or end. It will fail to calculate the |
645 | 649 | 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. | |
657 | 652 | |
658 | 653 | ;--report-similar-arcs |
659 | 654 | : Issue a warning when more than one arc connects two nodes and |
660 | 655 | 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 | |
667 | 660 | 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) | |
670 | 663 | :* 2 = also report on individual one-way roads that go nowhere. |
671 | 664 | |
672 | 665 | ;--dead-ends[=key[=value]][,key[=value]...] |
980 | 973 | The tag mkgmap:drawLevel can be used to override the |
981 | 974 | natural area of a polygon, so forcing changes to the rendering order. |
982 | 975 | |
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 | ||
983 | 993 | === 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. | |
984 | 999 | |
985 | 1000 | ;--drive-on-left |
986 | 1001 | ;--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. | |
989 | 1004 | |
990 | 1005 | ;--make-all-cycleways |
991 | 1006 | : Deprecated; use --make-opposite-cycleways instead. Former meaning: |
524 | 524 | that the first member is the start of the route. |
525 | 525 | |
526 | 526 | === 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). | |
529 | 531 | [source] |
530 | 532 | highway=motorway_link & oneway!=* { echo "motorway_link without oneway tag" } |
531 | 533 | |
532 | 534 | === 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). | |
535 | 539 | [source] |
536 | 540 | highway=living_street { echotags "This is a living_street" } |
537 | 541 |
0 | 0 | <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" /> | |
2 | 2 | <settings defaultResolver="custom" /> |
3 | 3 | |
4 | 4 | <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/> |
22 | 22 | <ibiblio name="geotools-resolver" m2compatible="true" root="https://repo.osgeo.org/repository/release/" /> |
23 | 23 | |
24 | 24 | <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]" /> | |
27 | 27 | </url> |
28 | 28 | |
29 | 29 | </resolvers> |
607 | 607 | |
608 | 608 | === Diagnostic options === |
609 | 609 | |
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 | ||
610 | 614 | --check-roundabouts |
611 | 615 | Check that roundabouts have the expected direction (clockwise when vehicles |
612 | 616 | drive on the left). Roundabouts that are complete loops and have the wrong |
626 | 630 | problems. Default value is 0 (disabled) because it's not a completely |
627 | 631 | reliable heuristic. |
628 | 632 | |
629 | --check-routing-island-len=INTEGER | |
633 | --report-routing-islands | |
630 | 634 | Routing islands are small road networks which are not connected to other |
631 | 635 | roads. A typical case is a footway that is not connected to the main road |
632 | 636 | network, or a small set of ways on the inner courtyard of a large building. |
633 | 637 | These islands can cause problems if you try to calculate a route and the |
634 | 638 | GPS selects a point on the island as a start or end. It will fail to |
635 | 639 | 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. | |
647 | 642 | |
648 | 643 | --report-similar-arcs |
649 | 644 | 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) | |
658 | 653 | * 2 = also report on individual one-way roads that go nowhere. |
659 | 654 | |
660 | 655 | --dead-ends[=key[=value]][,key[=value]...] |
964 | 959 | The tag mkgmap:drawLevel can be used to override the natural area of a |
965 | 960 | polygon, so forcing changes to the rendering order. |
966 | 961 | |
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 | ||
967 | 979 | === 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. | |
968 | 985 | |
969 | 986 | --drive-on-left |
970 | 987 | --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. | |
973 | 990 | |
974 | 991 | --make-all-cycleways |
975 | 992 | 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. | |
1 | 1 | # This is a list of all hgt files |
2 | 2 | # to compile it use |
3 | 3 | # java -cp mkgmap.jar uk.me.parabola.mkgmap.reader.hgt.HGTList compile known-hgt.txt |
10391 | 10391 | N60E154 |
10392 | 10392 | N60E155 |
10393 | 10393 | N60E156 |
10394 | N60E157 | |
10395 | 10394 | N60E159 |
10396 | 10395 | N60E160 |
10397 | 10396 | N60E161 |
11668 | 11667 | N64W174 |
11669 | 11668 | N64W175 |
11670 | 11669 | N64W176 |
11671 | N64W180 | |
11672 | 11670 | N65E010 |
11673 | 11671 | N65E011 |
11674 | 11672 | N65E012 |
13626 | 13624 | N72E054 |
13627 | 13625 | N72E055 |
13628 | 13626 | N72E056 |
13629 | N72E057 | |
13630 | 13627 | N72E068 |
13631 | 13628 | N72E069 |
13632 | 13629 | N72E070 |
14402 | 14399 | N77E025 |
14403 | 14400 | N77E067 |
14404 | 14401 | N77E082 |
14405 | N77E083 | |
14406 | 14402 | N77E088 |
14407 | 14403 | N77E089 |
14408 | 14404 | 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 |
30 | 30 | |
31 | 31 | import uk.me.parabola.imgfmt.app.Coord; |
32 | 32 | import uk.me.parabola.imgfmt.app.ImgFileWriter; |
33 | import uk.me.parabola.log.Logger; | |
33 | 34 | /** |
34 | 35 | * Some miscellaneous functions that are used within the .img code. |
35 | 36 | * |
188 | 189 | try { |
189 | 190 | f.close(); |
190 | 191 | } catch (IOException e) { |
191 | e.printStackTrace(); | |
192 | Logger.defaultLogger.error("Error closing file", e); | |
192 | 193 | } |
193 | 194 | } |
194 | 195 | } |
23 | 23 | import uk.me.parabola.imgfmt.Sized; |
24 | 24 | import uk.me.parabola.imgfmt.fs.ImgChannel; |
25 | 25 | import uk.me.parabola.imgfmt.sys.FileLink; |
26 | import uk.me.parabola.log.Logger; | |
26 | 27 | |
27 | 28 | /** |
28 | 29 | * Write img file data to a temporary file. On a call to sync() the data |
69 | 70 | channel.transferTo(0, channel.size(), outputChan); |
70 | 71 | } finally { |
71 | 72 | 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()); | |
73 | 74 | } |
74 | 75 | } |
75 | 76 |
28 | 28 | import uk.me.parabola.imgfmt.app.labelenc.DecodedText; |
29 | 29 | import uk.me.parabola.imgfmt.app.trergn.Subdivision; |
30 | 30 | import uk.me.parabola.imgfmt.fs.ImgChannel; |
31 | import uk.me.parabola.log.Logger; | |
31 | 32 | |
32 | 33 | import static uk.me.parabola.imgfmt.app.Label.NULL_LABEL; |
33 | 34 | |
443 | 444 | } |
444 | 445 | |
445 | 446 | if (hasTides) { |
446 | System.out.println("Map has tide prediction, please implement!"); | |
447 | Logger.defaultLogger.warn("Map has tide prediction, please implement!"); | |
447 | 448 | } |
448 | 449 | |
449 | 450 | pois.put(poiOffset, poi); |
27 | 27 | import uk.me.parabola.imgfmt.app.srt.Sort; |
28 | 28 | import uk.me.parabola.imgfmt.app.trergn.Point; |
29 | 29 | import uk.me.parabola.imgfmt.fs.ImgChannel; |
30 | import uk.me.parabola.log.Logger; | |
30 | 31 | |
31 | 32 | /** |
32 | 33 | * The MDR file. This is embedded into a .img file, either its own |
149 | 150 | Sort sort = mdrHeader.getSort(); |
150 | 151 | |
151 | 152 | 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"); | |
153 | 154 | } |
154 | 155 | |
155 | 156 | public Mdr14Record addCountry(Country country) { |
0 | 0 | package uk.me.parabola.imgfmt.app.net; |
1 | ||
2 | import uk.me.parabola.log.Logger; | |
1 | 3 | |
2 | 4 | /** |
3 | 5 | * The number style down one side of a side of a road. |
62 | 64 | case 'O': return ODD; |
63 | 65 | case 'B': return BOTH; |
64 | 66 | 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"); | |
66 | 68 | return ODD; |
67 | 69 | default: return NONE; |
68 | 70 | } |
60 | 60 | private int maxFlareLengthRatio ; |
61 | 61 | private boolean reportSimilarArcs; |
62 | 62 | private boolean routable; |
63 | ||
64 | private long maxSumRoadLenghts; | |
63 | private boolean reportRoutingIslands; | |
64 | private long maxSumRoadLengths; | |
65 | 65 | /** for route island search */ |
66 | 66 | private int visitId; |
67 | 67 | |
70 | 70 | checkRoundaboutFlares = props.getProperty("check-roundabout-flares", false); |
71 | 71 | maxFlareLengthRatio = props.getProperty("max-flare-length-ratio", 0); |
72 | 72 | 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); | |
74 | 81 | routable = props.containsKey("route"); |
75 | 82 | angleChecker.config(props); |
76 | 83 | } |
302 | 309 | * report routing islands and maybe remove them from NOD. |
303 | 310 | */ |
304 | 311 | private void checkRoutingIslands() { |
305 | if (maxSumRoadLenghts < 0) | |
312 | if (maxSumRoadLengths <= 0 && !reportRoutingIslands) | |
306 | 313 | return; // island check is disabled |
314 | ||
307 | 315 | long t1 = System.currentTimeMillis(); |
308 | 316 | |
309 | 317 | // calculate all islands |
313 | 321 | if (!islands.isEmpty()) { |
314 | 322 | analyseIslands(islands); |
315 | 323 | } |
316 | if (maxSumRoadLenghts > 0) { | |
324 | if (maxSumRoadLengths > 0) { | |
317 | 325 | long t3 = System.currentTimeMillis(); |
318 | 326 | log.info("routing island removal took", (t3 - t2), "ms"); |
319 | 327 | } |
349 | 357 | for (List<RouteNode> island : islands) { |
350 | 358 | // compute size of island as sum of road lengths |
351 | 359 | 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) { | |
356 | 365 | // set discarded flag for all nodes of the island |
357 | 366 | island.forEach(RouteNode::discard); |
358 | 367 | visitedRoads.forEach(rd -> rd.skipAddToNOD(true)); |
320 | 320 | } else { |
321 | 321 | writer.put(directionFromDegrees(initialHeading)); |
322 | 322 | } |
323 | } else { | |
324 | // System.out.println("skipped writing of initial dir"); | |
325 | 323 | } |
326 | 324 | if (haveCurve) { |
327 | 325 | int[] curvedat = encodeCurve(); |
387 | 387 | // non roundabout highway overlaps roundabout |
388 | 388 | nonRoundaboutArcs.remove(ra1); |
389 | 389 | 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()); | |
391 | 391 | break; |
392 | 392 | } |
393 | 393 | } |
460 | 460 | |
461 | 461 | RouteArc roundaboutArc = roundaboutArcs.get(0); |
462 | 462 | 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()); | |
464 | 464 | 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()); | |
466 | 466 | else if (countNonRoundaboutRoads == 1) { |
467 | 467 | if (countNonRoundaboutOtherHighways > 0) { |
468 | 468 | 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()); | |
470 | 470 | 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()); | |
472 | 472 | } |
473 | 473 | 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()); | |
475 | 475 | } |
476 | 476 | else if (countNonRoundaboutOtherHighways > 0) { |
477 | 477 | 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()); | |
479 | 479 | 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()); | |
481 | 481 | } |
482 | 482 | 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()); | |
484 | 484 | if(roundaboutArcs.size() > 2) { |
485 | 485 | for(RouteArc fa : roundaboutArcs) { |
486 | 486 | if(fa.isForward()) { |
491 | 491 | ((fb.isForward() && fb.getDest() == fa.getDest()) || |
492 | 492 | (!fb.isForward() && fb.getSource() == fa.getDest()))) { |
493 | 493 | 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()); | |
495 | 495 | } |
496 | 496 | } |
497 | 497 | else if (fb.isForward() |
498 | 498 | && !rd.messagePreviouslyIssued("roundabout forks/overlaps")) { |
499 | log.warn("Roundabout " + rd + " forks at " + coord.toOSMURL()); | |
499 | log.diagnostic("Roundabout " + rd + " forks at " + coord.toOSMURL()); | |
500 | 500 | } |
501 | 501 | } |
502 | 502 | } |
640 | 640 | |
641 | 641 | // only issue one warning per flare |
642 | 642 | 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()); | |
644 | 644 | 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()); | |
646 | 646 | 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()); | |
648 | 648 | |
649 | 649 | 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()); | |
651 | 651 | else { |
652 | 652 | // check that the flare road arcs are not |
653 | 653 | // part of a longer way |
654 | 654 | for(RouteArc a : fa.getDest().arcs) { |
655 | 655 | if(a.isDirect() && a.getDest() != this && a.getDest() != nb) { |
656 | 656 | 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()); | |
658 | 658 | 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()); | |
660 | 660 | } |
661 | 661 | } |
662 | 662 | } |
669 | 669 | public void reportSimilarArcs() { |
670 | 670 | for(int i = 0; i < arcs.size(); ++i) { |
671 | 671 | RouteArc arci = arcs.get(i); |
672 | if (!arci.isDirect()) | |
672 | RoadDef rdi = arci.getRoadDef(); | |
673 | if (!arci.isDirect() || rdi.isSynthesised()) | |
673 | 674 | continue; |
674 | 675 | for(int j = i + 1; j < arcs.size(); ++j) { |
675 | 676 | RouteArc arcj = arcs.get(j); |
676 | if (!arcj.isDirect()) | |
677 | RoadDef rdj = arcj.getRoadDef(); | |
678 | if (!arcj.isDirect() || rdj.isSynthesised()) | |
677 | 679 | continue; |
678 | 680 | if(arci.getDest() == arcj.getDest() && |
679 | 681 | 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()); | |
682 | 685 | } |
683 | 686 | } |
684 | 687 | } |
1114 | 1114 | range = Double.parseDouble(parts[1]); |
1115 | 1115 | if(parts.length > 2) |
1116 | 1116 | angle = Double.parseDouble(parts[2]); |
1117 | ||
1118 | //System.err.println("light = " + this); | |
1119 | 1117 | } |
1120 | 1118 | |
1121 | 1119 | public String toString() { |
74 | 74 | BitWriter bsBest = bsSimple; |
75 | 75 | int xBestBase = xBase; |
76 | 76 | int yBestBase = yBase; |
77 | if (xBase > 0 || yBase > 0 && log.isDebugEnabled()) { | |
77 | if ((xBase > 0 || yBase > 0) && log.isDebugEnabled()) { | |
78 | 78 | log.debug("start opt:", xBase, yBase, xSameSign, xSignNegative, ySameSign, ySignNegative); |
79 | 79 | } |
80 | 80 | if (xBase > 0){ |
81 | 81 | int notBetter = 0; |
82 | int xTestBase = xBase-1; | |
82 | 83 | 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--){ | |
85 | 89 | BitWriter bstest = makeBitStream(minPointsRequired, xTestBase, yBase); |
86 | if (bstest.getBitPosition() >= bsBest.getBitPosition() ){ | |
90 | if (bstest.getBitPosition() >= bsBest.getBitPosition()){ | |
87 | 91 | if (++notBetter >= 2) |
88 | 92 | break; // give up |
89 | 93 | } else { |
96 | 100 | } |
97 | 101 | if (yBase > 0){ |
98 | 102 | int notBetter = 0; |
103 | int yTestBase = yBase-1; | |
99 | 104 | 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--){ | |
102 | 110 | BitWriter bstest = makeBitStream(minPointsRequired, xBestBase, yTestBase); |
103 | 111 | if (bstest.getBitPosition() >= bsBest.getBitPosition()){ |
104 | 112 | if (++notBetter >= 2) |
111 | 119 | } |
112 | 120 | ySameSign = ySameSignBak; |
113 | 121 | } |
114 | if (xBase != xBestBase || yBestBase != yBase && log.isInfoEnabled()) { | |
122 | if ((xBase != xBestBase || yBestBase != yBase) && log.isInfoEnabled()) { | |
115 | 123 | if (bsSimple.getLength() > bsBest.getLength()) |
116 | 124 | 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"); |
117 | 125 | else |
251 | 259 | // OK go through the points |
252 | 260 | int lastLat = 0; |
253 | 261 | 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; | |
256 | 264 | // index of first point in a series of identical coords (after shift) |
257 | 265 | int firstsame = 0; |
258 | 266 | for (int i = 0; i < numPointsToUse; i++) { |
135 | 135 | } catch (CharacterCodingException ignore) { |
136 | 136 | //ignore.printStackTrace(); |
137 | 137 | String name = encoder.charset().name(); |
138 | //System.out.println("cs " + name); | |
139 | 138 | log.warn("Cannot represent String", tl.getText(), "for language", tl.getLang(), "in CodePage", name); |
140 | 139 | //throw new TypLabelException(name); |
141 | 140 | } |
21 | 21 | import java.nio.channels.WritableByteChannel; |
22 | 22 | import java.util.ArrayList; |
23 | 23 | import java.util.List; |
24 | ||
25 | import uk.me.parabola.log.Logger; | |
24 | 26 | |
25 | 27 | /** |
26 | 28 | * The MDX index file. Used with the global index. This is located |
102 | 104 | // Although its not necessarily wrong for them to be zero, it probably |
103 | 105 | // sign that something is wrong. |
104 | 106 | 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"); | |
106 | 108 | |
107 | 109 | buf.compact(); |
108 | 110 | info.write(buf); |
100 | 100 | FileChannel chan = FileChannel.open(Paths.get(filename), OPEN_CREATE_RW); |
101 | 101 | return createFs(chan, params); |
102 | 102 | } catch (IOException e) { |
103 | throw new FileNotWritableException("Could not create file: " + params.getFilename(), e); | |
103 | throw new FileNotWritableException("Could not create file", e); | |
104 | 104 | } |
105 | 105 | } |
106 | 106 |
187 | 187 | */ |
188 | 188 | private void writeSizeValues(int blockSize) { |
189 | 189 | int endSector = (int) (((numBlocks+1L) * blockSize + 511) / 512); |
190 | //System.out.printf("end sector %d %x\n", endSector, endSector); | |
191 | 190 | |
192 | 191 | // We have three maximum values for sectors, heads and cylinders. We attempt to find values |
193 | 192 | // for them that are larger than the |
204 | 203 | for (int s : asList(4, 8, 16, 32)) { |
205 | 204 | for (int c : asList(0x20, 0x40, 0x80, 0x100, 0x200, 0x3ff)) { |
206 | 205 | log.info("shc=", s + "," + h + "," + c, "end=", endSector); |
207 | //System.out.println("shc=" + s + "," + h + "," + c + "end=" + endSector); | |
208 | 206 | if (s * h * c > endSector) { |
209 | 207 | headsPerCylinder = h; |
210 | 208 | 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 | } |
34 | 34 | */ |
35 | 35 | public class Logger { |
36 | 36 | 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); | |
37 | 39 | |
38 | 40 | private static final ThreadLocal<String> threadTags = new ThreadLocal<>(); |
39 | 41 | |
41 | 43 | initLogging(); |
42 | 44 | } |
43 | 45 | |
44 | private Logger(String name) { | |
46 | private Logger(String name, boolean addPrefix) { | |
45 | 47 | this.log = java.util.logging.Logger.getLogger(name); |
48 | this.addPrefix = addPrefix; | |
46 | 49 | } |
47 | 50 | |
48 | 51 | /** |
54 | 57 | * @return The logger. |
55 | 58 | */ |
56 | 59 | public static Logger getLogger(String name) { |
57 | return new Logger(name); | |
60 | return new Logger(name, true); | |
58 | 61 | } |
59 | 62 | |
60 | 63 | /** |
82 | 85 | else { |
83 | 86 | staticSetup(); |
84 | 87 | } |
88 | if (!defaultLogger.isLoggable(Level.WARNING)) | |
89 | defaultLogger.log.setLevel(Level.WARNING); | |
85 | 90 | } |
86 | 91 | |
87 | 92 | private static void initLoggingFromFile(String logconf) { |
113 | 118 | f.setShowTime(false); |
114 | 119 | |
115 | 120 | handler.setFormatter(f); |
116 | handler.setLevel(Level.SEVERE); | |
121 | handler.setLevel(Level.FINE); | |
117 | 122 | |
118 | 123 | l.addHandler(handler); |
119 | l.setLevel(Level.WARNING); | |
124 | l.setLevel(Level.SEVERE); | |
120 | 125 | } |
121 | 126 | |
122 | 127 | public boolean isLoggable(Level level) { |
176 | 181 | } |
177 | 182 | |
178 | 183 | 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())); | |
180 | 186 | } |
181 | 187 | |
182 | 188 | public void warn(Object ... olist) { |
194 | 200 | } |
195 | 201 | |
196 | 202 | public void error(Object ... olist) { |
197 | arrayFormat(Level.SEVERE, olist); | |
198 | } | |
203 | arrayFormat(Level.SEVERE, olist); | |
204 | } | |
205 | ||
199 | 206 | public void errorf(String fmt, Object... args) { |
200 | 207 | printf(Level.SEVERE, fmt, args); |
201 | 208 | } |
203 | 210 | public void error(Object o, Throwable e) { |
204 | 211 | log.log(Level.SEVERE, tagMessage(o == null? "null" : o.toString()), e); |
205 | 212 | } |
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 | } | |
206 | 228 | |
207 | 229 | public void log(Level level, Object o) { |
208 | 230 | if (log.isLoggable(level)) |
225 | 247 | * @param olist The argument list as objects. |
226 | 248 | */ |
227 | 249 | 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 | } | |
237 | 259 | } |
238 | 260 | |
239 | 261 | 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 | ||
245 | 272 | String threadTag = threadTags.get(); |
246 | 273 | return (threadTag != null) ? threadTag + ": " + message : message; |
247 | 274 | } |
19 | 19 | import java.io.StringWriter; |
20 | 20 | import java.util.Calendar; |
21 | 21 | import java.util.logging.Formatter; |
22 | import java.util.logging.Level; | |
22 | 23 | import java.util.logging.LogRecord; |
23 | 24 | |
24 | 25 | /** |
37 | 38 | public String format(LogRecord record) { |
38 | 39 | StringBuffer sb = new StringBuffer(); |
39 | 40 | |
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("): "); | |
56 | 64 | } |
57 | ||
58 | sb.append(record.getLevel().getLocalizedName()); | |
59 | sb.append(" ("); | |
60 | sb.append(shortName(record.getLoggerName())); | |
61 | sb.append("): "); | |
62 | ||
63 | 65 | sb.append(record.getMessage()); |
64 | 66 | |
65 | 67 | sb.append(lineSeparator); |
10 | 10 | |
11 | 11 | import uk.me.parabola.imgfmt.ExitException; |
12 | 12 | import uk.me.parabola.imgfmt.app.srt.Sort; |
13 | import uk.me.parabola.log.Logger; | |
13 | 14 | import uk.me.parabola.util.EnhancedProperties; |
14 | 15 | |
15 | 16 | public class CommandArgs { |
90 | 91 | } |
91 | 92 | |
92 | 93 | 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 | ||
96 | 99 | // Test if directory exists |
97 | 100 | File outputDir = new File(fileOutputDir); |
98 | 101 | 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); | |
104 | 109 | } |
105 | 110 | } 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."); | |
108 | 112 | } |
109 | ||
113 | ||
110 | 114 | return fileOutputDir; |
111 | 115 | } |
112 | 116 |
16 | 16 | package uk.me.parabola.mkgmap; |
17 | 17 | |
18 | 18 | import java.io.File; |
19 | import java.io.IOException; | |
20 | 19 | import java.util.ArrayList; |
21 | 20 | import java.util.Formatter; |
22 | 21 | import java.util.Iterator; |
46 | 45 | private final ArgumentProcessor proc; |
47 | 46 | |
48 | 47 | private boolean mapnameWasSet; |
48 | private boolean hasFiles = false; | |
49 | 49 | |
50 | 50 | private final ArgList arglist = new ArgList(); |
51 | 51 | |
108 | 108 | |
109 | 109 | } else { |
110 | 110 | log.debug("adding filename:", arg); |
111 | hasFiles = true; | |
111 | 112 | add(new Filename(arg)); |
112 | 113 | } |
113 | 114 | } |
124 | 125 | proc.endOptions(new CommandArgs(this.args)); |
125 | 126 | } |
126 | 127 | |
128 | public boolean getHasFiles() { | |
129 | return hasFiles; | |
130 | } | |
127 | 131 | |
128 | 132 | /** |
129 | 133 | * Add an option based on the option and value separately. |
201 | 205 | case "input-file": |
202 | 206 | if (value != null){ |
203 | 207 | log.debug("adding filename", value); |
208 | hasFiles = true; | |
204 | 209 | add(new Filename(value)); |
205 | 210 | } |
206 | 211 | break; |
186 | 186 | { |
187 | 187 | String[] cityList = p.getIsIn().split(","); |
188 | 188 | |
189 | //System.out.println(p.getIsIn()); | |
190 | ||
191 | 189 | // is_in content is not well defined so we try our best to get some info out of it |
192 | 190 | // Format 1 popular in Germany: "County,State,Country,Continent" |
193 | 191 |
179 | 179 | } |
180 | 180 | else |
181 | 181 | { |
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 | } | |
185 | 185 | catch (Exception ex) |
186 | 186 | { |
187 | ex.printStackTrace(); | |
188 | //System.out.println("Something is wrong here"); | |
187 | Logger.defaultLogger.error("Unexpected error reading " + fileName, ex); | |
189 | 188 | } |
190 | 189 | } |
191 | 190 |
25 | 25 | import java.util.Objects; |
26 | 26 | |
27 | 27 | import uk.me.parabola.imgfmt.FileSystemParam; |
28 | import uk.me.parabola.imgfmt.MapFailedException; | |
28 | 29 | import uk.me.parabola.imgfmt.ReadFailedException; |
29 | 30 | import uk.me.parabola.imgfmt.Utils; |
30 | 31 | import uk.me.parabola.imgfmt.app.Area; |
163 | 164 | info = new FileInfo(inputName, UNKNOWN_KIND); |
164 | 165 | } |
165 | 166 | } catch (AssertionError | ReadFailedException e) { |
166 | throw new ReadFailedException("Could not read file " + inputName, e); | |
167 | throw new MapFailedException("Could not read file " + inputName, e); | |
167 | 168 | } |
168 | 169 | return info; |
169 | 170 | } |
203 | 204 | fr.position(0x15); |
204 | 205 | info.setCodePage(fr.get2u()); |
205 | 206 | } catch (IOException e) { |
206 | e.printStackTrace(); | |
207 | Logger.defaultLogger.error("Unexpected error reading " + filename, e); | |
207 | 208 | } |
208 | 209 | } |
209 | 210 |
98 | 98 | typFile = info.getFilename(); |
99 | 99 | |
100 | 100 | } catch (IOException e) { |
101 | e.printStackTrace(); | |
101 | throw new ExitException("Error saving gmapi data", e); | |
102 | 102 | } |
103 | 103 | } |
104 | 104 | |
130 | 130 | writeXmlFile(gmapDir); |
131 | 131 | |
132 | 132 | } catch (IOException e) { |
133 | e.printStackTrace(); | |
133 | throw new ExitException("Error building gmapi data", e); | |
134 | 134 | } |
135 | 135 | } |
136 | 136 |
59 | 59 | * @author Steve Ratcliffe |
60 | 60 | */ |
61 | 61 | public class GmapsuppBuilder implements Combiner { |
62 | private static final Logger log = Logger.getLogger(GmapsuppBuilder.class); | |
63 | ||
64 | 62 | private static final String GMAPSUPP = "gmapsupp.img"; |
65 | 63 | |
66 | 64 | private final Map<String, FileInfo> files = new LinkedHashMap<>(); |
120 | 118 | ImgChannel chan = imgFs.create(imgname); |
121 | 119 | mdrBuilder.initForDevice(chan, sort, mdrConfig); |
122 | 120 | } catch (FileExistsException e) { |
123 | System.err.println("Could not create duplicate MDR file"); | |
121 | Logger.defaultLogger.error("Could not create duplicate MDR file"); | |
124 | 122 | } |
125 | 123 | |
126 | 124 | mdrBuilderMap.put(familyId, mdrBuilder); |
139 | 137 | } |
140 | 138 | } else { |
141 | 139 | 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() + ")"); | |
144 | 141 | 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() + ")"); | |
147 | 143 | } |
148 | 144 | } |
149 | 145 | |
185 | 181 | writeMpsFile(); |
186 | 182 | |
187 | 183 | } 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"); | |
190 | 185 | } finally { |
191 | 186 | Utils.closeFile(imgFs); |
192 | 187 | } |
214 | 209 | // Do not close srtFile here |
215 | 210 | } catch (FileExistsException e) { |
216 | 211 | // 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"); | |
218 | 213 | throw new FileNotWritableException("already existed", e); |
219 | 214 | } |
220 | 215 | } |
285 | 280 | |
286 | 281 | ((FileLink)chan).link(sf, sync); |
287 | 282 | } catch (FileExistsException e) { |
288 | log.warn("Could not copy " + sf.getName(), e); | |
283 | Logger.defaultLogger.warn("Could not copy " + sf.getName(), e); | |
289 | 284 | } |
290 | 285 | } |
291 | 286 | } |
298 | 293 | ImgChannel chan = outfs.create(createImgFilename(filename)); |
299 | 294 | ((FileLink) chan).link(info.subFiles().get(0), fc.file(chan)); |
300 | 295 | } catch (FileExistsException e) { |
301 | log.warn("Counld not copy " + filename, e); | |
296 | Logger.defaultLogger.warn("Could not copy " + filename, e); | |
302 | 297 | } |
303 | 298 | } |
304 | 299 | |
318 | 313 | mpsFile.addProduct(b); |
319 | 314 | mr.close(); |
320 | 315 | } 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); | |
322 | 317 | } |
323 | 318 | } |
324 | 319 | |
339 | 334 | return new MpsFile(channel); |
340 | 335 | } catch (FileExistsException e) { |
341 | 336 | // 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"); | |
343 | 338 | throw new FileNotWritableException("already existed", e); |
344 | 339 | } |
345 | 340 | } |
26 | 26 | import java.util.Map; |
27 | 27 | |
28 | 28 | import uk.me.parabola.imgfmt.Utils; |
29 | import uk.me.parabola.log.Logger; | |
29 | 30 | import uk.me.parabola.mkgmap.CommandArgs; |
30 | 31 | import uk.me.parabola.mkgmap.Version; |
31 | 32 | |
94 | 95 | } catch (Exception ex) { |
95 | 96 | inStream = this.getClass().getResourceAsStream("/installer/installer_template.nsi"); |
96 | 97 | if (inStream == null) { |
97 | System.err.println("Could not find the installer template."); | |
98 | Logger.defaultLogger.error("Could not find the installer template."); | |
98 | 99 | return; |
99 | 100 | } |
100 | 101 | } |
117 | 118 | } |
118 | 119 | |
119 | 120 | } catch (IOException e) { |
120 | System.err.println("Could not write NSIS file"); | |
121 | Logger.defaultLogger.error("Could not write NSIS file"); | |
121 | 122 | } finally { |
122 | 123 | Utils.closeFile(inStream); |
123 | 124 | } |
181 | 182 | } catch (Exception ex) { |
182 | 183 | inStream = this.getClass().getResourceAsStream("/installer/license_template.txt"); |
183 | 184 | if (inStream == null) { |
184 | System.err.println("Could not find the license template."); | |
185 | Logger.defaultLogger.error("Could not find the license template."); | |
185 | 186 | return; |
186 | 187 | } |
187 | 188 | } |
197 | 198 | } |
198 | 199 | |
199 | 200 | } catch (IOException e) { |
200 | System.err.println("Could not write license file"); | |
201 | Logger.defaultLogger.error("Could not write license file"); | |
201 | 202 | } finally { |
202 | 203 | Utils.closeFile(inStream); |
203 | 204 | } |
214 | 214 | codepage = finfo.getCodePage(); |
215 | 215 | } |
216 | 216 | 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()); | |
218 | 218 | } |
219 | 219 | |
220 | 220 | try { |
224 | 224 | encodingType = mapReader.getEncodingType(); |
225 | 225 | } |
226 | 226 | 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); | |
228 | 228 | } |
229 | 229 | |
230 | 230 | String[] msgs = mapReader.getCopyrights(); |
323 | 323 | int min = levels[l].getLevel(); |
324 | 324 | int res = levels[l].getResolution(); |
325 | 325 | List<Polyline> lineList = mapReader.linesForLevel(min); |
326 | //System.out.println(lineList.size() + " lines in lowest resolution " + levels[1].getResolution()); | |
327 | 326 | for (Polyline line : lineList) { |
328 | 327 | if (log.isDebugEnabled()) |
329 | 328 | log.debug("got line", line); |
189 | 189 | try { |
190 | 190 | tdb.write(Utils.joinPath(outputDir, overviewMapname, "tdb")); |
191 | 191 | } catch (IOException e) { |
192 | log.error("tdb write", e); | |
193 | 192 | throw new ExitException("Could not write the TDB file", e); |
194 | 193 | } |
195 | 194 | } |
80 | 80 | */ |
81 | 81 | public class Main implements ArgumentProcessor { |
82 | 82 | private static final Logger log = Logger.getLogger(Main.class); |
83 | private static final Date StartTime = new Date(); | |
83 | 84 | |
84 | 85 | // Final .img file combiners. |
85 | 86 | private final List<Combiner> combiners = new ArrayList<>(); |
102 | 103 | private volatile int programRC = 0; |
103 | 104 | |
104 | 105 | private final Map<String, Combiner> combinerMap = new HashMap<>(); |
106 | private boolean informationDisplayed = false; | |
105 | 107 | |
106 | 108 | /** |
107 | 109 | * Used for unit tests |
125 | 127 | */ |
126 | 128 | private static int mainStart(String... args) { |
127 | 129 | Instant start = Instant.now(); |
128 | System.out.println("Time started: " + new Date()); | |
130 | ||
129 | 131 | // We need at least one argument. |
130 | 132 | if (args.length < 1) { |
131 | 133 | printUsage(); |
136 | 138 | Main mm = new Main(); |
137 | 139 | |
138 | 140 | int numExitExceptions = 0; |
141 | CommandArgsReader commandArgs = new CommandArgsReader(mm); | |
139 | 142 | try { |
140 | 143 | // Read the command line arguments and process each filename found. |
141 | CommandArgsReader commandArgs = new CommandArgsReader(mm); | |
142 | 144 | commandArgs.setValidOptions(getValidOptions(System.err)); |
143 | 145 | commandArgs.readArgs(args); |
144 | 146 | } catch (OutOfMemoryError e) { |
145 | 147 | ++numExitExceptions; |
146 | System.err.println(e); | |
148 | String message = "Out of memory.\r\n"; | |
147 | 149 | 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."; | |
149 | 151 | 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); | |
151 | 154 | } catch (MapFailedException | ExitException e) { |
152 | 155 | // one of the combiners failed |
153 | 156 | ++numExitExceptions; |
157 | 160 | message += "\r\n" + cause.toString(); |
158 | 161 | cause = cause.getCause(); |
159 | 162 | } |
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 | ||
186 | 190 | private static void printUsage (){ |
187 | 191 | System.err.println("Usage: mkgmap [options...] <file.osm>"); |
188 | 192 | } |
317 | 321 | |
318 | 322 | break; |
319 | 323 | case "help": |
324 | informationDisplayed = true; | |
320 | 325 | printHelp(System.out, getLang(), (!val.isEmpty()) ? val : "help"); |
321 | 326 | break; |
322 | 327 | case "style-file": |
330 | 335 | verbose = true; |
331 | 336 | break; |
332 | 337 | case "list-styles": |
338 | informationDisplayed = true; | |
333 | 339 | listStyles(); |
334 | 340 | break; |
335 | 341 | case "check-styles": |
342 | informationDisplayed = true; | |
336 | 343 | checkStyles(); |
337 | 344 | break; |
338 | 345 | case "max-jobs": |
341 | 348 | else { |
342 | 349 | maxJobs = Integer.parseInt(val); |
343 | 350 | 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"); | |
345 | 352 | maxJobs = 1; |
346 | 353 | } |
347 | 354 | 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"); | |
349 | 356 | } |
350 | 357 | break; |
351 | 358 | case "version": |
359 | informationDisplayed = true; | |
360 | System.err.println("Mkgmap version " + Version.VERSION); | |
352 | 361 | System.err.println(Version.VERSION); |
353 | 362 | System.exit(0); |
354 | 363 | } |
457 | 466 | try { |
458 | 467 | style = new StyleImpl(styleFile, name, new EnhancedProperties(), performChecks); |
459 | 468 | } catch (SyntaxException e) { |
460 | System.err.println("Error in style: " + e.getMessage()); | |
469 | Logger.defaultLogger.error("Error in style: " + e.getMessage()); | |
461 | 470 | } catch (FileNotFoundException e) { |
462 | 471 | log.debug("could not find style", name); |
463 | 472 | try { |
464 | 473 | searchedStyleName = new File(styleFile).getName(); |
465 | 474 | style = new StyleImpl(styleFile, null, new EnhancedProperties(), performChecks); |
466 | 475 | } catch (SyntaxException e1) { |
467 | System.err.println("Error in style: " + e1.getMessage()); | |
476 | Logger.defaultLogger.error("Error in style: " + e1.getMessage()); | |
468 | 477 | } catch (FileNotFoundException e1) { |
469 | 478 | log.debug("could not find style", styleFile); |
470 | 479 | } |
484 | 493 | public void endOptions(CommandArgs args) { |
485 | 494 | fileOptions(args); |
486 | 495 | |
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 | } | |
487 | 501 | log.info("Start tile processors"); |
488 | 502 | int threadCount = maxJobs; |
489 | int taskCount = futures.size(); | |
490 | 503 | Runtime runtime = Runtime.getRuntime(); |
491 | 504 | if (threadPool == null) { |
492 | 505 | if (threadCount == 0) { |
510 | 523 | } |
511 | 524 | threadCount = Math.max(threadCount, 1); |
512 | 525 | threadCount = Math.min(threadCount, runtime.availableProcessors()); |
513 | System.out.println("Setting max-jobs to " + threadCount); | |
526 | Logger.defaultLogger.warn("Setting max-jobs to " + threadCount); | |
514 | 527 | } |
515 | 528 | } |
516 | 529 | |
565 | 578 | throw new ExitException("Exiting - if you want to carry on regardless, use the --keep-going option"); |
566 | 579 | } |
567 | 580 | } catch (Exception e) { |
568 | e.printStackTrace(); | |
581 | Logger.defaultLogger.error("Unexpected error", e); | |
569 | 582 | throw new ExitException("Exiting due to unexpected error"); |
570 | 583 | } |
571 | 584 | } |
572 | 585 | } |
573 | System.out.println("Number of MapFailedExceptions: " + numMapFailedExceptions); | |
586 | Logger.defaultLogger.write("Number of MapFailedExceptions: " + numMapFailedExceptions); | |
574 | 587 | 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."); | |
576 | 589 | } |
577 | 590 | |
578 | 591 | if (combiners.isEmpty()) |
588 | 601 | hasFiles = true; |
589 | 602 | } |
590 | 603 | if (!hasFiles){ |
591 | log.warn("nothing to do for combiners."); | |
604 | log.info("nothing to do for combiners."); | |
592 | 605 | return; |
593 | 606 | } |
594 | 607 | log.info("Combining maps"); |
678 | 691 | if (f.exists() && f.isFile()) { |
679 | 692 | try { |
680 | 693 | Files.delete(f.toPath()); |
681 | log.warn("removed " + f); | |
694 | log.info("removed " + f); | |
682 | 695 | } catch (IOException e) { |
683 | 696 | log.warn("removing " + f + "failed with " + e.getMessage()); |
684 | 697 | } |
50 | 50 | |
51 | 51 | public String makeMap(CommandArgs args, String filename) { |
52 | 52 | 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); | |
54 | 54 | return filename; |
55 | 55 | } |
56 | 56 | try { |
68 | 68 | } |
69 | 69 | return makeMap(args, src, ""); |
70 | 70 | } 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); | |
73 | 72 | return filename; |
74 | 73 | } catch (FileNotFoundException e) { |
75 | System.err.println("Could not open file: " + filename); | |
74 | Logger.defaultLogger.error("Could not open file: " + filename); | |
76 | 75 | return filename; |
77 | 76 | } |
78 | 77 | } |
119 | 118 | map.close(); |
120 | 119 | return outName; |
121 | 120 | } catch (FileExistsException e) { |
122 | log.error("File exists already"); | |
121 | Logger.defaultLogger.error(e.getMessage()); | |
123 | 122 | throw new MapFailedException("File exists already", e); |
124 | 123 | } catch (FileNotWritableException e) { |
125 | log.error("Could not create or write to file"); | |
124 | Logger.defaultLogger.error(e.getMessage()); | |
126 | 125 | throw new MapFailedException("Could not create or write to file", e); |
127 | 126 | } |
128 | 127 | 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 | |
130 | 129 | throw e; |
131 | 130 | } |
132 | 131 | } |
41 | 41 | try (FileInputStream in = new FileInputStream(filename)) { |
42 | 42 | byte[] buf = new byte[256]; |
43 | 43 | int n = in.read(buf); |
44 | if (n == -1) | |
45 | throw new ExitException("TYP file is empty: " + filename); | |
44 | 46 | |
45 | 47 | ByteBuffer buffer = ByteBuffer.wrap(buf); |
46 | 48 | buffer.order(ByteOrder.LITTLE_ENDIAN); |
238 | 238 | try (InputStream is = this.getClass().getResourceAsStream("/styles/builtin-tag-list");) { |
239 | 239 | if (is != null) { |
240 | 240 | BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); |
241 | // System.out.println("Got built in list"); | |
242 | 241 | String line; |
243 | 242 | while ((line = br.readLine()) != null) { |
244 | 243 | line = line.trim(); |
245 | 244 | if (line.startsWith("#")) |
246 | 245 | continue; |
247 | // System.out.println("adding " + line); | |
246 | ||
248 | 247 | set.add(line); |
249 | 248 | } |
250 | 249 | } |
251 | 250 | } catch (IOException e) { |
252 | 251 | // 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"); | |
254 | 253 | } |
255 | 254 | return set; |
256 | 255 | } |
261 | 260 | l = LevelInfo.DEFAULT_LEVELS; |
262 | 261 | LevelInfo[] levels = LevelInfo.createFromString(l); |
263 | 262 | 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); | |
265 | 264 | } |
266 | 265 | l = generalOptions.get("overview-levels"); |
267 | 266 | if (l != null){ |
269 | 268 | // TODO: make sure that the combination of the two level strings makes sense |
270 | 269 | if (performChecks){ |
271 | 270 | 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); | |
273 | 272 | } |
274 | 273 | 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); | |
276 | 275 | } |
277 | 276 | } |
278 | 277 | List<LevelInfo> tmp = new ArrayList<>(); |
335 | 334 | String val = opt.getValue(); |
336 | 335 | if ("name-tag-list".equals(key)) { |
337 | 336 | 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. " | |
339 | 338 | + "Please use only the command line option to specify this value."); |
340 | 339 | } |
341 | 340 | } else if (OPTION_LIST.contains(key)) { |
409 | 408 | try { |
410 | 409 | baseStyles.add(new StyleImpl(location, name, props, performChecks)); |
411 | 410 | } catch (SyntaxException e) { |
412 | System.err.println("Error in style: " + e.getMessage()); | |
411 | Logger.defaultLogger.error("Error in style: " + e.getMessage()); | |
413 | 412 | } catch (FileNotFoundException e) { |
414 | 413 | // not found, try on the classpath. This is the common |
415 | 414 | // case where you have an external style, but want to |
419 | 418 | try { |
420 | 419 | baseStyles.add(new StyleImpl(null, name, props, performChecks)); |
421 | 420 | } catch (SyntaxException se) { |
422 | System.err.println("Error in style: " + se.getMessage()); | |
421 | Logger.defaultLogger.error("Error in style: " + se.getMessage()); | |
423 | 422 | } catch (FileNotFoundException e1) { |
424 | log.error("Could not find base style", e); | |
423 | Logger.defaultLogger.error("Could not find base style", e); | |
425 | 424 | } |
426 | 425 | } |
427 | 426 | } |
477 | 476 | } |
478 | 477 | |
479 | 478 | if (version > VERSION) { |
480 | System.err.println("Warning: unrecognised style version " + version + | |
479 | Logger.defaultLogger.warn("Unrecognised style version " + version + | |
481 | 480 | ", but only versions up to " + VERSION + " are understood"); |
482 | 481 | } |
483 | 482 | } |
545 | 544 | try { |
546 | 545 | style = new StyleImpl(loc, name, props, WITHOUT_CHECKS); |
547 | 546 | } catch (SyntaxException e) { |
548 | System.err.println("Error in style: " + e.getMessage()); | |
547 | Logger.defaultLogger.error("Error in style: " + e.getMessage()); | |
549 | 548 | throw new ExitException("Could not open style " + (name == null? "":name)); |
550 | 549 | } catch (FileNotFoundException e) { |
551 | 550 | String msg = "Could not open style "; |
164 | 164 | |
165 | 165 | private LineAdder lineAdder; |
166 | 166 | 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<>(); | |
167 | 171 | |
168 | 172 | public StyledConverter(Style style, MapCollector collector, EnhancedProperties props) { |
169 | 173 | this.collector = collector; |
203 | 207 | countryAbbr = countryAbbr.toUpperCase(); |
204 | 208 | |
205 | 209 | 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; | |
207 | 211 | prefixSuffixFilter = new PrefixSuffixFilter(props); |
208 | 212 | |
209 | 213 | lineAdder = line -> { |
249 | 253 | String optionKey = pair[0]; |
250 | 254 | String tagKey = STYLE_OPTION_PREF + optionKey; |
251 | 255 | 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 | } | |
259 | 273 | } |
260 | 274 | } |
261 | 275 | } |
263 | 277 | if (style.getUsedTags() != null) { |
264 | 278 | for (String s : style.getUsedTags()) { |
265 | 279 | 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 | } | |
268 | 287 | } |
269 | 288 | } |
270 | 289 | } |
347 | 366 | numDriveOnSideUnknown++; |
348 | 367 | } |
349 | 368 | } |
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() + ")"); | |
353 | 372 | } |
354 | 373 | lastRoadId = way.getId(); |
355 | 374 | } else { |
1074 | 1093 | if (points.get(0) == points.get(points.size() - 1)) { |
1075 | 1094 | // roundabout is a loop |
1076 | 1095 | 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 " | |
1078 | 1097 | + centre.toOSMURL() + ")"); |
1079 | 1098 | way.reverse(); |
1080 | 1099 | } |
1081 | 1100 | } else if (dirIsWrong) { |
1082 | 1101 | // 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 " | |
1084 | 1103 | + points.get(0).toOSMURL() + ")"); |
1085 | 1104 | } |
1086 | 1105 | } |
1231 | 1250 | line.setType(replType); |
1232 | 1251 | line.setPoints(points); |
1233 | 1252 | |
1234 | ||
1235 | 1253 | if (way.tagIsLikeYes(TK_ONEWAY)) |
1236 | 1254 | line.setDirection(true); |
1237 | 1255 | |
2230 | 2248 | } |
2231 | 2249 | |
2232 | 2250 | 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() | |
2234 | 2252 | + ((pos == 0) ? " comes from" : " goes to") + " nowhere at " + p.toOSMURL()); |
2235 | 2253 | } |
2236 | 2254 | } |
15 | 15 | package uk.me.parabola.mkgmap.osmstyle.actions; |
16 | 16 | |
17 | 17 | import uk.me.parabola.mkgmap.reader.osm.Element; |
18 | import uk.me.parabola.log.Logger; | |
18 | 19 | |
19 | 20 | /** |
20 | * Sends a message to the console. | |
21 | * Logs a message. | |
21 | 22 | * |
22 | 23 | * @author Richard Fairhurst |
23 | 24 | */ |
29 | 30 | } |
30 | 31 | |
31 | 32 | 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)); | |
33 | 34 | return false; |
34 | 35 | } |
35 | 36 | } |
13 | 13 | package uk.me.parabola.mkgmap.osmstyle.actions; |
14 | 14 | |
15 | 15 | import uk.me.parabola.mkgmap.reader.osm.Element; |
16 | import uk.me.parabola.log.Logger; | |
16 | 17 | |
17 | 18 | /** |
18 | * Sends a message including the tags of an element to System.err. | |
19 | * Logs a message including the tags of an element. | |
19 | 20 | * |
20 | 21 | * @author WanMil |
21 | 22 | */ |
27 | 28 | } |
28 | 29 | |
29 | 30 | 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)); | |
31 | 32 | return false; |
32 | 33 | } |
33 | 34 |
19 | 19 | import java.util.Set; |
20 | 20 | |
21 | 21 | import uk.me.parabola.imgfmt.ExitException; |
22 | import uk.me.parabola.log.Logger; | |
22 | 23 | import uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction; |
23 | 24 | import uk.me.parabola.mkgmap.reader.osm.Element; |
24 | 25 | import uk.me.parabola.mkgmap.scan.SyntaxException; |
209 | 210 | } else if (this.isType(NodeType.EXISTS) || this.isType(NodeType.NOT_EXISTS) || this.isType(NodeType.NOT)) { |
210 | 211 | set.addAll(getFirst().getEvaluatedTagKeys()); |
211 | 212 | } else if (this.getFirst() != null) { |
212 | System.err.println("Unhandled type of Op"); | |
213 | Logger.defaultLogger.error("Unhandled type of Op"); | |
213 | 214 | } |
214 | 215 | |
215 | 216 | } |
105 | 105 | if (n != nameSearchDepth) { |
106 | 106 | nameSearchDepth = Math.min(25, Math.max(0, n)); |
107 | 107 | 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); | |
109 | 109 | } |
110 | 110 | } |
111 | 111 | } |
37 | 37 | try { |
38 | 38 | knownHgt = loadConfig(); |
39 | 39 | } catch (IOException e) { |
40 | e.printStackTrace(); | |
40 | Logger.defaultLogger.error("Error reading hgt config", e); | |
41 | 41 | } |
42 | 42 | } |
43 | 43 | |
113 | 113 | |
114 | 114 | bs.set(getBitSetPos(lat, lon)); |
115 | 115 | } catch (NumberFormatException e) { |
116 | e.printStackTrace(); | |
116 | Logger.defaultLogger.error("Error reading latitude/longitude", e); | |
117 | 117 | } |
118 | 118 | } |
119 | 119 | return bs; |
129 | 129 | HGTList hgtList = HGTList.get(); |
130 | 130 | if (hgtList != null) { |
131 | 131 | 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."); | |
133 | 133 | } else { |
134 | 134 | log.warn("file " + fileName + " not found. Is expected to cover sea."); |
135 | 135 | } |
105 | 105 | } catch (FileNotFoundException exp) { |
106 | 106 | log.error("Coastline file " + coastlineFile + " not found."); |
107 | 107 | } catch (Exception exp) { |
108 | log.error(exp); | |
109 | exp.printStackTrace(); | |
108 | log.error("Unexpected exception reading " + coastlineFile, exp); | |
110 | 109 | } |
111 | 110 | } |
112 | 111 | coastlinesLoaded.set(true); |
456 | 456 | } |
457 | 457 | } |
458 | 458 | // try to connect ways lying outside or on the bbox |
459 | if (unclosed.size() >= 2) { | |
459 | if (!unclosed.isEmpty()) { | |
460 | 460 | log.debug("Checking", unclosed.size(), "unclosed ways for connections outside the bbox"); |
461 | 461 | Map<Coord, JoinedWay> outOfBboxPoints = new IdentityHashMap<>(); |
462 | 462 | |
504 | 504 | if (!lineCutsBbox(cd.c1, edgePoint1) && !lineCutsBbox(edgePoint1, cd.c2)) { |
505 | 505 | cd.imC = edgePoint1; |
506 | 506 | } else if (!lineCutsBbox(cd.c1, edgePoint2) && !lineCutsBbox(edgePoint2, cd.c2)) { |
507 | cd.imC = edgePoint1; | |
507 | cd.imC = edgePoint2; | |
508 | 508 | } else { |
509 | 509 | // both endpoints are on opposite sides of the bounding box |
510 | 510 | // automatically closing such points would create wrong polygons in most cases |
544 | 544 | minCon.w1.getPoints().addAll(minCon.w2.getPoints()); |
545 | 545 | minCon.w1.addWay(minCon.w2); |
546 | 546 | allWays.remove(minCon.w2); |
547 | return true; | |
548 | } | |
547 | } | |
548 | return true; | |
549 | 549 | } |
550 | 550 | } |
551 | 551 | return false; |
166 | 166 | break; |
167 | 167 | } catch (InstantiationException | IllegalAccessException e) { |
168 | 168 | // TODO Auto-generated catch block |
169 | e.printStackTrace(); | |
169 | log.error("Unexpected error", e); | |
170 | 170 | } |
171 | 171 | } |
172 | 172 | } |
689 | 689 | } catch (FileNotFoundException exp) { |
690 | 690 | log.error("Preompiled sea tile " + tileName + " not found."); |
691 | 691 | } catch (Exception exp) { |
692 | log.error(exp); | |
693 | exp.printStackTrace(); | |
692 | log.error("Unexpected error reading "+ tileName, exp); | |
694 | 693 | } |
695 | 694 | } |
696 | 695 |
17 | 17 | import java.io.InputStream; |
18 | 18 | import java.nio.charset.StandardCharsets; |
19 | 19 | |
20 | import uk.me.parabola.imgfmt.FormatException; | |
20 | 21 | import uk.me.parabola.imgfmt.app.Coord; |
22 | import uk.me.parabola.log.Logger; | |
21 | 23 | import uk.me.parabola.mkgmap.reader.osm.Element; |
22 | 24 | import uk.me.parabola.mkgmap.reader.osm.GeneralRelation; |
23 | 25 | import uk.me.parabola.mkgmap.reader.osm.Node; |
106 | 108 | try { |
107 | 109 | int start = is.read(); |
108 | 110 | ++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 | } | |
111 | 115 | readFile(); |
112 | 116 | } catch (IOException e) { |
113 | System.err.println("exception after " + countBytes + " bytes"); | |
114 | e.printStackTrace(); | |
117 | Logger.defaultLogger.error("exception after " + countBytes + " bytes", e); | |
115 | 118 | } |
116 | 119 | } |
117 | 120 |
220 | 220 | */ |
221 | 221 | @Override |
222 | 222 | 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 " | |
224 | 224 | + e.getColumnNumber()); |
225 | 225 | super.fatalError(e); |
226 | 226 | } |
13 | 13 | |
14 | 14 | import uk.me.parabola.imgfmt.app.CoordNode; |
15 | 15 | import uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction; |
16 | import uk.me.parabola.log.Logger; | |
16 | 17 | import uk.me.parabola.mkgmap.general.MapDetails; |
17 | 18 | |
18 | 19 | import java.util.ArrayList; |
55 | 56 | if (restriction.isValid()) |
56 | 57 | allRestrictions.add(restriction); |
57 | 58 | else { |
58 | System.err.println(restriction); | |
59 | Logger.defaultLogger.warn("Invalid restriction " + restriction.toString()); | |
59 | 60 | } |
60 | 61 | } |
61 | 62 | } |
37 | 37 | public class ArgsTest extends Base { |
38 | 38 | @Test |
39 | 39 | public void testHelp() { |
40 | Outputs outputs = TestUtils.run("--help"); | |
40 | Outputs outputs = TestUtils.runAsProcess("--help"); | |
41 | 41 | outputs.checkOutput("--help=options", "--help=links"); |
42 | 42 | outputs.checkNoError(); |
43 | 43 | checkNoStdFile(); |
45 | 45 | |
46 | 46 | @Test |
47 | 47 | public void testHelpOptions() { |
48 | Outputs outputs = TestUtils.run("--help=options"); | |
48 | Outputs outputs = TestUtils.runAsProcess("--help=options"); | |
49 | 49 | outputs.checkNoError(); |
50 | 50 | outputs.checkOutput("--mapname=name", "--latin1", "--list-styles"); |
51 | 51 | checkNoStdFile(); |
53 | 53 | |
54 | 54 | @Test |
55 | 55 | public void testHelpUnknown() { |
56 | Outputs outputs = TestUtils.run("--help=unknown-help-option"); | |
56 | Outputs outputs = TestUtils.runAsProcess("--help=unknown-help-option"); | |
57 | 57 | outputs.checkNoError(); |
58 | 58 | outputs.checkOutput("Could not find", "unknown-help-option"); |
59 | 59 | checkNoStdFile(); |
61 | 61 | |
62 | 62 | @Test |
63 | 63 | 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"); | |
65 | 65 | op.checkNoError(); |
66 | 66 | op.checkOutput("empty", "main", "simple", "derived", "2.2: A simple test style"); |
67 | 67 | checkNoStdFile(); |
69 | 69 | |
70 | 70 | @Test |
71 | 71 | public void testListStylesVerbose() { |
72 | Outputs op = TestUtils.run("--style-file=test/resources/teststyles", | |
72 | Outputs op = TestUtils.runAsProcess("--style-file=test/resources/teststyles", | |
73 | 73 | "--verbose", "--list-styles"); |
74 | 74 | op.checkNoError(); |
75 | 75 | op.checkOutput("empty", "main", "simple", "derived", |
82 | 82 | TestUtils.registerFile("osmmap.img"); |
83 | 83 | |
84 | 84 | int pri = 42; |
85 | Outputs op = TestUtils.run("--draw-priority=" + pri, | |
85 | Outputs op = TestUtils.runAsProcess("--draw-priority=" + pri, | |
86 | 86 | Args.TEST_RESOURCE_OSM + "uk-test-1.osm.gz"); |
87 | op.checkNoError(); | |
87 | op.checkError("Number of ExitExceptions: 0"); | |
88 | 88 | |
89 | 89 | FileSystem fs = openFs(Args.DEF_MAP_FILENAME); |
90 | 90 | ImgChannel chan = fs.open(Args.DEF_MAP_ID + ".TRE", "r"); |
95 | 95 | |
96 | 96 | @Test |
97 | 97 | 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"); | |
100 | 100 | } |
101 | 101 | } |
400 | 400 | "--latin1", |
401 | 401 | Args.TEST_RESOURCE_OSM + "uk-test-2.osm.gz"); |
402 | 402 | |
403 | Outputs outputs = TestUtils.run(Args.TEST_STYLE_ARG, | |
403 | Outputs outputs = TestUtils.runAsProcess(Args.TEST_STYLE_ARG, | |
404 | 404 | "--gmapsupp", |
405 | 405 | "--index", |
406 | 406 |
35 | 35 | f.delete(); |
36 | 36 | assertFalse("does not pre-exist", f.exists()); |
37 | 37 | |
38 | Outputs outputs = TestUtils.run( | |
38 | Outputs outputs = TestUtils.runAsProcess( | |
39 | 39 | Args.TEST_STYLE_ARG, |
40 | 40 | "--index", |
41 | 41 | "--latin1", |
44 | 44 | Args.TEST_RESOURCE_IMG + "63240001.img", |
45 | 45 | Args.TEST_RESOURCE_IMG + "63240002.img" |
46 | 46 | ); |
47 | outputs.checkNoError(); | |
47 | outputs.checkError("Number of ExitExceptions: 0"); | |
48 | 48 | |
49 | 49 | TestUtils.registerFile(MDR_IMG); |
50 | 50 | TestUtils.registerFile(OVERVIEW_NAME+".tdb"); |
15 | 15 | */ |
16 | 16 | package func.lib; |
17 | 17 | |
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; | |
19 | 22 | |
20 | 23 | /** |
21 | 24 | * Standard output and error as produced during a run. |
36 | 39 | } |
37 | 40 | |
38 | 41 | 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")); | |
40 | 47 | } |
41 | 48 | |
42 | 49 | /** |
15 | 15 | */ |
16 | 16 | package func.lib; |
17 | 17 | |
18 | import java.io.BufferedReader; | |
18 | 19 | import java.io.ByteArrayOutputStream; |
19 | 20 | import java.io.Closeable; |
20 | 21 | import java.io.File; |
21 | 22 | import java.io.FileNotFoundException; |
23 | import java.io.IOException; | |
24 | import java.io.InputStreamReader; | |
22 | 25 | import java.io.OutputStream; |
23 | 26 | import java.io.PrintStream; |
24 | 27 | import java.util.ArrayDeque; |
27 | 30 | import java.util.Collections; |
28 | 31 | import java.util.Deque; |
29 | 32 | import java.util.List; |
33 | import java.util.concurrent.TimeUnit; | |
30 | 34 | |
31 | 35 | import uk.me.parabola.imgfmt.Utils; |
32 | 36 | import uk.me.parabola.mkgmap.general.LevelInfo; |
135 | 139 | } |
136 | 140 | |
137 | 141 | /** |
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 | /** | |
138 | 190 | * Create a rule set out of a string. The string is processed |
139 | 191 | * as if it were in a file and the levels spec had been set. |
140 | 192 | */ |
11 | 11 | */ |
12 | 12 | package main; |
13 | 13 | |
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 | ||
14 | 25 | import java.io.BufferedWriter; |
15 | 26 | import java.io.ByteArrayOutputStream; |
16 | 27 | import java.io.File; |
20 | 31 | import java.io.PrintStream; |
21 | 32 | import java.io.StringReader; |
22 | 33 | import java.io.UnsupportedEncodingException; |
34 | import java.math.BigInteger; | |
23 | 35 | import java.nio.file.Files; |
24 | 36 | import java.nio.file.Paths; |
25 | 37 | import java.security.MessageDigest; |
39 | 51 | import java.util.concurrent.TimeUnit; |
40 | 52 | import java.util.concurrent.TimeoutException; |
41 | 53 | import java.util.function.BiFunction; |
42 | ||
43 | import javax.xml.bind.DatatypeConverter; | |
44 | 54 | |
45 | 55 | import uk.me.parabola.imgfmt.app.Coord; |
46 | 56 | import uk.me.parabola.mkgmap.main.StyleTester; |
66 | 76 | import uk.me.parabola.mkgmap.reader.osm.Way; |
67 | 77 | import uk.me.parabola.mkgmap.scan.SyntaxException; |
68 | 78 | 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.*; | |
72 | 79 | |
73 | 80 | public class RulesTest { |
74 | 81 | private static final Random rand = new Random(); |
347 | 354 | try { |
348 | 355 | MessageDigest md5 = MessageDigest.getInstance("md5"); |
349 | 356 | 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); | |
351 | 358 | fileName = String.format("t-%s.test", s); |
352 | 359 | } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { |
353 | 360 | fileName = String.format("t-%06d.test", id); |