source: osm/applications/editors/josm/plugins/relcontext/src/relcontext/actions/SortAndFixAction.java@ 25682

Last change on this file since 25682 was 25682, checked in by zverik, 13 years ago

nice design (relcontext plugin)

File size: 3.9 KB
Line 
1package relcontext.actions;
2
3import java.awt.event.ActionEvent;
4import java.util.*;
5import javax.swing.AbstractAction;
6import javax.swing.Action;
7import static org.openstreetmap.josm.tools.I18n.tr;
8import org.openstreetmap.josm.Main;
9import org.openstreetmap.josm.command.ChangeCommand;
10import org.openstreetmap.josm.command.Command;
11import org.openstreetmap.josm.command.SequenceCommand;
12import org.openstreetmap.josm.data.osm.*;
13import org.openstreetmap.josm.tools.ImageProvider;
14import relcontext.ChosenRelation;
15import relcontext.ChosenRelationListener;
16
17public class SortAndFixAction extends AbstractAction implements ChosenRelationListener {
18 private ChosenRelation rel;
19
20 public SortAndFixAction( ChosenRelation rel ) {
21 super();
22// putValue(Action.NAME, "AZ");
23 putValue(Action.SMALL_ICON, ImageProvider.get("data", "warning"));
24 putValue(Action.SHORT_DESCRIPTION, tr("Sort members and fix their roles"));
25 this.rel = rel;
26 rel.addChosenRelationListener(this);
27 setEnabled(false);
28 }
29
30 public void actionPerformed( ActionEvent e ) {
31 if( rel.get() == null ) return;
32 Relation r = rel.get();
33 List<Command> commands = new ArrayList<Command>();
34 // todo: sort members
35 // todo: set roles for multipolygon members
36 Relation fixed = fixMultipolygonRoles(rel.get());
37 if( fixed != null ) {
38 commands.add(new ChangeCommand(r, fixed));
39 r = fixed;
40 }
41 // todo: set roles for boundary members
42
43 if( !commands.isEmpty() )
44 Main.main.undoRedo.add(new SequenceCommand(tr("Sort and fix relation"), commands));
45 }
46
47 public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
48 setEnabled(newRelation != null && areMultipolygonTagsEmpty());
49 // todo: enable when needs fixing (empty roles or not ordered members)
50 }
51
52 private boolean areMultipolygonTagsEmpty() {
53 Relation r = rel == null ? null : rel.get();
54 if( r == null || r.getMembersCount() == 0 || !rel.isMultipolygon() )
55 return false;
56 for( RelationMember m : r.getMembers() ) {
57 if( m.getType().equals(OsmPrimitiveType.WAY) && (m.getRole() == null || (!m.getRole().equals("outer") && !m.getRole().equals("inner"))) )
58 return true;
59 }
60 return false;
61 }
62
63 /**
64 * Basically, created multipolygon from scratch, and if successful, replace roles with new ones.
65 */
66 private Relation fixMultipolygonRoles( Relation source ) {
67 Collection<Way> ways = new ArrayList<Way>();
68 for( OsmPrimitive p : source.getMemberPrimitives() )
69 if( p instanceof Way )
70 ways.add((Way)p);
71 MultipolygonCreate mpc = new MultipolygonCreate();
72 String error = mpc.makeFromWays(ways);
73 if( error != null )
74 return null;
75
76 Relation r = new Relation(source);
77 boolean fixed = false;
78 Set<Way> outerWays = new HashSet<Way>();
79 for( MultipolygonCreate.JoinedPolygon poly : mpc.outerWays )
80 for( Way w : poly.ways )
81 outerWays.add(w);
82 Set<Way> innerWays = new HashSet<Way>();
83 for( MultipolygonCreate.JoinedPolygon poly : mpc.innerWays )
84 for( Way w : poly.ways )
85 innerWays.add(w);
86 for( int i = 0; i < r.getMembersCount(); i++ ) {
87 RelationMember m = r.getMember(i);
88 if( m.getType().equals(OsmPrimitiveType.WAY) ) {
89 String role = null;
90 if( outerWays.contains(m.getMember()) )
91 role = "outer";
92 else if( innerWays.contains(m.getMember()) )
93 role = "inner";
94 if( role != null && !role.equals(m.getRole()) ) {
95 r.setMember(i, new RelationMember(role, m.getMember()));
96 fixed = true;
97 }
98 }
99 }
100 return fixed ? r : null;
101 }
102}
Note: See TracBrowser for help on using the repository browser.