source: osm/applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Buildings.java@ 20825

Last change on this file since 20825 was 20659, checked in by pieren, 15 years ago

added a scroll bar in preferences

File size: 26.7 KB
Line 
1package cadastre_fr;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.Color;
6import java.awt.Point;
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.awt.event.MouseEvent;
10import java.awt.event.MouseListener;
11import java.awt.event.MouseMotionListener;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.HashMap;
16import java.util.HashSet;
17import java.util.LinkedList;
18import java.util.List;
19import java.util.Map;
20import java.util.TreeMap;
21
22import javax.swing.JOptionPane;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.gui.MapFrame;
26import org.openstreetmap.josm.actions.mapmode.MapMode;
27import org.openstreetmap.josm.command.AddCommand;
28import org.openstreetmap.josm.command.ChangeCommand;
29import org.openstreetmap.josm.command.ChangePropertyCommand;
30import org.openstreetmap.josm.command.Command;
31import org.openstreetmap.josm.command.MoveCommand;
32import org.openstreetmap.josm.command.SequenceCommand;
33import org.openstreetmap.josm.data.coor.EastNorth;
34import org.openstreetmap.josm.data.osm.BBox;
35import org.openstreetmap.josm.data.osm.DataSet;
36import org.openstreetmap.josm.data.osm.Node;
37import org.openstreetmap.josm.data.osm.Way;
38import org.openstreetmap.josm.data.osm.WaySegment;
39import org.openstreetmap.josm.tools.ImageProvider;
40import org.openstreetmap.josm.tools.Shortcut;
41import org.openstreetmap.josm.gui.layer.Layer;
42
43/**
44 * Trace a way around buildings from cadastre images.
45 * Inspired by Lakewalker plugin.
46 * @author Pieren
47 */
48public class Buildings extends MapMode implements MouseListener, MouseMotionListener {
49
50 private static final long serialVersionUID = 1L;
51 GeorefImage selectedImage;
52 WMSLayer selectedLayer;
53 private EastNorth clickedEastNorth;
54 private class Pixel {
55 public Point p;
56 public int dir;
57 public Pixel(int x, int y, int dir) {
58 this.p = new Point(x,y);
59 this.dir = dir;
60 }
61 @Override
62 public int hashCode() {
63 return p.hashCode();
64 }
65 @Override
66 public boolean equals(Object obj) {
67 if (obj instanceof Pixel)
68 return p.equals(new Point(((Pixel)obj).p.x, ((Pixel)obj).p.y));
69 return p.equals(obj);
70 }
71 }
72 private ArrayList<Pixel> listPixels = new ArrayList<Pixel>();
73
74 private static final int cMaxnode = 10000;
75 private static final double cDistanceForOptimization = 0.7;
76 private int[] dirsX = new int[] {1,1,0,-1,-1,-1,0,1};
77 private int[] dirsY = new int[] {0,1,1,1,0,-1,-1,-1};
78
79 private int orange = Color.ORANGE.getRGB(); // new color of pixels ending nowhere (cul-de-sac)
80 BuildingsImageModifier bim = new BuildingsImageModifier();
81
82 private double snapDistance = Main.pref.getDouble("cadastrewms.snap-distance", 50); // in centimeters
83 private double snapDistanceSq = snapDistance*snapDistance;
84 private double dx, dy;
85
86
87 public Buildings(MapFrame mapFrame) {
88 super(tr("Grab buildings"), "buildings",
89 tr("Extract building on click (vector images only)"),
90 Shortcut.registerShortcut("mapmode:buildings", tr("Mode: {0}", tr("Buildings")), KeyEvent.VK_E, Shortcut.GROUP_EDIT),
91 mapFrame, ImageProvider.getCursor("normal", "move"));
92 }
93
94 @Override public void enterMode() {
95 super.enterMode();
96 boolean atLeastOneBuildingLayer = false;
97 for (Layer layer : Main.map.mapView.getAllLayers()) {
98 if (layer instanceof WMSLayer && ((WMSLayer)layer).isBuildingsOnly()) {
99 atLeastOneBuildingLayer = true;
100 break;
101 }
102 }
103 if (atLeastOneBuildingLayer && Main.main.getCurrentDataSet() != null) {
104 Main.map.mapView.addMouseListener(this);
105 Main.map.mapView.addMouseMotionListener(this);
106 } else {
107 JOptionPane.showMessageDialog(Main.parent,tr("This feature requires (at least) one special cadastre\nBuildings layer and an OSM data layer."));
108 exitMode();
109 Main.map.selectMapMode((MapMode)Main.map.getDefaultButtonAction());
110 }
111 }
112
113 @Override public void exitMode() {
114 super.exitMode();
115 Main.map.mapView.removeMouseListener(this);
116 Main.map.mapView.removeMouseMotionListener(this);
117 }
118
119 @Override
120 public void mousePressed(MouseEvent e) {
121 if (e.getButton() != MouseEvent.BUTTON1)
122 return;
123 selectedImage = null;
124 // ctrl = do not merge the new polygon with adjacent elements
125 boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
126 // shift = do not use the parcel as a separator
127 boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
128 // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
129 for (Layer layer : Main.map.mapView.getAllLayers()) {
130 if (layer.isVisible() && layer instanceof WMSLayer && ((WMSLayer)layer).isBuildingsOnly() ) {
131 clickedEastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
132 selectedLayer = ((WMSLayer) layer);
133 selectedImage = selectedLayer.findImage(clickedEastNorth);
134 }
135 }
136 if (selectedImage != null) {
137 int x = (int)((clickedEastNorth.east() - selectedImage.min.east())*selectedImage.getPixelPerEast());
138 int y = selectedImage.image.getHeight() - (int)((clickedEastNorth.north() - selectedImage.min.north())*selectedImage.getPixelPerNorth());
139 int rgb = selectedImage.image.getRGB(x, y);
140 System.out.println("image found"+", x="+x+", y="+y+", RGB="+rgb);
141 boolean clickOnRoof = bim.isRoofColor(rgb, shift);
142 boolean clickOnBuilding = bim.isBuildingColor(rgb, shift);
143 if (clickOnRoof || clickOnBuilding) {
144 if (traceBuilding(x, y, clickOnBuilding, shift) && listPixels.size() > 3) {
145 Way wayToCreate = new Way();
146 Way way2 = new Way();
147 double pPE = selectedImage.getPixelPerEast();
148 double pPN = selectedImage.getPixelPerNorth();
149 for (int i=0; i < listPixels.size(); i++) {
150 EastNorth en = new EastNorth(selectedImage.min.east() + ((listPixels.get(i).p.x + 0.5)/ pPE),
151 selectedImage.max.north() - ((listPixels.get(i).p.y + 0.5)/ pPN));
152 Node nodeToAdd = new Node(Main.proj.eastNorth2latlon(en));
153 wayToCreate.addNode(nodeToAdd);
154 }
155 wayToCreate.addNode(wayToCreate.getNode(0)); // close the way
156 new SimplifyWay().simplifyWay(wayToCreate, 0.2);
157 // move the node closing the loop and simplify again
158 for (int i = 1; i < wayToCreate.getNodesCount(); i++) {
159 way2.addNode(wayToCreate.getNode(i));
160 }
161 way2.addNode(way2.getNode(0));
162 new SimplifyWay().simplifyWay(way2, 0.2);
163 simplifyAngles(way2);
164 Way wayToAdd = new Way();
165 Collection<Command> cmds = new LinkedList<Command>();
166 if (ctrl) {
167 for (int i = 0; i < way2.getNodesCount()-1; i++) {
168 wayToAdd.addNode(way2.getNode(i));
169 cmds.add(new AddCommand(wayToAdd.getNode(i)));
170 }
171 wayToAdd.addNode(wayToAdd.getNode(0)); // close the polygon !
172 } else {
173 for (int i = 0; i < way2.getNodesCount()-1; i++) {
174 Node nearestNode = getNearestNode(way2.getNode(i));
175 if (nearestNode == null) {
176 // check if we can join new node to existing ways
177 List<WaySegment> wss = getNearestWaySegments(way2.getNode(i));
178 wayToAdd.addNode(way2.getNode(i));
179 cmds.add(new AddCommand(way2.getNode(i)));
180 if (wss.size() > 0) {
181 cmds.add(new MoveCommand(way2.getNode(i), dx, dy));
182 joinNodeToExistingWays(wss, way2.getNode(i), cmds);
183 }
184 } else {
185 // replace new node by an existing nearest node
186 wayToAdd.addNode(nearestNode);
187 cmds.add(new MoveCommand(nearestNode, dx, dy));
188 }
189 }
190 wayToAdd.addNode(wayToAdd.getNode(0)); // close the polygon !
191 for (int i = 1; i < wayToAdd.getNodesCount(); i++) {
192 Node nodeToJoin = existingNodesInNewSegment(wayToAdd.getNode(i-1), wayToAdd.getNode(i), wayToAdd);
193 // check if we join new way to existing nodes
194 if (nodeToJoin != null) {
195 List<WaySegment> wss = new LinkedList<WaySegment>();
196 wss.add(new WaySegment(wayToAdd, i-1));
197 wayToAdd = joinNodeToExistingWays(wss, nodeToJoin, cmds);
198 cmds.add(new MoveCommand(nodeToJoin, dx, dy));
199 i--; // re-assess the new segment (perhaps several nodes to join)
200 }
201 }
202 }
203 cmds.add(new AddCommand(wayToAdd));
204 if (clickOnBuilding)
205 addBuildingTags(cmds, wayToAdd);
206 if (clickOnRoof) {
207 addRoofTags(cmds, wayToAdd);
208 }
209 Main.main.undoRedo.add(new SequenceCommand(tr("Create building"), cmds));
210 getCurrentDataSet().setSelected(wayToAdd);
211 Main.map.repaint();
212 }
213 }
214 }
215 }
216
217 @Override public void mouseDragged(MouseEvent e) {
218 }
219
220 @Override public void mouseReleased(MouseEvent e) {
221 }
222
223 public void mouseEntered(MouseEvent e) {
224 }
225 public void mouseExited(MouseEvent e) {
226 }
227 public void mouseMoved(MouseEvent e) {
228 }
229
230 @Override public void mouseClicked(MouseEvent e) {
231 }
232
233 private void addBuildingTags(Collection<Command> cmds, Way wayToAdd) {
234 cmds.add(new ChangePropertyCommand(wayToAdd, "building", "yes"));
235 }
236
237 private void addRoofTags(Collection<Command> cmds, Way wayToAdd) {
238 cmds.add(new ChangePropertyCommand(wayToAdd, "building", "yes"));
239 cmds.add(new ChangePropertyCommand(wayToAdd, "wall", "no"));
240 }
241
242 private boolean traceBuilding (int x, int y, boolean buildingColors, boolean ignoreParcels) {
243 // search start point at same x but smallest y (upper border on the screen)
244 int startY = 0; int startX = x;
245 while (y > 0) {
246 y--;
247 if (!bim.isBuildingOrRoofColor(selectedImage.image, x, y, buildingColors, ignoreParcels)) {
248 System.out.println("at "+x+","+y+" color was "+selectedImage.image.getRGB(x,y));
249 y++;
250 startY = y;
251 break;
252 }
253 }
254 if (startY == 0) {
255 System.out.println("border not found");
256 return false;
257 } else
258 System.out.println("start at x="+startX+", y="+startY);
259 listPixels.clear();
260 int test_x = 0;
261 int test_y = 0;
262 int new_dir = 0;
263 addPixeltoList(x, y, new_dir);
264 int last_dir = 1;
265 for(int i = 0; i < cMaxnode; i++){
266 //System.out.println("node "+i);
267 for(int d = 1; d <= this.dirsY.length; d++){
268 new_dir = (last_dir + d + 4) % 8;
269 test_x = x + this.dirsX[new_dir];
270 test_y = y + this.dirsY[new_dir];
271 if (test_x < 0 || test_x >= selectedImage.image.getWidth() ||
272 test_y < 0 || test_y >= selectedImage.image.getHeight()){
273 System.out.println("Outside image");
274 return false;
275 }
276 if (bim.isBuildingOrRoofColor(selectedImage.image, test_x, test_y, buildingColors, ignoreParcels)){
277 System.out.println("building color at "+test_x+","+test_y+" new_dir="+new_dir);
278 break;
279 }
280
281 if(d == this.dirsY.length-1){
282 System.out.println("Got stuck at "+x+","+y);
283 // cul-de-sac : disable current pixel and move two steps back
284 selectedImage.image.setRGB(x, y, orange);
285 if (removeTwoLastPixelsFromList()) {
286 x = listPixels.get(listPixels.size()-1).p.x;
287 y = listPixels.get(listPixels.size()-1).p.y;
288 last_dir = listPixels.get(listPixels.size()-1).dir;
289 System.out.println("return at "+x+","+y+" and try again");
290 d = 1;
291 continue;
292 } else {
293 System.out.println("cannot try another way");
294 return false;
295 }
296 }
297 }
298// if (last_dir == new_dir)
299// // Same direction. First simplification by removing previous pixel.
300// listPixels.remove(listPixels.size()-1);
301 last_dir = new_dir;
302 // Set the pixel we found as current
303 x = test_x;
304 y = test_y;
305 // Break the loop if we managed to get back to our starting point
306 if (x == startX && y == startY) {
307 System.out.println("loop closed at "+x+","+y+", exit");
308 break;
309 } else if (listPixels.contains(new Pixel(x, y, 0))){
310 int j = listPixels.indexOf(new Pixel(x, y, 0));
311 int l = listPixels.size();
312 for (int k = j; k < l; k++)
313 listPixels.remove(j);
314 }
315 addPixeltoList(x, y, new_dir);
316 }
317 System.out.println("list size="+listPixels.size());
318 return true;
319 }
320
321 private void addPixeltoList(int x, int y, int dir) {
322 listPixels.add( new Pixel(x, y, dir));
323 System.out.println("added pixel at "+x+","+y);
324 }
325
326 private boolean removeTwoLastPixelsFromList() {
327 if (listPixels.size() > 2) {
328 System.out.println("remove "+listPixels.get(listPixels.size()-1).p.x + ","+listPixels.get(listPixels.size()-1).p.y);
329 listPixels.remove(listPixels.size()-1);
330 System.out.println("remove "+listPixels.get(listPixels.size()-1).p.x + ","+listPixels.get(listPixels.size()-1).p.y);
331 listPixels.remove(listPixels.size()-1);
332 return true;
333 }
334 return false;
335 }
336
337 private BBox getSnapDistanceBBox(Node n) {
338 return new BBox(Main.proj.eastNorth2latlon(new EastNorth(n.getEastNorth().east() - snapDistance, n.getEastNorth().north() - snapDistance)),
339 Main.proj.eastNorth2latlon(new EastNorth(n.getEastNorth().east() + snapDistance, n.getEastNorth().north() + snapDistance)));
340 }
341
342 private Point getPointInCm(Node n) {
343 return new Point(new Double(n.getEastNorth().getX()*100).intValue(),
344 new Double(n.getEastNorth().getY()*100).intValue());
345 }
346
347 public Node getNearestNode(Node newNode) {
348 Point newPoint = getPointInCm(newNode);
349 DataSet ds = getCurrentDataSet();
350 if (ds == null)
351 return null;
352
353 double minDistanceSq = snapDistanceSq;
354 Node minNode = null;
355 for (Node n : ds.searchNodes(getSnapDistanceBBox(newNode))) {
356 if (!n.isUsable()) {
357 continue;
358 }
359 Point sp = new Point(new Double(n.getEastNorth().getX()*100).intValue(),
360 new Double(n.getEastNorth().getY()*100).intValue());
361 double dist = newPoint.distanceSq(sp); // in centimeter !
362 if (dist < minDistanceSq) {
363 minDistanceSq = dist;
364 minNode = n;
365 }
366 // when multiple nodes on one point, prefer new or selected nodes
367 else if (dist == minDistanceSq && minNode != null
368 && ((n.isNew() && ds.isSelected(n))
369 || (!ds.isSelected(minNode) && (ds.isSelected(n) || n.isNew())))) {
370 minNode = n;
371 }
372 }
373 if (minNode != null) {
374 dx = (newNode.getEastNorth().getX() - minNode.getEastNorth().getX())/2;
375 dy = (newNode.getEastNorth().getY() - minNode.getEastNorth().getY())/2;
376 }
377 return minNode;
378 }
379
380 private List<WaySegment> getNearestWaySegments(Node newNode) {
381 Point newPoint = new Point(new Double(newNode.getEastNorth().getX()*100).intValue(),
382 new Double(newNode.getEastNorth().getY()*100).intValue());
383 TreeMap<Double, List<WaySegment>> nearest = new TreeMap<Double, List<WaySegment>>();
384 DataSet ds = getCurrentDataSet();
385 if (ds == null)
386 return null;
387
388 for (Way w : ds.searchWays(getSnapDistanceBBox(newNode))) {
389 if (!w.isUsable()) {
390 continue;
391 }
392 Node lastN = null;
393 int i = -2;
394 for (Node n : w.getNodes()) {
395 i++;
396 if (n.isDeleted() || n.isIncomplete()) {
397 continue;
398 }
399 if (lastN == null) {
400 lastN = n;
401 continue;
402 }
403
404 Point A = getPointInCm(lastN);
405 Point B = getPointInCm(n);
406 double c = A.distanceSq(B);
407 double a = newPoint.distanceSq(B);
408 double b = newPoint.distanceSq(A);
409 double perDist = a - (a - b + c) * (a - b + c) / 4 / c;
410 if (perDist < snapDistanceSq && a < c + snapDistanceSq && b < c + snapDistanceSq) {
411 if (ds.isSelected(w)) {
412 perDist -= 0.00001;
413 }
414 List<WaySegment> l;
415 if (nearest.containsKey(perDist)) {
416 l = nearest.get(perDist);
417 } else {
418 l = new LinkedList<WaySegment>();
419 nearest.put(perDist, l);
420 }
421 double ratio = A.distance(newPoint)/A.distance(B);
422 Point perP = new Point(A.x+new Double((B.x-A.x)*ratio).intValue(),
423 A.y+new Double((B.y-A.y)*ratio).intValue());
424 dx = (perP.x-newPoint.x)/200.0; // back to meters this time and whole distance by two
425 dy = (perP.y-newPoint.y)/200.0;
426// System.out.println(angle+","+ ratio+","+perP );
427 l.add(new WaySegment(w, i));
428 }
429
430 lastN = n;
431 }
432 }
433 ArrayList<WaySegment> nearestList = new ArrayList<WaySegment>();
434 for (List<WaySegment> wss : nearest.values()) {
435 nearestList.addAll(wss);
436 }
437 return nearestList;
438 }
439
440 private Node existingNodesInNewSegment(Node n1, Node n2, Way way) {
441 double minx = Math.min(n1.getEastNorth().getX(), n2.getEastNorth().getX())*100;
442 double miny = Math.min(n1.getEastNorth().getY(), n2.getEastNorth().getY())*100;
443 double maxx = Math.max(n1.getEastNorth().getX(), n2.getEastNorth().getX())*100;
444 double maxy = Math.max(n1.getEastNorth().getY(), n2.getEastNorth().getY())*100;
445// if ((maxx-minx)/2 < snapDistance && (maxy-miny)/2 < snapDistance) {
446// return null;
447// }
448 BBox bbox = new BBox( Main.proj.eastNorth2latlon(new EastNorth((minx-snapDistance)/100, (miny-snapDistance)/100)),
449 Main.proj.eastNorth2latlon(new EastNorth((maxx+snapDistance)/100, (maxy+snapDistance)/100)));
450 DataSet ds = getCurrentDataSet();
451 if (ds == null) {
452 return null;
453 }
454 Node ret = null;
455 List<Node> nodesInBbox = ds.searchNodes(bbox);
456 for (Node n:nodesInBbox) {
457 Point A = getPointInCm(n1);
458 Point B = getPointInCm(n2);
459 Point existingPoint = getPointInCm(n);
460 double c = A.distanceSq(B);
461 double a = existingPoint.distanceSq(B);
462 double b = existingPoint.distanceSq(A);
463 double perDist = a - (a - b + c) * (a - b + c) / 4 / c;
464 if (perDist < snapDistanceSq && a < c + snapDistanceSq && b < c + snapDistanceSq
465 && n.isUsable() && !way.getNodes().contains(n)) {
466 ret = n;
467 // shift the existing node to the half distance of the joined new segment
468 double ratio = A.distance(existingPoint)/A.distance(B);
469 Point perP = new Point(A.x+new Double((B.x-A.x)*ratio).intValue(),
470 A.y+new Double((B.y-A.y)*ratio).intValue());
471 dx = (perP.x-existingPoint.x)/200.0; // back to meters this time and whole distance by two
472 dy = (perP.y-existingPoint.y)/200.0;
473 break;
474 }
475 }
476// System.out.println("Found "+nodesInBbox.size()+", join node "+ret+" to new segment; "+Main.proj.latlon2eastNorth(bbox.getBottomRight())+","+Main.proj.latlon2eastNorth(bbox.getTopLeft()));
477 return ret;
478 }
479
480 private Way joinNodeToExistingWays(List<WaySegment> wss, Node newNode, Collection<Command> cmds) {
481 HashMap<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
482 for (WaySegment ws : wss) {
483 List<Integer> is;
484 if (insertPoints.containsKey(ws.way)) {
485 is = insertPoints.get(ws.way);
486 } else {
487 is = new ArrayList<Integer>();
488 insertPoints.put(ws.way, is);
489 }
490
491 if (ws.way.getNode(ws.lowerIndex) != newNode && ws.way.getNode(ws.lowerIndex+1) != newNode) {
492 is.add(ws.lowerIndex);
493 }
494 }
495
496 Way wnew = null;
497 for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
498 List<Integer> is = insertPoint.getValue();
499 if (is.size() == 0)
500 continue;
501
502 Way w = insertPoint.getKey();
503 List<Node> nodesToAdd = w.getNodes();
504 pruneSuccsAndReverse(is);
505 for (int i : is) {
506 nodesToAdd.add(i+1, newNode);
507 }
508 wnew = new Way(w);
509 wnew.setNodes(nodesToAdd);
510 cmds.add(new ChangeCommand(w, wnew));
511 }
512 return wnew;
513 }
514
515 private static void pruneSuccsAndReverse(List<Integer> is) {
516 HashSet<Integer> is2 = new HashSet<Integer>();
517 for (int i : is) {
518 if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
519 is2.add(i);
520 }
521 }
522 is.clear();
523 is.addAll(is2);
524 Collections.sort(is);
525 Collections.reverse(is);
526 }
527
528 /*
529 * The standard simplifier leaves sometimes closed nodes at buildings corners.
530 * We remove here the node not altering the building angle.
531 */
532 private void simplifyAngles(Way way){
533 for (int i=1; i<way.getNodes().size(); i++){
534 Node n1 = way.getNode(i-1);
535 Node n2 = way.getNode(i);
536 double dist = getPointInCm(n1).distance(getPointInCm(n2))/100;
537// System.out.println("dist="+dist+":"+(dist < cDistanceForOptimization));
538 if (dist < cDistanceForOptimization) {
539 Node n0, n3;
540 if (i > 1)
541 n0 = way.getNode(i-2);
542 else
543 n0 = way.getNode(way.getNodes().size()-1);
544 if (i < way.getNodes().size()-1)
545 n3 = way.getNode(i+1);
546 else
547 n3 = way.getNode(0);
548 double angle1 = AngleOfView(n1.getCoor().getX(), n1.getCoor().getY(),
549 n0.getCoor().getX(), n0.getCoor().getY(),
550 n2.getCoor().getX(), n2.getCoor().getY());
551// System.out.println("angle n0,n1,n2="+(angle1*180/Math.PI));
552 double angle2 = AngleOfView(n2.getCoor().getX(), n2.getCoor().getY(),
553 n1.getCoor().getX(), n1.getCoor().getY(),
554 n3.getCoor().getX(), n3.getCoor().getY());
555// System.out.println("angle n1,n2,n3="+(angle2*180/Math.PI));
556 if (angle1 > Math.PI*0.9 && angle1 < Math.PI*1.1) {
557 way.removeNode(n1);
558 System.out.println("remove n1");
559 } else if (angle2 > Math.PI*0.9 && angle2 < Math.PI*1.1) {
560 way.removeNode(n2);
561 System.out.println("remove n2");
562 } else
563 System.out.println("no angle near PI");
564 }
565 }
566 }
567
568 private double AngleOfView ( double ViewPt_X, double ViewPt_Y,
569 double Pt1_X, double Pt1_Y,
570 double Pt2_X, double Pt2_Y ) {
571 double a1, b1, a2, b2, a, b, t, cosinus ;
572 a1 = Pt1_X - ViewPt_X ;
573 a2 = Pt1_Y - ViewPt_Y ;
574 b1 = Pt2_X - ViewPt_X ;
575 b2 = Pt2_Y - ViewPt_Y ;
576 a = Math.sqrt( (a1*a1) + (a2*a2) );
577 b = Math.sqrt ( (b1*b1) + (b2*b2) );
578 if ( (a == 0.0) || (b == 0.0) )
579 return (0.0) ;
580 cosinus = (a1*b1+a2*b2) / (a*b) ;
581 t = Math.acos ( cosinus );
582 //t = t * 180.0 / Math.PI ;
583 return (t);
584 }
585
586 /*
587 * coming from SimplifyWayAction
588 */
589// private boolean isRequiredNode(Way way, Node node) {
590// boolean isRequired = Collections.frequency(way.getNodes(), node) > 1;
591// if (! isRequired) {
592// List<OsmPrimitive> parents = new LinkedList<OsmPrimitive>();
593// parents.addAll(node.getReferrers());
594// parents.remove(way);
595// isRequired = !parents.isEmpty();
596// }
597// if (!isRequired) {
598// isRequired = node.isTagged();
599// }
600// return isRequired;
601// }
602}
Note: See TracBrowser for help on using the repository browser.