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

Last change on this file since 35351 was 34130, checked in by donvip, 7 years ago

update to JOSM 13564

  • Property svn:eol-style set to native
File size: 8.2 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.data.Bounds;
16import org.openstreetmap.josm.data.osm.Node;
17import org.openstreetmap.josm.data.osm.OsmPrimitive;
18import org.openstreetmap.josm.data.osm.Relation;
19import org.openstreetmap.josm.data.osm.Way;
20import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
21import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
22import org.openstreetmap.josm.data.osm.event.DataSetListener;
23import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
24import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
25import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
26import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
27import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
28import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
29import org.openstreetmap.josm.gui.MainApplication;
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 MainApplication.getMap().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 * @return true if the relation type assumes all ways inside it form a multipolygon
85 */
86 public boolean isMultipolygon() {
87 return isMultipolygon(chosenRelation);
88 }
89
90 public static boolean isMultipolygon(Relation r) {
91 if (r == null)
92 return false;
93 String type = r.get("type");
94 if (type == null)
95 return false;
96 for (String t : MULTIPOLYGON_TYPES) {
97 if (t.equals(type))
98 return true;
99 }
100 return false;
101 }
102
103 public int getSegmentsCount() {
104 return 0;
105 }
106
107 public int getCirclesCount() {
108 return 0;
109 }
110
111 protected void analyse() {
112 // todo
113 }
114
115 public void addChosenRelationListener(ChosenRelationListener listener) {
116 chosenRelationListeners.add(listener);
117 }
118
119 public void removeChosenRelationListener(ChosenRelationListener listener) {
120 chosenRelationListeners.remove(listener);
121 }
122
123 @Override
124 public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
125 // todo: dim chosen relation when changing layer
126 // todo: check this WTF!
127 OsmDataLayer newLayer = MainApplication.getLayerManager().getEditLayer();
128 clear();
129 if (newLayer != null && e.getPreviousDataLayer() == null) {
130 MainApplication.getMap().mapView.addTemporaryLayer(this);
131 } else if (newLayer == null) {
132 MainApplication.getMap().mapView.removeTemporaryLayer(this);
133 }
134 }
135
136 @Override
137 public void paint(Graphics2D g, MapView mv, Bounds bbox) {
138 if (chosenRelation == null)
139 return;
140
141 OsmDataLayer dataLayer = mv.getLayerManager().getEditLayer();
142 float opacity = dataLayer == null ? 0.0f : !dataLayer.isVisible() ? 0.0f : (float) dataLayer.getOpacity();
143 if (opacity < 0.01)
144 return;
145
146 Composite oldComposite = g.getComposite();
147 Stroke oldStroke = g.getStroke();
148 g.setStroke(new BasicStroke(9, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
149 g.setColor(Color.yellow);
150 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f * opacity));
151
152 drawRelations(g, mv, bbox, chosenRelation, new HashSet<Relation>());
153
154 g.setComposite(oldComposite);
155 g.setStroke(oldStroke);
156 }
157
158 private void drawRelations(Graphics2D g, MapView mv, Bounds bbox, Relation rel, Set<Relation> visitedRelations) {
159 if (!visitedRelations.contains(rel)) {
160 visitedRelations.add(rel);
161 for (OsmPrimitive element : rel.getMemberPrimitives()) {
162 if (null != element.getType()) {
163 switch(element.getType()) {
164 case NODE:
165 Node node = (Node) element;
166 Point center = mv.getPoint(node);
167 g.drawOval(center.x - 4, center.y - 4, 9, 9);
168 break;
169 case WAY:
170 Way way = (Way) element;
171 if (way.getNodesCount() >= 2) {
172 GeneralPath b = new GeneralPath();
173 Point p = mv.getPoint(way.getNode(0));
174 b.moveTo(p.x, p.y);
175 for (int i = 1; i < way.getNodesCount(); i++) {
176 p = mv.getPoint(way.getNode(i));
177 b.lineTo(p.x, p.y);
178 }
179 g.draw(b);
180 } break;
181 case RELATION:
182 Color oldColor = g.getColor();
183 g.setColor(Color.magenta);
184 drawRelations(g, mv, bbox, (Relation) element, visitedRelations);
185 g.setColor(oldColor);
186 break;
187 default:
188 break;
189 }
190 }
191 }
192 }
193 }
194
195 @Override
196 public void relationMembersChanged(RelationMembersChangedEvent event) {
197 if (chosenRelation != null && event.getRelation().equals(chosenRelation)) {
198 fireRelationChanged(chosenRelation);
199 }
200 }
201
202 @Override
203 public void tagsChanged(TagsChangedEvent event) {
204 if (chosenRelation != null && event.getPrimitive().equals(chosenRelation)) {
205 fireRelationChanged(chosenRelation);
206 }
207 }
208
209 @Override
210 public void dataChanged(DataChangedEvent event) {
211 if (chosenRelation != null) {
212 fireRelationChanged(chosenRelation);
213 }
214 }
215
216 @Override
217 public void primitivesRemoved(PrimitivesRemovedEvent event) {
218 if (chosenRelation != null && event.getPrimitives().contains(chosenRelation)) {
219 clear();
220 }
221 }
222
223 @Override
224 public void wayNodesChanged(WayNodesChangedEvent event) {
225 if (chosenRelation != null) {
226 fireRelationChanged(chosenRelation); // download incomplete primitives doesn't cause dataChanged event
227 }
228 }
229
230 @Override
231 public void primitivesAdded(PrimitivesAddedEvent event) {}
232
233 @Override
234 public void nodeMoved(NodeMovedEvent event) {}
235
236 @Override
237 public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
238}
Note: See TracBrowser for help on using the repository browser.