Changeset 32395 in osm for applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java
- Timestamp:
- 2016-06-24T09:10:57+02:00 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java
r30738 r32395 1 // License: GPL. For details, see LICENSE file. 1 2 package relcontext.actions; 2 3 … … 40 41 public class ReconstructPolygonAction extends AbstractAction implements ChosenRelationListener { 41 42 private ChosenRelation rel; 42 43 43 44 private static final List<String> IRRELEVANT_KEYS = Arrays.asList(new String[] { 44 "source", "created_by", "note"}); 45 "source", "created_by", "note"}); 45 46 46 public ReconstructPolygonAction( ChosenRelation rel) {47 public ReconstructPolygonAction(ChosenRelation rel) { 47 48 super(tr("Reconstruct polygon")); 48 49 putValue(SMALL_ICON, ImageProvider.get("dialogs", "filter")); 49 putValue(LONG_DESCRIPTION, "Reconstruct polygon from multipolygon relation"); 50 putValue(LONG_DESCRIPTION, "Reconstruct polygon from multipolygon relation"); 50 51 this.rel = rel; 51 52 rel.addChosenRelationListener(this); … … 53 54 } 54 55 55 public void actionPerformed( ActionEvent e ) { 56 @Override 57 public void actionPerformed(ActionEvent e) { 56 58 Relation r = rel.get(); 57 List<Way> ways = new ArrayList<>(); 58 boolean wont = false; 59 for( RelationMember m : r.getMembers() ) { 60 if( m.isWay() ) 61 ways.add(m.getWay()); 62 else 63 wont = true; 64 } 65 if( wont ) { 66 JOptionPane.showMessageDialog(Main.parent, tr("Multipolygon must consist only of ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE); 67 return; 68 } 69 70 MultipolygonBuilder mpc = new MultipolygonBuilder(); 71 String error = mpc.makeFromWays(ways); 72 if( error != null ) { 73 JOptionPane.showMessageDialog(Main.parent, error); 74 return; 75 } 76 77 if( !mpc.innerWays.isEmpty() ) { 78 JOptionPane.showMessageDialog(Main.parent, tr("Reconstruction of polygons can be done only from outer ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE); 79 return; 80 } 81 82 rel.clear(); 83 List<Way> newSelection = new ArrayList<>(); 84 List<Command> commands = new ArrayList<>(); 85 Command c = DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(r), true, true); 86 if( c == null ) 87 return; 88 commands.add(c); 89 90 for( JoinedPolygon p : mpc.outerWays ) { 91 // move all tags from relation and common tags from ways 92 Map<String, String> tags = p.ways.get(0).getKeys(); 93 List<OsmPrimitive> relations = p.ways.get(0).getReferrers(); 94 Set<String> noTags = new HashSet<>(r.keySet()); 95 for( int i = 1; i < p.ways.size(); i++ ) { 96 Way w = p.ways.get(i); 97 for( String key : w.keySet() ) { 98 String value = w.get(key); 99 if( !noTags.contains(key) && tags.containsKey(key) && !tags.get(key).equals(value) ) { 100 tags.remove(key); 101 noTags.add(key); 59 List<Way> ways = new ArrayList<>(); 60 boolean wont = false; 61 for (RelationMember m : r.getMembers()) { 62 if (m.isWay() ) { 63 ways.add(m.getWay()); 64 } else { 65 wont = true; 102 66 } 103 67 } 104 List<OsmPrimitive> referrers = w.getReferrers(); 105 for( Iterator<OsmPrimitive> ref1 = relations.iterator(); ref1.hasNext(); ) 106 if( !referrers.contains(ref1.next()) ) 107 ref1.remove(); 68 if (wont) { 69 JOptionPane.showMessageDialog(Main.parent, tr("Multipolygon must consist only of ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE); 70 return; 108 71 } 109 tags.putAll(r.getKeys()); 110 tags.remove("type"); 111 112 // then delete ways that are not relevant (do not take part in other relations of have strange tags) 113 Way candidateWay = null; 114 for( Way w : p.ways ) { 115 if( w.getReferrers().equals(relations) ) { 116 // check tags that remain 117 Set<String> keys = new HashSet<>(w.keySet()); 118 keys.removeAll(tags.keySet()); 119 keys.removeAll(IRRELEVANT_KEYS); 120 if( keys.isEmpty() ) { 121 if( candidateWay == null ) 122 candidateWay = w; 123 else { 124 if( candidateWay.isNew() && !w.isNew() ) { 125 // prefer ways that are already in the database 126 Way tmp = w; 127 w = candidateWay; 128 candidateWay = tmp; 72 73 MultipolygonBuilder mpc = new MultipolygonBuilder(); 74 String error = mpc.makeFromWays(ways); 75 if (error != null) { 76 JOptionPane.showMessageDialog(Main.parent, error); 77 return; 78 } 79 80 if (!mpc.innerWays.isEmpty()) { 81 JOptionPane.showMessageDialog(Main.parent, tr("Reconstruction of polygons can be done only from outer ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE); 82 return; 83 } 84 85 rel.clear(); 86 List<Way> newSelection = new ArrayList<>(); 87 List<Command> commands = new ArrayList<>(); 88 Command c = DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(r), true, true); 89 if (c == null ) 90 return; 91 commands.add(c); 92 93 for (JoinedPolygon p : mpc.outerWays) { 94 // move all tags from relation and common tags from ways 95 Map<String, String> tags = p.ways.get(0).getKeys(); 96 List<OsmPrimitive> relations = p.ways.get(0).getReferrers(); 97 Set<String> noTags = new HashSet<>(r.keySet()); 98 for (int i = 1; i < p.ways.size(); i++) { 99 Way w = p.ways.get(i); 100 for (String key : w.keySet()) { 101 String value = w.get(key); 102 if (!noTags.contains(key) && tags.containsKey(key) && !tags.get(key).equals(value)) { 103 tags.remove(key); 104 noTags.add(key); 105 } 129 106 } 130 commands.add(new DeleteCommand(w)); 107 List<OsmPrimitive> referrers = w.getReferrers(); 108 for (Iterator<OsmPrimitive> ref1 = relations.iterator(); ref1.hasNext(); ) 109 if (!referrers.contains(ref1.next()) ) { 110 ref1.remove(); 111 } 131 112 } 113 tags.putAll(r.getKeys()); 114 tags.remove("type"); 115 116 // then delete ways that are not relevant (do not take part in other relations of have strange tags) 117 Way candidateWay = null; 118 for (Way w : p.ways) { 119 if (w.getReferrers().equals(relations)) { 120 // check tags that remain 121 Set<String> keys = new HashSet<>(w.keySet()); 122 keys.removeAll(tags.keySet()); 123 keys.removeAll(IRRELEVANT_KEYS); 124 if (keys.isEmpty()) { 125 if (candidateWay == null ) { 126 candidateWay = w; 127 } else { 128 if (candidateWay.isNew() && !w.isNew()) { 129 // prefer ways that are already in the database 130 Way tmp = w; 131 w = candidateWay; 132 candidateWay = tmp; 133 } 134 commands.add(new DeleteCommand(w)); 135 } 136 } 137 } 132 138 } 139 140 // take the first way, put all nodes into it, making it a closed polygon 141 Way result = candidateWay == null ? new Way() : new Way(candidateWay); 142 result.setNodes(p.nodes); 143 result.addNode(result.firstNode()); 144 result.setKeys(tags); 145 newSelection.add(candidateWay == null ? result : candidateWay); 146 commands.add(candidateWay == null ? new AddCommand(result) : new ChangeCommand(candidateWay, result)); 133 147 } 134 } 135 136 // take the first way, put all nodes into it, making it a closed polygon 137 Way result = candidateWay == null ? new Way() : new Way(candidateWay); 138 result.setNodes(p.nodes); 139 result.addNode(result.firstNode()); 140 result.setKeys(tags); 141 newSelection.add(candidateWay == null ? result : candidateWay); 142 commands.add(candidateWay == null ? new AddCommand(result) : new ChangeCommand(candidateWay, result)); 143 } 144 148 145 149 Main.main.undoRedo.add(new SequenceCommand(tr("Reconstruct polygons from relation {0}", 146 r.getDisplayName(DefaultNameFormatter.getInstance())), commands)); 147 Main.main.getCurrentDataSet().setSelected(newSelection); 150 r.getDisplayName(DefaultNameFormatter.getInstance())), commands)); 151 Main.main.getCurrentDataSet().setSelected(newSelection); 148 152 } 149 153 150 public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) { 151 setEnabled(isSuitableRelation(newRelation)); 154 @Override 155 public void chosenRelationChanged(Relation oldRelation, Relation newRelation) { 156 setEnabled(isSuitableRelation(newRelation)); 152 157 } 153 154 private boolean isSuitableRelation( Relation newRelation ) { 155 if( newRelation == null || !"multipolygon".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0 ) 156 return false; 157 else { 158 for( RelationMember m : newRelation.getMembers() ) 159 if( "inner".equals(m.getRole()) ) 158 159 private boolean isSuitableRelation(Relation newRelation) { 160 if (newRelation == null || !"multipolygon".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0 ) 160 161 return false; 161 return true; 162 } 162 else { 163 for (RelationMember m : newRelation.getMembers() ) 164 if ("inner".equals(m.getRole()) ) 165 return false; 166 return true; 167 } 163 168 } 164 169 }
Note:
See TracChangeset
for help on using the changeset viewer.
