Ignore:
Timestamp:
2010-09-15T18:53:09+02:00 (14 years ago)
Author:
stoecker
Message:

remove tabs

Location:
applications/editors/josm/plugins/graphview
Files:
83 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessEvaluator.java

    r16520 r23189  
    1919public interface AccessEvaluator<N, W> {
    2020
    21         /**
    22         * checks whether a way may be accessed in the given direction
    23         *
    24         * @param way                object to be checked; != null
    25         * @param segmentProperties  map from road property types to their values for this way's
    26         *                           segments; each value must be a valid value for its property type;
    27         *                           != null
    28         */
    29         public boolean wayUsable(W way, boolean forward,
    30                         Map<RoadPropertyType<?>, Object> roadPropertyValues);
     21    /**
     22    * checks whether a way may be accessed in the given direction
     23    *
     24    * @param way                object to be checked; != null
     25    * @param segmentProperties  map from road property types to their values for this way's
     26    *                           segments; each value must be a valid value for its property type;
     27    *                           != null
     28    */
     29    public boolean wayUsable(W way, boolean forward,
     30            Map<RoadPropertyType<?>, Object> roadPropertyValues);
    3131
    32         /**
    33         * checks whether a node may be accessed/passed
    34         *
    35         * @param node               object to be checked; != null
    36         * @param segmentProperties  map from road property types to their values for SegmentNodes
    37         *                           based on this node, each value must be a valid value for its
    38         *                           property type; != null
    39         */
    40         public boolean nodeUsable(N node, Map<RoadPropertyType<?>, Object> roadPropertyValues);
     32    /**
     33    * checks whether a node may be accessed/passed
     34    *
     35    * @param node               object to be checked; != null
     36    * @param segmentProperties  map from road property types to their values for SegmentNodes
     37    *                           based on this node, each value must be a valid value for its
     38    *                           property type; != null
     39    */
     40    public boolean nodeUsable(N node, Map<RoadPropertyType<?>, Object> roadPropertyValues);
    4141
    4242}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessParameters.java

    r16520 r23189  
    1111public interface AccessParameters {
    1212
    13         public String getAccessClass();
     13    public String getAccessClass();
    1414
    15         /**
    16         * returns true iff a road with a given access type can be used
    17         * @param accessType  access type to check usablitly for; != null
    18         */
    19         public boolean getAccessTypeUsable(AccessType accessType);
     15    /**
     16    * returns true iff a road with a given access type can be used
     17    * @param accessType  access type to check usablitly for; != null
     18    */
     19    public boolean getAccessTypeUsable(AccessType accessType);
    2020
    21         /**
    22         * returns all {@link VehiclePropertyType}s a value is avaliable for.
    23         * The value can be accessed using {@link #getVehiclePropertyValue(VehiclePropertyType)}
    24         * @return  collection of property types; != null
    25         */
    26         public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties();
     21    /**
     22    * returns all {@link VehiclePropertyType}s a value is avaliable for.
     23    * The value can be accessed using {@link #getVehiclePropertyValue(VehiclePropertyType)}
     24    * @return  collection of property types; != null
     25    */
     26    public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties();
    2727
    28         /**
    29         * returns the value for a vehicle property.
    30         *
    31         * @param <V>              type of property value
    32         * @param vehicleProperty  property to get value for; != null
    33         * @return                 value for vehicleProperty, null if no value is available.
    34         *                         Guaranteed to be valid according to vehicleProperty's
    35         *                         {@link VehiclePropertyType#isValidValue(Object)} method.
    36         */
    37         public <V> V getVehiclePropertyValue(VehiclePropertyType<V> vehicleProperty);
     28    /**
     29    * returns the value for a vehicle property.
     30    *
     31    * @param <V>              type of property value
     32    * @param vehicleProperty  property to get value for; != null
     33    * @return                 value for vehicleProperty, null if no value is available.
     34    *                         Guaranteed to be valid according to vehicleProperty's
     35    *                         {@link VehiclePropertyType#isValidValue(Object)} method.
     36    */
     37    public <V> V getVehiclePropertyValue(VehiclePropertyType<V> vehicleProperty);
    3838
    3939}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessRuleset.java

    r16520 r23189  
    1212public interface AccessRuleset {
    1313
    14         /**
    15         * for a mode of transport, returns all transport categories it is a subset of.
    16         * For example, the returned collection for "motorcycle" might include "motor_vehicle" and "vehicle".
    17         *
    18         * @param transportMode  mode of transport to get "supertypes" for; != null
    19         * @return parameters superset categories, including the parameter itself,
    20         *         in the order of decreasing specificness
    21         *         empty if the parameter was no known mode of transport; != null
    22         */
    23         public List<String> getAccessHierarchyAncestors(String transportMode);
     14    /**
     15    * for a mode of transport, returns all transport categories it is a subset of.
     16    * For example, the returned collection for "motorcycle" might include "motor_vehicle" and "vehicle".
     17    *
     18    * @param transportMode  mode of transport to get "supertypes" for; != null
     19    * @return parameters superset categories, including the parameter itself,
     20    *         in the order of decreasing specificness
     21    *         empty if the parameter was no known mode of transport; != null
     22    */
     23    public List<String> getAccessHierarchyAncestors(String transportMode);
    2424
    25         /**
    26         * returns all base tags.
    27         * Base tags are tags that make an object "eligible" for access evaluation
    28         * (commonly things like highway=* or barrier=*)
    29         */
    30         public Collection<Tag> getBaseTags();
     25    /**
     26    * returns all base tags.
     27    * Base tags are tags that make an object "eligible" for access evaluation
     28    * (commonly things like highway=* or barrier=*)
     29    */
     30    public Collection<Tag> getBaseTags();
    3131
    32         /**
    33         * returns ruleset-specific implications
    34         * @return  list of implications in the order they are expected to be applied; != null
    35         */
    36         public List<Implication> getImplications();
     32    /**
     33    * returns ruleset-specific implications
     34    * @return  list of implications in the order they are expected to be applied; != null
     35    */
     36    public List<Implication> getImplications();
    3737
    3838}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessRulesetReader.java

    r16836 r23189  
    2020public class AccessRulesetReader {
    2121
    22         public static class AccessRulesetSyntaxException extends IOException {
    23                 private static final long serialVersionUID = 1L;
    24                 public AccessRulesetSyntaxException(String message) {
    25                         super(message);
    26                 };
    27                 public AccessRulesetSyntaxException(Throwable t) {
    28                         super(t.toString());
    29                 }
    30         }
    31 
    32         /** private constructor to prevent instantiation */
    33         private AccessRulesetReader() { }
    34 
    35         public static AccessRuleset readAccessRuleset(InputStream inputStream)
    36         throws AccessRulesetSyntaxException, IOException {
    37 
    38                 RulesetHandler rulesetHandler = new RulesetHandler();
    39 
    40                 try {
    41                         XMLReader reader = XMLReaderFactory.createXMLReader();
    42                         InputSource input = new InputSource(inputStream);
    43                         reader.setContentHandler(rulesetHandler);
    44                         reader.setErrorHandler(null);
    45                         reader.parse(input);
    46                 } catch (SAXException e) {
    47                         throw new AccessRulesetSyntaxException(e);
    48                 }
    49 
    50                 return rulesetHandler.getAccessRuleset();
    51         }
    52 
    53         private static class RulesetHandler extends DefaultHandler {
    54 
    55                 private static class AccessClass {
    56                         final String name;
    57                         final AccessClass parent;
    58                         public AccessClass(String name, AccessClass parent) {
    59                                 this.name = name;
    60                                 this.parent = parent;
    61                         }
    62                         List<String> getAncestorHierarchy() {
    63                                 List<String> names;
    64                                 if (parent == null) {
    65                                         names = new LinkedList<String>();
    66                                 } else {
    67                                         names = parent.getAncestorHierarchy();
    68                                 }
    69                                 names.add(0, name);
    70                                 return names;
    71                         }
    72                 }
    73 
    74                 private final Collection<AccessClass> accessClasses = new LinkedList<AccessClass>();
    75                 private final Collection<Tag> baseTags = new LinkedList<Tag>();
    76 
    77                 private static enum Section {NONE, CLASSES, BASETAGS, IMPLICATIONS};
    78                 private Section currentSection = Section.NONE;
    79 
    80                 private AccessClass currentAccessClass = null;
    81 
    82                 private ImplicationXMLReader implicationReader = null;
    83                 private final List<Implication> implications = new LinkedList<Implication>();
    84 
    85                 /** returns the AccessRuleset that was read */
    86                 AccessRuleset getAccessRuleset() {
    87 
    88                         return new AccessRuleset() {
    89 
    90                                 public List<String> getAccessHierarchyAncestors(String transportMode) {
    91                                         for (AccessClass accessClass : accessClasses) {
    92                                                 if (accessClass.name.equals(transportMode)) {
    93                                                         return accessClass.getAncestorHierarchy();
    94                                                 }
    95                                         }
    96                                         return new LinkedList<String>();
    97                                 }
    98 
    99                                 public Collection<Tag> getBaseTags() {
    100                                         return baseTags;
    101                                 }
    102 
    103                                 public List<Implication> getImplications() {
    104                                         return implications;
    105                                 }
    106 
    107                         };
    108                 }
    109 
    110                 @Override
    111                 public void startElement(String uri, String localName, String name,
    112                                 Attributes attributes) throws SAXException {
    113 
    114                         if (implicationReader != null) {
    115                                 implicationReader.startElement(uri, localName, name, attributes);
    116                                 return;
    117                         }
    118 
    119                         if ("classes".equals(name)) {
    120 
    121                                 if (currentSection != Section.NONE) {
    122                                         throw new SAXException("classes element below root child level");
    123                                 }
    124 
    125                                 currentSection = Section.CLASSES;
    126 
    127                         } else if ("class".equals(name)) {
    128 
    129                                 String className = attributes.getValue("name");
    130 
    131                                 if (currentSection != Section.CLASSES) {
    132                                         throw new SAXException("class element (" + className + ") outside classes element");
    133                                 } else if (className == null) {
    134                                         throw new SAXException("class element without name");
    135                                 }
    136 
    137                                 AccessClass newAccessClass = new AccessClass(className, currentAccessClass);
    138 
    139                                 accessClasses.add(newAccessClass);
    140 
    141                                 currentAccessClass = newAccessClass;
    142 
    143                         } else if ("basetags".equals(name)) {
    144 
    145                                 if (currentSection != Section.NONE) {
    146                                         throw new SAXException("classes element below root child level");
    147                                 }
    148 
    149                                 currentSection = Section.BASETAGS;
    150 
    151                         } else if ("tag".equals(name)) {
    152 
    153                                 if (currentSection == Section.BASETAGS) {
    154                                         baseTags.add(readTag(attributes));
    155                                 } else {
    156                                         throw new SAXException("tag element outside basetag and implication elements");
    157                                 }
    158 
    159                         } else if ("implications".equals(name)) {
    160 
    161                                 if (currentSection != Section.NONE) {
    162                                         throw new SAXException("implications element below root child level");
    163                                 }
    164 
    165                                 implicationReader = new ImplicationXMLReader();
    166                                 currentSection = Section.IMPLICATIONS;
    167 
    168                         }
    169 
    170                 }
    171 
    172                 private static Tag readTag(Attributes attributes) throws SAXException {
    173 
    174                         String key = attributes.getValue("k");
    175                         String value = attributes.getValue("v");
    176 
    177                         if (key == null) {
    178                                 throw new SAXException("tag without key");
    179                         } else if (value == null) {
    180                                 throw new SAXException("tag without value (key is " + key + ")");
    181                         }
    182 
    183                         return new Tag(key, value);
    184                 }
    185 
    186                 @Override
    187                 public void endElement(String uri, String localName, String name)
    188                 throws SAXException {
    189 
    190                         if (implicationReader != null && !"implications".equals(name)) {
    191                                 implicationReader.endElement(uri, localName, name);
    192                         }
    193 
    194                         if ("classes".equals(name)) {
    195 
    196                                 if (currentSection != Section.CLASSES) {
    197                                         throw new SAXException("closed classes while it wasn't open");
    198                                 } else if (currentAccessClass != null) {
    199                                         throw new SAXException("closed classes element before all class elements were closed");
    200                                 }
    201 
    202                                 currentSection = Section.NONE;
    203 
    204                         } else if ("class".equals(name)) {
    205 
    206                                 if (currentAccessClass == null) {
    207                                         throw new SAXException("closed class element while none was open");
    208                                 }
    209 
    210                                 currentAccessClass = currentAccessClass.parent;
    211 
    212                         } else if ("basetags".equals(name)) {
    213 
    214                                 if (currentSection != Section.BASETAGS) {
    215                                         throw new SAXException("closed basetags while it wasn't open");
    216                                 }
    217 
    218                                 currentSection = Section.NONE;
    219 
    220                         } else if ("implications".equals(name)) {
    221 
    222                                 if (currentSection != Section.IMPLICATIONS) {
    223                                         throw new SAXException("closed implications while it wasn't open");
    224                                 }
    225 
    226                                 implications.addAll(implicationReader.getImplications());
    227                                 implicationReader = null;
    228                                 currentSection = Section.NONE;
    229 
    230                         }
    231 
    232                 }
    233 
    234         };
     22    public static class AccessRulesetSyntaxException extends IOException {
     23        private static final long serialVersionUID = 1L;
     24        public AccessRulesetSyntaxException(String message) {
     25            super(message);
     26        };
     27        public AccessRulesetSyntaxException(Throwable t) {
     28            super(t.toString());
     29        }
     30    }
     31
     32    /** private constructor to prevent instantiation */
     33    private AccessRulesetReader() { }
     34
     35    public static AccessRuleset readAccessRuleset(InputStream inputStream)
     36    throws AccessRulesetSyntaxException, IOException {
     37
     38        RulesetHandler rulesetHandler = new RulesetHandler();
     39
     40        try {
     41            XMLReader reader = XMLReaderFactory.createXMLReader();
     42            InputSource input = new InputSource(inputStream);
     43            reader.setContentHandler(rulesetHandler);
     44            reader.setErrorHandler(null);
     45            reader.parse(input);
     46        } catch (SAXException e) {
     47            throw new AccessRulesetSyntaxException(e);
     48        }
     49
     50        return rulesetHandler.getAccessRuleset();
     51    }
     52
     53    private static class RulesetHandler extends DefaultHandler {
     54
     55        private static class AccessClass {
     56            final String name;
     57            final AccessClass parent;
     58            public AccessClass(String name, AccessClass parent) {
     59                this.name = name;
     60                this.parent = parent;
     61            }
     62            List<String> getAncestorHierarchy() {
     63                List<String> names;
     64                if (parent == null) {
     65                    names = new LinkedList<String>();
     66                } else {
     67                    names = parent.getAncestorHierarchy();
     68                }
     69                names.add(0, name);
     70                return names;
     71            }
     72        }
     73
     74        private final Collection<AccessClass> accessClasses = new LinkedList<AccessClass>();
     75        private final Collection<Tag> baseTags = new LinkedList<Tag>();
     76
     77        private static enum Section {NONE, CLASSES, BASETAGS, IMPLICATIONS};
     78        private Section currentSection = Section.NONE;
     79
     80        private AccessClass currentAccessClass = null;
     81
     82        private ImplicationXMLReader implicationReader = null;
     83        private final List<Implication> implications = new LinkedList<Implication>();
     84
     85        /** returns the AccessRuleset that was read */
     86        AccessRuleset getAccessRuleset() {
     87
     88            return new AccessRuleset() {
     89
     90                public List<String> getAccessHierarchyAncestors(String transportMode) {
     91                    for (AccessClass accessClass : accessClasses) {
     92                        if (accessClass.name.equals(transportMode)) {
     93                            return accessClass.getAncestorHierarchy();
     94                        }
     95                    }
     96                    return new LinkedList<String>();
     97                }
     98
     99                public Collection<Tag> getBaseTags() {
     100                    return baseTags;
     101                }
     102
     103                public List<Implication> getImplications() {
     104                    return implications;
     105                }
     106
     107            };
     108        }
     109
     110        @Override
     111        public void startElement(String uri, String localName, String name,
     112                Attributes attributes) throws SAXException {
     113
     114            if (implicationReader != null) {
     115                implicationReader.startElement(uri, localName, name, attributes);
     116                return;
     117            }
     118
     119            if ("classes".equals(name)) {
     120
     121                if (currentSection != Section.NONE) {
     122                    throw new SAXException("classes element below root child level");
     123                }
     124
     125                currentSection = Section.CLASSES;
     126
     127            } else if ("class".equals(name)) {
     128
     129                String className = attributes.getValue("name");
     130
     131                if (currentSection != Section.CLASSES) {
     132                    throw new SAXException("class element (" + className + ") outside classes element");
     133                } else if (className == null) {
     134                    throw new SAXException("class element without name");
     135                }
     136
     137                AccessClass newAccessClass = new AccessClass(className, currentAccessClass);
     138
     139                accessClasses.add(newAccessClass);
     140
     141                currentAccessClass = newAccessClass;
     142
     143            } else if ("basetags".equals(name)) {
     144
     145                if (currentSection != Section.NONE) {
     146                    throw new SAXException("classes element below root child level");
     147                }
     148
     149                currentSection = Section.BASETAGS;
     150
     151            } else if ("tag".equals(name)) {
     152
     153                if (currentSection == Section.BASETAGS) {
     154                    baseTags.add(readTag(attributes));
     155                } else {
     156                    throw new SAXException("tag element outside basetag and implication elements");
     157                }
     158
     159            } else if ("implications".equals(name)) {
     160
     161                if (currentSection != Section.NONE) {
     162                    throw new SAXException("implications element below root child level");
     163                }
     164
     165                implicationReader = new ImplicationXMLReader();
     166                currentSection = Section.IMPLICATIONS;
     167
     168            }
     169
     170        }
     171
     172        private static Tag readTag(Attributes attributes) throws SAXException {
     173
     174            String key = attributes.getValue("k");
     175            String value = attributes.getValue("v");
     176
     177            if (key == null) {
     178                throw new SAXException("tag without key");
     179            } else if (value == null) {
     180                throw new SAXException("tag without value (key is " + key + ")");
     181            }
     182
     183            return new Tag(key, value);
     184        }
     185
     186        @Override
     187        public void endElement(String uri, String localName, String name)
     188        throws SAXException {
     189
     190            if (implicationReader != null && !"implications".equals(name)) {
     191                implicationReader.endElement(uri, localName, name);
     192            }
     193
     194            if ("classes".equals(name)) {
     195
     196                if (currentSection != Section.CLASSES) {
     197                    throw new SAXException("closed classes while it wasn't open");
     198                } else if (currentAccessClass != null) {
     199                    throw new SAXException("closed classes element before all class elements were closed");
     200                }
     201
     202                currentSection = Section.NONE;
     203
     204            } else if ("class".equals(name)) {
     205
     206                if (currentAccessClass == null) {
     207                    throw new SAXException("closed class element while none was open");
     208                }
     209
     210                currentAccessClass = currentAccessClass.parent;
     211
     212            } else if ("basetags".equals(name)) {
     213
     214                if (currentSection != Section.BASETAGS) {
     215                    throw new SAXException("closed basetags while it wasn't open");
     216                }
     217
     218                currentSection = Section.NONE;
     219
     220            } else if ("implications".equals(name)) {
     221
     222                if (currentSection != Section.IMPLICATIONS) {
     223                    throw new SAXException("closed implications while it wasn't open");
     224                }
     225
     226                implications.addAll(implicationReader.getImplications());
     227                implicationReader = null;
     228                currentSection = Section.NONE;
     229
     230            }
     231
     232        }
     233
     234    };
    235235}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessType.java

    r16520 r23189  
    33public enum AccessType {
    44
    5         YES("yes"),
    6         PERMISSIVE("permissive"),
    7         DESIGNATED("designated"),
    8         DESTINATION("destination"),
    9         AGRICULTURAL("agricultural"),
    10         FORESTRY("forestry"),
    11         DELIVERY("delivery"),
    12         PRIVATE("private"),
    13         NO("no"),
    14         UNDEFINED();
     5    YES("yes"),
     6    PERMISSIVE("permissive"),
     7    DESIGNATED("designated"),
     8    DESTINATION("destination"),
     9    AGRICULTURAL("agricultural"),
     10    FORESTRY("forestry"),
     11    DELIVERY("delivery"),
     12    PRIVATE("private"),
     13    NO("no"),
     14    UNDEFINED();
    1515
    16         private String[] valueStrings;
    17         private AccessType(String... valueStrings) {
    18                 this.valueStrings = valueStrings;
    19         }
     16    private String[] valueStrings;
     17    private AccessType(String... valueStrings) {
     18        this.valueStrings = valueStrings;
     19    }
    2020
    21         /**
    22         * returns the AccessType that fits for a tag's value
    23         *
    24         * @param valueString  a tag's value; != null
    25         * @return             AccessType for the value; != null, will be UNDEFINED for unknown values
    26         */
    27         public static AccessType getAccessType(String valueString) {
    28                 for (AccessType accessType : AccessType.values()) {
    29                         for (String typeValueString : accessType.valueStrings) {
    30                                 if (typeValueString.equals(valueString)) {
    31                                         return accessType;
    32                                 }
    33                         }
    34                 }
    35                 return UNDEFINED;
    36         }
     21    /**
     22    * returns the AccessType that fits for a tag's value
     23    *
     24    * @param valueString  a tag's value; != null
     25    * @return             AccessType for the value; != null, will be UNDEFINED for unknown values
     26    */
     27    public static AccessType getAccessType(String valueString) {
     28        for (AccessType accessType : AccessType.values()) {
     29            for (String typeValueString : accessType.valueStrings) {
     30                if (typeValueString.equals(valueString)) {
     31                    return accessType;
     32                }
     33            }
     34        }
     35        return UNDEFINED;
     36    }
    3737
    3838}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/Implication.java

    r16520 r23189  
    1515public final class Implication {
    1616
    17         private final TagCondition condition;
    18         private final Collection<Tag> impliedTags;
     17    private final TagCondition condition;
     18    private final Collection<Tag> impliedTags;
    1919
    20         public Implication(TagCondition condition, Collection<Tag> impliedTags) {
    21                 this.condition = condition;
    22                 this.impliedTags = impliedTags;
    23         }
     20    public Implication(TagCondition condition, Collection<Tag> impliedTags) {
     21        this.condition = condition;
     22        this.impliedTags = impliedTags;
     23    }
    2424
    25         /**
    26         * applies this implication to a tag group.
    27         * The resulting tag group will contain all tags from the original group
    28         * and all implied tags with a key that didn't occur in the original group.
    29         *
    30         * @param tags  tag group to apply implications to; != null
    31         */
    32         public TagGroup apply(TagGroup tags) {
     25    /**
     26    * applies this implication to a tag group.
     27    * The resulting tag group will contain all tags from the original group
     28    * and all implied tags with a key that didn't occur in the original group.
     29    *
     30    * @param tags  tag group to apply implications to; != null
     31    */
     32    public TagGroup apply(TagGroup tags) {
    3333
    34                 if (condition.matches(tags)) {
     34        if (condition.matches(tags)) {
    3535
    36                         Map<String, String> newTagMap = new HashMap<String, String>();
     36            Map<String, String> newTagMap = new HashMap<String, String>();
    3737
    38                         for (Tag tag : tags) {
    39                                 newTagMap.put(tag.key, tag.value);
    40                         }
     38            for (Tag tag : tags) {
     39                newTagMap.put(tag.key, tag.value);
     40            }
    4141
    42                         for (Tag impliedTag : impliedTags) {
    43                                 if (!newTagMap.containsKey(impliedTag.key)) {
    44                                         newTagMap.put(impliedTag.key, impliedTag.value);
    45                                 }
    46                         }
     42            for (Tag impliedTag : impliedTags) {
     43                if (!newTagMap.containsKey(impliedTag.key)) {
     44                    newTagMap.put(impliedTag.key, impliedTag.value);
     45                }
     46            }
    4747
    48                         return new MapBasedTagGroup(newTagMap);
     48            return new MapBasedTagGroup(newTagMap);
    4949
    50                 } else {
    51                         return tags;
    52                 }
     50        } else {
     51            return tags;
     52        }
    5353
    54         }
     54    }
    5555
    56         @Override
    57         public String toString() {
    58                 return condition.toString() + " => " + impliedTags.toString();
    59         }
     56    @Override
     57    public String toString() {
     58        return condition.toString() + " => " + impliedTags.toString();
     59    }
    6060
    6161}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/ImplicationXMLReader.java

    r16520 r23189  
    1717public class ImplicationXMLReader {
    1818
    19         private final List<Implication> implications = new LinkedList<Implication>();
    20 
    21         private static enum State {BEFORE_IMPLICATION, BEFORE_CONDITION, CONDITION, BEFORE_IMPLIES, IMPLIES, AFTER_IMPLIES};
    22         private State state = State.BEFORE_IMPLICATION;
    23 
    24         private ConditionReader currentConditionReader;
    25         private TagCondition currentCondition;
    26         private Collection<Tag> currentImpliedTags;
    27 
    28         boolean tagOpen = false;
    29 
    30         public void startElement(String uri, String localName, String name, Attributes attributes)
    31         throws SAXException {
    32 
    33                 switch (state) {
    34 
    35                         case BEFORE_IMPLICATION:
    36 
    37                                 if ("implication".equals(name)) {
    38                                         state = State.BEFORE_CONDITION;
    39                                         return;
    40                                 }
    41                                 break;
    42 
    43                         case BEFORE_CONDITION:
    44 
    45                                 if ("condition".equals(name)) {
    46                                         currentConditionReader = new ConditionReader();
    47                                         state = State.CONDITION;
    48                                         return;
    49                                 }
    50                                 break;
    51 
    52                         case CONDITION:
    53                                 currentConditionReader.startElement(uri, localName, name, attributes);
    54                                 return;
    55 
    56                         case BEFORE_IMPLIES:
    57 
    58                                 if ("implies".equals(name)) {
    59                                         currentImpliedTags = new LinkedList<Tag>();
    60                                         state = State.IMPLIES;
    61                                         return;
    62                                 }
    63                                 break;
    64 
    65                         case IMPLIES:
    66 
    67                                 if ("tag".equals(name)) {
    68                                         if (tagOpen) {
    69                                                 throw new SAXException("tag element inside other tag element");
    70                                         }
    71                                         currentImpliedTags.add(readTag(attributes));
    72                                         tagOpen = true;
    73                                         return;
    74                                 }
    75                                 break;
    76 
    77                 }
    78 
    79                 //all vaild paths end with return; reaching this indicates an invalid tag
    80                 throw new SAXException("invalid opening xml tag <" + name + "> in state " + state);
    81 
    82         }
    83 
    84         public void endElement(String uri, String localName, String name)
    85         throws SAXException {
    86 
    87                 switch (state) {
    88 
    89                         case CONDITION:
    90 
    91                                 if (name.equals("condition")) {
    92                                         if (!currentConditionReader.isFinished()) {
    93                                                 throw new SAXException("condition isn't finished at </condition> tag");
    94                                         } else {
    95                                                 currentCondition = currentConditionReader.getCondition();
    96                                                 currentConditionReader = null;
    97                                                 state = State.BEFORE_IMPLIES;
    98                                                 return;
    99                                         }
    100                                 } else {
    101                                         currentConditionReader.endElement(uri, localName, name);
    102                                         return;
    103                                 }
    104 
    105                         case IMPLIES:
    106 
    107                                 if (name.equals("implies")) {
    108                                         state = State.AFTER_IMPLIES;
    109                                         return;
    110                                 } else if (name.equals("tag")) {
    111                                         if (!tagOpen) {
    112                                                 throw new SAXException("closing tag element that was not open");
    113                                         }
    114                                         tagOpen = false;
    115                                         return;
    116                                 }
    117                                 break;
    118 
    119                         case AFTER_IMPLIES:
    120 
    121                                 if (name.equals("implication")) {
    122                                         implications.add(new Implication(currentCondition, currentImpliedTags));
    123                                         currentCondition = null;
    124                                         currentImpliedTags = null;
    125                                         state = State.BEFORE_IMPLICATION;
    126                                         return;
    127                                 }
    128                                 break;
    129 
    130                 }
    131 
    132                 //all vaild paths end with return; reaching this indicates an invalid tag
    133                 throw new SAXException("invalid closing xml tag </" + name + "> in state " + state);
    134 
    135         }
    136 
    137         public List<Implication> getImplications() throws SAXException {
    138 
    139                 if (state != State.BEFORE_IMPLICATION) {
    140                         throw new SAXException("some tags not been closed; now in state " + state);
    141                 } else {
    142                         return new ArrayList<Implication>(implications);
    143                 }
    144         }
    145 
    146         private static Tag readTag(Attributes attributes) throws SAXException {
    147 
    148                 String key = attributes.getValue("k");
    149                 String value = attributes.getValue("v");
    150 
    151                 if (key == null) {
    152                         throw new SAXException("tag without key");
    153                 } else if (value == null) {
    154                         throw new SAXException("tag without value (key is " + key + ")");
    155                 }
    156 
    157                 return new Tag(key, value);
    158         }
    159 
    160         private static String readKey(Attributes attributes) throws SAXException {
    161 
    162                 String key = attributes.getValue("k");
    163 
    164                 if (key == null) {
    165                         throw new SAXException("key element without attribute k");
    166                 }
    167 
    168                 return key;
    169         }
    170 
    171         /**
    172         * class to be used for reading tag condition sections of xml files
    173         */
    174         private static class ConditionReader {
    175 
    176                 String openingName;
    177                 TagCondition condition;
    178                 boolean finished;
    179 
    180                 private final List<ConditionReader> childReaders = new LinkedList<ConditionReader>();
    181                 private ConditionReader currentChildReader = null;
    182 
    183                 public void startElement(String uri, String localName, String name, Attributes attributes)
    184                 throws SAXException {
    185 
    186                         if (finished) {
    187                                 throw new SAXException("condition is already finished at <" + name + ">");
    188                         }
    189 
    190                         if (currentChildReader != null) {
    191                                 currentChildReader.startElement(uri, localName, name, attributes);
    192                                 return;
    193                         }
    194 
    195                         //first tag is start tag of this condition
    196                         if (openingName == null) {
    197 
    198                                 openingName = name;
    199 
    200                                 if ("tag".equals(name)) {
    201                                         condition = TagConditionLogic.tag(readTag(attributes));
    202                                 } else if ("key".equals(name)) {
    203                                         condition = TagConditionLogic.key(readKey(attributes));
    204                                 } else if (!("or".equals(name)) && !("and".equals(name)) && !("not".equals(name))) {
    205                                         throw new SAXException("unknown tag for condition: " + name);
    206                                 }
    207 
    208                                 //all tags after the first are start tags of child conditions
    209                         } else {
    210 
    211                                 if ("tag".equals(openingName) || "key".equals(openingName)) {
    212                                         throw new SAXException("element must not have childs: " + openingName);
    213                                 }
    214 
    215                                 currentChildReader = new ConditionReader();
    216                                 currentChildReader.startElement(uri, localName, name, attributes);
    217 
    218                         }
    219 
    220                 }
    221 
    222                 public void endElement(String uri, String localName, String name)
    223                 throws SAXException {
    224 
    225                         if (finished) {
    226                                 throw new SAXException("condition is already finished at </" + name + ">");
    227                         }
    228 
    229                         /* if active child reader exists, pass parameter to it. */
    230                         if (currentChildReader != null) {
    231 
    232                                 currentChildReader.endElement(uri, localName, name);
    233 
    234                                 if (currentChildReader.isFinished()) {
    235                                         childReaders.add(currentChildReader);
    236                                         currentChildReader = null;
    237                                 }
    238 
    239                         } else {
    240 
    241                                 if (openingName.equals(name)) {
    242 
    243                                         List<TagCondition> childConditions = new ArrayList<TagCondition>();
    244                                         for (ConditionReader childReader : childReaders) {
    245                                                 childConditions.add(childReader.getCondition());
    246                                         }
    247 
    248                                         if ("and".equals(openingName)) {
    249                                                 if (childConditions.size() > 0) {
    250                                                         condition = TagConditionLogic.and(childConditions);
    251                                                 } else {
    252                                                         throw new SAXException("<and> needs at least one child");
    253                                                 }
    254                                         } else if ("or".equals(openingName)) {
    255                                                 if (childConditions.size() > 0) {
    256                                                         condition = TagConditionLogic.or(childConditions);
    257                                                 } else {
    258                                                         throw new SAXException("<or> needs at least one child");
    259                                                 }
    260                                         } else if ("not".equals(openingName)) {
    261                                                 if (childConditions.size() == 1) {
    262                                                         condition = TagConditionLogic.not(childConditions.get(0));
    263                                                 } else {
    264                                                         throw new SAXException("<not> needs at least one child");
    265                                                 }
    266                                         }
    267 
    268                                         finished = true;
    269 
    270                                 } else {
    271                                         throw new SAXException("wrong closing tag " + name +
    272                                                         " (</" + openingName + "> expected");
    273                                 }
    274 
    275                         }
    276 
    277                 }
    278 
    279                 public boolean isFinished() {
    280                         return finished;
    281                 }
    282 
    283                 public TagCondition getCondition() {
    284                         if (!finished) {
    285                                 throw new IllegalStateException("condition " + openingName + " not yet finished");
    286                         } else {
    287                                 assert condition != null;
    288                                 return condition;
    289                         }
    290                 }
    291 
    292         }
     19    private final List<Implication> implications = new LinkedList<Implication>();
     20
     21    private static enum State {BEFORE_IMPLICATION, BEFORE_CONDITION, CONDITION, BEFORE_IMPLIES, IMPLIES, AFTER_IMPLIES};
     22    private State state = State.BEFORE_IMPLICATION;
     23
     24    private ConditionReader currentConditionReader;
     25    private TagCondition currentCondition;
     26    private Collection<Tag> currentImpliedTags;
     27
     28    boolean tagOpen = false;
     29
     30    public void startElement(String uri, String localName, String name, Attributes attributes)
     31    throws SAXException {
     32
     33        switch (state) {
     34
     35            case BEFORE_IMPLICATION:
     36
     37                if ("implication".equals(name)) {
     38                    state = State.BEFORE_CONDITION;
     39                    return;
     40                }
     41                break;
     42
     43            case BEFORE_CONDITION:
     44
     45                if ("condition".equals(name)) {
     46                    currentConditionReader = new ConditionReader();
     47                    state = State.CONDITION;
     48                    return;
     49                }
     50                break;
     51
     52            case CONDITION:
     53                currentConditionReader.startElement(uri, localName, name, attributes);
     54                return;
     55
     56            case BEFORE_IMPLIES:
     57
     58                if ("implies".equals(name)) {
     59                    currentImpliedTags = new LinkedList<Tag>();
     60                    state = State.IMPLIES;
     61                    return;
     62                }
     63                break;
     64
     65            case IMPLIES:
     66
     67                if ("tag".equals(name)) {
     68                    if (tagOpen) {
     69                        throw new SAXException("tag element inside other tag element");
     70                    }
     71                    currentImpliedTags.add(readTag(attributes));
     72                    tagOpen = true;
     73                    return;
     74                }
     75                break;
     76
     77        }
     78
     79        //all vaild paths end with return; reaching this indicates an invalid tag
     80        throw new SAXException("invalid opening xml tag <" + name + "> in state " + state);
     81
     82    }
     83
     84    public void endElement(String uri, String localName, String name)
     85    throws SAXException {
     86
     87        switch (state) {
     88
     89            case CONDITION:
     90
     91                if (name.equals("condition")) {
     92                    if (!currentConditionReader.isFinished()) {
     93                        throw new SAXException("condition isn't finished at </condition> tag");
     94                    } else {
     95                        currentCondition = currentConditionReader.getCondition();
     96                        currentConditionReader = null;
     97                        state = State.BEFORE_IMPLIES;
     98                        return;
     99                    }
     100                } else {
     101                    currentConditionReader.endElement(uri, localName, name);
     102                    return;
     103                }
     104
     105            case IMPLIES:
     106
     107                if (name.equals("implies")) {
     108                    state = State.AFTER_IMPLIES;
     109                    return;
     110                } else if (name.equals("tag")) {
     111                    if (!tagOpen) {
     112                        throw new SAXException("closing tag element that was not open");
     113                    }
     114                    tagOpen = false;
     115                    return;
     116                }
     117                break;
     118
     119            case AFTER_IMPLIES:
     120
     121                if (name.equals("implication")) {
     122                    implications.add(new Implication(currentCondition, currentImpliedTags));
     123                    currentCondition = null;
     124                    currentImpliedTags = null;
     125                    state = State.BEFORE_IMPLICATION;
     126                    return;
     127                }
     128                break;
     129
     130        }
     131
     132        //all vaild paths end with return; reaching this indicates an invalid tag
     133        throw new SAXException("invalid closing xml tag </" + name + "> in state " + state);
     134
     135    }
     136
     137    public List<Implication> getImplications() throws SAXException {
     138
     139        if (state != State.BEFORE_IMPLICATION) {
     140            throw new SAXException("some tags not been closed; now in state " + state);
     141        } else {
     142            return new ArrayList<Implication>(implications);
     143        }
     144    }
     145
     146    private static Tag readTag(Attributes attributes) throws SAXException {
     147
     148        String key = attributes.getValue("k");
     149        String value = attributes.getValue("v");
     150
     151        if (key == null) {
     152            throw new SAXException("tag without key");
     153        } else if (value == null) {
     154            throw new SAXException("tag without value (key is " + key + ")");
     155        }
     156
     157        return new Tag(key, value);
     158    }
     159
     160    private static String readKey(Attributes attributes) throws SAXException {
     161
     162        String key = attributes.getValue("k");
     163
     164        if (key == null) {
     165            throw new SAXException("key element without attribute k");
     166        }
     167
     168        return key;
     169    }
     170
     171    /**
     172    * class to be used for reading tag condition sections of xml files
     173    */
     174    private static class ConditionReader {
     175
     176        String openingName;
     177        TagCondition condition;
     178        boolean finished;
     179
     180        private final List<ConditionReader> childReaders = new LinkedList<ConditionReader>();
     181        private ConditionReader currentChildReader = null;
     182
     183        public void startElement(String uri, String localName, String name, Attributes attributes)
     184        throws SAXException {
     185
     186            if (finished) {
     187                throw new SAXException("condition is already finished at <" + name + ">");
     188            }
     189
     190            if (currentChildReader != null) {
     191                currentChildReader.startElement(uri, localName, name, attributes);
     192                return;
     193            }
     194
     195            //first tag is start tag of this condition
     196            if (openingName == null) {
     197
     198                openingName = name;
     199
     200                if ("tag".equals(name)) {
     201                    condition = TagConditionLogic.tag(readTag(attributes));
     202                } else if ("key".equals(name)) {
     203                    condition = TagConditionLogic.key(readKey(attributes));
     204                } else if (!("or".equals(name)) && !("and".equals(name)) && !("not".equals(name))) {
     205                    throw new SAXException("unknown tag for condition: " + name);
     206                }
     207
     208                //all tags after the first are start tags of child conditions
     209            } else {
     210
     211                if ("tag".equals(openingName) || "key".equals(openingName)) {
     212                    throw new SAXException("element must not have childs: " + openingName);
     213                }
     214
     215                currentChildReader = new ConditionReader();
     216                currentChildReader.startElement(uri, localName, name, attributes);
     217
     218            }
     219
     220        }
     221
     222        public void endElement(String uri, String localName, String name)
     223        throws SAXException {
     224
     225            if (finished) {
     226                throw new SAXException("condition is already finished at </" + name + ">");
     227            }
     228
     229            /* if active child reader exists, pass parameter to it. */
     230            if (currentChildReader != null) {
     231
     232                currentChildReader.endElement(uri, localName, name);
     233
     234                if (currentChildReader.isFinished()) {
     235                    childReaders.add(currentChildReader);
     236                    currentChildReader = null;
     237                }
     238
     239            } else {
     240
     241                if (openingName.equals(name)) {
     242
     243                    List<TagCondition> childConditions = new ArrayList<TagCondition>();
     244                    for (ConditionReader childReader : childReaders) {
     245                        childConditions.add(childReader.getCondition());
     246                    }
     247
     248                    if ("and".equals(openingName)) {
     249                        if (childConditions.size() > 0) {
     250                            condition = TagConditionLogic.and(childConditions);
     251                        } else {
     252                            throw new SAXException("<and> needs at least one child");
     253                        }
     254                    } else if ("or".equals(openingName)) {
     255                        if (childConditions.size() > 0) {
     256                            condition = TagConditionLogic.or(childConditions);
     257                        } else {
     258                            throw new SAXException("<or> needs at least one child");
     259                        }
     260                    } else if ("not".equals(openingName)) {
     261                        if (childConditions.size() == 1) {
     262                            condition = TagConditionLogic.not(childConditions.get(0));
     263                        } else {
     264                            throw new SAXException("<not> needs at least one child");
     265                        }
     266                    }
     267
     268                    finished = true;
     269
     270                } else {
     271                    throw new SAXException("wrong closing tag " + name +
     272                            " (</" + openingName + "> expected");
     273                }
     274
     275            }
     276
     277        }
     278
     279        public boolean isFinished() {
     280            return finished;
     281        }
     282
     283        public TagCondition getCondition() {
     284            if (!finished) {
     285                throw new IllegalStateException("condition " + openingName + " not yet finished");
     286            } else {
     287                assert condition != null;
     288                return condition;
     289            }
     290        }
     291
     292    }
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/RulesetAccessEvaluator.java

    r19216 r23189  
    1818public class RulesetAccessEvaluator<N, W, R, M> implements AccessEvaluator<N, W> {
    1919
    20         private final DataSource<N, W, R, M> dataSource;
    21         private final AccessRuleset ruleset;
    22         private final AccessParameters parameters;
     20    private final DataSource<N, W, R, M> dataSource;
     21    private final AccessRuleset ruleset;
     22    private final AccessParameters parameters;
    2323
    24         /**
    25         * @param dataSource  object that allows access to data objects and tags/members; != null
    26         * @param ruleset     ruleset that is used for evaluation; != null
    27         * @param parameters  parameters object that describes the vehicle
    28         *                    and situation to evaluate access for; != null
    29         */
    30         public RulesetAccessEvaluator(DataSource<N, W, R, M> dataSource, AccessRuleset ruleset, AccessParameters parameters) {
    31                 assert dataSource != null && ruleset != null && parameters != null;
     24    /**
     25    * @param dataSource  object that allows access to data objects and tags/members; != null
     26    * @param ruleset     ruleset that is used for evaluation; != null
     27    * @param parameters  parameters object that describes the vehicle
     28    *                    and situation to evaluate access for; != null
     29    */
     30    public RulesetAccessEvaluator(DataSource<N, W, R, M> dataSource, AccessRuleset ruleset, AccessParameters parameters) {
     31        assert dataSource != null && ruleset != null && parameters != null;
    3232
    33                 this.dataSource = dataSource;
    34                 this.ruleset = ruleset;
    35                 this.parameters = parameters;
     33        this.dataSource = dataSource;
     34        this.ruleset = ruleset;
     35        this.parameters = parameters;
    3636
    37         }
     37    }
    3838
    39         public boolean wayUsable(W way, boolean forward,
    40                         Map<RoadPropertyType<?>, Object> segmentPropertyValues) {
     39    public boolean wayUsable(W way, boolean forward,
     40            Map<RoadPropertyType<?>, Object> segmentPropertyValues) {
    4141
    42                 TagGroup wayTags = dataSource.getTagsW(way);
     42        TagGroup wayTags = dataSource.getTagsW(way);
    4343
    44                 TagGroup wayTagsWithImplications = new MapBasedTagGroup(wayTags);
    45                 for (Implication implication : ruleset.getImplications()) {
    46                         wayTagsWithImplications = implication.apply(wayTagsWithImplications);
    47                 }
     44        TagGroup wayTagsWithImplications = new MapBasedTagGroup(wayTags);
     45        for (Implication implication : ruleset.getImplications()) {
     46            wayTagsWithImplications = implication.apply(wayTagsWithImplications);
     47        }
    4848
    49                 /* check base tagging */
     49        /* check base tagging */
    5050
    51                 boolean usableWay = false;
    52                 for (Tag tag : ruleset.getBaseTags()) {
    53                         if (wayTags.contains(tag)) {
    54                                 usableWay = true;
    55                                 break;
    56                         }
    57                 }
     51        boolean usableWay = false;
     52        for (Tag tag : ruleset.getBaseTags()) {
     53            if (wayTags.contains(tag)) {
     54                usableWay = true;
     55                break;
     56            }
     57        }
    5858
    59                 if (!usableWay) {
    60                         return false;
    61                 }
     59        if (!usableWay) {
     60            return false;
     61        }
    6262
    63                 /* evaluate one-way tagging */
     63        /* evaluate one-way tagging */
    6464
    65                 String onewayValue =  wayTagsWithImplications.getValue("oneway");
     65        String onewayValue =  wayTagsWithImplications.getValue("oneway");
    6666
    67                 if (forward && "-1".equals(onewayValue)
    68                                 && !"foot".equals(parameters.getAccessClass())) {
    69                         return false;
    70                 }
     67        if (forward && "-1".equals(onewayValue)
     68                && !"foot".equals(parameters.getAccessClass())) {
     69            return false;
     70        }
    7171
    72                 if (!forward
    73                                 && ("1".equals(onewayValue) || "yes".equals(onewayValue) || "true".equals(onewayValue))
    74                                 && !"foot".equals(parameters.getAccessClass())) {
    75                         return false;
    76                 }
     72        if (!forward
     73                && ("1".equals(onewayValue) || "yes".equals(onewayValue) || "true".equals(onewayValue))
     74                && !"foot".equals(parameters.getAccessClass())) {
     75            return false;
     76        }
    7777
    78                 /* evaluate properties and access tagging */
     78        /* evaluate properties and access tagging */
    7979
    80                 return objectUsable(segmentPropertyValues, wayTags);
    81         }
     80        return objectUsable(segmentPropertyValues, wayTags);
     81    }
    8282
    83         public boolean nodeUsable(N node, Map<RoadPropertyType<?>,Object> roadPropertyValues) {
     83    public boolean nodeUsable(N node, Map<RoadPropertyType<?>,Object> roadPropertyValues) {
    8484
    85                 TagGroup nodeTags = dataSource.getTagsN(node);
     85        TagGroup nodeTags = dataSource.getTagsN(node);
    8686
    87                 return objectUsable(roadPropertyValues, nodeTags);
    88         };
     87        return objectUsable(roadPropertyValues, nodeTags);
     88    };
    8989
    90         private boolean objectUsable(Map<RoadPropertyType<?>, Object> roadPropertyValues,
    91                         TagGroup tags) {
     90    private boolean objectUsable(Map<RoadPropertyType<?>, Object> roadPropertyValues,
     91            TagGroup tags) {
    9292
    93                 /* evaluate road properties */
     93        /* evaluate road properties */
    9494
    95                 for (RoadPropertyType<?> property : roadPropertyValues.keySet()) {
    96                         if (!property.isUsable(roadPropertyValues.get(property), parameters)) {
    97                                 return false;
    98                         }
    99                 }
     95        for (RoadPropertyType<?> property : roadPropertyValues.keySet()) {
     96            if (!property.isUsable(roadPropertyValues.get(property), parameters)) {
     97                return false;
     98            }
     99        }
    100100
    101                 /* evaluate access type */
     101        /* evaluate access type */
    102102
    103                 AccessType accessType = UNDEFINED;
     103        AccessType accessType = UNDEFINED;
    104104
    105                 if (tags.size() > 0) {
     105        if (tags.size() > 0) {
    106106
    107                         Map<String, AccessType> accessTypePerClass =
    108                                 createAccessTypePerClassMap(tags, ruleset.getAccessHierarchyAncestors(parameters.getAccessClass()));
     107            Map<String, AccessType> accessTypePerClass =
     108                createAccessTypePerClassMap(tags, ruleset.getAccessHierarchyAncestors(parameters.getAccessClass()));
    109109
    110                         for (String accessClass : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
    111                                 accessType = accessTypePerClass.get(accessClass);
    112                                 if (accessType != UNDEFINED) { break; }
    113                         }
     110            for (String accessClass : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
     111                accessType = accessTypePerClass.get(accessClass);
     112                if (accessType != UNDEFINED) { break; }
     113            }
    114114
    115                 }
     115        }
    116116
    117                 return parameters.getAccessTypeUsable(accessType);
    118         }
     117        return parameters.getAccessTypeUsable(accessType);
     118    }
    119119
    120         private Map<String, AccessType> createAccessTypePerClassMap(
    121                         TagGroup wayTags, Collection<String> accessClasses) {
     120    private Map<String, AccessType> createAccessTypePerClassMap(
     121            TagGroup wayTags, Collection<String> accessClasses) {
    122122
    123                 /*
    124                 * create map and fill with UNDEFINED values
    125                 * (this also allows to use keySet instead of accessClasses later)
    126                 */
     123        /*
     124        * create map and fill with UNDEFINED values
     125        * (this also allows to use keySet instead of accessClasses later)
     126        */
    127127
    128                 Map<String, AccessType> accessTypePerClass = new HashMap<String, AccessType>();
     128        Map<String, AccessType> accessTypePerClass = new HashMap<String, AccessType>();
    129129
    130                 for (String accessClass : accessClasses) {
    131                         accessTypePerClass.put(accessClass, AccessType.UNDEFINED);
    132                 }
     130        for (String accessClass : accessClasses) {
     131            accessTypePerClass.put(accessClass, AccessType.UNDEFINED);
     132        }
    133133
    134                 /* evaluate implied tagging of base tag */
     134        /* evaluate implied tagging of base tag */
    135135
    136                 Tag baseTag = null;
    137                 for (Tag tag : wayTags) {
    138                         if (ruleset.getBaseTags().contains(tag)) {
    139                                 baseTag = tag;
    140                                 break;
    141                         }
    142                 }
     136        Tag baseTag = null;
     137        for (Tag tag : wayTags) {
     138            if (ruleset.getBaseTags().contains(tag)) {
     139                baseTag = tag;
     140                break;
     141            }
     142        }
    143143
    144                 if (baseTag != null) {
     144        if (baseTag != null) {
    145145
    146                         TagGroup tagsWithBaseImplications = new MapBasedTagGroup(baseTag);
    147                         for (Implication implication : ruleset.getImplications()) {
    148                                 tagsWithBaseImplications = implication.apply(tagsWithBaseImplications);
    149                         }
     146            TagGroup tagsWithBaseImplications = new MapBasedTagGroup(baseTag);
     147            for (Implication implication : ruleset.getImplications()) {
     148                tagsWithBaseImplications = implication.apply(tagsWithBaseImplications);
     149            }
    150150
    151                         setAccessTypesFromTags(accessTypePerClass, tagsWithBaseImplications);
     151            setAccessTypesFromTags(accessTypePerClass, tagsWithBaseImplications);
    152152
    153                 }
     153        }
    154154
    155                 /* evaluate implied tagging of other tags */
     155        /* evaluate implied tagging of other tags */
    156156
    157                 Map<String, String> tagMap = new HashMap<String, String>();
    158                 for (Tag tag : wayTags) {
    159                         if (!tag.equals(baseTag)) {
    160                                 tagMap.put(tag.key, tag.value);
    161                         }
    162                 }
     157        Map<String, String> tagMap = new HashMap<String, String>();
     158        for (Tag tag : wayTags) {
     159            if (!tag.equals(baseTag)) {
     160                tagMap.put(tag.key, tag.value);
     161            }
     162        }
    163163
    164                 TagGroup tagsWithOtherImplications = new MapBasedTagGroup(tagMap);
    165                 for (Implication implication : ruleset.getImplications()) {
    166                         tagsWithOtherImplications = implication.apply(tagsWithOtherImplications);
    167                 }
     164        TagGroup tagsWithOtherImplications = new MapBasedTagGroup(tagMap);
     165        for (Implication implication : ruleset.getImplications()) {
     166            tagsWithOtherImplications = implication.apply(tagsWithOtherImplications);
     167        }
    168168
    169                 setAccessTypesFromTags(accessTypePerClass, tagsWithOtherImplications);
     169        setAccessTypesFromTags(accessTypePerClass, tagsWithOtherImplications);
    170170
    171                 /* evaluate explicit access tagging */
     171        /* evaluate explicit access tagging */
    172172
    173                 for (String key : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
    174                         String value = wayTags.getValue(key);
    175                         if (value != null) {
    176                                 AccessType accessType = AccessType.getAccessType(value);
    177                                 accessTypePerClass.put(key, accessType);
    178                         }
    179                 }
     173        for (String key : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
     174            String value = wayTags.getValue(key);
     175            if (value != null) {
     176                AccessType accessType = AccessType.getAccessType(value);
     177                accessTypePerClass.put(key, accessType);
     178            }
     179        }
    180180
    181                 return accessTypePerClass;
    182         }
     181        return accessTypePerClass;
     182    }
    183183
    184         /**
    185         * adds all access information from a collection of tags to a [access class -> access type] map.
    186         * Existing entries will be replaced.
    187         */
    188         private void setAccessTypesFromTags(Map<String, AccessType> accessTypePerClass, TagGroup tags) {
    189                 for (String accessClass : accessTypePerClass.keySet()) {
    190                         String value = tags.getValue(accessClass);
    191                         if (value != null) {
    192                                 AccessType accessType = AccessType.getAccessType(value);
    193                                 accessTypePerClass.put(accessClass, accessType);
    194                         }
    195                 }
    196         }
     184    /**
     185    * adds all access information from a collection of tags to a [access class -> access type] map.
     186    * Existing entries will be replaced.
     187    */
     188    private void setAccessTypesFromTags(Map<String, AccessType> accessTypePerClass, TagGroup tags) {
     189        for (String accessClass : accessTypePerClass.keySet()) {
     190            String value = tags.getValue(accessClass);
     191            if (value != null) {
     192                AccessType accessType = AccessType.getAccessType(value);
     193                accessTypePerClass.put(accessClass, accessType);
     194            }
     195        }
     196    }
    197197
    198198}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/DataSource.java

    r19216 r23189  
    99 */
    1010public interface DataSource<N, W, R, M> {
    11        
    12         /** returns all nodes */
    13         public Iterable<N> getNodes();
    1411
    15         /** returns all ways */
    16         public Iterable<W> getWays();
     12    /** returns all nodes */
     13    public Iterable<N> getNodes();
    1714
    18         /** returns all relations */
    19         public Iterable<R> getRelations();
     15    /** returns all ways */
     16    public Iterable<W> getWays();
    2017
    21         /** returns a node's latitude */
    22         public double getLat(N node);
     18    /** returns all relations */
     19    public Iterable<R> getRelations();
    2320
    24         /** returns a node's longitude */
    25         public double getLon(N node);
     21    /** returns a node's latitude */
     22    public double getLat(N node);
    2623
    27         /** returns a way's nodes */
    28         public Iterable<N> getNodes(W way);
     24    /** returns a node's longitude */
     25    public double getLon(N node);
    2926
    30         /** returns a relation's members */
    31         public Iterable<M> getMembers(R relation);
     27    /** returns a way's nodes */
     28    public Iterable<N> getNodes(W way);
    3229
    33         /** returns a node's tags */
    34         public TagGroup getTagsN(N node);
     30    /** returns a relation's members */
     31    public Iterable<M> getMembers(R relation);
    3532
    36         /** returns a way's tags */
    37         public TagGroup getTagsW(W way);
     33    /** returns a node's tags */
     34    public TagGroup getTagsN(N node);
    3835
    39         /** returns a relation's tags */
    40         public TagGroup getTagsR(R relation);
     36    /** returns a way's tags */
     37    public TagGroup getTagsW(W way);
    4138
    42         /** returns a relation member's role */
    43         public String getRole(M member);
     39    /** returns a relation's tags */
     40    public TagGroup getTagsR(R relation);
    4441
    45         /** returns a relation member's member object */
    46         public Object getMember(M member);
    47        
    48         /** returns whether a relation member is a node */
    49         public boolean isNMember(M member);
    50        
    51         /** returns whether a relation member is a way */
    52         public boolean isWMember(M member);
    53        
    54         /** returns whether a relation member is a relation */
    55         public boolean isRMember(M member);
    56        
    57         /**
    58          * adds an observer.
    59          * Does nothing if the parameter is already an observer of this DataSource.
    60          *
    61          * @param observer  observer object, != null
    62          */
    63         public void addObserver(DataSourceObserver observer);
     42    /** returns a relation member's role */
     43    public String getRole(M member);
    6444
    65         /**
    66          * deletes an observer that has been added using {@link #addObserver(DataSourceObserver)}.
    67          * Does nothing if the parameter isn't currently an observer of this DataSource.
    68          *
    69          * @param observer  observer object, != null
    70          */
    71         public void deleteObserver(DataSourceObserver observer);
     45    /** returns a relation member's member object */
     46    public Object getMember(M member);
     47
     48    /** returns whether a relation member is a node */
     49    public boolean isNMember(M member);
     50
     51    /** returns whether a relation member is a way */
     52    public boolean isWMember(M member);
     53
     54    /** returns whether a relation member is a relation */
     55    public boolean isRMember(M member);
     56
     57    /**
     58     * adds an observer.
     59     * Does nothing if the parameter is already an observer of this DataSource.
     60     *
     61     * @param observer  observer object, != null
     62     */
     63    public void addObserver(DataSourceObserver observer);
     64
     65    /**
     66     * deletes an observer that has been added using {@link #addObserver(DataSourceObserver)}.
     67     * Does nothing if the parameter isn't currently an observer of this DataSource.
     68     *
     69     * @param observer  observer object, != null
     70     */
     71    public void deleteObserver(DataSourceObserver observer);
    7272
    7373}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/DataSourceObserver.java

    r19216 r23189  
    88public interface DataSourceObserver {
    99
    10         /**
    11         * informs this observer about changes in an observed data source
    12         * @param dataSource  observed data source that has changed; != null
    13         */
    14         public void update(DataSource<?, ?, ?, ?> dataSource);
     10    /**
     11    * informs this observer about changes in an observed data source
     12    * @param dataSource  observed data source that has changed; != null
     13    */
     14    public void update(DataSource<?, ?, ?, ?> dataSource);
    1515
    1616}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/MapBasedTagGroup.java

    r16520 r23189  
    1313public class MapBasedTagGroup implements TagGroup {
    1414
    15         private final Map<String, String> tagMap;
     15    private final Map<String, String> tagMap;
    1616
    17         /**
    18         * @param tagMap  map from keys to values; != null;
    19         *                must not be modified after being used as parameter
    20         */
    21         public MapBasedTagGroup(Map<String, String> tagMap) {
    22                 if (tagMap == null) {
    23                         throw new IllegalArgumentException();
    24                 }
     17    /**
     18    * @param tagMap  map from keys to values; != null;
     19    *                must not be modified after being used as parameter
     20    */
     21    public MapBasedTagGroup(Map<String, String> tagMap) {
     22        if (tagMap == null) {
     23            throw new IllegalArgumentException();
     24        }
    2525
    26                 this.tagMap = tagMap;
    27         }
     26        this.tagMap = tagMap;
     27    }
    2828
    29         /**
    30         * @param tags  tags to add to the group; != null, each != null
    31         */
    32         public MapBasedTagGroup(Iterable<Tag> tags) {
    33                 if (tags == null) {
    34                         throw new IllegalArgumentException();
    35                 }
    36                 this.tagMap = new HashMap<String, String>();
    37                 for (Tag tag : tags) {
    38                         if (tag == null) {
    39                                 throw new IllegalArgumentException();
    40                         } else {
    41                                 this.tagMap.put(tag.key, tag.value);
    42                         }
    43                 }
    44         }
     29    /**
     30    * @param tags  tags to add to the group; != null, each != null
     31    */
     32    public MapBasedTagGroup(Iterable<Tag> tags) {
     33        if (tags == null) {
     34            throw new IllegalArgumentException();
     35        }
     36        this.tagMap = new HashMap<String, String>();
     37        for (Tag tag : tags) {
     38            if (tag == null) {
     39                throw new IllegalArgumentException();
     40            } else {
     41                this.tagMap.put(tag.key, tag.value);
     42            }
     43        }
     44    }
    4545
    46         /**
    47         * @param tags  tags to add to the group; each != null
    48         */
    49         public MapBasedTagGroup(Tag... tags) {
    50                 this.tagMap = new HashMap<String, String>(tags.length);
    51                 for (Tag tag : tags) {
    52                         if (tag == null) {
    53                                 throw new IllegalArgumentException();
    54                         } else {
    55                                 this.tagMap.put(tag.key, tag.value);
    56                         }
    57                 }
    58         }
     46    /**
     47    * @param tags  tags to add to the group; each != null
     48    */
     49    public MapBasedTagGroup(Tag... tags) {
     50        this.tagMap = new HashMap<String, String>(tags.length);
     51        for (Tag tag : tags) {
     52            if (tag == null) {
     53                throw new IllegalArgumentException();
     54            } else {
     55                this.tagMap.put(tag.key, tag.value);
     56            }
     57        }
     58    }
    5959
    60         public String getValue(String key) {
    61                 assert key != null;
    62                 return tagMap.get(key);
    63         }
     60    public String getValue(String key) {
     61        assert key != null;
     62        return tagMap.get(key);
     63    }
    6464
    65         public boolean containsKey(String key) {
    66                 assert key != null;
    67                 return tagMap.containsKey(key);
    68         }
     65    public boolean containsKey(String key) {
     66        assert key != null;
     67        return tagMap.containsKey(key);
     68    }
    6969
    70         public boolean containsValue(String value) {
    71                 assert value != null;
    72                 return tagMap.containsValue(value);
    73         }
     70    public boolean containsValue(String value) {
     71        assert value != null;
     72        return tagMap.containsValue(value);
     73    }
    7474
    75         public boolean contains(Tag tag) {
    76                 assert tag != null;
    77                 return tag.value.equals(tagMap.get(tag.key));
    78         }
     75    public boolean contains(Tag tag) {
     76        assert tag != null;
     77        return tag.value.equals(tagMap.get(tag.key));
     78    }
    7979
    80         public int size() {
    81                 return tagMap.size();
    82         }
     80    public int size() {
     81        return tagMap.size();
     82    }
    8383
    84         /**
    85         * returns an Iterator providing access to all Tags.
    86         * The Iterator does not support the {@link Iterator#remove()} method.
    87         */
    88         public Iterator<Tag> iterator() {
     84    /**
     85    * returns an Iterator providing access to all Tags.
     86    * The Iterator does not support the {@link Iterator#remove()} method.
     87    */
     88    public Iterator<Tag> iterator() {
    8989
    90                 Collection<Tag> tagCollection = new LinkedList<Tag>();
     90        Collection<Tag> tagCollection = new LinkedList<Tag>();
    9191
    92                 for (String key : tagMap.keySet()) {
    93                         tagCollection.add(new Tag(key, tagMap.get(key)));
    94                 }
     92        for (String key : tagMap.keySet()) {
     93            tagCollection.add(new Tag(key, tagMap.get(key)));
     94        }
    9595
    96                 return Collections.unmodifiableCollection(tagCollection).iterator();
     96        return Collections.unmodifiableCollection(tagCollection).iterator();
    9797
    98         }
     98    }
    9999
    100         @Override
    101         public String toString() {
    102                 return tagMap.toString();
    103         }
     100    @Override
     101    public String toString() {
     102        return tagMap.toString();
     103    }
    104104
    105105}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/Tag.java

    r16520 r23189  
    66public class Tag {
    77
    8         /** key of the tag; != null */
    9         public final String key;
     8    /** key of the tag; != null */
     9    public final String key;
    1010
    11         /** value of the tag; != null */
    12         public final String value;
     11    /** value of the tag; != null */
     12    public final String value;
    1313
    14         public Tag(String key, String value) {
    15                 assert key != null && value != null;
    16                 this.key = key;
    17                 this.value = value;
    18         }
     14    public Tag(String key, String value) {
     15        assert key != null && value != null;
     16        this.key = key;
     17        this.value = value;
     18    }
    1919
    20         @Override
    21         public boolean equals(Object obj) {
    22                 if (!(obj instanceof Tag)) {
    23                         return false;
    24                 } else {
    25                         Tag otherTag = (Tag)obj;
    26                         return key.equals(otherTag.key) && value.equals(otherTag.value);
    27                 }
    28         }
     20    @Override
     21    public boolean equals(Object obj) {
     22        if (!(obj instanceof Tag)) {
     23            return false;
     24        } else {
     25            Tag otherTag = (Tag)obj;
     26            return key.equals(otherTag.key) && value.equals(otherTag.value);
     27        }
     28    }
    2929
    30         @Override
    31         public int hashCode() {
    32                 return key.hashCode() + value.hashCode();
    33         }
     30    @Override
     31    public int hashCode() {
     32        return key.hashCode() + value.hashCode();
     33    }
    3434
    35         @Override
    36         public String toString() {
    37                 return key + "=" + value;
    38         }
     35    @Override
     36    public String toString() {
     37        return key + "=" + value;
     38    }
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/TagGroup.java

    r16520 r23189  
    88public interface TagGroup extends Iterable<Tag> {
    99
    10         /**
    11         * returns the value for the given key or null if no tag in this group uses that key
    12         * @param key  key whose value will be returned; != null
    13         */
    14         public String getValue(String key);
     10    /**
     11    * returns the value for the given key or null if no tag in this group uses that key
     12    * @param key  key whose value will be returned; != null
     13    */
     14    public String getValue(String key);
    1515
    16         /**
    17         * returns true if this tag group contains a tag with the given key
    18         * @param key  key to check for; != null
    19         */
    20         public boolean containsKey(String key);
     16    /**
     17    * returns true if this tag group contains a tag with the given key
     18    * @param key  key to check for; != null
     19    */
     20    public boolean containsKey(String key);
    2121
    22         /**
    23         * returns true if this tag group contains at least one tag with the given value
    24         * @param value  value to check for; != null
    25         */
    26         public boolean containsValue(String value);
     22    /**
     23    * returns true if this tag group contains at least one tag with the given value
     24    * @param value  value to check for; != null
     25    */
     26    public boolean containsValue(String value);
    2727
    28         /**
    29         * returns true if this tag group contains the given tag
    30         * @param tag  tag to check for; != null
    31         */
    32         public boolean contains(Tag tag);
     28    /**
     29    * returns true if this tag group contains the given tag
     30    * @param tag  tag to check for; != null
     31    */
     32    public boolean contains(Tag tag);
    3333
    34         /**
    35         * returns the number of tags in this group
    36         */
    37         public int size();
     34    /**
     35    * returns the number of tags in this group
     36    */
     37    public int size();
    3838
    3939}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/ConnectorEvaluationGroup.java

    r18130 r23189  
    1616public class ConnectorEvaluationGroup extends EvaluationGroup {
    1717
    18         private final Set<Segment> segments;
    19         private final List<SegmentNode> borderNodes;
     18    private final Set<Segment> segments;
     19    private final List<SegmentNode> borderNodes;
    2020
    21         /**
    22         * @param segments     set of Segments, must not be modified
    23         *                     after being used as constructor parameter; != null
    24         * @param borderNodes  nodes that are used as starting/target nodes for sequences; != null
    25         */
    26         public ConnectorEvaluationGroup(Set<Segment> segments, Set<SegmentNode> borderNodes) {
    27                 assert segments != null && borderNodes != null;
     21    /**
     22    * @param segments     set of Segments, must not be modified
     23    *                     after being used as constructor parameter; != null
     24    * @param borderNodes  nodes that are used as starting/target nodes for sequences; != null
     25    */
     26    public ConnectorEvaluationGroup(Set<Segment> segments, Set<SegmentNode> borderNodes) {
     27        assert segments != null && borderNodes != null;
    2828
    29                 this.segments = segments;
    30                 this.borderNodes = new ArrayList<SegmentNode>(borderNodes);
    31         }
     29        this.segments = segments;
     30        this.borderNodes = new ArrayList<SegmentNode>(borderNodes);
     31    }
    3232
    33         /**
    34         * returns all nodes that can be used as start/target nodes
    35         * @return  border nodes; != null
    36         */
    37         public Collection<SegmentNode> getBorderNodes() {
    38                 return borderNodes;
    39         }
     33    /**
     34    * returns all nodes that can be used as start/target nodes
     35    * @return  border nodes; != null
     36    */
     37    public Collection<SegmentNode> getBorderNodes() {
     38        return borderNodes;
     39    }
    4040
    41         /**
    42         * returns all segments in the group
    43         * @return  segment set; != null
    44         */
    45         public Set<Segment> getSegments() {
    46                 return segments;
    47         }
     41    /**
     42    * returns all segments in the group
     43    * @return  segment set; != null
     44    */
     45    public Set<Segment> getSegments() {
     46        return segments;
     47    }
    4848
    49         /**
    50         * returns a segment sequence that runs from an inbound to an outbound
    51         * segment or null if no connection is possible.
    52         * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
    53         *
    54         * @param  startNode   start of the potential sequence; must be border node; != null
    55         * @param  targetNode  target of the potential sequence; must be border node; != null
    56         * @return             sequence of segments or null
    57         */
    58         public List<Segment> getSegmentSequence(SegmentNode startNode, SegmentNode targetNode) {
    59                 assert startNode != null && borderNodes.contains(startNode);
    60                 assert targetNode != null && borderNodes.contains(targetNode);
     49    /**
     50    * returns a segment sequence that runs from an inbound to an outbound
     51    * segment or null if no connection is possible.
     52    * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
     53    *
     54    * @param  startNode   start of the potential sequence; must be border node; != null
     55    * @param  targetNode  target of the potential sequence; must be border node; != null
     56    * @return             sequence of segments or null
     57    */
     58    public List<Segment> getSegmentSequence(SegmentNode startNode, SegmentNode targetNode) {
     59        assert startNode != null && borderNodes.contains(startNode);
     60        assert targetNode != null && borderNodes.contains(targetNode);
    6161
    62                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     62        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    6363
    64                 int inboundIndex = borderNodes.indexOf(startNode);
    65                 int outboundIndex = borderNodes.indexOf(targetNode);
     64        int inboundIndex = borderNodes.indexOf(startNode);
     65        int outboundIndex = borderNodes.indexOf(targetNode);
    6666
    67                 return segmentSequences[inboundIndex][outboundIndex];
    68         }
     67        return segmentSequences[inboundIndex][outboundIndex];
     68    }
    6969
    70         @Override
    71         protected void evaluateImpl(Collection<Restriction> restrictions) {
     70    @Override
     71    protected void evaluateImpl(Collection<Restriction> restrictions) {
    7272
    73                 /* find segment sequences from inbound to outbound segments */
     73        /* find segment sequences from inbound to outbound segments */
    7474
    75                 @SuppressWarnings("unchecked") //cannot create generic array without cast
    76                 List<Segment>[][] sequenceArray = new List[borderNodes.size()][borderNodes.size()];
     75        @SuppressWarnings("unchecked") //cannot create generic array without cast
     76        List<Segment>[][] sequenceArray = new List[borderNodes.size()][borderNodes.size()];
    7777
    78                 for (int startIndex = 0; startIndex < borderNodes.size(); startIndex ++) {
    79                         for (int targetIndex = 0; targetIndex < borderNodes.size(); targetIndex ++) {
     78        for (int startIndex = 0; startIndex < borderNodes.size(); startIndex ++) {
     79            for (int targetIndex = 0; targetIndex < borderNodes.size(); targetIndex ++) {
    8080
    81                                 List<Segment> sequence =
    82                                         findSegmentSequence(borderNodes.get(startIndex),
    83                                                         borderNodes.get(targetIndex), restrictions);
     81                List<Segment> sequence =
     82                    findSegmentSequence(borderNodes.get(startIndex),
     83                            borderNodes.get(targetIndex), restrictions);
    8484
    85                                 sequenceArray[startIndex][targetIndex] = sequence;
     85                sequenceArray[startIndex][targetIndex] = sequence;
    8686
    87                         }
    88                 }
     87            }
     88        }
    8989
    90                 segmentSequences = sequenceArray;
    91         }
     90        segmentSequences = sequenceArray;
     91    }
    9292
    93         @Override
    94         protected boolean isUsableNode(SegmentNode node) {
    95                 return shareElement(segments, node.getInboundSegments())
    96                 || shareElement(segments, node.getOutboundSegments());
    97         }
     93    @Override
     94    protected boolean isUsableNode(SegmentNode node) {
     95        return shareElement(segments, node.getInboundSegments())
     96        || shareElement(segments, node.getOutboundSegments());
     97    }
    9898
    99         @Override
    100         protected boolean isUsableSegment(Segment segment) {
    101                 return segments.contains(segment);
    102         }
     99    @Override
     100    protected boolean isUsableSegment(Segment segment) {
     101        return segments.contains(segment);
     102    }
    103103
    104         @Override
    105         public String toString() {
    106                 return "ConnectorEG " + segments;
    107         }
     104    @Override
     105    public String toString() {
     106        return "ConnectorEG " + segments;
     107    }
    108108
    109109}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/EvaluationGroup.java

    r16520 r23189  
    1919abstract class EvaluationGroup {
    2020
    21         protected boolean evaluated = false;
    22 
    23         /**
    24         * array of sequences.
    25         * First index is inbound segment/start node index,
    26         * second index is outbound segment/target node index.
    27         * Will contain the segment sequence after evaluation or null if none exists.
    28         */
    29         protected List<Segment>[][] segmentSequences;
    30 
    31         private static final List<Segment> EMPTY_SEGMENT_LIST =
    32                 Collections.unmodifiableList(new ArrayList<Segment>(0));
    33 
    34         private static final List<Restriction> EMPTY_RESTRICTION_LIST =
    35                 Collections.unmodifiableList(new ArrayList<Restriction>(0));
    36 
    37         private static class State {
    38                 SegmentNode currentNode;
    39                 Set<SegmentNode> visitedNodes;
    40                 Collection<Restriction> activeRestrictions;
    41                 List<Segment> segmentHistory;
    42         }
    43 
    44 
    45         /**
    46         * tries to find a legal sequence of segments between two segment nodes.
    47         *
    48         * @return  list of segments if connection is possible, null otherwise.
    49         */
    50         protected List<Segment> findSegmentSequence(
    51                         SegmentNode firstNode, SegmentNode lastNode,
    52                         Collection<Restriction> restrictions) {
    53 
    54                 return findSegmentSequence(firstNode, lastNode, restrictions,
    55                                 EMPTY_RESTRICTION_LIST, EMPTY_RESTRICTION_LIST);
    56 
    57         }
    58 
    59         /**
    60         * tries to find a legal sequence of segments between two segments.
    61         *
    62         * @return  list of segments if connection is possible, null otherwise.
    63         *          The list does NOT include firstSegment and lastSegment,
    64         *          but they are considered for restrictions.
    65         */
    66         protected List<Segment> findSegmentSequence(
    67                         Segment firstSegment, Segment lastSegment,
    68                         Collection<Restriction> restrictions) {
    69 
    70                 if (firstSegment == lastSegment) {
    71 
    72                         return EMPTY_SEGMENT_LIST;
    73 
    74                 } else {
    75 
    76                         Collection<Restriction> initiallyActiveRestrictions =
    77                                 activeRestrictionsAfterSegment(firstSegment, EMPTY_RESTRICTION_LIST, restrictions);
    78 
    79                         Collection<Restriction> restrictionsForbiddenAtLastNode = new HashSet<Restriction>();
    80                         for (Restriction restriction : restrictions) {
    81                                 if (restriction.getTos().contains(lastSegment)) {
    82                                         restrictionsForbiddenAtLastNode.add(restriction);
    83                                 }
    84                         }
    85 
    86                         return findSegmentSequence(
    87                                         firstSegment.getNode2(), lastSegment.getNode1(), restrictions,
    88                                         initiallyActiveRestrictions, restrictionsForbiddenAtLastNode);
    89                 }
    90 
    91         }
    92 
    93         /**
    94         * tries to find a legal sequence of segments between two segment nodes.
    95         *
    96         * @param restrictions  all restrictions that have to be taken into account
    97         * @param initiallyActiveRestrictions  restrictions that are already active at firstNode
    98         * @param restrictionsForbiddenAtLastNode  restrictions that must NOT be active at lastNode
    99         * @return  list of segments if connection is possible, null otherwise.
    100         */
    101         private List<Segment> findSegmentSequence(
    102                         SegmentNode firstNode, SegmentNode lastNode,
    103                         Collection<Restriction> restrictions,
    104                         Collection<Restriction> initiallyActiveRestrictions,
    105                         Collection<Restriction> restrictionsForbiddenAtLastNode) {
    106 
    107                 if (firstNode == lastNode
    108                                 && !shareElement(initiallyActiveRestrictions, restrictionsForbiddenAtLastNode)) {
    109                         return EMPTY_SEGMENT_LIST;
    110                 }
    111 
    112                 Queue<State> stateQueue = new LinkedList<State>();
    113                 stateQueue.add(createStartingState(firstNode, initiallyActiveRestrictions));
    114 
    115                 /* search for a possible segment sequence */
    116 
    117                 while (stateQueue.size() > 0) {
    118 
    119                         State state = stateQueue.poll();
    120 
    121                         Collection<State> subsequentStates = createSubsequentStates(state, restrictions);
    122 
    123                         for (State subsequentState : subsequentStates) {
    124                                 if (subsequentState.currentNode == lastNode
    125                                                 && !shareElement(subsequentState.activeRestrictions,
    126                                                                 restrictionsForbiddenAtLastNode)) {
    127                                         return subsequentState.segmentHistory;
    128                                 }
    129                         }
    130 
    131                         stateQueue.addAll(subsequentStates);
    132 
    133                 }
    134 
    135                 return null;
    136         }
    137 
    138         private static State createStartingState(SegmentNode firstNode,
    139                         Collection<Restriction> initiallyActiveRestrictions) {
    140 
    141                 State startingState = new State();
    142                 startingState.currentNode = firstNode;
    143                 startingState.activeRestrictions = initiallyActiveRestrictions;
    144                 startingState.segmentHistory = EMPTY_SEGMENT_LIST;
    145                 startingState.visitedNodes = new HashSet<SegmentNode>();
    146                 startingState.visitedNodes.add(firstNode);
    147 
    148                 return startingState;
    149         }
    150 
    151         private List<State> createSubsequentStates(State state, Collection<Restriction> allRestrictions) {
    152 
    153                 List<State> subsequentStates = new ArrayList<State>();
    154 
    155                 for (Segment segment : state.currentNode.getOutboundSegments()) {
    156 
    157                         if (isUsableSegment(segment) &&
    158                                         isLegalSegment(segment, state.activeRestrictions)) {
    159 
    160                                 State newState = new State();
    161 
    162                                 newState.activeRestrictions = activeRestrictionsAfterSegment(
    163                                                 segment, state.activeRestrictions, allRestrictions);
    164 
    165                                 newState.segmentHistory = new ArrayList<Segment>(state.segmentHistory.size() + 1);
    166                                 newState.segmentHistory.addAll(state.segmentHistory);
    167                                 newState.segmentHistory.add(segment);
    168 
    169                                 newState.currentNode = segment.getNode2();
    170 
    171                                 newState.visitedNodes = new HashSet<SegmentNode>(state.visitedNodes);
    172                                 newState.visitedNodes.add(newState.currentNode);
    173 
    174                                 /* add state to queue,
    175                                 * but avoid cycles as well as leaving the node set
    176                                 */
    177 
    178                                 if (!state.visitedNodes.contains(newState.currentNode)
    179                                                 && isUsableNode(newState.currentNode)) {
    180 
    181                                         subsequentStates.add(newState);
    182 
    183                                 }
    184                         }
    185                 }
    186 
    187                 return subsequentStates;
    188         }
    189 
    190         /**
    191         * returns all restrictions from a collection that have a segment as from member
    192         * @return  segment list; != null; must not be modified.
    193         *          May throw an exception when modifying is attempted.
    194         */
    195         private static List<Restriction> getRestrictionsStartedBySegment(
    196                         Collection<Restriction> restrictions, Segment segment) {
    197 
    198                 List<Restriction> result = EMPTY_RESTRICTION_LIST;
    199                 for (Restriction restriction : restrictions) {
    200                         if (restriction.getFrom() == segment) {
    201                                 if (result == EMPTY_RESTRICTION_LIST) {
    202                                         result = new ArrayList<Restriction>(restrictions.size());
    203                                 }
    204                                 result.add(restriction);
    205                         }
    206                 }
    207 
    208                 return result;
    209         }
    210 
    211         private static Collection<Restriction> activeRestrictionsAfterSegment(Segment segment,
    212                         Collection<Restriction> activeRestrictionsBeforeSegment,
    213                         Collection<Restriction> allRestrictions) {
    214 
    215                 Collection<Restriction> result = EMPTY_RESTRICTION_LIST;
    216 
    217                 for (Restriction restriction : activeRestrictionsBeforeSegment) {
    218                         if (restriction.getVias().contains(segment)) {
    219                                 if (result == EMPTY_RESTRICTION_LIST) {
    220                                         result = new ArrayList<Restriction>(allRestrictions.size());
    221                                 }
    222                                 result.add(restriction);
    223                         }
    224                 }
    225 
    226                 Collection<Restriction> newRestrictions =
    227                         getRestrictionsStartedBySegment(allRestrictions, segment);
    228 
    229                 if (newRestrictions.size() > 0) {
    230                         if (result == EMPTY_RESTRICTION_LIST) {
    231                                 result = newRestrictions;
    232                         } else {
    233                                 result.addAll(newRestrictions);
    234                         }
    235                 }
    236 
    237                 return result;
    238         }
    239 
    240         private static boolean isLegalSegment(
    241                         Segment segment, Collection<Restriction> activeRestrictions) {
    242 
    243                 for (Restriction restriction : activeRestrictions) {
    244                         if (restriction.getTos().contains(segment)) {
    245                                 return false;
    246                         }
    247                 }
    248 
    249                 return true;
    250         }
    251 
    252         /** returns true iff at least one element is contained in both collections */
    253         protected static boolean shareElement(
    254                         Collection<?> collection1, Collection<?> collection2) {
    255                 for (Object element : collection1) {
    256                         if (collection2.contains(element)) {
    257                                 return true;
    258                         }
    259                 }
    260                 return false;
    261         }
    262 
    263         public final void evaluate(Collection<Restriction> restrictions) {
    264 
    265                 if (evaluated) { return; }
    266 
    267                 evaluateImpl(restrictions);
    268 
    269                 evaluated = true;
    270         }
    271 
    272         /**
    273         * finds in- and outbound segments (if necessary) and segment sequences.
    274         * After calling this method, the group must be correctly evaluated
    275         * (see {@link #isCorrectlyEvaluated()}).
    276         *
    277         * @param restrictions  restrictions that are used when determining possible connections,
    278         *                      will not be modified; != null
    279         */
    280         abstract protected void evaluateImpl(Collection<Restriction> restrictions);
    281 
    282         /**
    283         * returns whether a node can be used while finding a segment sequence
    284         * @param node  node to check; != null
    285         */
    286         abstract protected boolean isUsableNode(SegmentNode node);
    287 
    288         /**
    289         * returns whether a segment can be used while finding a segment sequence
    290         * @param segment  segment to check; != null
    291         */
    292         abstract protected boolean isUsableSegment(Segment segment);
     21    protected boolean evaluated = false;
     22
     23    /**
     24    * array of sequences.
     25    * First index is inbound segment/start node index,
     26    * second index is outbound segment/target node index.
     27    * Will contain the segment sequence after evaluation or null if none exists.
     28    */
     29    protected List<Segment>[][] segmentSequences;
     30
     31    private static final List<Segment> EMPTY_SEGMENT_LIST =
     32        Collections.unmodifiableList(new ArrayList<Segment>(0));
     33
     34    private static final List<Restriction> EMPTY_RESTRICTION_LIST =
     35        Collections.unmodifiableList(new ArrayList<Restriction>(0));
     36
     37    private static class State {
     38        SegmentNode currentNode;
     39        Set<SegmentNode> visitedNodes;
     40        Collection<Restriction> activeRestrictions;
     41        List<Segment> segmentHistory;
     42    }
     43
     44
     45    /**
     46    * tries to find a legal sequence of segments between two segment nodes.
     47    *
     48    * @return  list of segments if connection is possible, null otherwise.
     49    */
     50    protected List<Segment> findSegmentSequence(
     51            SegmentNode firstNode, SegmentNode lastNode,
     52            Collection<Restriction> restrictions) {
     53
     54        return findSegmentSequence(firstNode, lastNode, restrictions,
     55                EMPTY_RESTRICTION_LIST, EMPTY_RESTRICTION_LIST);
     56
     57    }
     58
     59    /**
     60    * tries to find a legal sequence of segments between two segments.
     61    *
     62    * @return  list of segments if connection is possible, null otherwise.
     63    *          The list does NOT include firstSegment and lastSegment,
     64    *          but they are considered for restrictions.
     65    */
     66    protected List<Segment> findSegmentSequence(
     67            Segment firstSegment, Segment lastSegment,
     68            Collection<Restriction> restrictions) {
     69
     70        if (firstSegment == lastSegment) {
     71
     72            return EMPTY_SEGMENT_LIST;
     73
     74        } else {
     75
     76            Collection<Restriction> initiallyActiveRestrictions =
     77                activeRestrictionsAfterSegment(firstSegment, EMPTY_RESTRICTION_LIST, restrictions);
     78
     79            Collection<Restriction> restrictionsForbiddenAtLastNode = new HashSet<Restriction>();
     80            for (Restriction restriction : restrictions) {
     81                if (restriction.getTos().contains(lastSegment)) {
     82                    restrictionsForbiddenAtLastNode.add(restriction);
     83                }
     84            }
     85
     86            return findSegmentSequence(
     87                    firstSegment.getNode2(), lastSegment.getNode1(), restrictions,
     88                    initiallyActiveRestrictions, restrictionsForbiddenAtLastNode);
     89        }
     90
     91    }
     92
     93    /**
     94    * tries to find a legal sequence of segments between two segment nodes.
     95    *
     96    * @param restrictions  all restrictions that have to be taken into account
     97    * @param initiallyActiveRestrictions  restrictions that are already active at firstNode
     98    * @param restrictionsForbiddenAtLastNode  restrictions that must NOT be active at lastNode
     99    * @return  list of segments if connection is possible, null otherwise.
     100    */
     101    private List<Segment> findSegmentSequence(
     102            SegmentNode firstNode, SegmentNode lastNode,
     103            Collection<Restriction> restrictions,
     104            Collection<Restriction> initiallyActiveRestrictions,
     105            Collection<Restriction> restrictionsForbiddenAtLastNode) {
     106
     107        if (firstNode == lastNode
     108                && !shareElement(initiallyActiveRestrictions, restrictionsForbiddenAtLastNode)) {
     109            return EMPTY_SEGMENT_LIST;
     110        }
     111
     112        Queue<State> stateQueue = new LinkedList<State>();
     113        stateQueue.add(createStartingState(firstNode, initiallyActiveRestrictions));
     114
     115        /* search for a possible segment sequence */
     116
     117        while (stateQueue.size() > 0) {
     118
     119            State state = stateQueue.poll();
     120
     121            Collection<State> subsequentStates = createSubsequentStates(state, restrictions);
     122
     123            for (State subsequentState : subsequentStates) {
     124                if (subsequentState.currentNode == lastNode
     125                        && !shareElement(subsequentState.activeRestrictions,
     126                                restrictionsForbiddenAtLastNode)) {
     127                    return subsequentState.segmentHistory;
     128                }
     129            }
     130
     131            stateQueue.addAll(subsequentStates);
     132
     133        }
     134
     135        return null;
     136    }
     137
     138    private static State createStartingState(SegmentNode firstNode,
     139            Collection<Restriction> initiallyActiveRestrictions) {
     140
     141        State startingState = new State();
     142        startingState.currentNode = firstNode;
     143        startingState.activeRestrictions = initiallyActiveRestrictions;
     144        startingState.segmentHistory = EMPTY_SEGMENT_LIST;
     145        startingState.visitedNodes = new HashSet<SegmentNode>();
     146        startingState.visitedNodes.add(firstNode);
     147
     148        return startingState;
     149    }
     150
     151    private List<State> createSubsequentStates(State state, Collection<Restriction> allRestrictions) {
     152
     153        List<State> subsequentStates = new ArrayList<State>();
     154
     155        for (Segment segment : state.currentNode.getOutboundSegments()) {
     156
     157            if (isUsableSegment(segment) &&
     158                    isLegalSegment(segment, state.activeRestrictions)) {
     159
     160                State newState = new State();
     161
     162                newState.activeRestrictions = activeRestrictionsAfterSegment(
     163                        segment, state.activeRestrictions, allRestrictions);
     164
     165                newState.segmentHistory = new ArrayList<Segment>(state.segmentHistory.size() + 1);
     166                newState.segmentHistory.addAll(state.segmentHistory);
     167                newState.segmentHistory.add(segment);
     168
     169                newState.currentNode = segment.getNode2();
     170
     171                newState.visitedNodes = new HashSet<SegmentNode>(state.visitedNodes);
     172                newState.visitedNodes.add(newState.currentNode);
     173
     174                /* add state to queue,
     175                * but avoid cycles as well as leaving the node set
     176                */
     177
     178                if (!state.visitedNodes.contains(newState.currentNode)
     179                        && isUsableNode(newState.currentNode)) {
     180
     181                    subsequentStates.add(newState);
     182
     183                }
     184            }
     185        }
     186
     187        return subsequentStates;
     188    }
     189
     190    /**
     191    * returns all restrictions from a collection that have a segment as from member
     192    * @return  segment list; != null; must not be modified.
     193    *          May throw an exception when modifying is attempted.
     194    */
     195    private static List<Restriction> getRestrictionsStartedBySegment(
     196            Collection<Restriction> restrictions, Segment segment) {
     197
     198        List<Restriction> result = EMPTY_RESTRICTION_LIST;
     199        for (Restriction restriction : restrictions) {
     200            if (restriction.getFrom() == segment) {
     201                if (result == EMPTY_RESTRICTION_LIST) {
     202                    result = new ArrayList<Restriction>(restrictions.size());
     203                }
     204                result.add(restriction);
     205            }
     206        }
     207
     208        return result;
     209    }
     210
     211    private static Collection<Restriction> activeRestrictionsAfterSegment(Segment segment,
     212            Collection<Restriction> activeRestrictionsBeforeSegment,
     213            Collection<Restriction> allRestrictions) {
     214
     215        Collection<Restriction> result = EMPTY_RESTRICTION_LIST;
     216
     217        for (Restriction restriction : activeRestrictionsBeforeSegment) {
     218            if (restriction.getVias().contains(segment)) {
     219                if (result == EMPTY_RESTRICTION_LIST) {
     220                    result = new ArrayList<Restriction>(allRestrictions.size());
     221                }
     222                result.add(restriction);
     223            }
     224        }
     225
     226        Collection<Restriction> newRestrictions =
     227            getRestrictionsStartedBySegment(allRestrictions, segment);
     228
     229        if (newRestrictions.size() > 0) {
     230            if (result == EMPTY_RESTRICTION_LIST) {
     231                result = newRestrictions;
     232            } else {
     233                result.addAll(newRestrictions);
     234            }
     235        }
     236
     237        return result;
     238    }
     239
     240    private static boolean isLegalSegment(
     241            Segment segment, Collection<Restriction> activeRestrictions) {
     242
     243        for (Restriction restriction : activeRestrictions) {
     244            if (restriction.getTos().contains(segment)) {
     245                return false;
     246            }
     247        }
     248
     249        return true;
     250    }
     251
     252    /** returns true iff at least one element is contained in both collections */
     253    protected static boolean shareElement(
     254            Collection<?> collection1, Collection<?> collection2) {
     255        for (Object element : collection1) {
     256            if (collection2.contains(element)) {
     257                return true;
     258            }
     259        }
     260        return false;
     261    }
     262
     263    public final void evaluate(Collection<Restriction> restrictions) {
     264
     265        if (evaluated) { return; }
     266
     267        evaluateImpl(restrictions);
     268
     269        evaluated = true;
     270    }
     271
     272    /**
     273    * finds in- and outbound segments (if necessary) and segment sequences.
     274    * After calling this method, the group must be correctly evaluated
     275    * (see {@link #isCorrectlyEvaluated()}).
     276    *
     277    * @param restrictions  restrictions that are used when determining possible connections,
     278    *                      will not be modified; != null
     279    */
     280    abstract protected void evaluateImpl(Collection<Restriction> restrictions);
     281
     282    /**
     283    * returns whether a node can be used while finding a segment sequence
     284    * @param node  node to check; != null
     285    */
     286    abstract protected boolean isUsableNode(SegmentNode node);
     287
     288    /**
     289    * returns whether a segment can be used while finding a segment sequence
     290    * @param segment  segment to check; != null
     291    */
     292    abstract protected boolean isUsableSegment(Segment segment);
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/GraphEdge.java

    r18130 r23189  
    1212public interface GraphEdge {
    1313
    14         /** returns the node this edge starts at; != null */
    15         GraphNode getStartNode();
     14    /** returns the node this edge starts at; != null */
     15    GraphNode getStartNode();
    1616
    17         /** returns the node this edge leads to; != null */
    18         GraphNode getTargetNode();
     17    /** returns the node this edge leads to; != null */
     18    GraphNode getTargetNode();
    1919
    20         /** returns all property types for which property values are available */
    21         Collection<GraphEdgePropertyType<?>> getAvailableProperties();
    22        
    23         /** TODO */
    24         <V> V getPropertyValue(GraphEdgePropertyType<V> property);
    25        
     20    /** returns all property types for which property values are available */
     21    Collection<GraphEdgePropertyType<?>> getAvailableProperties();
     22
     23    /** TODO */
     24    <V> V getPropertyValue(GraphEdgePropertyType<V> property);
     25
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/GraphNode.java

    r16520 r23189  
    1313public interface GraphNode {
    1414
    15         /**
    16         * returns all edges that lead to this GraphNode; != null
    17         */
    18         public Collection<GraphEdge> getInboundEdges();
     15    /**
     16    * returns all edges that lead to this GraphNode; != null
     17    */
     18    public Collection<GraphEdge> getInboundEdges();
    1919
    20         /**
    21         * returns all edges that start at this GraphNode; != null
    22         */
    23         public Collection<GraphEdge> getOutboundEdges();
     20    /**
     21    * returns all edges that start at this GraphNode; != null
     22    */
     23    public Collection<GraphEdge> getOutboundEdges();
    2424
    25         /**
    26         * returns the SegmentNode this GraphNode is based on
    27         *
    28         * @return  SegmentNode, must be one of the nodes of the Segment returned
    29         *          by {@link #getSegment()}; != null
    30         */
    31         public SegmentNode getSegmentNode();
     25    /**
     26    * returns the SegmentNode this GraphNode is based on
     27    *
     28    * @return  SegmentNode, must be one of the nodes of the Segment returned
     29    *          by {@link #getSegment()}; != null
     30    */
     31    public SegmentNode getSegmentNode();
    3232
    33         /**
    34         * returns the Segment this GraphNode is based on
    35         *
    36         * @return  Segment; != null
    37         */
    38         public Segment getSegment();
     33    /**
     34    * returns the Segment this GraphNode is based on
     35    *
     36    * @return  Segment; != null
     37    */
     38    public Segment getSegment();
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/JunctionEvaluationGroup.java

    r18130 r23189  
    1515public class JunctionEvaluationGroup extends EvaluationGroup {
    1616
    17         private final Set<SegmentNode> segmentNodes;
     17    private final Set<SegmentNode> segmentNodes;
    1818
    19         protected List<Segment> inboundSegments;
    20         protected List<Segment> outboundSegments;
     19    protected List<Segment> inboundSegments;
     20    protected List<Segment> outboundSegments;
    2121
    22         /**
    23         * @param segmentNodes  set of SegmentNodes, must not be modified
    24         *                      after being used as constructor parameter; != null
    25         */
    26         public JunctionEvaluationGroup(Set<SegmentNode> segmentNodes) {
    27                 assert segmentNodes != null;
    28                 this.segmentNodes = segmentNodes;
    29         }
     22    /**
     23    * @param segmentNodes  set of SegmentNodes, must not be modified
     24    *                      after being used as constructor parameter; != null
     25    */
     26    public JunctionEvaluationGroup(Set<SegmentNode> segmentNodes) {
     27        assert segmentNodes != null;
     28        this.segmentNodes = segmentNodes;
     29    }
    3030
    31         /**
    32         * returns all segments that can be used to enter this group.
    33         * {@link #evaluate(Iterable)} needs be called before this method.
    34         *
    35         * @return  segment collection; != null
    36         */
    37         public Collection<Segment> getInboundSegments() {
    38                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    39                 return inboundSegments;
    40         }
     31    /**
     32    * returns all segments that can be used to enter this group.
     33    * {@link #evaluate(Iterable)} needs be called before this method.
     34    *
     35    * @return  segment collection; != null
     36    */
     37    public Collection<Segment> getInboundSegments() {
     38        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     39        return inboundSegments;
     40    }
    4141
    42         /**
    43         * returns all segments that can be used to leave this group.
    44         * {@link #evaluate(Iterable)} needs be called before this method.
    45         *
    46         * @return  segment collection; != null
    47         */
    48         public Collection<Segment> getOutboundSegments() {
    49                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    50                 return outboundSegments;
    51         }
     42    /**
     43    * returns all segments that can be used to leave this group.
     44    * {@link #evaluate(Iterable)} needs be called before this method.
     45    *
     46    * @return  segment collection; != null
     47    */
     48    public Collection<Segment> getOutboundSegments() {
     49        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     50        return outboundSegments;
     51    }
    5252
    53         /**
    54         * returns a segment sequence that runs from an inbound to an outbound
    55         * segment or null if no connection is possible.
    56         * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
    57         *
    58         * @param  inboundSegment  start of the potential sequence;
    59         *                         must be inbound segment; != null
    60         * @param  outboundSegment target of the potential sequence;
    61         *                         must be outbound segment; != null
    62         * @return  sequence of segments or null
    63         */
    64         public List<Segment> getSegmentSequence(Segment inboundSegment, Segment outboundSegment) {
    65                 assert inboundSegment != null && inboundSegments.contains(inboundSegment);
    66                 assert outboundSegment != null && outboundSegments.contains(outboundSegment);
     53    /**
     54    * returns a segment sequence that runs from an inbound to an outbound
     55    * segment or null if no connection is possible.
     56    * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
     57    *
     58    * @param  inboundSegment  start of the potential sequence;
     59    *                         must be inbound segment; != null
     60    * @param  outboundSegment target of the potential sequence;
     61    *                         must be outbound segment; != null
     62    * @return  sequence of segments or null
     63    */
     64    public List<Segment> getSegmentSequence(Segment inboundSegment, Segment outboundSegment) {
     65        assert inboundSegment != null && inboundSegments.contains(inboundSegment);
     66        assert outboundSegment != null && outboundSegments.contains(outboundSegment);
    6767
    68                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     68        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    6969
    70                 int inboundIndex = inboundSegments.indexOf(inboundSegment);
    71                 int outboundIndex = outboundSegments.indexOf(outboundSegment);
     70        int inboundIndex = inboundSegments.indexOf(inboundSegment);
     71        int outboundIndex = outboundSegments.indexOf(outboundSegment);
    7272
    73                 return segmentSequences[inboundIndex][outboundIndex];
    74         }
     73        return segmentSequences[inboundIndex][outboundIndex];
     74    }
    7575
    76         @Override
    77         protected void evaluateImpl(final Collection<Restriction> restrictions) {
     76    @Override
     77    protected void evaluateImpl(final Collection<Restriction> restrictions) {
    7878
    79                 assert restrictions != null;
     79        assert restrictions != null;
    8080
    81                 /* find inbound and outbound segments. An inbound segment is a segment whose target
    82                 * is in the set and whose start node isn't (analogous for outbound segments)       */
     81        /* find inbound and outbound segments. An inbound segment is a segment whose target
     82        * is in the set and whose start node isn't (analogous for outbound segments)       */
    8383
    84                 inboundSegments = new ArrayList<Segment>();
    85                 outboundSegments = new ArrayList<Segment>();
     84        inboundSegments = new ArrayList<Segment>();
     85        outboundSegments = new ArrayList<Segment>();
    8686
    87                 for (SegmentNode segmentNode : segmentNodes) {
    88                         for (Segment segment : segmentNode.getInboundSegments()) {
    89                                 if (!segmentNodes.contains(segment.getNode1())) {
    90                                         inboundSegments.add(segment);
    91                                 }
    92                         }
    93                         for (Segment segment : segmentNode.getOutboundSegments()) {
    94                                 if (!segmentNodes.contains(segment.getNode2())) {
    95                                         outboundSegments.add(segment);
    96                                 }
    97                         }
    98                 }
     87        for (SegmentNode segmentNode : segmentNodes) {
     88            for (Segment segment : segmentNode.getInboundSegments()) {
     89                if (!segmentNodes.contains(segment.getNode1())) {
     90                    inboundSegments.add(segment);
     91                }
     92            }
     93            for (Segment segment : segmentNode.getOutboundSegments()) {
     94                if (!segmentNodes.contains(segment.getNode2())) {
     95                    outboundSegments.add(segment);
     96                }
     97            }
     98        }
    9999
    100                 /* find segment sequences from inbound to outbound segments */
     100        /* find segment sequences from inbound to outbound segments */
    101101
    102                 @SuppressWarnings("unchecked") //cannot create generic array without cast
    103                 List<Segment>[][] sequenceArray = new List[inboundSegments.size()][outboundSegments.size()];
     102        @SuppressWarnings("unchecked") //cannot create generic array without cast
     103        List<Segment>[][] sequenceArray = new List[inboundSegments.size()][outboundSegments.size()];
    104104
    105                 for (int inboundIndex = 0; inboundIndex < inboundSegments.size(); inboundIndex ++) {
    106                         for (int outboundIndex = 0; outboundIndex < outboundSegments.size(); outboundIndex ++) {
     105        for (int inboundIndex = 0; inboundIndex < inboundSegments.size(); inboundIndex ++) {
     106            for (int outboundIndex = 0; outboundIndex < outboundSegments.size(); outboundIndex ++) {
    107107
    108                                 List<Segment> sequence =
    109                                         findSegmentSequence(inboundSegments.get(inboundIndex),
    110                                                         outboundSegments.get(outboundIndex), restrictions);
     108                List<Segment> sequence =
     109                    findSegmentSequence(inboundSegments.get(inboundIndex),
     110                            outboundSegments.get(outboundIndex), restrictions);
    111111
    112                                 sequenceArray[inboundIndex][outboundIndex] = sequence;
     112                sequenceArray[inboundIndex][outboundIndex] = sequence;
    113113
    114                         }
    115                 }
     114            }
     115        }
    116116
    117                 segmentSequences = sequenceArray;
     117        segmentSequences = sequenceArray;
    118118
    119         }
     119    }
    120120
    121         @Override
    122         protected boolean isUsableNode(SegmentNode node) {
    123                 return segmentNodes.contains(node);
    124         }
     121    @Override
     122    protected boolean isUsableNode(SegmentNode node) {
     123        return segmentNodes.contains(node);
     124    }
    125125
    126         @Override
    127         protected boolean isUsableSegment(Segment segment) {
    128                 return segmentNodes.contains(segment.getNode1())
    129                 && segmentNodes.contains(segment.getNode2());
    130         }
     126    @Override
     127    protected boolean isUsableSegment(Segment segment) {
     128        return segmentNodes.contains(segment.getNode1())
     129        && segmentNodes.contains(segment.getNode2());
     130    }
    131131
    132         @Override
    133         public String toString() {
    134                 return "JunctionEG " + segmentNodes;
    135         }
     132    @Override
     133    public String toString() {
     134        return "JunctionEG " + segmentNodes;
     135    }
    136136}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/TSBasedWayGraph.java

    r18130 r23189  
    2323public class TSBasedWayGraph implements WayGraph, TransitionStructureObserver {
    2424
    25         private static final GraphEdgePropertyType<?>[] PROPERTY_TYPES =
    26                 {GraphEdgeSegments.PROPERTY};
    27                 //TODO: -> parameter
    28        
    29         private static class GraphNodeImpl implements GraphNode {
    30                 private final SegmentNode node;
    31                 private final Segment segment;
    32                 private final List<GraphEdge> incomingEdges = new ArrayList<GraphEdge>();
    33                 private final List<GraphEdge> outgoingEdges = new ArrayList<GraphEdge>();
    34                 public GraphNodeImpl(SegmentNode node, Segment segment) {
    35                         assert node != null && segment != null;
    36                         assert segment.getNode1() == node || segment.getNode2() == node;
    37                         this.node = node;
    38                         this.segment = segment;
    39                 }
    40                 public SegmentNode getSegmentNode() {
    41                         return node;
    42                 }
    43                 public Segment getSegment() {
    44                         return segment;
    45                 }
    46                 public void addIncomingEdge(GraphEdge edge) {
    47                         assert edge != null;
    48                         incomingEdges.add(edge);
    49                 }
    50                 public Collection<GraphEdge> getInboundEdges() {
    51                         return incomingEdges;
    52                 }
    53                 public void addOutgoingEdge(GraphEdge edge) {
    54                         assert edge != null;
    55                         outgoingEdges.add(edge);
    56                 }
    57                 public Collection<GraphEdge> getOutboundEdges() {
    58                         return outgoingEdges;
    59                 }
    60                 @Override
    61                 public String toString() {
    62                         return "(" + node + "; " + segment + ")";
    63                 }
    64         }
    65 
    66         private static class GraphEdgeImpl implements GraphEdge {
    67                
    68                 private final GraphNode startNode;
    69                 private final GraphNode targetNode;
    70                 private final Map<GraphEdgePropertyType<?>, Object> properties;
    71                
    72                 public GraphEdgeImpl(GraphNode startNode, GraphNode targetNode,
    73                                 Map<GraphEdgePropertyType<?>, Object> properties) {
    74                         assert startNode != null && targetNode != null && properties != null;
    75                         this.startNode = startNode;
    76                         this.targetNode = targetNode;
    77                         this.properties = properties;
    78                 }
    79                
    80                 public GraphNode getStartNode() {
    81                         return startNode;
    82                 }
    83                 public GraphNode getTargetNode() {
    84                         return targetNode;
    85                 }
    86                
    87                 public Collection<GraphEdgePropertyType<?>> getAvailableProperties() {
    88                         return properties.keySet();
    89                 }
    90                 public <V> V getPropertyValue(GraphEdgePropertyType<V> property) {
    91                         V result = (V) properties.get(property);
    92                         return result;
    93                 }
    94                
    95                 @Override
    96                 public String toString() {
    97                         return "(" + startNode + "-->" + targetNode + ")";
    98                 }
    99                
    100         };
    101 
    102         private final Set<WayGraphObserver> observers = new HashSet<WayGraphObserver>();
    103 
    104         private final TransitionStructure transitionStructure;
    105 
    106         private Collection<GraphNode> nodes;
    107         private List<GraphEdge> edges;
    108 
    109         /**
    110         * create a WayGraph based on a {@link TransitionStructure}
    111         * @param transitionStructure  transition structure this graph is to be based on; != null
    112         */
    113         public TSBasedWayGraph(TransitionStructure transitionStructure) {
    114                 assert transitionStructure != null;
    115 
    116                 this.transitionStructure = transitionStructure;
    117                 transitionStructure.addObserver(this);
    118 
    119                 createNodesAndEdges();
    120         }
    121 
    122         public Collection<GraphEdge> getEdges() {
    123                 return edges;
    124         }
    125 
    126         public Collection<GraphNode> getNodes() {
    127                 return nodes;
    128         }
    129 
    130         private void createNodesAndEdges() {
    131 
    132                 Collection<EvaluationGroup> evaluationGroups =
    133                         createEvaluationGroups(transitionStructure);
    134 
    135                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    136                         evaluationGroup.evaluate(transitionStructure.getRestrictions());
    137                 }
    138 
    139                 createNodesAndEdgesFromEvaluationGroups(evaluationGroups);
    140 
    141                 evaluationGroups = null;
    142         }
    143 
    144         private static Collection<EvaluationGroup> createEvaluationGroups(
    145                         TransitionStructure transitionStructure) {
    146 
    147                 Map<SegmentNode, Set<SegmentNode>> nodeSetMap =
    148                         new HashMap<SegmentNode, Set<SegmentNode>>();
    149 
    150                 /* first step: everything that is part of the same restriction goes into the same set */
    151 
    152                 for (Restriction restriction : transitionStructure.getRestrictions()) {
    153 
    154                         /* group every node in via segments (which includes the
    155                         * last node of from and the first node of to) into a set */
    156 
    157                         SegmentNode firstNode = restriction.getFrom().getNode2();
    158                         createSetIfHasNone(firstNode, nodeSetMap);
    159 
    160                         for (Segment segment : restriction.getVias()) {
    161                                 putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
    162                                 putInSameSet(segment.getNode2(), firstNode, nodeSetMap);
    163                         }
    164 
    165                         for (Segment segment : restriction.getTos()) {
    166                                 putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
    167                         }
    168 
    169                 }
    170 
    171                 /* second step: create own sets for each junction and end point
    172                 * (node connected with more than / less than two nodes). */
    173 
    174                 for (SegmentNode node : transitionStructure.getNodes()) {
    175 
    176                         if (!nodeSetMap.containsKey(node)
    177                                         && !isConnectedWithExactly2Nodes(node)) {
    178 
    179                                 createSetIfHasNone(node, nodeSetMap);
    180 
    181                         }
    182 
    183                 }
    184 
    185                 /* third step: create segment sets for all segments that are not in one of the node sets
    186                 * (that is, at least one node is not part of a junction evaluation group
    187                 *  or the nodes are part of different junction evaluation groups)  */
    188 
    189                 Map<Segment, Set<Segment>> segmentSetMap =
    190                         new HashMap<Segment, Set<Segment>>();
    191 
    192                 for (Segment segment : transitionStructure.getSegments()) {
    193 
    194                         SegmentNode node1 = segment.getNode1();
    195                         SegmentNode node2 = segment.getNode2();
    196 
    197                         if (!nodeSetMap.containsKey(node1) || !nodeSetMap.containsKey(node2)
    198                                         || nodeSetMap.get(node1) != nodeSetMap.get(node2)) {
    199 
    200                                 createSetIfHasNone(segment, segmentSetMap);
    201 
    202                                 for (Segment subsequentSegment : segment.getNode2().getOutboundSegments()) {
    203                                         if (!nodeSetMap.containsKey(node2)
    204                                                         || subsequentSegment.getNode2() == node1) {
    205                                                 putInSameSet(subsequentSegment, segment, segmentSetMap);
    206                                         }
    207                                 }
    208                                 //note that segments leading to this segment will share sets anyway,
    209                                 //because this segment is a subsequent segment of them
    210 
    211 
    212                         }
    213 
    214                 }
    215 
    216                 /* create EvaluationGroup objects */
    217 
    218                 Collection<EvaluationGroup> evaluationGroups =
    219                         new ArrayList<EvaluationGroup>(nodeSetMap.size() + segmentSetMap.size());
    220 
    221                 Set<Set<SegmentNode>> nodeSets = new HashSet<Set<SegmentNode>>(nodeSetMap.values());
    222                 for (Set<SegmentNode> nodeSet : nodeSets) {
    223                         evaluationGroups.add(new JunctionEvaluationGroup(nodeSet));
    224                 }
    225 
    226                 HashSet<Set<Segment>> hashSets = new HashSet<Set<Segment>>(segmentSetMap.values());
    227                 for (Set<Segment> segmentSet : hashSets) {
    228                         Set<SegmentNode> borderNodes = new HashSet<SegmentNode>();
    229                         for (Segment segment : segmentSet) {
    230                                 if (nodeSetMap.containsKey(segment.getNode1())) {
    231                                         borderNodes.add(segment.getNode1());
    232                                 }
    233                                 if (nodeSetMap.containsKey(segment.getNode2())) {
    234                                         borderNodes.add(segment.getNode2());
    235                                 }
    236                         }
    237                         evaluationGroups.add(new ConnectorEvaluationGroup(segmentSet, borderNodes));
    238                 }
    239 
    240                 return evaluationGroups;
    241         }
    242 
    243         private void createNodesAndEdgesFromEvaluationGroups(
    244                         Collection<EvaluationGroup> evaluationGroups) {
    245 
    246                 nodes = new LinkedList<GraphNode>();
    247                 edges = new LinkedList<GraphEdge>();
    248 
    249                 //map from Segments to GraphNodes;
    250                 //for those GraphNodes representing an "approaching node on segment" state
    251                 final Map<Segment, GraphNodeImpl> segment2GNMap_approaching =
    252                         new HashMap<Segment, GraphNodeImpl>();
    253 
    254                 //map from Segments to GraphNodes;
    255                 //for those GraphNodes representing a "leaving node on segment" state
    256                 final Map<Segment, GraphNodeImpl> segment2GNMap_leaving =
    257                         new HashMap<Segment, GraphNodeImpl>();
    258 
    259                 //map from SegmentNodes to GraphNode collections;
    260                 //for those GraphNodes representing an "approaching node on segment" state
    261                 final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_approaching =
    262                         new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
    263 
    264                 //map from SegmentNodes to GraphNodes collections;
    265                 //for those GraphNodes representing a "leaving node on segment" state
    266                 final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_leaving =
    267                         new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
    268 
    269 
    270 
    271                 /* create graph nodes and edges for junction evaluation groups */
    272 
    273                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    274                         if (evaluationGroup instanceof JunctionEvaluationGroup) {
    275 
    276                                 JunctionEvaluationGroup junctionEG = (JunctionEvaluationGroup) evaluationGroup;
    277 
    278                                 //create graph nodes
    279                                 for (Segment segment : junctionEG.getInboundSegments()) {
    280                                         GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode2(), segment);
    281                                         nodes.add(graphNode);
    282                                         segment2GNMap_approaching.put(segment, graphNode);
    283                                         addToCollectionMap(segNode2GNMap_approaching, segment.getNode2(), graphNode);
    284                                 }
    285                                 for (Segment segment : junctionEG.getOutboundSegments()) {
    286                                         GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode1(), segment);
    287                                         nodes.add(graphNode);
    288                                         segment2GNMap_leaving.put(segment, graphNode);
    289                                         addToCollectionMap(segNode2GNMap_leaving, segment.getNode1(), graphNode);
    290                                 }
    291 
    292                                 //create graph edges for all segment sequences between in- and outbound edges
    293                                 for (Segment inboundSegment : junctionEG.getInboundSegments()) {
    294                                         for (Segment outboundSegment : junctionEG.getOutboundSegments()) {
    295 
    296                                                 List<Segment> segmentSequence =
    297                                                         junctionEG.getSegmentSequence(inboundSegment, outboundSegment);
    298 
    299                                                 if (segmentSequence != null) {
    300 
    301                                                         createGraphEdge(
    302                                                                         segment2GNMap_approaching.get(inboundSegment),
    303                                                                         segment2GNMap_leaving.get(outboundSegment),
    304                                                                         segmentSequence,
    305                                                                         junctionEG);
    306 
    307                                                 }
    308                                         }
    309                                 }
    310 
    311                         }
    312                 }
    313 
    314                 /* create graph edges for connector evaluation groups.
    315                 * Because GraphNodes are created for pairs of SegmentNodes (from connector groups)
    316                 * and Segments (from junction groups), the GraphNodes already exist.
    317                 */
    318 
    319                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    320                         if (evaluationGroup instanceof ConnectorEvaluationGroup) {
    321 
    322                                 ConnectorEvaluationGroup connectorEG = (ConnectorEvaluationGroup) evaluationGroup;
    323 
    324                                 for (SegmentNode startNode : connectorEG.getBorderNodes()) {
    325                                         for (SegmentNode targetNode : connectorEG.getBorderNodes()) {
    326 
    327                                                 if (segNode2GNMap_leaving.containsKey(startNode)
    328                                                                 && segNode2GNMap_approaching.containsKey(targetNode)) {
    329 
    330                                                         for (GraphNodeImpl startGraphNode : segNode2GNMap_leaving.get(startNode)) {
    331                                                                 for (GraphNodeImpl targetGraphNode : segNode2GNMap_approaching.get(targetNode)) {
    332 
    333                                                                         if (connectorEG.getSegments().contains(startGraphNode.getSegment())
    334                                                                                         && connectorEG.getSegments().contains(targetGraphNode.getSegment())) {
    335 
    336                                                                                 List<Segment> segmentSequence =
    337                                                                                         connectorEG.getSegmentSequence(startNode, targetNode);
    338 
    339                                                                                 if (segmentSequence != null) {
    340                                                                                         createGraphEdge(
    341                                                                                                         startGraphNode,
    342                                                                                                         targetGraphNode,
    343                                                                                                         segmentSequence,
    344                                                                                                         connectorEG);
    345                                                                                 }
    346 
    347                                                                         }
    348 
    349                                                                 }
    350                                                         }
    351 
    352                                                 }
    353 
    354                                         }
    355                                 }
    356 
    357                         }
    358                 }
    359 
    360         }
    361 
    362         private void createGraphEdge(
    363                         GraphNodeImpl startNode, GraphNodeImpl targetNode,
    364                         List<Segment> segments, ConnectorEvaluationGroup evaluationGroup) {
    365 
    366                 Map<GraphEdgePropertyType<?>, Object> properties =
    367                         new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
    368                
    369                 for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
    370                         Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
    371                         properties.put(propertyType, value);
    372                 }
    373                
    374                 createGraphEdge(startNode, targetNode, properties);
    375 
    376         }
    377 
    378         private void createGraphEdge(
    379                         GraphNodeImpl startNode, GraphNodeImpl targetNode,
    380                         List<Segment> segments, JunctionEvaluationGroup evaluationGroup) {
    381 
    382                 Map<GraphEdgePropertyType<?>, Object> properties =
    383                         new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
    384                
    385                 for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
    386                         Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
    387                         properties.put(propertyType, value);
    388                 }
    389                
    390                 createGraphEdge(startNode, targetNode, properties);
    391 
    392         }
    393 
    394         /**
    395         * creates a GraphEdge;
    396         * adds it to its nodes' collections and {@link #edges} collection.
    397         */
    398         private void createGraphEdge(GraphNodeImpl startNode, GraphNodeImpl targetNode,
    399                         Map<GraphEdgePropertyType<?>, Object> properties) {
    400 
    401                 GraphEdge newEdge = new GraphEdgeImpl(startNode, targetNode, properties);
    402 
    403                 startNode.addOutgoingEdge(newEdge);
    404                 targetNode.addIncomingEdge(newEdge);
    405 
    406                 edges.add(newEdge);
    407 
    408         }
    409        
    410         private static boolean isConnectedWithExactly2Nodes(SegmentNode node) {
    411 
    412                 Set<SegmentNode> connectedNodes = new HashSet<SegmentNode>(2);
    413 
    414                 for (Segment segment : node.getInboundSegments()) {
    415                         connectedNodes.add(segment.getNode1());
    416                 }
    417                 for (Segment segment : node.getOutboundSegments()) {
    418                         connectedNodes.add(segment.getNode2());
    419                 }
    420 
    421                 return connectedNodes.size() == 2;
    422         }
    423 
    424         /**
    425         * creates a set for an object if none exists in a map.
    426         * The set will contain the object and be added to the map with the object being its key.
    427         */
    428         private static <T> void createSetIfHasNone(T object, Map<T, Set<T>> objectSetMap) {
    429 
    430                 if (!objectSetMap.containsKey(object)) {
    431                         @SuppressWarnings("unchecked") //no set with generic parameter can be created directly
    432                         Set<T> set = new HashSet();
    433                         set.add(object);
    434                         objectSetMap.put(object, set);
    435                 }
    436 
    437         }
    438 
    439         /**
    440         * puts an object in another object's set.
    441         * If both nodes have sets already, these sets are merged.
    442         * The objectSetMap is modified accordingly.
    443         *
    444         * @param object        object that might or might not be in a set; != null
    445         * @param objectInSet   object that is guaranteed to be in a set; != null
    446         * @param objectSetMap  map from objects to the one set they are part of; != null
    447         */
    448         private static <T> void putInSameSet(T object, T objectInSet, Map<T, Set<T>> objectSetMap) {
    449                 assert object != null && objectInSet != null && objectSetMap != null;
    450                 assert objectSetMap.containsKey(objectInSet);
    451 
    452                 Set<T> set = objectSetMap.get(objectInSet);
    453 
    454                 if (objectSetMap.containsKey(object)) {
    455 
    456                         /* merge the two sets */
    457                         Set<T> oldSet = objectSetMap.get(object);
    458                         for (T objectFromOldSet : oldSet) {
    459                                 set.add(objectFromOldSet);
    460                                 objectSetMap.put(objectFromOldSet, set);
    461                         }
    462 
    463                 } else {
    464 
    465                         /* add object to objectInSet's set */
    466                         set.add(object);
    467                         objectSetMap.put(object, set);
    468 
    469                 }
    470 
    471         }
    472 
    473         private static <K, E> void addToCollectionMap(final Map<K, Collection<E>> map, K key, E entry) {
    474                 if (!map.containsKey(key)) {
    475                         Collection<E> newCollection = new ArrayList<E>();
    476                         map.put(key, newCollection);
    477                 }
    478                 map.get(key).add(entry);
    479         }
    480 
    481         public void update(TransitionStructure transitionStructure) {
    482                 createNodesAndEdges();
    483                 notifyObservers();
    484         }
    485 
    486         public void addObserver(WayGraphObserver observer) {
    487                 observers.add(observer);
    488         }
    489 
    490         public void deleteObserver(WayGraphObserver observer) {
    491                 observers.remove(observer);
    492         }
    493 
    494         private void notifyObservers() {
    495                 for (WayGraphObserver observer : observers) {
    496                         observer.update(this);
    497                 }
    498         }
     25    private static final GraphEdgePropertyType<?>[] PROPERTY_TYPES =
     26        {GraphEdgeSegments.PROPERTY};
     27        //TODO: -> parameter
     28
     29    private static class GraphNodeImpl implements GraphNode {
     30        private final SegmentNode node;
     31        private final Segment segment;
     32        private final List<GraphEdge> incomingEdges = new ArrayList<GraphEdge>();
     33        private final List<GraphEdge> outgoingEdges = new ArrayList<GraphEdge>();
     34        public GraphNodeImpl(SegmentNode node, Segment segment) {
     35            assert node != null && segment != null;
     36            assert segment.getNode1() == node || segment.getNode2() == node;
     37            this.node = node;
     38            this.segment = segment;
     39        }
     40        public SegmentNode getSegmentNode() {
     41            return node;
     42        }
     43        public Segment getSegment() {
     44            return segment;
     45        }
     46        public void addIncomingEdge(GraphEdge edge) {
     47            assert edge != null;
     48            incomingEdges.add(edge);
     49        }
     50        public Collection<GraphEdge> getInboundEdges() {
     51            return incomingEdges;
     52        }
     53        public void addOutgoingEdge(GraphEdge edge) {
     54            assert edge != null;
     55            outgoingEdges.add(edge);
     56        }
     57        public Collection<GraphEdge> getOutboundEdges() {
     58            return outgoingEdges;
     59        }
     60        @Override
     61        public String toString() {
     62            return "(" + node + "; " + segment + ")";
     63        }
     64    }
     65
     66    private static class GraphEdgeImpl implements GraphEdge {
     67
     68        private final GraphNode startNode;
     69        private final GraphNode targetNode;
     70        private final Map<GraphEdgePropertyType<?>, Object> properties;
     71
     72        public GraphEdgeImpl(GraphNode startNode, GraphNode targetNode,
     73                Map<GraphEdgePropertyType<?>, Object> properties) {
     74            assert startNode != null && targetNode != null && properties != null;
     75            this.startNode = startNode;
     76            this.targetNode = targetNode;
     77            this.properties = properties;
     78        }
     79
     80        public GraphNode getStartNode() {
     81            return startNode;
     82        }
     83        public GraphNode getTargetNode() {
     84            return targetNode;
     85        }
     86
     87        public Collection<GraphEdgePropertyType<?>> getAvailableProperties() {
     88            return properties.keySet();
     89        }
     90        public <V> V getPropertyValue(GraphEdgePropertyType<V> property) {
     91            V result = (V) properties.get(property);
     92            return result;
     93        }
     94
     95        @Override
     96        public String toString() {
     97            return "(" + startNode + "-->" + targetNode + ")";
     98        }
     99
     100    };
     101
     102    private final Set<WayGraphObserver> observers = new HashSet<WayGraphObserver>();
     103
     104    private final TransitionStructure transitionStructure;
     105
     106    private Collection<GraphNode> nodes;
     107    private List<GraphEdge> edges;
     108
     109    /**
     110    * create a WayGraph based on a {@link TransitionStructure}
     111    * @param transitionStructure  transition structure this graph is to be based on; != null
     112    */
     113    public TSBasedWayGraph(TransitionStructure transitionStructure) {
     114        assert transitionStructure != null;
     115
     116        this.transitionStructure = transitionStructure;
     117        transitionStructure.addObserver(this);
     118
     119        createNodesAndEdges();
     120    }
     121
     122    public Collection<GraphEdge> getEdges() {
     123        return edges;
     124    }
     125
     126    public Collection<GraphNode> getNodes() {
     127        return nodes;
     128    }
     129
     130    private void createNodesAndEdges() {
     131
     132        Collection<EvaluationGroup> evaluationGroups =
     133            createEvaluationGroups(transitionStructure);
     134
     135        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     136            evaluationGroup.evaluate(transitionStructure.getRestrictions());
     137        }
     138
     139        createNodesAndEdgesFromEvaluationGroups(evaluationGroups);
     140
     141        evaluationGroups = null;
     142    }
     143
     144    private static Collection<EvaluationGroup> createEvaluationGroups(
     145            TransitionStructure transitionStructure) {
     146
     147        Map<SegmentNode, Set<SegmentNode>> nodeSetMap =
     148            new HashMap<SegmentNode, Set<SegmentNode>>();
     149
     150        /* first step: everything that is part of the same restriction goes into the same set */
     151
     152        for (Restriction restriction : transitionStructure.getRestrictions()) {
     153
     154            /* group every node in via segments (which includes the
     155            * last node of from and the first node of to) into a set */
     156
     157            SegmentNode firstNode = restriction.getFrom().getNode2();
     158            createSetIfHasNone(firstNode, nodeSetMap);
     159
     160            for (Segment segment : restriction.getVias()) {
     161                putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
     162                putInSameSet(segment.getNode2(), firstNode, nodeSetMap);
     163            }
     164
     165            for (Segment segment : restriction.getTos()) {
     166                putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
     167            }
     168
     169        }
     170
     171        /* second step: create own sets for each junction and end point
     172        * (node connected with more than / less than two nodes). */
     173
     174        for (SegmentNode node : transitionStructure.getNodes()) {
     175
     176            if (!nodeSetMap.containsKey(node)
     177                    && !isConnectedWithExactly2Nodes(node)) {
     178
     179                createSetIfHasNone(node, nodeSetMap);
     180
     181            }
     182
     183        }
     184
     185        /* third step: create segment sets for all segments that are not in one of the node sets
     186        * (that is, at least one node is not part of a junction evaluation group
     187        *  or the nodes are part of different junction evaluation groups)  */
     188
     189        Map<Segment, Set<Segment>> segmentSetMap =
     190            new HashMap<Segment, Set<Segment>>();
     191
     192        for (Segment segment : transitionStructure.getSegments()) {
     193
     194            SegmentNode node1 = segment.getNode1();
     195            SegmentNode node2 = segment.getNode2();
     196
     197            if (!nodeSetMap.containsKey(node1) || !nodeSetMap.containsKey(node2)
     198                    || nodeSetMap.get(node1) != nodeSetMap.get(node2)) {
     199
     200                createSetIfHasNone(segment, segmentSetMap);
     201
     202                for (Segment subsequentSegment : segment.getNode2().getOutboundSegments()) {
     203                    if (!nodeSetMap.containsKey(node2)
     204                            || subsequentSegment.getNode2() == node1) {
     205                        putInSameSet(subsequentSegment, segment, segmentSetMap);
     206                    }
     207                }
     208                //note that segments leading to this segment will share sets anyway,
     209                //because this segment is a subsequent segment of them
     210
     211
     212            }
     213
     214        }
     215
     216        /* create EvaluationGroup objects */
     217
     218        Collection<EvaluationGroup> evaluationGroups =
     219            new ArrayList<EvaluationGroup>(nodeSetMap.size() + segmentSetMap.size());
     220
     221        Set<Set<SegmentNode>> nodeSets = new HashSet<Set<SegmentNode>>(nodeSetMap.values());
     222        for (Set<SegmentNode> nodeSet : nodeSets) {
     223            evaluationGroups.add(new JunctionEvaluationGroup(nodeSet));
     224        }
     225
     226        HashSet<Set<Segment>> hashSets = new HashSet<Set<Segment>>(segmentSetMap.values());
     227        for (Set<Segment> segmentSet : hashSets) {
     228            Set<SegmentNode> borderNodes = new HashSet<SegmentNode>();
     229            for (Segment segment : segmentSet) {
     230                if (nodeSetMap.containsKey(segment.getNode1())) {
     231                    borderNodes.add(segment.getNode1());
     232                }
     233                if (nodeSetMap.containsKey(segment.getNode2())) {
     234                    borderNodes.add(segment.getNode2());
     235                }
     236            }
     237            evaluationGroups.add(new ConnectorEvaluationGroup(segmentSet, borderNodes));
     238        }
     239
     240        return evaluationGroups;
     241    }
     242
     243    private void createNodesAndEdgesFromEvaluationGroups(
     244            Collection<EvaluationGroup> evaluationGroups) {
     245
     246        nodes = new LinkedList<GraphNode>();
     247        edges = new LinkedList<GraphEdge>();
     248
     249        //map from Segments to GraphNodes;
     250        //for those GraphNodes representing an "approaching node on segment" state
     251        final Map<Segment, GraphNodeImpl> segment2GNMap_approaching =
     252            new HashMap<Segment, GraphNodeImpl>();
     253
     254        //map from Segments to GraphNodes;
     255        //for those GraphNodes representing a "leaving node on segment" state
     256        final Map<Segment, GraphNodeImpl> segment2GNMap_leaving =
     257            new HashMap<Segment, GraphNodeImpl>();
     258
     259        //map from SegmentNodes to GraphNode collections;
     260        //for those GraphNodes representing an "approaching node on segment" state
     261        final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_approaching =
     262            new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
     263
     264        //map from SegmentNodes to GraphNodes collections;
     265        //for those GraphNodes representing a "leaving node on segment" state
     266        final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_leaving =
     267            new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
     268
     269
     270
     271        /* create graph nodes and edges for junction evaluation groups */
     272
     273        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     274            if (evaluationGroup instanceof JunctionEvaluationGroup) {
     275
     276                JunctionEvaluationGroup junctionEG = (JunctionEvaluationGroup) evaluationGroup;
     277
     278                //create graph nodes
     279                for (Segment segment : junctionEG.getInboundSegments()) {
     280                    GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode2(), segment);
     281                    nodes.add(graphNode);
     282                    segment2GNMap_approaching.put(segment, graphNode);
     283                    addToCollectionMap(segNode2GNMap_approaching, segment.getNode2(), graphNode);
     284                }
     285                for (Segment segment : junctionEG.getOutboundSegments()) {
     286                    GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode1(), segment);
     287                    nodes.add(graphNode);
     288                    segment2GNMap_leaving.put(segment, graphNode);
     289                    addToCollectionMap(segNode2GNMap_leaving, segment.getNode1(), graphNode);
     290                }
     291
     292                //create graph edges for all segment sequences between in- and outbound edges
     293                for (Segment inboundSegment : junctionEG.getInboundSegments()) {
     294                    for (Segment outboundSegment : junctionEG.getOutboundSegments()) {
     295
     296                        List<Segment> segmentSequence =
     297                            junctionEG.getSegmentSequence(inboundSegment, outboundSegment);
     298
     299                        if (segmentSequence != null) {
     300
     301                            createGraphEdge(
     302                                    segment2GNMap_approaching.get(inboundSegment),
     303                                    segment2GNMap_leaving.get(outboundSegment),
     304                                    segmentSequence,
     305                                    junctionEG);
     306
     307                        }
     308                    }
     309                }
     310
     311            }
     312        }
     313
     314        /* create graph edges for connector evaluation groups.
     315        * Because GraphNodes are created for pairs of SegmentNodes (from connector groups)
     316        * and Segments (from junction groups), the GraphNodes already exist.
     317        */
     318
     319        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     320            if (evaluationGroup instanceof ConnectorEvaluationGroup) {
     321
     322                ConnectorEvaluationGroup connectorEG = (ConnectorEvaluationGroup) evaluationGroup;
     323
     324                for (SegmentNode startNode : connectorEG.getBorderNodes()) {
     325                    for (SegmentNode targetNode : connectorEG.getBorderNodes()) {
     326
     327                        if (segNode2GNMap_leaving.containsKey(startNode)
     328                                && segNode2GNMap_approaching.containsKey(targetNode)) {
     329
     330                            for (GraphNodeImpl startGraphNode : segNode2GNMap_leaving.get(startNode)) {
     331                                for (GraphNodeImpl targetGraphNode : segNode2GNMap_approaching.get(targetNode)) {
     332
     333                                    if (connectorEG.getSegments().contains(startGraphNode.getSegment())
     334                                            && connectorEG.getSegments().contains(targetGraphNode.getSegment())) {
     335
     336                                        List<Segment> segmentSequence =
     337                                            connectorEG.getSegmentSequence(startNode, targetNode);
     338
     339                                        if (segmentSequence != null) {
     340                                            createGraphEdge(
     341                                                    startGraphNode,
     342                                                    targetGraphNode,
     343                                                    segmentSequence,
     344                                                    connectorEG);
     345                                        }
     346
     347                                    }
     348
     349                                }
     350                            }
     351
     352                        }
     353
     354                    }
     355                }
     356
     357            }
     358        }
     359
     360    }
     361
     362    private void createGraphEdge(
     363            GraphNodeImpl startNode, GraphNodeImpl targetNode,
     364            List<Segment> segments, ConnectorEvaluationGroup evaluationGroup) {
     365
     366        Map<GraphEdgePropertyType<?>, Object> properties =
     367            new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
     368
     369        for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
     370            Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
     371            properties.put(propertyType, value);
     372        }
     373
     374        createGraphEdge(startNode, targetNode, properties);
     375
     376    }
     377
     378    private void createGraphEdge(
     379            GraphNodeImpl startNode, GraphNodeImpl targetNode,
     380            List<Segment> segments, JunctionEvaluationGroup evaluationGroup) {
     381
     382        Map<GraphEdgePropertyType<?>, Object> properties =
     383            new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
     384
     385        for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
     386            Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
     387            properties.put(propertyType, value);
     388        }
     389
     390        createGraphEdge(startNode, targetNode, properties);
     391
     392    }
     393
     394    /**
     395    * creates a GraphEdge;
     396    * adds it to its nodes' collections and {@link #edges} collection.
     397    */
     398    private void createGraphEdge(GraphNodeImpl startNode, GraphNodeImpl targetNode,
     399            Map<GraphEdgePropertyType<?>, Object> properties) {
     400
     401        GraphEdge newEdge = new GraphEdgeImpl(startNode, targetNode, properties);
     402
     403        startNode.addOutgoingEdge(newEdge);
     404        targetNode.addIncomingEdge(newEdge);
     405
     406        edges.add(newEdge);
     407
     408    }
     409
     410    private static boolean isConnectedWithExactly2Nodes(SegmentNode node) {
     411
     412        Set<SegmentNode> connectedNodes = new HashSet<SegmentNode>(2);
     413
     414        for (Segment segment : node.getInboundSegments()) {
     415            connectedNodes.add(segment.getNode1());
     416        }
     417        for (Segment segment : node.getOutboundSegments()) {
     418            connectedNodes.add(segment.getNode2());
     419        }
     420
     421        return connectedNodes.size() == 2;
     422    }
     423
     424    /**
     425    * creates a set for an object if none exists in a map.
     426    * The set will contain the object and be added to the map with the object being its key.
     427    */
     428    private static <T> void createSetIfHasNone(T object, Map<T, Set<T>> objectSetMap) {
     429
     430        if (!objectSetMap.containsKey(object)) {
     431            @SuppressWarnings("unchecked") //no set with generic parameter can be created directly
     432            Set<T> set = new HashSet();
     433            set.add(object);
     434            objectSetMap.put(object, set);
     435        }
     436
     437    }
     438
     439    /**
     440    * puts an object in another object's set.
     441    * If both nodes have sets already, these sets are merged.
     442    * The objectSetMap is modified accordingly.
     443    *
     444    * @param object        object that might or might not be in a set; != null
     445    * @param objectInSet   object that is guaranteed to be in a set; != null
     446    * @param objectSetMap  map from objects to the one set they are part of; != null
     447    */
     448    private static <T> void putInSameSet(T object, T objectInSet, Map<T, Set<T>> objectSetMap) {
     449        assert object != null && objectInSet != null && objectSetMap != null;
     450        assert objectSetMap.containsKey(objectInSet);
     451
     452        Set<T> set = objectSetMap.get(objectInSet);
     453
     454        if (objectSetMap.containsKey(object)) {
     455
     456            /* merge the two sets */
     457            Set<T> oldSet = objectSetMap.get(object);
     458            for (T objectFromOldSet : oldSet) {
     459                set.add(objectFromOldSet);
     460                objectSetMap.put(objectFromOldSet, set);
     461            }
     462
     463        } else {
     464
     465            /* add object to objectInSet's set */
     466            set.add(object);
     467            objectSetMap.put(object, set);
     468
     469        }
     470
     471    }
     472
     473    private static <K, E> void addToCollectionMap(final Map<K, Collection<E>> map, K key, E entry) {
     474        if (!map.containsKey(key)) {
     475            Collection<E> newCollection = new ArrayList<E>();
     476            map.put(key, newCollection);
     477        }
     478        map.get(key).add(entry);
     479    }
     480
     481    public void update(TransitionStructure transitionStructure) {
     482        createNodesAndEdges();
     483        notifyObservers();
     484    }
     485
     486    public void addObserver(WayGraphObserver observer) {
     487        observers.add(observer);
     488    }
     489
     490    public void deleteObserver(WayGraphObserver observer) {
     491        observers.remove(observer);
     492    }
     493
     494    private void notifyObservers() {
     495        for (WayGraphObserver observer : observers) {
     496            observer.update(this);
     497        }
     498    }
    499499
    500500}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/WayGraph.java

    r16520 r23189  
    88public interface WayGraph {
    99
    10         Collection<GraphNode> getNodes();
    11         Collection<GraphEdge> getEdges();
     10    Collection<GraphNode> getNodes();
     11    Collection<GraphEdge> getEdges();
    1212
    13         /**
    14         * adds an observer.
    15         * Does nothing if the parameter is already an observer of this WayGraph.
    16         *
    17         * @param observer  observer object, != null
    18         */
    19         public void addObserver(WayGraphObserver observer);
     13    /**
     14    * adds an observer.
     15    * Does nothing if the parameter is already an observer of this WayGraph.
     16    *
     17    * @param observer  observer object, != null
     18    */
     19    public void addObserver(WayGraphObserver observer);
    2020
    21         /**
    22         * deletes an observer that has been added using {@link #addObserver(WayGraphObserver)}.
    23         * Does nothing if the parameter isn't currently an observer of this WayGraph.
    24         *
    25         * @param observer  observer object, != null
    26         */
    27         public void deleteObserver(WayGraphObserver observer);
     21    /**
     22    * deletes an observer that has been added using {@link #addObserver(WayGraphObserver)}.
     23    * Does nothing if the parameter isn't currently an observer of this WayGraph.
     24    *
     25    * @param observer  observer object, != null
     26    */
     27    public void deleteObserver(WayGraphObserver observer);
    2828
    2929}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/WayGraphObserver.java

    r16520 r23189  
    77public interface WayGraphObserver {
    88
    9         /**
    10         * informs this observer about changes in an observed graph
    11         * @param wayGraph  observed graph that has changed; != null
    12         */
    13         public void update(WayGraph wayGraph);
     9    /**
     10    * informs this observer about changes in an observed graph
     11    * @param wayGraph  observed graph that has changed; != null
     12    */
     13    public void update(WayGraph wayGraph);
    1414
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/GraphEdgePropertyType.java

    r18130 r23189  
    1717 */
    1818public interface GraphEdgePropertyType<V> {
    19        
    20         /**
    21          * determines the property value for segments created from junction groups
    22          */
    23         public V evaluate(JunctionEvaluationGroup junctionGroup,
    24                         List<Segment> segmentSequence,
    25                         TransitionStructure transitionStructure);
    2619
    27         /**
    28          * determines the property value for segments created from connector groups
    29          */
    30         public V evaluate(ConnectorEvaluationGroup connectorGroup,
    31                         List<Segment> segmentSequence,
    32                         TransitionStructure transitionStructure);
    33        
     20    /**
     21     * determines the property value for segments created from junction groups
     22     */
     23    public V evaluate(JunctionEvaluationGroup junctionGroup,
     24            List<Segment> segmentSequence,
     25            TransitionStructure transitionStructure);
     26
     27    /**
     28     * determines the property value for segments created from connector groups
     29     */
     30    public V evaluate(ConnectorEvaluationGroup connectorGroup,
     31            List<Segment> segmentSequence,
     32            TransitionStructure transitionStructure);
     33
    3434}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/GraphEdgeSegments.java

    r18130 r23189  
    1212 * property for the graph that is being constructed will preserve information
    1313 * from the {@link TransitionStructure}.
    14  * 
     14 *
    1515 * TODO: for some purposes, segments are not needed (only coordinate lists;
    1616 * without properties etc.)
    1717 */
    1818public final class GraphEdgeSegments implements GraphEdgePropertyType<List<Segment>> {
    19        
    20         public static final GraphEdgeSegments PROPERTY = new GraphEdgeSegments();
    21        
    22         /**
    23         * private constructor to make sure that {@link #INSTANCE} is the only instance
    24         */
    25         private GraphEdgeSegments() { }
    26        
    27         public List<Segment> evaluate(JunctionEvaluationGroup junctionGroup,
    28                         List<Segment> segmentSequence, TransitionStructure transitionStructure) {
    29                 return segmentSequence;
    30         }
    31        
    32         public List<Segment> evaluate(ConnectorEvaluationGroup connectorGroup,
    33                         List<Segment> segmentSequence, TransitionStructure transitionStructure) {
    34                 return segmentSequence;
    35         }
    36        
     19
     20    public static final GraphEdgeSegments PROPERTY = new GraphEdgeSegments();
     21
     22    /**
     23    * private constructor to make sure that {@link #INSTANCE} is the only instance
     24    */
     25    private GraphEdgeSegments() { }
     26
     27    public List<Segment> evaluate(JunctionEvaluationGroup junctionGroup,
     28            List<Segment> segmentSequence, TransitionStructure transitionStructure) {
     29        return segmentSequence;
     30    }
     31
     32    public List<Segment> evaluate(ConnectorEvaluationGroup connectorGroup,
     33            List<Segment> segmentSequence, TransitionStructure transitionStructure) {
     34        return segmentSequence;
     35    }
     36
    3737}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadIncline.java

    r19216 r23189  
    88public class RoadIncline implements RoadPropertyType<Float> {
    99
    10         public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
    11                         DataSource<N,W,R,M> dataSource) {
    12                 return null;
    13         };
     10    public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
     11            DataSource<N,W,R,M> dataSource) {
     12        return null;
     13    };
    1414
    15         public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
    16                         DataSource<N,W,R,M> dataSource) {
    17                 assert way != null && accessParameters != null && dataSource != null;
     15    public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
     16            DataSource<N,W,R,M> dataSource) {
     17        assert way != null && accessParameters != null && dataSource != null;
    1818
    19                 TagGroup tags = dataSource.getTagsW(way);
    20                 String inclineString = tags.getValue("incline");
     19        TagGroup tags = dataSource.getTagsW(way);
     20        String inclineString = tags.getValue("incline");
    2121
    22                 if (inclineString != null) {
    23                         Float incline = ValueStringParser.parseIncline(inclineString);
    24                         if (incline != null) {
    25                                 if (!forward) {
    26                                         incline = -incline;
    27                                 }
    28                                 return incline;
    29                         }
    30                 }
     22        if (inclineString != null) {
     23            Float incline = ValueStringParser.parseIncline(inclineString);
     24            if (incline != null) {
     25                if (!forward) {
     26                    incline = -incline;
     27                }
     28                return incline;
     29            }
     30        }
    3131
    32                 return null;
    33         };
     32        return null;
     33    };
    3434
    35         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    36                 assert propertyValue instanceof Float;
     35    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     36        assert propertyValue instanceof Float;
    3737
    38                 float incline = (Float)propertyValue;
     38        float incline = (Float)propertyValue;
    3939
    40                 Float maxInclineUp =
    41                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_UP);
    42                 Float maxInclineDown =
    43                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_DOWN);
     40        Float maxInclineUp =
     41            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_UP);
     42        Float maxInclineDown =
     43            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_DOWN);
    4444
    45                 if (maxInclineUp != null && incline > maxInclineUp) {
    46                         return false;
    47                 } else if (maxInclineDown != null && -incline > maxInclineDown) {
    48                         return false;
    49                 } else {
    50                         return true;
    51                 }
    52         }
     45        if (maxInclineUp != null && incline > maxInclineUp) {
     46            return false;
     47        } else if (maxInclineDown != null && -incline > maxInclineDown) {
     48            return false;
     49        } else {
     50            return true;
     51        }
     52    }
    5353
    5454}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxaxleload.java

    r20243 r23189  
    66
    77public class RoadMaxaxleload extends RoadValueLimit {
    8         public RoadMaxaxleload() {
    9                 super("maxaxleload", AXLELOAD, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseWeight(valueString);
    14         }
     8    public RoadMaxaxleload() {
     9        super("maxaxleload", AXLELOAD, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseWeight(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxheight.java

    r20243 r23189  
    66
    77public class RoadMaxheight extends RoadValueLimit {
    8         public RoadMaxheight() {
    9                 super("maxheight", HEIGHT, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxheight() {
     9        super("maxheight", HEIGHT, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxlength.java

    r20243 r23189  
    66
    77public class RoadMaxlength extends RoadValueLimit {
    8         public RoadMaxlength() {
    9                 super("maxlength", LENGTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxlength() {
     9        super("maxlength", LENGTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxspeed.java

    r19216 r23189  
    88public class RoadMaxspeed implements RoadPropertyType<Float> {
    99
    10         private DataSource<?, ?, ?, ?> lastDataSource;
     10    private DataSource<?, ?, ?, ?> lastDataSource;
    1111
    12         /**
    13         * (re)creates information like boundaries if data source has changed
    14         * since last call to {@link #evaluate(Object, boolean, AccessParameters, DataSource)}
    15         */
    16         private <N, W, R, M> void initializeIfNecessary(DataSource<N, W, R, M> dataSource) {
     12    /**
     13    * (re)creates information like boundaries if data source has changed
     14    * since last call to {@link #evaluate(Object, boolean, AccessParameters, DataSource)}
     15    */
     16    private <N, W, R, M> void initializeIfNecessary(DataSource<N, W, R, M> dataSource) {
    1717
    18                 if (dataSource != lastDataSource) {
     18        if (dataSource != lastDataSource) {
    1919
    20                         /*
    21                         *
    22                         * currently no activities;
    23                         * place boundaries or similar features can be handled here
    24                         * once there is consensus on the topic of implicit maxspeeds, trafficzones etc.
    25                         *
    26                         */
     20            /*
     21            *
     22            * currently no activities;
     23            * place boundaries or similar features can be handled here
     24            * once there is consensus on the topic of implicit maxspeeds, trafficzones etc.
     25            *
     26            */
    2727
    28                         lastDataSource = dataSource;
    29                 }
    30         }
     28            lastDataSource = dataSource;
     29        }
     30    }
    3131
    32         public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
    33                         DataSource<N, W, R, M> dataSource) {
    34                 assert node != null && accessParameters != null && dataSource != null;
     32    public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
     33            DataSource<N, W, R, M> dataSource) {
     34        assert node != null && accessParameters != null && dataSource != null;
    3535
    36                 initializeIfNecessary(dataSource);
     36        initializeIfNecessary(dataSource);
    3737
    38                 return evaluateTags(dataSource.getTagsN(node));
    39         }
     38        return evaluateTags(dataSource.getTagsN(node));
     39    }
    4040
    41         public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
    42                         DataSource<N, W, R, M> dataSource) {
    43                 assert way != null && accessParameters != null && dataSource != null;
     41    public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
     42            DataSource<N, W, R, M> dataSource) {
     43        assert way != null && accessParameters != null && dataSource != null;
    4444
    45                 initializeIfNecessary(dataSource);
     45        initializeIfNecessary(dataSource);
    4646
    47                 return evaluateTags(dataSource.getTagsW(way));
    48         }
     47        return evaluateTags(dataSource.getTagsW(way));
     48    }
    4949
    50         private Float evaluateTags(TagGroup tags) {
    51                 String maxspeedString = tags.getValue("maxspeed");
     50    private Float evaluateTags(TagGroup tags) {
     51        String maxspeedString = tags.getValue("maxspeed");
    5252
    53                 if (maxspeedString != null) {
     53        if (maxspeedString != null) {
    5454
    55                         Float maxspeed = ValueStringParser.parseSpeed(maxspeedString);
    56                         if (maxspeed != null) {
    57                                 return maxspeed;
    58                         }
     55            Float maxspeed = ValueStringParser.parseSpeed(maxspeedString);
     56            if (maxspeed != null) {
     57                return maxspeed;
     58            }
    5959
    60                 }
     60        }
    6161
    62                 return null;
    63         }
     62        return null;
     63    }
    6464
    65         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    66                 assert propertyValue instanceof Float;
    67                 return true;
    68         }
     65    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     66        assert propertyValue instanceof Float;
     67        return true;
     68    }
    6969
    7070}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxweight.java

    r20243 r23189  
    66
    77public class RoadMaxweight extends RoadValueLimit {
    8         public RoadMaxweight() {
    9                 super("maxweight", WEIGHT, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseWeight(valueString);
    14         }
     8    public RoadMaxweight() {
     9        super("maxweight", WEIGHT, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseWeight(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxwidth.java

    r20243 r23189  
    66
    77public class RoadMaxwidth extends RoadValueLimit {
    8         public RoadMaxwidth() {
    9                 super("maxwidth", WIDTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxwidth() {
     9        super("maxwidth", WIDTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMinspeed.java

    r20243 r23189  
    66
    77public class RoadMinspeed extends RoadValueLimit {
    8         public RoadMinspeed() {
    9                 super("minspeed", SPEED, LimitType.MINIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseSpeed(valueString);
    14         }
     8    public RoadMinspeed() {
     9        super("minspeed", SPEED, LimitType.MINIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseSpeed(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadPropertyType.java

    r19216 r23189  
    1414public interface RoadPropertyType<V> {
    1515
    16         /**
    17         * determines the property value for way-based segments.
    18         * Uses the way the segment is created from.
    19         *
    20         * @param way               way that is to be evaluated; != null
    21         * @param forward           chooses whether the property is evaluated
    22         *                          in (true) or against (false) way direction
    23         * @param accessParameters  access parameters for properties that depend on vehicle/situation
    24         * @param dataSource        object providing access to all data; != null
    25         * @return                  value of this property for the way;
    26         *                          null if property cannot be determined / does not apply
    27         */
    28         public <N, W, R, M> V evaluateW(W way, boolean forward,
    29                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
     16    /**
     17    * determines the property value for way-based segments.
     18    * Uses the way the segment is created from.
     19    *
     20    * @param way               way that is to be evaluated; != null
     21    * @param forward           chooses whether the property is evaluated
     22    *                          in (true) or against (false) way direction
     23    * @param accessParameters  access parameters for properties that depend on vehicle/situation
     24    * @param dataSource        object providing access to all data; != null
     25    * @return                  value of this property for the way;
     26    *                          null if property cannot be determined / does not apply
     27    */
     28    public <N, W, R, M> V evaluateW(W way, boolean forward,
     29            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
    3030
    31         /**
    32         * determines the property value for node-based segments.
    33         * Uses the node the segment is created from.
    34         *
    35         * @param way               node that is to be evaluated; != null
    36         * @param accessParameters  access parameters for properties that depend on vehicle/situation
    37         * @param dataSource        object providing access to all data; != null
    38         * @return                  value of this property for the way;
    39         *                          null if property cannot be determined / does not apply
    40         */
    41         public <N, W, R, M> V evaluateN(N node,
    42                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
     31    /**
     32    * determines the property value for node-based segments.
     33    * Uses the node the segment is created from.
     34    *
     35    * @param way               node that is to be evaluated; != null
     36    * @param accessParameters  access parameters for properties that depend on vehicle/situation
     37    * @param dataSource        object providing access to all data; != null
     38    * @return                  value of this property for the way;
     39    *                          null if property cannot be determined / does not apply
     40    */
     41    public <N, W, R, M> V evaluateN(N node,
     42            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
    4343
    44         /**
    45         * checks whether a segment with a given value for this property can be used by a vehicle
    46         * with a certain set of access parameters
    47         *
    48         * @param object  value of this property for the segment;
    49         *                MUST be of type V; != null
    50         */
    51         public boolean isUsable(Object object, AccessParameters accessParameters);
     44    /**
     45    * checks whether a segment with a given value for this property can be used by a vehicle
     46    * with a certain set of access parameters
     47    *
     48    * @param object  value of this property for the segment;
     49    *                MUST be of type V; != null
     50    */
     51    public boolean isUsable(Object object, AccessParameters accessParameters);
    5252
    5353}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadSurface.java

    r19216 r23189  
    99public class RoadSurface implements RoadPropertyType<String> {
    1010
    11         public <N, W, R, M> String evaluateN(N node, AccessParameters accessParameters,
    12                         DataSource<N,W,R,M> dataSource) {
    13                 return null;
    14         };
     11    public <N, W, R, M> String evaluateN(N node, AccessParameters accessParameters,
     12            DataSource<N,W,R,M> dataSource) {
     13        return null;
     14    };
    1515
    16         public <N, W, R, M> String evaluateW(W way, boolean forward, AccessParameters accessParameters,
    17                         DataSource<N,W,R,M> dataSource) {
    18                 assert way != null && accessParameters != null && dataSource != null;
     16    public <N, W, R, M> String evaluateW(W way, boolean forward, AccessParameters accessParameters,
     17            DataSource<N,W,R,M> dataSource) {
     18        assert way != null && accessParameters != null && dataSource != null;
    1919
    20                 TagGroup tags = dataSource.getTagsW(way);
    21                 return tags.getValue("surface");
     20        TagGroup tags = dataSource.getTagsW(way);
     21        return tags.getValue("surface");
    2222
    23         };
     23    };
    2424
    25         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    26                 assert propertyValue instanceof String;
     25    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     26        assert propertyValue instanceof String;
    2727
    28                 String surface = (String)propertyValue;
     28        String surface = (String)propertyValue;
    2929
    30                 Collection<String> surfaceBlacklist =
    31                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.SURFACE_BLACKLIST);
     30        Collection<String> surfaceBlacklist =
     31            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.SURFACE_BLACKLIST);
    3232
    33                 if (surfaceBlacklist != null && surfaceBlacklist.contains(surface)) {
    34                         return false;
    35                 } else {
    36                         return true;
    37                 }
    38         }
     33        if (surfaceBlacklist != null && surfaceBlacklist.contains(surface)) {
     34            return false;
     35        } else {
     36            return true;
     37        }
     38    }
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadTracktype.java

    r19216 r23189  
    77public class RoadTracktype implements RoadPropertyType<Integer> {
    88
    9         public <N, W, R, M> Integer evaluateN(N node, AccessParameters accessParameters,
    10                         DataSource<N,W,R,M> dataSource) {
    11                 return null;
    12         };
     9    public <N, W, R, M> Integer evaluateN(N node, AccessParameters accessParameters,
     10            DataSource<N,W,R,M> dataSource) {
     11        return null;
     12    };
    1313
    14         public <N, W, R, M> Integer evaluateW(W way, boolean forward, AccessParameters accessParameters,
    15                         DataSource<N,W,R,M> dataSource) {
    16                 assert way != null && accessParameters != null && dataSource != null;
     14    public <N, W, R, M> Integer evaluateW(W way, boolean forward, AccessParameters accessParameters,
     15            DataSource<N,W,R,M> dataSource) {
     16        assert way != null && accessParameters != null && dataSource != null;
    1717
    18                 TagGroup tags = dataSource.getTagsW(way);
    19                 String tracktypeString = tags.getValue("tracktype");
     18        TagGroup tags = dataSource.getTagsW(way);
     19        String tracktypeString = tags.getValue("tracktype");
    2020
    21                 if (tracktypeString != null) {
    22                         if        ("grade1".equals(tracktypeString)) {
    23                                 return 1;
    24                         } else if ("grade2".equals(tracktypeString)) {
    25                                 return 2;
    26                         } else if ("grade3".equals(tracktypeString)) {
    27                                 return 3;
    28                         } else if ("grade4".equals(tracktypeString)) {
    29                                 return 4;
    30                         } else if ("grade5".equals(tracktypeString)) {
    31                                 return 5;
    32                         }
    33                 }
     21        if (tracktypeString != null) {
     22            if        ("grade1".equals(tracktypeString)) {
     23                return 1;
     24            } else if ("grade2".equals(tracktypeString)) {
     25                return 2;
     26            } else if ("grade3".equals(tracktypeString)) {
     27                return 3;
     28            } else if ("grade4".equals(tracktypeString)) {
     29                return 4;
     30            } else if ("grade5".equals(tracktypeString)) {
     31                return 5;
     32            }
     33        }
    3434
    35                 return null;
    36         };
     35        return null;
     36    };
    3737
    38         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    39                 assert propertyValue instanceof Integer;
     38    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     39        assert propertyValue instanceof Integer;
    4040
    41                 int tracktype = (Integer)propertyValue;
     41        int tracktype = (Integer)propertyValue;
    4242
    43                 Integer maxTracktype =
    44                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_TRACKTYPE);
     43        Integer maxTracktype =
     44            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_TRACKTYPE);
    4545
    46                 if (maxTracktype != null && tracktype > maxTracktype) {
    47                         return false;
    48                 } else {
    49                         return true;
    50                 }
    51         }
     46        if (maxTracktype != null && tracktype > maxTracktype) {
     47            return false;
     48        } else {
     49            return true;
     50        }
     51    }
    5252
    5353}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadValueLimit.java

    r20243 r23189  
    1111abstract public class RoadValueLimit implements RoadPropertyType<Float> {
    1212
    13         protected static enum LimitType {MINIMUM, MAXIMUM};
     13    protected static enum LimitType {MINIMUM, MAXIMUM};
    1414
    15         private final String keyName;
    16         private final VehiclePropertyType<Float> vehicleProperty;
     15    private final String keyName;
     16    private final VehiclePropertyType<Float> vehicleProperty;
    1717
    18         private final LimitType upperLimit;
     18    private final LimitType upperLimit;
    1919
    20         /**
    21         * @param keyName          key that is used to add this property to a way; value must be in
    22         *                         format readable by {@link ValueStringParser#parseOsmDecimal(String)};
    23         *                         != null
    24         * @param vehicleProperty  vehicle property that is limited by this road property; != null
    25         * @param upperLimit       type of limit; != null
    26         */
    27         protected RoadValueLimit(String keyName, VehiclePropertyType<Float> vehicleProperty,
    28                         LimitType upperLimit) {
    29                 assert keyName != null && vehicleProperty != null && upperLimit != null;
     20    /**
     21    * @param keyName          key that is used to add this property to a way; value must be in
     22    *                         format readable by {@link ValueStringParser#parseOsmDecimal(String)};
     23    *                         != null
     24    * @param vehicleProperty  vehicle property that is limited by this road property; != null
     25    * @param upperLimit       type of limit; != null
     26    */
     27    protected RoadValueLimit(String keyName, VehiclePropertyType<Float> vehicleProperty,
     28            LimitType upperLimit) {
     29        assert keyName != null && vehicleProperty != null && upperLimit != null;
    3030
    31                 this.keyName = keyName;
    32                 this.vehicleProperty = vehicleProperty;
    33                 this.upperLimit = upperLimit;
    34         }
     31        this.keyName = keyName;
     32        this.vehicleProperty = vehicleProperty;
     33        this.upperLimit = upperLimit;
     34    }
    3535
    36         protected abstract Float parse(String valueString);
     36    protected abstract Float parse(String valueString);
    3737
    38         public <N, W, R, M> Float evaluateW(W way, boolean forward,
    39                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
    40                 assert way != null && accessParameters != null && dataSource != null;
    41                 return evaluateTags(dataSource.getTagsW(way));
    42         }
     38    public <N, W, R, M> Float evaluateW(W way, boolean forward,
     39            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
     40        assert way != null && accessParameters != null && dataSource != null;
     41        return evaluateTags(dataSource.getTagsW(way));
     42    }
    4343
    44         public <N, W, R, M> Float evaluateN(N node,
    45                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
    46                 assert node != null && accessParameters != null && dataSource != null;
    47                 return evaluateTags(dataSource.getTagsN(node));
    48         }
     44    public <N, W, R, M> Float evaluateN(N node,
     45            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
     46        assert node != null && accessParameters != null && dataSource != null;
     47        return evaluateTags(dataSource.getTagsN(node));
     48    }
    4949
    50         private final Float evaluateTags(TagGroup tags) {
    51                 String valueString = tags.getValue(keyName);
    52                 if (valueString != null) {
    53                         Float value = parse(valueString);
    54                         return value;
    55                 } else {
    56                         return null;
    57                 }
    58         }
     50    private final Float evaluateTags(TagGroup tags) {
     51        String valueString = tags.getValue(keyName);
     52        if (valueString != null) {
     53            Float value = parse(valueString);
     54            return value;
     55        } else {
     56            return null;
     57        }
     58    }
    5959
    60         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    61                 assert propertyValue instanceof Float;
     60    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     61        assert propertyValue instanceof Float;
    6262
    63                 Float vehicleValue = accessParameters.getVehiclePropertyValue(vehicleProperty);
     63        Float vehicleValue = accessParameters.getVehiclePropertyValue(vehicleProperty);
    6464
    65                 if (vehicleValue != null) {
    66                         switch(upperLimit) {
    67                                 case MINIMUM: return vehicleValue >= (Float) propertyValue;
    68                                 case MAXIMUM: return vehicleValue <= (Float) propertyValue;
    69                                 default:      throw new Error("unhandled LimitType");
    70                         }
    71                 } else {
    72                         return true;
    73                 }
    74         }
     65        if (vehicleValue != null) {
     66            switch(upperLimit) {
     67                case MINIMUM: return vehicleValue >= (Float) propertyValue;
     68                case MAXIMUM: return vehicleValue <= (Float) propertyValue;
     69                default:      throw new Error("unhandled LimitType");
     70            }
     71        } else {
     72            return true;
     73        }
     74    }
    7575
    7676}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadWidth.java

    r20243 r23189  
    66
    77public class RoadWidth extends RoadValueLimit {
    8         public RoadWidth() {
    9                 super("width", WIDTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadWidth() {
     9        super("width", WIDTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/VehiclePropertyType.java

    r16520 r23189  
    1111public interface VehiclePropertyType<V> {
    1212
    13         /**
    14         * determines whether a value is valid.
    15         * null is never a valid value and must not be used as parameter.
    16         */
    17         public boolean isValidValue(Object value);
     13    /**
     14    * determines whether a value is valid.
     15    * null is never a valid value and must not be used as parameter.
     16    */
     17    public boolean isValidValue(Object value);
    1818
    1919}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/VehiclePropertyTypes.java

    r16520 r23189  
    99public final class VehiclePropertyTypes {
    1010
    11         /** prevents instantiation */
    12         private VehiclePropertyTypes() { }
     11    /** prevents instantiation */
     12    private VehiclePropertyTypes() { }
    1313
    14         private static final class NonnegativeFloatProperty implements VehiclePropertyType<Float> {
    15                 public boolean isValidValue(Object value) {
    16                         return value instanceof Float && (Float)value >= 0;
    17                 }
    18         }
     14    private static final class NonnegativeFloatProperty implements VehiclePropertyType<Float> {
     15        public boolean isValidValue(Object value) {
     16            return value instanceof Float && (Float)value >= 0;
     17        }
     18    }
    1919
    20         /** length of a vehicle in meters; negative values are invalid */
    21         public static final VehiclePropertyType<Float> LENGTH = new NonnegativeFloatProperty();
     20    /** length of a vehicle in meters; negative values are invalid */
     21    public static final VehiclePropertyType<Float> LENGTH = new NonnegativeFloatProperty();
    2222
    23         /** width of a vehicle in meters; negative values are invalid */
    24         public static final VehiclePropertyType<Float> WIDTH = new NonnegativeFloatProperty();
     23    /** width of a vehicle in meters; negative values are invalid */
     24    public static final VehiclePropertyType<Float> WIDTH = new NonnegativeFloatProperty();
    2525
    26         /** height of a vehicle in meters; negative values are invalid */
    27         public static final VehiclePropertyType<Float> HEIGHT = new NonnegativeFloatProperty();
     26    /** height of a vehicle in meters; negative values are invalid */
     27    public static final VehiclePropertyType<Float> HEIGHT = new NonnegativeFloatProperty();
    2828
    29         /** weight of a vehicle in tons; negative values are invalid */
    30         public static final VehiclePropertyType<Float> WEIGHT = new NonnegativeFloatProperty();
     29    /** weight of a vehicle in tons; negative values are invalid */
     30    public static final VehiclePropertyType<Float> WEIGHT = new NonnegativeFloatProperty();
    3131
    32         /** axleload of a vehicle in tons; negative values are invalid */
    33         public static final VehiclePropertyType<Float> AXLELOAD = new NonnegativeFloatProperty();
     32    /** axleload of a vehicle in tons; negative values are invalid */
     33    public static final VehiclePropertyType<Float> AXLELOAD = new NonnegativeFloatProperty();
    3434
    35         /** speed a vehicle can reach in km/h; negative values are invalid */
    36         public static final VehiclePropertyType<Float> SPEED = new NonnegativeFloatProperty();
     35    /** speed a vehicle can reach in km/h; negative values are invalid */
     36    public static final VehiclePropertyType<Float> SPEED = new NonnegativeFloatProperty();
    3737
    38         /** maximum incline a vehicle can go up; negative values are invalid */
    39         public static final VehiclePropertyType<Float> MAX_INCLINE_UP = new NonnegativeFloatProperty();
     38    /** maximum incline a vehicle can go up; negative values are invalid */
     39    public static final VehiclePropertyType<Float> MAX_INCLINE_UP = new NonnegativeFloatProperty();
    4040
    41         /** maximum incline a vehicle can go down; negative values are invalid */
    42         public static final VehiclePropertyType<Float> MAX_INCLINE_DOWN = new NonnegativeFloatProperty();
     41    /** maximum incline a vehicle can go down; negative values are invalid */
     42    public static final VehiclePropertyType<Float> MAX_INCLINE_DOWN = new NonnegativeFloatProperty();
    4343
    44         /** surface types ("surface" key values) the vehicle cannot use */
    45         public static final VehiclePropertyType<Collection<String>> SURFACE_BLACKLIST = new VehiclePropertyType<Collection<String>>() {
    46                 public boolean isValidValue(Object value) {
     44    /** surface types ("surface" key values) the vehicle cannot use */
     45    public static final VehiclePropertyType<Collection<String>> SURFACE_BLACKLIST = new VehiclePropertyType<Collection<String>>() {
     46        public boolean isValidValue(Object value) {
    4747
    48                         if (!(value instanceof Collection)) {
    49                                 return false;
    50                         }
     48            if (!(value instanceof Collection)) {
     49                return false;
     50            }
    5151
    52                         for (Object contentObject : (Collection<?>)value) {
    53                                 if (!(contentObject instanceof String)) {
    54                                         return false;
    55                                 }
    56                         }
     52            for (Object contentObject : (Collection<?>)value) {
     53                if (!(contentObject instanceof String)) {
     54                    return false;
     55                }
     56            }
    5757
    58                         return true;
    59                 }
    60         };
     58            return true;
     59        }
     60    };
    6161
    62         /**
    63         * maximum tracktype grade the vehicle can use;
    64         * values are integers from = to 5
    65         * (values of key "tracktype" without "grade_" prefix, 0 is for "none")
    66         */
    67         public static final VehiclePropertyType<Integer> MAX_TRACKTYPE = new VehiclePropertyType<Integer>() {
    68                 public boolean isValidValue(Object value) {
    69                         return value instanceof Integer && (Integer)value >= 0 && (Integer)value <= 5;
    70                 }
    71         };
     62    /**
     63    * maximum tracktype grade the vehicle can use;
     64    * values are integers from = to 5
     65    * (values of key "tracktype" without "grade_" prefix, 0 is for "none")
     66    */
     67    public static final VehiclePropertyType<Integer> MAX_TRACKTYPE = new VehiclePropertyType<Integer>() {
     68        public boolean isValidValue(Object value) {
     69            return value instanceof Integer && (Integer)value >= 0 && (Integer)value <= 5;
     70        }
     71    };
    7272
    7373}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/GenericTransitionStructure.java

    r19216 r23189  
    3030public class GenericTransitionStructure<N, W, R, M> implements TransitionStructure, DataSourceObserver {
    3131
    32         private static final Collection<Segment> EMPTY_SEGMENT_LIST =
    33                 Collections.unmodifiableList(new ArrayList<Segment>(0));
    34         private static final Collection<Restriction> EMPTY_RESTRICTION_COLLECTION =
    35                 new ArrayList<Restriction>(0);
    36 
    37         private static class SegmentNodeImpl implements SegmentNode {
    38                 private final double lat;
    39                 private final double lon;
    40                 private final List<Segment> inboundSegments = new LinkedList<Segment>();
    41                 private final List<Segment> outboundSegments = new LinkedList<Segment>();
    42                 private final Map<RoadPropertyType<?>, Object> properties;
    43                 public SegmentNodeImpl(double lat, double lon, Map<RoadPropertyType<?>, Object> properties) {
    44                         assert properties != null;
    45                         this.lat = lat;
    46                         this.lon = lon;
    47                         this.properties = properties;
    48                 }
    49                 public double getLat() {
    50                         return lat;
    51                 }
    52                 public double getLon() {
    53                         return lon;
    54                 }
    55                 public void addInboundSegment(Segment segment) {
    56                         inboundSegments.add(segment);
    57                 }
    58                 public void addOutboundSegment(Segment segment) {
    59                         outboundSegments.add(segment);
    60                 }
    61                 public Collection<Segment> getOutboundSegments() {
    62                         return outboundSegments;
    63                 }
    64                 public Collection<Segment> getInboundSegments() {
    65                         return inboundSegments;
    66                 }
    67 
    68                 public <P> void setProperty(RoadPropertyType<P> property, P value) {
    69                         properties.put(property, value);
    70                 }
    71                 public Collection<RoadPropertyType<?>> getAvailableProperties() {
    72                         return properties.keySet();
    73                 }
    74                 public <P> P getPropertyValue(RoadPropertyType<P> property) {
    75                         @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
    76                         P result = (P) properties.get(property);
    77                         return result;
    78                 }
    79                 public Map<RoadPropertyType<?>, Object> getProperties() {
    80                         return properties;
    81                 }
    82 
    83                 @Override
    84                 public String toString() {
    85                         return "(" + lat + ", " + lon + ")";
    86                 }
    87         }
    88 
    89         private static class SegmentImpl implements Segment {
    90                 private final SegmentNode node1;
    91                 private final SegmentNode node2;
    92                 private final Map<RoadPropertyType<?>, Object> properties;
    93                 public SegmentImpl(SegmentNode node1, SegmentNode node2, Map<RoadPropertyType<?>, Object> properties) {
    94                         this.node1 = node1;
    95                         this.node2 = node2;
    96                         this.properties = properties;
    97                 }
    98                 public SegmentNode getNode1() {
    99                         return node1;
    100                 }
    101                 public SegmentNode getNode2() {
    102                         return node2;
    103                 }
    104                 public <P> void setProperty(RoadPropertyType<P> property, P value) {
    105                         properties.put(property, value);
    106                 }
    107                 public Collection<RoadPropertyType<?>> getAvailableProperties() {
    108                         return properties.keySet();
    109                 }
    110                 public <P> P getPropertyValue(RoadPropertyType<P> property) {
    111                         @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
    112                         P result = (P) properties.get(property);
    113                         return result;
    114                 }
    115 
    116                 @Override
    117                 public String toString() {
    118                         return "(" + node1 + "->" + node2 + ")";
    119                 }
    120         }
    121 
    122         private static class RestrictionImpl implements Restriction {
    123                 private final Segment from;
    124                 private final Collection<Segment> vias;
    125                 private final Collection<Segment> tos;
    126 
    127                 /** constructor, will directly use collection references, collections must not be changed after usage as constructor param */
    128                 public RestrictionImpl(Segment from, Collection<Segment> vias, Collection<Segment> tos) {
    129                         this.from = from;
    130                         this.vias = Collections.unmodifiableCollection(vias);
    131                         this.tos = Collections.unmodifiableCollection(tos);
    132                 }
    133 
    134                 public Segment getFrom() {
    135                         return from;
    136                 }
    137                 public Collection<Segment> getVias() {
    138                         return vias;
    139                 }
    140                 public Collection<Segment> getTos() {
    141                         return tos;
    142                 }
    143 
    144                 @Override
    145                 public String toString() {
    146                         return from + " -> " + vias + " -> " + tos;
    147                 }
    148         }
    149 
    150         private final Set<TransitionStructureObserver> observers = new HashSet<TransitionStructureObserver>();
    151 
    152         private final Collection<RoadPropertyType<?>> properties;
    153 
    154         private final DataSource<N, W, R, M> dataSource;
    155 
    156         private AccessParameters accessParameters;
    157         private AccessRuleset ruleset;
    158 
    159         private AccessEvaluator<N, W> accessEvaluator;
    160 
    161         private Collection<SegmentNode> nodes = null;
    162         private Collection<Segment> segments = new LinkedList<Segment>();
    163         private Collection<Restriction> restrictions = new LinkedList<Restriction>();
    164 
    165         public GenericTransitionStructure(
    166                         AccessParameters accessParameters, AccessRuleset ruleset,
    167                         DataSource<N, W, R, M> dataSource,
    168                         Collection<RoadPropertyType<?>> properties) {
    169 
    170                 assert accessParameters != null && ruleset != null;
    171                 assert dataSource != null;
    172                 assert properties != null;
    173 
    174                 this.dataSource = dataSource;
    175 
    176                 this.properties = properties;
    177 
    178                 setAccessParametersAndRuleset(accessParameters, ruleset);
    179 
    180                 dataSource.addObserver(this);
    181         }
    182 
    183         /**
    184         * sets new access parameters and/or a new ruleset.
    185         * Causes a data update if at least one is actually changed.
    186         *
    187         * @param accessParameters  new access parameters, null indicates no change
    188         * @param ruleset           new ruleset, null indicates no change
    189         */
    190         public void setAccessParametersAndRuleset(AccessParameters accessParameters, AccessRuleset ruleset) {
    191 
    192                 if (accessParameters != null) {
    193                         this.accessParameters = accessParameters;
    194                 }
    195                 if (ruleset != null) {
    196                         this.ruleset = ruleset;
    197                 }
    198 
    199                 if (accessParameters != null || ruleset != null) {
    200 
    201                         assert dataSource != null;
    202 
    203                         accessEvaluator = new RulesetAccessEvaluator<N, W, R, M>(
    204                                         dataSource,
    205                                         this.ruleset,
    206                                         this.accessParameters);
    207 
    208                         updateData();
    209                         notifyObservers();
    210 
    211                 }
    212 
    213         }
    214 
    215         public Collection<SegmentNode> getNodes() {
    216                 return nodes;
    217         }
    218 
    219         public Collection<Segment> getSegments() {
    220                 return segments;
    221         }
    222 
    223         public Collection<Restriction> getRestrictions() {
    224                 return restrictions;
    225         }
    226 
    227         /**
    228         * creates nodes, segments and restrictions based on the data source
    229         */
    230         protected void updateData() {
    231 
    232                 ArrayList<SegmentNode> nodes = new ArrayList<SegmentNode>();
    233                 ArrayList<Segment> segments = new ArrayList<Segment>();
    234 
    235                 Map<N, SegmentNodeImpl> nodeCreationMap = new HashMap<N, SegmentNodeImpl>();
    236                 Map<W, List<Segment>> waySegmentMap = new HashMap<W, List<Segment>>();
    237 
    238                 /* create segments (nodes are created only when included in a segment) */
    239 
    240                 for (W way : dataSource.getWays()) {
    241                         createSegmentsAndSegmentNodes(way, accessEvaluator, nodes, segments, nodeCreationMap, waySegmentMap);
    242                 }
    243 
    244                 nodes.trimToSize();
    245                 segments.trimToSize();
    246 
    247                 /* create restrictions */
    248 
    249                 Collection<Restriction> restrictions =
    250                         createRestrictionsFromTurnRestrictions(dataSource.getRelations(), nodeCreationMap, waySegmentMap);
    251 
    252                 restrictions.addAll(createRestrictionsFromBarrierNodes(nodeCreationMap, waySegmentMap));
    253 
    254                 /* keep data and inform observers */
    255 
    256                 this.nodes = nodes;
    257                 this.segments = segments;
    258                 this.restrictions = restrictions;
    259 
    260                 notifyObservers();
    261 
    262         }
    263 
    264         /**
    265         * creates all Segments and SegmentNodes for a way
    266         *
    267         * @param way                 way to create Segments and SegmentNodes from; != null
    268         * @param wayAccessEvaluator  evaluator object that decides whether way is usable; != null
    269         * @param nodes               collection of SegmentNodes, new SegmentNodes will be added here; != null
    270         * @param segments            collection of Segments, new Segments will be added here; != null
    271         * @param nodeCreationMap     map providing the SegmentNode that has been created from a Node,
    272         *                            if new SegmentNodes are created, they will be added appropriately; != null
    273         * @param waySegmentMap       map providing the Segments that have been created from a Way,
    274         *                            if new Segments are created, they will be added appropriately; != null
    275         */
    276         private void createSegmentsAndSegmentNodes(W way, AccessEvaluator<N, W> wayAccessEvaluator,
    277                         Collection<SegmentNode> nodes, Collection<Segment> segments,
    278                         Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap) {
    279 
    280                 assert way != null && wayAccessEvaluator != null && nodes != null && segments != null && nodeCreationMap != null && waySegmentMap != null;
    281 
    282                 /* calculate property values */
    283 
    284                 Map<RoadPropertyType<?>, Object> forwardPropertyValues = getWayPropertyMap(way, true);
    285                 Map<RoadPropertyType<?>, Object> backwardPropertyValues = getWayPropertyMap(way, false);
    286 
    287                 /* create segments from the way if it can be accessed and isn't incomplete or deleted */
    288 
    289                 boolean forwardAccess = wayAccessEvaluator.wayUsable(way, true, forwardPropertyValues);
    290                 boolean backwardAccess = wayAccessEvaluator.wayUsable(way, false, backwardPropertyValues);
    291 
    292                 if (forwardAccess || backwardAccess) {
    293 
    294                         if (!waySegmentMap.containsKey(way)) {
    295                                 waySegmentMap.put(way, new LinkedList<Segment>());
    296                         }
    297 
    298                         /* create segments from all pairs of subsequent nodes */
    299 
    300                         N previousNode = null;
    301                         for (N node : dataSource.getNodes(way)) {
    302                                 if (previousNode != null) {
    303 
    304                                         SegmentNodeImpl node1 =
    305                                                 getOrCreateSegmentNodeForNode(previousNode, nodes, nodeCreationMap);
    306                                         SegmentNodeImpl node2 =
    307                                                 getOrCreateSegmentNodeForNode(node, nodes, nodeCreationMap);
    308 
    309                                         if (forwardAccess) {
    310                                                 SegmentImpl segment = new SegmentImpl(node1, node2, forwardPropertyValues);
    311                                                 segments.add(segment);
    312                                                 waySegmentMap.get(way).add(segment);
    313                                                 node1.addOutboundSegment(segment);
    314                                                 node2.addInboundSegment(segment);
    315                                         }
    316                                         if (backwardAccess) { //no "else if" because both can be valid
    317                                                 SegmentImpl segment = new SegmentImpl(node2, node1, backwardPropertyValues);
    318                                                 segments.add(segment);
    319                                                 waySegmentMap.get(way).add(segment);
    320                                                 node1.addInboundSegment(segment);
    321                                                 node2.addOutboundSegment(segment);
    322                                         }
    323 
    324                                 }
    325                                 previousNode = node;
    326                         }
    327 
    328                 }
    329         }
    330 
    331         /**
    332         * if no segment node for a node exists in the nodeCreationMap,
    333         * creates a segment node for it and adds it to the nodeCreationMap and the nodes collection
    334         * and returns it; otherwise returns the existing segment node.
    335         */
    336         private SegmentNodeImpl getOrCreateSegmentNodeForNode(N node,
    337                         Collection<SegmentNode> nodes, Map<N, SegmentNodeImpl> nodeCreationMap) {
    338 
    339                 SegmentNodeImpl segmentNode = nodeCreationMap.get(node);
    340 
    341                 if (segmentNode == null) {
    342 
    343                         Map<RoadPropertyType<?>, Object> nodePropertyValues = getNodePropertyMap(node);
    344                         segmentNode = new SegmentNodeImpl(dataSource.getLat(node), dataSource.getLon(node),
    345                                         nodePropertyValues);
    346 
    347                         nodeCreationMap.put(node, segmentNode);
    348                         nodes.add(segmentNode);
    349 
    350                 }
    351 
    352                 return segmentNode;
    353         }
    354 
    355         /**
    356         * creates all Restrictions from a collection of Relations.
    357         * Only "type=restriction" relations are relevant for restrictions.
    358         *
    359         * @param relations        Relations to create Restrictions from.
    360         *                         They can have any type key, as filtering is done inside this method.
    361         * @param nodeCreationMap  map providing the SegmentNode that has been created from a Node,
    362         *                         will not be modified; != null
    363         * @param waySegmentMap    map providing the Segments that have been created from a Way,
    364         *                         will not be modified; != null
    365         * @return                 Restrictions created from the Relations; != null, but may be empty
    366         */
    367         private Collection<Restriction> createRestrictionsFromTurnRestrictions(
    368                         Iterable<R> relations,
    369                         Map<N, SegmentNodeImpl> nodeCreationMap,
    370                         Map<W, List<Segment>> waySegmentMap) {
    371 
    372                 assert relations != null && nodeCreationMap != null && waySegmentMap != null;
    373 
    374                 Collection<Restriction> results = new LinkedList<Restriction>();
    375 
    376                 for (R relation : relations) {
    377 
    378                         TagGroup tags = dataSource.getTagsR(relation);
    379 
    380                         if ("restriction".equals(tags.getValue("type"))
    381                                         && tags.getValue("restriction") != null ) {
    382 
    383                                 //evaluate relation
    384                                 if (tags.getValue("restriction").startsWith("no_")) {
    385                                         results.addAll(createRestrictionsFromRestrictionRelation(relation, true, nodeCreationMap, waySegmentMap));
    386                                 } else if (tags.getValue("restriction").startsWith("only_")) {
    387                                         results.addAll(createRestrictionsFromRestrictionRelation(relation, false, nodeCreationMap, waySegmentMap));
    388                                 }
    389 
    390                         }
    391                 }
    392 
    393                 return results;
    394         }
    395 
    396         @SuppressWarnings("unchecked") //several generic casts that are checked with isInstance
    397         private Collection<Restriction> createRestrictionsFromRestrictionRelation(
    398                         R relation,
    399                         boolean restrictive,
    400                         Map<N, SegmentNodeImpl> nodeCreationMap,
    401                         Map<W, List<Segment>> waySegmentMap) {
    402 
    403                 /* collect information about the relation */
    404 
    405                 W fromWay = null;
    406                 Collection<N> viaNodes = new LinkedList<N>();
    407                 Collection<W> viaWays = new LinkedList<W>();
    408                 Collection<W> toWays = new LinkedList<W>();
    409 
    410                 for (M member : dataSource.getMembers(relation)) {
    411 
    412                         if ("from".equals(dataSource.getRole(member))) {
    413                                 if (fromWay != null || !dataSource.isWMember(member)) {
    414                                         //broken restriction
    415                                         return EMPTY_RESTRICTION_COLLECTION;
    416                                 } else {
    417                                         fromWay = (W)dataSource.getMember(member);
    418                                 }
    419                         } else if ("to".equals(dataSource.getRole(member))) {
    420                                 if (!dataSource.isWMember(member)) {
    421                                         //broken restriction
    422                                         return EMPTY_RESTRICTION_COLLECTION;
    423                                 } else {
    424                                         toWays.add((W)dataSource.getMember(member));
    425                                 }
    426                         } else if ("via".equals(dataSource.getRole(member))) {
    427                                 if (dataSource.isWMember(member)) {
    428                                         viaWays.add((W)dataSource.getMember(member));
    429                                 } else if (dataSource.isNMember(member)) {
    430                                         viaNodes.add((N)dataSource.getMember(member));
    431                                 }
    432                         }
    433 
    434                 }
    435 
    436                 if (fromWay != null && toWays.size() > 0 &&
    437                                 (viaNodes.size() > 0 || viaWays.size() > 0)) {
    438 
    439                         return createRestrictionsFromRestrictionRelationMembers(
    440                                         restrictive, nodeCreationMap, waySegmentMap,
    441                                         fromWay, viaNodes, viaWays, toWays);
    442 
    443                 } else {
    444                         return new ArrayList<Restriction>(0);
    445                 }
    446         }
    447 
    448         private Collection<Restriction> createRestrictionsFromRestrictionRelationMembers(
    449                         boolean restrictive,
    450                         Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap,
    451                         W fromWay, Collection<N> viaNodes, Collection<W> viaWays, Collection<W> toWays) {
    452 
    453                 Collection<SegmentNode> nodesCreatedFromViaNodes = new ArrayList<SegmentNode>(viaNodes.size());
    454                 for (N viaNode : viaNodes) {
    455                         if (nodeCreationMap.containsKey(viaNode)) {
    456                                 nodesCreatedFromViaNodes.add(nodeCreationMap.get(viaNode));
    457                         }
    458                 }
    459 
    460                 /* check completeness of restriction to avoid dealing with incomplete restriction info */
    461 
    462                 if (!waySegmentMap.containsKey(fromWay)) {
    463                         //broken restriction
    464                         return EMPTY_RESTRICTION_COLLECTION;
    465                 }
    466 
    467                 for (W viaWay : viaWays) {
    468                         if (!waySegmentMap.containsKey(viaWay)) {
    469                                 //broken restriction
    470                                 return EMPTY_RESTRICTION_COLLECTION;
    471                         }
    472                 }
    473 
    474                 for (W toWay : toWays) {
    475                         if (!waySegmentMap.containsKey(toWay)) {
    476                                 //broken restriction
    477                                 return EMPTY_RESTRICTION_COLLECTION;
    478                         }
    479                 }
    480 
    481                 /* find all via segments:
    482                 * via segments are segments created from via ways
    483                 * or segments starting and ending with nodes created from via nodes */
    484 
    485                 ArrayList<Segment> viaSegments = new ArrayList<Segment>();
    486 
    487                 for (W viaWay : viaWays) {
    488                         viaSegments.addAll(waySegmentMap.get(viaWay));
    489                 }
    490 
    491                 for (SegmentNode nodeCreatedFromViaNode : nodesCreatedFromViaNodes) {
    492                         for (Segment segment : nodeCreatedFromViaNode.getOutboundSegments()) {
    493                                 if (nodesCreatedFromViaNodes.contains(segment.getNode2())) {
    494                                         viaSegments.add(segment);
    495                                 }
    496                         }
    497                 }
    498 
    499                 viaSegments.trimToSize();
    500 
    501                 /* create a set with all nodes that are based on via members */
    502 
    503                 Set<SegmentNode> nodesCreatedFromViaMembers
    504                 = new HashSet<SegmentNode>(nodesCreatedFromViaNodes);
    505 
    506                 for (W viaWay : viaWays) {
    507                         for (N viaWayNode : dataSource.getNodes(viaWay)) {
    508                                 nodesCreatedFromViaMembers.add(nodeCreationMap.get(viaWayNode));
    509                         }
    510                 }
    511 
    512                 /*
    513                 * find from segment and to segments:
    514                 * Such a segment contains a node based on a via member.
    515                 * Each way should contain only one possible segment
    516                 * connecting to via members (due to splitting).
    517                 */
    518 
    519                 Segment fromSegment = null;
    520                 Collection<Segment> toSegments = new ArrayList<Segment>();
    521 
    522                 for (Segment possibleFromSegment : waySegmentMap.get(fromWay)) {
    523                         if (nodesCreatedFromViaMembers.contains(possibleFromSegment.getNode2())) {
    524 
    525                                 if (fromSegment == null) {
    526                                         fromSegment = possibleFromSegment;
    527                                 } else {
    528                                         //broken restriction
    529                                         return EMPTY_RESTRICTION_COLLECTION;
    530                                 }
    531 
    532                         }
    533                 }
    534                 if (fromSegment == null) {
    535                         //broken restriction
    536                         return EMPTY_RESTRICTION_COLLECTION;
    537                 }
    538 
    539                 if (restrictive) {
    540 
    541                         for (W toWay : toWays) {
    542                                 if (waySegmentMap.containsKey(toWay)) {
    543                                         Segment toSegment = null;
    544                                         for (Segment possibleToSegment : waySegmentMap.get(toWay)) {
    545                                                 if (nodesCreatedFromViaMembers.contains(possibleToSegment.getNode1())) {
    546 
    547                                                         if (toSegment == null) {
    548                                                                 toSegment = possibleToSegment;
    549                                                         } else {
    550                                                                 //broken restriction
    551                                                                 return EMPTY_RESTRICTION_COLLECTION;
    552                                                         }
    553 
    554                                                 }
    555                                         }
    556                                         if (toSegment == null) {
    557                                                 //broken restriction
    558                                                 return EMPTY_RESTRICTION_COLLECTION;
    559                                         } else {
    560                                                 toSegments.add(toSegment);
    561                                         }
    562                                 }
    563                         }
    564 
    565                 } else { //!restrictive
    566 
    567                         /* forbidden "to" segments are all segments that start at a "via" node
    568                         * and are neither a via segment nor created from an allowed "to" way */
    569 
    570                         for (SegmentNode toStartingNode : nodesCreatedFromViaMembers) {
    571                                 for (Segment outboundSegment : toStartingNode.getOutboundSegments()) {
    572 
    573                                         if (!viaSegments.contains(outboundSegment)) {
    574 
    575                                                 boolean isAllowed = false;
    576 
    577                                                 for (W toWay : toWays) {
    578                                                         if (waySegmentMap.get(toWay).contains(outboundSegment)) {
    579                                                                 isAllowed = true;
    580                                                                 break;
    581                                                         }
    582                                                 }
    583 
    584                                                 if (!isAllowed) {
    585                                                         toSegments.add(outboundSegment);
    586                                                 }
    587 
    588                                         }
    589 
    590                                 }
    591                         }
    592 
    593                 }
    594 
    595                 /* create restriction */
    596 
    597                 Collection<Restriction> results = new ArrayList<Restriction>(1);
    598                 results.add(new RestrictionImpl(fromSegment, viaSegments, toSegments));
    599                 return results;
    600         }
    601 
    602         /**
    603         * creates Restrictions from barrier nodes (nodes that are considered impassable by the
    604         * {@link #accessEvaluator}). These restrictions prevent moving from a segment before the
    605         * barrier node to a segment after the barrier node.
    606         *
    607         * @param nodeCreationMap  map providing the SegmentNode that has been created from a node,
    608         *                         will not be modified; != null
    609         * @param waySegmentMap    map providing the Segments that have been created from a way,
    610         *                         will not be modified; != null
    611         * @return                 Restrictions created from barrier nodes; != null, but may be empty
    612         */
    613         private Collection<Restriction> createRestrictionsFromBarrierNodes(
    614                         Map<N, SegmentNodeImpl> nodeCreationMap,
    615                         Map<W, List<Segment>> waySegmentMap) {
    616 
    617                 assert nodeCreationMap != null;
    618                 assert waySegmentMap != null;
    619 
    620                 Collection<Restriction> results = new LinkedList<Restriction>();
    621 
    622                 for (N node : nodeCreationMap.keySet()) {
    623 
    624                         if (!accessEvaluator.nodeUsable(node, nodeCreationMap.get(node).getProperties())) {
    625 
    626                                 SegmentNode barrierNode = nodeCreationMap.get(node);
    627 
    628                                 for (Segment inboundSegment : barrierNode.getInboundSegments()) {
    629                                         for (Segment outboundSegment : barrierNode.getOutboundSegments()) {
    630                                                 results.add(new RestrictionImpl(inboundSegment, EMPTY_SEGMENT_LIST, Arrays.asList(outboundSegment)));
    631                                         }
    632                                 }
    633 
    634                         }
    635 
    636                 }
    637 
    638                 return results;
    639         }
    640 
    641         /**
    642         * determines the values of all RoadPropertyTypes from {@link #properties} for a way and
    643         * creates a map with the types that have non-null values as keys, property values as content
    644         */
    645         private Map<RoadPropertyType<?>, Object> getWayPropertyMap(W way, boolean forward) {
    646                 Map<RoadPropertyType<?>, Object> propertyValues;
    647                 propertyValues = new HashMap<RoadPropertyType<?>, Object>();
    648                 for (RoadPropertyType<?> property : properties) {
    649                         Object value = property.evaluateW(way, forward, accessParameters, dataSource);
    650                         if (value != null) {
    651                                 propertyValues.put(property, value);
    652                         }
    653                 }
    654                 return propertyValues;
    655         }
    656 
    657         /**
    658         * determines the values of all RoadPropertyTypes from {@link #properties} for a node and
    659         * creates a map with the types that have non-null values as keys, property values as content
    660         */
    661         private Map<RoadPropertyType<?>, Object> getNodePropertyMap(N node) {
    662                 Map<RoadPropertyType<?>, Object> propertyValues;
    663                 propertyValues = new HashMap<RoadPropertyType<?>, Object>();
    664                 for (RoadPropertyType<?> property : properties) {
    665                         Object value = property.evaluateN(node, accessParameters, dataSource);
    666                         if (value != null) {
    667                                 propertyValues.put(property, value);
    668                         }
    669                 }
    670                 return propertyValues;
    671         }
    672 
    673         public void update(DataSource<?, ?, ?, ?> dataSource) {
    674                 assert this.dataSource == dataSource;
    675                 updateData();
    676         }
    677 
    678         public void addObserver(TransitionStructureObserver observer) {
    679                 observers.add(observer);
    680         }
    681 
    682         public void deleteObserver(TransitionStructureObserver observer) {
    683                 observers.remove(observer);
    684         }
    685 
    686         protected void notifyObservers() {
    687                 for (TransitionStructureObserver observer : observers) {
    688                         observer.update(this);
    689                 }
    690         }
     32    private static final Collection<Segment> EMPTY_SEGMENT_LIST =
     33        Collections.unmodifiableList(new ArrayList<Segment>(0));
     34    private static final Collection<Restriction> EMPTY_RESTRICTION_COLLECTION =
     35        new ArrayList<Restriction>(0);
     36
     37    private static class SegmentNodeImpl implements SegmentNode {
     38        private final double lat;
     39        private final double lon;
     40        private final List<Segment> inboundSegments = new LinkedList<Segment>();
     41        private final List<Segment> outboundSegments = new LinkedList<Segment>();
     42        private final Map<RoadPropertyType<?>, Object> properties;
     43        public SegmentNodeImpl(double lat, double lon, Map<RoadPropertyType<?>, Object> properties) {
     44            assert properties != null;
     45            this.lat = lat;
     46            this.lon = lon;
     47            this.properties = properties;
     48        }
     49        public double getLat() {
     50            return lat;
     51        }
     52        public double getLon() {
     53            return lon;
     54        }
     55        public void addInboundSegment(Segment segment) {
     56            inboundSegments.add(segment);
     57        }
     58        public void addOutboundSegment(Segment segment) {
     59            outboundSegments.add(segment);
     60        }
     61        public Collection<Segment> getOutboundSegments() {
     62            return outboundSegments;
     63        }
     64        public Collection<Segment> getInboundSegments() {
     65            return inboundSegments;
     66        }
     67
     68        public <P> void setProperty(RoadPropertyType<P> property, P value) {
     69            properties.put(property, value);
     70        }
     71        public Collection<RoadPropertyType<?>> getAvailableProperties() {
     72            return properties.keySet();
     73        }
     74        public <P> P getPropertyValue(RoadPropertyType<P> property) {
     75            @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
     76            P result = (P) properties.get(property);
     77            return result;
     78        }
     79        public Map<RoadPropertyType<?>, Object> getProperties() {
     80            return properties;
     81        }
     82
     83        @Override
     84        public String toString() {
     85            return "(" + lat + ", " + lon + ")";
     86        }
     87    }
     88
     89    private static class SegmentImpl implements Segment {
     90        private final SegmentNode node1;
     91        private final SegmentNode node2;
     92        private final Map<RoadPropertyType<?>, Object> properties;
     93        public SegmentImpl(SegmentNode node1, SegmentNode node2, Map<RoadPropertyType<?>, Object> properties) {
     94            this.node1 = node1;
     95            this.node2 = node2;
     96            this.properties = properties;
     97        }
     98        public SegmentNode getNode1() {
     99            return node1;
     100        }
     101        public SegmentNode getNode2() {
     102            return node2;
     103        }
     104        public <P> void setProperty(RoadPropertyType<P> property, P value) {
     105            properties.put(property, value);
     106        }
     107        public Collection<RoadPropertyType<?>> getAvailableProperties() {
     108            return properties.keySet();
     109        }
     110        public <P> P getPropertyValue(RoadPropertyType<P> property) {
     111            @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
     112            P result = (P) properties.get(property);
     113            return result;
     114        }
     115
     116        @Override
     117        public String toString() {
     118            return "(" + node1 + "->" + node2 + ")";
     119        }
     120    }
     121
     122    private static class RestrictionImpl implements Restriction {
     123        private final Segment from;
     124        private final Collection<Segment> vias;
     125        private final Collection<Segment> tos;
     126
     127        /** constructor, will directly use collection references, collections must not be changed after usage as constructor param */
     128        public RestrictionImpl(Segment from, Collection<Segment> vias, Collection<Segment> tos) {
     129            this.from = from;
     130            this.vias = Collections.unmodifiableCollection(vias);
     131            this.tos = Collections.unmodifiableCollection(tos);
     132        }
     133
     134        public Segment getFrom() {
     135            return from;
     136        }
     137        public Collection<Segment> getVias() {
     138            return vias;
     139        }
     140        public Collection<Segment> getTos() {
     141            return tos;
     142        }
     143
     144        @Override
     145        public String toString() {
     146            return from + " -> " + vias + " -> " + tos;
     147        }
     148    }
     149
     150    private final Set<TransitionStructureObserver> observers = new HashSet<TransitionStructureObserver>();
     151
     152    private final Collection<RoadPropertyType<?>> properties;
     153
     154    private final DataSource<N, W, R, M> dataSource;
     155
     156    private AccessParameters accessParameters;
     157    private AccessRuleset ruleset;
     158
     159    private AccessEvaluator<N, W> accessEvaluator;
     160
     161    private Collection<SegmentNode> nodes = null;
     162    private Collection<Segment> segments = new LinkedList<Segment>();
     163    private Collection<Restriction> restrictions = new LinkedList<Restriction>();
     164
     165    public GenericTransitionStructure(
     166            AccessParameters accessParameters, AccessRuleset ruleset,
     167            DataSource<N, W, R, M> dataSource,
     168            Collection<RoadPropertyType<?>> properties) {
     169
     170        assert accessParameters != null && ruleset != null;
     171        assert dataSource != null;
     172        assert properties != null;
     173
     174        this.dataSource = dataSource;
     175
     176        this.properties = properties;
     177
     178        setAccessParametersAndRuleset(accessParameters, ruleset);
     179
     180        dataSource.addObserver(this);
     181    }
     182
     183    /**
     184    * sets new access parameters and/or a new ruleset.
     185    * Causes a data update if at least one is actually changed.
     186    *
     187    * @param accessParameters  new access parameters, null indicates no change
     188    * @param ruleset           new ruleset, null indicates no change
     189    */
     190    public void setAccessParametersAndRuleset(AccessParameters accessParameters, AccessRuleset ruleset) {
     191
     192        if (accessParameters != null) {
     193            this.accessParameters = accessParameters;
     194        }
     195        if (ruleset != null) {
     196            this.ruleset = ruleset;
     197        }
     198
     199        if (accessParameters != null || ruleset != null) {
     200
     201            assert dataSource != null;
     202
     203            accessEvaluator = new RulesetAccessEvaluator<N, W, R, M>(
     204                    dataSource,
     205                    this.ruleset,
     206                    this.accessParameters);
     207
     208            updateData();
     209            notifyObservers();
     210
     211        }
     212
     213    }
     214
     215    public Collection<SegmentNode> getNodes() {
     216        return nodes;
     217    }
     218
     219    public Collection<Segment> getSegments() {
     220        return segments;
     221    }
     222
     223    public Collection<Restriction> getRestrictions() {
     224        return restrictions;
     225    }
     226
     227    /**
     228    * creates nodes, segments and restrictions based on the data source
     229    */
     230    protected void updateData() {
     231
     232        ArrayList<SegmentNode> nodes = new ArrayList<SegmentNode>();
     233        ArrayList<Segment> segments = new ArrayList<Segment>();
     234
     235        Map<N, SegmentNodeImpl> nodeCreationMap = new HashMap<N, SegmentNodeImpl>();
     236        Map<W, List<Segment>> waySegmentMap = new HashMap<W, List<Segment>>();
     237
     238        /* create segments (nodes are created only when included in a segment) */
     239
     240        for (W way : dataSource.getWays()) {
     241            createSegmentsAndSegmentNodes(way, accessEvaluator, nodes, segments, nodeCreationMap, waySegmentMap);
     242        }
     243
     244        nodes.trimToSize();
     245        segments.trimToSize();
     246
     247        /* create restrictions */
     248
     249        Collection<Restriction> restrictions =
     250            createRestrictionsFromTurnRestrictions(dataSource.getRelations(), nodeCreationMap, waySegmentMap);
     251
     252        restrictions.addAll(createRestrictionsFromBarrierNodes(nodeCreationMap, waySegmentMap));
     253
     254        /* keep data and inform observers */
     255
     256        this.nodes = nodes;
     257        this.segments = segments;
     258        this.restrictions = restrictions;
     259
     260        notifyObservers();
     261
     262    }
     263
     264    /**
     265    * creates all Segments and SegmentNodes for a way
     266    *
     267    * @param way                 way to create Segments and SegmentNodes from; != null
     268    * @param wayAccessEvaluator  evaluator object that decides whether way is usable; != null
     269    * @param nodes               collection of SegmentNodes, new SegmentNodes will be added here; != null
     270    * @param segments            collection of Segments, new Segments will be added here; != null
     271    * @param nodeCreationMap     map providing the SegmentNode that has been created from a Node,
     272    *                            if new SegmentNodes are created, they will be added appropriately; != null
     273    * @param waySegmentMap       map providing the Segments that have been created from a Way,
     274    *                            if new Segments are created, they will be added appropriately; != null
     275    */
     276    private void createSegmentsAndSegmentNodes(W way, AccessEvaluator<N, W> wayAccessEvaluator,
     277            Collection<SegmentNode> nodes, Collection<Segment> segments,
     278            Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap) {
     279
     280        assert way != null && wayAccessEvaluator != null && nodes != null && segments != null && nodeCreationMap != null && waySegmentMap != null;
     281
     282        /* calculate property values */
     283
     284        Map<RoadPropertyType<?>, Object> forwardPropertyValues = getWayPropertyMap(way, true);
     285        Map<RoadPropertyType<?>, Object> backwardPropertyValues = getWayPropertyMap(way, false);
     286
     287        /* create segments from the way if it can be accessed and isn't incomplete or deleted */
     288
     289        boolean forwardAccess = wayAccessEvaluator.wayUsable(way, true, forwardPropertyValues);
     290        boolean backwardAccess = wayAccessEvaluator.wayUsable(way, false, backwardPropertyValues);
     291
     292        if (forwardAccess || backwardAccess) {
     293
     294            if (!waySegmentMap.containsKey(way)) {
     295                waySegmentMap.put(way, new LinkedList<Segment>());
     296            }
     297
     298            /* create segments from all pairs of subsequent nodes */
     299
     300            N previousNode = null;
     301            for (N node : dataSource.getNodes(way)) {
     302                if (previousNode != null) {
     303
     304                    SegmentNodeImpl node1 =
     305                        getOrCreateSegmentNodeForNode(previousNode, nodes, nodeCreationMap);
     306                    SegmentNodeImpl node2 =
     307                        getOrCreateSegmentNodeForNode(node, nodes, nodeCreationMap);
     308
     309                    if (forwardAccess) {
     310                        SegmentImpl segment = new SegmentImpl(node1, node2, forwardPropertyValues);
     311                        segments.add(segment);
     312                        waySegmentMap.get(way).add(segment);
     313                        node1.addOutboundSegment(segment);
     314                        node2.addInboundSegment(segment);
     315                    }
     316                    if (backwardAccess) { //no "else if" because both can be valid
     317                        SegmentImpl segment = new SegmentImpl(node2, node1, backwardPropertyValues);
     318                        segments.add(segment);
     319                        waySegmentMap.get(way).add(segment);
     320                        node1.addInboundSegment(segment);
     321                        node2.addOutboundSegment(segment);
     322                    }
     323
     324                }
     325                previousNode = node;
     326            }
     327
     328        }
     329    }
     330
     331    /**
     332    * if no segment node for a node exists in the nodeCreationMap,
     333    * creates a segment node for it and adds it to the nodeCreationMap and the nodes collection
     334    * and returns it; otherwise returns the existing segment node.
     335    */
     336    private SegmentNodeImpl getOrCreateSegmentNodeForNode(N node,
     337            Collection<SegmentNode> nodes, Map<N, SegmentNodeImpl> nodeCreationMap) {
     338
     339        SegmentNodeImpl segmentNode = nodeCreationMap.get(node);
     340
     341        if (segmentNode == null) {
     342
     343            Map<RoadPropertyType<?>, Object> nodePropertyValues = getNodePropertyMap(node);
     344            segmentNode = new SegmentNodeImpl(dataSource.getLat(node), dataSource.getLon(node),
     345                    nodePropertyValues);
     346
     347            nodeCreationMap.put(node, segmentNode);
     348            nodes.add(segmentNode);
     349
     350        }
     351
     352        return segmentNode;
     353    }
     354
     355    /**
     356    * creates all Restrictions from a collection of Relations.
     357    * Only "type=restriction" relations are relevant for restrictions.
     358    *
     359    * @param relations        Relations to create Restrictions from.
     360    *                         They can have any type key, as filtering is done inside this method.
     361    * @param nodeCreationMap  map providing the SegmentNode that has been created from a Node,
     362    *                         will not be modified; != null
     363    * @param waySegmentMap    map providing the Segments that have been created from a Way,
     364    *                         will not be modified; != null
     365    * @return                 Restrictions created from the Relations; != null, but may be empty
     366    */
     367    private Collection<Restriction> createRestrictionsFromTurnRestrictions(
     368            Iterable<R> relations,
     369            Map<N, SegmentNodeImpl> nodeCreationMap,
     370            Map<W, List<Segment>> waySegmentMap) {
     371
     372        assert relations != null && nodeCreationMap != null && waySegmentMap != null;
     373
     374        Collection<Restriction> results = new LinkedList<Restriction>();
     375
     376        for (R relation : relations) {
     377
     378            TagGroup tags = dataSource.getTagsR(relation);
     379
     380            if ("restriction".equals(tags.getValue("type"))
     381                    && tags.getValue("restriction") != null ) {
     382
     383                //evaluate relation
     384                if (tags.getValue("restriction").startsWith("no_")) {
     385                    results.addAll(createRestrictionsFromRestrictionRelation(relation, true, nodeCreationMap, waySegmentMap));
     386                } else if (tags.getValue("restriction").startsWith("only_")) {
     387                    results.addAll(createRestrictionsFromRestrictionRelation(relation, false, nodeCreationMap, waySegmentMap));
     388                }
     389
     390            }
     391        }
     392
     393        return results;
     394    }
     395
     396    @SuppressWarnings("unchecked") //several generic casts that are checked with isInstance
     397    private Collection<Restriction> createRestrictionsFromRestrictionRelation(
     398            R relation,
     399            boolean restrictive,
     400            Map<N, SegmentNodeImpl> nodeCreationMap,
     401            Map<W, List<Segment>> waySegmentMap) {
     402
     403        /* collect information about the relation */
     404
     405        W fromWay = null;
     406        Collection<N> viaNodes = new LinkedList<N>();
     407        Collection<W> viaWays = new LinkedList<W>();
     408        Collection<W> toWays = new LinkedList<W>();
     409
     410        for (M member : dataSource.getMembers(relation)) {
     411
     412            if ("from".equals(dataSource.getRole(member))) {
     413                if (fromWay != null || !dataSource.isWMember(member)) {
     414                    //broken restriction
     415                    return EMPTY_RESTRICTION_COLLECTION;
     416                } else {
     417                    fromWay = (W)dataSource.getMember(member);
     418                }
     419            } else if ("to".equals(dataSource.getRole(member))) {
     420                if (!dataSource.isWMember(member)) {
     421                    //broken restriction
     422                    return EMPTY_RESTRICTION_COLLECTION;
     423                } else {
     424                    toWays.add((W)dataSource.getMember(member));
     425                }
     426            } else if ("via".equals(dataSource.getRole(member))) {
     427                if (dataSource.isWMember(member)) {
     428                    viaWays.add((W)dataSource.getMember(member));
     429                } else if (dataSource.isNMember(member)) {
     430                    viaNodes.add((N)dataSource.getMember(member));
     431                }
     432            }
     433
     434        }
     435
     436        if (fromWay != null && toWays.size() > 0 &&
     437                (viaNodes.size() > 0 || viaWays.size() > 0)) {
     438
     439            return createRestrictionsFromRestrictionRelationMembers(
     440                    restrictive, nodeCreationMap, waySegmentMap,
     441                    fromWay, viaNodes, viaWays, toWays);
     442
     443        } else {
     444            return new ArrayList<Restriction>(0);
     445        }
     446    }
     447
     448    private Collection<Restriction> createRestrictionsFromRestrictionRelationMembers(
     449            boolean restrictive,
     450            Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap,
     451            W fromWay, Collection<N> viaNodes, Collection<W> viaWays, Collection<W> toWays) {
     452
     453        Collection<SegmentNode> nodesCreatedFromViaNodes = new ArrayList<SegmentNode>(viaNodes.size());
     454        for (N viaNode : viaNodes) {
     455            if (nodeCreationMap.containsKey(viaNode)) {
     456                nodesCreatedFromViaNodes.add(nodeCreationMap.get(viaNode));
     457            }
     458        }
     459
     460        /* check completeness of restriction to avoid dealing with incomplete restriction info */
     461
     462        if (!waySegmentMap.containsKey(fromWay)) {
     463            //broken restriction
     464            return EMPTY_RESTRICTION_COLLECTION;
     465        }
     466
     467        for (W viaWay : viaWays) {
     468            if (!waySegmentMap.containsKey(viaWay)) {
     469                //broken restriction
     470                return EMPTY_RESTRICTION_COLLECTION;
     471            }
     472        }
     473
     474        for (W toWay : toWays) {
     475            if (!waySegmentMap.containsKey(toWay)) {
     476                //broken restriction
     477                return EMPTY_RESTRICTION_COLLECTION;
     478            }
     479        }
     480
     481        /* find all via segments:
     482        * via segments are segments created from via ways
     483        * or segments starting and ending with nodes created from via nodes */
     484
     485        ArrayList<Segment> viaSegments = new ArrayList<Segment>();
     486
     487        for (W viaWay : viaWays) {
     488            viaSegments.addAll(waySegmentMap.get(viaWay));
     489        }
     490
     491        for (SegmentNode nodeCreatedFromViaNode : nodesCreatedFromViaNodes) {
     492            for (Segment segment : nodeCreatedFromViaNode.getOutboundSegments()) {
     493                if (nodesCreatedFromViaNodes.contains(segment.getNode2())) {
     494                    viaSegments.add(segment);
     495                }
     496            }
     497        }
     498
     499        viaSegments.trimToSize();
     500
     501        /* create a set with all nodes that are based on via members */
     502
     503        Set<SegmentNode> nodesCreatedFromViaMembers
     504        = new HashSet<SegmentNode>(nodesCreatedFromViaNodes);
     505
     506        for (W viaWay : viaWays) {
     507            for (N viaWayNode : dataSource.getNodes(viaWay)) {
     508                nodesCreatedFromViaMembers.add(nodeCreationMap.get(viaWayNode));
     509            }
     510        }
     511
     512        /*
     513        * find from segment and to segments:
     514        * Such a segment contains a node based on a via member.
     515        * Each way should contain only one possible segment
     516        * connecting to via members (due to splitting).
     517        */
     518
     519        Segment fromSegment = null;
     520        Collection<Segment> toSegments = new ArrayList<Segment>();
     521
     522        for (Segment possibleFromSegment : waySegmentMap.get(fromWay)) {
     523            if (nodesCreatedFromViaMembers.contains(possibleFromSegment.getNode2())) {
     524
     525                if (fromSegment == null) {
     526                    fromSegment = possibleFromSegment;
     527                } else {
     528                    //broken restriction
     529                    return EMPTY_RESTRICTION_COLLECTION;
     530                }
     531
     532            }
     533        }
     534        if (fromSegment == null) {
     535            //broken restriction
     536            return EMPTY_RESTRICTION_COLLECTION;
     537        }
     538
     539        if (restrictive) {
     540
     541            for (W toWay : toWays) {
     542                if (waySegmentMap.containsKey(toWay)) {
     543                    Segment toSegment = null;
     544                    for (Segment possibleToSegment : waySegmentMap.get(toWay)) {
     545                        if (nodesCreatedFromViaMembers.contains(possibleToSegment.getNode1())) {
     546
     547                            if (toSegment == null) {
     548                                toSegment = possibleToSegment;
     549                            } else {
     550                                //broken restriction
     551                                return EMPTY_RESTRICTION_COLLECTION;
     552                            }
     553
     554                        }
     555                    }
     556                    if (toSegment == null) {
     557                        //broken restriction
     558                        return EMPTY_RESTRICTION_COLLECTION;
     559                    } else {
     560                        toSegments.add(toSegment);
     561                    }
     562                }
     563            }
     564
     565        } else { //!restrictive
     566
     567            /* forbidden "to" segments are all segments that start at a "via" node
     568            * and are neither a via segment nor created from an allowed "to" way */
     569
     570            for (SegmentNode toStartingNode : nodesCreatedFromViaMembers) {
     571                for (Segment outboundSegment : toStartingNode.getOutboundSegments()) {
     572
     573                    if (!viaSegments.contains(outboundSegment)) {
     574
     575                        boolean isAllowed = false;
     576
     577                        for (W toWay : toWays) {
     578                            if (waySegmentMap.get(toWay).contains(outboundSegment)) {
     579                                isAllowed = true;
     580                                break;
     581                            }
     582                        }
     583
     584                        if (!isAllowed) {
     585                            toSegments.add(outboundSegment);
     586                        }
     587
     588                    }
     589
     590                }
     591            }
     592
     593        }
     594
     595        /* create restriction */
     596
     597        Collection<Restriction> results = new ArrayList<Restriction>(1);
     598        results.add(new RestrictionImpl(fromSegment, viaSegments, toSegments));
     599        return results;
     600    }
     601
     602    /**
     603    * creates Restrictions from barrier nodes (nodes that are considered impassable by the
     604    * {@link #accessEvaluator}). These restrictions prevent moving from a segment before the
     605    * barrier node to a segment after the barrier node.
     606    *
     607    * @param nodeCreationMap  map providing the SegmentNode that has been created from a node,
     608    *                         will not be modified; != null
     609    * @param waySegmentMap    map providing the Segments that have been created from a way,
     610    *                         will not be modified; != null
     611    * @return                 Restrictions created from barrier nodes; != null, but may be empty
     612    */
     613    private Collection<Restriction> createRestrictionsFromBarrierNodes(
     614            Map<N, SegmentNodeImpl> nodeCreationMap,
     615            Map<W, List<Segment>> waySegmentMap) {
     616
     617        assert nodeCreationMap != null;
     618        assert waySegmentMap != null;
     619
     620        Collection<Restriction> results = new LinkedList<Restriction>();
     621
     622        for (N node : nodeCreationMap.keySet()) {
     623
     624            if (!accessEvaluator.nodeUsable(node, nodeCreationMap.get(node).getProperties())) {
     625
     626                SegmentNode barrierNode = nodeCreationMap.get(node);
     627
     628                for (Segment inboundSegment : barrierNode.getInboundSegments()) {
     629                    for (Segment outboundSegment : barrierNode.getOutboundSegments()) {
     630                        results.add(new RestrictionImpl(inboundSegment, EMPTY_SEGMENT_LIST, Arrays.asList(outboundSegment)));
     631                    }
     632                }
     633
     634            }
     635
     636        }
     637
     638        return results;
     639    }
     640
     641    /**
     642    * determines the values of all RoadPropertyTypes from {@link #properties} for a way and
     643    * creates a map with the types that have non-null values as keys, property values as content
     644    */
     645    private Map<RoadPropertyType<?>, Object> getWayPropertyMap(W way, boolean forward) {
     646        Map<RoadPropertyType<?>, Object> propertyValues;
     647        propertyValues = new HashMap<RoadPropertyType<?>, Object>();
     648        for (RoadPropertyType<?> property : properties) {
     649            Object value = property.evaluateW(way, forward, accessParameters, dataSource);
     650            if (value != null) {
     651                propertyValues.put(property, value);
     652            }
     653        }
     654        return propertyValues;
     655    }
     656
     657    /**
     658    * determines the values of all RoadPropertyTypes from {@link #properties} for a node and
     659    * creates a map with the types that have non-null values as keys, property values as content
     660    */
     661    private Map<RoadPropertyType<?>, Object> getNodePropertyMap(N node) {
     662        Map<RoadPropertyType<?>, Object> propertyValues;
     663        propertyValues = new HashMap<RoadPropertyType<?>, Object>();
     664        for (RoadPropertyType<?> property : properties) {
     665            Object value = property.evaluateN(node, accessParameters, dataSource);
     666            if (value != null) {
     667                propertyValues.put(property, value);
     668            }
     669        }
     670        return propertyValues;
     671    }
     672
     673    public void update(DataSource<?, ?, ?, ?> dataSource) {
     674        assert this.dataSource == dataSource;
     675        updateData();
     676    }
     677
     678    public void addObserver(TransitionStructureObserver observer) {
     679        observers.add(observer);
     680    }
     681
     682    public void deleteObserver(TransitionStructureObserver observer) {
     683        observers.remove(observer);
     684    }
     685
     686    protected void notifyObservers() {
     687        for (TransitionStructureObserver observer : observers) {
     688            observer.update(this);
     689        }
     690    }
    691691
    692692}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/Restriction.java

    r16520 r23189  
    1010public interface Restriction {
    1111
    12         /**
    13         * returns the starting segment that will trigger the restriction when used;
    14         * != null
    15         */
    16         public Segment getFrom();
     12    /**
     13    * returns the starting segment that will trigger the restriction when used;
     14    * != null
     15    */
     16    public Segment getFrom();
    1717
    18         /**
    19         * returns the "via" segments.
    20         * The restriction will remain active as long as only via segments are used.
    21         *
    22         * @return  unmodifiable collection of segments; != null
    23         */
    24         public Collection<Segment> getVias();
     18    /**
     19    * returns the "via" segments.
     20    * The restriction will remain active as long as only via segments are used.
     21    *
     22    * @return  unmodifiable collection of segments; != null
     23    */
     24    public Collection<Segment> getVias();
    2525
    26         /**
    27         * returns the forbidden "to" segments.
    28         * The restriction prevents leaving the via segment set by using one of the to segments.
    29         *
    30         * @return  unmodifiable collection of segments; != null
    31         */
    32         public Collection<Segment> getTos();
     26    /**
     27    * returns the forbidden "to" segments.
     28    * The restriction prevents leaving the via segment set by using one of the to segments.
     29    *
     30    * @return  unmodifiable collection of segments; != null
     31    */
     32    public Collection<Segment> getTos();
    3333
    3434}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/Segment.java

    r16520 r23189  
    66public interface Segment extends TransitionStructureElement {
    77
    8         /**
    9         * returns the node this segment starts at; != null
    10         */
    11         public SegmentNode getNode1();
     8    /**
     9    * returns the node this segment starts at; != null
     10    */
     11    public SegmentNode getNode1();
    1212
    13         /**
    14         * returns the node this segment leads to; != null
    15         */
    16         public SegmentNode getNode2();
     13    /**
     14    * returns the node this segment leads to; != null
     15    */
     16    public SegmentNode getNode2();
    1717
    1818}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/SegmentNode.java

    r16520 r23189  
    88public interface SegmentNode extends TransitionStructureElement {
    99
    10         /** returns the node's latitude */
    11         public double getLat();
     10    /** returns the node's latitude */
     11    public double getLat();
    1212
    13         /** returns the node's longitude */
    14         public double getLon();
     13    /** returns the node's longitude */
     14    public double getLon();
    1515
    16         /** returns all segments that end at this node */
    17         Collection<Segment> getInboundSegments();
     16    /** returns all segments that end at this node */
     17    Collection<Segment> getInboundSegments();
    1818
    19         /** returns all segments that start at this node */
    20         Collection<Segment> getOutboundSegments();
     19    /** returns all segments that start at this node */
     20    Collection<Segment> getOutboundSegments();
    2121
    2222}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructure.java

    r16520 r23189  
    99public interface TransitionStructure {
    1010
    11         public Collection<SegmentNode> getNodes();
    12         public Collection<Segment> getSegments();
    13         public Collection<Restriction> getRestrictions();
     11    public Collection<SegmentNode> getNodes();
     12    public Collection<Segment> getSegments();
     13    public Collection<Restriction> getRestrictions();
    1414
    15         /**
    16         * adds an observer.
    17         * Does nothing if the parameter is already an observer of this TransitionStructure.
    18         *
    19         * @param observer  observer object, != null
    20         */
    21         public void addObserver(TransitionStructureObserver observer);
     15    /**
     16    * adds an observer.
     17    * Does nothing if the parameter is already an observer of this TransitionStructure.
     18    *
     19    * @param observer  observer object, != null
     20    */
     21    public void addObserver(TransitionStructureObserver observer);
    2222
    23         /**
    24         * deletes an observer that has been added using {@link #addObserver(TransitionStructureObserver)}.
    25         * Does nothing if the parameter isn't currently an observer of this TransitionStructure.
    26         *
    27         * @param observer  observer object, != null
    28         */
    29         public void deleteObserver(TransitionStructureObserver observer);
     23    /**
     24    * deletes an observer that has been added using {@link #addObserver(TransitionStructureObserver)}.
     25    * Does nothing if the parameter isn't currently an observer of this TransitionStructure.
     26    *
     27    * @param observer  observer object, != null
     28    */
     29    public void deleteObserver(TransitionStructureObserver observer);
    3030
    3131}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructureElement.java

    r16520 r23189  
    1010public interface TransitionStructureElement {
    1111
    12         /**
    13         * returns the types of this object's properties
    14         *
    15         * @return  property type collection; != null
    16         */
    17         public Collection<RoadPropertyType<?>> getAvailableProperties();
     12    /**
     13    * returns the types of this object's properties
     14    *
     15    * @return  property type collection; != null
     16    */
     17    public Collection<RoadPropertyType<?>> getAvailableProperties();
    1818
    19         /**
    20         * returns the value of a property for this object
    21         *
    22         * @param propertyType   property type to return value for; != null
    23         * @return property      value of the property for this segment; null if not available
    24         */
    25         public <P> P getPropertyValue(RoadPropertyType<P> propertyType);
     19    /**
     20    * returns the value of a property for this object
     21    *
     22    * @param propertyType   property type to return value for; != null
     23    * @return property      value of the property for this segment; null if not available
     24    */
     25    public <P> P getPropertyValue(RoadPropertyType<P> propertyType);
    2626
    2727}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructureObserver.java

    r16520 r23189  
    77public interface TransitionStructureObserver {
    88
    9         /**
    10         * informs this observer about changes in an observed transition structure
    11         * @param transitionStructure  observed transition structure that has changed; != null
    12         */
    13         public void update(TransitionStructure transitionStructure);
     9    /**
     10    * informs this observer about changes in an observed transition structure
     11    * @param transitionStructure  observed transition structure that has changed; != null
     12    */
     13    public void update(TransitionStructure transitionStructure);
    1414
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/GraphUtil.java

    r16520 r23189  
    1111public final class GraphUtil {
    1212
    13         /** prevents instantiation */
    14         private GraphUtil() { }
     13    /** prevents instantiation */
     14    private GraphUtil() { }
    1515
    16         /**
    17         * checks whether a node is an "end node"
    18         * (a node whose {@link SegmentNode} is connected to at most one other {@link SegmentNode})
    19         */
    20         public static final boolean isEndNode(GraphNode node) {
     16    /**
     17    * checks whether a node is an "end node"
     18    * (a node whose {@link SegmentNode} is connected to at most one other {@link SegmentNode})
     19    */
     20    public static final boolean isEndNode(GraphNode node) {
    2121
    22                 SegmentNode ownSegmentNode = node.getSegmentNode();
     22        SegmentNode ownSegmentNode = node.getSegmentNode();
    2323
    24                 SegmentNode connectedNode = null;
     24        SegmentNode connectedNode = null;
    2525
    26                 for (Segment inboundSegment : node.getSegmentNode().getInboundSegments()) {
    27                         SegmentNode otherSegmentNode = inboundSegment.getNode1();
    28                         if (otherSegmentNode != ownSegmentNode) {
    29                                 if (connectedNode == null) {
    30                                         connectedNode = otherSegmentNode;
    31                                 } else if (connectedNode != otherSegmentNode) {
    32                                         return false;
    33                                 }
    34                         }
    35                 }
     26        for (Segment inboundSegment : node.getSegmentNode().getInboundSegments()) {
     27            SegmentNode otherSegmentNode = inboundSegment.getNode1();
     28            if (otherSegmentNode != ownSegmentNode) {
     29                if (connectedNode == null) {
     30                    connectedNode = otherSegmentNode;
     31                } else if (connectedNode != otherSegmentNode) {
     32                    return false;
     33                }
     34            }
     35        }
    3636
    37                 for (Segment outboundSegment : node.getSegmentNode().getOutboundSegments()) {
    38                         SegmentNode otherSegmentNode = outboundSegment.getNode2();
    39                         if (otherSegmentNode != ownSegmentNode) {
    40                                 if (connectedNode == null) {
    41                                         connectedNode = otherSegmentNode;
    42                                 } else if (connectedNode != otherSegmentNode) {
    43                                         return false;
    44                                 }
    45                         }
    46                 }
     37        for (Segment outboundSegment : node.getSegmentNode().getOutboundSegments()) {
     38            SegmentNode otherSegmentNode = outboundSegment.getNode2();
     39            if (otherSegmentNode != ownSegmentNode) {
     40                if (connectedNode == null) {
     41                    connectedNode = otherSegmentNode;
     42                } else if (connectedNode != otherSegmentNode) {
     43                    return false;
     44                }
     45            }
     46        }
    4747
    48                 return true;
     48        return true;
    4949
    50         }
     50    }
    5151
    5252}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/TagCondition.java

    r16520 r23189  
    99public interface TagCondition {
    1010
    11         /**
    12         * returns true if the tags match the condition
    13         *
    14         * @param tags  tags to check against the condition; != null
    15         */
    16         boolean matches(TagGroup tags);
     11    /**
     12    * returns true if the tags match the condition
     13    *
     14    * @param tags  tags to check against the condition; != null
     15    */
     16    boolean matches(TagGroup tags);
    1717
    1818}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/TagConditionLogic.java

    r16520 r23189  
    1111public final class TagConditionLogic {
    1212
    13         /** prevents instantiation */
    14         private TagConditionLogic(){ }
    15 
    16         /**
    17         * creates a condition that is fulfilled if the set of tags contains a given tag
    18         *
    19         * @param tag  tag that must be in the tag collection; != null
    20         */
    21         public static TagCondition tag(final Tag tag) {
    22                 assert tag != null;
    23                 return new TagCondition() {
    24                         public boolean matches(TagGroup tags) {
    25                                 return tags.contains(tag);
    26                         }
    27                         @Override
    28                         public String toString() {
    29                                 return tag.toString();
    30                         }
    31                 };
    32         }
    33 
    34         /**
    35         * creates a condition that is fulfilled if the set of tags contains a tag with the given key
    36         *
    37         * @param key  the key to look for; != null
    38         */
    39         public static TagCondition key(final String key) {
    40                 assert key != null;
    41                 return new TagCondition() {
    42                         public boolean matches(TagGroup tags) {
    43                                 return tags.containsKey(key);
    44                         }
    45                         @Override
    46                         public String toString() {
    47                                 return key;
    48                         }
    49                 };
    50         }
    51 
    52         /**
    53         * combines conditions using a boolean "and"
    54         *
    55         * @param condition   first condition; != null
    56         * @param conditions  more conditions; each != null
    57         */
    58         public static TagCondition and(final TagCondition condition, final TagCondition... conditions) {
    59                 return new TagCondition() {
    60                         public boolean matches(TagGroup tags) {
    61                                 for (TagCondition c : conditions) {
    62                                         if (!c.matches(tags)) {
    63                                                 return false;
    64                                         }
    65                                 }
    66                                 return condition.matches(tags);
    67                         }
    68                         @Override
    69                         public String toString() {
    70                                 StringBuilder result = new StringBuilder();
    71                                 result.append("(");
    72                                 result.append(condition);
    73                                 for (TagCondition c : conditions) {
    74                                         result.append(" && ");
    75                                         result.append(c);
    76                                 }
    77                                 result.append(")");
    78                                 return result.toString();
    79                         }
    80                 };
    81         }
    82 
    83         /**
    84         * combines conditions using a boolean "and"
    85         *
    86         * @param conditions   collection of conditions, must contain at least one element; != null
    87         */
    88         public static TagCondition and(final Collection<TagCondition> conditions) {
    89                 if (conditions.size() == 0) {
    90                         throw new IllegalArgumentException("collection must contain at least one condition");
    91                 }
    92                 return new TagCondition() {
    93                         public boolean matches(TagGroup tags) {
    94                                 for (TagCondition c : conditions) {
    95                                         if (!c.matches(tags)) {
    96                                                 return false;
    97                                         }
    98                                 }
    99                                 return true;
    100                         }
    101                         @Override
    102                         public String toString() {
    103                                 StringBuilder result = new StringBuilder();
    104                                 result.append("(");
    105                                 boolean firstCondition = true;
    106                                 for (TagCondition c : conditions) {
    107                                         if (!firstCondition) {
    108                                                 result.append(" && ");
    109                                         }
    110                                         firstCondition = false;
    111                                         result.append(c);
    112                                 }
    113                                 result.append(")");
    114                                 return result.toString();
    115                         }
    116                 };
    117         }
    118 
    119         /**
    120         * combines conditions using a boolean "or"
    121         *
    122         * @param condition   first condition; != null
    123         * @param conditions  more conditions; each != null
    124         */
    125         public static TagCondition or(final TagCondition condition, final TagCondition... conditions) {
    126                 return new TagCondition() {
    127                         public boolean matches(TagGroup tags) {
    128                                 for (TagCondition c : conditions) {
    129                                         if (c.matches(tags)) {
    130                                                 return true;
    131                                         }
    132                                 }
    133                                 return condition.matches(tags);
    134                         }
    135                         @Override
    136                         public String toString() {
    137                                 StringBuilder result = new StringBuilder();
    138                                 result.append("(");
    139                                 result.append(condition);
    140                                 for (TagCondition c : conditions) {
    141                                         result.append(" || ");
    142                                         result.append(c);
    143                                 }
    144                                 result.append(")");
    145                                 return result.toString();
    146                         }
    147                 };
    148         }
    149 
    150         /**
    151         * combines conditions using a boolean "or"
    152         *
    153         * @param conditions   collection of conditions, must contain at least one element; != null
    154         */
    155         public static TagCondition or(final Collection<TagCondition> conditions) {
    156                 if (conditions.size() == 0) {
    157                         throw new IllegalArgumentException("collection must contain at least one condition");
    158                 }
    159                 return new TagCondition() {
    160                         public boolean matches(TagGroup tags) {
    161                                 for (TagCondition c : conditions) {
    162                                         if (c.matches(tags)) {
    163                                                 return true;
    164                                         }
    165                                 }
    166                                 return false;
    167                         }
    168                         @Override
    169                         public String toString() {
    170                                 StringBuilder result = new StringBuilder();
    171                                 result.append("(");
    172                                 boolean firstCondition = true;
    173                                 for (TagCondition c : conditions) {
    174                                         if (!firstCondition) {
    175                                                 result.append(" || ");
    176                                         }
    177                                         firstCondition = false;
    178                                         result.append(c);
    179                                 }
    180                                 result.append(")");
    181                                 return result.toString();
    182                         }
    183                 };
    184         }
    185 
    186         /**
    187         * inverts a condition
    188         *
    189         * @param condition  condition to invert, != null
    190         */
    191         public static TagCondition not(final TagCondition condition) {
    192                 return new TagCondition() {
    193                         public boolean matches(TagGroup tags) {
    194                                 return !condition.matches(tags);
    195                         }
    196                         @Override
    197                         public String toString() {
    198                                 return "!" + condition;
    199                         }
    200                 };
    201         }
     13    /** prevents instantiation */
     14    private TagConditionLogic(){ }
     15
     16    /**
     17    * creates a condition that is fulfilled if the set of tags contains a given tag
     18    *
     19    * @param tag  tag that must be in the tag collection; != null
     20    */
     21    public static TagCondition tag(final Tag tag) {
     22        assert tag != null;
     23        return new TagCondition() {
     24            public boolean matches(TagGroup tags) {
     25                return tags.contains(tag);
     26            }
     27            @Override
     28            public String toString() {
     29                return tag.toString();
     30            }
     31        };
     32    }
     33
     34    /**
     35    * creates a condition that is fulfilled if the set of tags contains a tag with the given key
     36    *
     37    * @param key  the key to look for; != null
     38    */
     39    public static TagCondition key(final String key) {
     40        assert key != null;
     41        return new TagCondition() {
     42            public boolean matches(TagGroup tags) {
     43                return tags.containsKey(key);
     44            }
     45            @Override
     46            public String toString() {
     47                return key;
     48            }
     49        };
     50    }
     51
     52    /**
     53    * combines conditions using a boolean "and"
     54    *
     55    * @param condition   first condition; != null
     56    * @param conditions  more conditions; each != null
     57    */
     58    public static TagCondition and(final TagCondition condition, final TagCondition... conditions) {
     59        return new TagCondition() {
     60            public boolean matches(TagGroup tags) {
     61                for (TagCondition c : conditions) {
     62                    if (!c.matches(tags)) {
     63                        return false;
     64                    }
     65                }
     66                return condition.matches(tags);
     67            }
     68            @Override
     69            public String toString() {
     70                StringBuilder result = new StringBuilder();
     71                result.append("(");
     72                result.append(condition);
     73                for (TagCondition c : conditions) {
     74                    result.append(" && ");
     75                    result.append(c);
     76                }
     77                result.append(")");
     78                return result.toString();
     79            }
     80        };
     81    }
     82
     83    /**
     84    * combines conditions using a boolean "and"
     85    *
     86    * @param conditions   collection of conditions, must contain at least one element; != null
     87    */
     88    public static TagCondition and(final Collection<TagCondition> conditions) {
     89        if (conditions.size() == 0) {
     90            throw new IllegalArgumentException("collection must contain at least one condition");
     91        }
     92        return new TagCondition() {
     93            public boolean matches(TagGroup tags) {
     94                for (TagCondition c : conditions) {
     95                    if (!c.matches(tags)) {
     96                        return false;
     97                    }
     98                }
     99                return true;
     100            }
     101            @Override
     102            public String toString() {
     103                StringBuilder result = new StringBuilder();
     104                result.append("(");
     105                boolean firstCondition = true;
     106                for (TagCondition c : conditions) {
     107                    if (!firstCondition) {
     108                        result.append(" && ");
     109                    }
     110                    firstCondition = false;
     111                    result.append(c);
     112                }
     113                result.append(")");
     114                return result.toString();
     115            }
     116        };
     117    }
     118
     119    /**
     120    * combines conditions using a boolean "or"
     121    *
     122    * @param condition   first condition; != null
     123    * @param conditions  more conditions; each != null
     124    */
     125    public static TagCondition or(final TagCondition condition, final TagCondition... conditions) {
     126        return new TagCondition() {
     127            public boolean matches(TagGroup tags) {
     128                for (TagCondition c : conditions) {
     129                    if (c.matches(tags)) {
     130                        return true;
     131                    }
     132                }
     133                return condition.matches(tags);
     134            }
     135            @Override
     136            public String toString() {
     137                StringBuilder result = new StringBuilder();
     138                result.append("(");
     139                result.append(condition);
     140                for (TagCondition c : conditions) {
     141                    result.append(" || ");
     142                    result.append(c);
     143                }
     144                result.append(")");
     145                return result.toString();
     146            }
     147        };
     148    }
     149
     150    /**
     151    * combines conditions using a boolean "or"
     152    *
     153    * @param conditions   collection of conditions, must contain at least one element; != null
     154    */
     155    public static TagCondition or(final Collection<TagCondition> conditions) {
     156        if (conditions.size() == 0) {
     157            throw new IllegalArgumentException("collection must contain at least one condition");
     158        }
     159        return new TagCondition() {
     160            public boolean matches(TagGroup tags) {
     161                for (TagCondition c : conditions) {
     162                    if (c.matches(tags)) {
     163                        return true;
     164                    }
     165                }
     166                return false;
     167            }
     168            @Override
     169            public String toString() {
     170                StringBuilder result = new StringBuilder();
     171                result.append("(");
     172                boolean firstCondition = true;
     173                for (TagCondition c : conditions) {
     174                    if (!firstCondition) {
     175                        result.append(" || ");
     176                    }
     177                    firstCondition = false;
     178                    result.append(c);
     179                }
     180                result.append(")");
     181                return result.toString();
     182            }
     183        };
     184    }
     185
     186    /**
     187    * inverts a condition
     188    *
     189    * @param condition  condition to invert, != null
     190    */
     191    public static TagCondition not(final TagCondition condition) {
     192        return new TagCondition() {
     193            public boolean matches(TagGroup tags) {
     194                return !condition.matches(tags);
     195            }
     196            @Override
     197            public String toString() {
     198                return "!" + condition;
     199            }
     200        };
     201    }
    202202
    203203}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/ValueStringParser.java

    r20243 r23189  
    66public final class ValueStringParser {
    77
    8         /** prevents instantiation */
    9         private ValueStringParser() { }
    10 
    11         /** pattern that splits into a part before and after a decimal point */
    12         private static final Pattern DEC_POINT_PATTERN = Pattern.compile("^(\\-?\\d+)\\.(\\d+)$");
    13 
    14         public static final Float parseOsmDecimal(String value, boolean allowNegative) {
    15 
    16                 /* positive integer */
    17 
    18                 try {
    19 
    20                         int weight = Integer.parseInt(value);
    21                         if (weight >= 0 || allowNegative) {
    22                                 return (float)weight;
    23                         }
    24 
    25                 } catch (NumberFormatException nfe) {}
    26 
    27                 /* positive number with decimal point */
    28 
    29                 Matcher matcher = DEC_POINT_PATTERN.matcher(value);
    30 
    31                 if (matcher.matches()) {
    32 
    33                         String stringBeforePoint = matcher.group(1);
    34                         String stringAfterPoint = matcher.group(2);
    35 
    36                         if (stringBeforePoint.length() > 0 || stringAfterPoint.length() > 0) {
    37 
    38                                 try {
    39 
    40                                         float beforePoint = Integer.parseInt(stringBeforePoint);
    41                                         float afterPoint = Integer.parseInt(stringAfterPoint);
    42 
    43                                         double result = Math.signum(beforePoint) *
    44                                         (Math.abs(beforePoint)
    45                                                         + Math.pow(10, -stringAfterPoint.length()) * afterPoint);
    46 
    47                                         if (result >= 0 || allowNegative) {
    48                                                 return (float)result;
    49                                         }
    50 
    51                                 } catch (NumberFormatException nfe) {}
    52 
    53                         }
    54                 }
    55 
    56                 return null;
    57         }
    58 
    59         private static final Pattern KMH_PATTERN = Pattern.compile("^(\\d+)\\s*km/h$");
    60         private static final Pattern MPH_PATTERN = Pattern.compile("^(\\d+)\\s*mph$");
    61 
    62         private static final float KM_PER_MILE = 1.609344f;
    63 
    64         /**
    65         * parses a speed value given e.g. for the "maxspeed" key.
    66         *
    67         * @return  speed in km/h; null if value had syntax errors
    68         */
    69         public static final Float parseSpeed(String value) {
    70 
    71                 /* try numeric speed (implied km/h) */
    72 
    73                 Float speed = parseOsmDecimal(value, false);
    74                 if (speed != null) {
    75                         return speed;
    76                 }
    77 
    78                 /* try km/h speed */
    79 
    80                 Matcher kmhMatcher = KMH_PATTERN.matcher(value);
    81                 if (kmhMatcher.matches()) {
    82                         String kmhString = kmhMatcher.group(1);
    83                         try {
    84                                 return (float)Integer.parseInt(kmhString);
    85                         } catch (NumberFormatException nfe) {}
    86                 }
    87 
    88                 /* try mph speed */
    89 
    90                 Matcher mphMatcher = MPH_PATTERN.matcher(value);
    91                 if (mphMatcher.matches()) {
    92                         String mphString = mphMatcher.group(1);
    93                         try {
    94                                 int mph = Integer.parseInt(mphString);
    95                                 return KM_PER_MILE * mph;
    96                         } catch (NumberFormatException nfe) {}
    97                 }
    98 
    99                 /* all possibilities failed */
    100 
    101                 return null;
    102         }
    103 
    104         private static final Pattern M_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*m$");
    105         private static final Pattern KM_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*km$");
    106         private static final Pattern MI_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*mi$");
    107         private static final Pattern FEET_INCHES_PATTERN = Pattern.compile("^([\\d]+)'\\s*([\\d]+)\"");
    108 
    109         private static final double M_PER_MI = 1609.344;
    110         private static final double M_PER_INCH = 0.0254f;
    111 
    112         /**
    113         * parses a measure value given e.g. for the "width" or "length" key.
    114         *
    115         * @return  measure in m; null if value had syntax errors
    116         */
    117         public static final Float parseMeasure(String value) {
    118 
    119                 /* try numeric measure (implied m) */
    120 
    121                 Float measure = parseOsmDecimal(value, false);
    122                 if (measure != null) {
    123                         return measure;
    124                 }
    125 
    126                 /* try m measure */
    127 
    128                 Matcher mMatcher = M_PATTERN.matcher(value);
    129                 if (mMatcher.matches()) {
    130                         String mString = mMatcher.group(1);
    131                         return parseOsmDecimal(mString, false);
    132                 }
    133 
    134                 /* try km measure */
    135 
    136                 Matcher kmMatcher = KM_PATTERN.matcher(value);
    137                 if (kmMatcher.matches()) {
    138                         String kmString = kmMatcher.group(1);
    139                         float km = parseOsmDecimal(kmString, false);
    140                         return 1000 * km;
    141                 }
    142 
    143                 /* try mi measure */
    144 
    145                 Matcher miMatcher = MI_PATTERN.matcher(value);
    146                 if (miMatcher.matches()) {
    147                         String miString = miMatcher.group(1);
    148                         float mi = parseOsmDecimal(miString, false);
    149                         return (float)(M_PER_MI * mi);
    150                 }
    151 
    152                 /* try feet/inches measure */
    153 
    154                 Matcher feetInchesMatcher = FEET_INCHES_PATTERN.matcher(value);
    155                 if (feetInchesMatcher.matches()) {
    156                         String feetString = feetInchesMatcher.group(1);
    157                         String inchesString = feetInchesMatcher.group(2);
    158                         try {
    159                                 int feet = Integer.parseInt(feetString);
    160                                 int inches = Integer.parseInt(inchesString);
    161                                 if (feet >= 0 && inches >= 0 && inches < 12) {
    162                                         return (float)(M_PER_INCH * (12 * feet + inches));
    163                                 }
    164                         } catch (NumberFormatException nfe) {}
    165                 }
    166 
    167                 /* all possibilities failed */
    168 
    169                 return null;
    170         }
    171 
    172         private static final Pattern T_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*t$");
    173 
    174         /**
    175         * parses a weight value given e.g. for the "maxweight" or "maxaxleload" key.
    176         *
    177         * @return  weight in t; null if value had syntax errors
    178         */
    179         public static Float parseWeight(String value) {
    180 
    181                 /* try numeric weight (implied t) */
    182 
    183                 Float weight = parseOsmDecimal(value, false);
    184                 if (weight != null) {
    185                         return weight;
    186                 }
    187 
    188                 /* try t weight */
    189 
    190                 Matcher tMatcher = T_PATTERN.matcher(value);
    191                 if (tMatcher.matches()) {
    192                         String tString = tMatcher.group(1);
    193                         return parseOsmDecimal(tString, false);
    194                 }
    195 
    196                 /* all possibilities failed */
    197 
    198                 return null;
    199 
    200         }
    201 
    202         private static final Pattern INCLINE_PATTERN = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)\\s*%$");
    203 
    204         /**
    205         * parses an incline value as given for the "incline" key.
    206         *
    207         * @return  incline in percents; null if value had syntax errors
    208         */
    209         public static final Float parseIncline(String value) {
    210 
    211                 Matcher inclineMatcher = INCLINE_PATTERN.matcher(value);
    212                 if (inclineMatcher.matches()) {
    213                         String inclineString = inclineMatcher.group(1);
    214                         return parseOsmDecimal(inclineString, true);
    215                 }
    216 
    217                 return null;
    218         }
     8    /** prevents instantiation */
     9    private ValueStringParser() { }
     10
     11    /** pattern that splits into a part before and after a decimal point */
     12    private static final Pattern DEC_POINT_PATTERN = Pattern.compile("^(\\-?\\d+)\\.(\\d+)$");
     13
     14    public static final Float parseOsmDecimal(String value, boolean allowNegative) {
     15
     16        /* positive integer */
     17
     18        try {
     19
     20            int weight = Integer.parseInt(value);
     21            if (weight >= 0 || allowNegative) {
     22                return (float)weight;
     23            }
     24
     25        } catch (NumberFormatException nfe) {}
     26
     27        /* positive number with decimal point */
     28
     29        Matcher matcher = DEC_POINT_PATTERN.matcher(value);
     30
     31        if (matcher.matches()) {
     32
     33            String stringBeforePoint = matcher.group(1);
     34            String stringAfterPoint = matcher.group(2);
     35
     36            if (stringBeforePoint.length() > 0 || stringAfterPoint.length() > 0) {
     37
     38                try {
     39
     40                    float beforePoint = Integer.parseInt(stringBeforePoint);
     41                    float afterPoint = Integer.parseInt(stringAfterPoint);
     42
     43                    double result = Math.signum(beforePoint) *
     44                    (Math.abs(beforePoint)
     45                            + Math.pow(10, -stringAfterPoint.length()) * afterPoint);
     46
     47                    if (result >= 0 || allowNegative) {
     48                        return (float)result;
     49                    }
     50
     51                } catch (NumberFormatException nfe) {}
     52
     53            }
     54        }
     55
     56        return null;
     57    }
     58
     59    private static final Pattern KMH_PATTERN = Pattern.compile("^(\\d+)\\s*km/h$");
     60    private static final Pattern MPH_PATTERN = Pattern.compile("^(\\d+)\\s*mph$");
     61
     62    private static final float KM_PER_MILE = 1.609344f;
     63
     64    /**
     65    * parses a speed value given e.g. for the "maxspeed" key.
     66    *
     67    * @return  speed in km/h; null if value had syntax errors
     68    */
     69    public static final Float parseSpeed(String value) {
     70
     71        /* try numeric speed (implied km/h) */
     72
     73        Float speed = parseOsmDecimal(value, false);
     74        if (speed != null) {
     75            return speed;
     76        }
     77
     78        /* try km/h speed */
     79
     80        Matcher kmhMatcher = KMH_PATTERN.matcher(value);
     81        if (kmhMatcher.matches()) {
     82            String kmhString = kmhMatcher.group(1);
     83            try {
     84                return (float)Integer.parseInt(kmhString);
     85            } catch (NumberFormatException nfe) {}
     86        }
     87
     88        /* try mph speed */
     89
     90        Matcher mphMatcher = MPH_PATTERN.matcher(value);
     91        if (mphMatcher.matches()) {
     92            String mphString = mphMatcher.group(1);
     93            try {
     94                int mph = Integer.parseInt(mphString);
     95                return KM_PER_MILE * mph;
     96            } catch (NumberFormatException nfe) {}
     97        }
     98
     99        /* all possibilities failed */
     100
     101        return null;
     102    }
     103
     104    private static final Pattern M_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*m$");
     105    private static final Pattern KM_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*km$");
     106    private static final Pattern MI_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*mi$");
     107    private static final Pattern FEET_INCHES_PATTERN = Pattern.compile("^([\\d]+)'\\s*([\\d]+)\"");
     108
     109    private static final double M_PER_MI = 1609.344;
     110    private static final double M_PER_INCH = 0.0254f;
     111
     112    /**
     113    * parses a measure value given e.g. for the "width" or "length" key.
     114    *
     115    * @return  measure in m; null if value had syntax errors
     116    */
     117    public static final Float parseMeasure(String value) {
     118
     119        /* try numeric measure (implied m) */
     120
     121        Float measure = parseOsmDecimal(value, false);
     122        if (measure != null) {
     123            return measure;
     124        }
     125
     126        /* try m measure */
     127
     128        Matcher mMatcher = M_PATTERN.matcher(value);
     129        if (mMatcher.matches()) {
     130            String mString = mMatcher.group(1);
     131            return parseOsmDecimal(mString, false);
     132        }
     133
     134        /* try km measure */
     135
     136        Matcher kmMatcher = KM_PATTERN.matcher(value);
     137        if (kmMatcher.matches()) {
     138            String kmString = kmMatcher.group(1);
     139            float km = parseOsmDecimal(kmString, false);
     140            return 1000 * km;
     141        }
     142
     143        /* try mi measure */
     144
     145        Matcher miMatcher = MI_PATTERN.matcher(value);
     146        if (miMatcher.matches()) {
     147            String miString = miMatcher.group(1);
     148            float mi = parseOsmDecimal(miString, false);
     149            return (float)(M_PER_MI * mi);
     150        }
     151
     152        /* try feet/inches measure */
     153
     154        Matcher feetInchesMatcher = FEET_INCHES_PATTERN.matcher(value);
     155        if (feetInchesMatcher.matches()) {
     156            String feetString = feetInchesMatcher.group(1);
     157            String inchesString = feetInchesMatcher.group(2);
     158            try {
     159                int feet = Integer.parseInt(feetString);
     160                int inches = Integer.parseInt(inchesString);
     161                if (feet >= 0 && inches >= 0 && inches < 12) {
     162                    return (float)(M_PER_INCH * (12 * feet + inches));
     163                }
     164            } catch (NumberFormatException nfe) {}
     165        }
     166
     167        /* all possibilities failed */
     168
     169        return null;
     170    }
     171
     172    private static final Pattern T_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*t$");
     173
     174    /**
     175    * parses a weight value given e.g. for the "maxweight" or "maxaxleload" key.
     176    *
     177    * @return  weight in t; null if value had syntax errors
     178    */
     179    public static Float parseWeight(String value) {
     180
     181        /* try numeric weight (implied t) */
     182
     183        Float weight = parseOsmDecimal(value, false);
     184        if (weight != null) {
     185            return weight;
     186        }
     187
     188        /* try t weight */
     189
     190        Matcher tMatcher = T_PATTERN.matcher(value);
     191        if (tMatcher.matches()) {
     192            String tString = tMatcher.group(1);
     193            return parseOsmDecimal(tString, false);
     194        }
     195
     196        /* all possibilities failed */
     197
     198        return null;
     199
     200    }
     201
     202    private static final Pattern INCLINE_PATTERN = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)\\s*%$");
     203
     204    /**
     205    * parses an incline value as given for the "incline" key.
     206    *
     207    * @return  incline in percents; null if value had syntax errors
     208    */
     209    public static final Float parseIncline(String value) {
     210
     211        Matcher inclineMatcher = INCLINE_PATTERN.matcher(value);
     212        if (inclineMatcher.matches()) {
     213            String inclineString = inclineMatcher.group(1);
     214            return parseOsmDecimal(inclineString, true);
     215        }
     216
     217        return null;
     218    }
    219219
    220220}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/ColorScheme.java

    r16520 r23189  
    1111public interface ColorScheme {
    1212
    13         /**
    14         * returns the color to be used for a node in a WayGraph
    15         * @param edge  GraphNode to determine the color for; != null
    16         */
    17         public Color getNodeColor(GraphNode node);
     13    /**
     14    * returns the color to be used for a node in a WayGraph
     15    * @param edge  GraphNode to determine the color for; != null
     16    */
     17    public Color getNodeColor(GraphNode node);
    1818
    19         /**
    20         * returns the color to be used for an edge in a WayGraph
    21         * @param segment  segment to determine the color for; != null
    22         */
    23         public Color getSegmentColor(Segment segment);
     19    /**
     20    * returns the color to be used for an edge in a WayGraph
     21    * @param segment  segment to determine the color for; != null
     22    */
     23    public Color getSegmentColor(Segment segment);
    2424
    2525}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/DefaultNodePositioner.java

    r16520 r23189  
    1111public class DefaultNodePositioner implements NodePositioner {
    1212
    13         public LatLonCoords getPosition(GraphNode node) {
     13    public LatLonCoords getPosition(GraphNode node) {
    1414
    15                 SegmentNode segmentNode = node.getSegmentNode();
     15        SegmentNode segmentNode = node.getSegmentNode();
    1616
    17                 if (2 >= segmentNode.getInboundSegments().size()
    18                                 + segmentNode.getOutboundSegments().size() ) {
     17        if (2 >= segmentNode.getInboundSegments().size()
     18                + segmentNode.getOutboundSegments().size() ) {
    1919
    20                         return new LatLonCoords(
    21                                         node.getSegmentNode().getLat(),
    22                                         node.getSegmentNode().getLon());
     20            return new LatLonCoords(
     21                    node.getSegmentNode().getLat(),
     22                    node.getSegmentNode().getLon());
    2323
    24                 } else {
     24        } else {
    2525
    26                         SegmentNode node1 = node.getSegment().getNode1();
    27                         SegmentNode node2 = node.getSegment().getNode2();
     26            SegmentNode node1 = node.getSegment().getNode1();
     27            SegmentNode node2 = node.getSegment().getNode2();
    2828
    29                         assert segmentNode == node1 || segmentNode == node2;
     29            assert segmentNode == node1 || segmentNode == node2;
    3030
    31                         LatLonCoords result;
     31            LatLonCoords result;
    3232
    33                         if (segmentNode == node1) {
    34                                 result = new LatLonCoords(
    35                                                 (2 * node1.getLat() + node2.getLat()) / 3,
    36                                                 (2 * node1.getLon() + node2.getLon()) / 3);
    37                         } else {
    38                                 result = new LatLonCoords(
    39                                                 (node1.getLat() + 2 * node2.getLat()) / 3,
    40                                                 (node1.getLon() + 2 * node2.getLon()) / 3);
    41                         }
     33            if (segmentNode == node1) {
     34                result = new LatLonCoords(
     35                        (2 * node1.getLat() + node2.getLat()) / 3,
     36                        (2 * node1.getLon() + node2.getLon()) / 3);
     37            } else {
     38                result = new LatLonCoords(
     39                        (node1.getLat() + 2 * node2.getLat()) / 3,
     40                        (node1.getLon() + 2 * node2.getLon()) / 3);
     41            }
    4242
    43                         return result;
    44                 }
    45         }
     43            return result;
     44        }
     45    }
    4646
    4747}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/EndNodeColorScheme.java

    r16520 r23189  
    1212public class EndNodeColorScheme implements ColorScheme {
    1313
    14         private final Color nodeColor;
    15         private final Color endNodeColor;
    16         private final Color segmentColor;
     14    private final Color nodeColor;
     15    private final Color endNodeColor;
     16    private final Color segmentColor;
    1717
    18         public EndNodeColorScheme(Color nodeColor, Color endNodeColor, Color segmentColor) {
    19                 this.nodeColor = nodeColor;
    20                 this.endNodeColor = endNodeColor;
    21                 this.segmentColor = segmentColor;
    22         }
     18    public EndNodeColorScheme(Color nodeColor, Color endNodeColor, Color segmentColor) {
     19        this.nodeColor = nodeColor;
     20        this.endNodeColor = endNodeColor;
     21        this.segmentColor = segmentColor;
     22    }
    2323
    24         public Color getNodeColor(GraphNode node) {
    25                 return GraphUtil.isEndNode(node) ? endNodeColor : nodeColor;
    26         }
     24    public Color getNodeColor(GraphNode node) {
     25        return GraphUtil.isEndNode(node) ? endNodeColor : nodeColor;
     26    }
    2727
    28         public Color getSegmentColor(Segment segment) {
    29                 return segmentColor;
    30         }
     28    public Color getSegmentColor(Segment segment) {
     29        return segmentColor;
     30    }
    3131
    3232}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/FloatPropertyColorScheme.java

    r18130 r23189  
    2222public class FloatPropertyColorScheme implements ColorScheme {
    2323
    24         private final Class<? extends RoadPropertyType<Float>> propertyClass;
    25         private final Map<Float, Color> colorMap;
    26         private final Color defaultColor;
     24    private final Class<? extends RoadPropertyType<Float>> propertyClass;
     25    private final Map<Float, Color> colorMap;
     26    private final Color defaultColor;
    2727
    28         /**
    29         * @param propertyClass  property type to get values for; != null
    30         * @param colorMap       map from some values to colors.
    31         *                       Colors for all other values are interpolated.
    32         *                       This map will be copied and not used directly later. != null
    33         * @param defaultColor   color that is used when the property is not available; != null
    34         */
    35         public FloatPropertyColorScheme(Class<? extends RoadPropertyType<Float>> propertyClass,
    36                         Map<Float, Color> colorMap, Color defaultColor) {
    37                 assert propertyClass != null && colorMap != null && defaultColor != null;
     28    /**
     29    * @param propertyClass  property type to get values for; != null
     30    * @param colorMap       map from some values to colors.
     31    *                       Colors for all other values are interpolated.
     32    *                       This map will be copied and not used directly later. != null
     33    * @param defaultColor   color that is used when the property is not available; != null
     34    */
     35    public FloatPropertyColorScheme(Class<? extends RoadPropertyType<Float>> propertyClass,
     36            Map<Float, Color> colorMap, Color defaultColor) {
     37        assert propertyClass != null && colorMap != null && defaultColor != null;
    3838
    39                 this.propertyClass = propertyClass;
    40                 this.colorMap = new HashMap<Float, Color>(colorMap);
    41                 this.defaultColor = defaultColor;
    42         }
     39        this.propertyClass = propertyClass;
     40        this.colorMap = new HashMap<Float, Color>(colorMap);
     41        this.defaultColor = defaultColor;
     42    }
    4343
    44         public Color getSegmentColor(Segment segment) {
    45                 assert segment != null;
     44    public Color getSegmentColor(Segment segment) {
     45        assert segment != null;
    4646
    47                 Float propertyValue = null;
    48                 Collection<RoadPropertyType<?>> availableProperties = segment.getAvailableProperties();
    49                 for (RoadPropertyType<?> property : availableProperties) {
    50                         if (propertyClass.isInstance(property)) {
    51                                 @SuppressWarnings("unchecked") //has been checked using isInstance
    52                                 RoadPropertyType<Float> floatProperty = (RoadPropertyType<Float>)property;
    53                                 propertyValue = segment.getPropertyValue(floatProperty);
    54                                 break;
    55                         }
    56                 }
     47        Float propertyValue = null;
     48        Collection<RoadPropertyType<?>> availableProperties = segment.getAvailableProperties();
     49        for (RoadPropertyType<?> property : availableProperties) {
     50            if (propertyClass.isInstance(property)) {
     51                @SuppressWarnings("unchecked") //has been checked using isInstance
     52                RoadPropertyType<Float> floatProperty = (RoadPropertyType<Float>)property;
     53                propertyValue = segment.getPropertyValue(floatProperty);
     54                break;
     55            }
     56        }
    5757
    58                 if (propertyValue != null) {
    59                         return getColorForValue(propertyValue);
    60                 } else {
    61                         return defaultColor;
    62                 }
    63         }
     58        if (propertyValue != null) {
     59            return getColorForValue(propertyValue);
     60        } else {
     61            return defaultColor;
     62        }
     63    }
    6464
    65         public Color getNodeColor(GraphNode node) {
     65    public Color getNodeColor(GraphNode node) {
    6666
    67                 List<Color> segmentColors = new ArrayList<Color>();
     67        List<Color> segmentColors = new ArrayList<Color>();
    6868
    69                
    70                
    71                 for (GraphEdge edge : node.getInboundEdges()) {
    72                         List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
    73                         if (edgeSegments.size() > 0) {
    74                                 Segment firstSegment = edgeSegments.get(0);
    75                                 segmentColors.add(getSegmentColor(firstSegment));
    76                         }
    77                 }
    78                 for (GraphEdge edge : node.getOutboundEdges()) {
    79                         List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
    80                         if (edgeSegments.size() > 0) {
    81                                 Segment lastSegment = edgeSegments.get(edgeSegments.size()-1);
    82                                 segmentColors.add(getSegmentColor(lastSegment));
    83                         }
    84                 }
    8569
    86                 if (segmentColors.size() > 0) {
    87                         return averageColor(segmentColors);
    88                 } else {
    89                         return Color.WHITE;
    90                 }
    9170
    92         }
     71        for (GraphEdge edge : node.getInboundEdges()) {
     72            List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
     73            if (edgeSegments.size() > 0) {
     74                Segment firstSegment = edgeSegments.get(0);
     75                segmentColors.add(getSegmentColor(firstSegment));
     76            }
     77        }
     78        for (GraphEdge edge : node.getOutboundEdges()) {
     79            List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
     80            if (edgeSegments.size() > 0) {
     81                Segment lastSegment = edgeSegments.get(edgeSegments.size()-1);
     82                segmentColors.add(getSegmentColor(lastSegment));
     83            }
     84        }
    9385
    94         /**
    95          * returns the color for a value
    96          * @param value  value to get color for; != null
    97          * @return       color; != null
    98          */
    99         protected Color getColorForValue(Float value) {
    100                 assert value != null;
     86        if (segmentColors.size() > 0) {
     87            return averageColor(segmentColors);
     88        } else {
     89            return Color.WHITE;
     90        }
    10191
    102                 if (colorMap.containsKey(value)) {
     92    }
    10393
    104                         return colorMap.get(value);
     94    /**
     95     * returns the color for a value
     96     * @param value  value to get color for; != null
     97     * @return       color; != null
     98     */
     99    protected Color getColorForValue(Float value) {
     100        assert value != null;
    105101
    106                 } else {
     102        if (colorMap.containsKey(value)) {
    107103
    108                         LinkedList<Float> valuesWithDefinedColor = new LinkedList<Float>(colorMap.keySet());
    109                         Collections.sort(valuesWithDefinedColor);
     104            return colorMap.get(value);
    110105
    111                         if (value <= valuesWithDefinedColor.getFirst()) {
     106        } else {
    112107
    113                                 return colorMap.get(valuesWithDefinedColor.getFirst());
     108            LinkedList<Float> valuesWithDefinedColor = new LinkedList<Float>(colorMap.keySet());
     109            Collections.sort(valuesWithDefinedColor);
    114110
    115                         } else if (value >= valuesWithDefinedColor.getLast()) {
     111            if (value <= valuesWithDefinedColor.getFirst()) {
    116112
    117                                 return colorMap.get(valuesWithDefinedColor.getLast());
     113                return colorMap.get(valuesWithDefinedColor.getFirst());
    118114
    119                         } else {
     115            } else if (value >= valuesWithDefinedColor.getLast()) {
    120116
    121                                 /* interpolate */
     117                return colorMap.get(valuesWithDefinedColor.getLast());
    122118
    123                                 Float lowerValue = valuesWithDefinedColor.getFirst();
    124                                 Float higherValue = null;
     119            } else {
    125120
    126                                 for (Float v : valuesWithDefinedColor) {
    127                                         if (v >= value) {
    128                                                 higherValue = v;
    129                                                 break;
    130                                         }
    131                                         lowerValue = v;
    132                                 }
     121                /* interpolate */
    133122
    134                                 assert lowerValue != null && higherValue != null;
     123                Float lowerValue = valuesWithDefinedColor.getFirst();
     124                Float higherValue = null;
    135125
    136                                 Color lowerColor = colorMap.get(lowerValue);
    137                                 Color higherColor = colorMap.get(higherValue);
     126                for (Float v : valuesWithDefinedColor) {
     127                    if (v >= value) {
     128                        higherValue = v;
     129                        break;
     130                    }
     131                    lowerValue = v;
     132                }
    138133
    139                                 float weightHigherColor = (value - lowerValue) / (higherValue - lowerValue);
     134                assert lowerValue != null && higherValue != null;
    140135
    141                                 return weightedAverageColor(lowerColor, higherColor, weightHigherColor);
     136                Color lowerColor = colorMap.get(lowerValue);
     137                Color higherColor = colorMap.get(higherValue);
    142138
    143                         }
     139                float weightHigherColor = (value - lowerValue) / (higherValue - lowerValue);
    144140
    145                 }
     141                return weightedAverageColor(lowerColor, higherColor, weightHigherColor);
    146142
    147         }
     143            }
    148144
    149         /**
    150          * returns an average of all colors that have been passed as parameter
    151          *
    152          * @param colors  colors to calculate average from; not empty or null
    153          * @return        average color; != null
    154          */
    155         private static Color averageColor(List<Color> colors) {
    156                 assert colors != null && colors.size() > 0;
     145        }
    157146
    158                 float weightPerColor = 1.0f / colors.size();
     147    }
    159148
    160                 Color average = new Color(0,0,0);
     149    /**
     150     * returns an average of all colors that have been passed as parameter
     151     *
     152     * @param colors  colors to calculate average from; not empty or null
     153     * @return        average color; != null
     154     */
     155    private static Color averageColor(List<Color> colors) {
     156        assert colors != null && colors.size() > 0;
    161157
    162                 for (Color color : colors) {
    163                         average = new Color(
    164                                         Math.min(Math.round(average.getRed() + weightPerColor*color.getRed()), 255),
    165                                         Math.min(Math.round(average.getGreen() + weightPerColor*color.getGreen()), 255),
    166                                         Math.min(Math.round(average.getBlue() + weightPerColor*color.getBlue()), 255));
    167                 }
     158        float weightPerColor = 1.0f / colors.size();
    168159
    169                 return average;
    170         }
     160        Color average = new Color(0,0,0);
    171161
    172         /**
    173          * returns a weighted average of two colors
    174          *
    175          * @param color1        first color for the average; != null
    176          * @param color2        second color for the average; != null
    177          * @param weightColor2  weight of color2; must be in [0..1]
    178          * @return              average color; != null
    179          */
    180         private static Color weightedAverageColor(Color color1, Color color2, float weightColor2) {
    181                 assert color1 != null && color2 != null;
    182                 assert 0 <= weightColor2 && weightColor2 <= 1;
     162        for (Color color : colors) {
     163            average = new Color(
     164                    Math.min(Math.round(average.getRed() + weightPerColor*color.getRed()), 255),
     165                    Math.min(Math.round(average.getGreen() + weightPerColor*color.getGreen()), 255),
     166                    Math.min(Math.round(average.getBlue() + weightPerColor*color.getBlue()), 255));
     167        }
    183168
    184                 return new Color(
    185                                 Math.round((1 - weightColor2) * color1.getRed() + weightColor2 * color2.getRed()),
    186                                 Math.round((1 - weightColor2) * color1.getGreen() + weightColor2 * color2.getGreen()),
    187                                 Math.round((1 - weightColor2) * color1.getBlue() + weightColor2 * color2.getBlue()));
    188         }
     169        return average;
     170    }
     171
     172    /**
     173     * returns a weighted average of two colors
     174     *
     175     * @param color1        first color for the average; != null
     176     * @param color2        second color for the average; != null
     177     * @param weightColor2  weight of color2; must be in [0..1]
     178     * @return              average color; != null
     179     */
     180    private static Color weightedAverageColor(Color color1, Color color2, float weightColor2) {
     181        assert color1 != null && color2 != null;
     182        assert 0 <= weightColor2 && weightColor2 <= 1;
     183
     184        return new Color(
     185                Math.round((1 - weightColor2) * color1.getRed() + weightColor2 * color2.getRed()),
     186                Math.round((1 - weightColor2) * color1.getGreen() + weightColor2 * color2.getGreen()),
     187                Math.round((1 - weightColor2) * color1.getBlue() + weightColor2 * color2.getBlue()));
     188    }
    189189
    190190}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/InclineColorScheme.java

    r16520 r23189  
    1212public class InclineColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(-30f, Color.BLUE);
    19                 COLOR_MAP.put(0f, Color.WHITE);
    20                 COLOR_MAP.put(30f, Color.RED);
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(-30f, Color.BLUE);
     19        COLOR_MAP.put(0f, Color.WHITE);
     20        COLOR_MAP.put(30f, Color.RED);
     21    }
    2222
    23         public InclineColorScheme() {
    24                 super(RoadIncline.class, COLOR_MAP, Color.GRAY);
    25         }
     23    public InclineColorScheme() {
     24        super(RoadIncline.class, COLOR_MAP, Color.GRAY);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/LatLonCoords.java

    r16520 r23189  
    66public final class LatLonCoords {
    77
    8         private final double lat;
    9         private final double lon;
     8    private final double lat;
     9    private final double lon;
    1010
    11         public LatLonCoords(double lat, double lon) {
    12                 this.lat = lat;
    13                 this.lon = lon;
    14         }
     11    public LatLonCoords(double lat, double lon) {
     12        this.lat = lat;
     13        this.lon = lon;
     14    }
    1515
    16         public double getLat() {
    17                 return lat;
    18         }
     16    public double getLat() {
     17        return lat;
     18    }
    1919
    20         public double getLon() {
    21                 return lon;
    22         }
     20    public double getLon() {
     21        return lon;
     22    }
    2323
    2424}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxheightColorScheme.java

    r16520 r23189  
    1212public class MaxheightColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(0, 0, 50));
    19                 COLOR_MAP.put(10f, new Color(100, 100, 255));
    20                 COLOR_MAP.put(30f, new Color(200, 200, 255));
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(0, 0, 50));
     19        COLOR_MAP.put(10f, new Color(100, 100, 255));
     20        COLOR_MAP.put(30f, new Color(200, 200, 255));
     21    }
    2222
    23         public MaxheightColorScheme() {
    24                 super(RoadMaxheight.class, COLOR_MAP, Color.WHITE);
    25         }
     23    public MaxheightColorScheme() {
     24        super(RoadMaxheight.class, COLOR_MAP, Color.WHITE);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxspeedColorScheme.java

    r16520 r23189  
    1212public class MaxspeedColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(50, 0, 0));
    19                 COLOR_MAP.put(30f, Color.RED);
    20                 COLOR_MAP.put(60f, Color.YELLOW);
    21                 COLOR_MAP.put(90f, Color.GREEN);
    22                 COLOR_MAP.put(150f, Color.BLUE);
    23         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(50, 0, 0));
     19        COLOR_MAP.put(30f, Color.RED);
     20        COLOR_MAP.put(60f, Color.YELLOW);
     21        COLOR_MAP.put(90f, Color.GREEN);
     22        COLOR_MAP.put(150f, Color.BLUE);
     23    }
    2424
    25         public MaxspeedColorScheme() {
    26                 super(RoadMaxspeed.class, COLOR_MAP, Color.GRAY);
    27         }
     25    public MaxspeedColorScheme() {
     26        super(RoadMaxspeed.class, COLOR_MAP, Color.GRAY);
     27    }
    2828}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxweightColorScheme.java

    r16520 r23189  
    1212public class MaxweightColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(0, 0, 50));
    19                 COLOR_MAP.put(20f, new Color(100, 100, 255));
    20                 COLOR_MAP.put(50f, new Color(200, 200, 255));
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(0, 0, 50));
     19        COLOR_MAP.put(20f, new Color(100, 100, 255));
     20        COLOR_MAP.put(50f, new Color(200, 200, 255));
     21    }
    2222
    23         public MaxweightColorScheme() {
    24                 super(RoadMaxweight.class, COLOR_MAP, Color.WHITE);
    25         }
     23    public MaxweightColorScheme() {
     24        super(RoadMaxweight.class, COLOR_MAP, Color.WHITE);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/NodePositioner.java

    r16520 r23189  
    99public interface NodePositioner {
    1010
    11         LatLonCoords getPosition(GraphNode node);
     11    LatLonCoords getPosition(GraphNode node);
    1212
    1313}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/NonMovingNodePositioner.java

    r16520 r23189  
    55public class NonMovingNodePositioner implements NodePositioner {
    66
    7         public LatLonCoords getPosition(GraphNode node) {
    8                 return new LatLonCoords(
    9                                 node.getSegmentNode().getLat(),
    10                                 node.getSegmentNode().getLon());
    11         }
     7    public LatLonCoords getPosition(GraphNode node) {
     8        return new LatLonCoords(
     9                node.getSegmentNode().getLat(),
     10                node.getSegmentNode().getLon());
     11    }
    1212
    1313}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/SingleColorScheme.java

    r16520 r23189  
    1212public class SingleColorScheme implements ColorScheme {
    1313
    14         private final Color nodeColor;
    15         private final Color segmentColor;
     14    private final Color nodeColor;
     15    private final Color segmentColor;
    1616
    17         public SingleColorScheme(Color nodeColor, Color segmentColor) {
    18                 this.nodeColor = nodeColor;
    19                 this.segmentColor = segmentColor;
    20         }
     17    public SingleColorScheme(Color nodeColor, Color segmentColor) {
     18        this.nodeColor = nodeColor;
     19        this.segmentColor = segmentColor;
     20    }
    2121
    22         public Color getNodeColor(GraphNode node) {
    23                 return nodeColor;
    24         }
     22    public Color getNodeColor(GraphNode node) {
     23        return nodeColor;
     24    }
    2525
    26         public Color getSegmentColor(Segment segment) {
    27                 return segmentColor;
    28         }
     26    public Color getSegmentColor(Segment segment) {
     27        return segmentColor;
     28    }
    2929
    3030}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/GraphViewPlugin.java

    r19441 r23189  
    5252public class GraphViewPlugin extends Plugin implements LayerChangeListener, Observer {
    5353
    54         private static final Collection<RoadPropertyType<?>> PROPERTIES;
    55 
    56         static {
    57                 PROPERTIES = new LinkedList<RoadPropertyType<?>>();
    58                 PROPERTIES.add(new RoadIncline());
    59                 PROPERTIES.add(new RoadMaxaxleload());
    60                 PROPERTIES.add(new RoadMaxheight());
    61                 PROPERTIES.add(new RoadMaxlength());
    62                 PROPERTIES.add(new RoadMaxspeed());
    63                 PROPERTIES.add(new RoadMaxweight());
    64                 PROPERTIES.add(new RoadMaxwidth());
    65                 PROPERTIES.add(new RoadMinspeed());
    66                 PROPERTIES.add(new RoadSurface());
    67                 PROPERTIES.add(new RoadTracktype());
    68                 PROPERTIES.add(new RoadWidth());
    69         }
    70 
    71         private final GraphViewPreferences preferences;
    72 
    73         private JOSMTransitionStructure transitionStructure;
    74         private GraphViewLayer graphViewLayer;
    75 
    76         /** creates the plugin */
    77         public GraphViewPlugin(PluginInformation info) {
    78                 super(info);
    79                 preferences = GraphViewPreferences.getInstance();
    80                 this.preferences.addObserver(this);
    81 
    82         }
    83 
    84         /** allows creation/update of GraphViewLayer */
    85         public void createGraphViewLayer() {
    86 
    87                 try {
    88 
    89                         if (graphViewLayer != null) {
    90 
    91                                 AccessRuleset accessRuleset = getAccessRuleset();
    92 
    93                                 if (accessRuleset == null) {
    94                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!", "No ruleset", JOptionPane.ERROR_MESSAGE);
    95                                 } else {
    96                                         transitionStructure.setAccessParametersAndRuleset(preferences.getCurrentParameterBookmark(), accessRuleset);
    97                                         transitionStructure.forceUpdate();
    98                                 }
    99 
    100                         } else {
    101 
    102                                 AccessRuleset accessRuleset = getAccessRuleset();
    103 
    104                                 if (accessRuleset == null) {
    105                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
    106                                                         "No ruleset", JOptionPane.ERROR_MESSAGE);
    107                                 } else {
    108 
    109                                         transitionStructure = new JOSMTransitionStructure(
    110                                                         preferences.getCurrentParameterBookmark(),
    111                                                         accessRuleset,
    112                                                         PROPERTIES);
    113 
    114                                         WayGraph graph = new TSBasedWayGraph(transitionStructure);
    115 
    116                                         graphViewLayer = new GraphViewLayer();
    117                                         graphViewLayer.setWayGraph(graph);
    118                                         graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
    119                                         graphViewLayer.setNodePositioner(new DefaultNodePositioner());
    120 
    121                                         Main.main.addLayer(graphViewLayer);
    122 
    123                                 }
    124 
    125                         }
    126 
    127                 } catch (AccessRulesetSyntaxException e) {
    128                         JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
    129                         e.printStackTrace();
    130                 } catch (FileNotFoundException e) {
    131                         JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
    132                         e.printStackTrace();
    133                 } catch (IOException e) {
    134                         JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
    135                         e.printStackTrace();
    136                 }
    137 
    138         }
    139 
    140         /** allows update of GraphViewLayer */
    141         public void updateGraphViewLayer() {
    142 
    143                 try {
    144 
    145                         if (graphViewLayer != null) {
    146 
    147                                 AccessRuleset accessRuleset = getAccessRuleset();
    148 
    149                                 if (accessRuleset == null) {
    150                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
    151                                                         "No ruleset", JOptionPane.ERROR_MESSAGE);
    152                                 } else {
    153                                         transitionStructure.setAccessParametersAndRuleset(
    154                                                         preferences.getCurrentParameterBookmark(), accessRuleset);
    155                                         transitionStructure.forceUpdate();
    156                                 }
    157 
    158                         }
    159 
    160                 } catch (AccessRulesetSyntaxException e) {
    161                         JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
    162                         e.printStackTrace();
    163                 } catch (FileNotFoundException e) {
    164                         JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
    165                         e.printStackTrace();
    166                 } catch (IOException e) {
    167                         JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
    168                         e.printStackTrace();
    169                 }
    170 
    171         }
    172 
    173         /** repaints the GraphViewLayer without recalculating the graph (visual update) */
    174         public void repaintGraphViewLayer() {
    175 
    176                 if (graphViewLayer != null) {
    177                         Main.panel.repaint();
    178                 }
    179 
    180         }
    181 
    182         /**
    183         * @return ruleset read from a source as specified by preferences, null if the preferences
    184         *         don't specify a ruleset source
    185         * @throws AccessRulesetSyntaxException
    186         * @throws IOException
    187         * @throws FileNotFoundException
    188         */
    189         private AccessRuleset getAccessRuleset()
    190         throws AccessRulesetSyntaxException, IOException, FileNotFoundException {
    191 
    192                 InputStream rulesetInputStream;
    193 
    194                 if (preferences.getUseInternalRulesets()) {
    195 
    196                         InternalRuleset ruleset = preferences.getCurrentInternalRuleset();
    197 
    198                         if (ruleset == null) {
    199                                 return null;
    200                         }
    201 
    202                         ClassLoader classLoader = this.getClass().getClassLoader();
    203                         URL rulesetURL = classLoader.getResource(ruleset.getResourceName());
    204 
    205                         if (rulesetURL != null) {
    206                                 rulesetInputStream = rulesetURL.openStream();
    207                         } else {
    208                                 throw new FileNotFoundException("couldn't find built-in ruleset " + ruleset);
    209                         }
    210 
    211                 } else {
    212 
    213                         File rulesetFile = preferences.getCurrentRulesetFile();
    214 
    215                         if (rulesetFile == null) {
    216                                 return null;
    217                         }
    218 
    219                         rulesetInputStream = new FileInputStream(rulesetFile);
    220 
    221                 }
    222 
    223                 return AccessRulesetReader.readAccessRuleset(rulesetInputStream);
    224 
    225         }
    226 
    227         @Override
    228         public PreferenceSetting getPreferenceSetting() {
    229                 return new GraphViewPreferenceEditor();
    230         }
    231 
    232         @Override
    233         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    234                 if (newFrame != null) {
    235                         if (oldFrame == null) {
    236                                 final GraphViewDialog laneDialog
    237                                         = new GraphViewDialog(this);
    238                                 newFrame.addToggleDialog(laneDialog);
    239                         }
    240                         MapView.addLayerChangeListener(this);
    241                 } else {
    242                         MapView.removeLayerChangeListener(this);
    243                 }
    244         }
    245 
    246         public void layerRemoved(Layer oldLayer) {
    247                 if (oldLayer == graphViewLayer) {
    248                         graphViewLayer = null;
    249                 } else if (oldLayer == Main.map.mapView.getEditLayer()) { //data layer removed
    250                         if (graphViewLayer != null) {
    251                                 Main.map.mapView.removeLayer(graphViewLayer);
    252                                 graphViewLayer = null;
    253                         }
    254                 }
    255         }
    256 
    257         public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    258                 //do nothing
    259         }
    260 
    261         public void layerAdded(Layer newLayer) {
    262                 //do nothing
    263         }
    264 
    265         public void update(Observable arg0, Object arg1) {
    266                 if (arg0 == preferences) {
    267                         if (graphViewLayer != null) {
    268                                 graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
    269                         }
    270                 }
    271         }
     54    private static final Collection<RoadPropertyType<?>> PROPERTIES;
     55
     56    static {
     57        PROPERTIES = new LinkedList<RoadPropertyType<?>>();
     58        PROPERTIES.add(new RoadIncline());
     59        PROPERTIES.add(new RoadMaxaxleload());
     60        PROPERTIES.add(new RoadMaxheight());
     61        PROPERTIES.add(new RoadMaxlength());
     62        PROPERTIES.add(new RoadMaxspeed());
     63        PROPERTIES.add(new RoadMaxweight());
     64        PROPERTIES.add(new RoadMaxwidth());
     65        PROPERTIES.add(new RoadMinspeed());
     66        PROPERTIES.add(new RoadSurface());
     67        PROPERTIES.add(new RoadTracktype());
     68        PROPERTIES.add(new RoadWidth());
     69    }
     70
     71    private final GraphViewPreferences preferences;
     72
     73    private JOSMTransitionStructure transitionStructure;
     74    private GraphViewLayer graphViewLayer;
     75
     76    /** creates the plugin */
     77    public GraphViewPlugin(PluginInformation info) {
     78        super(info);
     79        preferences = GraphViewPreferences.getInstance();
     80        this.preferences.addObserver(this);
     81
     82    }
     83
     84    /** allows creation/update of GraphViewLayer */
     85    public void createGraphViewLayer() {
     86
     87        try {
     88
     89            if (graphViewLayer != null) {
     90
     91                AccessRuleset accessRuleset = getAccessRuleset();
     92
     93                if (accessRuleset == null) {
     94                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!", "No ruleset", JOptionPane.ERROR_MESSAGE);
     95                } else {
     96                    transitionStructure.setAccessParametersAndRuleset(preferences.getCurrentParameterBookmark(), accessRuleset);
     97                    transitionStructure.forceUpdate();
     98                }
     99
     100            } else {
     101
     102                AccessRuleset accessRuleset = getAccessRuleset();
     103
     104                if (accessRuleset == null) {
     105                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
     106                            "No ruleset", JOptionPane.ERROR_MESSAGE);
     107                } else {
     108
     109                    transitionStructure = new JOSMTransitionStructure(
     110                            preferences.getCurrentParameterBookmark(),
     111                            accessRuleset,
     112                            PROPERTIES);
     113
     114                    WayGraph graph = new TSBasedWayGraph(transitionStructure);
     115
     116                    graphViewLayer = new GraphViewLayer();
     117                    graphViewLayer.setWayGraph(graph);
     118                    graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
     119                    graphViewLayer.setNodePositioner(new DefaultNodePositioner());
     120
     121                    Main.main.addLayer(graphViewLayer);
     122
     123                }
     124
     125            }
     126
     127        } catch (AccessRulesetSyntaxException e) {
     128            JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
     129            e.printStackTrace();
     130        } catch (FileNotFoundException e) {
     131            JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
     132            e.printStackTrace();
     133        } catch (IOException e) {
     134            JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
     135            e.printStackTrace();
     136        }
     137
     138    }
     139
     140    /** allows update of GraphViewLayer */
     141    public void updateGraphViewLayer() {
     142
     143        try {
     144
     145            if (graphViewLayer != null) {
     146
     147                AccessRuleset accessRuleset = getAccessRuleset();
     148
     149                if (accessRuleset == null) {
     150                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
     151                            "No ruleset", JOptionPane.ERROR_MESSAGE);
     152                } else {
     153                    transitionStructure.setAccessParametersAndRuleset(
     154                            preferences.getCurrentParameterBookmark(), accessRuleset);
     155                    transitionStructure.forceUpdate();
     156                }
     157
     158            }
     159
     160        } catch (AccessRulesetSyntaxException e) {
     161            JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
     162            e.printStackTrace();
     163        } catch (FileNotFoundException e) {
     164            JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
     165            e.printStackTrace();
     166        } catch (IOException e) {
     167            JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
     168            e.printStackTrace();
     169        }
     170
     171    }
     172
     173    /** repaints the GraphViewLayer without recalculating the graph (visual update) */
     174    public void repaintGraphViewLayer() {
     175
     176        if (graphViewLayer != null) {
     177            Main.panel.repaint();
     178        }
     179
     180    }
     181
     182    /**
     183    * @return ruleset read from a source as specified by preferences, null if the preferences
     184    *         don't specify a ruleset source
     185    * @throws AccessRulesetSyntaxException
     186    * @throws IOException
     187    * @throws FileNotFoundException
     188    */
     189    private AccessRuleset getAccessRuleset()
     190    throws AccessRulesetSyntaxException, IOException, FileNotFoundException {
     191
     192        InputStream rulesetInputStream;
     193
     194        if (preferences.getUseInternalRulesets()) {
     195
     196            InternalRuleset ruleset = preferences.getCurrentInternalRuleset();
     197
     198            if (ruleset == null) {
     199                return null;
     200            }
     201
     202            ClassLoader classLoader = this.getClass().getClassLoader();
     203            URL rulesetURL = classLoader.getResource(ruleset.getResourceName());
     204
     205            if (rulesetURL != null) {
     206                rulesetInputStream = rulesetURL.openStream();
     207            } else {
     208                throw new FileNotFoundException("couldn't find built-in ruleset " + ruleset);
     209            }
     210
     211        } else {
     212
     213            File rulesetFile = preferences.getCurrentRulesetFile();
     214
     215            if (rulesetFile == null) {
     216                return null;
     217            }
     218
     219            rulesetInputStream = new FileInputStream(rulesetFile);
     220
     221        }
     222
     223        return AccessRulesetReader.readAccessRuleset(rulesetInputStream);
     224
     225    }
     226
     227    @Override
     228    public PreferenceSetting getPreferenceSetting() {
     229        return new GraphViewPreferenceEditor();
     230    }
     231
     232    @Override
     233    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     234        if (newFrame != null) {
     235            if (oldFrame == null) {
     236                final GraphViewDialog laneDialog
     237                    = new GraphViewDialog(this);
     238                newFrame.addToggleDialog(laneDialog);
     239            }
     240            MapView.addLayerChangeListener(this);
     241        } else {
     242            MapView.removeLayerChangeListener(this);
     243        }
     244    }
     245
     246    public void layerRemoved(Layer oldLayer) {
     247        if (oldLayer == graphViewLayer) {
     248            graphViewLayer = null;
     249        } else if (oldLayer == Main.map.mapView.getEditLayer()) { //data layer removed
     250            if (graphViewLayer != null) {
     251                Main.map.mapView.removeLayer(graphViewLayer);
     252                graphViewLayer = null;
     253            }
     254        }
     255    }
     256
     257    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     258        //do nothing
     259    }
     260
     261    public void layerAdded(Layer newLayer) {
     262        //do nothing
     263    }
     264
     265    public void update(Observable arg0, Object arg1) {
     266        if (arg0 == preferences) {
     267            if (graphViewLayer != null) {
     268                graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
     269            }
     270        }
     271    }
    272272
    273273}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/data/JOSMDataSource.java

    r21610 r23189  
    2626public class JOSMDataSource implements DataSource<Node, Way, Relation, RelationMember> {
    2727
    28         public double getLat(Node node) {
    29                 return node.getCoor().lat();
    30         }
    31 
    32         public double getLon(Node node) {
    33                 return node.getCoor().lon();
    34         }
    35 
    36         public Iterable<RelationMember> getMembers(Relation relation) {
    37                 return relation.getMembers();
    38         }
    39 
    40         public Iterable<Node> getNodes(Way way) {
    41                 return new FilteredOsmPrimitiveIterable<Node>(way.getNodes());
    42         }
    43 
    44         public Iterable<Node> getNodes() {
    45                 return new FilteredOsmPrimitiveIterable<Node>(Main.main.getCurrentDataSet().getNodes());
    46         }
    47 
    48         public Iterable<Relation> getRelations() {
    49                 return new FilteredRelationIterable(Main.main.getCurrentDataSet().getRelations());
    50         }
    51 
    52         public Iterable<Way> getWays() {
    53                 return new FilteredOsmPrimitiveIterable<Way>(Main.main.getCurrentDataSet().getWays());
    54         }
    55 
    56         public TagGroup getTagsN(Node node) {
    57                 return getTags(node);
    58         }
    59 
    60         public TagGroup getTagsW(Way way) {
    61                 return getTags(way);
    62         }
    63 
    64         public TagGroup getTagsR(Relation relation) {
    65                 return getTags(relation);
    66         }
    67 
    68         private TagGroup getTags(OsmPrimitive primitive) {
    69                 if (primitive.getKeys() == null) {
    70                         return EMPTY_TAG_GROUP;
    71                 } else {
    72                         return new MapBasedTagGroup(primitive.getKeys());
    73                 }
    74         }
    75 
    76         public Object getMember(RelationMember member) {
    77                 return member.getMember();
    78         }
    79 
    80         public String getRole(RelationMember member) {
    81                 return member.getRole();
    82         }
    83 
    84         public boolean isNMember(RelationMember member) {
    85                 return member.getMember() instanceof Node;
    86         }
    87 
    88         public boolean isWMember(RelationMember member) {
    89                 return member.getMember() instanceof Way;
    90         }
    91 
    92         public boolean isRMember(RelationMember member) {
    93                 return member.getMember() instanceof Relation;
    94         }
    95 
    96 
    97         private static final TagGroup EMPTY_TAG_GROUP;
    98         static {
    99                 Map<String, String> emptyMap = new HashMap<String, String>(0);
    100                 EMPTY_TAG_GROUP = new MapBasedTagGroup(emptyMap);
    101         }
    102 
    103         /**
    104         * Iterable of OsmPrimitive objects based on an existing Iterable,
    105         * will filter incomplete and deleted objects from the iterator.
    106         *
    107         * @param <P>  OsmPrimitive subtype
    108         */
    109         public static class FilteredOsmPrimitiveIterable<P extends OsmPrimitive> implements Iterable<P> {
    110 
    111                 private final Iterable<P> originalIterable;
    112 
    113                 public FilteredOsmPrimitiveIterable(Iterable<P> originalIterable) {
    114                         this.originalIterable = originalIterable;
    115                 }
    116 
    117                 /** returns an iterator. The iterator does not support {@link Iterator#remove()}. */
    118                 public Iterator<P> iterator() {
    119                         return new FilteredIterator(originalIterable.iterator());
    120                 }
    121 
    122                 private class FilteredIterator implements Iterator<P> {
    123 
    124                         private final Iterator<P> originalIterator;
    125 
    126                         private P next;
    127 
    128                         public FilteredIterator(Iterator<P> originalIterator) {
    129                                 this.originalIterator = originalIterator;
    130                                 updateNext();
    131                         }
    132 
    133                         public boolean hasNext() {
    134                                 return next != null;
    135                         }
    136 
    137                         public P next() {
    138                                 if (next != null) {
    139                                         P result = next;
    140                                         updateNext();
    141                                         return result;
    142                                 } else {
    143                                         throw new NoSuchElementException();
    144                                 }
    145                         }
    146 
    147                         public void remove() {
    148                                 throw new UnsupportedOperationException();
    149                         }
    150 
    151                         private void updateNext() {
    152                                 next = null;
    153                                 while (originalIterator.hasNext()) {
    154                                         P originalNext = originalIterator.next();
    155                                         if (accept(originalNext)) {
    156                                                 next = originalNext;
    157                                                 break;
    158                                         }
    159                                 }
    160                         }
    161 
    162                 }
    163 
    164                 protected boolean accept(P primitive) {
    165                         return !primitive.isDeleted() && !primitive.isIncomplete();
    166                 }
    167         }
    168 
    169         /**
    170         * Relation-specific variant of the FilteredOsmPrimitiveIterable,
    171         * also checks completeness of relation's members
    172         */
    173         public static class FilteredRelationIterable extends FilteredOsmPrimitiveIterable<Relation> {
    174 
    175                 public FilteredRelationIterable(Iterable<Relation> originalIterable) {
    176                         super(originalIterable);
    177                 }
    178 
    179                 @Override
    180                 protected boolean accept(Relation relation) {
    181                         boolean complete = true;
    182                         for (org.openstreetmap.josm.data.osm.RelationMember member : relation.getMembers()) {
    183                                 if (member.getMember() == null || member.getMember().isDeleted() || member.getMember().isIncomplete()) {
    184                                         complete = false;
    185                                 }
    186                         }
    187                         return complete && super.accept(relation);
    188                 }
    189         }
    190 
    191         static class RelationMemberImpl {
    192                 private final String role;
    193                 private final Object member;
    194                 public RelationMemberImpl(org.openstreetmap.josm.data.osm.RelationMember originalMember) {
    195                         this.role = originalMember.getRole();
    196                         this.member = originalMember.getMember();
    197                 }
    198                 public String getRole() {
    199                         return role;
    200                 }
    201                 public Object getMember() {
    202                         return member;
    203                 }
    204         }
    205 
    206         private final Set<DataSourceObserver> observers = new HashSet<DataSourceObserver>();
    207 
    208         public void addObserver(DataSourceObserver observer) {
    209                 observers.add(observer);
    210         }
    211 
    212         public void deleteObserver(DataSourceObserver observer) {
    213                 observers.remove(observer);
    214         }
     28    public double getLat(Node node) {
     29        return node.getCoor().lat();
     30    }
     31
     32    public double getLon(Node node) {
     33        return node.getCoor().lon();
     34    }
     35
     36    public Iterable<RelationMember> getMembers(Relation relation) {
     37        return relation.getMembers();
     38    }
     39
     40    public Iterable<Node> getNodes(Way way) {
     41        return new FilteredOsmPrimitiveIterable<Node>(way.getNodes());
     42    }
     43
     44    public Iterable<Node> getNodes() {
     45        return new FilteredOsmPrimitiveIterable<Node>(Main.main.getCurrentDataSet().getNodes());
     46    }
     47
     48    public Iterable<Relation> getRelations() {
     49        return new FilteredRelationIterable(Main.main.getCurrentDataSet().getRelations());
     50    }
     51
     52    public Iterable<Way> getWays() {
     53        return new FilteredOsmPrimitiveIterable<Way>(Main.main.getCurrentDataSet().getWays());
     54    }
     55
     56    public TagGroup getTagsN(Node node) {
     57        return getTags(node);
     58    }
     59
     60    public TagGroup getTagsW(Way way) {
     61        return getTags(way);
     62    }
     63
     64    public TagGroup getTagsR(Relation relation) {
     65        return getTags(relation);
     66    }
     67
     68    private TagGroup getTags(OsmPrimitive primitive) {
     69        if (primitive.getKeys() == null) {
     70            return EMPTY_TAG_GROUP;
     71        } else {
     72            return new MapBasedTagGroup(primitive.getKeys());
     73        }
     74    }
     75
     76    public Object getMember(RelationMember member) {
     77        return member.getMember();
     78    }
     79
     80    public String getRole(RelationMember member) {
     81        return member.getRole();
     82    }
     83
     84    public boolean isNMember(RelationMember member) {
     85        return member.getMember() instanceof Node;
     86    }
     87
     88    public boolean isWMember(RelationMember member) {
     89        return member.getMember() instanceof Way;
     90    }
     91
     92    public boolean isRMember(RelationMember member) {
     93        return member.getMember() instanceof Relation;
     94    }
     95
     96
     97    private static final TagGroup EMPTY_TAG_GROUP;
     98    static {
     99        Map<String, String> emptyMap = new HashMap<String, String>(0);
     100        EMPTY_TAG_GROUP = new MapBasedTagGroup(emptyMap);
     101    }
     102
     103    /**
     104    * Iterable of OsmPrimitive objects based on an existing Iterable,
     105    * will filter incomplete and deleted objects from the iterator.
     106    *
     107    * @param <P>  OsmPrimitive subtype
     108    */
     109    public static class FilteredOsmPrimitiveIterable<P extends OsmPrimitive> implements Iterable<P> {
     110
     111        private final Iterable<P> originalIterable;
     112
     113        public FilteredOsmPrimitiveIterable(Iterable<P> originalIterable) {
     114            this.originalIterable = originalIterable;
     115        }
     116
     117        /** returns an iterator. The iterator does not support {@link Iterator#remove()}. */
     118        public Iterator<P> iterator() {
     119            return new FilteredIterator(originalIterable.iterator());
     120        }
     121
     122        private class FilteredIterator implements Iterator<P> {
     123
     124            private final Iterator<P> originalIterator;
     125
     126            private P next;
     127
     128            public FilteredIterator(Iterator<P> originalIterator) {
     129                this.originalIterator = originalIterator;
     130                updateNext();
     131            }
     132
     133            public boolean hasNext() {
     134                return next != null;
     135            }
     136
     137            public P next() {
     138                if (next != null) {
     139                    P result = next;
     140                    updateNext();
     141                    return result;
     142                } else {
     143                    throw new NoSuchElementException();
     144                }
     145            }
     146
     147            public void remove() {
     148                throw new UnsupportedOperationException();
     149            }
     150
     151            private void updateNext() {
     152                next = null;
     153                while (originalIterator.hasNext()) {
     154                    P originalNext = originalIterator.next();
     155                    if (accept(originalNext)) {
     156                        next = originalNext;
     157                        break;
     158                    }
     159                }
     160            }
     161
     162        }
     163
     164        protected boolean accept(P primitive) {
     165            return !primitive.isDeleted() && !primitive.isIncomplete();
     166        }
     167    }
     168
     169    /**
     170    * Relation-specific variant of the FilteredOsmPrimitiveIterable,
     171    * also checks completeness of relation's members
     172    */
     173    public static class FilteredRelationIterable extends FilteredOsmPrimitiveIterable<Relation> {
     174
     175        public FilteredRelationIterable(Iterable<Relation> originalIterable) {
     176            super(originalIterable);
     177        }
     178
     179        @Override
     180        protected boolean accept(Relation relation) {
     181            boolean complete = true;
     182            for (org.openstreetmap.josm.data.osm.RelationMember member : relation.getMembers()) {
     183                if (member.getMember() == null || member.getMember().isDeleted() || member.getMember().isIncomplete()) {
     184                    complete = false;
     185                }
     186            }
     187            return complete && super.accept(relation);
     188        }
     189    }
     190
     191    static class RelationMemberImpl {
     192        private final String role;
     193        private final Object member;
     194        public RelationMemberImpl(org.openstreetmap.josm.data.osm.RelationMember originalMember) {
     195            this.role = originalMember.getRole();
     196            this.member = originalMember.getMember();
     197        }
     198        public String getRole() {
     199            return role;
     200        }
     201        public Object getMember() {
     202            return member;
     203        }
     204    }
     205
     206    private final Set<DataSourceObserver> observers = new HashSet<DataSourceObserver>();
     207
     208    public void addObserver(DataSourceObserver observer) {
     209        observers.add(observer);
     210    }
     211
     212    public void deleteObserver(DataSourceObserver observer) {
     213        observers.remove(observer);
     214    }
    215215
    216216}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/data/JOSMTransitionStructure.java

    r19216 r23189  
    1717public class JOSMTransitionStructure extends GenericTransitionStructure<Node, Way, Relation, RelationMember> {
    1818
    19         private static final JOSMDataSource DATA_SOURCE = new JOSMDataSource();
     19    private static final JOSMDataSource DATA_SOURCE = new JOSMDataSource();
    2020
    21         public JOSMTransitionStructure(AccessParameters accessParameters, AccessRuleset ruleset,
    22                         Collection<RoadPropertyType<?>> properties) {
     21    public JOSMTransitionStructure(AccessParameters accessParameters, AccessRuleset ruleset,
     22            Collection<RoadPropertyType<?>> properties) {
    2323
    24                 super(accessParameters, ruleset,
    25                                 DATA_SOURCE,
    26                                 properties);
     24        super(accessParameters, ruleset,
     25                DATA_SOURCE,
     26                properties);
    2727
    28         }
     28    }
    2929
    30         /** causes an update (as if the DataSource had noticed a change) */
    31         public void forceUpdate() {
    32                 super.update(DATA_SOURCE);
    33         }
     30    /** causes an update (as if the DataSource had noticed a change) */
     31    public void forceUpdate() {
     32        super.update(DATA_SOURCE);
     33    }
    3434
    3535}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/AccessParameterDialog.java

    r16520 r23189  
    3838public class AccessParameterDialog extends JDialog {
    3939
    40         public static interface BookmarkAction {
    41                 public void execute(String name, PreferenceAccessParameters parameters);
    42         }
    43 
    44         /**
    45         * map that contains all float value vehicle properties (as those can be treated uniformly)
    46         * and their labels
    47         */
    48         private static final Map<VehiclePropertyType<Float>, String> FLOAT_PROPERTIES;
    49 
    50         static {
    51                 FLOAT_PROPERTIES = new LinkedHashMap<VehiclePropertyType<Float>, String>();
    52                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.HEIGHT, "height (m)");
    53                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.WIDTH, "width (m)");
    54                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.LENGTH, "length (m)");
    55                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.SPEED, "speed (km/h)");
    56                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.WEIGHT, "weight (t)");
    57                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.AXLELOAD, "axleload (t)");
    58         }
    59 
    60         private static final Collection<Character> FORBIDDEN_CHARS =
    61                 Arrays.asList(',', ';', '{', '}', '=', '|');
    62 
    63         private class BookmarkNamePanel extends JPanel {
    64 
    65                 private final JTextField bookmarkNameTextField;
    66 
    67                 public BookmarkNamePanel(String initialName) {
    68                         super();
    69                         this.setBorder(BorderFactory.createTitledBorder("bookmark name"));
    70 
    71                         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    72 
    73                         bookmarkNameTextField = new JTextField(initialName);
    74                         this.add(bookmarkNameTextField);
    75 
    76                 }
    77 
    78                 public String getBookmarkName() {
    79 
    80                         String name = bookmarkNameTextField.getText();
    81 
    82                         if (existingBookmarkNames.contains(name)) {
    83                                 JOptionPane.showMessageDialog(this, "Bookmark name already exists!");
    84                                 return null;
    85                         }
    86 
    87                         for (char nameChar : name.toCharArray()) {
    88                                 if (FORBIDDEN_CHARS.contains(nameChar)) {
    89                                         JOptionPane.showMessageDialog(this, "Bookmark name must not contain '" +
    90                                                         nameChar + "'!");
    91                                         return null;
    92                                 }
    93                         }
    94 
    95                         return name;
    96                 }
    97         }
    98 
    99         private static class AccessClassPanel extends JPanel {
    100 
    101                 private final JTextField accessClassTextField;
    102 
    103                 public AccessClassPanel(PreferenceAccessParameters initialParameters) {
    104                         super();
    105                         this.setBorder(BorderFactory.createTitledBorder("access class"));
    106 
    107                         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    108 
    109                         accessClassTextField = new JTextField(initialParameters.getAccessClass());
    110                         this.add(accessClassTextField);
    111 
    112                 }
    113 
    114                 public String getAccessClass() {
    115 
    116                         String name = accessClassTextField.getText();
    117 
    118                         for (char nameChar : name.toCharArray()) {
    119                                 if (FORBIDDEN_CHARS.contains(nameChar)) {
    120                                         JOptionPane.showMessageDialog(this, "Access class must not contain '" +
    121                                                         nameChar + "'!");
    122                                         return null;
    123                                 }
    124                         }
    125 
    126                         return name;
    127                 }
    128         }
    129 
    130         private static class AccessTypesPanel extends JPanel {
    131 
    132                 private static final int COLS = 4;
    133 
    134                 private final Map<AccessType, JCheckBox> accessTypeCheckBoxes =
    135                         new EnumMap<AccessType, JCheckBox>(AccessType.class);
    136 
    137                 public AccessTypesPanel(PreferenceAccessParameters initialParameters) {
    138                         super();
    139                         this.setBorder(BorderFactory.createTitledBorder("access types"));
    140 
    141                         this.setLayout(
    142                                         new GridLayout(((COLS-1 + AccessType.values().length) / COLS), COLS));
    143 
    144                         for (AccessType accessType : AccessType.values()) {
    145                                 JCheckBox checkBox = new JCheckBox(accessType.toString());
    146                                 checkBox.setSelected(initialParameters.getAccessTypeUsable(accessType));
    147                                 accessTypeCheckBoxes.put(accessType, checkBox);
    148                                 this.add(checkBox);
    149                         }
    150 
    151                 }
    152 
    153                 public Collection<AccessType> getUsableAccessTypes() {
    154 
    155                         Collection<AccessType> usableAccessTypes = new LinkedList<AccessType>();
    156 
    157                         for (AccessType accessType : AccessType.values()) {
    158                                 if (accessTypeCheckBoxes.get(accessType).isSelected()) {
    159                                         usableAccessTypes.add(accessType);
    160                                 }
    161                         }
    162 
    163                         return usableAccessTypes;
    164                 }
    165         }
    166 
    167         private static class VehiclePropertiesPanel extends JPanel {
    168 
    169                 private static final int COLS = 2;
    170 
    171                 private final Map<VehiclePropertyType<Float>, JTextField> floatPropertyTextFields =
    172                         new HashMap<VehiclePropertyType<Float>, JTextField>();
    173 
    174                 public VehiclePropertiesPanel(PreferenceAccessParameters initialParameters) {
    175                         super();
    176                         this.setBorder(BorderFactory.createTitledBorder("vehicle properties"));
    177 
    178                         this.setLayout(new GridLayout(((COLS-1 + FLOAT_PROPERTIES.size()) / COLS),
    179                                         2*COLS));
    180 
    181                         for (VehiclePropertyType<Float> vehicleProperty : FLOAT_PROPERTIES.keySet()) {
    182 
    183                                 JLabel label = new JLabel(FLOAT_PROPERTIES.get(vehicleProperty));
    184                                 this.add(label);
    185 
    186                                 JTextField textField = new JTextField();
    187 
    188                                 String vehiclePropertyString =
    189                                         initialParameters.getVehiclePropertyString(vehicleProperty);
    190                                 if (vehiclePropertyString != null) {
    191                                         textField.setText(vehiclePropertyString);
    192                                 }
    193 
    194                                 floatPropertyTextFields.put(vehicleProperty, textField);
    195                                 this.add(textField);
    196                         }
    197 
    198                 }
    199 
    200                 public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
    201 
    202                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    203                                 new HashMap<VehiclePropertyType<?>, String>();
    204 
    205                         for (VehiclePropertyType<Float> vehicleProperty : floatPropertyTextFields.keySet()) {
    206                                 String textFieldContent = floatPropertyTextFields.get(vehicleProperty).getText();
    207                                 if (textFieldContent.trim().length() > 0) {
    208                                         vehiclePropertyStrings.put(vehicleProperty, textFieldContent);
    209                                 }
    210                         }
    211 
    212                         return vehiclePropertyStrings;
    213                 }
    214         }
    215 
    216         private static class RoadQualityPanel extends JPanel {
    217 
    218                 private JTextField inclineUpTextField;
    219                 private JTextField inclineDownTextField;
    220                 private JTextField surfaceTextField;
    221                 private JTextField tracktypeTextField;
    222 
    223                 public RoadQualityPanel(PreferenceAccessParameters initialParameters) {
    224                         super();
    225                         this.setBorder(BorderFactory.createTitledBorder("road requirements"));
    226 
    227 
    228                         this.setLayout(new GridLayout(4, 2));
    229 
    230                         /* incline up */
    231                         {
    232                                 JLabel inclineUpLabel = new JLabel("max. incline up (%, pos.)");
    233                                 inclineUpLabel.setToolTipText("maximum incline the vehicle can go up");
    234                                 this.add(inclineUpLabel);
    235 
    236                                 inclineUpTextField = new JTextField();
    237 
    238                                 String vehiclePropertyString =
    239                                         initialParameters.getVehiclePropertyString(MAX_INCLINE_UP);
    240                                 if (vehiclePropertyString != null) {
    241                                         inclineUpTextField.setText(vehiclePropertyString);
    242                                 }
    243                                 inclineUpTextField.setToolTipText("maximum incline the vehicle can go up");
    244 
    245                                 this.add(inclineUpTextField);
    246                         }
    247 
    248                         /* incline down */
    249                         {
    250                                 JLabel inclineDownLabel = new JLabel("max. incline down (%, pos.)");
    251                                 inclineDownLabel.setToolTipText("maximum incline the vehicle can go down");
    252                                 this.add(inclineDownLabel);
    253 
    254                                 inclineDownTextField = new JTextField();
    255 
    256                                 String vehiclePropertyString =
    257                                         initialParameters.getVehiclePropertyString(MAX_INCLINE_DOWN);
    258                                 if (vehiclePropertyString != null) {
    259                                         inclineDownTextField.setText(vehiclePropertyString);
    260                                 }
    261                                 inclineDownTextField.setToolTipText("maximum incline the vehicle can go down");
    262 
    263                                 this.add(inclineDownTextField);
    264                         }
    265 
    266                         /* surface */
    267                         {
    268                                 JLabel surfaceLabel = new JLabel("surface blacklist");
    269                                 surfaceLabel.setToolTipText("list of surfaces the vehicle cannot use, "
    270                                                 + "values are separated by semicolons (;)");
    271                                 this.add(surfaceLabel);
    272 
    273                                 surfaceTextField = new JTextField();
    274 
    275                                 String vehiclePropertyString =
    276                                         initialParameters.getVehiclePropertyString(SURFACE_BLACKLIST);
    277 
    278                                 if (vehiclePropertyString != null) {
    279                                         surfaceTextField.setText(vehiclePropertyString);
    280                                 }
    281 
    282                                 surfaceTextField.setToolTipText("list of surfaces the vehicle cannot use, "
    283                                                 + "values are separated by semicolons (;)");
    284 
    285                                 this.add(surfaceTextField);
    286                         }
    287 
    288                         /* tracktype */
    289                         {
    290                                 JLabel tracktypeLabel = new JLabel("max. tracktype grade");
    291                                 tracktypeLabel.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
    292                                                 + " 0 for none");
    293                                 this.add(tracktypeLabel);
    294 
    295                                 tracktypeTextField = new JTextField();
    296 
    297                                 String vehiclePropertyString =
    298                                         initialParameters.getVehiclePropertyString(MAX_TRACKTYPE);
    299                                 if (vehiclePropertyString != null) {
    300                                         tracktypeTextField.setText(vehiclePropertyString);
    301                                 }
    302                                 tracktypeTextField.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
    303                                                 + " 0 for none");
    304 
    305                                 this.add(tracktypeTextField);
    306                         }
    307 
    308                 }
    309 
    310                 public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
    311 
    312                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    313                                 new HashMap<VehiclePropertyType<?>, String>();
    314 
    315                         String incUpString = inclineUpTextField.getText();
    316                         if (incUpString.trim().length() > 0) {
    317                                 vehiclePropertyStrings.put(MAX_INCLINE_UP, incUpString);
    318                         }
    319 
    320                         String incDownString = inclineDownTextField.getText();
    321                         if (incDownString.trim().length() > 0) {
    322                                 vehiclePropertyStrings.put(MAX_INCLINE_DOWN, incDownString);
    323                         }
    324 
    325                         String surfaceString = surfaceTextField.getText();
    326                         if (surfaceString.trim().length() > 0) {
    327                                 vehiclePropertyStrings.put(SURFACE_BLACKLIST, surfaceString);
    328                         }
    329 
    330                         String tracktypeString = tracktypeTextField.getText();
    331                         if (tracktypeString.trim().length() > 0) {
    332                                 vehiclePropertyStrings.put(MAX_TRACKTYPE, tracktypeString);
    333                         }
    334 
    335                         return vehiclePropertyStrings;
    336                 }
    337         }
    338 
    339         private class OkCancelPanel extends JPanel {
    340 
    341                 public OkCancelPanel() {
    342 
    343                         new BoxLayout(this, BoxLayout.X_AXIS);
    344 
    345                         JButton okButton = new JButton(existingBookmark?"Change bookmark":"Create bookmark");
    346                         okButton.addActionListener(new ActionListener() {
    347                                 public void actionPerformed(ActionEvent e) {
    348                                         String bookmarkName = bookmarkNamePanel.getBookmarkName();
    349                                         if (bookmarkName != null) {
    350                                                 PreferenceAccessParameters parameters = getAccessParameters();
    351                                                 if (parameters != null) {
    352                                                         okAction.execute(bookmarkName, parameters);
    353                                                         AccessParameterDialog.this.dispose();
    354                                                 }
    355                                         }
    356                                 }
    357                         });
    358                         this.add(okButton);
    359 
    360                         JButton cancelButton = new JButton("Cancel");
    361                         cancelButton.addActionListener(new ActionListener() {
    362                                 public void actionPerformed(ActionEvent e) {
    363                                         AccessParameterDialog.this.dispose();
    364                                 }
    365                         });
    366                         this.add(cancelButton);
    367 
    368                 }
    369 
    370         }
    371 
    372         private boolean existingBookmark = false;
    373         private final Collection<String> existingBookmarkNames;
    374 
    375         private final BookmarkAction okAction;
    376 
    377         private final BookmarkNamePanel bookmarkNamePanel;
    378         private final AccessClassPanel accessClassPanel;
    379         private final AccessTypesPanel accessTypesPanel;
    380         private final VehiclePropertiesPanel vehiclePropertiesPanel;
    381         private final RoadQualityPanel roadQualityPanel;
    382 
    383         public AccessParameterDialog(final Frame owner, boolean existingBookmark, String initialName,
    384                         Collection<String> existingBookmarkNames,
    385                         PreferenceAccessParameters initialAccessParameters, BookmarkAction okAction) {
    386                 super(owner, "edit access parameters", true);
    387 
    388                 this.existingBookmark = existingBookmark;
    389                 this.existingBookmarkNames = existingBookmarkNames;
    390                 this.okAction = okAction;
    391 
    392                 GridBagLayout layout = new GridBagLayout();
    393                 this.setLayout(layout);
    394 
    395                 GridBagConstraints gbc = new GridBagConstraints();
    396                 gbc.gridx = 0;
    397                 gbc.weighty = 1;
    398                 gbc.fill = GridBagConstraints.BOTH;
    399 
    400                 bookmarkNamePanel = new BookmarkNamePanel(initialName);
    401                 gbc.gridy = 0;
    402                 layout.setConstraints(bookmarkNamePanel, gbc);
    403                 this.add(bookmarkNamePanel);
    404 
    405                 accessClassPanel = new AccessClassPanel(initialAccessParameters);
    406                 gbc.gridy = 1;
    407                 layout.setConstraints(accessClassPanel, gbc);
    408                 this.add(accessClassPanel);
    409 
    410                 accessTypesPanel = new AccessTypesPanel(initialAccessParameters);
    411                 gbc.gridy = 2;
    412                 layout.setConstraints(accessTypesPanel, gbc);
    413                 this.add(accessTypesPanel);
    414 
    415                 vehiclePropertiesPanel = new VehiclePropertiesPanel(initialAccessParameters);
    416                 gbc.gridy = 3;
    417                 layout.setConstraints(vehiclePropertiesPanel, gbc);
    418                 this.add(vehiclePropertiesPanel);
    419 
    420                 roadQualityPanel = new RoadQualityPanel(initialAccessParameters);
    421                 gbc.gridy = 4;
    422                 layout.setConstraints(roadQualityPanel, gbc);
    423                 this.add(roadQualityPanel);
    424 
    425                 JPanel okCancelPanel = new OkCancelPanel();
    426                 gbc.gridy = 5;
    427                 gbc.weighty = 0;
    428                 gbc.fill = GridBagConstraints.HORIZONTAL;
    429                 layout.setConstraints(okCancelPanel, gbc);
    430                 this.add(okCancelPanel);
    431 
    432                 this.pack();
    433         }
    434 
    435         private PreferenceAccessParameters getAccessParameters() {
    436 
    437                 String accessClass = accessClassPanel.getAccessClass();
    438                 Collection<AccessType> usableAccessTypes = accessTypesPanel.getUsableAccessTypes();
    439                 Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    440                         vehiclePropertiesPanel.getVehiclePropertyStrings();
    441                 Map<VehiclePropertyType<?>, String> additionalVehiclePropertyStrings =
    442                         roadQualityPanel.getVehiclePropertyStrings();
    443 
    444                 if (accessClass != null && usableAccessTypes != null && vehiclePropertyStrings != null
    445                                 && additionalVehiclePropertyStrings != null) {
    446 
    447                         vehiclePropertyStrings.putAll(additionalVehiclePropertyStrings);
    448 
    449                         try {
    450                                 return new PreferenceAccessParameters(accessClass, usableAccessTypes, vehiclePropertyStrings);
    451                         } catch (PropertyValueSyntaxException e) {
    452                                 JOptionPane.showMessageDialog(this, e.getMessage());
    453                                 return null;
    454                         }
    455 
    456                 } else {
    457                         return null;
    458                 }
    459         }
     40    public static interface BookmarkAction {
     41        public void execute(String name, PreferenceAccessParameters parameters);
     42    }
     43
     44    /**
     45    * map that contains all float value vehicle properties (as those can be treated uniformly)
     46    * and their labels
     47    */
     48    private static final Map<VehiclePropertyType<Float>, String> FLOAT_PROPERTIES;
     49
     50    static {
     51        FLOAT_PROPERTIES = new LinkedHashMap<VehiclePropertyType<Float>, String>();
     52        FLOAT_PROPERTIES.put(VehiclePropertyTypes.HEIGHT, "height (m)");
     53        FLOAT_PROPERTIES.put(VehiclePropertyTypes.WIDTH, "width (m)");
     54        FLOAT_PROPERTIES.put(VehiclePropertyTypes.LENGTH, "length (m)");
     55        FLOAT_PROPERTIES.put(VehiclePropertyTypes.SPEED, "speed (km/h)");
     56        FLOAT_PROPERTIES.put(VehiclePropertyTypes.WEIGHT, "weight (t)");
     57        FLOAT_PROPERTIES.put(VehiclePropertyTypes.AXLELOAD, "axleload (t)");
     58    }
     59
     60    private static final Collection<Character> FORBIDDEN_CHARS =
     61        Arrays.asList(',', ';', '{', '}', '=', '|');
     62
     63    private class BookmarkNamePanel extends JPanel {
     64
     65        private final JTextField bookmarkNameTextField;
     66
     67        public BookmarkNamePanel(String initialName) {
     68            super();
     69            this.setBorder(BorderFactory.createTitledBorder("bookmark name"));
     70
     71            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
     72
     73            bookmarkNameTextField = new JTextField(initialName);
     74            this.add(bookmarkNameTextField);
     75
     76        }
     77
     78        public String getBookmarkName() {
     79
     80            String name = bookmarkNameTextField.getText();
     81
     82            if (existingBookmarkNames.contains(name)) {
     83                JOptionPane.showMessageDialog(this, "Bookmark name already exists!");
     84                return null;
     85            }
     86
     87            for (char nameChar : name.toCharArray()) {
     88                if (FORBIDDEN_CHARS.contains(nameChar)) {
     89                    JOptionPane.showMessageDialog(this, "Bookmark name must not contain '" +
     90                            nameChar + "'!");
     91                    return null;
     92                }
     93            }
     94
     95            return name;
     96        }
     97    }
     98
     99    private static class AccessClassPanel extends JPanel {
     100
     101        private final JTextField accessClassTextField;
     102
     103        public AccessClassPanel(PreferenceAccessParameters initialParameters) {
     104            super();
     105            this.setBorder(BorderFactory.createTitledBorder("access class"));
     106
     107            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
     108
     109            accessClassTextField = new JTextField(initialParameters.getAccessClass());
     110            this.add(accessClassTextField);
     111
     112        }
     113
     114        public String getAccessClass() {
     115
     116            String name = accessClassTextField.getText();
     117
     118            for (char nameChar : name.toCharArray()) {
     119                if (FORBIDDEN_CHARS.contains(nameChar)) {
     120                    JOptionPane.showMessageDialog(this, "Access class must not contain '" +
     121                            nameChar + "'!");
     122                    return null;
     123                }
     124            }
     125
     126            return name;
     127        }
     128    }
     129
     130    private static class AccessTypesPanel extends JPanel {
     131
     132        private static final int COLS = 4;
     133
     134        private final Map<AccessType, JCheckBox> accessTypeCheckBoxes =
     135            new EnumMap<AccessType, JCheckBox>(AccessType.class);
     136
     137        public AccessTypesPanel(PreferenceAccessParameters initialParameters) {
     138            super();
     139            this.setBorder(BorderFactory.createTitledBorder("access types"));
     140
     141            this.setLayout(
     142                    new GridLayout(((COLS-1 + AccessType.values().length) / COLS), COLS));
     143
     144            for (AccessType accessType : AccessType.values()) {
     145                JCheckBox checkBox = new JCheckBox(accessType.toString());
     146                checkBox.setSelected(initialParameters.getAccessTypeUsable(accessType));
     147                accessTypeCheckBoxes.put(accessType, checkBox);
     148                this.add(checkBox);
     149            }
     150
     151        }
     152
     153        public Collection<AccessType> getUsableAccessTypes() {
     154
     155            Collection<AccessType> usableAccessTypes = new LinkedList<AccessType>();
     156
     157            for (AccessType accessType : AccessType.values()) {
     158                if (accessTypeCheckBoxes.get(accessType).isSelected()) {
     159                    usableAccessTypes.add(accessType);
     160                }
     161            }
     162
     163            return usableAccessTypes;
     164        }
     165    }
     166
     167    private static class VehiclePropertiesPanel extends JPanel {
     168
     169        private static final int COLS = 2;
     170
     171        private final Map<VehiclePropertyType<Float>, JTextField> floatPropertyTextFields =
     172            new HashMap<VehiclePropertyType<Float>, JTextField>();
     173
     174        public VehiclePropertiesPanel(PreferenceAccessParameters initialParameters) {
     175            super();
     176            this.setBorder(BorderFactory.createTitledBorder("vehicle properties"));
     177
     178            this.setLayout(new GridLayout(((COLS-1 + FLOAT_PROPERTIES.size()) / COLS),
     179                    2*COLS));
     180
     181            for (VehiclePropertyType<Float> vehicleProperty : FLOAT_PROPERTIES.keySet()) {
     182
     183                JLabel label = new JLabel(FLOAT_PROPERTIES.get(vehicleProperty));
     184                this.add(label);
     185
     186                JTextField textField = new JTextField();
     187
     188                String vehiclePropertyString =
     189                    initialParameters.getVehiclePropertyString(vehicleProperty);
     190                if (vehiclePropertyString != null) {
     191                    textField.setText(vehiclePropertyString);
     192                }
     193
     194                floatPropertyTextFields.put(vehicleProperty, textField);
     195                this.add(textField);
     196            }
     197
     198        }
     199
     200        public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
     201
     202            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     203                new HashMap<VehiclePropertyType<?>, String>();
     204
     205            for (VehiclePropertyType<Float> vehicleProperty : floatPropertyTextFields.keySet()) {
     206                String textFieldContent = floatPropertyTextFields.get(vehicleProperty).getText();
     207                if (textFieldContent.trim().length() > 0) {
     208                    vehiclePropertyStrings.put(vehicleProperty, textFieldContent);
     209                }
     210            }
     211
     212            return vehiclePropertyStrings;
     213        }
     214    }
     215
     216    private static class RoadQualityPanel extends JPanel {
     217
     218        private JTextField inclineUpTextField;
     219        private JTextField inclineDownTextField;
     220        private JTextField surfaceTextField;
     221        private JTextField tracktypeTextField;
     222
     223        public RoadQualityPanel(PreferenceAccessParameters initialParameters) {
     224            super();
     225            this.setBorder(BorderFactory.createTitledBorder("road requirements"));
     226
     227
     228            this.setLayout(new GridLayout(4, 2));
     229
     230            /* incline up */
     231            {
     232                JLabel inclineUpLabel = new JLabel("max. incline up (%, pos.)");
     233                inclineUpLabel.setToolTipText("maximum incline the vehicle can go up");
     234                this.add(inclineUpLabel);
     235
     236                inclineUpTextField = new JTextField();
     237
     238                String vehiclePropertyString =
     239                    initialParameters.getVehiclePropertyString(MAX_INCLINE_UP);
     240                if (vehiclePropertyString != null) {
     241                    inclineUpTextField.setText(vehiclePropertyString);
     242                }
     243                inclineUpTextField.setToolTipText("maximum incline the vehicle can go up");
     244
     245                this.add(inclineUpTextField);
     246            }
     247
     248            /* incline down */
     249            {
     250                JLabel inclineDownLabel = new JLabel("max. incline down (%, pos.)");
     251                inclineDownLabel.setToolTipText("maximum incline the vehicle can go down");
     252                this.add(inclineDownLabel);
     253
     254                inclineDownTextField = new JTextField();
     255
     256                String vehiclePropertyString =
     257                    initialParameters.getVehiclePropertyString(MAX_INCLINE_DOWN);
     258                if (vehiclePropertyString != null) {
     259                    inclineDownTextField.setText(vehiclePropertyString);
     260                }
     261                inclineDownTextField.setToolTipText("maximum incline the vehicle can go down");
     262
     263                this.add(inclineDownTextField);
     264            }
     265
     266            /* surface */
     267            {
     268                JLabel surfaceLabel = new JLabel("surface blacklist");
     269                surfaceLabel.setToolTipText("list of surfaces the vehicle cannot use, "
     270                        + "values are separated by semicolons (;)");
     271                this.add(surfaceLabel);
     272
     273                surfaceTextField = new JTextField();
     274
     275                String vehiclePropertyString =
     276                    initialParameters.getVehiclePropertyString(SURFACE_BLACKLIST);
     277
     278                if (vehiclePropertyString != null) {
     279                    surfaceTextField.setText(vehiclePropertyString);
     280                }
     281
     282                surfaceTextField.setToolTipText("list of surfaces the vehicle cannot use, "
     283                        + "values are separated by semicolons (;)");
     284
     285                this.add(surfaceTextField);
     286            }
     287
     288            /* tracktype */
     289            {
     290                JLabel tracktypeLabel = new JLabel("max. tracktype grade");
     291                tracktypeLabel.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
     292                        + " 0 for none");
     293                this.add(tracktypeLabel);
     294
     295                tracktypeTextField = new JTextField();
     296
     297                String vehiclePropertyString =
     298                    initialParameters.getVehiclePropertyString(MAX_TRACKTYPE);
     299                if (vehiclePropertyString != null) {
     300                    tracktypeTextField.setText(vehiclePropertyString);
     301                }
     302                tracktypeTextField.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
     303                        + " 0 for none");
     304
     305                this.add(tracktypeTextField);
     306            }
     307
     308        }
     309
     310        public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
     311
     312            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     313                new HashMap<VehiclePropertyType<?>, String>();
     314
     315            String incUpString = inclineUpTextField.getText();
     316            if (incUpString.trim().length() > 0) {
     317                vehiclePropertyStrings.put(MAX_INCLINE_UP, incUpString);
     318            }
     319
     320            String incDownString = inclineDownTextField.getText();
     321            if (incDownString.trim().length() > 0) {
     322                vehiclePropertyStrings.put(MAX_INCLINE_DOWN, incDownString);
     323            }
     324
     325            String surfaceString = surfaceTextField.getText();
     326            if (surfaceString.trim().length() > 0) {
     327                vehiclePropertyStrings.put(SURFACE_BLACKLIST, surfaceString);
     328            }
     329
     330            String tracktypeString = tracktypeTextField.getText();
     331            if (tracktypeString.trim().length() > 0) {
     332                vehiclePropertyStrings.put(MAX_TRACKTYPE, tracktypeString);
     333            }
     334
     335            return vehiclePropertyStrings;
     336        }
     337    }
     338
     339    private class OkCancelPanel extends JPanel {
     340
     341        public OkCancelPanel() {
     342
     343            new BoxLayout(this, BoxLayout.X_AXIS);
     344
     345            JButton okButton = new JButton(existingBookmark?"Change bookmark":"Create bookmark");
     346            okButton.addActionListener(new ActionListener() {
     347                public void actionPerformed(ActionEvent e) {
     348                    String bookmarkName = bookmarkNamePanel.getBookmarkName();
     349                    if (bookmarkName != null) {
     350                        PreferenceAccessParameters parameters = getAccessParameters();
     351                        if (parameters != null) {
     352                            okAction.execute(bookmarkName, parameters);
     353                            AccessParameterDialog.this.dispose();
     354                        }
     355                    }
     356                }
     357            });
     358            this.add(okButton);
     359
     360            JButton cancelButton = new JButton("Cancel");
     361            cancelButton.addActionListener(new ActionListener() {
     362                public void actionPerformed(ActionEvent e) {
     363                    AccessParameterDialog.this.dispose();
     364                }
     365            });
     366            this.add(cancelButton);
     367
     368        }
     369
     370    }
     371
     372    private boolean existingBookmark = false;
     373    private final Collection<String> existingBookmarkNames;
     374
     375    private final BookmarkAction okAction;
     376
     377    private final BookmarkNamePanel bookmarkNamePanel;
     378    private final AccessClassPanel accessClassPanel;
     379    private final AccessTypesPanel accessTypesPanel;
     380    private final VehiclePropertiesPanel vehiclePropertiesPanel;
     381    private final RoadQualityPanel roadQualityPanel;
     382
     383    public AccessParameterDialog(final Frame owner, boolean existingBookmark, String initialName,
     384            Collection<String> existingBookmarkNames,
     385            PreferenceAccessParameters initialAccessParameters, BookmarkAction okAction) {
     386        super(owner, "edit access parameters", true);
     387
     388        this.existingBookmark = existingBookmark;
     389        this.existingBookmarkNames = existingBookmarkNames;
     390        this.okAction = okAction;
     391
     392        GridBagLayout layout = new GridBagLayout();
     393        this.setLayout(layout);
     394
     395        GridBagConstraints gbc = new GridBagConstraints();
     396        gbc.gridx = 0;
     397        gbc.weighty = 1;
     398        gbc.fill = GridBagConstraints.BOTH;
     399
     400        bookmarkNamePanel = new BookmarkNamePanel(initialName);
     401        gbc.gridy = 0;
     402        layout.setConstraints(bookmarkNamePanel, gbc);
     403        this.add(bookmarkNamePanel);
     404
     405        accessClassPanel = new AccessClassPanel(initialAccessParameters);
     406        gbc.gridy = 1;
     407        layout.setConstraints(accessClassPanel, gbc);
     408        this.add(accessClassPanel);
     409
     410        accessTypesPanel = new AccessTypesPanel(initialAccessParameters);
     411        gbc.gridy = 2;
     412        layout.setConstraints(accessTypesPanel, gbc);
     413        this.add(accessTypesPanel);
     414
     415        vehiclePropertiesPanel = new VehiclePropertiesPanel(initialAccessParameters);
     416        gbc.gridy = 3;
     417        layout.setConstraints(vehiclePropertiesPanel, gbc);
     418        this.add(vehiclePropertiesPanel);
     419
     420        roadQualityPanel = new RoadQualityPanel(initialAccessParameters);
     421        gbc.gridy = 4;
     422        layout.setConstraints(roadQualityPanel, gbc);
     423        this.add(roadQualityPanel);
     424
     425        JPanel okCancelPanel = new OkCancelPanel();
     426        gbc.gridy = 5;
     427        gbc.weighty = 0;
     428        gbc.fill = GridBagConstraints.HORIZONTAL;
     429        layout.setConstraints(okCancelPanel, gbc);
     430        this.add(okCancelPanel);
     431
     432        this.pack();
     433    }
     434
     435    private PreferenceAccessParameters getAccessParameters() {
     436
     437        String accessClass = accessClassPanel.getAccessClass();
     438        Collection<AccessType> usableAccessTypes = accessTypesPanel.getUsableAccessTypes();
     439        Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     440            vehiclePropertiesPanel.getVehiclePropertyStrings();
     441        Map<VehiclePropertyType<?>, String> additionalVehiclePropertyStrings =
     442            roadQualityPanel.getVehiclePropertyStrings();
     443
     444        if (accessClass != null && usableAccessTypes != null && vehiclePropertyStrings != null
     445                && additionalVehiclePropertyStrings != null) {
     446
     447            vehiclePropertyStrings.putAll(additionalVehiclePropertyStrings);
     448
     449            try {
     450                return new PreferenceAccessParameters(accessClass, usableAccessTypes, vehiclePropertyStrings);
     451            } catch (PropertyValueSyntaxException e) {
     452                JOptionPane.showMessageDialog(this, e.getMessage());
     453                return null;
     454            }
     455
     456        } else {
     457            return null;
     458        }
     459    }
    460460
    461461}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewDialog.java

    r16520 r23189  
    4444public class GraphViewDialog extends ToggleDialog implements Observer {
    4545
    46         private static final int HEIGHT = 150;
    47 
    48         /** map from labels to available color schemes */
    49         private final LinkedHashMap<String, ColorScheme> availableColorSchemes;
    50 
    51 
    52         private final GraphViewPreferences preferences;
    53         private final GraphViewPlugin plugin;
    54 
    55         private final JComboBox rulesetComboBox;
    56         private final JComboBox bookmarkComboBox;
    57         private final JComboBox colorSchemeComboBox;
    58 
    59         /**
    60         * list of ruleset files in the order currently used by rulesetComboBox;
    61         * null if internal rulesets are used
    62         */
    63         private List<File> rulesetFiles;
    64 
    65         public GraphViewDialog(final GraphViewPlugin plugin) {
    66 
    67                 super("Graph View Dialog", "graphview",
    68                                 "Open the dialog for graph view configuration.", (Shortcut)null, HEIGHT);
    69 
    70                 this.preferences = GraphViewPreferences.getInstance();
    71                 this.plugin = plugin;
    72 
    73                 availableColorSchemes = new LinkedHashMap<String, ColorScheme>();
    74 
    75                 availableColorSchemes.put("default",
    76                                 new PreferencesColorScheme(preferences));
    77                 availableColorSchemes.put("end nodes",
    78                                 new EndNodeColorScheme(Color.GRAY, Color.RED, Color.GRAY));
    79                 availableColorSchemes.put("maxspeed",
    80                                 new MaxspeedColorScheme());
    81                 availableColorSchemes.put("maxweight",
    82                                 new MaxweightColorScheme());
    83                 availableColorSchemes.put("maxheight",
    84                                 new MaxheightColorScheme());
    85                 availableColorSchemes.put("incline",
    86                                 new InclineColorScheme());
    87 
    88                 JPanel selectionPanel = new JPanel();
    89                 GridBagLayout selectionLayout = new GridBagLayout();
    90                 selectionPanel.setLayout(selectionLayout);
    91 
    92                 GridBagConstraints gbcLabel = new GridBagConstraints();
    93                 gbcLabel.gridx = 0;
    94                 gbcLabel.anchor = GridBagConstraints.WEST;
    95                 gbcLabel.insets = new Insets(0, 5, 0, 5);
    96 
    97                 GridBagConstraints gbcComboBox = new GridBagConstraints();
    98                 gbcComboBox.gridx = 1;
    99                 gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
    100                 gbcComboBox.weightx = 1;
    101 
    102 
    103                 /* create ruleset label and combo box */
    104                 {
    105                         JLabel rulesetLabel = new JLabel("ruleset:");
    106                         gbcLabel.gridy = 0;
    107                         selectionLayout.setConstraints(rulesetLabel, gbcLabel);
    108                         selectionPanel.add(rulesetLabel);
    109 
    110                         rulesetComboBox = new JComboBox();
    111                         rulesetComboBox.addActionListener(rulesetActionListener);
    112                         gbcComboBox.gridy = 0;
    113                         selectionLayout.setConstraints(rulesetComboBox, gbcComboBox);
    114                         selectionPanel.add(rulesetComboBox);
    115                 }
    116 
    117                 /* create bookmark label and combo box */
    118                 {
    119                         JLabel bookmarkLabel = new JLabel("parameters:");
    120                         gbcLabel.gridy = 1;
    121                         selectionLayout.setConstraints(bookmarkLabel, gbcLabel);
    122                         selectionPanel.add(bookmarkLabel);
    123 
    124                         bookmarkComboBox = new JComboBox();
    125                         bookmarkComboBox.addActionListener(bookmarkActionListener);
    126                         gbcComboBox.gridy = 1;
    127                         selectionLayout.setConstraints(bookmarkComboBox, gbcComboBox);
    128                         selectionPanel.add(bookmarkComboBox);
    129                 }
    130 
    131                 /* create color scheme label and combo box */
    132                 {
    133                         JLabel colorSchemeLabel = new JLabel("coloring:");
    134                         gbcLabel.gridy = 2;
    135                         selectionLayout.setConstraints(colorSchemeLabel, gbcLabel);
    136                         selectionPanel.add(colorSchemeLabel);
    137 
    138                         colorSchemeComboBox = new JComboBox();
    139                         for (String colorSchemeName : availableColorSchemes.keySet()) {
    140                                 colorSchemeComboBox.addItem(colorSchemeName);
    141                                 ColorScheme colorScheme = availableColorSchemes.get(colorSchemeName);
    142                                 if (colorScheme.getClass().equals(preferences.getCurrentColorScheme().getClass())) {
    143                                         colorSchemeComboBox.setSelectedItem(colorSchemeName);
    144                                 }
    145                         }
    146                         colorSchemeComboBox.addActionListener(colorSchemeActionListener);
    147                         gbcComboBox.gridy = 2;
    148                         selectionLayout.setConstraints(colorSchemeComboBox, gbcComboBox);
    149                         selectionPanel.add(colorSchemeComboBox);
    150                 }
    151 
    152                 this.add(BorderLayout.CENTER, selectionPanel);
    153 
    154 
    155                 JPanel buttonPanel = new JPanel();
    156                 JButton showLayerButton = new JButton("create/update graph");
    157                 showLayerButton.addActionListener(new ActionListener() {
    158                         public void actionPerformed(ActionEvent e) {
    159                                 plugin.createGraphViewLayer();
    160                         }
    161                 });
    162                 buttonPanel.add(showLayerButton);
    163 
    164                 this.add(BorderLayout.SOUTH, buttonPanel);
    165 
    166                 updateSelections();
    167                 this.preferences.addObserver(this);
    168 
    169         }
    170 
    171         private final ActionListener rulesetActionListener = new ActionListener() {
    172                 public void actionPerformed(ActionEvent e) {
    173                         if (rulesetComboBox.getSelectedItem() != null) {
    174                                 int selectedRulesetIndex = rulesetComboBox.getSelectedIndex();
    175                                 if (rulesetFiles != null) {
    176                                         File selectedRulesetFile = rulesetFiles.get(selectedRulesetIndex);
    177                                         preferences.setCurrentRulesetFile(selectedRulesetFile);
    178                                         preferences.distributeChanges();
    179                                         plugin.updateGraphViewLayer();
    180                                 } else {
    181                                         if (selectedRulesetIndex < InternalRuleset.values().length) {
    182                                                 InternalRuleset selectedIRR = InternalRuleset.values()[selectedRulesetIndex];
    183                                                 preferences.setCurrentInternalRuleset(selectedIRR);
    184                                                 preferences.distributeChanges();
    185                                                 plugin.updateGraphViewLayer();
    186                                         }
    187                                 }
    188                         }
    189                 }
    190         };
    191 
    192         private final ActionListener bookmarkActionListener = new ActionListener() {
    193                 public void actionPerformed(ActionEvent e) {
    194                         String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    195                         if (selectedBookmarkName != null) {
    196                                 preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
    197                                 preferences.distributeChanges();
    198                                 plugin.updateGraphViewLayer();
    199                         }
    200                 }
    201         };
    202 
    203         private final ActionListener colorSchemeActionListener = new ActionListener() {
    204                 public void actionPerformed(ActionEvent e) {
    205                         assert availableColorSchemes.containsKey(colorSchemeComboBox.getSelectedItem());
    206                         String colorSchemeLabel = (String)colorSchemeComboBox.getSelectedItem();
    207                         preferences.setCurrentColorScheme(availableColorSchemes.get(colorSchemeLabel));
    208                         preferences.distributeChanges();
    209                         plugin.repaintGraphViewLayer();
    210                 }
    211         };
    212 
    213         public void update(Observable observable, Object param) {
    214                 if (observable == preferences) {
    215                         updateSelections();
    216                 }
    217         }
    218 
    219         protected void updateSelections() {
    220 
    221                 /* update rulesets */
    222 
    223                 rulesetComboBox.removeActionListener(rulesetActionListener);
    224 
    225                 if (preferences.getUseInternalRulesets()) {
    226 
    227                         rulesetFiles = null;
    228 
    229                         rulesetComboBox.removeAllItems();
    230                         for (int i=0; i < InternalRuleset.values().length; i++) {
    231                                 InternalRuleset ruleset = InternalRuleset.values()[i];
    232                                 rulesetComboBox.addItem(ruleset.toString());
    233                                 if (ruleset == preferences.getCurrentInternalRuleset()) {
    234                                         rulesetComboBox.setSelectedIndex(i);
    235                                 }
    236                         }
    237 
    238                         if (preferences.getCurrentInternalRuleset() == null) {
    239                                 rulesetComboBox.addItem("");
    240                                 rulesetComboBox.setSelectedIndex(InternalRuleset.values().length);
    241                         }
    242 
    243                 } else {
    244 
    245                         rulesetFiles = new LinkedList<File>();
    246 
    247                         File[] filesInRulesetFolder = preferences.getRulesetFolder().listFiles();
    248 
    249                         if (filesInRulesetFolder != null) {
    250                                 for (File possibleRulesetFile : filesInRulesetFolder) {
    251                                         try {
    252                                                 AccessRulesetReader.readAccessRuleset(new FileInputStream(possibleRulesetFile));
    253                                                 rulesetFiles.add(possibleRulesetFile);
    254                                         } catch (IOException ioe) {
    255                                                 //don't add to rulesetFiles
    256                                         }
    257                                 }
    258                         }
    259 
    260                         Collections.sort(rulesetFiles);
    261 
    262                         rulesetComboBox.removeAllItems();
    263                         for (int i=0; i < rulesetFiles.size(); i++) {
    264                                 File rulesetFile = rulesetFiles.get(i);
    265                                 rulesetComboBox.addItem(rulesetFile.getName());
    266                                 if (rulesetFile.equals(preferences.getCurrentRulesetFile())) {
    267                                         rulesetComboBox.setSelectedIndex(i);
    268                                 }
    269                         }
    270 
    271                 }
    272 
    273                 rulesetComboBox.addActionListener(rulesetActionListener);
    274 
    275                 /* update bookmarks */
    276 
    277                 bookmarkComboBox.removeActionListener(bookmarkActionListener);
    278 
    279                 String activeBookmarkName = preferences.getCurrentParameterBookmarkName();
    280                 Set<String> bookmarkNames = new HashSet<String>(preferences.getParameterBookmarks().keySet());
    281 
    282                 bookmarkComboBox.removeAllItems();
    283                 for (String bookmarkName : bookmarkNames) {
    284                         bookmarkComboBox.addItem(bookmarkName);
    285                         if (bookmarkName.equals(activeBookmarkName)) {
    286                                 bookmarkComboBox.setSelectedItem(bookmarkName);
    287                         }
    288                 }
    289 
    290                 bookmarkComboBox.addActionListener(bookmarkActionListener);
    291 
    292         }
     46    private static final int HEIGHT = 150;
     47
     48    /** map from labels to available color schemes */
     49    private final LinkedHashMap<String, ColorScheme> availableColorSchemes;
     50
     51
     52    private final GraphViewPreferences preferences;
     53    private final GraphViewPlugin plugin;
     54
     55    private final JComboBox rulesetComboBox;
     56    private final JComboBox bookmarkComboBox;
     57    private final JComboBox colorSchemeComboBox;
     58
     59    /**
     60    * list of ruleset files in the order currently used by rulesetComboBox;
     61    * null if internal rulesets are used
     62    */
     63    private List<File> rulesetFiles;
     64
     65    public GraphViewDialog(final GraphViewPlugin plugin) {
     66
     67        super("Graph View Dialog", "graphview",
     68                "Open the dialog for graph view configuration.", (Shortcut)null, HEIGHT);
     69
     70        this.preferences = GraphViewPreferences.getInstance();
     71        this.plugin = plugin;
     72
     73        availableColorSchemes = new LinkedHashMap<String, ColorScheme>();
     74
     75        availableColorSchemes.put("default",
     76                new PreferencesColorScheme(preferences));
     77        availableColorSchemes.put("end nodes",
     78                new EndNodeColorScheme(Color.GRAY, Color.RED, Color.GRAY));
     79        availableColorSchemes.put("maxspeed",
     80                new MaxspeedColorScheme());
     81        availableColorSchemes.put("maxweight",
     82                new MaxweightColorScheme());
     83        availableColorSchemes.put("maxheight",
     84                new MaxheightColorScheme());
     85        availableColorSchemes.put("incline",
     86                new InclineColorScheme());
     87
     88        JPanel selectionPanel = new JPanel();
     89        GridBagLayout selectionLayout = new GridBagLayout();
     90        selectionPanel.setLayout(selectionLayout);
     91
     92        GridBagConstraints gbcLabel = new GridBagConstraints();
     93        gbcLabel.gridx = 0;
     94        gbcLabel.anchor = GridBagConstraints.WEST;
     95        gbcLabel.insets = new Insets(0, 5, 0, 5);
     96
     97        GridBagConstraints gbcComboBox = new GridBagConstraints();
     98        gbcComboBox.gridx = 1;
     99        gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
     100        gbcComboBox.weightx = 1;
     101
     102
     103        /* create ruleset label and combo box */
     104        {
     105            JLabel rulesetLabel = new JLabel("ruleset:");
     106            gbcLabel.gridy = 0;
     107            selectionLayout.setConstraints(rulesetLabel, gbcLabel);
     108            selectionPanel.add(rulesetLabel);
     109
     110            rulesetComboBox = new JComboBox();
     111            rulesetComboBox.addActionListener(rulesetActionListener);
     112            gbcComboBox.gridy = 0;
     113            selectionLayout.setConstraints(rulesetComboBox, gbcComboBox);
     114            selectionPanel.add(rulesetComboBox);
     115        }
     116
     117        /* create bookmark label and combo box */
     118        {
     119            JLabel bookmarkLabel = new JLabel("parameters:");
     120            gbcLabel.gridy = 1;
     121            selectionLayout.setConstraints(bookmarkLabel, gbcLabel);
     122            selectionPanel.add(bookmarkLabel);
     123
     124            bookmarkComboBox = new JComboBox();
     125            bookmarkComboBox.addActionListener(bookmarkActionListener);
     126            gbcComboBox.gridy = 1;
     127            selectionLayout.setConstraints(bookmarkComboBox, gbcComboBox);
     128            selectionPanel.add(bookmarkComboBox);
     129        }
     130
     131        /* create color scheme label and combo box */
     132        {
     133            JLabel colorSchemeLabel = new JLabel("coloring:");
     134            gbcLabel.gridy = 2;
     135            selectionLayout.setConstraints(colorSchemeLabel, gbcLabel);
     136            selectionPanel.add(colorSchemeLabel);
     137
     138            colorSchemeComboBox = new JComboBox();
     139            for (String colorSchemeName : availableColorSchemes.keySet()) {
     140                colorSchemeComboBox.addItem(colorSchemeName);
     141                ColorScheme colorScheme = availableColorSchemes.get(colorSchemeName);
     142                if (colorScheme.getClass().equals(preferences.getCurrentColorScheme().getClass())) {
     143                    colorSchemeComboBox.setSelectedItem(colorSchemeName);
     144                }
     145            }
     146            colorSchemeComboBox.addActionListener(colorSchemeActionListener);
     147            gbcComboBox.gridy = 2;
     148            selectionLayout.setConstraints(colorSchemeComboBox, gbcComboBox);
     149            selectionPanel.add(colorSchemeComboBox);
     150        }
     151
     152        this.add(BorderLayout.CENTER, selectionPanel);
     153
     154
     155        JPanel buttonPanel = new JPanel();
     156        JButton showLayerButton = new JButton("create/update graph");
     157        showLayerButton.addActionListener(new ActionListener() {
     158            public void actionPerformed(ActionEvent e) {
     159                plugin.createGraphViewLayer();
     160            }
     161        });
     162        buttonPanel.add(showLayerButton);
     163
     164        this.add(BorderLayout.SOUTH, buttonPanel);
     165
     166        updateSelections();
     167        this.preferences.addObserver(this);
     168
     169    }
     170
     171    private final ActionListener rulesetActionListener = new ActionListener() {
     172        public void actionPerformed(ActionEvent e) {
     173            if (rulesetComboBox.getSelectedItem() != null) {
     174                int selectedRulesetIndex = rulesetComboBox.getSelectedIndex();
     175                if (rulesetFiles != null) {
     176                    File selectedRulesetFile = rulesetFiles.get(selectedRulesetIndex);
     177                    preferences.setCurrentRulesetFile(selectedRulesetFile);
     178                    preferences.distributeChanges();
     179                    plugin.updateGraphViewLayer();
     180                } else {
     181                    if (selectedRulesetIndex < InternalRuleset.values().length) {
     182                        InternalRuleset selectedIRR = InternalRuleset.values()[selectedRulesetIndex];
     183                        preferences.setCurrentInternalRuleset(selectedIRR);
     184                        preferences.distributeChanges();
     185                        plugin.updateGraphViewLayer();
     186                    }
     187                }
     188            }
     189        }
     190    };
     191
     192    private final ActionListener bookmarkActionListener = new ActionListener() {
     193        public void actionPerformed(ActionEvent e) {
     194            String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     195            if (selectedBookmarkName != null) {
     196                preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
     197                preferences.distributeChanges();
     198                plugin.updateGraphViewLayer();
     199            }
     200        }
     201    };
     202
     203    private final ActionListener colorSchemeActionListener = new ActionListener() {
     204        public void actionPerformed(ActionEvent e) {
     205            assert availableColorSchemes.containsKey(colorSchemeComboBox.getSelectedItem());
     206            String colorSchemeLabel = (String)colorSchemeComboBox.getSelectedItem();
     207            preferences.setCurrentColorScheme(availableColorSchemes.get(colorSchemeLabel));
     208            preferences.distributeChanges();
     209            plugin.repaintGraphViewLayer();
     210        }
     211    };
     212
     213    public void update(Observable observable, Object param) {
     214        if (observable == preferences) {
     215            updateSelections();
     216        }
     217    }
     218
     219    protected void updateSelections() {
     220
     221        /* update rulesets */
     222
     223        rulesetComboBox.removeActionListener(rulesetActionListener);
     224
     225        if (preferences.getUseInternalRulesets()) {
     226
     227            rulesetFiles = null;
     228
     229            rulesetComboBox.removeAllItems();
     230            for (int i=0; i < InternalRuleset.values().length; i++) {
     231                InternalRuleset ruleset = InternalRuleset.values()[i];
     232                rulesetComboBox.addItem(ruleset.toString());
     233                if (ruleset == preferences.getCurrentInternalRuleset()) {
     234                    rulesetComboBox.setSelectedIndex(i);
     235                }
     236            }
     237
     238            if (preferences.getCurrentInternalRuleset() == null) {
     239                rulesetComboBox.addItem("");
     240                rulesetComboBox.setSelectedIndex(InternalRuleset.values().length);
     241            }
     242
     243        } else {
     244
     245            rulesetFiles = new LinkedList<File>();
     246
     247            File[] filesInRulesetFolder = preferences.getRulesetFolder().listFiles();
     248
     249            if (filesInRulesetFolder != null) {
     250                for (File possibleRulesetFile : filesInRulesetFolder) {
     251                    try {
     252                        AccessRulesetReader.readAccessRuleset(new FileInputStream(possibleRulesetFile));
     253                        rulesetFiles.add(possibleRulesetFile);
     254                    } catch (IOException ioe) {
     255                        //don't add to rulesetFiles
     256                    }
     257                }
     258            }
     259
     260            Collections.sort(rulesetFiles);
     261
     262            rulesetComboBox.removeAllItems();
     263            for (int i=0; i < rulesetFiles.size(); i++) {
     264                File rulesetFile = rulesetFiles.get(i);
     265                rulesetComboBox.addItem(rulesetFile.getName());
     266                if (rulesetFile.equals(preferences.getCurrentRulesetFile())) {
     267                    rulesetComboBox.setSelectedIndex(i);
     268                }
     269            }
     270
     271        }
     272
     273        rulesetComboBox.addActionListener(rulesetActionListener);
     274
     275        /* update bookmarks */
     276
     277        bookmarkComboBox.removeActionListener(bookmarkActionListener);
     278
     279        String activeBookmarkName = preferences.getCurrentParameterBookmarkName();
     280        Set<String> bookmarkNames = new HashSet<String>(preferences.getParameterBookmarks().keySet());
     281
     282        bookmarkComboBox.removeAllItems();
     283        for (String bookmarkName : bookmarkNames) {
     284            bookmarkComboBox.addItem(bookmarkName);
     285            if (bookmarkName.equals(activeBookmarkName)) {
     286                bookmarkComboBox.setSelectedItem(bookmarkName);
     287            }
     288        }
     289
     290        bookmarkComboBox.addActionListener(bookmarkActionListener);
     291
     292    }
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewPreferenceEditor.java

    r19292 r23189  
    3333public class GraphViewPreferenceEditor implements PreferenceSetting {
    3434
    35         private File rulesetFolder;
    36         private Map<String, PreferenceAccessParameters> parameterBookmarks;
    37 
    38         private JPanel preferencePanel;
    39 
    40         private JCheckBox internalRulesetCheckBox;
    41         private JLabel rulesetFolderLabel;
    42         private JTextField rulesetFolderTextField;
    43         private JButton selectRulesetFolderButton;
    44 
    45         private JComboBox bookmarkComboBox;
    46         private JButton editBookmarkButton;
    47         private JButton deleteBookmarkButton;
    48 
    49         private JCheckBox separateDirectionsCheckBox;
    50 
    51         public void addGui(PreferenceTabbedPane gui) {
    52 
    53                 readPreferences();
    54 
    55                 preferencePanel = gui.createPreferenceTab("graphview", "Graphview",
    56                 "Settings for the Graphview plugin that visualizes routing graphs.");
    57 
    58                 JPanel mainPanel = createMainPanel();
    59 
    60                 preferencePanel.add(mainPanel, GBC.eol().fill(GBC.BOTH));
    61 
    62                 updateVehiclePanel(GraphViewPreferences.getInstance().getCurrentParameterBookmarkName());
    63 
    64         }
    65 
    66         /**
    67         * creates local versions of preference information
    68         * that will only be written to real preferences if the OK button is pressed
    69         */
    70         private void readPreferences() {
    71 
    72                 GraphViewPreferences preferences = GraphViewPreferences.getInstance();
    73 
    74                 rulesetFolder = preferences.getRulesetFolder();
    75 
    76                 parameterBookmarks =
    77                         new HashMap<String, PreferenceAccessParameters>(preferences.getParameterBookmarks());
    78 
    79         }
    80 
    81         private JPanel createMainPanel() {
    82 
    83                 JPanel mainPanel = new JPanel();
    84 
    85                 GridBagLayout mainLayout = new GridBagLayout();
    86                 mainPanel.setLayout(mainLayout);
    87 
    88                 GridBagConstraints constraints = new GridBagConstraints();
    89                 constraints.fill = GridBagConstraints.HORIZONTAL;
    90                 constraints.weightx = 1;
    91                 constraints.gridx = 0;
    92 
    93                 {
    94                         JPanel rulesetPanel = createRulesetPanel();
    95                         constraints.gridy = 0;
    96                         mainLayout.setConstraints(rulesetPanel, constraints);
    97                         mainPanel.add(rulesetPanel);
    98                 } {
    99                         JPanel vehiclePanel = createVehiclePanel();
    100                         constraints.gridy = 1;
    101                         mainLayout.setConstraints(vehiclePanel, constraints);
    102                         mainPanel.add(vehiclePanel);
    103                 } {
    104                         JPanel visualizationPanel = createVisualizationPanel();
    105                         constraints.gridy = 2;
    106                         mainLayout.setConstraints(visualizationPanel, constraints);
    107                         mainPanel.add(visualizationPanel);
    108                 }
    109 
    110                 mainPanel.add(GBC.glue(0, 0));
    111 
    112                 return mainPanel;
    113 
    114         }
    115 
    116         private JPanel createRulesetPanel() {
    117 
    118                 JPanel rulesetPanel = new JPanel();
    119                 rulesetPanel.setBorder(BorderFactory.createTitledBorder("ruleset"));
    120                 rulesetPanel.setLayout(new BoxLayout(rulesetPanel, BoxLayout.Y_AXIS));
    121 
    122                 internalRulesetCheckBox = new JCheckBox("use built-in rulesets");
    123                 internalRulesetCheckBox.setSelected(GraphViewPreferences.getInstance().getUseInternalRulesets());
    124                 internalRulesetCheckBox.addActionListener(internalRulesetActionListener);
    125                 rulesetPanel.add(internalRulesetCheckBox);
    126 
    127                 rulesetFolderLabel = new JLabel("external ruleset directory:");
    128                 rulesetPanel.add(rulesetFolderLabel);
    129 
    130                 rulesetFolderTextField = new JTextField();
    131                 rulesetFolderTextField.setText(rulesetFolder.getPath());
    132                 rulesetFolderTextField.setEditable(false);
    133                 rulesetPanel.add(rulesetFolderTextField);
    134 
    135                 selectRulesetFolderButton = new JButton("select directory");
    136                 selectRulesetFolderButton.addActionListener(selectRulesetFolderActionListener);
    137                 rulesetPanel.add(selectRulesetFolderButton);
    138 
    139                 updateRulesetPanel();
    140 
    141                 return rulesetPanel;
    142         }
    143 
    144         private JPanel createVehiclePanel() {
    145 
    146                 JPanel vehiclePanel = new JPanel();
    147                 vehiclePanel.setBorder(BorderFactory.createTitledBorder("vehicle"));
    148                 vehiclePanel.setLayout(new BoxLayout(vehiclePanel, BoxLayout.Y_AXIS));
    149 
    150                 bookmarkComboBox = new JComboBox();
    151                 vehiclePanel.add(bookmarkComboBox);
    152 
    153                 JPanel buttonPanel = new JPanel();
    154                 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
    155 
    156                 JButton createButton = new JButton("create");
    157                 createButton.addActionListener(createVehicleActionListener);
    158                 buttonPanel.add(createButton);
    159 
    160                 editBookmarkButton = new JButton("edit");
    161                 editBookmarkButton.addActionListener(editVehicleActionListener);
    162                 buttonPanel.add(editBookmarkButton);
    163 
    164                 deleteBookmarkButton = new JButton("delete");
    165                 deleteBookmarkButton.addActionListener(deleteVehicleActionListener);
    166                 buttonPanel.add(deleteBookmarkButton);
    167 
    168                 JButton restoreDefaultsButton = new JButton("restore defaults");
    169                 restoreDefaultsButton.addActionListener(restoreVehicleDefaultsActionListener);
    170                 buttonPanel.add(restoreDefaultsButton);
    171 
    172                 vehiclePanel.add(buttonPanel);
    173 
    174                 return vehiclePanel;
    175         }
    176 
    177         private JPanel createVisualizationPanel() {
    178 
    179                 JPanel visualizationPanel = new JPanel();
    180                 visualizationPanel.setBorder(BorderFactory.createTitledBorder("visualization"));
    181                 visualizationPanel.setLayout(new BoxLayout(visualizationPanel, BoxLayout.Y_AXIS));
    182 
    183                 separateDirectionsCheckBox = new JCheckBox("draw directions separately");
    184                 separateDirectionsCheckBox.setSelected(GraphViewPreferences.getInstance().getSeparateDirections());
    185                 visualizationPanel.add(separateDirectionsCheckBox);
    186 
    187                 return visualizationPanel;
    188         }
    189 
    190         public boolean ok() {
    191 
    192                 GraphViewPreferences preferences = GraphViewPreferences.getInstance();
    193 
    194                 preferences.setUseInternalRulesets(internalRulesetCheckBox.isSelected());
    195                 preferences.setRulesetFolder(rulesetFolder);
    196 
    197                 preferences.setParameterBookmarks(parameterBookmarks);
    198 
    199                 String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    200                 preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
    201 
    202                 preferences.setSeparateDirections(separateDirectionsCheckBox.isSelected());
    203 
    204                 preferences.distributeChanges();
    205 
    206                 return false;
    207         }
    208 
    209         private final ActionListener internalRulesetActionListener = new ActionListener() {
    210                 public void actionPerformed(ActionEvent e) {
    211                         updateRulesetPanel();
    212                 }
    213         };
    214 
    215         private final ActionListener selectRulesetFolderActionListener = new ActionListener() {
    216                 public void actionPerformed(ActionEvent e) {
    217 
    218                         File initialFCDirectory = rulesetFolder;
    219                         if (rulesetFolder.getParentFile() != null) {
    220                                 initialFCDirectory = rulesetFolder.getParentFile();
    221                         }
    222 
    223                         final JFileChooser fc = new JFileChooser();
    224                         fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    225                         fc.setCurrentDirectory(initialFCDirectory);
    226 
    227                         int returnVal = fc.showOpenDialog(preferencePanel);
    228 
    229                         if (returnVal == JFileChooser.APPROVE_OPTION) {
    230                                 rulesetFolder = fc.getSelectedFile();
    231                                 rulesetFolderTextField.setText(rulesetFolder.getPath());
    232                         }
    233 
    234                 }
    235         };
    236 
    237         private final ActionListener createVehicleActionListener = new ActionListener() {
    238                 public void actionPerformed(ActionEvent e) {
    239 
    240                         PreferenceAccessParameters defaultBookmarkParameters =
    241                                 GraphViewPreferenceDefaults.createDefaultBookmarkAccessParameters();
    242 
    243                         AccessParameterDialog apd = new AccessParameterDialog(
    244                                         null,
    245                                         false,
    246                                         "new bookmark",
    247                                         parameterBookmarks.keySet(),
    248                                         defaultBookmarkParameters,
    249                                         new BookmarkAction() {
    250                                                 public void execute(String name, PreferenceAccessParameters parameters) {
    251                                                         parameterBookmarks.put(name, parameters);
    252                                                         updateVehiclePanel(name);
    253                                                 }
    254                                         });
    255 
    256                         apd.setVisible(true);
    257                 }
    258         };
    259 
    260         private final ActionListener editVehicleActionListener = new ActionListener() {
    261                 public void actionPerformed(ActionEvent e) {
    262                         if (bookmarkComboBox.getSelectedItem() != null) {
    263 
    264                                 final String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    265                                 PreferenceAccessParameters parameters =
    266                                         parameterBookmarks.get(selectedBookmarkName);
    267 
    268                                 Collection<String> otherBookmarkNames = new LinkedList<String>();
    269                                 for (String bookmarkName : parameterBookmarks.keySet()) {
    270                                         if (!bookmarkName.equals(selectedBookmarkName)) {
    271                                                 otherBookmarkNames.add(bookmarkName);
    272                                         }
    273                                 }
    274 
    275                                 AccessParameterDialog apd = new AccessParameterDialog(
    276                                                 null,
    277                                                 true,
    278                                                 selectedBookmarkName,
    279                                                 otherBookmarkNames,
    280                                                 parameters,
    281                                                 new BookmarkAction() {
    282                                                         public void execute(String name, PreferenceAccessParameters parameters) {
    283                                                                 parameterBookmarks.remove(selectedBookmarkName);
    284                                                                 parameterBookmarks.put(name, parameters);
    285                                                                 updateVehiclePanel(name);
    286                                                         }
    287                                                 });
    288 
    289                                 apd.setVisible(true);
    290                         }
    291 
    292                 }
    293         };
    294 
    295         private final ActionListener deleteVehicleActionListener = new ActionListener() {
    296                 public void actionPerformed(ActionEvent e) {
    297                         if (bookmarkComboBox.getSelectedItem() != null) {
    298 
    299                                 String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    300 
    301                                 int userChoice = JOptionPane.showConfirmDialog(
    302                                                 preferencePanel,
    303                                                 "Really delete \"" + selectedBookmarkName + "\"?",
    304                                                 "Bookmark deletion",
    305                                                 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    306 
    307                                 if (userChoice == JOptionPane.YES_OPTION) {
    308                                         parameterBookmarks.remove(selectedBookmarkName);
    309                                         updateVehiclePanel(null);
    310                                 }
    311 
    312                         }
    313                 }
    314         };
    315 
    316         private final ActionListener restoreVehicleDefaultsActionListener = new ActionListener() {
    317                 public void actionPerformed(ActionEvent e) {
    318 
    319                         int userChoice = JOptionPane.showConfirmDialog(
    320                                         preferencePanel,
    321                                         "Really restore default bookmarks?\n"
    322                                         + "All manually added or edited bookmarks will be lost!",
    323                                         "Bookmark reset",
    324                                         JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    325 
    326                         if (userChoice == JOptionPane.YES_OPTION) {
    327                                 parameterBookmarks.clear();
    328                                 parameterBookmarks.putAll(
    329                                                 GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks());
    330                                 updateVehiclePanel(null);
    331                         }
    332 
    333                 }
    334         };
    335 
    336         private void updateRulesetPanel() {
    337 
    338                 rulesetFolderLabel.setEnabled(!internalRulesetCheckBox.isSelected());
    339                 rulesetFolderTextField.setEnabled(!internalRulesetCheckBox.isSelected());
    340                 selectRulesetFolderButton.setEnabled(!internalRulesetCheckBox.isSelected());
    341 
    342         }
    343 
    344         private void updateVehiclePanel(String selectedBookmarkName) {
    345 
    346                 bookmarkComboBox.removeAllItems();
    347                 for (String bookmarkName : parameterBookmarks.keySet()) {
    348                         bookmarkComboBox.addItem(bookmarkName);
    349                 }
    350 
    351                 if (selectedBookmarkName == null) {
    352                         if (bookmarkComboBox.getItemCount() > 0) {
    353                                 bookmarkComboBox.setSelectedIndex(0);
    354                         }
    355                 } else {
    356                         bookmarkComboBox.setSelectedItem(selectedBookmarkName);
    357                 }
    358 
    359                 editBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
    360                 deleteBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
    361 
    362         }
     35    private File rulesetFolder;
     36    private Map<String, PreferenceAccessParameters> parameterBookmarks;
     37
     38    private JPanel preferencePanel;
     39
     40    private JCheckBox internalRulesetCheckBox;
     41    private JLabel rulesetFolderLabel;
     42    private JTextField rulesetFolderTextField;
     43    private JButton selectRulesetFolderButton;
     44
     45    private JComboBox bookmarkComboBox;
     46    private JButton editBookmarkButton;
     47    private JButton deleteBookmarkButton;
     48
     49    private JCheckBox separateDirectionsCheckBox;
     50
     51    public void addGui(PreferenceTabbedPane gui) {
     52
     53        readPreferences();
     54
     55        preferencePanel = gui.createPreferenceTab("graphview", "Graphview",
     56        "Settings for the Graphview plugin that visualizes routing graphs.");
     57
     58        JPanel mainPanel = createMainPanel();
     59
     60        preferencePanel.add(mainPanel, GBC.eol().fill(GBC.BOTH));
     61
     62        updateVehiclePanel(GraphViewPreferences.getInstance().getCurrentParameterBookmarkName());
     63
     64    }
     65
     66    /**
     67    * creates local versions of preference information
     68    * that will only be written to real preferences if the OK button is pressed
     69    */
     70    private void readPreferences() {
     71
     72        GraphViewPreferences preferences = GraphViewPreferences.getInstance();
     73
     74        rulesetFolder = preferences.getRulesetFolder();
     75
     76        parameterBookmarks =
     77            new HashMap<String, PreferenceAccessParameters>(preferences.getParameterBookmarks());
     78
     79    }
     80
     81    private JPanel createMainPanel() {
     82
     83        JPanel mainPanel = new JPanel();
     84
     85        GridBagLayout mainLayout = new GridBagLayout();
     86        mainPanel.setLayout(mainLayout);
     87
     88        GridBagConstraints constraints = new GridBagConstraints();
     89        constraints.fill = GridBagConstraints.HORIZONTAL;
     90        constraints.weightx = 1;
     91        constraints.gridx = 0;
     92
     93        {
     94            JPanel rulesetPanel = createRulesetPanel();
     95            constraints.gridy = 0;
     96            mainLayout.setConstraints(rulesetPanel, constraints);
     97            mainPanel.add(rulesetPanel);
     98        } {
     99            JPanel vehiclePanel = createVehiclePanel();
     100            constraints.gridy = 1;
     101            mainLayout.setConstraints(vehiclePanel, constraints);
     102            mainPanel.add(vehiclePanel);
     103        } {
     104            JPanel visualizationPanel = createVisualizationPanel();
     105            constraints.gridy = 2;
     106            mainLayout.setConstraints(visualizationPanel, constraints);
     107            mainPanel.add(visualizationPanel);
     108        }
     109
     110        mainPanel.add(GBC.glue(0, 0));
     111
     112        return mainPanel;
     113
     114    }
     115
     116    private JPanel createRulesetPanel() {
     117
     118        JPanel rulesetPanel = new JPanel();
     119        rulesetPanel.setBorder(BorderFactory.createTitledBorder("ruleset"));
     120        rulesetPanel.setLayout(new BoxLayout(rulesetPanel, BoxLayout.Y_AXIS));
     121
     122        internalRulesetCheckBox = new JCheckBox("use built-in rulesets");
     123        internalRulesetCheckBox.setSelected(GraphViewPreferences.getInstance().getUseInternalRulesets());
     124        internalRulesetCheckBox.addActionListener(internalRulesetActionListener);
     125        rulesetPanel.add(internalRulesetCheckBox);
     126
     127        rulesetFolderLabel = new JLabel("external ruleset directory:");
     128        rulesetPanel.add(rulesetFolderLabel);
     129
     130        rulesetFolderTextField = new JTextField();
     131        rulesetFolderTextField.setText(rulesetFolder.getPath());
     132        rulesetFolderTextField.setEditable(false);
     133        rulesetPanel.add(rulesetFolderTextField);
     134
     135        selectRulesetFolderButton = new JButton("select directory");
     136        selectRulesetFolderButton.addActionListener(selectRulesetFolderActionListener);
     137        rulesetPanel.add(selectRulesetFolderButton);
     138
     139        updateRulesetPanel();
     140
     141        return rulesetPanel;
     142    }
     143
     144    private JPanel createVehiclePanel() {
     145
     146        JPanel vehiclePanel = new JPanel();
     147        vehiclePanel.setBorder(BorderFactory.createTitledBorder("vehicle"));
     148        vehiclePanel.setLayout(new BoxLayout(vehiclePanel, BoxLayout.Y_AXIS));
     149
     150        bookmarkComboBox = new JComboBox();
     151        vehiclePanel.add(bookmarkComboBox);
     152
     153        JPanel buttonPanel = new JPanel();
     154        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
     155
     156        JButton createButton = new JButton("create");
     157        createButton.addActionListener(createVehicleActionListener);
     158        buttonPanel.add(createButton);
     159
     160        editBookmarkButton = new JButton("edit");
     161        editBookmarkButton.addActionListener(editVehicleActionListener);
     162        buttonPanel.add(editBookmarkButton);
     163
     164        deleteBookmarkButton = new JButton("delete");
     165        deleteBookmarkButton.addActionListener(deleteVehicleActionListener);
     166        buttonPanel.add(deleteBookmarkButton);
     167
     168        JButton restoreDefaultsButton = new JButton("restore defaults");
     169        restoreDefaultsButton.addActionListener(restoreVehicleDefaultsActionListener);
     170        buttonPanel.add(restoreDefaultsButton);
     171
     172        vehiclePanel.add(buttonPanel);
     173
     174        return vehiclePanel;
     175    }
     176
     177    private JPanel createVisualizationPanel() {
     178
     179        JPanel visualizationPanel = new JPanel();
     180        visualizationPanel.setBorder(BorderFactory.createTitledBorder("visualization"));
     181        visualizationPanel.setLayout(new BoxLayout(visualizationPanel, BoxLayout.Y_AXIS));
     182
     183        separateDirectionsCheckBox = new JCheckBox("draw directions separately");
     184        separateDirectionsCheckBox.setSelected(GraphViewPreferences.getInstance().getSeparateDirections());
     185        visualizationPanel.add(separateDirectionsCheckBox);
     186
     187        return visualizationPanel;
     188    }
     189
     190    public boolean ok() {
     191
     192        GraphViewPreferences preferences = GraphViewPreferences.getInstance();
     193
     194        preferences.setUseInternalRulesets(internalRulesetCheckBox.isSelected());
     195        preferences.setRulesetFolder(rulesetFolder);
     196
     197        preferences.setParameterBookmarks(parameterBookmarks);
     198
     199        String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     200        preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
     201
     202        preferences.setSeparateDirections(separateDirectionsCheckBox.isSelected());
     203
     204        preferences.distributeChanges();
     205
     206        return false;
     207    }
     208
     209    private final ActionListener internalRulesetActionListener = new ActionListener() {
     210        public void actionPerformed(ActionEvent e) {
     211            updateRulesetPanel();
     212        }
     213    };
     214
     215    private final ActionListener selectRulesetFolderActionListener = new ActionListener() {
     216        public void actionPerformed(ActionEvent e) {
     217
     218            File initialFCDirectory = rulesetFolder;
     219            if (rulesetFolder.getParentFile() != null) {
     220                initialFCDirectory = rulesetFolder.getParentFile();
     221            }
     222
     223            final JFileChooser fc = new JFileChooser();
     224            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
     225            fc.setCurrentDirectory(initialFCDirectory);
     226
     227            int returnVal = fc.showOpenDialog(preferencePanel);
     228
     229            if (returnVal == JFileChooser.APPROVE_OPTION) {
     230                rulesetFolder = fc.getSelectedFile();
     231                rulesetFolderTextField.setText(rulesetFolder.getPath());
     232            }
     233
     234        }
     235    };
     236
     237    private final ActionListener createVehicleActionListener = new ActionListener() {
     238        public void actionPerformed(ActionEvent e) {
     239
     240            PreferenceAccessParameters defaultBookmarkParameters =
     241                GraphViewPreferenceDefaults.createDefaultBookmarkAccessParameters();
     242
     243            AccessParameterDialog apd = new AccessParameterDialog(
     244                    null,
     245                    false,
     246                    "new bookmark",
     247                    parameterBookmarks.keySet(),
     248                    defaultBookmarkParameters,
     249                    new BookmarkAction() {
     250                        public void execute(String name, PreferenceAccessParameters parameters) {
     251                            parameterBookmarks.put(name, parameters);
     252                            updateVehiclePanel(name);
     253                        }
     254                    });
     255
     256            apd.setVisible(true);
     257        }
     258    };
     259
     260    private final ActionListener editVehicleActionListener = new ActionListener() {
     261        public void actionPerformed(ActionEvent e) {
     262            if (bookmarkComboBox.getSelectedItem() != null) {
     263
     264                final String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     265                PreferenceAccessParameters parameters =
     266                    parameterBookmarks.get(selectedBookmarkName);
     267
     268                Collection<String> otherBookmarkNames = new LinkedList<String>();
     269                for (String bookmarkName : parameterBookmarks.keySet()) {
     270                    if (!bookmarkName.equals(selectedBookmarkName)) {
     271                        otherBookmarkNames.add(bookmarkName);
     272                    }
     273                }
     274
     275                AccessParameterDialog apd = new AccessParameterDialog(
     276                        null,
     277                        true,
     278                        selectedBookmarkName,
     279                        otherBookmarkNames,
     280                        parameters,
     281                        new BookmarkAction() {
     282                            public void execute(String name, PreferenceAccessParameters parameters) {
     283                                parameterBookmarks.remove(selectedBookmarkName);
     284                                parameterBookmarks.put(name, parameters);
     285                                updateVehiclePanel(name);
     286                            }
     287                        });
     288
     289                apd.setVisible(true);
     290            }
     291
     292        }
     293    };
     294
     295    private final ActionListener deleteVehicleActionListener = new ActionListener() {
     296        public void actionPerformed(ActionEvent e) {
     297            if (bookmarkComboBox.getSelectedItem() != null) {
     298
     299                String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     300
     301                int userChoice = JOptionPane.showConfirmDialog(
     302                        preferencePanel,
     303                        "Really delete \"" + selectedBookmarkName + "\"?",
     304                        "Bookmark deletion",
     305                        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
     306
     307                if (userChoice == JOptionPane.YES_OPTION) {
     308                    parameterBookmarks.remove(selectedBookmarkName);
     309                    updateVehiclePanel(null);
     310                }
     311
     312            }
     313        }
     314    };
     315
     316    private final ActionListener restoreVehicleDefaultsActionListener = new ActionListener() {
     317        public void actionPerformed(ActionEvent e) {
     318
     319            int userChoice = JOptionPane.showConfirmDialog(
     320                    preferencePanel,
     321                    "Really restore default bookmarks?\n"
     322                    + "All manually added or edited bookmarks will be lost!",
     323                    "Bookmark reset",
     324                    JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
     325
     326            if (userChoice == JOptionPane.YES_OPTION) {
     327                parameterBookmarks.clear();
     328                parameterBookmarks.putAll(
     329                        GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks());
     330                updateVehiclePanel(null);
     331            }
     332
     333        }
     334    };
     335
     336    private void updateRulesetPanel() {
     337
     338        rulesetFolderLabel.setEnabled(!internalRulesetCheckBox.isSelected());
     339        rulesetFolderTextField.setEnabled(!internalRulesetCheckBox.isSelected());
     340        selectRulesetFolderButton.setEnabled(!internalRulesetCheckBox.isSelected());
     341
     342    }
     343
     344    private void updateVehiclePanel(String selectedBookmarkName) {
     345
     346        bookmarkComboBox.removeAllItems();
     347        for (String bookmarkName : parameterBookmarks.keySet()) {
     348            bookmarkComboBox.addItem(bookmarkName);
     349        }
     350
     351        if (selectedBookmarkName == null) {
     352            if (bookmarkComboBox.getItemCount() > 0) {
     353                bookmarkComboBox.setSelectedIndex(0);
     354            }
     355        } else {
     356            bookmarkComboBox.setSelectedItem(selectedBookmarkName);
     357        }
     358
     359        editBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
     360        deleteBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
     361
     362    }
    363363
    364364}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/GraphViewLayer.java

    r22547 r23189  
    4646public class GraphViewLayer extends Layer implements LayerChangeListener, WayGraphObserver {
    4747
    48         private static final int NODE_RADIUS = 5;
    49 
    50         /**
    51         * offset from real position if {@link GraphViewPreferences#getSeparateDirections()} is active,
    52         * causes the graph nodes for the two directions to be visually distinguishable.
    53         * Positive values move "forward" direction to the right.
    54         */
    55         private static final double DIRECTIONAL_OFFSET = 20;
    56 
    57         private static final double OFFSET_ANGLE = 0.5 * Math.PI;
    58 
    59         private static final double MIN_QUAD_DISTANCE_FOR_OFFSET = 4;
    60 
    61         private static final boolean CONNECT_ALL_NODE_PAIRS = false;
    62 
    63         /** an arrow head that points along the x-axis to (0,0) */
    64         private static final Shape ARROW_HEAD;
    65 
    66         static {
    67 
    68                 Polygon head = new Polygon();
    69 
    70                 head.addPoint(  0,  0);
    71                 head.addPoint(-15, +4);
    72                 head.addPoint(-15, -4);
    73 
    74                 ARROW_HEAD = head;
    75         }
    76 
    77         private WayGraph wayGraph = null;
    78 
    79         private ColorScheme colorScheme = null;
    80         private NodePositioner nodePositioner = new NonMovingNodePositioner();
    81 
    82         public GraphViewLayer() {
    83                 super("Graph view");
    84                 MapView.addLayerChangeListener(this);
    85         }
    86 
    87         /** sets the WayGraph that is to be displayed by this layer, may be null */
    88         public void setWayGraph(WayGraph wayGraph) {
    89                 if (this.wayGraph != null) {
    90                         this.wayGraph.deleteObserver(this);
    91                 }
    92                 this.wayGraph = wayGraph;
    93                 if (wayGraph != null) {
    94                         wayGraph.addObserver(this);
    95                 }
    96         }
    97 
    98         /** sets the ColorScheme that is to be used for choosing colors, may be null */
    99         public void setColorScheme(ColorScheme colorScheme) {
    100                 this.colorScheme = colorScheme;
    101                 Main.panel.repaint();
    102         }
    103 
    104         /**
    105         * sets the NodePositioner that is to be used for determining node placement,
    106         * null will cause a {@link NonMovingNodePositioner} to be used.
    107         */
    108         public void setNodePositioner(NodePositioner nodePositioner) {
    109                 this.nodePositioner = nodePositioner;
    110                 if (nodePositioner == null) {
    111                         this.nodePositioner = new NonMovingNodePositioner();
    112                 }
    113                 Main.panel.repaint();
    114         }
    115 
    116         @Override
    117         public Icon getIcon() {
    118                 return ImageProvider.get("layer", "graphview");
    119         }
    120 
    121         private void paintGraphNode(final GraphNode node, final Graphics g, final MapView mv) {
    122 
    123                 Color color = colorScheme != null ? colorScheme.getNodeColor(node) : Color.LIGHT_GRAY;
    124 
    125                 Point p = getNodePoint(node, mv);
    126                 g.setColor(color);
    127                 g.fillOval(p.x - NODE_RADIUS, p.y - NODE_RADIUS, 2 * NODE_RADIUS, 2 * NODE_RADIUS);
    128 
    129         }
    130 
    131         private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv) {
    132 
    133                 if (!CONNECT_ALL_NODE_PAIRS && GraphViewPreferences.getInstance().getSeparateDirections()) {
    134 
    135                         //don't paint edges between nodes from the same SegmentNode and simply inverted Segment
    136                         if (e.getStartNode().getSegmentNode() == e.getTargetNode().getSegmentNode()
    137                                         && e.getStartNode().getSegment().getNode2() == e.getTargetNode().getSegment().getNode1()
    138                                         && e.getStartNode().getSegment().getNode1() == e.getTargetNode().getSegment().getNode2()) {
    139                                 return;
    140                         }
    141 
    142                 }
    143 
    144                 /* draw line(s) */
    145 
    146                 g2D.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    147 
    148                 List<Segment> edgeSegments = e.getPropertyValue(GraphEdgeSegments.PROPERTY);
    149 
    150                 if (edgeSegments.size() > 0) {
    151 
    152                         Segment firstSegment = edgeSegments.get(0);
    153                         Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
    154 
    155                         //draw segments
    156 
    157                         for (Segment segment : edgeSegments) {
    158 
    159                                 Color color = Color.WHITE;
    160                                 if (colorScheme != null) {
    161                                         color = colorScheme.getSegmentColor(segment);
    162                                 }
    163                                 g2D.setColor(color);
    164 
    165                                 Point p1 = getNodePoint(segment.getNode1(), mv);
    166                                 Point p2 = getNodePoint(segment.getNode2(), mv);
    167 
    168                                 if (segment == firstSegment) {
    169                                         p1 = getNodePoint(e.getStartNode(), mv);
    170                                 }
    171                                 if (segment == lastSegment) {
    172                                         p2 = getNodePoint(e.getTargetNode(), mv);
    173                                 }
    174 
    175                                 g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
    176 
    177                         }
    178 
    179                 } else {
    180 
    181                         g2D.setColor(Color.WHITE);
    182 
    183                         Point p1 = getNodePoint(e.getStartNode(), mv);
    184                         Point p2 = getNodePoint(e.getTargetNode(), mv);
    185 
    186                         g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
    187 
    188                 }
    189 
    190                 /* draw arrow head (note: color of last segment is still set) */
    191 
    192                 {
    193                         Point p1 = getNodePoint(e.getStartNode(), mv);
    194                         Point p2 = getNodePoint(e.getTargetNode(), mv);
    195 
    196                         if (edgeSegments.size() > 0) {
    197                                 Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
    198                                 p1 = getNodePoint(lastSegment.getNode1(), mv);
    199                         }
    200 
    201                         double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
    202                         Shape head = ARROW_HEAD;
    203                         head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
    204                         head = AffineTransform.getTranslateInstance(p2.x, p2.y).createTransformedShape(head);
    205 
    206                         g2D.fill(head);
    207 
    208                 }
    209         }
    210 
    211         private Point getNodePoint(GraphNode node, MapView mv) {
    212 
    213                 Point nodePoint = getNodePoint(nodePositioner.getPosition(node), mv);
    214 
    215                 if (GraphViewPreferences.getInstance().getSeparateDirections()
    216                                 && !GraphUtil.isEndNode(node)) {
    217 
    218                         SegmentNode node1 = node.getSegment().getNode1();
    219                         SegmentNode node2 = node.getSegment().getNode2();
    220 
    221                         Point node1Point = getNodePoint(node1, mv);
    222                         Point node2Point = getNodePoint(node2, mv);
    223 
    224                         double segmentX = node2Point.getX() - node1Point.getX();
    225                         double segmentY = node2Point.getY() - node1Point.getY();
    226 
    227                         if (segmentX*segmentX + segmentY*segmentY >= MIN_QUAD_DISTANCE_FOR_OFFSET) {
    228 
    229                                 double rotatedX = Math.cos(OFFSET_ANGLE) * segmentX - Math.sin(OFFSET_ANGLE) * segmentY;
    230                                 double rotatedY = Math.sin(OFFSET_ANGLE) * segmentX + Math.cos(OFFSET_ANGLE) * segmentY;
    231 
    232                                 double segmentLength = Math.sqrt(rotatedX * rotatedX + rotatedY * rotatedY);
    233 
    234                                 double normalizedX = rotatedX / segmentLength;
    235                                 double normalizedY = rotatedY / segmentLength;
    236 
    237                                 nodePoint.x += DIRECTIONAL_OFFSET * normalizedX;
    238                                 nodePoint.y += DIRECTIONAL_OFFSET * normalizedY;
    239 
    240                         }
    241 
    242                 }
    243 
    244                 return nodePoint;
    245         }
    246         private Point getNodePoint(SegmentNode node, MapView mv) {
    247                 LatLonCoords coords = new LatLonCoords(node.getLat(), node.getLon());
    248                 return getNodePoint(coords, mv);
    249         }
    250         private Point getNodePoint(LatLonCoords coords, MapView mv) {
    251                 LatLon latLon = new LatLon(coords.getLat(), coords.getLon());
    252                 EastNorth eastNorth = Main.proj.latlon2eastNorth(latLon);
    253                 return mv.getPoint(eastNorth);
    254         }
    255 
    256         /**
    257         * calculates the angle between the x axis and a vector given by two points
    258         * @param p1  first point for vector; != null
    259         * @param p2  second point for vector; != null
    260         * @return  angle in radians, in range [-Pi .. +Pi]
    261         */
    262         private double angleFromXAxis(Point p1, Point p2) {
    263                 assert p1 != null && p2 != null;
    264 
    265                 final float vecX = p2.x - p1.x;
    266                 final float vecY = p2.y - p1.y;
    267 
    268                 final float vecLength = (float)Math.sqrt(vecX*vecX + vecY*vecY);
    269 
    270                 final float dotProductVecAxis = vecX;
    271 
    272                 float angle = (float)Math.acos(dotProductVecAxis / vecLength);
    273 
    274                 if (p2.y < p1.y) {
    275                         angle = -angle;
    276                 }
    277 
    278                 assert -Math.PI*0.5 < angle && angle <= Math.PI*0.5;
    279 
    280                 return angle;
    281         }
    282 
    283         @Override
    284         public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
    285                 if (wayGraph != null) {
    286 
    287                         for (GraphNode n : wayGraph.getNodes()) {
    288                                 paintGraphNode(n, g, mv);
    289                         }
    290 
    291                         for (GraphEdge e : wayGraph.getEdges()) {
    292                                 paintGraphEdge(e, g, mv);
    293                         }
    294 
    295                 }
    296 
    297         }
    298 
    299         @Override
    300         public String getToolTipText() {
    301                 return "routing graph calculated by the GraphView plugin";
    302         }
    303 
    304         @Override
    305         public void mergeFrom(Layer from) {
    306                 throw new AssertionError("GraphView layer is not mergable");
    307         }
    308 
    309         @Override
    310         public boolean isMergable(Layer other) {
    311                 return false;
    312         }
    313 
    314         @Override
    315         public void visitBoundingBox(BoundingXYVisitor v) {
    316         }
    317 
    318         @Override
    319         public Object getInfoComponent() {
    320                 return getToolTipText();
    321         }
    322 
    323         @Override
    324         public Action[] getMenuEntries() {
    325                 return new Action[] {
    326                                 LayerListDialog.getInstance().createShowHideLayerAction(),
    327                                 LayerListDialog.getInstance().createDeleteLayerAction(),
    328                                 SeparatorLayerAction.INSTANCE,
    329                                 new RenameLayerAction(null, this),
    330                                 SeparatorLayerAction.INSTANCE,
    331                                 new LayerListPopup.InfoAction(this)};
    332         }
    333 
    334         public void update(WayGraph wayGraph) {
    335                 assert wayGraph == this.wayGraph;
    336                 Main.panel.repaint();
    337         }
    338 
    339         public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    340                 //do nothing
    341         }
    342         public void layerAdded(Layer newLayer) {
    343                 //do nothing
    344         }
    345         public void layerRemoved(Layer oldLayer) {
    346                 if (oldLayer == this) {
    347                         MapView.removeLayerChangeListener(this);
    348                 }
    349         }
     48    private static final int NODE_RADIUS = 5;
     49
     50    /**
     51    * offset from real position if {@link GraphViewPreferences#getSeparateDirections()} is active,
     52    * causes the graph nodes for the two directions to be visually distinguishable.
     53    * Positive values move "forward" direction to the right.
     54    */
     55    private static final double DIRECTIONAL_OFFSET = 20;
     56
     57    private static final double OFFSET_ANGLE = 0.5 * Math.PI;
     58
     59    private static final double MIN_QUAD_DISTANCE_FOR_OFFSET = 4;
     60
     61    private static final boolean CONNECT_ALL_NODE_PAIRS = false;
     62
     63    /** an arrow head that points along the x-axis to (0,0) */
     64    private static final Shape ARROW_HEAD;
     65
     66    static {
     67
     68        Polygon head = new Polygon();
     69
     70        head.addPoint(  0,  0);
     71        head.addPoint(-15, +4);
     72        head.addPoint(-15, -4);
     73
     74        ARROW_HEAD = head;
     75    }
     76
     77    private WayGraph wayGraph = null;
     78
     79    private ColorScheme colorScheme = null;
     80    private NodePositioner nodePositioner = new NonMovingNodePositioner();
     81
     82    public GraphViewLayer() {
     83        super("Graph view");
     84        MapView.addLayerChangeListener(this);
     85    }
     86
     87    /** sets the WayGraph that is to be displayed by this layer, may be null */
     88    public void setWayGraph(WayGraph wayGraph) {
     89        if (this.wayGraph != null) {
     90            this.wayGraph.deleteObserver(this);
     91        }
     92        this.wayGraph = wayGraph;
     93        if (wayGraph != null) {
     94            wayGraph.addObserver(this);
     95        }
     96    }
     97
     98    /** sets the ColorScheme that is to be used for choosing colors, may be null */
     99    public void setColorScheme(ColorScheme colorScheme) {
     100        this.colorScheme = colorScheme;
     101        Main.panel.repaint();
     102    }
     103
     104    /**
     105    * sets the NodePositioner that is to be used for determining node placement,
     106    * null will cause a {@link NonMovingNodePositioner} to be used.
     107    */
     108    public void setNodePositioner(NodePositioner nodePositioner) {
     109        this.nodePositioner = nodePositioner;
     110        if (nodePositioner == null) {
     111            this.nodePositioner = new NonMovingNodePositioner();
     112        }
     113        Main.panel.repaint();
     114    }
     115
     116    @Override
     117    public Icon getIcon() {
     118        return ImageProvider.get("layer", "graphview");
     119    }
     120
     121    private void paintGraphNode(final GraphNode node, final Graphics g, final MapView mv) {
     122
     123        Color color = colorScheme != null ? colorScheme.getNodeColor(node) : Color.LIGHT_GRAY;
     124
     125        Point p = getNodePoint(node, mv);
     126        g.setColor(color);
     127        g.fillOval(p.x - NODE_RADIUS, p.y - NODE_RADIUS, 2 * NODE_RADIUS, 2 * NODE_RADIUS);
     128
     129    }
     130
     131    private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv) {
     132
     133        if (!CONNECT_ALL_NODE_PAIRS && GraphViewPreferences.getInstance().getSeparateDirections()) {
     134
     135            //don't paint edges between nodes from the same SegmentNode and simply inverted Segment
     136            if (e.getStartNode().getSegmentNode() == e.getTargetNode().getSegmentNode()
     137                    && e.getStartNode().getSegment().getNode2() == e.getTargetNode().getSegment().getNode1()
     138                    && e.getStartNode().getSegment().getNode1() == e.getTargetNode().getSegment().getNode2()) {
     139                return;
     140            }
     141
     142        }
     143
     144        /* draw line(s) */
     145
     146        g2D.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     147
     148        List<Segment> edgeSegments = e.getPropertyValue(GraphEdgeSegments.PROPERTY);
     149
     150        if (edgeSegments.size() > 0) {
     151
     152            Segment firstSegment = edgeSegments.get(0);
     153            Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
     154
     155            //draw segments
     156
     157            for (Segment segment : edgeSegments) {
     158
     159                Color color = Color.WHITE;
     160                if (colorScheme != null) {
     161                    color = colorScheme.getSegmentColor(segment);
     162                }
     163                g2D.setColor(color);
     164
     165                Point p1 = getNodePoint(segment.getNode1(), mv);
     166                Point p2 = getNodePoint(segment.getNode2(), mv);
     167
     168                if (segment == firstSegment) {
     169                    p1 = getNodePoint(e.getStartNode(), mv);
     170                }
     171                if (segment == lastSegment) {
     172                    p2 = getNodePoint(e.getTargetNode(), mv);
     173                }
     174
     175                g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
     176
     177            }
     178
     179        } else {
     180
     181            g2D.setColor(Color.WHITE);
     182
     183            Point p1 = getNodePoint(e.getStartNode(), mv);
     184            Point p2 = getNodePoint(e.getTargetNode(), mv);
     185
     186            g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
     187
     188        }
     189
     190        /* draw arrow head (note: color of last segment is still set) */
     191
     192        {
     193            Point p1 = getNodePoint(e.getStartNode(), mv);
     194            Point p2 = getNodePoint(e.getTargetNode(), mv);
     195
     196            if (edgeSegments.size() > 0) {
     197                Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
     198                p1 = getNodePoint(lastSegment.getNode1(), mv);
     199            }
     200
     201            double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
     202            Shape head = ARROW_HEAD;
     203            head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
     204            head = AffineTransform.getTranslateInstance(p2.x, p2.y).createTransformedShape(head);
     205
     206            g2D.fill(head);
     207
     208        }
     209    }
     210
     211    private Point getNodePoint(GraphNode node, MapView mv) {
     212
     213        Point nodePoint = getNodePoint(nodePositioner.getPosition(node), mv);
     214
     215        if (GraphViewPreferences.getInstance().getSeparateDirections()
     216                && !GraphUtil.isEndNode(node)) {
     217
     218            SegmentNode node1 = node.getSegment().getNode1();
     219            SegmentNode node2 = node.getSegment().getNode2();
     220
     221            Point node1Point = getNodePoint(node1, mv);
     222            Point node2Point = getNodePoint(node2, mv);
     223
     224            double segmentX = node2Point.getX() - node1Point.getX();
     225            double segmentY = node2Point.getY() - node1Point.getY();
     226
     227            if (segmentX*segmentX + segmentY*segmentY >= MIN_QUAD_DISTANCE_FOR_OFFSET) {
     228
     229                double rotatedX = Math.cos(OFFSET_ANGLE) * segmentX - Math.sin(OFFSET_ANGLE) * segmentY;
     230                double rotatedY = Math.sin(OFFSET_ANGLE) * segmentX + Math.cos(OFFSET_ANGLE) * segmentY;
     231
     232                double segmentLength = Math.sqrt(rotatedX * rotatedX + rotatedY * rotatedY);
     233
     234                double normalizedX = rotatedX / segmentLength;
     235                double normalizedY = rotatedY / segmentLength;
     236
     237                nodePoint.x += DIRECTIONAL_OFFSET * normalizedX;
     238                nodePoint.y += DIRECTIONAL_OFFSET * normalizedY;
     239
     240            }
     241
     242        }
     243
     244        return nodePoint;
     245    }
     246    private Point getNodePoint(SegmentNode node, MapView mv) {
     247        LatLonCoords coords = new LatLonCoords(node.getLat(), node.getLon());
     248        return getNodePoint(coords, mv);
     249    }
     250    private Point getNodePoint(LatLonCoords coords, MapView mv) {
     251        LatLon latLon = new LatLon(coords.getLat(), coords.getLon());
     252        EastNorth eastNorth = Main.proj.latlon2eastNorth(latLon);
     253        return mv.getPoint(eastNorth);
     254    }
     255
     256    /**
     257    * calculates the angle between the x axis and a vector given by two points
     258    * @param p1  first point for vector; != null
     259    * @param p2  second point for vector; != null
     260    * @return  angle in radians, in range [-Pi .. +Pi]
     261    */
     262    private double angleFromXAxis(Point p1, Point p2) {
     263        assert p1 != null && p2 != null;
     264
     265        final float vecX = p2.x - p1.x;
     266        final float vecY = p2.y - p1.y;
     267
     268        final float vecLength = (float)Math.sqrt(vecX*vecX + vecY*vecY);
     269
     270        final float dotProductVecAxis = vecX;
     271
     272        float angle = (float)Math.acos(dotProductVecAxis / vecLength);
     273
     274        if (p2.y < p1.y) {
     275            angle = -angle;
     276        }
     277
     278        assert -Math.PI*0.5 < angle && angle <= Math.PI*0.5;
     279
     280        return angle;
     281    }
     282
     283    @Override
     284    public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
     285        if (wayGraph != null) {
     286
     287            for (GraphNode n : wayGraph.getNodes()) {
     288                paintGraphNode(n, g, mv);
     289            }
     290
     291            for (GraphEdge e : wayGraph.getEdges()) {
     292                paintGraphEdge(e, g, mv);
     293            }
     294
     295        }
     296
     297    }
     298
     299    @Override
     300    public String getToolTipText() {
     301        return "routing graph calculated by the GraphView plugin";
     302    }
     303
     304    @Override
     305    public void mergeFrom(Layer from) {
     306        throw new AssertionError("GraphView layer is not mergable");
     307    }
     308
     309    @Override
     310    public boolean isMergable(Layer other) {
     311        return false;
     312    }
     313
     314    @Override
     315    public void visitBoundingBox(BoundingXYVisitor v) {
     316    }
     317
     318    @Override
     319    public Object getInfoComponent() {
     320        return getToolTipText();
     321    }
     322
     323    @Override
     324    public Action[] getMenuEntries() {
     325        return new Action[] {
     326                LayerListDialog.getInstance().createShowHideLayerAction(),
     327                LayerListDialog.getInstance().createDeleteLayerAction(),
     328                SeparatorLayerAction.INSTANCE,
     329                new RenameLayerAction(null, this),
     330                SeparatorLayerAction.INSTANCE,
     331                new LayerListPopup.InfoAction(this)};
     332    }
     333
     334    public void update(WayGraph wayGraph) {
     335        assert wayGraph == this.wayGraph;
     336        Main.panel.repaint();
     337    }
     338
     339    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     340        //do nothing
     341    }
     342    public void layerAdded(Layer newLayer) {
     343        //do nothing
     344    }
     345    public void layerRemoved(Layer oldLayer) {
     346        if (oldLayer == this) {
     347            MapView.removeLayerChangeListener(this);
     348        }
     349    }
    350350}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/PreferencesColorScheme.java

    r16520 r23189  
    1313public class PreferencesColorScheme implements ColorScheme {
    1414
    15         private final GraphViewPreferences preferences;
     15    private final GraphViewPreferences preferences;
    1616
    17         public PreferencesColorScheme(GraphViewPreferences preferences) {
    18                 this.preferences = preferences;
    19         }
     17    public PreferencesColorScheme(GraphViewPreferences preferences) {
     18        this.preferences = preferences;
     19    }
    2020
    21         public Color getNodeColor(GraphNode node) {
    22                 return preferences.getNodeColor();
    23         }
     21    public Color getNodeColor(GraphNode node) {
     22        return preferences.getNodeColor();
     23    }
    2424
    25         public Color getSegmentColor(Segment segment) {
    26                 return preferences.getSegmentColor();
    27         }
     25    public Color getSegmentColor(Segment segment) {
     26        return preferences.getSegmentColor();
     27    }
    2828
    2929}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferenceDefaults.java

    r16520 r23189  
    2222public final class GraphViewPreferenceDefaults {
    2323
    24         /** prevents instantiation */
    25         private GraphViewPreferenceDefaults() { }
     24    /** prevents instantiation */
     25    private GraphViewPreferenceDefaults() { }
    2626
    27         /** creates a default "empty" bookmark */
    28         public static PreferenceAccessParameters createDefaultBookmarkAccessParameters() {
     27    /** creates a default "empty" bookmark */
     28    public static PreferenceAccessParameters createDefaultBookmarkAccessParameters() {
    2929
    30                 Collection<AccessType> accessTypes =
    31                         Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
     30        Collection<AccessType> accessTypes =
     31            Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
    3232
    33                 Map<VehiclePropertyType<?>, String> propertyStringMap =
    34                         new HashMap<VehiclePropertyType<?>, String>();
     33        Map<VehiclePropertyType<?>, String> propertyStringMap =
     34            new HashMap<VehiclePropertyType<?>, String>();
    3535
    36                 try {
    37                         return new PreferenceAccessParameters("", accessTypes, propertyStringMap);
    38                 } catch (PropertyValueSyntaxException e) {
    39                         throw new AssertionError(e);
    40                 }
     36        try {
     37            return new PreferenceAccessParameters("", accessTypes, propertyStringMap);
     38        } catch (PropertyValueSyntaxException e) {
     39            throw new AssertionError(e);
     40        }
    4141
    42         }
     42    }
    4343
    44         /** creates the default map of access parameter bookmarks */
    45         public static Map<String, PreferenceAccessParameters> createDefaultAccessParameterBookmarks() {
     44    /** creates the default map of access parameter bookmarks */
     45    public static Map<String, PreferenceAccessParameters> createDefaultAccessParameterBookmarks() {
    4646
    47                 try {
     47        try {
    4848
    49                         Map<String, PreferenceAccessParameters> result =
    50                                 new HashMap<String, PreferenceAccessParameters>();
     49            Map<String, PreferenceAccessParameters> result =
     50                new HashMap<String, PreferenceAccessParameters>();
    5151
    52                         Collection<AccessType> accessTypes =
    53                                 Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
     52            Collection<AccessType> accessTypes =
     53                Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
    5454
    55                         /* create motorcar bookmark */
    56                         {
    57                                 Map<VehiclePropertyType<?>, String> propertyMap =
    58                                         new HashMap<VehiclePropertyType<?>, String>();
     55            /* create motorcar bookmark */
     56            {
     57                Map<VehiclePropertyType<?>, String> propertyMap =
     58                    new HashMap<VehiclePropertyType<?>, String>();
    5959
    60                                 PreferenceAccessParameters accessParameters =
    61                                         new PreferenceAccessParameters("motorcar", accessTypes, propertyMap);
     60                PreferenceAccessParameters accessParameters =
     61                    new PreferenceAccessParameters("motorcar", accessTypes, propertyMap);
    6262
    63                                 result.put("motorcar", accessParameters);
    64                         }
     63                result.put("motorcar", accessParameters);
     64            }
    6565
    66                         /* create hgv bookmark */
    67                         {
    68                                 Map<VehiclePropertyType<?>, String> propertyMap =
    69                                         new HashMap<VehiclePropertyType<?>, String>();
    70                                 propertyMap.put(VehiclePropertyTypes.WEIGHT, "3.5");
     66            /* create hgv bookmark */
     67            {
     68                Map<VehiclePropertyType<?>, String> propertyMap =
     69                    new HashMap<VehiclePropertyType<?>, String>();
     70                propertyMap.put(VehiclePropertyTypes.WEIGHT, "3.5");
    7171
    72                                 PreferenceAccessParameters accessParameters =
    73                                         new PreferenceAccessParameters("hgv", accessTypes, propertyMap);
     72                PreferenceAccessParameters accessParameters =
     73                    new PreferenceAccessParameters("hgv", accessTypes, propertyMap);
    7474
    75                                 result.put("hgv (3.5 t)", accessParameters);
    76                         }
     75                result.put("hgv (3.5 t)", accessParameters);
     76            }
    7777
    78                         /* create bicycle bookmark */
    79                         {
    80                                 Map<VehiclePropertyType<?>, String> propertyMap =
    81                                         new HashMap<VehiclePropertyType<?>, String>();
     78            /* create bicycle bookmark */
     79            {
     80                Map<VehiclePropertyType<?>, String> propertyMap =
     81                    new HashMap<VehiclePropertyType<?>, String>();
    8282
    83                                 PreferenceAccessParameters accessParameters =
    84                                         new PreferenceAccessParameters("bicycle", accessTypes, propertyMap);
     83                PreferenceAccessParameters accessParameters =
     84                    new PreferenceAccessParameters("bicycle", accessTypes, propertyMap);
    8585
    86                                 result.put("bicycle", accessParameters);
    87                         }
     86                result.put("bicycle", accessParameters);
     87            }
    8888
    89                         /* create pedestrian bookmark */
    90                         {
    91                                 Map<VehiclePropertyType<?>, String> propertyMap =
    92                                         new HashMap<VehiclePropertyType<?>, String>();
     89            /* create pedestrian bookmark */
     90            {
     91                Map<VehiclePropertyType<?>, String> propertyMap =
     92                    new HashMap<VehiclePropertyType<?>, String>();
    9393
    94                                 PreferenceAccessParameters accessParameters =
    95                                         new PreferenceAccessParameters("foot", accessTypes, propertyMap);
     94                PreferenceAccessParameters accessParameters =
     95                    new PreferenceAccessParameters("foot", accessTypes, propertyMap);
    9696
    97                                 result.put("pedestrian", accessParameters);
    98                         }
     97                result.put("pedestrian", accessParameters);
     98            }
    9999
    100                         return result;
     100            return result;
    101101
    102                 } catch (PropertyValueSyntaxException e) {
    103                         throw new AssertionError(e);
    104                 }
    105         }
     102        } catch (PropertyValueSyntaxException e) {
     103            throw new AssertionError(e);
     104        }
     105    }
    106106
    107         public static File getDefaultRulesetFolder() {
    108                 return new File(System.getProperty("user.home"));
    109         }
     107    public static File getDefaultRulesetFolder() {
     108        return new File(System.getProperty("user.home"));
     109    }
    110110
    111111}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferences.java

    r16520 r23189  
    3939public class GraphViewPreferences extends Observable {
    4040
    41         private static GraphViewPreferences instance;
    42 
    43         /**
    44         * returns the single instance of GraphViewPreferences.
    45         * @param ignoreSyntaxErrors
    46         * @return
    47         */
    48         public static GraphViewPreferences getInstance() {
    49                 if (instance == null) {
    50                         instance = new GraphViewPreferences();
    51                 }
    52                 return instance;
    53         }
    54 
    55         private boolean useInternalRulesets;
    56         private File rulesetFolder;
    57         private File currentRulesetFile;
    58         private InternalRuleset currentInternalRuleset;
    59 
    60         private String currentParameterBookmarkName;
    61         private Map<String, PreferenceAccessParameters> parameterBookmarks;
    62 
    63         private ColorScheme currentColorScheme;
    64         private Color nodeColor;
    65         private Color segmentColor;
    66 
    67         private boolean separateDirections;
    68 
    69 
    70         public synchronized boolean getUseInternalRulesets() {
    71                 return useInternalRulesets;
    72         }
    73         public synchronized void setUseInternalRulesets(boolean useInternalRulesets) {
    74                 this.useInternalRulesets = useInternalRulesets;
    75         }
    76 
    77         public synchronized File getRulesetFolder() {
    78                 return rulesetFolder;
    79         }
    80         public synchronized void setRulesetFolder(File rulesetFolder) {
    81                 this.rulesetFolder = rulesetFolder;
    82         }
    83 
    84         public synchronized File getCurrentRulesetFile() {
    85                 return currentRulesetFile;
    86         }
    87         public synchronized void setCurrentRulesetFile(File currentRulesetFile) {
    88                 this.currentRulesetFile = currentRulesetFile;
    89         }
    90 
    91         public synchronized InternalRuleset getCurrentInternalRuleset() {
    92                 return currentInternalRuleset;
    93         }
    94         public synchronized void setCurrentInternalRuleset(InternalRuleset internalRuleset) {
    95                 this.currentInternalRuleset = internalRuleset;
    96         }
    97 
    98         /**
    99         * returns the name (map key) of the currently selected parameter bookmark
    100         * or null if none is selected.
    101         * If a name is returned, is has to be a key of the map returned by
    102         * {@link #getParameterBookmarks()}.
    103         */
    104         public synchronized String getCurrentParameterBookmarkName() {
    105                 assert parameterBookmarks.containsKey(currentParameterBookmarkName);
    106                 return currentParameterBookmarkName;
    107         }
    108 
    109         /**
    110         * returns the access parameters of the currently selected parameter bookmark
    111         * or null if none is selected.
    112         */
    113         public synchronized AccessParameters getCurrentParameterBookmark() {
    114                 if (currentParameterBookmarkName == null) {
    115                         return null;
    116                 } else {
    117                         assert parameterBookmarks.containsKey(currentParameterBookmarkName);
    118                         return parameterBookmarks.get(currentParameterBookmarkName);
    119                 }
    120         }
    121 
    122         /**
    123         * sets the active parameter bookmark using its name as an identifier
    124         * @param currentParameters  name of bookmark to set or null (no active bookmark).
    125         *                           Non-null values must be keys of the map returned by
    126         *                           {@link #getParameterBookmarks()}.
    127         */
    128         public synchronized void setCurrentParameterBookmarkName(String parameterBookmarkName) {
    129                 assert parameterBookmarks.containsKey(parameterBookmarkName);
    130                 this.currentParameterBookmarkName = parameterBookmarkName;
    131         }
    132 
    133         public synchronized Map<String, PreferenceAccessParameters> getParameterBookmarks() {
    134                 return Collections.unmodifiableMap(parameterBookmarks);
    135         }
    136         public synchronized void setParameterBookmarks(
    137                         Map<String, PreferenceAccessParameters> parameterBookmarks) {
    138                 assert parameterBookmarks != null;
    139 
    140                 this.parameterBookmarks =
    141                         new HashMap<String, PreferenceAccessParameters>(parameterBookmarks);
    142         }
    143 
    144         public synchronized ColorScheme getCurrentColorScheme() {
    145                 return currentColorScheme;
    146         }
    147         public synchronized void setCurrentColorScheme(ColorScheme currentColorScheme) {
    148                 this.currentColorScheme = currentColorScheme;
    149         }
    150 
    151         public synchronized Color getNodeColor() {
    152                 return nodeColor;
    153         }
    154         public synchronized void setNodeColor(Color nodeColor) {
    155                 this.nodeColor = nodeColor;
    156         }
    157 
    158         public synchronized Color getSegmentColor() {
    159                 return segmentColor;
    160         }
    161         public synchronized void setSegmentColor(Color segmentColor) {
    162                 this.segmentColor = segmentColor;
    163         }
    164 
    165         public synchronized boolean getSeparateDirections() {
    166                 return separateDirections;
    167         }
    168         public synchronized void setSeparateDirections(boolean separateDirections) {
    169                 this.separateDirections = separateDirections;
    170         }
    171 
    172         /**
    173         * writes changes to JOSM's preferences and notifies observers.
    174         * Must be called explicitly after setters (to prevent distributing incomplete changes).
    175         */
    176         public void distributeChanges() {
    177                 writePreferences();
    178                 setChanged();
    179                 notifyObservers();
    180         }
    181 
    182         private GraphViewPreferences() {
    183 
    184                 /* set defaults first (in case preferences are incomplete) */
    185 
    186                 fillDefaults();
    187 
    188                 /* read preferences and overwrite defaults */
    189 
    190                 readPreferences();
    191 
    192                 /* write preferences
    193                 * (this will restore missing/defect preferences,
    194                 *  but will simply rewrite valid preferences) */
    195 
    196                 writePreferences();
    197 
    198         }
    199 
    200         private void fillDefaults() {
    201 
    202                 parameterBookmarks = GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks();
    203 
    204                 if (parameterBookmarks.size() > 0) {
    205                         currentParameterBookmarkName = parameterBookmarks.keySet().iterator().next();
    206                 } else {
    207                         currentParameterBookmarkName = null;
    208                 }
    209 
    210                 useInternalRulesets = true;
    211                 rulesetFolder = GraphViewPreferenceDefaults.getDefaultRulesetFolder();
    212                 currentRulesetFile = null;
    213                 currentInternalRuleset = null;
    214 
    215                 nodeColor = Color.WHITE;
    216                 segmentColor = Color.WHITE;
    217                 currentColorScheme = new PreferencesColorScheme(this);
    218 
    219                 separateDirections = false;
    220 
    221         }
    222 
    223         private void writePreferences() {
    224 
    225                 Main.pref.put("graphview.parameterBookmarks",
    226                                 createAccessParameterBookmarksString(parameterBookmarks));
    227 
    228                 if (currentParameterBookmarkName != null) {
    229                         Main.pref.put("graphview.activeBookmark", currentParameterBookmarkName);
    230                 }
    231 
    232                 Main.pref.put("graphview.useInternalRulesets", useInternalRulesets);
    233 
    234                 Main.pref.put("graphview.rulesetFolder", rulesetFolder.getPath());
    235 
    236                 if (currentRulesetFile != null) {
    237                         Main.pref.put("graphview.rulesetFile", currentRulesetFile.getPath());
    238                 }
    239                 if (currentInternalRuleset != null) {
    240                         Main.pref.put("graphview.rulesetResource", currentInternalRuleset.toString());
    241                 }
    242 
    243                 Main.pref.put("graphview.defaultNodeColor", createColorString(nodeColor));
    244                 Main.pref.put("graphview.defaultSegmentColor", createColorString(segmentColor));
    245 
    246                 Main.pref.put("graphview.separateDirections", separateDirections);
    247 
    248         }
    249 
    250         private void readPreferences() {
    251 
    252                 if (Main.pref.hasKey("graphview.parameterBookmarks")) {
    253                         String bookmarksString = Main.pref.get("graphview.parameterBookmarks");
    254                         parameterBookmarks = parseAccessParameterBookmarksString(bookmarksString);
    255                 }
    256 
    257                 if (Main.pref.hasKey("graphview.activeBookmark")) {
    258                         currentParameterBookmarkName = Main.pref.get("graphview.activeBookmark");
    259                 }
    260                 if (!parameterBookmarks.containsKey(currentParameterBookmarkName)) {
    261                         currentParameterBookmarkName = null;
    262                 }
    263 
    264 
    265                 useInternalRulesets = Main.pref.getBoolean("graphview.useInternalRulesets", true);
    266 
    267                 if (Main.pref.hasKey("graphview.rulesetFolder")) {
    268                         String dirString = Main.pref.get("graphview.rulesetFolder");
    269                         rulesetFolder = new File(dirString);
    270                 }
    271                 if (Main.pref.hasKey("graphview.rulesetFile")) {
    272                         String fileString = Main.pref.get("graphview.rulesetFile");
    273                         currentRulesetFile = new File(fileString);
    274                 }
    275 
    276                 if (Main.pref.hasKey("graphview.rulesetResource")) {
    277                         String rulesetString = Main.pref.get("graphview.rulesetResource");
    278                         //get the enum value for the string
    279                         //(InternalRuleset.valueOf cannot be used because it cannot handle invalid strings well)
    280                         for (InternalRuleset ruleset : InternalRuleset.values()) {
    281                                 if (ruleset.toString().equals(rulesetString)) {
    282                                         currentInternalRuleset = ruleset;
    283                                         break;
    284                                 }
    285                         }
    286                 }
    287 
    288                 if (Main.pref.hasKey("graphview.defaultNodeColor")) {
    289                         Color color = parseColorString(Main.pref.get("graphview.defaultNodeColor"));
    290                         if (color != null) {
    291                                 nodeColor = color;
    292                         }
    293                 }
    294                 if (Main.pref.hasKey("graphview.defaultSegmentColor")) {
    295                         Color color = parseColorString(Main.pref.get("graphview.defaultSegmentColor"));
    296                         if (color != null) {
    297                                 segmentColor = color;
    298                         }
    299                 }
    300 
    301                 separateDirections = Main.pref.getBoolean("graphview.separateDirections", false);
    302 
    303         }
    304 
    305         private static final Pattern ACCESS_PARAM_PATTERN = Pattern.compile("^([^;]*);([^;]*);types=\\{([^\\}]*)\\};properties=\\{([^\\}]*)\\}$");
    306 
    307         private static final Pattern PROPERTY_MAP_ENTRY_PATTERN = Pattern.compile("^([^=]*)=(.*)$");
    308 
    309         private static final Map<VehiclePropertyType<?>, String> VEHICLE_PROPERTY_TYPE_NAME_MAP =
    310                 new HashMap<VehiclePropertyType<?>, String>();
    311 
    312 
    313         static {
    314                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(AXLELOAD, "AXLELOAD");
    315                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(HEIGHT, "HEIGHT");
    316                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(LENGTH, "LENGTH");
    317                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_DOWN, "MAX_INCLINE_DOWN");
    318                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_UP, "MAX_INCLINE_UP");
    319                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_TRACKTYPE, "MAX_TRACKTYPE");
    320                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SPEED, "SPEED");
    321                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SURFACE_BLACKLIST, "SURFACE_BLACKLIST");
    322                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WEIGHT, "WEIGHT");
    323                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WIDTH, "WIDTH");
    324         }
    325 
    326         private static String createAccessParameterBookmarksString(
    327                         Map<String, PreferenceAccessParameters> parameterBookmarks) {
    328 
    329                 StringBuilder stringBuilder = new StringBuilder();
    330 
    331                 boolean firstEntry = true;
    332 
    333                 for (String bookmarkName : parameterBookmarks.keySet()) {
    334 
    335                         if (!firstEntry) {
    336                                 stringBuilder.append("|");
    337                         } else {
    338                                 firstEntry = false;
    339                         }
    340 
    341                         stringBuilder.append(createAccessParameterBookmarkString(
    342                                         bookmarkName,
    343                                         parameterBookmarks.get(bookmarkName)));
    344 
    345                 }
    346 
    347                 return stringBuilder.toString();
    348         }
    349 
    350         private static String createAccessParameterBookmarkString(
    351                         String bookmarkName, PreferenceAccessParameters parameters) {
    352 
    353                 StringBuilder stringBuilder = new StringBuilder();
    354 
    355                 stringBuilder.append(bookmarkName).append(";");
    356 
    357                 stringBuilder.append(parameters.getAccessClass());
    358 
    359                 stringBuilder.append(";types={");
    360                 for (AccessType accessType : AccessType.values()) {
    361                         if (parameters.getAccessTypeUsable(accessType)) {
    362                                 stringBuilder.append(accessType).append(",");
    363                         }
    364                 }
    365 
    366                 if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
    367                         stringBuilder.deleteCharAt(stringBuilder.length()-1);
    368                 }
    369                 stringBuilder.append("}");
    370 
    371                 stringBuilder.append(";properties={");
    372 
    373                 for (VehiclePropertyType<?> vehiclePropertyType : VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
    374                         String propertyString = parameters.getVehiclePropertyString(vehiclePropertyType);
    375                         if (propertyString != null) {
    376                                 stringBuilder.append(VEHICLE_PROPERTY_TYPE_NAME_MAP.get(vehiclePropertyType));
    377                                 stringBuilder.append("=");
    378                                 stringBuilder.append(propertyString);
    379                                 stringBuilder.append(",");
    380                         }
    381                 }
    382 
    383                 if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
    384                         stringBuilder.deleteCharAt(stringBuilder.length()-1);
    385                 }
    386                 stringBuilder.append("}");
    387 
    388                 assert ACCESS_PARAM_PATTERN.matcher(stringBuilder.toString()).matches();
    389 
    390                 return stringBuilder.toString();
    391         }
    392 
    393         private static Map<String, PreferenceAccessParameters> parseAccessParameterBookmarksString(
    394                         String string) {
    395 
    396                 Map<String, PreferenceAccessParameters> resultMap =
    397                         new HashMap<String, PreferenceAccessParameters>();
    398 
    399                 String[] bookmarkStrings = string.split("\\|");
    400 
    401                 for (String bookmarkString : bookmarkStrings) {
    402                         parseAccessParameterBookmarkString(bookmarkString, resultMap);
    403                 }
    404 
    405                 return resultMap;
    406         }
    407 
    408         private static void parseAccessParameterBookmarkString(String bookmarkString,
    409                         Map<String, PreferenceAccessParameters> resultMap) {
    410 
    411                 Matcher matcher = ACCESS_PARAM_PATTERN.matcher(bookmarkString);
    412 
    413                 if (matcher.matches()) {
    414 
    415                         String bookmarkName = matcher.group(1);
    416 
    417                         String accessClass = matcher.group(2);
    418 
    419                         String[] accessTypeStrings = matcher.group(3).split(",");
    420                         Collection<AccessType> accessTypes = new LinkedList<AccessType>();
    421                         for (String accessTypeString : accessTypeStrings) {
    422                                 AccessType accessType = AccessType.valueOf(accessTypeString);
    423                                 if (accessType != null) {
    424                                         accessTypes.add(accessType);
    425                                 }
    426                         }
    427 
    428 
    429                         String[] vehiclePropertyStrings = matcher.group(4).split(",");
    430                         Map<VehiclePropertyType<?>, String> vehiclePropertyMap =
    431                                 new HashMap<VehiclePropertyType<?>, String>();
    432 
    433                         for (String vehiclePropertyString : vehiclePropertyStrings) {
    434 
    435                                 Matcher entryMatcher = PROPERTY_MAP_ENTRY_PATTERN.matcher(vehiclePropertyString);
    436                                 if (entryMatcher.matches()) {
    437 
    438                                         String propertyTypeString = entryMatcher.group(1);
    439                                         String propertyValueString = entryMatcher.group(2);
    440 
    441                                         for (VehiclePropertyType<?> propertyType :
    442                                                 VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
    443 
    444                                                 if (propertyTypeString.equals(
    445                                                                 VEHICLE_PROPERTY_TYPE_NAME_MAP.get(propertyType))) {
    446 
    447                                                         vehiclePropertyMap.put(propertyType, propertyValueString);
    448 
    449                                                 }
    450 
    451                                         }
    452 
    453                                 }
    454 
    455                         }
    456 
    457                         try {
    458 
    459                                 PreferenceAccessParameters accessParameters =
    460                                         new PreferenceAccessParameters(accessClass, accessTypes, vehiclePropertyMap);
    461 
    462                                 resultMap.put(bookmarkName, accessParameters);
    463 
    464                         } catch (PropertyValueSyntaxException e) {
    465                                 //don't add bookmark
    466                         }
    467 
    468                 }
    469         }
    470 
    471         private static final Pattern COLOR_PATTERN =
    472                 Pattern.compile("^(\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})$");
    473         private String createColorString(Color color) {
    474                 return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
    475         }
    476 
    477         private Color parseColorString(String string) {
    478                 Matcher matcher = COLOR_PATTERN.matcher(string);
    479                 if (!matcher.matches()) {
    480                         return null;
    481                 } else {
    482                         int r = Integer.parseInt(matcher.group(1));
    483                         int g = Integer.parseInt(matcher.group(2));
    484                         int b = Integer.parseInt(matcher.group(3));
    485                         return new Color(r, g, b);
    486                 }
    487         }
     41    private static GraphViewPreferences instance;
     42
     43    /**
     44    * returns the single instance of GraphViewPreferences.
     45    * @param ignoreSyntaxErrors
     46    * @return
     47    */
     48    public static GraphViewPreferences getInstance() {
     49        if (instance == null) {
     50            instance = new GraphViewPreferences();
     51        }
     52        return instance;
     53    }
     54
     55    private boolean useInternalRulesets;
     56    private File rulesetFolder;
     57    private File currentRulesetFile;
     58    private InternalRuleset currentInternalRuleset;
     59
     60    private String currentParameterBookmarkName;
     61    private Map<String, PreferenceAccessParameters> parameterBookmarks;
     62
     63    private ColorScheme currentColorScheme;
     64    private Color nodeColor;
     65    private Color segmentColor;
     66
     67    private boolean separateDirections;
     68
     69
     70    public synchronized boolean getUseInternalRulesets() {
     71        return useInternalRulesets;
     72    }
     73    public synchronized void setUseInternalRulesets(boolean useInternalRulesets) {
     74        this.useInternalRulesets = useInternalRulesets;
     75    }
     76
     77    public synchronized File getRulesetFolder() {
     78        return rulesetFolder;
     79    }
     80    public synchronized void setRulesetFolder(File rulesetFolder) {
     81        this.rulesetFolder = rulesetFolder;
     82    }
     83
     84    public synchronized File getCurrentRulesetFile() {
     85        return currentRulesetFile;
     86    }
     87    public synchronized void setCurrentRulesetFile(File currentRulesetFile) {
     88        this.currentRulesetFile = currentRulesetFile;
     89    }
     90
     91    public synchronized InternalRuleset getCurrentInternalRuleset() {
     92        return currentInternalRuleset;
     93    }
     94    public synchronized void setCurrentInternalRuleset(InternalRuleset internalRuleset) {
     95        this.currentInternalRuleset = internalRuleset;
     96    }
     97
     98    /**
     99    * returns the name (map key) of the currently selected parameter bookmark
     100    * or null if none is selected.
     101    * If a name is returned, is has to be a key of the map returned by
     102    * {@link #getParameterBookmarks()}.
     103    */
     104    public synchronized String getCurrentParameterBookmarkName() {
     105        assert parameterBookmarks.containsKey(currentParameterBookmarkName);
     106        return currentParameterBookmarkName;
     107    }
     108
     109    /**
     110    * returns the access parameters of the currently selected parameter bookmark
     111    * or null if none is selected.
     112    */
     113    public synchronized AccessParameters getCurrentParameterBookmark() {
     114        if (currentParameterBookmarkName == null) {
     115            return null;
     116        } else {
     117            assert parameterBookmarks.containsKey(currentParameterBookmarkName);
     118            return parameterBookmarks.get(currentParameterBookmarkName);
     119        }
     120    }
     121
     122    /**
     123    * sets the active parameter bookmark using its name as an identifier
     124    * @param currentParameters  name of bookmark to set or null (no active bookmark).
     125    *                           Non-null values must be keys of the map returned by
     126    *                           {@link #getParameterBookmarks()}.
     127    */
     128    public synchronized void setCurrentParameterBookmarkName(String parameterBookmarkName) {
     129        assert parameterBookmarks.containsKey(parameterBookmarkName);
     130        this.currentParameterBookmarkName = parameterBookmarkName;
     131    }
     132
     133    public synchronized Map<String, PreferenceAccessParameters> getParameterBookmarks() {
     134        return Collections.unmodifiableMap(parameterBookmarks);
     135    }
     136    public synchronized void setParameterBookmarks(
     137            Map<String, PreferenceAccessParameters> parameterBookmarks) {
     138        assert parameterBookmarks != null;
     139
     140        this.parameterBookmarks =
     141            new HashMap<String, PreferenceAccessParameters>(parameterBookmarks);
     142    }
     143
     144    public synchronized ColorScheme getCurrentColorScheme() {
     145        return currentColorScheme;
     146    }
     147    public synchronized void setCurrentColorScheme(ColorScheme currentColorScheme) {
     148        this.currentColorScheme = currentColorScheme;
     149    }
     150
     151    public synchronized Color getNodeColor() {
     152        return nodeColor;
     153    }
     154    public synchronized void setNodeColor(Color nodeColor) {
     155        this.nodeColor = nodeColor;
     156    }
     157
     158    public synchronized Color getSegmentColor() {
     159        return segmentColor;
     160    }
     161    public synchronized void setSegmentColor(Color segmentColor) {
     162        this.segmentColor = segmentColor;
     163    }
     164
     165    public synchronized boolean getSeparateDirections() {
     166        return separateDirections;
     167    }
     168    public synchronized void setSeparateDirections(boolean separateDirections) {
     169        this.separateDirections = separateDirections;
     170    }
     171
     172    /**
     173    * writes changes to JOSM's preferences and notifies observers.
     174    * Must be called explicitly after setters (to prevent distributing incomplete changes).
     175    */
     176    public void distributeChanges() {
     177        writePreferences();
     178        setChanged();
     179        notifyObservers();
     180    }
     181
     182    private GraphViewPreferences() {
     183
     184        /* set defaults first (in case preferences are incomplete) */
     185
     186        fillDefaults();
     187
     188        /* read preferences and overwrite defaults */
     189
     190        readPreferences();
     191
     192        /* write preferences
     193        * (this will restore missing/defect preferences,
     194        *  but will simply rewrite valid preferences) */
     195
     196        writePreferences();
     197
     198    }
     199
     200    private void fillDefaults() {
     201
     202        parameterBookmarks = GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks();
     203
     204        if (parameterBookmarks.size() > 0) {
     205            currentParameterBookmarkName = parameterBookmarks.keySet().iterator().next();
     206        } else {
     207            currentParameterBookmarkName = null;
     208        }
     209
     210        useInternalRulesets = true;
     211        rulesetFolder = GraphViewPreferenceDefaults.getDefaultRulesetFolder();
     212        currentRulesetFile = null;
     213        currentInternalRuleset = null;
     214
     215        nodeColor = Color.WHITE;
     216        segmentColor = Color.WHITE;
     217        currentColorScheme = new PreferencesColorScheme(this);
     218
     219        separateDirections = false;
     220
     221    }
     222
     223    private void writePreferences() {
     224
     225        Main.pref.put("graphview.parameterBookmarks",
     226                createAccessParameterBookmarksString(parameterBookmarks));
     227
     228        if (currentParameterBookmarkName != null) {
     229            Main.pref.put("graphview.activeBookmark", currentParameterBookmarkName);
     230        }
     231
     232        Main.pref.put("graphview.useInternalRulesets", useInternalRulesets);
     233
     234        Main.pref.put("graphview.rulesetFolder", rulesetFolder.getPath());
     235
     236        if (currentRulesetFile != null) {
     237            Main.pref.put("graphview.rulesetFile", currentRulesetFile.getPath());
     238        }
     239        if (currentInternalRuleset != null) {
     240            Main.pref.put("graphview.rulesetResource", currentInternalRuleset.toString());
     241        }
     242
     243        Main.pref.put("graphview.defaultNodeColor", createColorString(nodeColor));
     244        Main.pref.put("graphview.defaultSegmentColor", createColorString(segmentColor));
     245
     246        Main.pref.put("graphview.separateDirections", separateDirections);
     247
     248    }
     249
     250    private void readPreferences() {
     251
     252        if (Main.pref.hasKey("graphview.parameterBookmarks")) {
     253            String bookmarksString = Main.pref.get("graphview.parameterBookmarks");
     254            parameterBookmarks = parseAccessParameterBookmarksString(bookmarksString);
     255        }
     256
     257        if (Main.pref.hasKey("graphview.activeBookmark")) {
     258            currentParameterBookmarkName = Main.pref.get("graphview.activeBookmark");
     259        }
     260        if (!parameterBookmarks.containsKey(currentParameterBookmarkName)) {
     261            currentParameterBookmarkName = null;
     262        }
     263
     264
     265        useInternalRulesets = Main.pref.getBoolean("graphview.useInternalRulesets", true);
     266
     267        if (Main.pref.hasKey("graphview.rulesetFolder")) {
     268            String dirString = Main.pref.get("graphview.rulesetFolder");
     269            rulesetFolder = new File(dirString);
     270        }
     271        if (Main.pref.hasKey("graphview.rulesetFile")) {
     272            String fileString = Main.pref.get("graphview.rulesetFile");
     273            currentRulesetFile = new File(fileString);
     274        }
     275
     276        if (Main.pref.hasKey("graphview.rulesetResource")) {
     277            String rulesetString = Main.pref.get("graphview.rulesetResource");
     278            //get the enum value for the string
     279            //(InternalRuleset.valueOf cannot be used because it cannot handle invalid strings well)
     280            for (InternalRuleset ruleset : InternalRuleset.values()) {
     281                if (ruleset.toString().equals(rulesetString)) {
     282                    currentInternalRuleset = ruleset;
     283                    break;
     284                }
     285            }
     286        }
     287
     288        if (Main.pref.hasKey("graphview.defaultNodeColor")) {
     289            Color color = parseColorString(Main.pref.get("graphview.defaultNodeColor"));
     290            if (color != null) {
     291                nodeColor = color;
     292            }
     293        }
     294        if (Main.pref.hasKey("graphview.defaultSegmentColor")) {
     295            Color color = parseColorString(Main.pref.get("graphview.defaultSegmentColor"));
     296            if (color != null) {
     297                segmentColor = color;
     298            }
     299        }
     300
     301        separateDirections = Main.pref.getBoolean("graphview.separateDirections", false);
     302
     303    }
     304
     305    private static final Pattern ACCESS_PARAM_PATTERN = Pattern.compile("^([^;]*);([^;]*);types=\\{([^\\}]*)\\};properties=\\{([^\\}]*)\\}$");
     306
     307    private static final Pattern PROPERTY_MAP_ENTRY_PATTERN = Pattern.compile("^([^=]*)=(.*)$");
     308
     309    private static final Map<VehiclePropertyType<?>, String> VEHICLE_PROPERTY_TYPE_NAME_MAP =
     310        new HashMap<VehiclePropertyType<?>, String>();
     311
     312
     313    static {
     314        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(AXLELOAD, "AXLELOAD");
     315        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(HEIGHT, "HEIGHT");
     316        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(LENGTH, "LENGTH");
     317        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_DOWN, "MAX_INCLINE_DOWN");
     318        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_UP, "MAX_INCLINE_UP");
     319        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_TRACKTYPE, "MAX_TRACKTYPE");
     320        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SPEED, "SPEED");
     321        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SURFACE_BLACKLIST, "SURFACE_BLACKLIST");
     322        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WEIGHT, "WEIGHT");
     323        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WIDTH, "WIDTH");
     324    }
     325
     326    private static String createAccessParameterBookmarksString(
     327            Map<String, PreferenceAccessParameters> parameterBookmarks) {
     328
     329        StringBuilder stringBuilder = new StringBuilder();
     330
     331        boolean firstEntry = true;
     332
     333        for (String bookmarkName : parameterBookmarks.keySet()) {
     334
     335            if (!firstEntry) {
     336                stringBuilder.append("|");
     337            } else {
     338                firstEntry = false;
     339            }
     340
     341            stringBuilder.append(createAccessParameterBookmarkString(
     342                    bookmarkName,
     343                    parameterBookmarks.get(bookmarkName)));
     344
     345        }
     346
     347        return stringBuilder.toString();
     348    }
     349
     350    private static String createAccessParameterBookmarkString(
     351            String bookmarkName, PreferenceAccessParameters parameters) {
     352
     353        StringBuilder stringBuilder = new StringBuilder();
     354
     355        stringBuilder.append(bookmarkName).append(";");
     356
     357        stringBuilder.append(parameters.getAccessClass());
     358
     359        stringBuilder.append(";types={");
     360        for (AccessType accessType : AccessType.values()) {
     361            if (parameters.getAccessTypeUsable(accessType)) {
     362                stringBuilder.append(accessType).append(",");
     363            }
     364        }
     365
     366        if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
     367            stringBuilder.deleteCharAt(stringBuilder.length()-1);
     368        }
     369        stringBuilder.append("}");
     370
     371        stringBuilder.append(";properties={");
     372
     373        for (VehiclePropertyType<?> vehiclePropertyType : VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
     374            String propertyString = parameters.getVehiclePropertyString(vehiclePropertyType);
     375            if (propertyString != null) {
     376                stringBuilder.append(VEHICLE_PROPERTY_TYPE_NAME_MAP.get(vehiclePropertyType));
     377                stringBuilder.append("=");
     378                stringBuilder.append(propertyString);
     379                stringBuilder.append(",");
     380            }
     381        }
     382
     383        if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
     384            stringBuilder.deleteCharAt(stringBuilder.length()-1);
     385        }
     386        stringBuilder.append("}");
     387
     388        assert ACCESS_PARAM_PATTERN.matcher(stringBuilder.toString()).matches();
     389
     390        return stringBuilder.toString();
     391    }
     392
     393    private static Map<String, PreferenceAccessParameters> parseAccessParameterBookmarksString(
     394            String string) {
     395
     396        Map<String, PreferenceAccessParameters> resultMap =
     397            new HashMap<String, PreferenceAccessParameters>();
     398
     399        String[] bookmarkStrings = string.split("\\|");
     400
     401        for (String bookmarkString : bookmarkStrings) {
     402            parseAccessParameterBookmarkString(bookmarkString, resultMap);
     403        }
     404
     405        return resultMap;
     406    }
     407
     408    private static void parseAccessParameterBookmarkString(String bookmarkString,
     409            Map<String, PreferenceAccessParameters> resultMap) {
     410
     411        Matcher matcher = ACCESS_PARAM_PATTERN.matcher(bookmarkString);
     412
     413        if (matcher.matches()) {
     414
     415            String bookmarkName = matcher.group(1);
     416
     417            String accessClass = matcher.group(2);
     418
     419            String[] accessTypeStrings = matcher.group(3).split(",");
     420            Collection<AccessType> accessTypes = new LinkedList<AccessType>();
     421            for (String accessTypeString : accessTypeStrings) {
     422                AccessType accessType = AccessType.valueOf(accessTypeString);
     423                if (accessType != null) {
     424                    accessTypes.add(accessType);
     425                }
     426            }
     427
     428
     429            String[] vehiclePropertyStrings = matcher.group(4).split(",");
     430            Map<VehiclePropertyType<?>, String> vehiclePropertyMap =
     431                new HashMap<VehiclePropertyType<?>, String>();
     432
     433            for (String vehiclePropertyString : vehiclePropertyStrings) {
     434
     435                Matcher entryMatcher = PROPERTY_MAP_ENTRY_PATTERN.matcher(vehiclePropertyString);
     436                if (entryMatcher.matches()) {
     437
     438                    String propertyTypeString = entryMatcher.group(1);
     439                    String propertyValueString = entryMatcher.group(2);
     440
     441                    for (VehiclePropertyType<?> propertyType :
     442                        VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
     443
     444                        if (propertyTypeString.equals(
     445                                VEHICLE_PROPERTY_TYPE_NAME_MAP.get(propertyType))) {
     446
     447                            vehiclePropertyMap.put(propertyType, propertyValueString);
     448
     449                        }
     450
     451                    }
     452
     453                }
     454
     455            }
     456
     457            try {
     458
     459                PreferenceAccessParameters accessParameters =
     460                    new PreferenceAccessParameters(accessClass, accessTypes, vehiclePropertyMap);
     461
     462                resultMap.put(bookmarkName, accessParameters);
     463
     464            } catch (PropertyValueSyntaxException e) {
     465                //don't add bookmark
     466            }
     467
     468        }
     469    }
     470
     471    private static final Pattern COLOR_PATTERN =
     472        Pattern.compile("^(\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})$");
     473    private String createColorString(Color color) {
     474        return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
     475    }
     476
     477    private Color parseColorString(String string) {
     478        Matcher matcher = COLOR_PATTERN.matcher(string);
     479        if (!matcher.matches()) {
     480            return null;
     481        } else {
     482            int r = Integer.parseInt(matcher.group(1));
     483            int g = Integer.parseInt(matcher.group(2));
     484            int b = Integer.parseInt(matcher.group(3));
     485            return new Color(r, g, b);
     486        }
     487    }
    488488
    489489}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/InternalRuleset.java

    r16520 r23189  
    33public enum InternalRuleset {
    44
    5         DEFAULT("files/accessRuleset.xml"),
    6         GERMANY("files/accessRuleset_de.xml");
     5    DEFAULT("files/accessRuleset.xml"),
     6    GERMANY("files/accessRuleset_de.xml");
    77
    8         private String resourceName;
    9         private InternalRuleset(String resourceName) {
    10                 this.resourceName = resourceName;
    11         }
    12         public String getResourceName() {
    13                 return resourceName;
    14         }
     8    private String resourceName;
     9    private InternalRuleset(String resourceName) {
     10        this.resourceName = resourceName;
     11    }
     12    public String getResourceName() {
     13        return resourceName;
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/PreferenceAccessParameters.java

    r16520 r23189  
    1717public class PreferenceAccessParameters implements AccessParameters {
    1818
    19         private final String accessClass;
    20         private final Map<AccessType, Boolean> accessTypeUsableMap;
    21         private final Map<VehiclePropertyType<?>, String> vehiclePropertyStrings;
    22         private final Map<VehiclePropertyType<?>, Object> vehiclePropertyValues;
     19    private final String accessClass;
     20    private final Map<AccessType, Boolean> accessTypeUsableMap;
     21    private final Map<VehiclePropertyType<?>, String> vehiclePropertyStrings;
     22    private final Map<VehiclePropertyType<?>, Object> vehiclePropertyValues;
    2323
    24         public String getAccessClass() {
    25                 return accessClass;
    26         }
     24    public String getAccessClass() {
     25        return accessClass;
     26    }
    2727
    28         public boolean getAccessTypeUsable(AccessType accessType) {
    29                 assert accessType != null;
    30                 return accessTypeUsableMap.get(accessType);
    31         }
     28    public boolean getAccessTypeUsable(AccessType accessType) {
     29        assert accessType != null;
     30        return accessTypeUsableMap.get(accessType);
     31    }
    3232
    33         public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties() {
    34                 return vehiclePropertyValues.keySet();
    35         }
     33    public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties() {
     34        return vehiclePropertyValues.keySet();
     35    }
    3636
    37         /**
    38         * returns the value for a vehicle property.
    39         *
    40         * @param <D>              type of property value
    41         * @param vehicleProperty  property to get value for; != null
    42         * @return                 value for vehicleProperty, null if no value is available.
    43         *                         Guaranteed to be valid according to vehicleProperty's
    44         *                         {@link VehiclePropertyType#isValidValue(Object)} method.
    45         */
    46         public <D> D getVehiclePropertyValue(VehiclePropertyType<D> vehicleProperty) {
    47                 assert vehicleProperty != null;
     37    /**
     38    * returns the value for a vehicle property.
     39    *
     40    * @param <D>              type of property value
     41    * @param vehicleProperty  property to get value for; != null
     42    * @return                 value for vehicleProperty, null if no value is available.
     43    *                         Guaranteed to be valid according to vehicleProperty's
     44    *                         {@link VehiclePropertyType#isValidValue(Object)} method.
     45    */
     46    public <D> D getVehiclePropertyValue(VehiclePropertyType<D> vehicleProperty) {
     47        assert vehicleProperty != null;
    4848
    49                 @SuppressWarnings("unchecked")
    50                 D value = (D)vehiclePropertyValues.get(vehicleProperty);
    51                 return value;
    52         }
     49        @SuppressWarnings("unchecked")
     50        D value = (D)vehiclePropertyValues.get(vehicleProperty);
     51        return value;
     52    }
    5353
    54         /**
    55         * returns the unparsed String for a vehicle property.
    56         *
    57         * @param vehicleProperty  property to get String for; != null
    58         * @return                 unparsed String, null if no value is available.
    59         */
    60         public String getVehiclePropertyString(VehiclePropertyType<?> vehicleProperty) {
    61                 assert vehicleProperty != null;
     54    /**
     55    * returns the unparsed String for a vehicle property.
     56    *
     57    * @param vehicleProperty  property to get String for; != null
     58    * @return                 unparsed String, null if no value is available.
     59    */
     60    public String getVehiclePropertyString(VehiclePropertyType<?> vehicleProperty) {
     61        assert vehicleProperty != null;
    6262
    63                 return vehiclePropertyStrings.get(vehicleProperty);
    64         }
     63        return vehiclePropertyStrings.get(vehicleProperty);
     64    }
    6565
    66         /**
    67         * @param vehiclePropertyStrings  map from vehicle properties to string representations
    68         *                                that will be parsed using {@link VehiclePropertyStringParser}
    69         *                                to get the property values; != null
    70         *
    71         * @throws VehiclePropertyStringParser.PropertyValueSyntaxException
    72         *         if a String from vehiclePropertyStrings contains a syntax error
    73         */
    74         public PreferenceAccessParameters(String accessClass,
    75                         Collection<AccessType> usableAccessTypes,
    76                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings)
    77         throws VehiclePropertyStringParser.PropertyValueSyntaxException {
     66    /**
     67    * @param vehiclePropertyStrings  map from vehicle properties to string representations
     68    *                                that will be parsed using {@link VehiclePropertyStringParser}
     69    *                                to get the property values; != null
     70    *
     71    * @throws VehiclePropertyStringParser.PropertyValueSyntaxException
     72    *         if a String from vehiclePropertyStrings contains a syntax error
     73    */
     74    public PreferenceAccessParameters(String accessClass,
     75            Collection<AccessType> usableAccessTypes,
     76            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings)
     77    throws VehiclePropertyStringParser.PropertyValueSyntaxException {
    7878
    79                 this.accessClass = accessClass;
     79        this.accessClass = accessClass;
    8080
    81                 accessTypeUsableMap = new EnumMap<AccessType, Boolean>(AccessType.class);
    82                 for (AccessType accessType : AccessType.values()) {
    83                         accessTypeUsableMap.put(accessType, usableAccessTypes.contains(accessType));
    84                 }
     81        accessTypeUsableMap = new EnumMap<AccessType, Boolean>(AccessType.class);
     82        for (AccessType accessType : AccessType.values()) {
     83            accessTypeUsableMap.put(accessType, usableAccessTypes.contains(accessType));
     84        }
    8585
    86                 /* check and use vehicle properties */
     86        /* check and use vehicle properties */
    8787
    88                 this.vehiclePropertyStrings = Collections.unmodifiableMap(
    89                                 new HashMap<VehiclePropertyType<?>, String>(vehiclePropertyStrings));
     88        this.vehiclePropertyStrings = Collections.unmodifiableMap(
     89                new HashMap<VehiclePropertyType<?>, String>(vehiclePropertyStrings));
    9090
    91                 this.vehiclePropertyValues = new HashMap<VehiclePropertyType<?>, Object>();
    92                 for (VehiclePropertyType<?> vehiclePropertyType : vehiclePropertyStrings.keySet()) {
    93                         String propertyValueString = vehiclePropertyStrings.get(vehiclePropertyType);
    94                         Object propertyValue = VehiclePropertyStringParser.parsePropertyValue(
    95                                         vehiclePropertyType, propertyValueString);
    96                         this.vehiclePropertyValues.put(vehiclePropertyType, propertyValue);
    97                 }
     91        this.vehiclePropertyValues = new HashMap<VehiclePropertyType<?>, Object>();
     92        for (VehiclePropertyType<?> vehiclePropertyType : vehiclePropertyStrings.keySet()) {
     93            String propertyValueString = vehiclePropertyStrings.get(vehiclePropertyType);
     94            Object propertyValue = VehiclePropertyStringParser.parsePropertyValue(
     95                    vehiclePropertyType, propertyValueString);
     96            this.vehiclePropertyValues.put(vehiclePropertyType, propertyValue);
     97        }
    9898
    99         }
     99    }
    100100
    101101}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/VehiclePropertyStringParser.java

    r20243 r23189  
    1616public final class VehiclePropertyStringParser {
    1717
    18         /** prevents instantiation */
    19         private VehiclePropertyStringParser() { }
     18    /** prevents instantiation */
     19    private VehiclePropertyStringParser() { }
    2020
    21         /**
    22         * Exception class for syntax errors in property value Strings,
    23         * the message contains the reason using one of this utility class' public String constants.
    24         */
    25         public static class PropertyValueSyntaxException extends Exception {
    26                 private static final long serialVersionUID = 1L;
    27                 public PropertyValueSyntaxException(String message) {
    28                         super(message);
    29                 }
    30         }
     21    /**
     22    * Exception class for syntax errors in property value Strings,
     23    * the message contains the reason using one of this utility class' public String constants.
     24    */
     25    public static class PropertyValueSyntaxException extends Exception {
     26        private static final long serialVersionUID = 1L;
     27        public PropertyValueSyntaxException(String message) {
     28            super(message);
     29        }
     30    }
    3131
    32         public static final String ERROR_WEIGHT =
    33                 "Weights must be given as positive decimal numbers with unit \"t\" or without unit.";
    34         public static final String ERROR_LENGTH =
    35                 "Lengths must be given as positive decimal numbers with unit \"m\", \"km\", \"mi\"" +
    36                 " or without unit.\nAlternatively, the format FEET' INCHES\" can be used.";
    37         public static final String ERROR_SPEED =
    38                 "Speeds should be given as numbers without unit or "
    39                 + "as numbers followed by \"mph\".";
    40         public static final String ERROR_INCLINE =
    41                 "Inclines must be given as positive decimal numbers with followed by \"%\".";
    42         public static final String ERROR_TRACKTYPE =
    43                 "Tracktype grades must be given as integers between 0 and 5.";
    44         public static final String ERROR_SURFACE =
    45                 "Surface values must not contain any of the following characters: ',' '{' '}' '=' '|";
     32    public static final String ERROR_WEIGHT =
     33        "Weights must be given as positive decimal numbers with unit \"t\" or without unit.";
     34    public static final String ERROR_LENGTH =
     35        "Lengths must be given as positive decimal numbers with unit \"m\", \"km\", \"mi\"" +
     36        " or without unit.\nAlternatively, the format FEET' INCHES\" can be used.";
     37    public static final String ERROR_SPEED =
     38        "Speeds should be given as numbers without unit or "
     39        + "as numbers followed by \"mph\".";
     40    public static final String ERROR_INCLINE =
     41        "Inclines must be given as positive decimal numbers with followed by \"%\".";
     42    public static final String ERROR_TRACKTYPE =
     43        "Tracktype grades must be given as integers between 0 and 5.";
     44    public static final String ERROR_SURFACE =
     45        "Surface values must not contain any of the following characters: ',' '{' '}' '=' '|";
    4646
    47         private static final List<Character> FORBIDDEN_SURFACE_CHARS =
    48                 Arrays.asList(',', '{', '}', '=', '|');
     47    private static final List<Character> FORBIDDEN_SURFACE_CHARS =
     48        Arrays.asList(',', '{', '}', '=', '|');
    4949
    50         /**
    51         * returns the value represented by the propertyValueString
    52         *
    53         * @throws PropertyValueSyntaxException  if the string has syntax errors that prevent parsing
    54         * @throws InvalidParameterException     if an unknown property type was passed
    55         *
    56         * @param propertyType         type of the property; != null
    57         * @param propertyValueString  string to parse; != null
    58         * @return                     property value; != null.
    59         *                             Guaranteed to be valid according to propertyType's
    60         *                             {@link VehiclePropertyType#isValidValue(Object)} method.
    61         */
    62         public static final <V> V parsePropertyValue(
    63                         VehiclePropertyType<V> propertyType, String propertyValueString)
    64         throws PropertyValueSyntaxException {
     50    /**
     51    * returns the value represented by the propertyValueString
     52    *
     53    * @throws PropertyValueSyntaxException  if the string has syntax errors that prevent parsing
     54    * @throws InvalidParameterException     if an unknown property type was passed
     55    *
     56    * @param propertyType         type of the property; != null
     57    * @param propertyValueString  string to parse; != null
     58    * @return                     property value; != null.
     59    *                             Guaranteed to be valid according to propertyType's
     60    *                             {@link VehiclePropertyType#isValidValue(Object)} method.
     61    */
     62    public static final <V> V parsePropertyValue(
     63            VehiclePropertyType<V> propertyType, String propertyValueString)
     64    throws PropertyValueSyntaxException {
    6565
    66                 assert propertyType != null && propertyValueString != null;
     66        assert propertyType != null && propertyValueString != null;
    6767
    68                 if (propertyType == VehiclePropertyTypes.AXLELOAD
    69                                 || propertyType == VehiclePropertyTypes.WEIGHT) {
     68        if (propertyType == VehiclePropertyTypes.AXLELOAD
     69                || propertyType == VehiclePropertyTypes.WEIGHT) {
    7070
    71                         Float value = ValueStringParser.parseWeight(propertyValueString);
    72                         if (value != null && propertyType.isValidValue(value)) {
    73                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    74                                 V result = (V)value;
    75                                 return result;
    76                         } else {
    77                                 throw new PropertyValueSyntaxException(ERROR_WEIGHT);
    78                         }
     71            Float value = ValueStringParser.parseWeight(propertyValueString);
     72            if (value != null && propertyType.isValidValue(value)) {
     73                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     74                V result = (V)value;
     75                return result;
     76            } else {
     77                throw new PropertyValueSyntaxException(ERROR_WEIGHT);
     78            }
    7979
    80                 } else if (propertyType == VehiclePropertyTypes.HEIGHT
    81                                 || propertyType == VehiclePropertyTypes.LENGTH
    82                                 || propertyType == VehiclePropertyTypes.WIDTH) {
     80        } else if (propertyType == VehiclePropertyTypes.HEIGHT
     81                || propertyType == VehiclePropertyTypes.LENGTH
     82                || propertyType == VehiclePropertyTypes.WIDTH) {
    8383
    84                         Float value = ValueStringParser.parseMeasure(propertyValueString);
    85                         if (value != null && propertyType.isValidValue(value)) {
    86                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    87                                 V result = (V)value;
    88                                 return result;
    89                         } else {
    90                                 throw new PropertyValueSyntaxException(ERROR_LENGTH);
    91                         }
     84            Float value = ValueStringParser.parseMeasure(propertyValueString);
     85            if (value != null && propertyType.isValidValue(value)) {
     86                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     87                V result = (V)value;
     88                return result;
     89            } else {
     90                throw new PropertyValueSyntaxException(ERROR_LENGTH);
     91            }
    9292
    93                 } else if (propertyType == VehiclePropertyTypes.SPEED) {
     93        } else if (propertyType == VehiclePropertyTypes.SPEED) {
    9494
    95                         Float value = ValueStringParser.parseSpeed(propertyValueString);
    96                         if (value != null && propertyType.isValidValue(value)) {
    97                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    98                                 V result = (V)value;
    99                                 return result;
    100                         } else {
    101                                 throw new PropertyValueSyntaxException(ERROR_SPEED);
    102                         }
     95            Float value = ValueStringParser.parseSpeed(propertyValueString);
     96            if (value != null && propertyType.isValidValue(value)) {
     97                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     98                V result = (V)value;
     99                return result;
     100            } else {
     101                throw new PropertyValueSyntaxException(ERROR_SPEED);
     102            }
    103103
    104                 } else if (propertyType == VehiclePropertyTypes.MAX_INCLINE_DOWN
    105                                 || propertyType == VehiclePropertyTypes.MAX_INCLINE_UP) {
     104        } else if (propertyType == VehiclePropertyTypes.MAX_INCLINE_DOWN
     105                || propertyType == VehiclePropertyTypes.MAX_INCLINE_UP) {
    106106
    107                         Float value = ValueStringParser.parseIncline(propertyValueString);
    108                         if (value != null && propertyType.isValidValue(value)) {
    109                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    110                                 V result = (V)value;
    111                                 return result;
    112                         } else {
    113                                 throw new PropertyValueSyntaxException(ERROR_INCLINE);
    114                         }
     107            Float value = ValueStringParser.parseIncline(propertyValueString);
     108            if (value != null && propertyType.isValidValue(value)) {
     109                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     110                V result = (V)value;
     111                return result;
     112            } else {
     113                throw new PropertyValueSyntaxException(ERROR_INCLINE);
     114            }
    115115
    116                 } else if (propertyType == VehiclePropertyTypes.MAX_TRACKTYPE) {
     116        } else if (propertyType == VehiclePropertyTypes.MAX_TRACKTYPE) {
    117117
    118                         try {
    119                                 int value = Integer.parseInt(propertyValueString);
    120                                 if (0 <= value && value <= 5) {
    121                                         @SuppressWarnings("unchecked") //V must be int because of propertyType condition
    122                                         V result = (V)(Integer)value;
    123                                         return result;
    124                                 }
    125                         } catch (NumberFormatException e) {}
     118            try {
     119                int value = Integer.parseInt(propertyValueString);
     120                if (0 <= value && value <= 5) {
     121                    @SuppressWarnings("unchecked") //V must be int because of propertyType condition
     122                    V result = (V)(Integer)value;
     123                    return result;
     124                }
     125            } catch (NumberFormatException e) {}
    126126
    127                         throw new PropertyValueSyntaxException(ERROR_TRACKTYPE);
     127            throw new PropertyValueSyntaxException(ERROR_TRACKTYPE);
    128128
    129                 } else if (propertyType == VehiclePropertyTypes.SURFACE_BLACKLIST) {
     129        } else if (propertyType == VehiclePropertyTypes.SURFACE_BLACKLIST) {
    130130
    131                         String[] surfaces = propertyValueString.split(";\\s*");
    132                         Collection<String> surfaceBlacklist = new ArrayList<String>(surfaces.length);
    133                         for (String surface : surfaces) {
    134                                 for (char nameChar : surface.toCharArray()) {
    135                                         if (FORBIDDEN_SURFACE_CHARS.contains(nameChar)) {
    136                                                 throw new PropertyValueSyntaxException(ERROR_SURFACE);
    137                                         }
    138                                 }
    139                                 surfaceBlacklist.add(surface);
    140                         }
     131            String[] surfaces = propertyValueString.split(";\\s*");
     132            Collection<String> surfaceBlacklist = new ArrayList<String>(surfaces.length);
     133            for (String surface : surfaces) {
     134                for (char nameChar : surface.toCharArray()) {
     135                    if (FORBIDDEN_SURFACE_CHARS.contains(nameChar)) {
     136                        throw new PropertyValueSyntaxException(ERROR_SURFACE);
     137                    }
     138                }
     139                surfaceBlacklist.add(surface);
     140            }
    141141
    142                         @SuppressWarnings("unchecked") //V must be Collection because of propertyType condition
    143                         V result = (V)surfaceBlacklist;
    144                         return result;
     142            @SuppressWarnings("unchecked") //V must be Collection because of propertyType condition
     143            V result = (V)surfaceBlacklist;
     144            return result;
    145145
    146                 } else {
    147                         throw new InvalidParameterException("unknown property type: " + propertyType);
    148                 }
     146        } else {
     147            throw new InvalidParameterException("unknown property type: " + propertyType);
     148        }
    149149
    150         }
     150    }
    151151
    152152}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/FullGraphCreationTest.java

    r19216 r23189  
    3232public class FullGraphCreationTest {
    3333
    34         private static final AccessParameters ACCESS_PARAMS;
    35         static {
    36                 Map<VehiclePropertyType<?>, String> vehiclePropertyValues =
    37                         new HashMap<VehiclePropertyType<?>, String>();
    38                 vehiclePropertyValues.put(VehiclePropertyTypes.WIDTH, "3.0");
     34    private static final AccessParameters ACCESS_PARAMS;
     35    static {
     36        Map<VehiclePropertyType<?>, String> vehiclePropertyValues =
     37            new HashMap<VehiclePropertyType<?>, String>();
     38        vehiclePropertyValues.put(VehiclePropertyTypes.WIDTH, "3.0");
    3939
    40                 try {
    41                         ACCESS_PARAMS = new PreferenceAccessParameters(
    42                                         "test_vehicle",
    43                                         Arrays.asList(AccessType.UNDEFINED),
    44                                         vehiclePropertyValues);
    45                 } catch (PropertyValueSyntaxException e) {
    46                         throw new Error(e);
    47                 }
    48         }
     40        try {
     41            ACCESS_PARAMS = new PreferenceAccessParameters(
     42                    "test_vehicle",
     43                    Arrays.asList(AccessType.UNDEFINED),
     44                    vehiclePropertyValues);
     45        } catch (PropertyValueSyntaxException e) {
     46            throw new Error(e);
     47        }
     48    }
    4949
    50         private static final AccessRuleset TEST_RULESET = new AccessRuleset() {
    51                 public java.util.List<String> getAccessHierarchyAncestors(String transportMode) {
    52                         return Arrays.asList(transportMode);
    53                 }
    54                 public java.util.Collection<Tag> getBaseTags() {
    55                         return Arrays.asList(new Tag("highway", "test"));
    56                 }
    57                 public java.util.List<Implication> getImplications() {
    58                         return new LinkedList<Implication>();
    59                 }
    60         };
     50    private static final AccessRuleset TEST_RULESET = new AccessRuleset() {
     51        public java.util.List<String> getAccessHierarchyAncestors(String transportMode) {
     52            return Arrays.asList(transportMode);
     53        }
     54        public java.util.Collection<Tag> getBaseTags() {
     55            return Arrays.asList(new Tag("highway", "test"));
     56        }
     57        public java.util.List<Implication> getImplications() {
     58            return new LinkedList<Implication>();
     59        }
     60    };
    6161
    62         @Test
    63         public void testTJunction() {
     62    @Test
     63    public void testTJunction() {
    6464
    65                 TestDataSource ds = new TestDataSource();
     65        TestDataSource ds = new TestDataSource();
    6666
    67                 TestNode nodeN = new TestNode(2, 1);
    68                 TestNode nodeW = new TestNode(1, 0);
    69                 TestNode nodeS = new TestNode(0, 1);
    70                 TestNode nodeC = new TestNode(1, 1);
     67        TestNode nodeN = new TestNode(2, 1);
     68        TestNode nodeW = new TestNode(1, 0);
     69        TestNode nodeS = new TestNode(0, 1);
     70        TestNode nodeC = new TestNode(1, 1);
    7171
    72                 ds.nodes.addAll(Arrays.asList(nodeN, nodeW, nodeS, nodeC));
     72        ds.nodes.addAll(Arrays.asList(nodeN, nodeW, nodeS, nodeC));
    7373
    74                 TestWay wayNC = new TestWay();
    75                 wayNC.tags.put("highway", "test");
    76                 wayNC.nodes.addAll(Arrays.asList(nodeN, nodeC));
    77                 TestWay wayCS = new TestWay();
    78                 wayCS.tags.put("highway", "test");
    79                 wayCS.nodes.addAll(Arrays.asList(nodeC, nodeS));
    80                 TestWay wayCW = new TestWay();
    81                 wayCW.tags.put("highway", "test");
    82                 wayCW.nodes.addAll(Arrays.asList(nodeC, nodeW));
     74        TestWay wayNC = new TestWay();
     75        wayNC.tags.put("highway", "test");
     76        wayNC.nodes.addAll(Arrays.asList(nodeN, nodeC));
     77        TestWay wayCS = new TestWay();
     78        wayCS.tags.put("highway", "test");
     79        wayCS.nodes.addAll(Arrays.asList(nodeC, nodeS));
     80        TestWay wayCW = new TestWay();
     81        wayCW.tags.put("highway", "test");
     82        wayCW.nodes.addAll(Arrays.asList(nodeC, nodeW));
    8383
    84                 ds.ways.add(wayNC);
    85                 ds.ways.add(wayCS);
    86                 ds.ways.add(wayCW);
     84        ds.ways.add(wayNC);
     85        ds.ways.add(wayCS);
     86        ds.ways.add(wayCW);
    8787
    88                 /* variant 1: no restrictions */
    89                 {
    90                         TransitionStructure ts1 = createTestTransitionStructure(ds);
     88        /* variant 1: no restrictions */
     89        {
     90            TransitionStructure ts1 = createTestTransitionStructure(ds);
    9191
    92                         assertSame(4, size(ts1.getNodes()));
    93                         assertSame(6, size(ts1.getSegments()));
    94                         assertSame(0, size(ts1.getRestrictions()));
     92            assertSame(4, size(ts1.getNodes()));
     93            assertSame(6, size(ts1.getSegments()));
     94            assertSame(0, size(ts1.getRestrictions()));
    9595
    96                         WayGraph graph1 = new TSBasedWayGraph(ts1);
     96            WayGraph graph1 = new TSBasedWayGraph(ts1);
    9797
    98                         assertSame(12, graph1.getNodes().size());
    99                         assertSame(24, graph1.getEdges().size());
    100                 }
    101                 /* variant 2: no left turn from S to W */
    102                 {
    103                         ds.relations.add(createTurnRestrictionRelation(wayCS, nodeC, wayCW, "no_left_turn"));
    104                         TransitionStructure ts2 = createTestTransitionStructure(ds);
     98            assertSame(12, graph1.getNodes().size());
     99            assertSame(24, graph1.getEdges().size());
     100        }
     101        /* variant 2: no left turn from S to W */
     102        {
     103            ds.relations.add(createTurnRestrictionRelation(wayCS, nodeC, wayCW, "no_left_turn"));
     104            TransitionStructure ts2 = createTestTransitionStructure(ds);
    105105
    106                         assertSame(4, size(ts2.getNodes()));
    107                         assertSame(6, size(ts2.getSegments()));
    108                         assertSame(1, size(ts2.getRestrictions()));
     106            assertSame(4, size(ts2.getNodes()));
     107            assertSame(6, size(ts2.getSegments()));
     108            assertSame(1, size(ts2.getRestrictions()));
    109109
    110                         WayGraph graph2 = new TSBasedWayGraph(ts2);
     110            WayGraph graph2 = new TSBasedWayGraph(ts2);
    111111
    112                         assertSame(12, graph2.getNodes().size());
    113                         assertSame(23, graph2.getEdges().size());
    114                 }
     112            assertSame(12, graph2.getNodes().size());
     113            assertSame(23, graph2.getEdges().size());
     114        }
    115115
    116         }
     116    }
    117117
    118         @Test
    119         public void testBarrier() {
     118    @Test
     119    public void testBarrier() {
    120120
    121                 TestDataSource ds = new TestDataSource();
     121        TestDataSource ds = new TestDataSource();
    122122
    123                 TestNode node1 = new TestNode(0, 1);
    124                 TestNode nodeB = new TestNode(0, 2);
    125                 nodeB.tags.put("width", "1");
    126                 TestNode node2 = new TestNode(0, 3);
     123        TestNode node1 = new TestNode(0, 1);
     124        TestNode nodeB = new TestNode(0, 2);
     125        nodeB.tags.put("width", "1");
     126        TestNode node2 = new TestNode(0, 3);
    127127
    128                 ds.nodes.addAll(Arrays.asList(node1, nodeB, node2));
     128        ds.nodes.addAll(Arrays.asList(node1, nodeB, node2));
    129129
    130                 TestWay way = new TestWay();
    131                 way.tags.put("highway", "test");
    132                 way.tags.put("oneway", "yes");
    133                 way.nodes.addAll(Arrays.asList(node1, nodeB, node2));
    134                 ds.ways.add(way);
     130        TestWay way = new TestWay();
     131        way.tags.put("highway", "test");
     132        way.tags.put("oneway", "yes");
     133        way.nodes.addAll(Arrays.asList(node1, nodeB, node2));
     134        ds.ways.add(way);
    135135
    136                 /* variant 1: no restrictions */
     136        /* variant 1: no restrictions */
    137137
    138                 TransitionStructure ts = createTestTransitionStructure(ds);
     138        TransitionStructure ts = createTestTransitionStructure(ds);
    139139
    140                 assertSame(3, size(ts.getNodes()));
    141                 assertSame(2, size(ts.getSegments()));
    142                 assertSame(1, size(ts.getRestrictions()));
     140        assertSame(3, size(ts.getNodes()));
     141        assertSame(2, size(ts.getSegments()));
     142        assertSame(1, size(ts.getRestrictions()));
    143143
    144                 WayGraph graph = new TSBasedWayGraph(ts);
     144        WayGraph graph = new TSBasedWayGraph(ts);
    145145
    146                 assertSame(4, graph.getNodes().size());
    147                 assertSame(2, graph.getEdges().size());
     146        assertSame(4, graph.getNodes().size());
     147        assertSame(2, graph.getEdges().size());
    148148
    149         }
     149    }
    150150
    151         private TestRelation createTurnRestrictionRelation(
    152                         TestWay from, TestNode via, TestWay to, String restriction) {
    153                 TestRelation resultRelation = new TestRelation();
    154                 resultRelation.tags.put("type", "restriction");
    155                 resultRelation.tags.put("restriction", restriction);
    156                 resultRelation.members.add(new TestRelationMember("from", from));
    157                 resultRelation.members.add(new TestRelationMember("via", via));
    158                 resultRelation.members.add(new TestRelationMember("to", to));
    159                 return resultRelation;
    160         }
     151    private TestRelation createTurnRestrictionRelation(
     152            TestWay from, TestNode via, TestWay to, String restriction) {
     153        TestRelation resultRelation = new TestRelation();
     154        resultRelation.tags.put("type", "restriction");
     155        resultRelation.tags.put("restriction", restriction);
     156        resultRelation.members.add(new TestRelationMember("from", from));
     157        resultRelation.members.add(new TestRelationMember("via", via));
     158        resultRelation.members.add(new TestRelationMember("to", to));
     159        return resultRelation;
     160    }
    161161
    162         private TransitionStructure createTestTransitionStructure(TestDataSource dataSource) {
     162    private TransitionStructure createTestTransitionStructure(TestDataSource dataSource) {
    163163
    164                 LinkedList<RoadPropertyType<?>> properties = new LinkedList<RoadPropertyType<?>>();
    165                 properties.add(new RoadWidth());
     164        LinkedList<RoadPropertyType<?>> properties = new LinkedList<RoadPropertyType<?>>();
     165        properties.add(new RoadWidth());
    166166
    167                 return new GenericTransitionStructure<TestNode, TestWay, TestRelation, TestRelationMember>(
    168                                 ACCESS_PARAMS, TEST_RULESET, dataSource, properties);
    169         }
     167        return new GenericTransitionStructure<TestNode, TestWay, TestRelation, TestRelationMember>(
     168                ACCESS_PARAMS, TEST_RULESET, dataSource, properties);
     169    }
    170170
    171         private static int size(Iterable<?> iterable) {
    172                 Iterator<?> iterator = iterable.iterator();
    173                 int size = 0;
    174                 while (iterator.hasNext()) {
    175                         iterator.next();
    176                         size ++;
    177                 }
    178                 return size;
    179         }
     171    private static int size(Iterable<?> iterable) {
     172        Iterator<?> iterator = iterable.iterator();
     173        int size = 0;
     174        while (iterator.hasNext()) {
     175            iterator.next();
     176            size ++;
     177        }
     178        return size;
     179    }
    180180
    181181}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/TestDataSource.java

    r19216 r23189  
    1414public class TestDataSource implements DataSource<TestDataSource.TestNode, TestDataSource.TestWay, TestDataSource.TestRelation, TestDataSource.TestRelationMember> {
    1515
    16         public static class TestPrimitive {
    17                 public final Map<String, String> tags = new HashMap<String, String>();
    18         };
     16    public static class TestPrimitive {
     17        public final Map<String, String> tags = new HashMap<String, String>();
     18    };
    1919
    20         public static class TestNode extends TestPrimitive {
    21                 public final double lat;
    22                 public final double lon;
    23                 public TestNode() {
    24                         this(0, 0);
    25                 }
    26                 public TestNode(double lat, double lon) {
    27                         this.lat = lat;
    28                         this.lon = lon;
    29                 }
    30                 @Override
    31                 public String toString() {
    32                         return "(" + lat + ", " + lon + "); " + tags;
    33                 }
    34         }
     20    public static class TestNode extends TestPrimitive {
     21        public final double lat;
     22        public final double lon;
     23        public TestNode() {
     24            this(0, 0);
     25        }
     26        public TestNode(double lat, double lon) {
     27            this.lat = lat;
     28            this.lon = lon;
     29        }
     30        @Override
     31        public String toString() {
     32            return "(" + lat + ", " + lon + "); " + tags;
     33        }
     34    }
    3535
    36         public static class TestWay extends TestPrimitive {
    37                 public final List<TestNode> nodes = new LinkedList<TestNode>();
    38                 @Override
    39                 public String toString() {
    40                         return nodes + "; " + tags;
    41                 }
    42         }
     36    public static class TestWay extends TestPrimitive {
     37        public final List<TestNode> nodes = new LinkedList<TestNode>();
     38        @Override
     39        public String toString() {
     40            return nodes + "; " + tags;
     41        }
     42    }
    4343
    44         public static class TestRelation extends TestPrimitive {
    45                 public final Collection<TestRelationMember> members = new LinkedList<TestRelationMember>();
    46                 @Override
    47                 public String toString() {
    48                         return members + "; " + tags;
    49                 }
    50         }
     44    public static class TestRelation extends TestPrimitive {
     45        public final Collection<TestRelationMember> members = new LinkedList<TestRelationMember>();
     46        @Override
     47        public String toString() {
     48            return members + "; " + tags;
     49        }
     50    }
    5151
    52         public static class TestRelationMember {
    53                 public final String role;
    54                 public final TestPrimitive member;
    55                 public TestRelationMember(String role, TestPrimitive member) {
    56                         this.role = role;
    57                         this.member = member;
    58                 }
    59                 public TestPrimitive getMember() {
    60                         return member;
    61                 }
    62                 public String getRole() {
    63                         return role;
    64                 }
    65                 @Override
    66                 public String toString() {
    67                         return role + "=" + member;
    68                 }
    69         }
     52    public static class TestRelationMember {
     53        public final String role;
     54        public final TestPrimitive member;
     55        public TestRelationMember(String role, TestPrimitive member) {
     56            this.role = role;
     57            this.member = member;
     58        }
     59        public TestPrimitive getMember() {
     60            return member;
     61        }
     62        public String getRole() {
     63            return role;
     64        }
     65        @Override
     66        public String toString() {
     67            return role + "=" + member;
     68        }
     69    }
    7070
    7171
    72         public final Collection<TestNode> nodes = new LinkedList<TestNode>();
    73         public final Collection<TestWay> ways = new LinkedList<TestWay>();
    74         public final Collection<TestRelation> relations = new LinkedList<TestRelation>();
     72    public final Collection<TestNode> nodes = new LinkedList<TestNode>();
     73    public final Collection<TestWay> ways = new LinkedList<TestWay>();
     74    public final Collection<TestRelation> relations = new LinkedList<TestRelation>();
    7575
    7676
    77         public double getLat(TestNode node) {
    78                 return node.lat;
    79         }
    80         public double getLon(TestNode node) {
    81                 return node.lon;
    82         }
     77    public double getLat(TestNode node) {
     78        return node.lat;
     79    }
     80    public double getLon(TestNode node) {
     81        return node.lon;
     82    }
    8383
    84         public Iterable<TestRelationMember> getMembers(TestRelation relation) {
    85                 return relation.members;
    86         }
     84    public Iterable<TestRelationMember> getMembers(TestRelation relation) {
     85        return relation.members;
     86    }
    8787
    88         public Iterable<TestNode> getNodes() {
    89                 return nodes;
    90         }
     88    public Iterable<TestNode> getNodes() {
     89        return nodes;
     90    }
    9191
    92         public Iterable<TestNode> getNodes(TestWay way) {
    93                 return way.nodes;
    94         }
     92    public Iterable<TestNode> getNodes(TestWay way) {
     93        return way.nodes;
     94    }
    9595
    96         public Iterable<TestWay> getWays() {
    97                 return ways;
    98         }
     96    public Iterable<TestWay> getWays() {
     97        return ways;
     98    }
    9999
    100         public Iterable<TestRelation> getRelations() {
    101                 return relations;
    102         }
     100    public Iterable<TestRelation> getRelations() {
     101        return relations;
     102    }
    103103
    104         public TagGroup getTagsN(TestNode node) {
    105                 return new MapBasedTagGroup(node.tags);
    106         }
     104    public TagGroup getTagsN(TestNode node) {
     105        return new MapBasedTagGroup(node.tags);
     106    }
    107107
    108         public TagGroup getTagsW(TestWay way) {
    109                 return new MapBasedTagGroup(way.tags);
    110         }
     108    public TagGroup getTagsW(TestWay way) {
     109        return new MapBasedTagGroup(way.tags);
     110    }
    111111
    112         public TagGroup getTagsR(TestRelation relation) {
    113                 return new MapBasedTagGroup(relation.tags);
    114         }
    115        
    116         public Object getMember(TestRelationMember member) {
    117                 return member.getMember();
    118         }
    119        
    120         public String getRole(TestRelationMember member) {
    121                 return member.getRole();
    122         }
    123        
    124         public boolean isNMember(TestRelationMember member) {
    125                 return member.getMember() instanceof TestNode;
    126         }
    127        
    128         public boolean isWMember(TestRelationMember member) {
    129                 return member.getMember() instanceof TestWay;
    130         }
    131        
    132         public boolean isRMember(TestRelationMember member) {
    133                 return member.getMember() instanceof TestRelation;
    134         }
     112    public TagGroup getTagsR(TestRelation relation) {
     113        return new MapBasedTagGroup(relation.tags);
     114    }
    135115
    136         public void addObserver(DataSourceObserver observer) {
    137                 // not needed for test
    138         }
     116    public Object getMember(TestRelationMember member) {
     117        return member.getMember();
     118    }
    139119
    140         public void deleteObserver(DataSourceObserver observer) {
    141                 // not needed for test
    142         }
     120    public String getRole(TestRelationMember member) {
     121        return member.getRole();
     122    }
     123
     124    public boolean isNMember(TestRelationMember member) {
     125        return member.getMember() instanceof TestNode;
     126    }
     127
     128    public boolean isWMember(TestRelationMember member) {
     129        return member.getMember() instanceof TestWay;
     130    }
     131
     132    public boolean isRMember(TestRelationMember member) {
     133        return member.getMember() instanceof TestRelation;
     134    }
     135
     136    public void addObserver(DataSourceObserver observer) {
     137        // not needed for test
     138    }
     139
     140    public void deleteObserver(DataSourceObserver observer) {
     141        // not needed for test
     142    }
    143143
    144144}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/access/AccessRulesetReaderTest.java

    r16520 r23189  
    2222public class AccessRulesetReaderTest {
    2323
    24         @Test
    25         public void testReadAccessRuleset_valid_classes() throws IOException {
     24    @Test
     25    public void testReadAccessRuleset_valid_classes() throws IOException {
    2626
    27                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    28                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    29                 assertNotNull(ruleset);
     27        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     28        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     29        assertNotNull(ruleset);
    3030
    3131
    32                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("vehicle").get(0));
     32        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("vehicle").get(0));
    3333
    34                 assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(0));
    35                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(1));
     34        assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(0));
     35        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(1));
    3636
    37                 assertEquals("bus", ruleset.getAccessHierarchyAncestors("bus").get(0));
    38                 assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("bus").get(1));
    39                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bus").get(2));
     37        assertEquals("bus", ruleset.getAccessHierarchyAncestors("bus").get(0));
     38        assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("bus").get(1));
     39        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bus").get(2));
    4040
    41                 assertEquals("bicycle", ruleset.getAccessHierarchyAncestors("bicycle").get(0));
    42                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bicycle").get(1));
     41        assertEquals("bicycle", ruleset.getAccessHierarchyAncestors("bicycle").get(0));
     42        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bicycle").get(1));
    4343
    44                 assertFalse(ruleset.getAccessHierarchyAncestors("bus").contains("bicycle"));
     44        assertFalse(ruleset.getAccessHierarchyAncestors("bus").contains("bicycle"));
    4545
    46                 assertSame(ruleset.getAccessHierarchyAncestors("boat").size(), 0);
     46        assertSame(ruleset.getAccessHierarchyAncestors("boat").size(), 0);
    4747
    48         }
     48    }
    4949
    50         @Test
    51         public void testReadAccessRuleset_valid_basetags() throws IOException {
     50    @Test
     51    public void testReadAccessRuleset_valid_basetags() throws IOException {
    5252
    53                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    54                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    55                 assertNotNull(ruleset);
     53        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     54        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     55        assertNotNull(ruleset);
    5656
    57                 assertSame(2, ruleset.getBaseTags().size());
     57        assertSame(2, ruleset.getBaseTags().size());
    5858
    59                 assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "residential")));
    60                 assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "cycleway")));
    61                 assertFalse(ruleset.getBaseTags().contains(new Tag("building", "residential")));
    62                 assertFalse(ruleset.getBaseTags().contains(new Tag("highway", "stop")));
     59        assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "residential")));
     60        assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "cycleway")));
     61        assertFalse(ruleset.getBaseTags().contains(new Tag("building", "residential")));
     62        assertFalse(ruleset.getBaseTags().contains(new Tag("highway", "stop")));
    6363
    64         }
     64    }
    6565
    66         @Test
    67         public void testReadAccessRuleset_valid_implications() throws IOException {
     66    @Test
     67    public void testReadAccessRuleset_valid_implications() throws IOException {
    6868
    69                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    70                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    71                 assertNotNull(ruleset);
     69        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     70        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     71        assertNotNull(ruleset);
    7272
    73                 List<Implication> implications = ruleset.getImplications();
     73        List<Implication> implications = ruleset.getImplications();
    7474
    75                 assertSame(3, implications.size());
     75        assertSame(3, implications.size());
    7676
    77                 TagGroup[] tagGroups = new TagGroup[4];
    78                 tagGroups[0] = createTagGroup(new Tag("highway", "cycleway"));
    79                 tagGroups[1] = createTagGroup(new Tag("highway", "steps"));
    80                 tagGroups[2] = createTagGroup(new Tag("highway", "steps"), new Tag("escalator", "yes"));
    81                 tagGroups[3] = createTagGroup(new Tag("disused", "yes"), new Tag("construction", "no"));
     77        TagGroup[] tagGroups = new TagGroup[4];
     78        tagGroups[0] = createTagGroup(new Tag("highway", "cycleway"));
     79        tagGroups[1] = createTagGroup(new Tag("highway", "steps"));
     80        tagGroups[2] = createTagGroup(new Tag("highway", "steps"), new Tag("escalator", "yes"));
     81        tagGroups[3] = createTagGroup(new Tag("disused", "yes"), new Tag("construction", "no"));
    8282
    83                 for (Implication implication : implications) {
    84                         for (int i = 0; i < tagGroups.length; i++) {
    85                                 tagGroups[i] = implication.apply(tagGroups[i]);
    86                         }
    87                 }
     83        for (Implication implication : implications) {
     84            for (int i = 0; i < tagGroups.length; i++) {
     85                tagGroups[i] = implication.apply(tagGroups[i]);
     86            }
     87        }
    8888
    89                 assertSame(2, tagGroups[0].size());
    90                 assertTrue(tagGroups[0].contains(new Tag("bicycle", "designated")));
     89        assertSame(2, tagGroups[0].size());
     90        assertTrue(tagGroups[0].contains(new Tag("bicycle", "designated")));
    9191
    92                 assertSame(2, tagGroups[1].size());
    93                 assertTrue(tagGroups[1].contains(new Tag("normal_steps", "yes")));
     92        assertSame(2, tagGroups[1].size());
     93        assertTrue(tagGroups[1].contains(new Tag("normal_steps", "yes")));
    9494
    95                 assertSame(2, tagGroups[2].size());
    96                 assertFalse(tagGroups[2].contains(new Tag("normal_steps", "yes")));
     95        assertSame(2, tagGroups[2].size());
     96        assertFalse(tagGroups[2].contains(new Tag("normal_steps", "yes")));
    9797
    98                 assertSame(3, tagGroups[3].size());
    99                 assertTrue(tagGroups[3].contains(new Tag("usable", "no")));
    100         }
     98        assertSame(3, tagGroups[3].size());
     99        assertTrue(tagGroups[3].contains(new Tag("usable", "no")));
     100    }
    101101
    102         private static TagGroup createTagGroup(Tag... tags) {
    103                 Map<String, String> tagMap = new HashMap<String, String>();
    104                 for (Tag tag : tags) {
    105                         tagMap.put(tag.key, tag.value);
    106                 }
    107                 return new MapBasedTagGroup(tagMap);
    108         }
     102    private static TagGroup createTagGroup(Tag... tags) {
     103        Map<String, String> tagMap = new HashMap<String, String>();
     104        for (Tag tag : tags) {
     105            tagMap.put(tag.key, tag.value);
     106        }
     107        return new MapBasedTagGroup(tagMap);
     108    }
    109109
    110110}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadInclineTest.java

    r16520 r23189  
    66public class RoadInclineTest extends RoadPropertyTest {
    77
    8         private static void testIncline(Float expectedInclineForward, Float expectedInclineBackward,
    9                         String inclineString) {
     8    private static void testIncline(Float expectedInclineForward, Float expectedInclineBackward,
     9            String inclineString) {
    1010
    11                 testEvaluateW(new RoadIncline(),
    12                                 expectedInclineForward, expectedInclineBackward,
    13                                 new Tag("incline", inclineString));
    14         }
     11        testEvaluateW(new RoadIncline(),
     12                expectedInclineForward, expectedInclineBackward,
     13                new Tag("incline", inclineString));
     14    }
    1515
    16         @Test
    17         public void testEvaluate() {
    18                 testIncline(5f, -5f, "5 %");
    19                 testIncline(9.5f, -9.5f, "9.5 %");
    20                 testIncline(-2.5f, 2.5f, "-2.5%");
    21                 testIncline(null, null, "steep");
    22         }
     16    @Test
     17    public void testEvaluate() {
     18        testIncline(5f, -5f, "5 %");
     19        testIncline(9.5f, -9.5f, "9.5 %");
     20        testIncline(-2.5f, 2.5f, "-2.5%");
     21        testIncline(null, null, "steep");
     22    }
    2323
    2424}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxspeedTest.java

    r21609 r23189  
    66public class RoadMaxspeedTest extends RoadPropertyTest {
    77
    8         private static void testMaxspeed(float expectedMaxspeed, String maxspeedString) {
    9                 testEvaluateBoth(new RoadMaxspeed(),    expectedMaxspeed, new Tag("maxspeed", maxspeedString));
    10         }
     8    private static void testMaxspeed(float expectedMaxspeed, String maxspeedString) {
     9        testEvaluateBoth(new RoadMaxspeed(),    expectedMaxspeed, new Tag("maxspeed", maxspeedString));
     10    }
    1111
    12         @Test
    13         public void testEvaluate_numeric() {
    14                 testMaxspeed(30, "30");
    15                 testMaxspeed(48.3f, "48.3");
    16         }
     12    @Test
     13    public void testEvaluate_numeric() {
     14        testMaxspeed(30, "30");
     15        testMaxspeed(48.3f, "48.3");
     16    }
    1717
    18         @Test
    19         public void testEvaluate_kmh() {
    20                 testMaxspeed(50, "50 km/h");
    21                 testMaxspeed(120, "120km/h");
    22                 testMaxspeed(30, "30    km/h");
    23         }
     18    @Test
     19    public void testEvaluate_kmh() {
     20        testMaxspeed(50, "50 km/h");
     21        testMaxspeed(120, "120km/h");
     22        testMaxspeed(30, "30    km/h");
     23    }
    2424
    25         @Test
    26         public void testEvaluate_mph() {
    27                 testMaxspeed(72.42048f, "45 mph");
    28                 testMaxspeed(64.373764f, "40mph");
    29                 testMaxspeed(24.14016f, "15     mph");
    30         }
     25    @Test
     26    public void testEvaluate_mph() {
     27        testMaxspeed(72.42048f, "45 mph");
     28        testMaxspeed(64.373764f, "40mph");
     29        testMaxspeed(24.14016f, "15 mph");
     30    }
    3131
    3232}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadPropertyTest.java

    r16520 r23189  
    88abstract public class RoadPropertyTest {
    99
    10         protected static <P> void testEvaluateW(RoadPropertyType<P> property, P expectedForward, P expectedBackward, Tag... wayTags) {
     10    protected static <P> void testEvaluateW(RoadPropertyType<P> property, P expectedForward, P expectedBackward, Tag... wayTags) {
    1111
    12                 TestDataSource ds = new TestDataSource();
    13                 TestDataSource.TestWay testWay = new TestDataSource.TestWay();
    14                 for (Tag tag : wayTags) {
    15                         testWay.tags.put(tag.key, tag.value);
    16                 }
    17                 ds.ways.add(testWay);
     12        TestDataSource ds = new TestDataSource();
     13        TestDataSource.TestWay testWay = new TestDataSource.TestWay();
     14        for (Tag tag : wayTags) {
     15            testWay.tags.put(tag.key, tag.value);
     16        }
     17        ds.ways.add(testWay);
    1818
    19                 assertEquals(expectedForward, property.evaluateW(testWay, true, null, ds));
    20                 assertEquals(expectedBackward, property.evaluateW(testWay, false, null, ds));
     19        assertEquals(expectedForward, property.evaluateW(testWay, true, null, ds));
     20        assertEquals(expectedBackward, property.evaluateW(testWay, false, null, ds));
    2121
    22         }
     22    }
    2323
    24         protected static <P> void testEvaluateN(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
     24    protected static <P> void testEvaluateN(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
    2525
    26                 TestDataSource ds = new TestDataSource();
    27                 TestDataSource.TestNode testNode = new TestDataSource.TestNode();
    28                 for (Tag tag : nodeTags) {
    29                         testNode.tags.put(tag.key, tag.value);
    30                 }
    31                 ds.nodes.add(testNode);
     26        TestDataSource ds = new TestDataSource();
     27        TestDataSource.TestNode testNode = new TestDataSource.TestNode();
     28        for (Tag tag : nodeTags) {
     29            testNode.tags.put(tag.key, tag.value);
     30        }
     31        ds.nodes.add(testNode);
    3232
    33                 RoadMaxspeed m = new RoadMaxspeed();
     33        RoadMaxspeed m = new RoadMaxspeed();
    3434
    35                 assertEquals(expected, m.evaluateN(testNode, null, ds));
     35        assertEquals(expected, m.evaluateN(testNode, null, ds));
    3636
    37         }
     37    }
    3838
    39         protected static <P> void testEvaluateBoth(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
    40                 testEvaluateW(property, expected, expected, nodeTags);
    41                 testEvaluateN(property, expected, nodeTags);
    42         }
     39    protected static <P> void testEvaluateBoth(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
     40        testEvaluateW(property, expected, expected, nodeTags);
     41        testEvaluateN(property, expected, nodeTags);
     42    }
    4343
    4444}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/util/TagConditionLogicTest.java

    r16520 r23189  
    1515public class TagConditionLogicTest {
    1616
    17         TagGroup groupA;
    18         TagGroup groupB;
     17    TagGroup groupA;
     18    TagGroup groupB;
    1919
    20         @Before
    21         public void setUp() {
    22                 Map<String, String> mapA = new HashMap<String, String>();
    23                 mapA.put("key1", "value1");
    24                 mapA.put("key2", "value2");
    25                 mapA.put("key3", "value1");
    26                 groupA = new MapBasedTagGroup(mapA);
     20    @Before
     21    public void setUp() {
     22        Map<String, String> mapA = new HashMap<String, String>();
     23        mapA.put("key1", "value1");
     24        mapA.put("key2", "value2");
     25        mapA.put("key3", "value1");
     26        groupA = new MapBasedTagGroup(mapA);
    2727
    28                 Map<String, String> mapB = new HashMap<String, String>();
    29                 mapB.put("key1", "value1");
    30                 mapB.put("key4", "value4");
    31                 groupB = new MapBasedTagGroup(mapB);
    32         }
     28        Map<String, String> mapB = new HashMap<String, String>();
     29        mapB.put("key1", "value1");
     30        mapB.put("key4", "value4");
     31        groupB = new MapBasedTagGroup(mapB);
     32    }
    3333
    34         @Test
    35         public void testTag() {
    36                 TagCondition condition = TagConditionLogic.tag(new Tag("key3", "value1"));
    37                 assertTrue(condition.matches(groupA));
    38                 assertFalse(condition.matches(groupB));
    39         }
     34    @Test
     35    public void testTag() {
     36        TagCondition condition = TagConditionLogic.tag(new Tag("key3", "value1"));
     37        assertTrue(condition.matches(groupA));
     38        assertFalse(condition.matches(groupB));
     39    }
    4040
    41         @Test
    42         public void testKey() {
    43                 TagCondition condition = TagConditionLogic.key("key3");
    44                 assertTrue(condition.matches(groupA));
    45                 assertFalse(condition.matches(groupB));
    46         }
     41    @Test
     42    public void testKey() {
     43        TagCondition condition = TagConditionLogic.key("key3");
     44        assertTrue(condition.matches(groupA));
     45        assertFalse(condition.matches(groupB));
     46    }
    4747
    48         @Test
    49         public void testAnd() {
    50                 TagCondition condition1 = TagConditionLogic.tag(new Tag("key2", "value2"));
    51                 TagCondition conditionAnd1a = TagConditionLogic.and(condition1);
    52                 TagCondition conditionAnd1b = TagConditionLogic.and(Arrays.asList(condition1));
     48    @Test
     49    public void testAnd() {
     50        TagCondition condition1 = TagConditionLogic.tag(new Tag("key2", "value2"));
     51        TagCondition conditionAnd1a = TagConditionLogic.and(condition1);
     52        TagCondition conditionAnd1b = TagConditionLogic.and(Arrays.asList(condition1));
    5353
    54                 assertTrue(conditionAnd1a.matches(groupA));
    55                 assertTrue(conditionAnd1b.matches(groupA));
    56                 assertFalse(conditionAnd1a.matches(groupB));
    57                 assertFalse(conditionAnd1b.matches(groupB));
     54        assertTrue(conditionAnd1a.matches(groupA));
     55        assertTrue(conditionAnd1b.matches(groupA));
     56        assertFalse(conditionAnd1a.matches(groupB));
     57        assertFalse(conditionAnd1b.matches(groupB));
    5858
    59                 TagCondition condition2 = TagConditionLogic.tag(new Tag("key1", "value1"));
    60                 TagCondition conditionAnd2a = TagConditionLogic.and(condition1, condition2);
    61                 TagCondition conditionAnd2b = TagConditionLogic.and(Arrays.asList(condition1, condition2));
     59        TagCondition condition2 = TagConditionLogic.tag(new Tag("key1", "value1"));
     60        TagCondition conditionAnd2a = TagConditionLogic.and(condition1, condition2);
     61        TagCondition conditionAnd2b = TagConditionLogic.and(Arrays.asList(condition1, condition2));
    6262
    63                 assertTrue(conditionAnd2a.matches(groupA));
    64                 assertTrue(conditionAnd2b.matches(groupA));
    65                 assertFalse(conditionAnd2a.matches(groupB));
    66                 assertFalse(conditionAnd2b.matches(groupB));
     63        assertTrue(conditionAnd2a.matches(groupA));
     64        assertTrue(conditionAnd2b.matches(groupA));
     65        assertFalse(conditionAnd2a.matches(groupB));
     66        assertFalse(conditionAnd2b.matches(groupB));
    6767
    68                 TagCondition condition3 = TagConditionLogic.tag(new Tag("key4", "value4"));
    69                 TagCondition conditionAnd3a = TagConditionLogic.and(condition1, condition2, condition3);
    70                 TagCondition conditionAnd3b = TagConditionLogic.and(Arrays.asList(condition1, condition2, condition3));
     68        TagCondition condition3 = TagConditionLogic.tag(new Tag("key4", "value4"));
     69        TagCondition conditionAnd3a = TagConditionLogic.and(condition1, condition2, condition3);
     70        TagCondition conditionAnd3b = TagConditionLogic.and(Arrays.asList(condition1, condition2, condition3));
    7171
    72                 assertFalse(conditionAnd3a.matches(groupA));
    73                 assertFalse(conditionAnd3b.matches(groupA));
    74                 assertFalse(conditionAnd3a.matches(groupB));
    75                 assertFalse(conditionAnd3b.matches(groupB));
    76         }
     72        assertFalse(conditionAnd3a.matches(groupA));
     73        assertFalse(conditionAnd3b.matches(groupA));
     74        assertFalse(conditionAnd3a.matches(groupB));
     75        assertFalse(conditionAnd3b.matches(groupB));
     76    }
    7777
    78         @Test
    79         public void testOr() {
    80                 TagCondition condition1 = TagConditionLogic.tag(new Tag("key42", "value42"));
    81                 TagCondition conditionOr1a = TagConditionLogic.or(condition1);
    82                 TagCondition conditionOr1b = TagConditionLogic.or(Arrays.asList(condition1));
     78    @Test
     79    public void testOr() {
     80        TagCondition condition1 = TagConditionLogic.tag(new Tag("key42", "value42"));
     81        TagCondition conditionOr1a = TagConditionLogic.or(condition1);
     82        TagCondition conditionOr1b = TagConditionLogic.or(Arrays.asList(condition1));
    8383
    84                 assertFalse(conditionOr1a.matches(groupA));
    85                 assertFalse(conditionOr1b.matches(groupA));
    86                 assertFalse(conditionOr1a.matches(groupB));
    87                 assertFalse(conditionOr1b.matches(groupB));
     84        assertFalse(conditionOr1a.matches(groupA));
     85        assertFalse(conditionOr1b.matches(groupA));
     86        assertFalse(conditionOr1a.matches(groupB));
     87        assertFalse(conditionOr1b.matches(groupB));
    8888
    89                 TagCondition condition2 = TagConditionLogic.tag(new Tag("key3", "value1"));
    90                 TagCondition conditionOr2a = TagConditionLogic.or(condition1, condition2);
    91                 TagCondition conditionOr2b = TagConditionLogic.or(Arrays.asList(condition1, condition2));
     89        TagCondition condition2 = TagConditionLogic.tag(new Tag("key3", "value1"));
     90        TagCondition conditionOr2a = TagConditionLogic.or(condition1, condition2);
     91        TagCondition conditionOr2b = TagConditionLogic.or(Arrays.asList(condition1, condition2));
    9292
    93                 assertTrue(conditionOr2a.matches(groupA));
    94                 assertTrue(conditionOr2b.matches(groupA));
    95                 assertFalse(conditionOr2a.matches(groupB));
    96                 assertFalse(conditionOr2b.matches(groupB));
     93        assertTrue(conditionOr2a.matches(groupA));
     94        assertTrue(conditionOr2b.matches(groupA));
     95        assertFalse(conditionOr2a.matches(groupB));
     96        assertFalse(conditionOr2b.matches(groupB));
    9797
    98                 TagCondition condition3 = TagConditionLogic.tag(new Tag("key1", "value1"));
    99                 TagCondition conditionOr3a = TagConditionLogic.or(condition1, condition2, condition3);
    100                 TagCondition conditionOr3b = TagConditionLogic.or(Arrays.asList(condition1, condition2, condition3));
     98        TagCondition condition3 = TagConditionLogic.tag(new Tag("key1", "value1"));
     99        TagCondition conditionOr3a = TagConditionLogic.or(condition1, condition2, condition3);
     100        TagCondition conditionOr3b = TagConditionLogic.or(Arrays.asList(condition1, condition2, condition3));
    101101
    102                 assertTrue(conditionOr3a.matches(groupA));
    103                 assertTrue(conditionOr3b.matches(groupA));
    104                 assertTrue(conditionOr3a.matches(groupB));
    105                 assertTrue(conditionOr3b.matches(groupB));
    106         }
     102        assertTrue(conditionOr3a.matches(groupA));
     103        assertTrue(conditionOr3b.matches(groupA));
     104        assertTrue(conditionOr3a.matches(groupB));
     105        assertTrue(conditionOr3b.matches(groupB));
     106    }
    107107
    108         @Test
    109         public void testNot() {
    110                 TagCondition condition = TagConditionLogic.not(TagConditionLogic.key("key3"));
    111                 assertFalse(condition.matches(groupA));
    112                 assertTrue(condition.matches(groupB));
    113         }
     108    @Test
     109    public void testNot() {
     110        TagCondition condition = TagConditionLogic.not(TagConditionLogic.key("key3"));
     111        assertFalse(condition.matches(groupA));
     112        assertTrue(condition.matches(groupB));
     113    }
    114114
    115115}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/util/ValueStringParserTest.java

    r20244 r23189  
    1010public class ValueStringParserTest {
    1111
    12         /* speed */
     12    /* speed */
    1313
    14         @Test
    15         public void testParseSpeedDefault() {
    16                 assertClose(50, parseSpeed("50"));
    17         }
     14    @Test
     15    public void testParseSpeedDefault() {
     16        assertClose(50, parseSpeed("50"));
     17    }
    1818
    19         @Test
    20         public void testParseSpeedKmh() {
    21                 assertClose(30, parseSpeed("30 km/h"));
    22                 assertClose(100, parseSpeed("100km/h"));
    23         }
     19    @Test
     20    public void testParseSpeedKmh() {
     21        assertClose(30, parseSpeed("30 km/h"));
     22        assertClose(100, parseSpeed("100km/h"));
     23    }
    2424
    25         @Test
    26         public void testParseSpeedMph() {
    27                 assertClose(40.234f, parseSpeed("25mph"));
    28                 assertClose(40.234f, parseSpeed("25 mph"));
    29         }
     25    @Test
     26    public void testParseSpeedMph() {
     27        assertClose(40.234f, parseSpeed("25mph"));
     28        assertClose(40.234f, parseSpeed("25 mph"));
     29    }
    3030
    31         @Test
    32         public void testParseSpeedInvalid() {
    33                 assertNull(parseSpeed("lightspeed"));
    34         }
     31    @Test
     32    public void testParseSpeedInvalid() {
     33        assertNull(parseSpeed("lightspeed"));
     34    }
    3535
    36         /* measure */
     36    /* measure */
    3737
    38         @Test
    39         public void testParseMeasureDefault() {
    40                 assertClose(3.5f, parseMeasure("3.5"));
    41         }
     38    @Test
     39    public void testParseMeasureDefault() {
     40        assertClose(3.5f, parseMeasure("3.5"));
     41    }
    4242
    43         @Test
    44         public void testParseMeasureM() {
    45                 assertClose(2, parseMeasure("2m"));
    46                 assertClose(5.5f, parseMeasure("5.5 m"));
    47         }
     43    @Test
     44    public void testParseMeasureM() {
     45        assertClose(2, parseMeasure("2m"));
     46        assertClose(5.5f, parseMeasure("5.5 m"));
     47    }
    4848
    49         @Test
    50         public void testParseMeasureKm() {
    51                 assertClose(1000, parseMeasure("1 km"));
    52                 assertClose(7200, parseMeasure("7.2km"));
    53         }
     49    @Test
     50    public void testParseMeasureKm() {
     51        assertClose(1000, parseMeasure("1 km"));
     52        assertClose(7200, parseMeasure("7.2km"));
     53    }
    5454
    55         @Test
    56         public void testParseMeasureMi() {
    57                 assertClose(1609.344f, parseMeasure("1 mi"));
    58         }
     55    @Test
     56    public void testParseMeasureMi() {
     57        assertClose(1609.344f, parseMeasure("1 mi"));
     58    }
    5959
    60         @Test
    61         public void testParseMeasureFeetInches() {
    62                 assertClose(3.6576f, parseMeasure("12'0\""));
    63                 assertClose(1.9812f, parseMeasure("6' 6\""));
    64         }
     60    @Test
     61    public void testParseMeasureFeetInches() {
     62        assertClose(3.6576f, parseMeasure("12'0\""));
     63        assertClose(1.9812f, parseMeasure("6' 6\""));
     64    }
    6565
    66         @Test
    67         public void testParseMeasureInvalid() {
    68                 assertNull(parseMeasure("very long"));
    69                 assertNull(parseMeasure("6' 16\""));
    70         }
     66    @Test
     67    public void testParseMeasureInvalid() {
     68        assertNull(parseMeasure("very long"));
     69        assertNull(parseMeasure("6' 16\""));
     70    }
    7171
    72         /* weight */
     72    /* weight */
    7373
    74         @Test
    75         public void testParseWeightDefault() {
    76                 assertClose(3.6f, parseWeight("3.6"));
    77         }
     74    @Test
     75    public void testParseWeightDefault() {
     76        assertClose(3.6f, parseWeight("3.6"));
     77    }
    7878
    79         @Test
    80         public void testParseWeightT() {
    81                 assertClose(30, parseWeight("30t"));
    82                 assertClose(3.5f, parseWeight("3.5 t"));
    83         }
     79    @Test
     80    public void testParseWeightT() {
     81        assertClose(30, parseWeight("30t"));
     82        assertClose(3.5f, parseWeight("3.5 t"));
     83    }
    8484
    85         @Test
    86         public void testParseWeightInvalid() {
    87                 assertNull(parseWeight("heavy"));
    88         }
     85    @Test
     86    public void testParseWeightInvalid() {
     87        assertNull(parseWeight("heavy"));
     88    }
    8989
    90         private static final void assertClose(float expected, float actual) {
    91                 if (Math.abs(expected - actual) > 0.001) {
    92                         throw new AssertionError("expected " + expected + ", was " + actual);
    93                 }
    94         }
     90    private static final void assertClose(float expected, float actual) {
     91        if (Math.abs(expected - actual) > 0.001) {
     92            throw new AssertionError("expected " + expected + ", was " + actual);
     93        }
     94    }
    9595
    9696}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/visualisation/FloatPropertyColorSchemeTest.java

    r16520 r23189  
    1313public class FloatPropertyColorSchemeTest {
    1414
    15         private FloatPropertyColorScheme subject;
     15    private FloatPropertyColorScheme subject;
    1616
    17         @Before
    18         public void setUp() {
     17    @Before
     18    public void setUp() {
    1919
    20                 Map<Float, Color> colorMap = new HashMap<Float, Color>();
    21                 colorMap.put( 5f, new Color( 42,  42,  42));
    22                 colorMap.put(10f, new Color(100, 100, 100));
    23                 colorMap.put(20f, new Color(200, 200, 200));
     20        Map<Float, Color> colorMap = new HashMap<Float, Color>();
     21        colorMap.put( 5f, new Color( 42,  42,  42));
     22        colorMap.put(10f, new Color(100, 100, 100));
     23        colorMap.put(20f, new Color(200, 200, 200));
    2424
    25                 subject = new FloatPropertyColorScheme(RoadMaxweight.class, colorMap, Color.RED);
    26         }
     25        subject = new FloatPropertyColorScheme(RoadMaxweight.class, colorMap, Color.RED);
     26    }
    2727
    28         @Test
    29         public void testGetColorForValue_below() {
    30                 assertEquals(new Color(42, 42, 42), subject.getColorForValue(1f));
    31                 assertEquals(new Color(42, 42, 42), subject.getColorForValue(5f));
    32         }
     28    @Test
     29    public void testGetColorForValue_below() {
     30        assertEquals(new Color(42, 42, 42), subject.getColorForValue(1f));
     31        assertEquals(new Color(42, 42, 42), subject.getColorForValue(5f));
     32    }
    3333
    34         @Test
    35         public void testGetColorForValue_above() {
    36                 assertEquals(new Color(200, 200, 200), subject.getColorForValue(25f));
    37         }
     34    @Test
     35    public void testGetColorForValue_above() {
     36        assertEquals(new Color(200, 200, 200), subject.getColorForValue(25f));
     37    }
    3838
    39         @Test
    40         public void testGetColorForValue_value() {
    41                 assertEquals(new Color(100, 100, 100), subject.getColorForValue(10f));
    42         }
     39    @Test
     40    public void testGetColorForValue_value() {
     41        assertEquals(new Color(100, 100, 100), subject.getColorForValue(10f));
     42    }
    4343
    44         @Test
    45         public void testGetColorForValue_interpolate() {
    46                 assertEquals(new Color(150, 150, 150), subject.getColorForValue(15f));
    47         }
     44    @Test
     45    public void testGetColorForValue_interpolate() {
     46        assertEquals(new Color(150, 150, 150), subject.getColorForValue(15f));
     47    }
    4848
    4949}
Note: See TracChangeset for help on using the changeset viewer.