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

Last change on this file since 8624 was 8393, checked in by Don-vip, 9 years ago

see #11447 - partial revert of r8384

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