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

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

checkstyle, update to JOSM 10279

  • Property svn:eol-style set to native
File size: 7.7 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.OsmPrimitiveType;
20import org.openstreetmap.josm.data.osm.Relation;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
23import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
24import org.openstreetmap.josm.data.osm.event.DataSetListener;
25import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
26import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
27import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
28import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
29import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
30import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
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 Set<ChosenRelationListener> chosenRelationListeners = new HashSet<>();
45
46 public void set(Relation rel) {
47 if (rel == chosenRelation || (rel != null && chosenRelation != null && rel.equals(chosenRelation)))
48 return; // new is the same as old
49 Relation oldRel = chosenRelation;
50 chosenRelation = rel;
51 analyse();
52 Main.map.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 chosenRelation != null && 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 */
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 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.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);
152
153 g.setComposite(oldComposite);
154 g.setStroke(oldStroke);
155
156 }
157
158 private void drawRelations(Graphics2D g, MapView mv, Bounds bbox, Relation rel) {
159 for (OsmPrimitive element : rel.getMemberPrimitives()) {
160 if (element.getType() == OsmPrimitiveType.NODE) {
161 Node node = (Node)element;
162 Point center = mv.getPoint(node);
163 g.drawOval(center.x - 4, center.y - 4, 9, 9);
164 } else if (element.getType() == OsmPrimitiveType.WAY) {
165 Way way = (Way)element;
166 if (way.getNodesCount() >= 2) {
167 GeneralPath b = new GeneralPath();
168 Point p = mv.getPoint(way.getNode(0));
169 b.moveTo(p.x, p.y);
170 for (int i = 1; i < way.getNodesCount(); i++) {
171 p = mv.getPoint(way.getNode(i));
172 b.lineTo(p.x, p.y);
173 }
174 g.draw(b);
175 }
176 } else if (element.getType() == OsmPrimitiveType.RELATION) {
177 Color oldColor = g.getColor();
178 g.setColor(Color.magenta);
179 drawRelations(g, mv, bbox, (Relation)element);
180 g.setColor(oldColor);
181 }
182 // todo: closedway, multipolygon - ?
183 }
184 }
185
186 @Override
187 public void relationMembersChanged(RelationMembersChangedEvent event) {
188 if (chosenRelation != null && event.getRelation().equals(chosenRelation) ) {
189 fireRelationChanged(chosenRelation);
190 }
191 }
192
193 @Override
194 public void tagsChanged(TagsChangedEvent event) {
195 if (chosenRelation != null && event.getPrimitive().equals(chosenRelation) ) {
196 fireRelationChanged(chosenRelation);
197 }
198 }
199
200 @Override
201 public void dataChanged(DataChangedEvent event) {
202 if (chosenRelation != null ) {
203 fireRelationChanged(chosenRelation);
204 }
205 }
206
207 @Override
208 public void primitivesRemoved(PrimitivesRemovedEvent event) {
209 if (chosenRelation != null && event.getPrimitives().contains(chosenRelation) ) {
210 clear();
211 }
212 }
213
214 @Override
215 public void wayNodesChanged(WayNodesChangedEvent event) {
216 if (chosenRelation != null )
217 {
218 fireRelationChanged(chosenRelation); // download incomplete primitives doesn't cause dataChanged event
219 }
220 }
221
222 @Override
223 public void primitivesAdded(PrimitivesAddedEvent event) {}
224 @Override
225 public void nodeMoved(NodeMovedEvent event) {}
226 @Override
227 public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
228}
Note: See TracBrowser for help on using the repository browser.