Changeset 23771 in osm for applications/editors


Ignore:
Timestamp:
2010-10-23T21:20:27+02:00 (14 years ago)
Author:
extropy
Message:

Improved create multipolygon plugin.
Can now handle polygons consisting of several unclosed ways, several outer ways and other stuff. Detects crossings. Opens relation editor.

Location:
applications/editors/josm/plugins/multipoly/src/multipoly
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/multipoly/src/multipoly/MultipolyAction.java

    r23189 r23771  
    66import java.awt.event.ActionEvent;
    77import java.awt.event.KeyEvent;
    8 import java.util.ArrayList;
    98import java.util.Collection;
    10 import java.util.HashSet;
    11 import java.util.LinkedList;
    12 import java.util.List;
     9import java.util.Collections;
    1310
    1411import javax.swing.JOptionPane;
     12
     13import multipoly.Multipolygon.JoinedPolygon;
    1514
    1615import org.openstreetmap.josm.Main;
     
    1918import org.openstreetmap.josm.command.Command;
    2019import org.openstreetmap.josm.command.SequenceCommand;
    21 import org.openstreetmap.josm.data.coor.EastNorth;
    22 import org.openstreetmap.josm.data.osm.Node;
    2320import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2421import org.openstreetmap.josm.data.osm.Relation;
    2522import org.openstreetmap.josm.data.osm.RelationMember;
    2623import org.openstreetmap.josm.data.osm.Way;
    27 import org.openstreetmap.josm.tools.Pair;
     24import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
     25import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2826import org.openstreetmap.josm.tools.Shortcut;
    2927
     
    6058     */
    6159    public void actionPerformed(ActionEvent e) {
    62 
    63         // Get all ways in some type=multipolygon relation
    64         HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
    65         for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
    66             if (!r.isUsable())
    67                 continue;
    68             if (r.get("type") != "multipolygon")
    69                 continue;
    70             for (RelationMember rm : r.getMembers()) {
    71                 OsmPrimitive m = rm.getMember();
    72                 if (m instanceof Way) {
    73                     relationsInMulti.add(m);
    74                 }
    75             }
    76         }
    77 
    78         // List of selected ways
    79         List<Way> selectedWays = new ArrayList<Way>();
    80         // Area of largest way (in square degrees)
    81         double maxarea = 0;
    82         // Which way is the largest one (outer)
    83         Way maxWay = null;
    84 
    85         // For every selected way
    86         for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
    87             if (osm instanceof Way) {
    88                 Way way = (Way) osm;
    89                 // Check if way is already in another multipolygon
    90                 if (relationsInMulti.contains(osm)) {
    91                     JOptionPane
    92                             .showMessageDialog(
    93                                     Main.parent,
    94                                     tr("One of the selected ways is already part of another multipolygon."));
    95                     return;
    96                 }
    97                 EastNorth first = null, last = null;
    98                 // Boundingbox of way
    99                 double minx = 9999, miny = 9999, maxx = -9999, maxy = -9999;
    100                 for (Pair<Node, Node> seg : way.getNodePairs(false)) {
    101                     if (first == null)
    102                         first = seg.a.getEastNorth();
    103                     last = seg.b.getEastNorth();
    104                     double x = seg.a.getEastNorth().east();
    105                     double y = seg.a.getEastNorth().north();
    106                     if (x < minx)
    107                         minx = x;
    108                     if (y < miny)
    109                         miny = y;
    110                     if (x > maxx)
    111                         maxx = x;
    112                     if (y > maxy)
    113                         maxy = y;
    114                 }
    115                 // Check if first and last node are the same
    116                 if (!first.equals(last)) {
    117                     JOptionPane
    118                             .showMessageDialog(
    119                                     Main.parent,
    120                                     tr("Multipolygon must consist only of closed ways."));
    121                     return;
    122                 }
    123                 // Determine area
    124                 double area = (maxx - minx) * (maxy - miny);
    125                 selectedWays.add(way);
    126                 if (area > maxarea) {
    127                     maxarea = area;
    128                     maxWay = way;
    129                 }
    130             }
    131         }
    132 
    133         if (Main.map == null) {
     60        if (Main.main.getEditLayer() == null) {
    13461            JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
    13562            return;
    13663        }
    137 
     64       
     65        Collection<Way> selectedWays = Main.main.getCurrentDataSet().getSelectedWays();
     66             
    13867        if (selectedWays.size() < 2) {
    13968            JOptionPane.showMessageDialog(Main.parent,
     
    14170            return;
    14271        }
     72       
     73        Multipolygon polygon = this.analyzeWays(selectedWays);
     74       
     75        if (polygon == null) {
     76                return; //could not make multipolygon.
     77        }
     78       
     79        Relation relation = this.createRelation(polygon);
    14380
    144         Collection<Command> cmds = new LinkedList<Command>();
    145         // Create new relation
    146         Relation rel = new Relation();
    147         rel.put("type", "multipolygon");
    148         // Add ways to it
    149         for (int i = 0; i < selectedWays.size(); i++) {
    150             Way s = selectedWays.get(i);
    151             String xrole = "inner";
    152             if (s == maxWay)
    153                 xrole = "outer";
    154             RelationMember rm = new RelationMember(xrole, s);
    155             rel.addMember(rm);
    156         }
    157         // Add relation
    158         cmds.add(new AddCommand(rel));
    159         // Commit
    160         Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"),
    161                 cmds));
    162         Main.map.repaint();
    163     }
     81        //open relation edit window
     82        RelationEditor editor = RelationEditor.getEditor(
     83                        Main.main.getEditLayer(),
     84                        relation,
     85                        null);
     86       
     87        editor.setVisible(true);
     88    } 
    16489
    165     /** Enable this action only if something is selected */
     90        /** Enable this action only if something is selected */
    16691    @Override
    16792    protected void updateEnabledState() {
     
    179104        setEnabled(selection != null && !selection.isEmpty());
    180105    }
     106   
     107   
     108    /**
     109     * This method analyzes ways and creates multipolygon.
     110     * @param selectedWays
     111     * @return null, if there was a problem with the ways.
     112     */
     113    private Multipolygon analyzeWays(Collection<Way> selectedWays) {
     114       
     115        Multipolygon pol = new Multipolygon();         
     116        String error = pol.makeFromWays(selectedWays);
     117       
     118        if (error != null) {
     119                JOptionPane.showMessageDialog(Main.parent, error);
     120                return null;                   
     121        }
     122        else {
     123                return pol;
     124        }
     125        }   
     126   
     127   
     128    /**
     129     * Builds a relation from polygon ways.
     130     * @param pol
     131     * @return
     132     */
     133    private Relation createRelation(Multipolygon pol){
     134           // Create new relation
     135           Relation rel = new Relation();
     136           rel.put("type", "multipolygon");           
     137           // Add ways to it
     138           for(JoinedPolygon jway: pol.outerWays){
     139                   for(Way way: jway.ways){
     140                           rel.addMember(new RelationMember("outer", way));
     141                   }
     142           }
     143           
     144           for(JoinedPolygon jway: pol.innerWays){
     145                   for(Way way: jway.ways){
     146                           rel.addMember(new RelationMember("inner", way));
     147                   }
     148           }
     149           
     150           return rel;
     151    }   
    181152}
Note: See TracChangeset for help on using the changeset viewer.