Ignore:
Timestamp:
2012-09-07T16:40:13+02:00 (12 years ago)
Author:
larry0ua
Message:

'RelToolbox: refactored relation fixing code, added associatedStreet as a fixable relation'

Location:
applications/editors/josm/plugins/reltoolbox
Files:
6 added
5 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/reltoolbox/build.xml

    r27927 r28693  
    3030<project name="reltoolbox" default="dist" basedir=".">
    3131    <!-- enter the SVN commit message -->
    32     <property name="commit.message" value="RelToolbox: fix redifinition warnings"/>
     32    <property name="commit.message" value="RelToolbox: refactored relation fixing code, added associatedStreet as a fixable relation"/>
    3333    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    3434    <property name="plugin.main.version" value="5018"/>
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelation.java

    r26299 r28693  
    118118        if( opacity < 0.01 )
    119119            return;
    120 
     120       
     121        Composite oldComposite = g.getComposite();
    121122        Stroke oldStroke = g.getStroke();
    122         Composite oldComposite = g.getComposite();
     123        g.setStroke(new BasicStroke(9, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    123124        g.setColor(Color.yellow);
    124         g.setStroke(new BasicStroke(9, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    125125        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f * opacity));
    126         for( OsmPrimitive element : chosenRelation.getMemberPrimitives() ) {
     126       
     127        drawRelations(g, mv, bbox, chosenRelation);
     128       
     129        g.setComposite(oldComposite);
     130        g.setStroke(oldStroke);
     131       
     132    }
     133    private void drawRelations(Graphics2D g, MapView mv, Bounds bbox, Relation rel) {
     134        for( OsmPrimitive element : rel.getMemberPrimitives() ) {
    127135            if( element.getType() == OsmPrimitiveType.NODE ) {
    128136                Node node = (Node)element;
     
    142150                }
    143151            } else if( element.getType() == OsmPrimitiveType.RELATION ) {
    144                 // todo: draw all relation members (recursion?)
     152                Color oldColor = g.getColor();
     153                g.setColor(Color.magenta);
     154                drawRelations(g, mv, bbox, (Relation)element);
     155                g.setColor(oldColor);
    145156            }
    146157            // todo: closedway, multipolygon - ?
    147158        }
    148         g.setStroke(oldStroke);
    149         g.setComposite(oldComposite);
    150159    }
    151160
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java

    r28290 r28693  
    108108        roleBox.setVisible(false);
    109109        enterRoleAction = new EnterRoleAction(); // just for the shortcut
     110        sortAndFixAction = new SortAndFixAction(chosenRelation);
    110111
    111112        // [±][X] relation U [AZ][Down][Edit]
    112113        chosenRelationPanel = new JPanel(new GridBagLayout());
    113         addRemoveMemberAction = new AddRemoveMemberAction(chosenRelation);
     114        addRemoveMemberAction = new AddRemoveMemberAction(chosenRelation, sortAndFixAction);
    114115        chosenRelationPanel.add(new JButton(addRemoveMemberAction), GBC.std());
    115116        chosenRelationPanel.add(sizeButton(new JButton(new ClearChosenRelationAction(chosenRelation)), 32, 0), GBC.std());
     
    118119        chosenRelationPanel.add(chosenRelationComponent, GBC.std().fill().insets(5, 0, 5, 0));
    119120        chosenRelationPanel.add(roleBox, GBC.std().fill().insets(5, 0, 5, 0));
    120         sortAndFixAction = new SortAndFixAction(chosenRelation);
    121121        final JButton sortAndFixButton = (JButton) sizeButton(new JButton(sortAndFixAction), 32, 0);
    122122        chosenRelationPanel.add(sortAndFixButton, GBC.std().fill(GBC.VERTICAL));
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/AddRemoveMemberAction.java

    r27927 r28693  
    11package relcontext.actions;
    22
    3 import java.util.*;
    4 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    53import static org.openstreetmap.josm.tools.I18n.tr;
     4
    65import java.awt.event.ActionEvent;
    76import java.awt.event.KeyEvent;
     7import java.util.ArrayList;
     8import java.util.Collection;
     9
    810import org.openstreetmap.josm.Main;
    911import org.openstreetmap.josm.actions.JosmAction;
     
    1113import org.openstreetmap.josm.command.Command;
    1214import org.openstreetmap.josm.data.osm.Node;
     15import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1316import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1417import org.openstreetmap.josm.data.osm.Relation;
     
    1720import org.openstreetmap.josm.tools.ImageProvider;
    1821import org.openstreetmap.josm.tools.Shortcut;
     22
    1923import relcontext.ChosenRelation;
    2024import relcontext.ChosenRelationListener;
     
    3034    private static final String ACTION_NAME = "Add/remove member";
    3135    private ChosenRelation rel;
     36    private SortAndFixAction sortAndFix;
    3237
    33     public AddRemoveMemberAction( ChosenRelation rel ) {
     38    public AddRemoveMemberAction( ChosenRelation rel, SortAndFixAction sortAndFix ) {
    3439        super(null, "relcontext/addremove", tr("Add/remove members from the chosen relation"),
    3540                Shortcut.registerShortcut("reltoolbox:addremove", tr("Relation Toolbox: {0}", tr("Add/remove members from the chosen relation")),
    3641                KeyEvent.VK_EQUALS, Shortcut.DIRECT), false);
    3742        this.rel = rel;
     43        this.sortAndFix = sortAndFix;
    3844        rel.addChosenRelationListener(this);
    3945        updateEnabledState();
     
    5157
    5258        // 0. check if relation is broken (temporary)
    53         boolean isBroken = !toAdd.isEmpty() && SortAndFixAction.needsFixing(r);
     59        boolean isBroken = !toAdd.isEmpty() && sortAndFix.needsFixing(r);
    5460
    5561        // 1. remove all present members
     
    6672
    6773        // 3. check for roles again (temporary)
    68         Command roleFix = !isBroken && SortAndFixAction.needsFixing(r) ? SortAndFixAction.fixRelation(r) : null;
     74        Command roleFix = !isBroken && sortAndFix.needsFixing(r) ? sortAndFix.fixRelation(r) : null;
    6975        if( roleFix != null )
    7076            roleFix.executeCommand();
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SortAndFixAction.java

    r25751 r28693  
    11package relcontext.actions;
    22
     3import static org.openstreetmap.josm.tools.I18n.tr;
     4
    35import java.awt.event.ActionEvent;
    4 import java.util.*;
     6import java.util.ArrayList;
     7import java.util.List;
     8
    59import javax.swing.AbstractAction;
    610import javax.swing.Action;
    7 import static org.openstreetmap.josm.tools.I18n.tr;
     11
    812import org.openstreetmap.josm.Main;
    9 import org.openstreetmap.josm.command.ChangeCommand;
    1013import org.openstreetmap.josm.command.Command;
    11 import org.openstreetmap.josm.data.osm.*;
     14import org.openstreetmap.josm.data.osm.Relation;
     15import org.openstreetmap.josm.data.osm.RelationMember;
    1216import org.openstreetmap.josm.tools.ImageProvider;
     17
    1318import relcontext.ChosenRelation;
    1419import relcontext.ChosenRelationListener;
     20import relcontext.relationfix.AssociatedStreetFixer;
     21import relcontext.relationfix.BoundaryFixer;
     22import relcontext.relationfix.MultipolygonFixer;
     23import relcontext.relationfix.NothingFixer;
     24import relcontext.relationfix.RelationFixer;
    1525
    1626public class SortAndFixAction extends AbstractAction implements ChosenRelationListener {
    17     private ChosenRelation rel;
     27        private static final long serialVersionUID = 1L;
     28        private ChosenRelation rel;
     29    private List<RelationFixer> fixers;
    1830
    1931    public SortAndFixAction( ChosenRelation rel ) {
     
    2537        rel.addChosenRelationListener(this);
    2638        setEnabled(false);
     39       
     40        // construct all available fixers
     41        fixers = new ArrayList<RelationFixer>();
     42        fixers.add(new BoundaryFixer()); // should be before multipolygon as takes special case of multipolygon relation - boundary
     43        fixers.add(new MultipolygonFixer());
     44        fixers.add(new AssociatedStreetFixer());
     45       
    2746    }
    2847
     
    3756    }
    3857
    39     public static boolean needsFixing( Relation rel ) {
    40         return !isIncomplete(rel) && (areMultipolygonTagsEmpty(rel) || areBoundaryTagsNotRight(rel));
     58    public boolean needsFixing( Relation rel ) {
     59        return !isIncomplete(rel) && !getFixer(rel).isRelationGood(rel);
     60    }
     61   
     62    private RelationFixer getFixer( Relation rel ) {
     63        for(RelationFixer fixer : fixers)
     64                if (fixer.isFixerApplicable(rel))
     65                        return fixer;
     66        return new NothingFixer();
    4167    }
    4268
    43     public static Command fixRelation( Relation rel ) {
    44         Relation r = rel;
    45         boolean fixed = false;
    46         // todo: sort members
    47         // todo: set roles for multipolygon members
    48         Relation rr = fixMultipolygonRoles(r);
    49         if( rr != null ) {
    50             r = rr;
    51             fixed = true;
    52         }
    53         // todo: set roles for boundary members
    54         rr= fixBoundaryRoles(r);
    55         if( rr != null ) {
    56             r = rr;
    57             fixed = true;
    58         }
    59 
    60         return fixed ? new ChangeCommand(rel, r) : null;
     69    public Command fixRelation( Relation rel ) {
     70        return getFixer(rel).fixRelation(rel);
    6171    }
    6272
     
    7080    }
    7181
    72     /**
    73      * Check for ways that have roles different from "outer" and "inner".
    74      */
    75     private static boolean areMultipolygonTagsEmpty( Relation r ) {
    76         if( r == null || r.getMembersCount() == 0 || !ChosenRelation.isMultipolygon(r) )
    77             return false;
    78         for( RelationMember m : r.getMembers() ) {
    79             if( m.getType().equals(OsmPrimitiveType.WAY) && (m.getRole() == null || (!m.getRole().equals("outer") && !m.getRole().equals("inner"))) )
    80                 return true;
    81         }
    82         return false;
    83     }
    84 
    85     /**
    86      * Check for nodes and relations without needed roles.
    87      */
    88     private static boolean areBoundaryTagsNotRight( Relation r ) {
    89         if( r == null || r.getMembersCount() == 0 || !r.hasKey("type") || !r.get("type").equals("boundary") )
    90             return false;
    91         for( RelationMember m : r.getMembers() ) {
    92             if( m.getType().equals(OsmPrimitiveType.RELATION) && (m.getRole() == null || !m.getRole().equals("subarea")) )
    93                 return true;
    94             else if(m.getType().equals(OsmPrimitiveType.NODE) && (m.getRole() == null || (!m.getRole().equals("label") && !m.getRole().equals("admin_centre"))) )
    95                 return true;
    96         }
    97         return false;
    98     }
    99 
    100     /**
    101      * Basically, created multipolygon from scratch, and if successful, replace roles with new ones.
    102      */
    103     private static Relation fixMultipolygonRoles( Relation source ) {
    104         Collection<Way> ways = new ArrayList<Way>();
    105         for( OsmPrimitive p : source.getMemberPrimitives() )
    106             if( p instanceof Way )
    107                 ways.add((Way)p);
    108         MultipolygonCreate mpc = new MultipolygonCreate();
    109         String error = mpc.makeFromWays(ways);
    110         if( error != null )
    111             return null;
    112 
    113         Relation r = new Relation(source);
    114         boolean fixed = false;
    115         Set<Way> outerWays = new HashSet<Way>();
    116         for( MultipolygonCreate.JoinedPolygon poly : mpc.outerWays )
    117             for( Way w : poly.ways )
    118                 outerWays.add(w);
    119         Set<Way> innerWays = new HashSet<Way>();
    120         for( MultipolygonCreate.JoinedPolygon poly : mpc.innerWays )
    121             for( Way w : poly.ways )
    122                 innerWays.add(w);
    123         for( int i = 0; i < r.getMembersCount(); i++ ) {
    124             RelationMember m = r.getMember(i);
    125             if( m.isWay() ) {
    126                 String role = null;
    127                 if( outerWays.contains((Way)m.getMember()) )
    128                     role = "outer";
    129                 else if( innerWays.contains((Way)m.getMember()) )
    130                     role = "inner";
    131                 if( role != null && !role.equals(m.getRole()) ) {
    132                     r.setMember(i, new RelationMember(role, m.getMember()));
    133                     fixed = true;
    134                 }
    135             }
    136         }
    137         return fixed ? r : null;
    138     }
    139 
    140     private static Relation fixBoundaryRoles( Relation source ) {
    141         Relation r = new Relation(source);
    142         boolean fixed = false;
    143         for( int i = 0; i < r.getMembersCount(); i++ ) {
    144             RelationMember m = r.getMember(i);
    145             String role = null;
    146             if( m.isRelation() )
    147                 role = "subarea";
    148             else if( m.isNode() ) {
    149                 Node n = (Node)m.getMember();
    150                 if( !n.isIncomplete() ) {
    151                     if( n.hasKey("place") )
    152                         role = "admin_centre";
    153                     else
    154                         role = "label";
    155                 }
    156             }
    157             if( role != null && !role.equals(m.getRole()) ) {
    158                 r.setMember(i, new RelationMember(role, m.getMember()));
    159                 fixed = true;
    160             }
    161         }
    162         return fixed ? r : null;
    163     }
    16482}
Note: See TracChangeset for help on using the changeset viewer.