Update upstream source from tag 'upstream/0.0.0+svn4620'
Update to upstream version '0.0.0+svn4620'
with Debian dir 95288c4383a44a709bd36eb738898f3b18003127
Bas Couwenberg
3 years ago
0 | svn.version: 4604 | |
1 | build.timestamp: 2021-02-28T07:50:49+0000 | |
0 | svn.version: 4620 | |
1 | build.timestamp: 2021-03-28T10:11:16+0100 |
11 | 11 | */ |
12 | 12 | package uk.me.parabola.imgfmt; |
13 | 13 | |
14 | import uk.me.parabola.log.Logger; | |
15 | ||
16 | 14 | /** |
17 | 15 | * Used for cases where the current map has failed to compile, but the error |
18 | 16 | * is expected to be specific to the map (eg it is too big etc). When this |
25 | 23 | * @author Steve Ratcliffe |
26 | 24 | */ |
27 | 25 | public class MapFailedException extends RuntimeException { |
28 | private static final Logger log = Logger.getLogger(MapFailedException.class); | |
29 | 26 | |
30 | 27 | /** |
31 | * Constructs a new runtime exception with the specified detail message. | |
28 | * Constructs a new runtime exception with the calling method name | |
29 | * appended to the detail message. | |
32 | 30 | * The cause is not initialized, and may subsequently be initialized by a |
33 | 31 | * call to {@link #initCause}. |
34 | 32 | * |
36 | 34 | * later retrieval by the {@link #getMessage()} method. |
37 | 35 | */ |
38 | 36 | public MapFailedException(String message) { |
39 | super(message); | |
40 | log(message); | |
37 | super(buildMessage(message)); | |
41 | 38 | } |
42 | 39 | |
43 | 40 | /** |
44 | * Constructs a new runtime exception with the specified detail message and | |
45 | * cause. <p>Note that the detail message associated with | |
41 | * Constructs a new runtime exception with the calling method name | |
42 | * appended to the detail message and includes the cause. | |
43 | * <p>Note that the detail message associated with | |
46 | 44 | * <code>cause</code> is <i>not</i> automatically incorporated in |
47 | 45 | * this runtime exception's detail message. |
48 | 46 | * |
52 | 50 | * {@link #getCause()} method). (A <tt>null</tt> value is |
53 | 51 | * permitted, and indicates that the cause is nonexistent or |
54 | 52 | * unknown.) |
55 | * @since 1.4 | |
56 | 53 | */ |
57 | 54 | public MapFailedException(String message, Throwable cause) { |
58 | super(message, cause); | |
59 | log(message); | |
55 | super(buildMessage(message), cause); | |
60 | 56 | } |
61 | 57 | |
62 | private static void log(String message){ | |
58 | /** | |
59 | * Constructs a new runtime exception without appending the calling method | |
60 | * name to the detail message. The calling method can be appended by the | |
61 | * derived class if required. | |
62 | */ | |
63 | protected MapFailedException(String message, boolean ignored) { | |
64 | super(message); | |
65 | } | |
66 | ||
67 | /** | |
68 | * Appends the calling method name to the supplied message. | |
69 | */ | |
70 | protected static String buildMessage(String message) { | |
63 | 71 | String thrownBy = ""; |
64 | 72 | try{ |
65 | 73 | StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); |
66 | 74 | int callerPosInStack = 3; |
67 | 75 | String[] caller = stackTraceElements[callerPosInStack].getClassName().split("\\."); |
68 | thrownBy = "(thrown in " + caller[caller.length-1]+ "." +stackTraceElements[callerPosInStack].getMethodName() + "()) "; | |
76 | thrownBy = " (thrown in " + caller[caller.length-1]+ "." +stackTraceElements[callerPosInStack].getMethodName() + "())"; | |
69 | 77 | } catch(Exception e){ |
70 | log.info(e); | |
71 | 78 | } |
72 | log.error(thrownBy + message); | |
79 | return message + thrownBy; | |
73 | 80 | } |
74 | 81 | }⏎ |
0 | package uk.me.parabola.imgfmt; | |
1 | ||
2 | public class MapTooBigException extends MapFailedException { | |
3 | protected final long maxAllowedSize; | |
4 | ||
5 | public MapTooBigException(long maxSize, String message, String suggestion) { | |
6 | super(message + " The maximum size is " + maxSize + " bytes. " + suggestion, false); | |
7 | maxAllowedSize = maxSize; | |
8 | } | |
9 | ||
10 | public long getMaxAllowedSize() { | |
11 | return maxAllowedSize; | |
12 | } | |
13 | } |
19 | 19 | import java.nio.ByteBuffer; |
20 | 20 | import java.nio.ByteOrder; |
21 | 21 | |
22 | import uk.me.parabola.imgfmt.MapFailedException; | |
22 | import uk.me.parabola.imgfmt.MapTooBigException; | |
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; |
40 | 40 | private static final int GUARD_SIZE = KBYTE; |
41 | 41 | |
42 | 42 | private final ImgChannel chan; |
43 | private final String subfile; | |
43 | 44 | |
44 | 45 | private ByteBuffer buf = ByteBuffer.allocate(INIT_SIZE); |
45 | 46 | private int bufferSize = INIT_SIZE; |
54 | 55 | // The maximum allowed file size. |
55 | 56 | private long maxAllowedSize = 0xffffff; |
56 | 57 | |
57 | public BufferedImgFileWriter(ImgChannel chan) { | |
58 | public BufferedImgFileWriter(ImgChannel chan, String subfile) { | |
58 | 59 | this.chan = chan; |
60 | this.subfile = subfile; | |
59 | 61 | buf.order(ByteOrder.LITTLE_ENDIAN); |
60 | 62 | if (chan instanceof FileLink) { |
61 | 63 | ((FileLink) chan).link(this, this); |
269 | 271 | while(needed > (bufferSize - GUARD_SIZE)) |
270 | 272 | bufferSize += GROW_SIZE; |
271 | 273 | if (bufferSize > maxAllowedSize) { |
272 | // Previous message was confusing people, although it is difficult to come | |
273 | // up with something that is strictly true in all situations. | |
274 | throw new MapFailedException( | |
275 | "There is not enough room in a single garmin map for all the input data." + | |
276 | " The .osm file should be split into smaller pieces first."); | |
274 | throw new MapTooBigException(maxAllowedSize, | |
275 | "The " + subfile + " section of the map or tile is too big.", | |
276 | "Try splitting the map into smaller tiles or reducing the amount of information included in the map."); | |
277 | 277 | } |
278 | 278 | ByteBuffer newb = ByteBuffer.allocate(bufferSize); |
279 | 279 | newb.order(ByteOrder.LITTLE_ENDIAN); |
14 | 14 | |
15 | 15 | import java.util.List; |
16 | 16 | |
17 | import uk.me.parabola.imgfmt.ExitException; | |
17 | 18 | import uk.me.parabola.imgfmt.Utils; |
18 | 19 | import uk.me.parabola.imgfmt.app.Area; |
19 | 20 | import uk.me.parabola.imgfmt.app.BufferedImgFileReader; |
45 | 46 | setHeader(demHeader); |
46 | 47 | |
47 | 48 | if (write) { |
48 | setWriter(new BufferedImgFileWriter(chan)); | |
49 | setWriter(new BufferedImgFileWriter(chan, "DEM")); | |
49 | 50 | position(DEMHeader.HEADER_LEN); |
50 | 51 | } else { |
51 | 52 | setReader(new BufferedImgFileReader(chan)); |
97 | 98 | } |
98 | 99 | // last 4 bits of distance should be 0 |
99 | 100 | distance = ((distance + 8) / 16) * 16; |
101 | if (distance == 0) | |
102 | throw new ExitException("DEM distance is zero"); | |
100 | 103 | |
101 | 104 | int xTop = top; |
102 | 105 | int xLeft = left; |
65 | 65 | lblHeader.setOffsetMultiplier(OFFSET_MULTIPLIER); |
66 | 66 | setHeader(lblHeader); |
67 | 67 | |
68 | setWriter(new BufferedImgFileWriter(chan)); | |
68 | setWriter(new BufferedImgFileWriter(chan, "LBL")); | |
69 | 69 | |
70 | 70 | position((long) LBLHeader.HEADER_LEN + lblHeader.getSortDescriptionLength()); |
71 | 71 |
24 | 24 | */ |
25 | 25 | public class Mdr1MapIndex { |
26 | 26 | private final Mdr1SubHeader subHeader = new Mdr1SubHeader(); |
27 | private final BufferedImgFileWriter subWriter = new BufferedImgFileWriter(null); | |
27 | private final BufferedImgFileWriter subWriter = new BufferedImgFileWriter(null, "MDR"); | |
28 | 28 | |
29 | 29 | private int pointerSize; |
30 | 30 |
50 | 50 | |
51 | 51 | public NETFile(ImgChannel chan) { |
52 | 52 | setHeader(netHeader); |
53 | setWriter(new BufferedImgFileWriter(chan)); | |
53 | setWriter(new BufferedImgFileWriter(chan, "NET")); | |
54 | 54 | position(NETHeader.HEADER_LEN); |
55 | 55 | } |
56 | 56 |
58 | 58 | public NODFile(ImgChannel chan, boolean write) { |
59 | 59 | setHeader(nodHeader); |
60 | 60 | if (write) { |
61 | setWriter(new BufferedImgFileWriter(chan)); | |
61 | setWriter(new BufferedImgFileWriter(chan, "NOD")); | |
62 | 62 | position(NODHeader.HEADER_LEN); |
63 | 63 | } else { |
64 | 64 | setReader(new BufferedImgFileReader(chan)); |
39 | 39 | private final List<Integer> srt8Starts = new ArrayList<>(); |
40 | 40 | |
41 | 41 | public SRTFile(ImgChannel chan) { |
42 | BufferedImgFileWriter fileWriter = new BufferedImgFileWriter(chan); | |
42 | BufferedImgFileWriter fileWriter = new BufferedImgFileWriter(chan, "SRT"); | |
43 | 43 | fileWriter.setMaxSize(Long.MAX_VALUE); |
44 | 44 | setWriter(fileWriter); |
45 | 45 | } |
56 | 56 | public RGNFile(ImgChannel chan) { |
57 | 57 | setHeader(header); |
58 | 58 | |
59 | setWriter(new BufferedImgFileWriter(chan)); | |
59 | setWriter(new BufferedImgFileWriter(chan, "RGN")); | |
60 | 60 | |
61 | 61 | // Position at the start of the writable area. |
62 | 62 | position(HEADER_LEN); |
63 | 63 | |
64 | 64 | public TREFile(ImgChannel chan) { |
65 | 65 | setHeader(header); |
66 | setWriter(new BufferedImgFileWriter(chan)); | |
66 | setWriter(new BufferedImgFileWriter(chan, "TRE")); | |
67 | 67 | |
68 | 68 | // Position at the start of the writable area. |
69 | 69 | position(header.getHeaderLength()); |
54 | 54 | |
55 | 55 | public TYPFile(ImgChannel chan) { |
56 | 56 | setHeader(header); |
57 | setWriter(new BufferedImgFileWriter(chan)); | |
57 | setWriter(new BufferedImgFileWriter(chan, "TYP")); | |
58 | 58 | position(TYPHeader.HEADER_LEN); |
59 | 59 | } |
60 | 60 |
45 | 45 | |
46 | 46 | public MpsFile(ImgChannel chan) { |
47 | 47 | assert chan instanceof FileNode; |
48 | writer = new BufferedImgFileWriter(chan); | |
48 | writer = new BufferedImgFileWriter(chan, "MPS"); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | public void sync() throws IOException { |
240 | 240 | }); |
241 | 241 | try { |
242 | 242 | opts.readOptionFile(filename); |
243 | } catch (IOException e) { | |
244 | throw new ExitException("Failed to read option file", e); | |
243 | } catch (Exception e) { | |
244 | throw new ExitException("Failed to read option file.", e); | |
245 | 245 | } |
246 | 246 | } |
247 | 247 |
35 | 35 | import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; |
36 | 36 | import uk.me.parabola.imgfmt.ExitException; |
37 | 37 | import uk.me.parabola.imgfmt.MapFailedException; |
38 | import uk.me.parabola.imgfmt.MapTooBigException; | |
38 | 39 | import uk.me.parabola.imgfmt.Utils; |
39 | 40 | import uk.me.parabola.imgfmt.app.Area; |
40 | 41 | import uk.me.parabola.imgfmt.app.Coord; |
373 | 374 | long t2 = System.currentTimeMillis(); |
374 | 375 | log.info("DEM file calculation for", map.getFilename(), "took", (t2 - t1), "ms"); |
375 | 376 | demFile.write(); |
377 | } catch (MapTooBigException e) { | |
378 | throw new MapTooBigException(e.getMaxAllowedSize(), "The DEM section of the map or tile is too big.", "Try increasing the DEM distance."); | |
376 | 379 | } catch (MapFailedException e) { |
377 | log.error("exception while creating DEM file", e.getMessage()); | |
378 | throw new MapFailedException("DEM"); | |
380 | throw new MapFailedException("Error creating DEM File. " + e.getMessage()); | |
379 | 381 | } |
380 | 382 | } |
381 | 383 | |
500 | 502 | } |
501 | 503 | |
502 | 504 | } |
503 | ||
505 | ||
504 | 506 | private void processRoads(Map map, MapDataSource src) { |
505 | 507 | LBLFile lbl = map.getLblFile(); |
506 | 508 | MapPoint searchPoint = new MapPoint(); |
21 | 21 | import uk.me.parabola.imgfmt.FileNotWritableException; |
22 | 22 | import uk.me.parabola.imgfmt.FileSystemParam; |
23 | 23 | import uk.me.parabola.imgfmt.MapFailedException; |
24 | import uk.me.parabola.imgfmt.MapTooBigException; | |
24 | 25 | import uk.me.parabola.imgfmt.Utils; |
25 | 26 | import uk.me.parabola.imgfmt.app.Area; |
26 | 27 | import uk.me.parabola.imgfmt.app.Coord; |
194 | 195 | throw new ExitException("Could not create overview map", e); |
195 | 196 | } catch (FileNotWritableException e) { |
196 | 197 | throw new ExitException("Could not write to overview map", e); |
198 | } catch (MapTooBigException e) { | |
199 | throw new MapTooBigException(e.getMaxAllowedSize(), | |
200 | "The overview map is too big.", | |
201 | "Try reducing the highest overview resolution or reducing the amount of information included in the overview."); | |
197 | 202 | } |
198 | 203 | } |
199 | 204 |
29 | 29 | public class RemoveObsoletePointsFilter implements MapFilter { |
30 | 30 | private static final Logger log = Logger.getLogger(RemoveObsoletePointsFilter.class); |
31 | 31 | |
32 | final Coord[] areaTest = new Coord[3]; | |
33 | ||
34 | 32 | private boolean checkPreserved; |
35 | 33 | |
36 | 34 | @Override |
47 | 45 | MapLine line = (MapLine) element; |
48 | 46 | List<Coord> points = line.getPoints(); |
49 | 47 | int numPoints = points.size(); |
50 | if (numPoints <= 1){ | |
51 | return; | |
48 | if (numPoints <= 1) { | |
49 | return; | |
52 | 50 | } |
53 | 51 | int requiredPoints = (line instanceof MapShape ) ? 4:2; |
54 | 52 | List<Coord> newPoints = new ArrayList<>(numPoints); |
66 | 64 | if (lastP.equals(newP)){ |
67 | 65 | // only add the new point if it has different |
68 | 66 | // coordinates to the last point or is preserved |
69 | if (checkPreserved && line.isRoad()){ | |
67 | if (checkPreserved && line.isRoad()) { | |
70 | 68 | if (!newP.preserved()) { |
71 | 69 | continue; |
72 | } else if (!lastP.preserved()){ | |
70 | } else if (!lastP.preserved()) { | |
73 | 71 | newPoints.set(last, newP); // replace last |
74 | } | |
75 | } else { | |
72 | continue; | |
73 | } | |
74 | } else { | |
76 | 75 | continue; |
77 | 76 | } |
78 | 77 | } |
115 | 114 | int nPoints = newPoints.size(); |
116 | 115 | switch(Utils.isStraight(newPoints.get(newPoints.size()-2), newPoints.get(0), newPoints.get(1))){ |
117 | 116 | case Utils.STRAIGHT_SPIKE: |
117 | log.debug("removing closing spike"); | |
118 | 118 | newPoints.remove(0); |
119 | 119 | newPoints.set(newPoints.size()-1, newPoints.get(0)); |
120 | 120 | if (newPoints.get(newPoints.size()-2).equals(newPoints.get(newPoints.size()-1))) |
121 | 121 | newPoints.remove(newPoints.size()-1); |
122 | 122 | break; |
123 | 123 | case Utils.STRICTLY_STRAIGHT: |
124 | log.debug("removing straight line across closing"); | |
124 | 125 | newPoints.remove(newPoints.size()-1); |
125 | 126 | newPoints.set(0, newPoints.get(newPoints.size()-1)); |
126 | 127 | break; |
30 | 30 | @Override |
31 | 31 | public void init(FilterConfig config) { |
32 | 32 | shift = config.getShift(); |
33 | keepNodes = config.getLevel() == 0 && config.hasNet(); | |
34 | 33 | level = config.getLevel(); |
34 | keepNodes = level == 0 && config.hasNet(); | |
35 | 35 | } |
36 | 36 | |
37 | 37 | /** |
40 | 40 | */ |
41 | 41 | @Override |
42 | 42 | public void doFilter(MapElement element, MapFilterChain next) { |
43 | MapLine line = (MapLine) element; | |
44 | if(shift == 0) { | |
43 | if (shift == 0) { | |
45 | 44 | // do nothing |
46 | next.doFilter(line); | |
47 | } | |
48 | else { | |
45 | next.doFilter(element); | |
46 | } else { | |
47 | MapLine line = (MapLine) element; | |
49 | 48 | int half = 1 << (shift - 1); // 0.5 shifted |
50 | 49 | int mask = ~((1 << shift) - 1); // to remove fraction bits |
51 | 50 | |
63 | 62 | int lon = (p.getLongitude() + half) & mask; |
64 | 63 | Coord newP; |
65 | 64 | |
66 | if(p instanceof CoordNode && keepNodes) | |
65 | if (p instanceof CoordNode && keepNodes) { | |
67 | 66 | newP = new CoordNode(lat, lon, p.getId(), p.getOnBoundary(), p.getOnCountryBorder()); |
68 | else { | |
67 | } else { | |
69 | 68 | newP = new Coord(lat, lon); |
70 | 69 | newP.preserved(p.preserved()); |
71 | 70 | newP.setNumberNode(hasNumbers && p.isNumberNode()); |
74 | 73 | // only add the new point if it has different |
75 | 74 | // coordinates to the last point or if it's a |
76 | 75 | // special node |
77 | if (lastP == null || !lastP.equals(newP) || newP.getId() > 0|| (hasNumbers && newP.isNumberNode())) { | |
76 | if (lastP == null || !lastP.equals(newP) || newP.getId() > 0 || (hasNumbers && newP.isNumberNode())) { | |
78 | 77 | newPoints.add(newP); |
79 | 78 | lastP = newP; |
80 | 79 | } else if (newP.preserved()) { |
86 | 85 | lastP.preserved(true); |
87 | 86 | } |
88 | 87 | } |
89 | if(newPoints.size() > 1) { | |
88 | if (newPoints.size() > 1) { | |
90 | 89 | MapLine newLine = line.copy(); |
91 | 90 | newLine.setPoints(newPoints); |
92 | 91 | next.doFilter(newLine); |
148 | 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."); |
149 | 149 | else |
150 | 150 | System.err.println("Try using the Java -Xmx option to increase the available heap memory."); |
151 | } catch (MapFailedException e) { | |
151 | } catch (MapFailedException | ExitException e) { | |
152 | 152 | // one of the combiners failed |
153 | e.printStackTrace(); | |
154 | ++numExitExceptions; | |
155 | } catch (ExitException e) { | |
156 | 153 | ++numExitExceptions; |
157 | 154 | String message = e.getMessage(); |
158 | 155 | Throwable cause = e.getCause(); |
564 | 561 | } catch (MapFailedException mfe) { |
565 | 562 | numMapFailedExceptions++; |
566 | 563 | setProgramRC(-1); |
567 | } catch (Throwable t) { | |
568 | t.printStackTrace(); | |
569 | 564 | if (!args.getProperties().getProperty("keep-going", false)) { |
570 | 565 | throw new ExitException("Exiting - if you want to carry on regardless, use the --keep-going option"); |
571 | 566 | } |
567 | } catch (Exception e) { | |
568 | e.printStackTrace(); | |
569 | throw new ExitException("Exiting due to unexpected error"); | |
572 | 570 | } |
573 | 571 | } |
574 | 572 | } |
119 | 119 | map.close(); |
120 | 120 | return outName; |
121 | 121 | } catch (FileExistsException e) { |
122 | log.error("File exists already"); | |
122 | 123 | throw new MapFailedException("File exists already", e); |
123 | 124 | } catch (FileNotWritableException e) { |
125 | log.error("Could not create or write to file"); | |
124 | 126 | throw new MapFailedException("Could not create or write to file", e); |
127 | } | |
128 | catch (MapFailedException e) { | |
129 | log.error(e.getMessage()); // make sure the filename is logged | |
130 | throw e; | |
125 | 131 | } |
126 | 132 | } |
127 | 133 |
890 | 890 | MapRoad[] uncheckedRoads = new MapRoad[houses.length]; |
891 | 891 | for (int i = 0 ; i < houses.length; i++) |
892 | 892 | uncheckedRoads[i] = houses[i].getRoad(); |
893 | isOK = info.checkRoads(); | |
893 | info.checkRoads(); | |
894 | 894 | // check if houses are assigned to different roads now |
895 | 895 | houses = info.getHouseNodes(); |
896 | 896 | for (int i = 0 ; i < houses.length; i++) { |
897 | 897 | if (houses[i].getRoad() != uncheckedRoads[i]) { |
898 | 898 | initialHousesForRoads.removeMapping(uncheckedRoads[i], houses[i]); |
899 | if (!houses[i].isIgnored()) | |
899 | if (!houses[i].isIgnored()) { | |
900 | 900 | initialHousesForRoads.add(houses[i].getRoad(), houses[i]); |
901 | else { | |
902 | if (!isOK) | |
903 | log.info("housenumber is assigned to different road after checking addr:interpolation way which turned out to be invalid",houses[i],info ); | |
904 | 901 | } |
905 | 902 | } |
906 | 903 | } |
1156 | 1153 | if (dupCount > 0) { |
1157 | 1154 | log.warn("addr:interpolation way",streetName,hivl,"is ignored, it produces",dupCount,"duplicate number(s) too far from existing nodes"); |
1158 | 1155 | badIvls.add(hivl); |
1159 | } | |
1160 | else { | |
1156 | } else { | |
1161 | 1157 | housesToAdd.put(hivl, interpolatedHouses); |
1162 | 1158 | for (HousenumberMatch hnm : interpolatedHouses) |
1163 | 1159 | interpolatedNumbers.put(hnm.getHousenumber(), hnm); |
16 | 16 | import java.util.Collections; |
17 | 17 | import java.util.List; |
18 | 18 | import java.util.Map; |
19 | ||
19 | 20 | import uk.me.parabola.imgfmt.Utils; |
20 | 21 | import uk.me.parabola.imgfmt.app.Coord; |
21 | 22 | import uk.me.parabola.log.Logger; |
199 | 200 | HousenumberGenerator.findClosestRoadSegment(test[i], r); |
200 | 201 | test[i].calcRoadSide(); |
201 | 202 | } |
202 | if (test[i].getRoad() == null || test[i].getDistance() > MAX_INTERPOLATION_DISTANCE_TO_ROAD ){ | |
203 | if (test[i].getRoad() == null || test[i].getDistance() > MAX_INTERPOLATION_DISTANCE_TO_ROAD) { | |
203 | 204 | foundSingleRoad = false; |
204 | 205 | break; |
205 | 206 | } |
256 | 257 | } |
257 | 258 | } |
258 | 259 | } |
259 | if (!foundSingleRoad && bestRoad != null){ | |
260 | if (!foundSingleRoad && bestRoad != null) { | |
260 | 261 | // not matching road name in original OSM data, use the closest |
261 | 262 | foundSingleRoad = true; |
262 | 263 | test[0] = closest[0]; |
270 | 271 | hasMultipleRoads = true; |
271 | 272 | return true; |
272 | 273 | } |
273 | // we found the road that should be used for interpolation | |
274 | for (int i = 0; i < 2; i++) { | |
275 | if (test[i].getSegmentFrac() < 0 || test[i].getSegmentFrac() > 1) { | |
276 | // might still be one road that bends but that will not cause trouble | |
277 | hasMultipleRoads = true; | |
278 | return true; | |
279 | } | |
280 | } | |
281 | ||
282 | // we found a single road instance that should be used for all interpolated numbers | |
274 | 283 | roadForInterpolatedHouses = test[0].getRoad(); |
275 | 284 | |
276 | 285 | // we found a single plausible road, make sure that both nodes are using it |
277 | for (int i = 0; i < 2; i++){ | |
278 | if (knownHouses[i].getRoad() != test[i].getRoad() || knownHouses[i].getSegment() != test[i].getSegment()){ | |
286 | for (int i = 0; i < 2; i++) { | |
287 | if (knownHouses[i].getRoad() != test[i].getRoad() || knownHouses[i].getSegment() != test[i].getSegment()) { | |
279 | 288 | copyRoadData(test[i], knownHouses[i]); |
280 | 289 | knownHouses[i].forgetAlternativeRoads(); |
281 | 290 | } |
282 | if (knownHouses[i].getSegmentFrac() < 0 || knownHouses[i].getSegmentFrac() > 1){ | |
283 | hasMultipleRoads = true; | |
284 | } | |
285 | } | |
286 | if (knownHouses[0].isLeft() != knownHouses[1].isLeft()){ | |
287 | log.warn("addr:interpolation way crosses road",streetName,this); | |
291 | } | |
292 | if (knownHouses[0].isLeft() != knownHouses[1].isLeft()) { | |
293 | log.warn("addr:interpolation way crosses road", streetName, this); | |
288 | 294 | return false; |
289 | 295 | } |
290 | 296 | return true; |
478 | 484 | return false; |
479 | 485 | } |
480 | 486 | |
481 | public boolean foundCluster() { | |
482 | return foundCluster; | |
483 | } | |
484 | ||
485 | 487 | public void setEqualEnds() { |
486 | 488 | this.equalEnds = true; |
487 | 489 |
1300 | 1300 | String tagName = tagEntry.getKey(); |
1301 | 1301 | // all tags are style relevant |
1302 | 1302 | // except: type (for relations), mkgmap:* |
1303 | boolean isStyleRelevant = !(element instanceof Relation && "typ".equals(tagName)) | |
1303 | boolean isStyleRelevant = !(element instanceof Relation && "type".equals(tagName)) | |
1304 | 1304 | && !tagName.startsWith("mkgmap:"); |
1305 | 1305 | if (isStyleRelevant) { |
1306 | 1306 | return true; |