Ticket #8255: 8255_v2.patch

File 8255_v2.patch, 17.7 KB (added by simon04, 13 years ago)
  • data/defaultpresets.xml

    diff --git a/data/defaultpresets.xml b/data/defaultpresets.xml
    index d798bac..c9b9477 100755
    a b role: type to specify possible roles in relations  
    8888  requisite: optional/required (default is "optional")
    8989  count: how often can the role occur (if not given unlimited number is assumed)
    9090  type: the data types - way,node,relation,closedway (separated by comma)
     91  member_expression: an expression (cf. search dialog) for objects of this role
    9192
    9293 presets: For external files <presets> should have following attributes:
    9394   author: the author of the preset
    Note that for a match, at least one positive and no negative is required.  
    24252426            </optional>
    24262427            <roles>
    24272428                <role key="" text="route segment" requisite="required" type="way" />
    2428                 <role key="stop" text="stop position" requisite="optional" type="node" />
    2429                 <role key="stop_exit_only" text="stop position (exit only)" requisite="optional" type="node" />
    2430                 <role key="stop_entry_only" text="stop position (entry only)" requisite="optional" type="node" />
    2431                 <role key="platform" text="platform" requisite="optional" type="node,way,closedway" />
    2432                 <role key="platform_exit_only" text="platform (exit only)" requisite="optional" type="node,way,closedway" />
    2433                 <role key="platform_entry_only" text="platform (entry only)" requisite="optional" type="node,way,closedway" />
     2429                <role key="stop" text="stop position" requisite="optional" type="node" member_expression="public_transport=stop_position" />
     2430                <role key="stop_exit_only" text="stop position (exit only)" requisite="optional" type="node" member_expression="public_transport=stop_position" />
     2431                <role key="stop_entry_only" text="stop position (entry only)" requisite="optional" type="node" member_expression="public_transport=stop_position" />
     2432                <role key="platform" text="platform" requisite="optional" type="node,way,closedway" member_expression="public_transport=platform" />
     2433                <role key="platform_exit_only" text="platform (exit only)" requisite="optional" type="node,way,closedway" member_expression="public_transport=platform" />
     2434                <role key="platform_entry_only" text="platform (entry only)" requisite="optional" type="node,way,closedway" member_expression="public_transport=platform" />
    24342435            </roles>
    24352436        </item>
    24362437        <item name="Route master" icon="presets/path.png" type="relation">
    Note that for a match, at least one positive and no negative is required.  
    24462447                <combo key="colour" text="Color (HTML name or hexadecimal code)" values_context="color" values="black,brown,green,red,blue,gray,white,#CD853F" />
    24472448            </optional>
    24482449            <roles>
    2449                 <role key="" text="route variant/direction (at least 2)" requisite="required" type="relation"/> <!-- FIXME: at least 2 members are required -->
     2450                <role key="" text="route variant/direction (at least 2)" requisite="required" type="relation" member_expression="type=route"/> <!-- FIXME: at least 2 members are required -->
    24502451            </roles>
    24512452        </item>
    24522453        <item name="Stop Area" type="relation" icon="presets/interpolation.png">
    Note that for a match, at least one positive and no negative is required.  
    24632464                <text key="network" text="Network"/>
    24642465            </optional>
    24652466            <roles>
    2466                 <role key="stop" text="Stop Position" requisite="optional" type="node"/>
    2467                 <role key="platform" text="Platform" requisite="optional" type="node,way,closedway"/>
    2468                 <role key="" text="Station or amenities" requisite="optional" type="node,way,closedway"/>
     2467                <role key="stop" text="Stop Position" requisite="optional" type="node" member_expression="public_transport=stop_position"/>
     2468                <role key="platform" text="Platform" requisite="optional" type="node,way,closedway" member_expression="public_transport=platform"/>
     2469                <role key="" text="Station or amenities" requisite="optional" type="node,way,closedway" member_expression="amenity|public_transport=station"/>
    24692470            </roles>
    24702471        </item>
    24712472        <separator/>
    Note that for a match, at least one positive and no negative is required.  
    59055906            <key key="type" value="associatedStreet" />
    59065907            <text key="name" text="Street name" />
    59075908            <roles>
    5908                 <role key="street" text="street" requisite="required" type="way" />
    5909                 <role key="house" text="house" requisite="required" type="node,way,closedway,relation" />
     5909                <role key="street" text="street" requisite="required" type="way" member_expression="highway &quot;addr:street&quot;" />
     5910                <role key="house" text="house" requisite="required" type="node,way,closedway,relation" member_expression="&quot;addr:housenumber&quot;" />
    59105911            </roles>
    59115912        </item>
    59125913        <item name="Street" type="relation">
    Note that for a match, at least one positive and no negative is required.  
    59625963                <text key="wikipedia" text="Wikipedia" />
    59635964            </optional>
    59645965            <roles>
    5965                 <role key="" text="waterways (no riverbank)" requisite="optional" type="way" />
    5966                 <role key="main_stream" text="waterways (no riverbank)" requisite="optional" type="way" />
    5967                 <role key="side_stream" text="branch waterways (no riverbank)" requisite="optional" type="way" />
     5966                <role key="" text="waterways (no riverbank)" requisite="optional" type="way" member_expression="waterway -waterway:riverbank" />
     5967                <role key="main_stream" text="waterways (no riverbank)" requisite="optional" type="way" member_expression="waterway -waterway:riverbank" />
     5968                <role key="side_stream" text="branch waterways (no riverbank)" requisite="optional" type="way" member_expression="waterway -waterway:riverbank"/>
    59685969                <role key="spring" text="spring of waterway" requisite="optional" type="node" />
    59695970            </roles>
    59705971        </item>
  • data/tagging-preset.xsd

    diff --git a/data/tagging-preset.xsd b/data/tagging-preset.xsd
    index 72f84e4..183f296 100644
    a b  
    231231                <attribute name="requisite" type="tns:role_requisite" />
    232232                <attribute name="type" type="string" />
    233233                <attribute name="count" type="integer" />
     234                <attribute name="member_expression" type="string" />
    234235        </complexType>
    235236
    236237        <simpleType name="role_requisite">
  • src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java b/src/org/openstreetmap/josm/gui/dialogs/properties/PresetListPanel.java
    index f52e70c..cebd1fe 100644
    a b import javax.swing.JPanel;  
    2020
    2121import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2222import org.openstreetmap.josm.data.osm.Tag;
    23 import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
    2423import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    2524import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
    2625import org.openstreetmap.josm.tools.GBC;
    public class PresetListPanel extends JPanel {  
    8584            return;
    8685        }
    8786
    88         for (TaggingPreset t : TaggingPresetPreference.taggingPresets) {
    89             if (!t.matches(types, tags, true)) {
    90                 continue;
    91             }
    92 
     87        for (TaggingPreset t : TaggingPreset.getMatchingPresets(types, tags, true)) {
    9388            JLabel lbl = new JLabel(t.getName() + " …");
    9489            lbl.setIcon((Icon) t.getValue(Action.SMALL_ICON));
    9590            lbl.addMouseListener(new PresetLabelML(lbl, t, presetHandler));
  • src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java b/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
    index abba54b..5205c52 100644
    a b import org.openstreetmap.josm.gui.HelpAwareOptionPane;  
    6161import org.openstreetmap.josm.gui.MainMenu;
    6262import org.openstreetmap.josm.gui.SideButton;
    6363import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
     64import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel;
    6465import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel.PresetHandler;
    6566import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
    6667import org.openstreetmap.josm.gui.help.HelpUtil;
    public class GenericRelationEditor extends RelationEditor {  
    114115        setRememberWindowGeometry(getClass().getName() + ".geometry",
    115116                WindowGeometry.centerInWindow(Main.parent, new Dimension(700, 650)));
    116117
    117         // init the various models
    118         //
    119         memberTableModel = new MemberTableModel(getLayer());
    120         memberTableModel.register();
    121         selectionTableModel = new SelectionTableModel(getLayer());
    122         selectionTableModel.register();
    123         referrerModel = new ReferringRelationsBrowserModel(relation);
    124 
    125         tagEditorPanel = new TagEditorPanel(new PresetHandler() {
     118        final PresetHandler presetHandler = new PresetHandler() {
    126119
    127120            @Override
    128121            public void updateTags(List<Tag> tags) {
    public class GenericRelationEditor extends RelationEditor {  
    135128                tagEditorPanel.getModel().applyToPrimitive(relation);
    136129                return Collections.<OsmPrimitive>singletonList(relation);
    137130            }
    138         });
     131        };
     132
     133        // init the various models
     134        //
     135        memberTableModel = new MemberTableModel(getLayer(), presetHandler);
     136        memberTableModel.register();
     137        selectionTableModel = new SelectionTableModel(getLayer());
     138        selectionTableModel.register();
     139        referrerModel = new ReferringRelationsBrowserModel(relation);
     140
     141        tagEditorPanel = new TagEditorPanel(presetHandler);
    139142
    140143        // populate the models
    141144        //
  • src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

    diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
    index 8908626..2b37958 100644
    a b import java.util.Arrays;  
    1212import java.util.Collection;
    1313import java.util.Collections;
    1414import java.util.Comparator;
     15import java.util.EnumSet;
    1516import java.util.HashMap;
    1617import java.util.HashSet;
    1718import java.util.Iterator;
    import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;  
    4546import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
    4647import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
    4748import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
     49import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel;
    4850import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction;
    4951import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     52import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    5053import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
    5154
    5255public class MemberTableModel extends AbstractTableModel implements TableModelListener, SelectionChangedListener, DataSetListener, OsmPrimitivesTableModel {
    public class MemberTableModel extends AbstractTableModel implements TableModelLi  
    5861    private List<WayConnectionType> connectionType = null;
    5962
    6063    private DefaultListSelectionModel listSelectionModel;
    61     private CopyOnWriteArrayList<IMemberModelListener> listeners;
    62     private OsmDataLayer layer;
     64    private final CopyOnWriteArrayList<IMemberModelListener> listeners;
     65    private final OsmDataLayer layer;
     66    private final PresetListPanel.PresetHandler presetHandler;
    6367
    6468    private final int UNCONNECTED = Integer.MIN_VALUE;
    6569   
    public class MemberTableModel extends AbstractTableModel implements TableModelLi  
    7276    /**
    7377     * constructor
    7478     */
    75     public MemberTableModel(OsmDataLayer layer) {
     79    public MemberTableModel(OsmDataLayer layer, PresetListPanel.PresetHandler presetHandler) {
    7680        members = new ArrayList<RelationMember>();
    7781        listeners = new CopyOnWriteArrayList<IMemberModelListener>();
    7882        this.layer = layer;
     83        this.presetHandler = presetHandler;
    7984        addTableModelListener(this);
    8085    }
    8186
    public class MemberTableModel extends AbstractTableModel implements TableModelLi  
    394399    }
    395400
    396401    private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int index) {
     402        final Collection<TaggingPreset> presets = TaggingPreset.getMatchingPresets(EnumSet.of(TaggingPreset.PresetType.RELATION), presetHandler.getSelection().iterator().next().getKeys(), false);
    397403        if (primitives == null)
    398404            return;
    399405        int idx = index;
    400406        for (OsmPrimitive primitive : primitives) {
    401             RelationMember member = new RelationMember("", primitive);
     407            final String role = presets.isEmpty() ? null : presets.iterator().next().suggestRoleForOsmPrimitive(primitive);
     408            RelationMember member = new RelationMember(role == null ? "" : role, primitive);
    402409            members.add(idx++, member);
    403410        }
    404411        fireTableDataChanged();
  • src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java

    diff --git a/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java
    index a68b4c6..cb971f7 100644
    a b import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;  
    6666import org.openstreetmap.josm.gui.layer.Layer;
    6767import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    6868import org.openstreetmap.josm.gui.preferences.SourceEntry;
     69import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
    6970import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference.PresetPrefHelper;
    7071import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
    7172import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
    import org.openstreetmap.josm.gui.widgets.JosmComboBox;  
    7576import org.openstreetmap.josm.io.MirroredInputStream;
    7677import org.openstreetmap.josm.tools.GBC;
    7778import org.openstreetmap.josm.tools.ImageProvider;
     79import org.openstreetmap.josm.tools.Predicate;
    7880import org.openstreetmap.josm.tools.UrlLabel;
    7981import org.openstreetmap.josm.tools.Utils;
    8082import org.openstreetmap.josm.tools.XmlObjectParser;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange  
    10931095        public String text;
    10941096        public String text_context;
    10951097        public String locale_text;
     1098        public Match memberExpression;
    10961099
    10971100        public boolean required = false;
    10981101        public long count = 0;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange  
    11081111                throw new SAXException(tr("Unknown requisite: {0}", str));
    11091112        }
    11101113
     1114        public void setMember_expression(String member_expression) throws SAXException {
     1115            try {
     1116                this.memberExpression = SearchCompiler.compile(member_expression, true, true);
     1117            } catch (SearchCompiler.ParseError ex) {
     1118                throw new SAXException(tr("Illegal member expression: {0}", ex.getMessage()), ex);
     1119            }
     1120        }
     1121
    11111122        /* return either argument, the highest possible value or the lowest
    11121123           allowed value */
    11131124        public long getValidCount(long c)
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange  
    15711582        return false;
    15721583    }
    15731584
     1585    public String suggestRoleForOsmPrimitive(OsmPrimitive osm) {
     1586        final List<Role> roles = new ArrayList<Role>();
     1587        for (Item i : data) {
     1588            if (i instanceof Roles) {
     1589                roles.addAll(((Roles) i).roles);
     1590            }
     1591        }
     1592        for (Role i : roles) {
     1593            if (i.memberExpression != null && i.memberExpression.match(osm)) {
     1594                return i.key;
     1595            }
     1596        }
     1597        return null;
     1598    }
     1599
    15741600    public void actionPerformed(ActionEvent e) {
    15751601        if (Main.main == null) return;
    15761602        if (Main.main.getCurrentDataSet() == null) return;
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange  
    15891615            for(Tag t : getChangedTags()) {
    15901616                r.put(t.getKey(), t.getValue());
    15911617            }
    1592             for(OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
    1593                 RelationMember rm = new RelationMember("", osm);
     1618            for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
     1619                String role = suggestRoleForOsmPrimitive(osm);
     1620                RelationMember rm = new RelationMember(role == null ? "" : role, osm);
    15941621                r.addMember(rm);
    15951622                members.add(rm);
    15961623            }
    public class TaggingPreset extends AbstractAction implements MapView.LayerChange  
    17721799        }
    17731800        return atLeastOnePositiveMatch;
    17741801    }
     1802
     1803    public static Collection<TaggingPreset> getMatchingPresets(final Collection<PresetType> t, final Map<String, String> tags, final boolean onlyShowable) {
     1804        return Utils.filter(TaggingPresetPreference.taggingPresets, new Predicate<TaggingPreset>() {
     1805            @Override
     1806            public boolean evaluate(TaggingPreset object) {
     1807                return object.matches(t, tags, onlyShowable);
     1808            }
     1809        });
     1810    }
    17751811}