source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelation.java@ 36102

Last change on this file since 36102 was 36102, checked in by taylor.smock, 22 months ago

reltoolbox: Clean up a bunch of lint warnings

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package relcontext;
3
4import java.awt.AlphaComposite;
5import java.awt.BasicStroke;
6import java.awt.Color;
7import java.awt.Composite;
8import java.awt.Graphics2D;
9import java.awt.Point;
10import java.awt.Stroke;
11import java.awt.geom.GeneralPath;
12import java.util.HashSet;
13import java.util.Objects;
14import java.util.Set;
15
16import org.openstreetmap.josm.data.Bounds;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.Way;
21import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
22import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
23import org.openstreetmap.josm.data.osm.event.DataSetListener;
24import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
25import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
26import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
27import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
28import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
29import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
30import org.openstreetmap.josm.gui.MainApplication;
31import org.openstreetmap.josm.gui.MapView;
32import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
33import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
34import org.openstreetmap.josm.gui.layer.MapViewPaintable;
35import org.openstreetmap.josm.gui.layer.OsmDataLayer;
36
37/**
38 * Chosen relation; is used for all actions and is highlighted on the map.
39 *
40 * @author Zverik
41 */
42public class ChosenRelation implements ActiveLayerChangeListener, MapViewPaintable, DataSetListener {
43 protected Relation chosenRelation = null;
44 private final Set<ChosenRelationListener> chosenRelationListeners = new HashSet<>();
45
46 public void set(Relation rel) {
47 if (Objects.equals(rel, chosenRelation))
48 return; // new is the same as old
49 Relation oldRel = chosenRelation;
50 chosenRelation = rel;
51 analyse();
52 MainApplication.getMap().mapView.repaint();
53 fireRelationChanged(oldRel);
54 }
55
56 protected void fireRelationChanged(Relation oldRel) {
57 for (ChosenRelationListener listener : chosenRelationListeners) {
58 listener.chosenRelationChanged(oldRel, chosenRelation);
59 }
60 }
61
62 public Relation get() {
63 return chosenRelation;
64 }
65
66 public void clear() {
67 set(null);
68 }
69
70 public boolean isSame(Object r) {
71 if (r == null)
72 return chosenRelation == null;
73 else if (!(r instanceof Relation))
74 return false;
75 else
76 return r.equals(chosenRelation);
77 }
78
79 private static final String[] MULTIPOLYGON_TYPES = new String[] {
80 "multipolygon", "boundary"
81 };
82
83 /**
84 * Check if the relation type assumes all ways inside it form a multipolygon.
85 * @return true if the relation type assumes all ways inside it form a multipolygon
86 */
87 public boolean isMultipolygon() {
88 return isMultipolygon(chosenRelation);
89 }
90
91 public static boolean isMultipolygon(Relation r) {
92 if (r == null)
93 return false;
94 String type = r.get("type");
95 if (type == null)
96 return false;
97 for (String t : MULTIPOLYGON_TYPES) {
98 if (t.equals(type))
99 return true;
100 }
101 return false;
102 }
103
104 public int getSegmentsCount() {
105 return 0;
106 }
107
108 public int getCirclesCount() {
109 return 0;
110 }
111
112 protected void analyse() {
113 // todo
114 }
115
116 public void addChosenRelationListener(ChosenRelationListener listener) {
117 chosenRelationListeners.add(listener);
118 }
119
120 public void removeChosenRelationListener(ChosenRelationListener listener) {
121 chosenRelationListeners.remove(listener);
122 }
123
124 @Override
125 public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
126 // todo: dim chosen relation when changing layer
127 // todo: check this WTF!
128 OsmDataLayer newLayer = MainApplication.getLayerManager().getEditLayer();
129 clear();
130 if (newLayer != null && e.getPreviousDataLayer() == null) {
131 MainApplication.getMap().mapView.addTemporaryLayer(this);
132 } else if (newLayer == null) {
133 MainApplication.getMap().mapView.removeTemporaryLayer(this);
134 }
135 }
136
137 @Override
138 public void paint(Graphics2D g, MapView mv, Bounds bbox) {
139 if (chosenRelation == null)
140 return;
141
142 OsmDataLayer dataLayer = mv.getLayerManager().getEditLayer();
143 float opacity = dataLayer == null ? 0.0f : !dataLayer.isVisible() ? 0.0f : (float) dataLayer.getOpacity();
144 if (opacity < 0.01)
145 return;
146
147 Composite oldComposite = g.getComposite();
148 Stroke oldStroke = g.getStroke();
149 g.setStroke(new BasicStroke(9, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
150 g.setColor(Color.yellow);
151 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f * opacity));
152
153 drawRelations(g, mv, bbox, chosenRelation, new HashSet<>());
154
155 g.setComposite(oldComposite);
156 g.setStroke(oldStroke);
157 }
158
159 private void drawRelations(Graphics2D g, MapView mv, Bounds bbox, Relation rel, Set<Relation> visitedRelations) {
160 if (!visitedRelations.contains(rel)) {
161 visitedRelations.add(rel);
162 for (OsmPrimitive element : rel.getMemberPrimitives()) {
163 if (null != element.getType()) {
164 switch(element.getType()) {
165 case NODE:
166 Node node = (Node) element;
167 Point center = mv.getPoint(node);
168 g.drawOval(center.x - 4, center.y - 4, 9, 9);
169 break;
170 case WAY:
171 Way way = (Way) element;
172 if (way.getNodesCount() >= 2) {
173 GeneralPath b = new GeneralPath();
174 Point p = mv.getPoint(way.getNode(0));
175 b.moveTo(p.x, p.y);
176 for (int i = 1; i < way.getNodesCount(); i++) {
177 p = mv.getPoint(way.getNode(i));
178 b.lineTo(p.x, p.y);
179 }
180 g.draw(b);
181 }
182 break;
183 case RELATION:
184 Color oldColor = g.getColor();
185 g.setColor(Color.magenta);
186 drawRelations(g, mv, bbox, (Relation) element, visitedRelations);
187 g.setColor(oldColor);
188 break;
189 default:
190 break;
191 }
192 }
193 }
194 }
195 }
196
197 @Override
198 public void relationMembersChanged(RelationMembersChangedEvent event) {
199 if (event.getRelation().equals(chosenRelation)) {
200 fireRelationChanged(chosenRelation);
201 }
202 }
203
204 @Override
205 public void tagsChanged(TagsChangedEvent event) {
206 if (event.getPrimitive().equals(chosenRelation)) {
207 fireRelationChanged(chosenRelation);
208 }
209 }
210
211 @Override
212 public void dataChanged(DataChangedEvent event) {
213 if (chosenRelation != null) {
214 fireRelationChanged(chosenRelation);
215 }
216 }
217
218 @Override
219 public void primitivesRemoved(PrimitivesRemovedEvent event) {
220 if (chosenRelation != null && event.getPrimitives().contains(chosenRelation)) {
221 clear();
222 }
223 }
224
225 @Override
226 public void wayNodesChanged(WayNodesChangedEvent event) {
227 if (chosenRelation != null) {
228 fireRelationChanged(chosenRelation); // download incomplete primitives doesn't cause dataChanged event
229 }
230 }
231
232 @Override
233 public void primitivesAdded(PrimitivesAddedEvent event) {}
234
235 @Override
236 public void nodeMoved(NodeMovedEvent event) {}
237
238 @Override
239 public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
240}
Note: See TracBrowser for help on using the repository browser.