source: josm/trunk/src/org/openstreetmap/josm/data/validation/util/ValUtil.java@ 6360

Last change on this file since 6360 was 6360, checked in by Don-vip, 11 years ago

Sonar/Findbugs - Hide Utility Class Constructor

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.data.validation.util;
3
4import java.awt.geom.Point2D;
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.Way;
14import org.openstreetmap.josm.data.validation.OsmValidator;
15
16/**
17 * Utility class
18 *
19 * @author frsantos
20 */
21public class ValUtil {
22
23 private ValUtil() {
24 // Hide default constructor for utils classes
25 }
26
27 /**
28 * Returns the start and end cells of a way.
29 * @param w The way
30 * @param cellWays The map with all cells
31 * @return A list with all the cells the way starts or ends
32 */
33 public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays) {
34 if (w.getNodesCount() == 0)
35 return Collections.emptyList();
36
37 Node n1 = w.getNode(0);
38 Node n2 = w.getNode(w.getNodesCount() - 1);
39
40 List<List<Way>> cells = new ArrayList<List<Way>>(2);
41 Set<Point2D> cellNodes = new HashSet<Point2D>();
42 Point2D cell;
43
44 // First, round coordinates
45 long x0 = Math.round(n1.getEastNorth().east() * OsmValidator.griddetail);
46 long y0 = Math.round(n1.getEastNorth().north() * OsmValidator.griddetail);
47 long x1 = Math.round(n2.getEastNorth().east() * OsmValidator.griddetail);
48 long y1 = Math.round(n2.getEastNorth().north() * OsmValidator.griddetail);
49
50 // Start of the way
51 cell = new Point2D.Double(x0, y0);
52 cellNodes.add(cell);
53 List<Way> ways = cellWays.get(cell);
54 if (ways == null) {
55 ways = new ArrayList<Way>();
56 cellWays.put(cell, ways);
57 }
58 cells.add(ways);
59
60 // End of the way
61 cell = new Point2D.Double(x1, y1);
62 if (!cellNodes.contains(cell)) {
63 cellNodes.add(cell);
64 ways = cellWays.get( cell );
65 if (ways == null) {
66 ways = new ArrayList<Way>();
67 cellWays.put(cell, ways);
68 }
69 cells.add(ways);
70 }
71
72 // Then floor coordinates, in case the way is in the border of the cell.
73 x0 = (long) Math.floor(n1.getEastNorth().east() * OsmValidator.griddetail);
74 y0 = (long) Math.floor(n1.getEastNorth().north() * OsmValidator.griddetail);
75 x1 = (long) Math.floor(n2.getEastNorth().east() * OsmValidator.griddetail);
76 y1 = (long) Math.floor(n2.getEastNorth().north() * OsmValidator.griddetail);
77
78 // Start of the way
79 cell = new Point2D.Double(x0, y0);
80 if (!cellNodes.contains(cell)) {
81 cellNodes.add(cell);
82 ways = cellWays.get(cell);
83 if (ways == null) {
84 ways = new ArrayList<Way>();
85 cellWays.put(cell, ways);
86 }
87 cells.add(ways);
88 }
89
90 // End of the way
91 cell = new Point2D.Double(x1, y1);
92 if (!cellNodes.contains(cell)) {
93 cellNodes.add(cell);
94 ways = cellWays.get(cell);
95 if (ways == null) {
96 ways = new ArrayList<Way>();
97 cellWays.put(cell, ways);
98 }
99 cells.add(ways);
100 }
101 return cells;
102 }
103
104 /**
105 * Returns the coordinates of all cells in a grid that a line between 2
106 * nodes intersects with.
107 *
108 * @param n1 The first node.
109 * @param n2 The second node.
110 * @param gridDetail The detail of the grid. Bigger values give smaller
111 * cells, but a bigger number of them.
112 * @return A list with the coordinates of all cells
113 */
114 public static List<Point2D> getSegmentCells(Node n1, Node n2, double gridDetail) {
115 List<Point2D> cells = new ArrayList<Point2D>();
116 double x0 = n1.getEastNorth().east() * gridDetail;
117 double x1 = n2.getEastNorth().east() * gridDetail;
118 double y0 = n1.getEastNorth().north() * gridDetail + 1;
119 double y1 = n2.getEastNorth().north() * gridDetail + 1;
120
121 if (x0 > x1) {
122 // Move to 1st-4th cuadrants
123 double aux;
124 aux = x0; x0 = x1; x1 = aux;
125 aux = y0; y0 = y1; y1 = aux;
126 }
127
128 double dx = x1 - x0;
129 double dy = y1 - y0;
130 long stepY = y0 <= y1 ? 1 : -1;
131 long gridX0 = (long) Math.floor(x0);
132 long gridX1 = (long) Math.floor(x1);
133 long gridY0 = (long) Math.floor(y0);
134 long gridY1 = (long) Math.floor(y1);
135
136 long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1;
137 while ((gridX0 <= gridX1 && (gridY0 - gridY1)*stepY <= 0) && maxSteps-- > 0) {
138 cells.add( new Point2D.Double(gridX0, gridY0));
139
140 // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line?
141 // Note: segment line formula: y=dy/dx(x-x1)+y1
142 // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line
143 double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0);
144 double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1;
145
146 double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2);
147 double distY = Math.pow(scanX - x0, 2) + Math.pow(gridY0 + stepY - y0, 2);
148
149 if (distX < distY) {
150 gridX0 += 1;
151 } else {
152 gridY0 += stepY;
153 }
154 }
155 return cells;
156 }
157}
Note: See TracBrowser for help on using the repository browser.