Ignore:
Timestamp:
2013-09-27T00:01:14+02:00 (11 years ago)
Author:
oliverw
Message:

[josm_fixadresses]: Fixes #josm8336

Location:
applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressEditContainer.java

    r29869 r29967  
    6464        private HashMap<String, OSMStreet> streetDict = new HashMap<String, OSMStreet>(100);
    6565
    66         /** The unresolved addresses list. */
     66        /** The unresolved (addresses without valid street name) addresses list. */
    6767        private List<OSMAddress> unresolvedAddresses = new ArrayList<OSMAddress>(100);
    6868
     
    476476                String streetName = aNode.getStreetName();
    477477
     478                // street name via relation -> implicitly resolved (see TRAC #8336)
     479                if (aNode.isPartOfRelation()) {
     480                    return true;
     481                }
     482               
    478483                if (streetName != null && shadowStreetDict.containsKey(streetName)) {
    479484                        OSMStreet sNode = shadowStreetDict.get(streetName);
     
    529534                        clearData();
    530535                        clearProblems();
    531                         /*
     536                        // visit data set for problems...
    532537                        for (OsmPrimitive osmPrimitive : osmData) {
    533538                                if (osmPrimitive.isUsable()) {
     
    535540                                }
    536541                        }
    537                          */
     542                       
     543                        // match streets with addresses...
    538544                        resolveAddresses();
    539                         // sort lists
     545                        // sort problem lists
    540546                        Collections.sort(shadowIncompleteAddresses);
    541547                        Collections.sort(shadowUnresolvedAddresses);
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/OSMAddress.java

    r29869 r29967  
    2424
    2525/**
    26  * The class OSMAddress represents a single address node of OSM. It is a lightweight
    27  * wrapper for a OSM node in order to simplify tag handling.
     26 * The class OSMAddress represents a single address node of OSM. It is a
     27 * lightweight wrapper for a OSM node in order to simplify tag handling.
    2828 */
    2929public class OSMAddress extends OSMEntityBase {
    30         public static final String MISSING_TAG = "?";
    31         public static final String INTERPOLATION_TAG = "x..y";
    32 
    33 
    34         /** True, if address is part of an address interpolation. */
    35         private boolean isPartOfInterpolation;
    36         /**
    37          * True, if address has derived values from an associated street relation.
    38          */
    39         private boolean isPartOfAssocStreetRel;
    40 
    41         /** The dictionary containing guessed values. */
    42         private HashMap<String, String> guessedValues = new HashMap<String, String>();
    43         /** The dictionary containing guessed objects. */
    44         private HashMap<String, OsmPrimitive> guessedObjects = new HashMap<String, OsmPrimitive>();
    45         /** The dictionary containing indirect values. */
    46         private HashMap<String, String> derivedValues = new HashMap<String, String>();
    47 
    48         public OSMAddress(OsmPrimitive osmObject) {
    49                 super(osmObject);
    50         }
    51 
    52         /* (non-Javadoc)
    53          * @see org.openstreetmap.josm.plugins.addressEdit.NodeEntityBase#setOsmObject(org.openstreetmap.josm.data.osm.OsmPrimitive)
    54          */
    55         @Override
    56         public void setOsmObject(OsmPrimitive osmObject) {
    57                 super.setOsmObject(osmObject);
    58 
    59                 isPartOfInterpolation = OsmUtils.getValuesFromAddressInterpolation(this);
    60                 isPartOfAssocStreetRel = OsmUtils.getValuesFromRelation(this);
    61         }
    62 
    63         /**
    64          * Checks if the underlying address node has all tags usually needed to describe an address.
    65          * @return
    66          */
    67         public boolean isComplete() {
    68                 boolean isComplete =    hasCity() &&
    69                                                                 hasHouseNumber() &&                                                             
    70                                                                 hasCity() &&
    71                                                                 hasStreetName();
    72 
    73                 // Check, if "addr:state" is required (US and AU)
    74                 if (TagUtils.isStateRequired()) {
    75                         isComplete = isComplete && hasState();
     30    public static final String MISSING_TAG = "?";
     31    public static final String INTERPOLATION_TAG = "x..y";
     32
     33    /** True, if address is part of an address interpolation. */
     34    private boolean isPartOfInterpolation;
     35    /**
     36     * True, if address has derived values from an associated street relation.
     37     */
     38    private boolean isPartOfAssocStreetRel;
     39
     40    /** The dictionary containing guessed values. */
     41    private HashMap<String, String> guessedValues = new HashMap<String, String>();
     42    /** The dictionary containing guessed objects. */
     43    private HashMap<String, OsmPrimitive> guessedObjects = new HashMap<String, OsmPrimitive>();
     44    /** The dictionary containing indirect values. */
     45    private HashMap<String, String> derivedValues = new HashMap<String, String>();
     46
     47    public OSMAddress(OsmPrimitive osmObject) {
     48        super(osmObject);
     49    }
     50
     51    /*
     52     * (non-Javadoc)
     53     *
     54     * @see
     55     * org.openstreetmap.josm.plugins.addressEdit.NodeEntityBase#setOsmObject
     56     * (org.openstreetmap.josm.data.osm.OsmPrimitive)
     57     */
     58    @Override
     59    public void setOsmObject(OsmPrimitive osmObject) {
     60        super.setOsmObject(osmObject);
     61
     62        isPartOfInterpolation = OsmUtils
     63                .getValuesFromAddressInterpolation(this);
     64        isPartOfAssocStreetRel = OsmUtils.getValuesFromRelation(this);
     65    }
     66
     67    /**
     68     * Checks if the underlying address node has all tags usually needed to
     69     * describe an address.
     70     *
     71     * @return
     72     */
     73    public boolean isComplete() {
     74        boolean isComplete = hasCity() && hasHouseNumber() && hasCity()
     75                && hasStreetName();
     76
     77        // Check, if "addr:state" is required (US and AU)
     78        if (TagUtils.isStateRequired()) {
     79            isComplete = isComplete && hasState();
     80        }
     81
     82        // Check, if user checked "ignore post code"
     83        if (!FixAddressesPlugin.getPreferences().isIgnorePostCode()) {
     84            isComplete = isComplete && hasPostalCode()
     85                    && PostalCodeChecker.hasValidPostalCode(this);
     86        }
     87
     88        return isComplete;
     89    }
     90
     91    /**
     92     * Gets the name of the street associated with this address.
     93     *
     94     * @return
     95     */
     96    public String getStreetName() {
     97        return getTagValueWithGuess(TagUtils.ADDR_STREET_TAG);
     98    }
     99
     100    /**
     101     * Gets the tag value with guess. If the object does not have the given tag,
     102     * this method looks for an appropriate guess. If both, real value and
     103     * guess, are missing, a question mark is returned.
     104     *
     105     * @param tag
     106     *            the tag
     107     * @return the tag value with guess
     108     */
     109    private String getTagValueWithGuess(String tag) {
     110        if (StringUtils.isNullOrEmpty(tag))
     111            return MISSING_TAG;
     112        if (osmObject == null)
     113            return MISSING_TAG;
     114
     115        if (!osmObject.hasKey(tag)
     116                || StringUtils.isNullOrEmpty(osmObject.get(tag))) {
     117            if (!hasDerivedValue(tag)) {
     118                // object does not have this tag -> check for guess
     119                if (hasGuessedValue(tag)) {
     120                    return "*" + getGuessedValue(tag);
     121                } else {
     122                    // give up
     123                    return MISSING_TAG;
    76124                }
    77                
    78                 // Check, if user checked "ignore post code"
    79                 if (!FixAddressesPlugin.getPreferences().isIgnorePostCode()) {
    80                         isComplete = isComplete  &&
    81                                         hasPostalCode() &&
    82                                         PostalCodeChecker.hasValidPostalCode(this);
     125            } else { // ok, use derived value known via associated relation or
     126                     // way
     127                return getDerivedValue(tag);
     128            }
     129        } else { // get existing tag value
     130            return osmObject.get(tag);
     131        }
     132    }
     133
     134    /**
     135     * Returns <tt>true</tt>, if this address node has a street name.
     136     *
     137     * @return
     138     */
     139    public boolean hasStreetName() {
     140        return hasTag(TagUtils.ADDR_STREET_TAG) || isPartOfRelation();
     141    }
     142
     143    /**
     144     * Returns the street name guessed by the nearest-neighbor search.
     145     *
     146     * @return the guessedStreetName
     147     */
     148    public String getGuessedStreetName() {
     149        return getGuessedValue(TagUtils.ADDR_STREET_TAG);
     150    }
     151
     152    /**
     153     * Sets the guessed street name.
     154     *
     155     * @param guessedStreetName
     156     *            the guessedStreetName to set
     157     * @param srcObj
     158     *            the source object of the guess.
     159     */
     160    public void setGuessedStreetName(String guessedStreetName,
     161            OsmPrimitive srcObj) {
     162        setGuessedValue(TagUtils.ADDR_STREET_TAG, guessedStreetName, srcObj);
     163    }
     164
     165    /**
     166     * Checks for a guessed street name.
     167     *
     168     * @return true, if this instance has a guessed street name.
     169     */
     170    public boolean hasGuessedStreetName() {
     171        return hasGuessedValue(TagUtils.ADDR_STREET_TAG);
     172    }
     173
     174    /**
     175     * @return the guessedPostCode
     176     */
     177    public String getGuessedPostalCode() {
     178        return getGuessedValue(TagUtils.ADDR_POSTCODE_TAG);
     179    }
     180
     181    /**
     182     * Sets the guessed post code.
     183     *
     184     * @param guessedPostCode
     185     *            the guessedPostCode to set
     186     * @param srcObj
     187     *            srcObj the source object of the guess
     188     */
     189    public void setGuessedPostalCode(String guessedPostCode, OsmPrimitive srcObj) {
     190        setGuessedValue(TagUtils.ADDR_POSTCODE_TAG, guessedPostCode, srcObj);
     191    }
     192
     193    /**
     194     * Checks for a guessed post code.
     195     *
     196     * @return true, if this instance has a guessed post code.
     197     */
     198    public boolean hasGuessedPostalCode() {
     199        return hasGuessedValue(TagUtils.ADDR_POSTCODE_TAG);
     200    }
     201
     202    /**
     203     * @return the guessedCity
     204     */
     205    public String getGuessedCity() {
     206        return getGuessedValue(TagUtils.ADDR_CITY_TAG);
     207    }
     208
     209    /**
     210     * Sets the guessed city.
     211     *
     212     * @param guessedCity
     213     *            the guessedCity to set
     214     * @param srcObj
     215     *            the source object of the guess
     216     */
     217    public void setGuessedCity(String guessedCity, OsmPrimitive srcObj) {
     218        setGuessedValue(TagUtils.ADDR_CITY_TAG, guessedCity, srcObj);
     219    }
     220
     221    /**
     222     * Checks for a guessed city name.
     223     *
     224     * @return true, if this instance has a guessed city name.
     225     */
     226    public boolean hasGuessedCity() {
     227        return hasGuessedValue(TagUtils.ADDR_CITY_TAG);
     228    }
     229
     230    /**
     231     * Returns true, if this instance has guesses regarding address tags.
     232     *
     233     * @return
     234     */
     235    public boolean hasGuesses() {
     236        return guessedValues.size() > 0;
     237    }
     238
     239    /**
     240     * Applies all guessed tags for this node.
     241     */
     242    public void applyAllGuesses() {
     243        for (String tag : guessedValues.keySet()) {
     244            applyGuessForTag(tag);
     245        }
     246
     247        // Clear all guesses
     248        guessedValues.clear();
     249        guessedObjects.clear();
     250    }
     251
     252    /**
     253     * Apply the guessed value for the given tag.
     254     *
     255     * @param tag
     256     *            the tag to apply the guessed value for.
     257     */
     258    public void applyGuessForTag(String tag) {
     259        if (guessedValues.containsKey(tag)) {
     260            String val = guessedValues.get(tag);
     261            if (!StringUtils.isNullOrEmpty(val)) {
     262                setOSMTag(tag, val);
     263            }
     264        }
     265    }
     266
     267    /**
     268     * Gets the name of the post code associated with this address.
     269     *
     270     * @return
     271     */
     272    public String getPostalCode() {
     273        String pc = getTagValueWithGuess(TagUtils.ADDR_POSTCODE_TAG);
     274
     275        if (!MISSING_TAG.equals(pc)
     276                && !PostalCodeChecker.hasValidPostalCode(getCountry(), pc)) {
     277            pc = "(!)" + pc;
     278        }
     279        return pc;
     280    }
     281
     282    /**
     283     * Checks if this instance has a valid postal code.
     284     *
     285     * @return true, if successful
     286     */
     287    public boolean hasValidPostalCode() {
     288        return PostalCodeChecker.hasValidPostalCode(this);
     289    }
     290
     291    /**
     292     * Checks for post code tag.
     293     *
     294     * @return true, if successful
     295     */
     296    public boolean hasPostalCode() {
     297        return hasTag(TagUtils.ADDR_POSTCODE_TAG);
     298    }
     299
     300    /**
     301     * Gets the name of the house number associated with this address.
     302     *
     303     * @return
     304     */
     305    public String getHouseNumber() {
     306        if (!TagUtils.hasAddrHousenumberTag(osmObject)) {
     307            if (!isPartOfInterpolation) {
     308                return MISSING_TAG;
     309            } else {
     310                return INTERPOLATION_TAG;
     311            }
     312        }
     313        return TagUtils.getAddrHousenumberValue(osmObject);
     314    }
     315
     316    /**
     317     * Checks for house number.
     318     *
     319     * @return true, if successful
     320     */
     321    public boolean hasHouseNumber() {
     322        return TagUtils.hasAddrHousenumberTag(osmObject)
     323                || isPartOfInterpolation;
     324    }
     325
     326    /*
     327     * (non-Javadoc)
     328     *
     329     * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#getName()
     330     */
     331    public String getName() {
     332        String name = TagUtils.getNameValue(osmObject);
     333        if (!StringUtils.isNullOrEmpty(name)) {
     334            return TagUtils.getAddrHousenameValue(osmObject);
     335        }
     336
     337        return "";
     338    }
     339
     340    /**
     341     * Checks if this address is part of a address interpolation.
     342     *
     343     * @return true, if is part of interpolation
     344     */
     345    protected boolean isPartOfInterpolation() {
     346        return isPartOfInterpolation;
     347    }
     348
     349    /**
     350     * Checks if this address is part of an 'associated street' relation.
     351     *
     352     * @return true, if is part of interpolation
     353     */
     354    protected boolean isPartOfRelation() {
     355        return isPartOfAssocStreetRel;
     356    }
     357
     358    /**
     359     * Gets the name of the city associated with this address.
     360     *
     361     * @return
     362     */
     363    public String getCity() {
     364        return getTagValueWithGuess(TagUtils.ADDR_CITY_TAG);
     365    }
     366
     367    /**
     368     * Checks for city tag.
     369     *
     370     * @return true, if a city tag is present or available via referrer.
     371     */
     372    public boolean hasCity() {
     373        return hasTag(TagUtils.ADDR_CITY_TAG);
     374    }
     375
     376    /**
     377     * Gets the name of the state associated with this address.
     378     *
     379     * @return
     380     */
     381    public String getState() {
     382        return getTagValueWithGuess(TagUtils.ADDR_STATE_TAG);
     383    }
     384
     385    /**
     386     * Checks for state tag.
     387     *
     388     * @return true, if a state tag is present or available via referrer.
     389     */
     390    public boolean hasState() {
     391        return hasTag(TagUtils.ADDR_STATE_TAG);
     392    }
     393
     394    /**
     395     * Gets the name of the country associated with this address.
     396     *
     397     * @return
     398     */
     399    public String getCountry() {
     400        return getTagValueWithGuess(TagUtils.ADDR_COUNTRY_TAG);
     401    }
     402
     403    /**
     404     * Checks for country tag.
     405     *
     406     * @return true, if a country tag is present or available via referrer.
     407     */
     408    public boolean hasCountry() {
     409        return hasTag(TagUtils.ADDR_COUNTRY_TAG);
     410    }
     411
     412    /**
     413     * Removes all address-related tags from the node or way.
     414     */
     415    public void removeAllAddressTags() {
     416        removeOSMTag(TagUtils.ADDR_CITY_TAG);
     417        removeOSMTag(TagUtils.ADDR_COUNTRY_TAG);
     418        removeOSMTag(TagUtils.ADDR_POSTCODE_TAG);
     419        removeOSMTag(TagUtils.ADDR_HOUSENUMBER_TAG);
     420        removeOSMTag(TagUtils.ADDR_STATE_TAG);
     421        removeOSMTag(TagUtils.ADDR_STREET_TAG);
     422    }
     423
     424    /**
     425     * Checks if the associated OSM object has the given tag or if the tag is
     426     * available via a referrer.
     427     *
     428     * @param tag
     429     *            the tag to look for.
     430     * @return true, if there is a value for the given tag.
     431     */
     432    public boolean hasTag(String tag) {
     433        if (StringUtils.isNullOrEmpty(tag))
     434            return false;
     435
     436        return TagUtils.hasTag(osmObject, tag) || hasDerivedValue(tag);
     437    }
     438
     439    /*
     440     * (non-Javadoc)
     441     *
     442     * @see
     443     * org.openstreetmap.josm.plugins.addressEdit.NodeEntityBase#compareTo(org
     444     * .openstreetmap.josm.plugins.addressEdit.INodeEntity)
     445     */
     446    @Override
     447    public int compareTo(IOSMEntity o) {
     448        if (o == null || !(o instanceof OSMAddress)) {
     449            return -1;
     450        }
     451        OSMAddress other = (OSMAddress) o;
     452
     453        if (this.equals(other))
     454            return 0;
     455
     456        int cc = 0;
     457        cc = this.getCountry().compareTo(other.getCountry());
     458        if (cc == 0) {
     459            cc = this.getState().compareTo(other.getState());
     460            if (cc == 0) {
     461                cc = this.getCity().compareTo(other.getCity());
     462                if (cc == 0) {
     463                    cc = this.getStreetName().compareTo(other.getStreetName());
     464                    if (cc == 0) {
     465                        if (hasGuessedStreetName()) {
     466                            if (other.hasStreetName()) {
     467                                // Compare guessed name with the real name
     468                                String gsm = this.getGuessedStreetName();
     469                                cc = this.getGuessedStreetName().compareTo(
     470                                        other.getStreetName());
     471                                if (cc == 0) {
     472                                    cc = this.getHouseNumber().compareTo(
     473                                            other.getHouseNumber());
     474                                }
     475                            } else if (other.hasGuessedStreetName()) {
     476                                // Compare guessed name with the guessed name
     477                                cc = this.getGuessedStreetName().compareTo(
     478                                        other.getGuessedStreetName());
     479                                if (cc == 0) {
     480                                    cc = this.getHouseNumber().compareTo(
     481                                            other.getHouseNumber());
     482                                }
     483                            } // else: give up
     484                              // No guessed name at all -> just compare the
     485                              // number
     486                        } else {
     487                            cc = this.getHouseNumber().compareTo(
     488                                    other.getHouseNumber());
     489                        }
     490                    }
    83491                }
    84 
    85                 return isComplete;
    86         }
    87 
    88         /**
    89          * Gets the name of the street associated with this address.
    90          * @return
    91          */
    92         public String getStreetName() {
    93                 return getTagValueWithGuess(TagUtils.ADDR_STREET_TAG);
    94         }
    95 
    96         /**
    97          * Gets the tag value with guess. If the object does not have the given tag, this method looks for
    98          * an appropriate guess. If both, real value and guess, are missing, a question mark is returned.
    99          *
    100          * @param tag the tag
    101          * @return the tag value with guess
    102          */
    103         private String getTagValueWithGuess(String tag) {
    104                 if (StringUtils.isNullOrEmpty(tag)) return MISSING_TAG;
    105                 if (osmObject == null) return MISSING_TAG;
    106 
    107                 if (!osmObject.hasKey(tag) || StringUtils.isNullOrEmpty(osmObject.get(tag))) {
    108                         if (!hasDerivedValue(tag)) {
    109                                 // object does not have this tag -> check for guess
    110                                 if (hasGuessedValue(tag)) {
    111                                         return "*" + getGuessedValue(tag);
    112                                 } else {
    113                                         // give up
    114                                         return MISSING_TAG;
    115                                 }
    116                         } else { // ok, use derived value known via associated relation or way
    117                                 return getDerivedValue(tag);
    118                         }
    119                 } else { // get existing tag value
    120                         return osmObject.get(tag);
    121                 }
    122         }
    123 
    124         /**
    125          * Returns <tt>true</tt>, if this address node has a street name.
    126          * @return
    127          */
    128         public boolean hasStreetName() {
    129                 return hasTag(TagUtils.ADDR_STREET_TAG);
    130         }
    131 
    132         /**
    133          * Returns the street name guessed by the nearest-neighbor search.
    134          * @return the guessedStreetName
    135          */
    136         public String getGuessedStreetName() {
    137                 return getGuessedValue(TagUtils.ADDR_STREET_TAG);
    138         }
    139 
    140         /**
    141          * Sets the guessed street name.
    142          *
    143          * @param guessedStreetName the guessedStreetName to set
    144          * @param srcObj the source object of the guess.
    145          */
    146         public void setGuessedStreetName(String guessedStreetName, OsmPrimitive srcObj) {
    147                 setGuessedValue(TagUtils.ADDR_STREET_TAG, guessedStreetName, srcObj);
    148         }
    149 
    150         /**
    151          * Checks for a guessed street name.
    152          *
    153          * @return true, if this instance has a guessed street name.
    154          */
    155         public boolean hasGuessedStreetName() {
    156                 return hasGuessedValue(TagUtils.ADDR_STREET_TAG);
    157         }
    158 
    159         /**
    160          * @return the guessedPostCode
    161          */
    162         public String getGuessedPostalCode() {
    163                 return getGuessedValue(TagUtils.ADDR_POSTCODE_TAG);
    164         }
    165 
    166         /**
    167          * Sets the guessed post code.
    168          *
    169          * @param guessedPostCode the guessedPostCode to set
    170          * @param srcObj srcObj the source object of the guess
    171          */
    172         public void setGuessedPostalCode(String guessedPostCode, OsmPrimitive srcObj) {
    173                 setGuessedValue(TagUtils.ADDR_POSTCODE_TAG, guessedPostCode, srcObj);
    174         }
    175 
    176         /**
    177          * Checks for a guessed post code.
    178          *
    179          * @return true, if this instance has a guessed post code.
    180          */
    181         public boolean hasGuessedPostalCode() {
    182                 return hasGuessedValue(TagUtils.ADDR_POSTCODE_TAG);
    183         }
    184 
    185         /**
    186          * @return the guessedCity
    187          */
    188         public String getGuessedCity() {
    189                 return getGuessedValue(TagUtils.ADDR_CITY_TAG);
    190         }
    191 
    192         /**
    193          * Sets the guessed city.
    194          *
    195          * @param guessedCity the guessedCity to set
    196          * @param srcObj the source object of the guess
    197          */
    198         public void setGuessedCity(String guessedCity, OsmPrimitive srcObj) {
    199                 setGuessedValue(TagUtils.ADDR_CITY_TAG, guessedCity, srcObj);
    200         }
    201 
    202         /**
    203          * Checks for a guessed city name.
    204          *
    205          * @return true, if this instance has a guessed city name.
    206          */
    207         public boolean hasGuessedCity() {
    208                 return hasGuessedValue(TagUtils.ADDR_CITY_TAG);
    209         }
    210 
    211         /**
    212          * Returns true, if this instance has guesses regarding address tags.
    213          * @return
    214          */
    215         public boolean hasGuesses() {
    216                 return guessedValues.size() > 0;
    217         }
    218 
    219         /**
    220          * Applies all guessed tags for this node.
    221          */
    222         public void applyAllGuesses() {
    223                 for (String tag : guessedValues.keySet()) {
    224                         applyGuessForTag(tag);
    225                 }
    226 
    227                 // Clear all guesses
    228                 guessedValues.clear();
    229                 guessedObjects.clear();
    230         }
    231 
    232         /**
    233          * Apply the guessed value for the given tag.
    234          *
    235          * @param tag the tag to apply the guessed value for.
    236          */
    237         public void applyGuessForTag(String tag) {
    238                 if (guessedValues.containsKey(tag)) {
    239                         String val = guessedValues.get(tag);
    240                         if (!StringUtils.isNullOrEmpty(val)) {
    241                                 setOSMTag(tag, val);
    242                         }
    243                 }
    244         }
    245 
    246         /**
    247          * Gets the name of the post code associated with this address.
    248          * @return
    249          */
    250         public String getPostalCode() {
    251                 String pc = getTagValueWithGuess(TagUtils.ADDR_POSTCODE_TAG);
    252 
    253 
    254                 if (!MISSING_TAG.equals(pc) && !PostalCodeChecker.hasValidPostalCode(getCountry(), pc)) {
    255                         pc = "(!)" + pc;
    256                 }
    257                 return pc;
    258         }
    259 
    260         /**
    261          * Checks if this instance has a valid postal code.
    262          *
    263          * @return true, if successful
    264          */
    265         public boolean hasValidPostalCode() {
    266                 return PostalCodeChecker.hasValidPostalCode(this);
    267         }
    268 
    269         /**
    270          * Checks for post code tag.
    271          *
    272          * @return true, if successful
    273          */
    274         public boolean hasPostalCode() {
    275                 return hasTag(TagUtils.ADDR_POSTCODE_TAG);
    276         }
    277 
    278         /**
    279          * Gets the name of the house number associated with this address.
    280          * @return
    281          */
    282         public String getHouseNumber() {
    283                 if (!TagUtils.hasAddrHousenumberTag(osmObject)) {
    284                         if (!isPartOfInterpolation) {
    285                                 return MISSING_TAG;
    286                         } else {
    287                                 return INTERPOLATION_TAG;
    288                         }
    289                 }
    290                 return TagUtils.getAddrHousenumberValue(osmObject);
    291         }
    292 
    293         /**
    294          * Checks for house number.
    295          *
    296          * @return true, if successful
    297          */
    298         public boolean hasHouseNumber() {
    299                 return TagUtils.hasAddrHousenumberTag(osmObject) || isPartOfInterpolation;
    300         }
    301 
    302         /* (non-Javadoc)
    303          * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#getName()
    304          */
    305         public String getName() {
    306                 String name = TagUtils.getNameValue(osmObject);
    307                 if (!StringUtils.isNullOrEmpty(name)) {
    308                         return TagUtils.getAddrHousenameValue(osmObject);
    309                 }
    310 
    311                 return "";
    312         }
    313 
    314         /**
    315          * Checks if this address is part of a address interpolation.
    316          *
    317          * @return true, if is part of interpolation
    318          */
    319         protected boolean isPartOfInterpolation() {
    320                 return isPartOfInterpolation;
    321         }
    322 
    323         /**
    324          * Checks if this address is part of an 'associated street' relation.
    325          *
    326          * @return true, if is part of interpolation
    327          */
    328         protected boolean isPartOfRelation() {
    329                 return isPartOfAssocStreetRel;
    330         }
    331 
    332         /**
    333          * Gets the name of the city associated with this address.
    334          * @return
    335          */
    336         public String getCity() {
    337                 return getTagValueWithGuess(TagUtils.ADDR_CITY_TAG);
    338         }
    339 
    340         /**
    341          * Checks for city tag.
    342          *
    343          * @return true, if a city tag is present or available via referrer.
    344          */
    345         public boolean hasCity() {
    346                 return hasTag(TagUtils.ADDR_CITY_TAG);
    347         }
    348 
    349         /**
    350          * Gets the name of the state associated with this address.
    351          * @return
    352          */
    353         public String getState() {
    354                 return getTagValueWithGuess(TagUtils.ADDR_STATE_TAG);
    355         }
    356 
    357         /**
    358          * Checks for state tag.
    359          *
    360          * @return true, if a state tag is present or available via referrer.
    361          */
    362         public boolean hasState() {
    363                 return hasTag(TagUtils.ADDR_STATE_TAG);
    364         }
    365 
    366         /**
    367          * Gets the name of the country associated with this address.
    368          * @return
    369          */
    370         public String getCountry() {
    371                 return getTagValueWithGuess(TagUtils.ADDR_COUNTRY_TAG);
    372         }
    373 
    374         /**
    375          * Checks for country tag.
    376          *
    377          * @return true, if a country tag is present or available via referrer.
    378          */
    379         public boolean hasCountry() {
    380                 return hasTag(TagUtils.ADDR_COUNTRY_TAG);
    381         }
    382 
    383         /**
    384          * Removes all address-related tags from the node or way.
    385          */
    386         public void removeAllAddressTags() {
    387                 removeOSMTag(TagUtils.ADDR_CITY_TAG);
    388                 removeOSMTag(TagUtils.ADDR_COUNTRY_TAG);
    389                 removeOSMTag(TagUtils.ADDR_POSTCODE_TAG);
    390                 removeOSMTag(TagUtils.ADDR_HOUSENUMBER_TAG);
    391                 removeOSMTag(TagUtils.ADDR_STATE_TAG);
    392                 removeOSMTag(TagUtils.ADDR_STREET_TAG);
    393         }
    394 
    395         /**
    396          * Checks if the associated OSM object has the given tag or if the tag is available via a referrer.
    397          *
    398          * @param tag the tag to look for.
    399          * @return true, if there is a value for the given tag.
    400          */
    401         public boolean hasTag(String tag) {
    402                 if (StringUtils.isNullOrEmpty(tag)) return false;
    403 
    404                 return TagUtils.hasTag(osmObject, tag) || hasDerivedValue(tag);
    405         }
    406 
    407         /* (non-Javadoc)
    408          * @see org.openstreetmap.josm.plugins.addressEdit.NodeEntityBase#compareTo(org.openstreetmap.josm.plugins.addressEdit.INodeEntity)
    409          */
    410         @Override
    411         public int compareTo(IOSMEntity o) {
    412                 if (o == null || !(o instanceof OSMAddress)) {
    413                         return -1;
    414                 }
    415                 OSMAddress other = (OSMAddress) o;
    416                
    417                 if (this.equals(other)) return 0;
    418 
    419                 int cc = 0;
    420                 cc = this.getCountry().compareTo(other.getCountry());
    421                 if ( cc  == 0) {
    422                         cc = this.getState().compareTo(other.getState());
    423                         if (cc  == 0) {
    424                                 cc = this.getCity().compareTo(other.getCity());
    425                                 if (cc  == 0) {
    426                                         cc = this.getStreetName().compareTo(other.getStreetName());
    427                                         if (cc  == 0) {
    428                                                 if (hasGuessedStreetName()) {
    429                                                         if (other.hasStreetName()) {
    430                                                                 // Compare guessed name with the real name
    431                                                                 cc = this.getGuessedStreetName().compareTo(other.getStreetName());
    432                                                                 if (cc == 0) {
    433                                                                         cc = this.getHouseNumber().compareTo(other.getHouseNumber());
    434                                                                 }
    435                                                         } else if (other.hasGuessedStreetName()){
    436                                                                 // Compare guessed name with the guessed name
    437                                                                 cc = this.getGuessedStreetName().compareTo(other.getGuessedStreetName());
    438                                                                 if (cc == 0) {
    439                                                                         cc = this.getHouseNumber().compareTo(other.getHouseNumber());
    440                                                                 }
    441                                                         } // else: give up
    442                                                 // No guessed name at all -> just compare the number
    443                                                 } else {
    444                                                         cc = this.getHouseNumber().compareTo(other.getHouseNumber());
    445                                                 }
    446                                         }
    447                                 }
    448                         }
    449                 }
    450 
    451                 return cc;
    452         }
    453 
    454         /**
    455          * Applies the street name from the specified street node.
    456          * @param node
    457          */
    458         public void assignStreet(OSMStreet node) {
    459                 if (node == null || !node.hasName()) return;
    460 
    461                 if (!node.getName().equals(getStreetName())) {
    462                         setStreetName(node.getName());
    463                         node.addAddress(this);
    464                         fireEntityChanged(this);
    465                 }
    466         }
    467 
    468         /**
    469          * Gets the guessed value for the given tag.
    470          *
    471          * @param tag The tag to get the guessed value for.
    472          * @return the guessed value
    473          */
    474         public String getGuessedValue(String tag) {
    475                 CheckParameterUtil.ensureParameterNotNull(tag, "tag");
    476 
    477                 if (!hasGuessedValue(tag)) {
    478                         return null;
    479                 }
    480                 return guessedValues.get(tag);
    481         }
    482 
    483         /**
    484          * Gets the guessed object.
    485          *
    486          * @param tag the guessed tag
    487          * @return the object which has been selected for the guess
    488          */
    489         public OsmPrimitive getGuessedObject(String tag) {
    490                 CheckParameterUtil.ensureParameterNotNull(tag, "tag");
    491 
    492                 if (guessedObjects.containsKey(tag)) {
    493                         return guessedObjects.get(tag);
    494                 }
    495                 return null;
    496         }
    497 
    498         /**
    499          * Gets all guessed objects or an empty list, if no guesses have been made yet.
    500          *
    501          * @return the guessed objects.
    502          */
    503         public Collection<OsmPrimitive> getGuessedObjects() {
    504                 if (guessedObjects == null) return null;
    505 
    506                 return guessedObjects.values();
    507         }
    508 
    509         /**
    510          * Check if this instance needs guessed values. This is the case, if the underlying OSM node
    511          * has either no street name, post code or city.
    512          *
    513          * @return true, if this instance needs at least one guessed value.
    514          */
    515         public boolean needsGuess() {
    516                 return  needsGuessedValue(TagUtils.ADDR_CITY_TAG) ||
    517                                 needsGuessedValue(TagUtils.ADDR_POSTCODE_TAG) ||
    518                                 needsGuessedValue(TagUtils.ADDR_COUNTRY_TAG) ||
    519                                 //needsGuessedValue(TagUtils.ADDR_STATE_TAG) ||
    520                                 needsGuessedValue(TagUtils.ADDR_STREET_TAG);
    521         }
    522 
    523         /**
    524          * Check if this instance needs guessed value for a given tag.
    525          * @return true, if successful
    526          */
    527         public boolean needsGuessedValue(String tag) {
    528                 return MISSING_TAG.equals(getTagValueWithGuess(tag));
    529         }
    530 
    531         /**
    532          * Clears all guessed values.
    533          */
    534         public void clearAllGuesses() {
    535                 guessedValues.clear();
    536         }
    537 
    538         /**
    539          * Checks if given tag has a guessed value (tag exists and has a non-empty value).
    540          *
    541          * @param tag the tag
    542          * @return true, if tag has a guessed value.
    543          */
    544         private boolean hasGuessedValue(String tag) {
    545                 CheckParameterUtil.ensureParameterNotNull(tag, "tag");
    546 
    547                 return guessedValues.containsKey(tag) &&
    548                         !StringUtils.isNullOrEmpty(guessedValues.get(tag));
    549         }
    550 
    551         /**
    552          * Sets the guessed value with the given tag.
    553          *
    554          * @param tag the tag to set the guess for
    555          * @param value the value of the guessed tag.
    556          * @param osm the (optional) object which was used for the guess
    557          */
    558         public void setGuessedValue(String tag, String value, OsmPrimitive osm) {
    559                 CheckParameterUtil.ensureParameterNotNull(tag, "tag");
    560 
    561                 if (value != null && osm != null) {
    562                         guessedValues.put(tag, value);
    563                         if (osm != null) {
    564                                 guessedObjects.put(tag, osm);
    565                         }
    566                         fireEntityChanged(this);
    567                 }
    568         }
    569 
    570         /**
    571          * Checks if given tag has a derived value (value is available via a referrer).
    572          *
    573          * @param tag the tag
    574          * @return true, if tag has a derived value.
    575          */
    576         private boolean hasDerivedValue(String tag) {
    577                 CheckParameterUtil.ensureParameterNotNull(tag, "tag");
    578 
    579                 return derivedValues.containsKey(tag) &&
    580                         !StringUtils.isNullOrEmpty(derivedValues.get(tag));
    581         }
    582 
    583         /**
    584          * Returns true, if this instance has derived values from any referrer.
    585          * @return
    586          */
    587         public boolean hasDerivedValues() {
    588                 return derivedValues.size() > 0;
    589         }
    590 
    591         /**
    592          * Gets the derived value for the given tag.
    593          * @param tag The tag to get the derived value for.
    594          * @return
    595          */
    596         public String getDerivedValue(String tag) {
    597                 if (!hasDerivedValue(tag)) {
    598                         return null;
    599                 }
    600                 return derivedValues.get(tag);
    601         }
    602 
    603         /**
    604          * Sets the value known indirectly via a referrer with the given tag.
    605          *
    606          * @param tag the tag to set the derived value for
    607          * @param value the value of the derived tag.
    608          */
    609         public void setDerivedValue(String tag, String value) {
    610                 derivedValues.put(tag, value);
    611         }
    612 
    613         /**
    614          * Sets the street name of the address node.
    615          * @param streetName
    616          */
    617         public void setStreetName(String streetName) {
    618                 if (streetName != null && streetName.length() == 0) return;
    619 
    620                 setOSMTag(TagUtils.ADDR_STREET_TAG, streetName);
    621         }
    622 
    623 
    624         /**
    625          * Sets the state of the address node.
    626          * @param state
    627          */
    628         public void setState(String state) {
    629                 if (state != null && state.length() == 0) return;
    630 
    631                 setOSMTag(TagUtils.ADDR_STATE_TAG, state);
    632         }
    633 
    634         /**
    635          * Sets the country of the address node.
    636          * @param country
    637          */
    638         public void setCountry(String country) {
    639                 if (country != null && country.length() == 0) return;
    640 
    641                 setOSMTag(TagUtils.ADDR_COUNTRY_TAG, country);
    642         }
    643 
    644         /**
    645          * Sets the post code of the address node.
    646          * @param postCode
    647          */
    648         public void setPostCode(String postCode) {
    649                 if (postCode != null && postCode.length() == 0) return;
    650 
    651                 setOSMTag(TagUtils.ADDR_POSTCODE_TAG, postCode);
    652         }
    653 
    654         /* (non-Javadoc)
    655          * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#visit(org.openstreetmap.josm.plugins.fixAddresses.IProblemVisitor)
    656          */
    657         @Override
    658         public void visit(IAllKnowingTrashHeap trashHeap, IProblemVisitor visitor) {
    659                 CheckParameterUtil.ensureParameterNotNull(visitor, "visitor");
    660 
    661                 // Check for street
    662                 if (!hasStreetName()) {
    663                         AddressProblem p = new AddressProblem(this, tr("Address has no street"));
    664                         if (hasGuessedStreetName()) { // guess exists -> add solution entry
    665                                 String tag = TagUtils.ADDR_STREET_TAG;
    666                                 addGuessValueSolution(p, tag);
    667                         }
    668                         addRemoveAddressTagsSolution(p);
    669                         visitor.addProblem(p);
    670                 // Street name exists, but is invalid -> ask the all knowing trash heap
    671                 } else if (!trashHeap.isValidStreetName(getStreetName())) {
    672                         AddressProblem p = new AddressProblem(this, tr("Address has no valid street"));
    673                         String match = trashHeap.getClosestStreetName(getStreetName());
    674 
    675                         if (!StringUtils.isNullOrEmpty(match)) {
    676                                 setGuessedStreetName(match, null);
    677                                 addGuessValueSolution(p, TagUtils.ADDR_STREET_TAG);
    678                         }
    679                         visitor.addProblem(p);
    680                 }
    681 
    682                 // Check for postal code
    683                 if (!hasPostalCode()) {
    684                         AddressProblem p = new AddressProblem(this, tr("Address has no post code"));
    685                         if (hasGuessedStreetName()) {
    686                                 String tag = TagUtils.ADDR_POSTCODE_TAG;
    687                                 addGuessValueSolution(p, tag);
    688                         }
    689                         addRemoveAddressTagsSolution(p);
    690                         visitor.addProblem(p);
    691                 }
    692 
    693                 // Check for city
    694                 if (!hasCity()) {
    695                         AddressProblem p = new AddressProblem(this, tr("Address has no city"));
    696                         if (hasGuessedStreetName()) {
    697                                 String tag = TagUtils.ADDR_CITY_TAG;
    698                                 addGuessValueSolution(p, tag);
    699                         }
    700                         addRemoveAddressTagsSolution(p);
    701                         visitor.addProblem(p);
    702                 }
    703 
    704                 // Check for country
    705                 if (!hasCountry()) {
    706                         // TODO: Add guess for country
    707                         AddressProblem p = new AddressProblem(this, tr("Address has no country"));
    708                         addRemoveAddressTagsSolution(p);
    709                         visitor.addProblem(p);
    710                 }
    711         }
    712 
    713         /**
    714          * Adds the guess value solution to a problem.
    715          *
    716          * @param p the problem to add the solution to.
    717          * @param tag the tag to change.
    718          */
    719         private void addGuessValueSolution(AddressProblem p, String tag) {
    720                 AddressSolution s = new AddressSolution(
    721                                 String.format("%s '%s'", tr("Assign to"), getGuessedValue(tag)),
    722                                 AddressActions.getApplyGuessesAction(),
    723                                 SolutionType.Change);
    724 
    725                 p.addSolution(s);
    726         }
    727 
    728         /**
    729          * Adds the remove address tags solution entry to a problem.
    730          *
    731          * @param problem the problem
    732          */
    733         private void addRemoveAddressTagsSolution(IProblem problem) {
    734                 CheckParameterUtil.ensureParameterNotNull(problem, "problem");
    735 
    736                 AddressSolution s = new AddressSolution(
    737                                                 tr("Remove all address tags"),
    738                                                 AddressActions.getRemoveTagsAction(),
    739                                                 SolutionType.Remove);
    740                 problem.addSolution(s);
    741         }
    742 
    743         /* (non-Javadoc)
    744          * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#toString()
    745          */
    746         @Override
    747         public String toString() {
    748                 return OSMAddress.getFormatString(this);
    749         }
    750 
    751         /**
    752          * Gets the formatted string representation of the given node.
    753          *
    754          * @param node the node
    755          * @return the format string
    756          */
    757         public static String getFormatString(OSMAddress node) {
    758                 // TODO: Add further countries here
    759                 // DE
    760                 String guessed = node.getGuessedStreetName();
    761                 String sName = node.getStreetName();
    762                 if (!StringUtils.isNullOrEmpty(guessed) && MISSING_TAG.equals(sName)) {
    763                         sName = String.format("(%s)", guessed);
    764                 }
    765 
    766                 return String.format("%s %s, %s-%s %s (%s) ",
    767                                 sName,
    768                                 node.getHouseNumber(),
    769                                 node.getCountry(),
    770                                 node.getPostalCode(),
    771                                 node.getCity(),
    772                                 node.getState());
    773         }
     492            }
     493        }
     494
     495        return cc;
     496    }
     497
     498    /**
     499     * Applies the street name from the specified street node.
     500     *
     501     * @param node
     502     */
     503    public void assignStreet(OSMStreet node) {
     504        if (node == null || !node.hasName())
     505            return;
     506
     507        if (!node.getName().equals(getStreetName())) {
     508            setStreetName(node.getName());
     509            node.addAddress(this);
     510            fireEntityChanged(this);
     511        }
     512    }
     513
     514    /**
     515     * Gets the guessed value for the given tag.
     516     *
     517     * @param tag
     518     *            The tag to get the guessed value for.
     519     * @return the guessed value
     520     */
     521    public String getGuessedValue(String tag) {
     522        CheckParameterUtil.ensureParameterNotNull(tag, "tag");
     523
     524        if (!hasGuessedValue(tag)) {
     525            return null;
     526        }
     527        return guessedValues.get(tag);
     528    }
     529
     530    /**
     531     * Gets the guessed object.
     532     *
     533     * @param tag
     534     *            the guessed tag
     535     * @return the object which has been selected for the guess
     536     */
     537    public OsmPrimitive getGuessedObject(String tag) {
     538        CheckParameterUtil.ensureParameterNotNull(tag, "tag");
     539
     540        if (guessedObjects.containsKey(tag)) {
     541            return guessedObjects.get(tag);
     542        }
     543        return null;
     544    }
     545
     546    /**
     547     * Gets all guessed objects or an empty list, if no guesses have been made
     548     * yet.
     549     *
     550     * @return the guessed objects.
     551     */
     552    public Collection<OsmPrimitive> getGuessedObjects() {
     553        if (guessedObjects == null)
     554            return null;
     555
     556        return guessedObjects.values();
     557    }
     558
     559    /**
     560     * Check if this instance needs guessed values. This is the case, if the
     561     * underlying OSM node has either no street name, post code or city.
     562     *
     563     * @return true, if this instance needs at least one guessed value.
     564     */
     565    public boolean needsGuess() {
     566        return needsGuessedValue(TagUtils.ADDR_CITY_TAG)
     567                || needsGuessedValue(TagUtils.ADDR_POSTCODE_TAG)
     568                || needsGuessedValue(TagUtils.ADDR_COUNTRY_TAG) ||
     569                // needsGuessedValue(TagUtils.ADDR_STATE_TAG) ||
     570                needsGuessedValue(TagUtils.ADDR_STREET_TAG);
     571    }
     572
     573    /**
     574     * Check if this instance needs guessed value for a given tag.
     575     *
     576     * @return true, if successful
     577     */
     578    public boolean needsGuessedValue(String tag) {
     579        return MISSING_TAG.equals(getTagValueWithGuess(tag));
     580    }
     581
     582    /**
     583     * Clears all guessed values.
     584     */
     585    public void clearAllGuesses() {
     586        guessedValues.clear();
     587    }
     588
     589    /**
     590     * Checks if given tag has a guessed value (tag exists and has a non-empty
     591     * value).
     592     *
     593     * @param tag
     594     *            the tag
     595     * @return true, if tag has a guessed value.
     596     */
     597    private boolean hasGuessedValue(String tag) {
     598        CheckParameterUtil.ensureParameterNotNull(tag, "tag");
     599
     600        return guessedValues.containsKey(tag)
     601                && !StringUtils.isNullOrEmpty(guessedValues.get(tag));
     602    }
     603
     604    /**
     605     * Sets the guessed value with the given tag.
     606     *
     607     * @param tag
     608     *            the tag to set the guess for
     609     * @param value
     610     *            the value of the guessed tag.
     611     * @param osm
     612     *            the (optional) object which was used for the guess
     613     */
     614    public void setGuessedValue(String tag, String value, OsmPrimitive osm) {
     615        CheckParameterUtil.ensureParameterNotNull(tag, "tag");
     616
     617        if (value != null && osm != null) {
     618            guessedValues.put(tag, value);
     619            if (osm != null) {
     620                guessedObjects.put(tag, osm);
     621            }
     622            fireEntityChanged(this);
     623        }
     624    }
     625
     626    /**
     627     * Checks if given tag has a derived value (value is available via a
     628     * referrer).
     629     *
     630     * @param tag
     631     *            the tag
     632     * @return true, if tag has a derived value.
     633     */
     634    private boolean hasDerivedValue(String tag) {
     635        CheckParameterUtil.ensureParameterNotNull(tag, "tag");
     636
     637        return derivedValues.containsKey(tag)
     638                && !StringUtils.isNullOrEmpty(derivedValues.get(tag));
     639    }
     640
     641    /**
     642     * Returns true, if this instance has derived values from any referrer.
     643     *
     644     * @return
     645     */
     646    public boolean hasDerivedValues() {
     647        return derivedValues.size() > 0;
     648    }
     649
     650    /**
     651     * Gets the derived value for the given tag.
     652     *
     653     * @param tag
     654     *            The tag to get the derived value for.
     655     * @return
     656     */
     657    public String getDerivedValue(String tag) {
     658        if (!hasDerivedValue(tag)) {
     659            return null;
     660        }
     661        return derivedValues.get(tag);
     662    }
     663
     664    /**
     665     * Sets the value known indirectly via a referrer with the given tag.
     666     *
     667     * @param tag
     668     *            the tag to set the derived value for
     669     * @param value
     670     *            the value of the derived tag.
     671     */
     672    public void setDerivedValue(String tag, String value) {
     673        derivedValues.put(tag, value);
     674    }
     675
     676    /**
     677     * Sets the street name of the address node.
     678     *
     679     * @param streetName
     680     */
     681    public void setStreetName(String streetName) {
     682        if (streetName != null && streetName.length() == 0)
     683            return;
     684
     685        setOSMTag(TagUtils.ADDR_STREET_TAG, streetName);
     686    }
     687
     688    /**
     689     * Sets the state of the address node.
     690     *
     691     * @param state
     692     */
     693    public void setState(String state) {
     694        if (state != null && state.length() == 0)
     695            return;
     696
     697        setOSMTag(TagUtils.ADDR_STATE_TAG, state);
     698    }
     699
     700    /**
     701     * Sets the country of the address node.
     702     *
     703     * @param country
     704     */
     705    public void setCountry(String country) {
     706        if (country != null && country.length() == 0)
     707            return;
     708
     709        setOSMTag(TagUtils.ADDR_COUNTRY_TAG, country);
     710    }
     711
     712    /**
     713     * Sets the post code of the address node.
     714     *
     715     * @param postCode
     716     */
     717    public void setPostCode(String postCode) {
     718        if (postCode != null && postCode.length() == 0)
     719            return;
     720
     721        setOSMTag(TagUtils.ADDR_POSTCODE_TAG, postCode);
     722    }
     723
     724    /*
     725     * (non-Javadoc)
     726     *
     727     * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#visit(org.
     728     * openstreetmap.josm.plugins.fixAddresses.IProblemVisitor)
     729     */
     730    @Override
     731    public void visit(IAllKnowingTrashHeap trashHeap, IProblemVisitor visitor) {
     732        CheckParameterUtil.ensureParameterNotNull(visitor, "visitor");
     733
     734        // Check for street
     735        if (!hasStreetName()) {
     736            AddressProblem p = new AddressProblem(this,
     737                    tr("Address has no street"));
     738            if (hasGuessedStreetName()) { // guess exists -> add solution entry
     739                String tag = TagUtils.ADDR_STREET_TAG;
     740                addGuessValueSolution(p, tag);
     741            }
     742            addRemoveAddressTagsSolution(p);
     743            visitor.addProblem(p);
     744            // Street name exists, but is invalid -> ask the all knowing trash
     745            // heap
     746        } else if (!trashHeap.isValidStreetName(getStreetName())) {
     747            AddressProblem p = new AddressProblem(this,
     748                    tr("Address has no valid street"));
     749            String match = trashHeap.getClosestStreetName(getStreetName());
     750
     751            if (!StringUtils.isNullOrEmpty(match)) {
     752                setGuessedStreetName(match, null);
     753                addGuessValueSolution(p, TagUtils.ADDR_STREET_TAG);
     754            }
     755            visitor.addProblem(p);
     756        }
     757
     758        // Check for postal code
     759        if (!hasPostalCode()) {
     760            AddressProblem p = new AddressProblem(this,
     761                    tr("Address has no post code"));
     762            if (hasGuessedStreetName()) {
     763                String tag = TagUtils.ADDR_POSTCODE_TAG;
     764                addGuessValueSolution(p, tag);
     765            }
     766            addRemoveAddressTagsSolution(p);
     767            visitor.addProblem(p);
     768        }
     769
     770        // Check for city
     771        if (!hasCity()) {
     772            AddressProblem p = new AddressProblem(this,
     773                    tr("Address has no city"));
     774            if (hasGuessedStreetName()) {
     775                String tag = TagUtils.ADDR_CITY_TAG;
     776                addGuessValueSolution(p, tag);
     777            }
     778            addRemoveAddressTagsSolution(p);
     779            visitor.addProblem(p);
     780        }
     781
     782        // Check for country
     783        if (!hasCountry()) {
     784            // TODO: Add guess for country
     785            AddressProblem p = new AddressProblem(this,
     786                    tr("Address has no country"));
     787            addRemoveAddressTagsSolution(p);
     788            visitor.addProblem(p);
     789        }
     790    }
     791
     792    /**
     793     * Adds the guess value solution to a problem.
     794     *
     795     * @param p
     796     *            the problem to add the solution to.
     797     * @param tag
     798     *            the tag to change.
     799     */
     800    private void addGuessValueSolution(AddressProblem p, String tag) {
     801        AddressSolution s = new AddressSolution(String.format("%s '%s'",
     802                tr("Assign to"), getGuessedValue(tag)),
     803                AddressActions.getApplyGuessesAction(), SolutionType.Change);
     804
     805        p.addSolution(s);
     806    }
     807
     808    /**
     809     * Adds the remove address tags solution entry to a problem.
     810     *
     811     * @param problem
     812     *            the problem
     813     */
     814    private void addRemoveAddressTagsSolution(IProblem problem) {
     815        CheckParameterUtil.ensureParameterNotNull(problem, "problem");
     816
     817        AddressSolution s = new AddressSolution(tr("Remove all address tags"),
     818                AddressActions.getRemoveTagsAction(), SolutionType.Remove);
     819        problem.addSolution(s);
     820    }
     821
     822    /*
     823     * (non-Javadoc)
     824     *
     825     * @see org.openstreetmap.josm.plugins.fixAddresses.OSMEntityBase#toString()
     826     */
     827    @Override
     828    public String toString() {
     829        return OSMAddress.getFormatString(this);
     830    }
     831
     832    /**
     833     * Gets the formatted string representation of the given node.
     834     *
     835     * @param node
     836     *            the node
     837     * @return the format string
     838     */
     839    public static String getFormatString(OSMAddress node) {
     840        // TODO: Add further countries here
     841        // DE
     842        String guessed = node.getGuessedStreetName();
     843        String sName = node.getStreetName();
     844        if (!StringUtils.isNullOrEmpty(guessed) && MISSING_TAG.equals(sName)) {
     845            sName = String.format("(%s)", guessed);
     846        }
     847
     848        return String.format("%s %s, %s-%s %s (%s) ", sName,
     849                node.getHouseNumber(), node.getCountry(), node.getPostalCode(),
     850                node.getCity(), node.getState());
     851    }
    774852}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/OsmUtils.java

    r25373 r29967  
    232232
    233233        /**
    234          * Helper method to set an derived value of an address node.
     234         * Helper method to set a derived value of an address node.
    235235         *
    236236         * @param address The address to change
Note: See TracChangeset for help on using the changeset viewer.