Ignore:
Timestamp:
2011-03-25T21:30:40+01:00 (13 years ago)
Author:
bastiK
Message:

applied #6149 - Multipolygon - Extended functionality (patch by Gubaer)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java

    r3095 r4004  
    88import java.util.Collection;
    99import java.util.List;
    10 
     10import java.util.logging.Logger;
     11
     12import org.openstreetmap.josm.Main;
     13import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
     14import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
    1115import org.openstreetmap.josm.data.osm.Node;
    1216import org.openstreetmap.josm.data.osm.Relation;
     
    1721
    1822public class Multipolygon {
     23    static private final Logger logger = Logger.getLogger(Multipolygon.class.getName());
     24
     25    /** preference key for a collection of roles which indicate that the respective member belongs to an
     26     * <em>outer</em> polygon. Default is <tt>outer</tt>.
     27     */
     28    static public final String PREF_KEY_OUTER_ROLES = "mappaint.multipolygon.outer.roles";
     29    /** preference key for collection of role prefixes which indicate that the respective
     30     *  member belongs to an <em>outer</em> polygon. Default is empty.
     31     */
     32    static public final String PREF_KEY_OUTER_ROLE_PREFIXES = "mappaint.multipolygon.outer.role-prefixes";
     33    /** preference key for a collection of roles which indicate that the respective member belongs to an
     34     * <em>inner</em> polygon. Default is <tt>inner</tt>.
     35     */
     36    static public final String PREF_KEY_INNER_ROLES = "mappaint.multipolygon.inner.roles";
     37    /** preference key for collection of role prefixes which indicate that the respective
     38     *  member belongs to an <em>inner</em> polygon. Default is empty.
     39     */
     40    static public final String PREF_KEY_INNER_ROLE_PREFIXES = "mappaint.multipolygon.inner.role-prefixes";
     41
     42    /**
     43     * <p>Kind of strategy object which is responsible for deciding whether a given
     44     * member role indicates that the member belongs to an <em>outer</em> or an
     45     * <em>inner</em> polygon.</p>
     46     *
     47     * <p>The decision is taken based on preference settings, see the four preference keys
     48     * above.</p>
     49     *
     50     */
     51    private static class MultipolygonRoleMatcher implements PreferenceChangedListener{
     52        private final List<String> outerExactRoles = new ArrayList<String>();
     53        private final List<String> outerRolePrefixes = new ArrayList<String>();
     54        private final List<String> innerExactRoles = new ArrayList<String>();
     55        private final List<String> innerRolePrefixes = new ArrayList<String>();
     56
     57        private void initDefaults() {
     58            outerExactRoles.clear();
     59            outerRolePrefixes.clear();
     60            innerExactRoles.clear();
     61            innerRolePrefixes.clear();
     62            outerExactRoles.add("outer");
     63            innerExactRoles.add("inner");
     64        }
     65
     66        private void setNormalized(Collection<String> literals, List<String> target){
     67            target.clear();
     68            for(String l: literals) {
     69                if (l == null) {
     70                    continue;
     71                }
     72                l = l.trim();
     73                if (!target.contains(l)) {
     74                    target.add(l);
     75                }
     76            }
     77        }
     78
     79        private void initFromPreferences() {
     80            initDefaults();
     81            if (Main.pref == null) return;
     82            Collection<String> literals;
     83            literals = Main.pref.getCollection(PREF_KEY_OUTER_ROLES);
     84            if (literals != null && !literals.isEmpty()){
     85                setNormalized(literals, outerExactRoles);
     86            }
     87            literals = Main.pref.getCollection(PREF_KEY_OUTER_ROLE_PREFIXES);
     88            if (literals != null && !literals.isEmpty()){
     89                setNormalized(literals, outerRolePrefixes);
     90            }
     91            literals = Main.pref.getCollection(PREF_KEY_INNER_ROLES);
     92            if (literals != null && !literals.isEmpty()){
     93                setNormalized(literals, innerExactRoles);
     94            }
     95            literals = Main.pref.getCollection(PREF_KEY_INNER_ROLE_PREFIXES);
     96            if (literals != null && !literals.isEmpty()){
     97                setNormalized(literals, innerRolePrefixes);
     98            }
     99        }
     100
     101        @Override
     102        public void preferenceChanged(PreferenceChangeEvent evt) {
     103            if (PREF_KEY_INNER_ROLE_PREFIXES.equals(evt.getKey()) ||
     104                    PREF_KEY_INNER_ROLES.equals(evt.getKey()) ||
     105                    PREF_KEY_OUTER_ROLE_PREFIXES.equals(evt.getKey()) ||
     106                    PREF_KEY_OUTER_ROLES.equals(evt.getKey())){
     107                initFromPreferences();
     108            }
     109        }
     110
     111        public boolean isOuterRole(String role){
     112            if (role == null) return false;
     113            for (String candidate: outerExactRoles) {
     114                if (role.equals(candidate)) return true;
     115            }
     116            for (String candidate: outerRolePrefixes) {
     117                if (role.startsWith(candidate)) return true;
     118            }
     119            return false;
     120        }
     121
     122        public boolean isInnerRole(String role){
     123            if (role == null) return false;
     124            for (String candidate: innerExactRoles) {
     125                if (role.equals(candidate)) return true;
     126            }
     127            for (String candidate: innerRolePrefixes) {
     128                if (role.startsWith(candidate)) return true;
     129            }
     130            return false;
     131        }
     132    }
     133
     134    /*
     135     * Init a private global matcher object which will listen to preference
     136     * changes.
     137     */
     138    private static MultipolygonRoleMatcher roleMatcher;
     139    private static MultipolygonRoleMatcher getMultipoloygonRoleMatcher() {
     140        if (roleMatcher == null) {
     141            roleMatcher = new MultipolygonRoleMatcher();
     142            if (Main.pref != null){
     143                roleMatcher.initFromPreferences();
     144                Main.pref.addPreferenceChangeListener(roleMatcher);
     145            }
     146        }
     147        return roleMatcher;
     148    }
    19149
    20150    public static class JoinedWay {
     
    123253
    124254    public void load(Relation r) {
     255        MultipolygonRoleMatcher matcher = getMultipoloygonRoleMatcher();
     256
    125257        // Fill inner and outer list with valid ways
    126258        for (RelationMember m : r.getMembers()) {
     
    133265                    }
    134266
    135                     if("inner".equals(m.getRole())) {
    136                         getInnerWays().add(w);
    137                     } else if("outer".equals(m.getRole())) {
    138                         getOuterWays().add(w);
     267                    if(matcher.isInnerRole(m.getRole())) {
     268                        innerWays.add(w);
     269                    } else if(matcher.isOuterRole(m.getRole())) {
     270                        outerWays.add(w);
    139271                    } else if (!m.hasRole()) {
    140                         getOuterWays().add(w);
     272                        outerWays.add(w);
    141273                    } // Remaining roles ignored
    142274                } // Non ways ignored
Note: See TracChangeset for help on using the changeset viewer.