source: josm/trunk/src/org/openstreetmap/josm/actions/SelectByInternalPointAction.java@ 7180

Last change on this file since 7180 was 7146, checked in by simon04, 10 years ago

see #10037 - Improve class name

File size: 4.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import org.openstreetmap.josm.Main;
5import org.openstreetmap.josm.data.coor.EastNorth;
6import org.openstreetmap.josm.data.osm.BBox;
7import org.openstreetmap.josm.data.osm.Node;
8import org.openstreetmap.josm.data.osm.OsmPrimitive;
9import org.openstreetmap.josm.data.osm.Relation;
10import org.openstreetmap.josm.data.osm.RelationMember;
11import org.openstreetmap.josm.data.osm.Way;
12import org.openstreetmap.josm.tools.Geometry;
13
14import java.awt.event.ActionEvent;
15import java.util.ArrayList;
16import java.util.Collection;
17import java.util.TreeMap;
18
19/**
20 * This allows to select a polygon/multipolgon by an internal point.
21 */
22public class SelectByInternalPointAction extends JosmAction {
23
24 /**
25 * Returns the surrounding polygons/multipolgons
26 * ordered by their area size (from small to large)
27 * which contain the internal point.
28 *
29 * @param internalPoint the internal point.
30 */
31 public static Collection<OsmPrimitive> getSurroundingObjects(EastNorth internalPoint) {
32 final Node n = new Node(internalPoint);
33 final TreeMap<Double, OsmPrimitive> found = new TreeMap<>();
34 for (Way w : getCurrentDataSet().getWays()) {
35 if (w.isUsable() && w.isClosed()) {
36 if (Geometry.nodeInsidePolygon(n, w.getNodes())) {
37 found.put(Geometry.closedWayArea(w), w);
38 }
39 }
40 }
41 for (Relation r : getCurrentDataSet().getRelations()) {
42 if (r.isUsable() && r.isMultipolygon()) {
43 if (Geometry.isNodeInsideMultiPolygon(n, r, null)) {
44 for (RelationMember m : r.getMembers()) {
45 if (m.isWay() && m.getWay().isClosed()) {
46 found.values().remove(m.getWay());
47 }
48 }
49 // estimate multipolygon size by its bounding box area
50 BBox bBox = r.getBBox();
51 EastNorth en1 = Main.map.mapView.getProjection().latlon2eastNorth(bBox.getTopLeft());
52 EastNorth en2 = Main.map.mapView.getProjection().latlon2eastNorth(bBox.getBottomRight());
53 double s = Math.abs((en1.east() - en2.east()) * (en1.north() - en2.north()));
54 if (s == 0) s = 1e8;
55 found.put(s, r);
56 }
57 }
58 }
59 return found.values();
60 }
61
62
63 /**
64 * Returns the smallest surrounding polygon/multipolgon which contains the internal point.
65 *
66 * @param internalPoint the internal point.
67 */
68 public static OsmPrimitive getSmallestSurroundingObject(EastNorth internalPoint) {
69 final Collection<OsmPrimitive> surroundingObjects = getSurroundingObjects(internalPoint);
70 return surroundingObjects.isEmpty() ? null : surroundingObjects.iterator().next();
71 }
72
73 /**
74 * Select a polygon or multipolgon by an internal point.
75 *
76 * @param internalPoint the internal point.
77 * @param doAdd whether to add selected polygon to the current selection.
78 * @param doRemove whether to remove the selected polygon from the current selection.
79 */
80 public static void performSelection(EastNorth internalPoint, boolean doAdd, boolean doRemove) {
81 final Collection<OsmPrimitive> surroundingObjects = getSurroundingObjects(internalPoint);
82 if (surroundingObjects.isEmpty()) {
83 return;
84 } else if (doRemove) {
85 final Collection<OsmPrimitive> newSelection = new ArrayList<>(getCurrentDataSet().getSelected());
86 newSelection.removeAll(surroundingObjects);
87 getCurrentDataSet().setSelected(newSelection);
88 } else if (doAdd) {
89 final Collection<OsmPrimitive> newSelection = new ArrayList<>(getCurrentDataSet().getSelected());
90 newSelection.add(surroundingObjects.iterator().next());
91 getCurrentDataSet().setSelected(newSelection);
92 } else {
93 getCurrentDataSet().setSelected(surroundingObjects.iterator().next());
94 }
95 }
96
97 @Override
98 public void actionPerformed(ActionEvent e) {
99 throw new UnsupportedOperationException();
100 }
101}
Note: See TracBrowser for help on using the repository browser.