pear / Services_Openstreetmap

Makes communicating with the Open Street Map API, and Nominatim, from PHP intuitive.
https://pear.php.net/package/Services_OpenStreetMap/
BSD 3-Clause "New" or "Revised" License
202 stars 53 forks source link

Allowing to create/change two tags with the same value #12

Closed Maturion closed 7 years ago

Maturion commented 7 years ago

I noticed that, when opening a changeset with Services_Openstreetmap, creating two tags with exactly the same value is prevented. It's also not possible to change an existing tag to exactly the same value used by another tag.

However, there are certain cases where it does make sense to add two tags with the same value. For example in Ukraine, where most objects are tagged both in Ukrainian and Russian, it is even explicitly suggested to duplicate the Ukrainian name (usually used in the main "name" tag) in name:uk to better distinguish it from Russian names. Also, wouldn't this above check even prevent objects from having certain names? Imagine a café (tagged as amenity=cafe) being called "cafe" (name=cafe)? I'm sure somewhere in this world, we'll have a café called "cafe" (in exactly this spelling :) ).

Any chance of allowing such edits? The relevant code is one line, in Services/OpenStreetMap/Object.php in getOsmChangeXml(): $diff = array_diff($this->getTags(), $set);

kenguest commented 7 years ago

What you say doesn't seem to be supported by the newly added https://github.com/kenguest/Services_Openstreetmap/blob/master/tests/TagsWithSameValueTest.php test class, so I'm inclined to close this issue.

Perhaps you could submit a pull request with changes to the file TagsWithSameValueTest.php to convince me otherwise?

Maturion commented 7 years ago

I think the problem does not occur when you create a new node/way (as it is done in TagsWithSameValueTest.php). I ran your test and it indeed seemed like there was no problem. Then I tried it again with an existing node from the live OSM database and the problem reappeared.

array_diff($this->getTags(), $set) does compare $this->getTags() and $set.

Values are assigned to $set this way:

$set = array();
            for ($i = 0; $i < $tags->length; $i++) {
                $key = $tags->item($i)->getAttribute('k');
                $val = $tags->item($i)->getAttribute('v');
                $set[$key] = $val;
            }

$set contains the values of an object before your new ChangeSet is applied. Hence when you create a new object, $set is empty and array_diff($this->getTags(), $set) will save two tags with the same value. However, when you're editing an existing object, $set is not empty and the problem I described in my issue will appear. Therefore I still sugesst removing this check.