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

Last change on this file since 33530 was 33530, checked in by donvip, 8 years ago

update to JOSM 12663

  • 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.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 */
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 = MainApplication.getLayerManager().getEditLayer();
127 clear();
128 if (newLayer != null && e.getPreviousEditLayer() == null) {
129 MainApplication.getMap().mapView.addTemporaryLayer(this);
130 } else if (newLayer == null) {
131 MainApplication.getMap().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()) {
162 switch(element.getType()) {
163 case NODE:
164 Node node = (Node) element;
165 Point center = mv.getPoint(node);
166 g.drawOval(center.x - 4, center.y - 4, 9, 9);
167 break;
168 case WAY:
169 Way way = (Way) element;
170 if (way.getNodesCount() >= 2) {
171 GeneralPath b = new GeneralPath();
172 Point p = mv.getPoint(way.getNode(0));
173 b.moveTo(p.x, p.y);
174 for (int i = 1; i < way.getNodesCount(); i++) {
175 p = mv.getPoint(way.getNode(i));
176 b.lineTo(p.x, p.y);
177 }
178 g.draw(b);
179 } break;
180 case RELATION:
181 Color oldColor = g.getColor();
182 g.setColor(Color.magenta);
183 drawRelations(g, mv, bbox, (Relation) element, visitedRelations);
184 g.setColor(oldColor);
185 break;
186 default:
187 break;
188 }
189 }
190 }
191 }
192 }
193
194 @Override
195 public void relationMembersChanged(RelationMembersChangedEvent event) {
196 if (chosenRelation != null && event.getRelation().equals(chosenRelation)) {
197 fireRelationChanged(chosenRelation);
198 }
199 }
200
201 @Override
202 public void tagsChanged(TagsChangedEvent event) {
203 if (chosenRelation != null && event.getPrimitive().equals(chosenRelation)) {
204 fireRelationChanged(chosenRelation);
205 }
206 }
207
208 @Override
209 public void dataChanged(DataChangedEvent event) {
210 if (chosenRelation != null) {
211 fireRelationChanged(chosenRelation);
212 }
213 }
214
215 @Override
216 public void primitivesRemoved(PrimitivesRemovedEvent event) {
217 if (chosenRelation != null && event.getPrimitives().contains(chosenRelation)) {
218 clear();
219 }
220 }
221
222 @Override
223 public void wayNodesChanged(WayNodesChangedEvent event) {
224 if (chosenRelation != null) {
225 fireRelationChanged(chosenRelation); // download incomplete primitives doesn't cause dataChanged event
226 }
227 }
228
229 @Override
230 public void primitivesAdded(PrimitivesAddedEvent event) {}
231
232 @Override
233 public void nodeMoved(NodeMovedEvent event) {}
234
235 @Override
236 public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
237}
Note: See TracBrowser for help on using the repository browser.