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

Last change on this file since 3775 was 3707, checked in by bastiK, 13 years ago

Added remotecontrol plugin to josm core. This plugin was initially written by Frederik Ramm (frederik) and incorporates code taken from YWMS plugin by frsantos. Major contributions by Bodo Meissner (bomm) and stephankn. Note: The code has been added, but is not "active" yet (RemoteControl.on == false). This is because wmsplugin and imagery plugin has not been adapted to this change. They are about to be integrated as well, so this adaption is not necessary.

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