Ignore:
Timestamp:
2011-10-13T21:18:37+02:00 (13 years ago)
Author:
zverik
Message:

ReconstructPolygonAction is done

Location:
applications/editors/josm/plugins/reltoolbox/src/relcontext
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java

    r26837 r26882  
    456456            add(new DeleteChosenRelationAction(chosenRelation));
    457457            add(new DownloadParentsAction(chosenRelation));
     458            add(new ReconstructPolygonAction(chosenRelation));
    458459            addSeparator();
    459460            add(new SelectInRelationPanelAction(chosenRelation));
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java

    r26832 r26882  
    33import static org.openstreetmap.josm.tools.I18n.tr;
    44import java.awt.event.ActionEvent;
     5import java.util.*;
    56import javax.swing.AbstractAction;
     7import javax.swing.JOptionPane;
    68import org.openstreetmap.josm.Main;
    7 import org.openstreetmap.josm.command.DeleteCommand;
    8 import org.openstreetmap.josm.data.osm.Relation;
     9import org.openstreetmap.josm.command.*;
     10import org.openstreetmap.josm.data.osm.*;
     11import org.openstreetmap.josm.data.osm.MultipolygonCreate.JoinedPolygon;
     12import org.openstreetmap.josm.gui.DefaultNameFormatter;
    913import org.openstreetmap.josm.tools.ImageProvider;
    1014import relcontext.ChosenRelation;
     
    1721public class ReconstructPolygonAction extends AbstractAction implements ChosenRelationListener {
    1822    private ChosenRelation rel;
     23   
     24    private static final List<String> IRRELEVANT_KEYS = Arrays.asList(new String[] {
     25        "source", "created_by", "note"});
    1926
    2027    public ReconstructPolygonAction( ChosenRelation rel ) {
    2128        super(tr("Reconstruct polygon"));
    22         putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
     29        putValue(SMALL_ICON, ImageProvider.get("dialogs", "filter"));
    2330        putValue(LONG_DESCRIPTION, "Reconstruct polygon from multipolygon relation");
    2431        this.rel = rel;
    2532        rel.addChosenRelationListener(this);
    26         setEnabled(rel.get() != null);
     33        setEnabled(isSuitableRelation(rel.get()));
    2734    }
    2835
    2936    public void actionPerformed( ActionEvent e ) {
    3037        Relation r = rel.get();
    31         rel.clear();
    32 //        Main.main.undoRedo.add(new DeleteCommand(r));
     38        List<Way> ways = new ArrayList<Way>();
     39        boolean wont = false;
     40        for( RelationMember m : r.getMembers() ) {
     41            if( m.isWay() )
     42                ways.add(m.getWay());
     43            else
     44                wont = true;
     45        }
     46        if( wont ) {
     47            JOptionPane.showMessageDialog(Main.parent, tr("Multipolygon must consist only of ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
     48            return;
     49        }
     50       
     51        MultipolygonCreate mpc = new MultipolygonCreate();
     52        String error = mpc.makeFromWays(ways);
     53        if( error != null ) {
     54            JOptionPane.showMessageDialog(Main.parent, error);
     55            return;
     56        }
     57       
     58        if( !mpc.innerWays.isEmpty() ) {
     59            JOptionPane.showMessageDialog(Main.parent, tr("Reconstruction of polygons can be done only from outer ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
     60            return;
     61        }
     62       
     63        rel.clear();
     64        List<Way> newSelection = new ArrayList<Way>();
     65        List<Command> commands = new ArrayList<Command>();
     66        commands.add(new DeleteCommand(r));
     67       
     68        for( JoinedPolygon p : mpc.outerWays ) {
     69            // move all tags from relation and common tags from ways
     70            Map<String, String> tags = p.ways.get(0).getKeys();
     71            List<OsmPrimitive> relations = p.ways.get(0).getReferrers();
     72            Set<String> noTags = new HashSet<String>(r.keySet());
     73            for( int i = 1; i < p.ways.size(); i++ ) {
     74                Way w = p.ways.get(i);
     75                for( String key : w.keySet() ) {
     76                    String value = w.get(key);
     77                    if( !noTags.contains(key) && tags.containsKey(key) && !tags.get(key).equals(value) ) {
     78                        tags.remove(key);
     79                        noTags.add(key);
     80                    }
     81                }
     82                List<OsmPrimitive> referrers = w.getReferrers();
     83                for( Iterator<OsmPrimitive> ref1 = relations.iterator(); ref1.hasNext(); )
     84                    if( !referrers.contains(ref1.next()) )
     85                        ref1.remove();
     86            }
     87            tags.putAll(r.getKeys());
     88            tags.remove("type");
     89           
     90            // then delete ways that are not relevant (do not take part in other relations of have strange tags)
     91            Way candidateWay = null;
     92            for( Way w : p.ways ) {
     93                if( w.getReferrers().equals(relations) ) {
     94                    // check tags that remain
     95                    Set<String> keys = new HashSet<String>(w.keySet());
     96                    keys.removeAll(tags.keySet());
     97                    keys.removeAll(IRRELEVANT_KEYS);
     98                    if( keys.isEmpty() ) {
     99                        if( candidateWay == null )
     100                            candidateWay = w;
     101                        else {
     102                            if( candidateWay.isNew() && !w.isNew() ) {
     103                                // prefer ways that are already in the database
     104                                Way tmp = w;
     105                                w = candidateWay;
     106                                candidateWay = w;
     107                            }
     108                            commands.add(new DeleteCommand(w));
     109                        }
     110                    }
     111                }
     112            }
     113           
     114            // take the first way, put all nodes into it, making it a closed polygon
     115            Way result = candidateWay == null ? new Way() : new Way(candidateWay);
     116            result.setNodes(p.nodes);
     117            result.addNode(result.firstNode());
     118            result.setKeys(tags);
     119            newSelection.add(candidateWay == null ? result : candidateWay);
     120            commands.add(candidateWay == null ? new AddCommand(result) : new ChangeCommand(candidateWay, result));
     121        }
     122       
     123        Main.main.undoRedo.add(new SequenceCommand(tr("Reconstruct polygons from relation {0}",
     124                r.getDisplayName(DefaultNameFormatter.getInstance())), commands));
     125        Main.main.getCurrentDataSet().setSelected(newSelection);
    33126    }
    34127
    35128    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
    36         setEnabled(newRelation != null); //todo
     129        setEnabled(isSuitableRelation(newRelation));
     130    }
     131   
     132    private boolean isSuitableRelation( Relation newRelation ) {
     133        if( newRelation == null || !"multipolygon".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0 )
     134            return false;
     135        else {
     136            for( RelationMember m : newRelation.getMembers() )
     137                if( "inner".equals(m.getRole()) )
     138                    return false;
     139            return true;
     140        }
    37141    }
    38142}
Note: See TracChangeset for help on using the changeset viewer.