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

Last change on this file since 33311 was 33311, checked in by zverik, 9 years ago

Updated possible roles and did a little refactoring

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