Changeset 19927 in osm for applications/editors/josm/plugins/tracer/src/org
- Timestamp:
- 2010-02-07T23:24:41+01:00 (15 years ago)
- Location:
- applications/editors/josm/plugins/tracer/src/org/openstreetmap/josm/plugins/tracer
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/tracer/src/org/openstreetmap/josm/plugins/tracer/TracerAction.java
r19892 r19927 17 17 import java.util.Collection; 18 18 import java.util.LinkedList; 19 import java.util.List;20 19 import org.openstreetmap.josm.Main; 21 20 import org.openstreetmap.josm.actions.mapmode.MapMode; 22 21 import org.openstreetmap.josm.command.AddCommand; 23 import org.openstreetmap.josm.command.ChangeCommand;24 22 import org.openstreetmap.josm.command.Command; 25 import org.openstreetmap.josm.command.DeleteCommand;26 import org.openstreetmap.josm.command.MoveCommand;27 23 import org.openstreetmap.josm.command.SequenceCommand; 28 24 import org.openstreetmap.josm.data.coor.LatLon; … … 35 31 import org.openstreetmap.josm.tools.Shortcut; 36 32 import org.xml.sax.SAXException; 37 import org.openstreetmap.josm.data.osm.BBox;38 import org.openstreetmap.josm.data.osm.OsmPrimitive;39 import org.openstreetmap.josm.tools.Pair;40 33 41 34 class TracerAction extends MapMode implements MouseListener { … … 47 40 private boolean shift; 48 41 protected TracerServer server = new TracerServer(); 49 50 final double MIN_DISTANCE = 0.000015; //Minimal distance, when nodes are merged51 final double MIN_DISTANCE_TW = 0.000015; //Minimal distance, when node is connected to other way52 final double MIN_DISTANCE_SQ = 0.000015; //Minimal distance, when other node is connected this way53 final double MAX_ANGLE = 30; //Minimal angle, when other node is connected this way54 42 55 43 public TracerAction(MapFrame mapFrame) { … … 108 96 } 109 97 110 private boolean isBuilding(Way w) {111 return (w.getKeys().get("building") == null ? false : w.getKeys().get("building").equals("yes"));112 }113 114 private boolean isInBuilding(Node n) {115 for (OsmPrimitive op : n.getReferrers()) {116 if (op instanceof Way) {117 if (isBuilding((Way) op)) {118 return true;119 }120 }121 }122 return false;123 }124 125 /**126 * Try connect way to other buidings.127 * @param way Way to connect.128 * @return Commands.129 */130 private Command connectObjects(Way way) {131 132 List<Command> cmds = new LinkedList<Command>();133 Way newWay = new Way(way);134 for (int i = 0; i < way.getNodesCount() - 1; i++) {135 Node n = way.getNode(i);136 //System.out.println("-------");137 //System.out.println("Node: " + n);138 LatLon ll = n.getCoor();139 BBox bbox = new BBox(140 ll.getX() - MIN_DISTANCE,141 ll.getY() - MIN_DISTANCE,142 ll.getX() + MIN_DISTANCE,143 ll.getY() + MIN_DISTANCE);144 145 // bude se node slucovat s jinym?146 double minDistanceSq = MIN_DISTANCE;147 List<Node> nodes = Main.main.getCurrentDataSet().searchNodes(bbox);148 Node nearestNode = null;149 for (Node nn : nodes) {150 if (!nn.isUsable() || way.containsNode(nn) || newWay.containsNode(nn) || !isInBuilding(nn)) {151 continue;152 }153 double dist = nn.getCoor().distance(ll);154 if (dist < minDistanceSq) {155 minDistanceSq = dist;156 nearestNode = nn;157 }158 }159 160 //System.out.println("Nearest: " + nearestNode);161 if (nearestNode == null) {162 cmds.addAll(tryConnectNodeToAnyWay(n));163 } else {164 cmds.addAll(mergeNodes(n, nearestNode, newWay));165 }166 }167 168 cmds.add(new ChangeCommand(way, trySplitWayByAnyNodes(newWay)));169 170 Command cmd = new SequenceCommand(tr("Merge objects nodes"), cmds);171 return cmd;172 }173 174 /**175 * Merges two nodes176 * @param n1 First node177 * @param n2 Second node178 * @param way Way containing first node179 * @return List of Commands.180 */181 private List<Command> mergeNodes(Node n1, Node n2, Way way){182 List<Command> cmds = new LinkedList<Command>();183 cmds.add(new MoveCommand(n2,184 (n1.getEastNorth().getX() - n2.getEastNorth().getX())/2,185 (n1.getEastNorth().getY() - n2.getEastNorth().getY())/2186 ));187 188 int j = way.getNodes().indexOf(n1);189 way.addNode(j, n2);190 if (j == 0) {191 // first + last point192 way.addNode(way.getNodesCount(), n2);193 }194 way.removeNode(n1);195 196 cmds.add(new DeleteCommand(n1));197 return cmds;198 }199 200 /**201 * Try connect node "node" to way of other building.202 *203 * Zkusi zjistit, zda node neni tak blizko nejake usecky existujici budovy,204 * ze by mel byt zacnenen do teto usecky. Pokud ano, provede to.205 *206 * @param node Node to connect.207 * @throws IllegalStateException208 * @throws IndexOutOfBoundsException209 * @return List of Commands.210 */211 private List<Command> tryConnectNodeToAnyWay(Node node)212 throws IllegalStateException, IndexOutOfBoundsException {213 214 List<Command> cmds = new LinkedList<Command>();215 216 LatLon ll = node.getCoor();217 BBox bbox = new BBox(218 ll.getX() - MIN_DISTANCE_TW,219 ll.getY() - MIN_DISTANCE_TW,220 ll.getX() + MIN_DISTANCE_TW,221 ll.getY() + MIN_DISTANCE_TW);222 223 // node nebyl slouceny s jinym224 // hledani pripadne blizke usecky, kam bod pridat225 List<Way> ways = Main.main.getCurrentDataSet().searchWays(bbox);226 double minDist = Double.MAX_VALUE;227 Way nearestWay = null;228 int nearestNodeIndex = 0;229 for (Way ww : ways) {230 if (!ww.isUsable() || ww.containsNode(node) || !isBuilding(ww)) {231 continue;232 }233 for (Pair<Node, Node> np : ww.getNodePairs(false)) {234 double dist = TracerGeometry.distanceFromSegment(ll, np.a.getCoor(), np.b.getCoor());235 if (dist < minDist) {236 minDist = dist;237 nearestWay = ww;238 nearestNodeIndex = ww.getNodes().indexOf(np.a);239 }240 }241 }242 //System.out.println("Nearest way: " + nearestWay + " distance: " + minDist);243 if (minDist < MIN_DISTANCE_TW) {244 Way newNWay = new Way(nearestWay);245 newNWay.addNode(nearestNodeIndex + 1, node);246 //System.out.println("New way:" + newNWay);247 Command c = new ChangeCommand(nearestWay, newNWay);248 c.executeCommand();249 cmds.add(c);250 }251 return cmds;252 }253 254 /**255 * Try split way by any existing buiding nodes.256 *257 * Zkusi zjistit zda nejake usecka z way by nemela prochazet nejakym existujicim bodem,258 * ktery je ji velmi blizko. Pokud ano, tak puvodni usecku rozdeli na dve tak, aby259 * prochazela takovym bodem.260 *261 * @param way Way to split.262 * @throws IndexOutOfBoundsException263 * @throws IllegalStateException264 * @return Modified way265 */266 private Way trySplitWayByAnyNodes(Way way)267 throws IndexOutOfBoundsException, IllegalStateException {268 269 // projdi kazdou novou usecku a zjisti, zda by nemela vest pres existujici body270 int i = 0;271 while (i < way.getNodesCount()) {272 // usecka n1, n2273 LatLon n1 = way.getNodes().get(i).getCoor();274 LatLon n2 = way.getNodes().get((i + 1) % way.getNodesCount()).getCoor();275 //System.out.println(way.getNodes().get(i) + "-----" + way.getNodes().get((i + 1) % way.getNodesCount()));276 double minDistanceSq = MIN_DISTANCE_SQ;277 double maxAngle = MAX_ANGLE;278 List<Node> nodes = Main.main.getCurrentDataSet().searchNodes(new BBox(279 Math.min(n1.getX(), n2.getX()) - minDistanceSq,280 Math.min(n1.getY(), n2.getY()) - minDistanceSq,281 Math.max(n1.getX(), n2.getX()) + minDistanceSq,282 Math.max(n1.getY(), n2.getY()) + minDistanceSq283 ));284 Node nearestNode = null;285 for (Node nod : nodes) {286 if (!nod.isUsable() || way.containsNode(nod) || !isInBuilding(nod)) {287 continue;288 }289 LatLon nn = nod.getCoor();290 double dist = TracerGeometry.distanceFromSegment(nn, n1, n2);291 double angle = TracerGeometry.angleOfLines(n1, nn, nn, n2);292 //System.out.println("Angle: " + angle + " distance: " + dist + " Node: " + nod);293 if (!n1.equalsEpsilon(nn) && !n2.equalsEpsilon(nn) && dist < minDistanceSq && Math.abs(angle) < maxAngle) {294 maxAngle = angle;295 nearestNode = nod;296 }297 }298 //System.out.println("Nearest_: " + nearestNode);299 //System.out.println("");300 if (nearestNode == null) {301 // tato usecka se nerozdeli302 i++;303 continue;304 } else {305 // rozdeleni usecky306 way.addNode(i + 1, nearestNode);307 continue; // i nezvetsuji, treba bude treba rozdelit usecku znovu308 }309 }310 return way;311 }312 313 98 private void tagBuilding(Way way) { 314 99 if(!alt) way.put("building", "yes"); … … 345 130 // connect to other buildings 346 131 if (!ctrl) { 347 commands.add( connectObjects(way));348 }132 commands.add(ConnectWays.connect(way)); 133 } 349 134 350 135 if (!commands.isEmpty()) { 351 Main.main.undoRedo.add(new SequenceCommand(tr("Tracer building"), commands));136 Main.main.undoRedo.add(new SequenceCommand(tr("Tracer building"), commands)); 352 137 353 138 if (shift) {
Note:
See TracChangeset
for help on using the changeset viewer.