/**
* Copyright (C) 2006 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Author: steve
* Date: 26-Dec-2006
*/
package uk.me.parabola.mkgmap.reader.osm;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import uk.me.parabola.imgfmt.app.Label;
import uk.me.parabola.log.Logger;
/**
* Superclass of the node, segment and way OSM elements.
*/
public abstract class Element {
private static final Logger log = Logger.getLogger(Element.class);
private Tags tags;
private long id;
private long originalId;
public int getTagCount() {
return (tags == null ? 0 : tags.size());
}
/**
* Add a tag to the element. This method should be called by OSM readers
* because it trims obsolete spaces from the value.
*
* @param key The tag name.
* @param val Its value.
*/
public void addTagFromRawOSM(String key, String val) {
if (val != null){
val = val.trim();
if (val.isEmpty() == false){
// remove duplicated spaces within value
String squashed = Label.squashSpaces(val);
if (val.equals(squashed) == false) {
if (log.isInfoEnabled())
log.info(this.toBrowseURL(),"obsolete blanks removed from tag", key, " '" + val + "' -> '" + squashed + "'");
val = squashed;
}
}
}
addTag(key, val.intern());
}
/**
* Add a tag to the element. Some tags are recognised separately and saved in
* separate fields.
*
* @param key The tag name.
* @param val Its value.
*/
public void addTag(String key, String val) {
if (tags == null)
tags = new Tags();
tags.put(key, val);
}
/**
* Add a tag to the element. Some tags are recognised separately and saved in
* separate fields.
*
* @param tagKey The tag id created by TagDict
* @param val Its value.
*/
public void addTag(short tagKey, String val) {
if (tags == null)
tags = new Tags();
tags.put(tagKey, val);
}
public String getTag(String key) {
if (tags == null)
return null;
return tags.get(key);
}
public String getTag(short tagKey) {
if (tags == null)
return null;
return tags.get(tagKey);
}
public String deleteTag(String tagname) {
String old = null;
if(tags != null) {
old = tags.remove(tagname);
if (tags.size() == 0) {
tags = null;
}
}
return old;
}
public String deleteTag(short tagKey) {
String old = null;
if(tags != null) {
old = tags.remove(tagKey);
if (tags.size() == 0) {
tags = null;
}
}
return old;
}
/**
* Retrieves if the given tag has a "positive" boolean value which means its value is
* one of
* <ul>
* <li><code>true</code></li>
* <li><code>yes</code></li>
* <li><code>1</code></li>
* </ul>
* @param s tag name
* @return <code>true</code> if the tag value is a boolean tag with a "positive" value
*/
public boolean tagIsLikeYes(String s) {
return tagIsLikeYes(TagDict.getInstance().xlate(s));
}
/**
* Retrieves if the given tag has a "positive" boolean value which means its value is
* one of
* <ul>
* <li><code>true</code></li>
* <li><code>yes</code></li>
* <li><code>1</code></li>
* </ul>
* @param tagKey tag id returned by TagDict
* @return <code>true</code> if the tag value is a boolean tag with a "positive" value
*/
public boolean tagIsLikeYes(short tagKey) {
String val = getTag(tagKey);
if (val == null)
return false;
if (val.equals("yes") || val.equals("true") || val.equals("1"))
return true;
return false;
}
/**
* Retrieves if the given tag has a "negative" boolean value which means its value is
* one of
* <ul>
* <li><code>false</code></li>
* <li><code>no</code></li>
* <li><code>0</code></li>
* </ul>
* @param s tag name
* @return <code>true</code> if the tag value is a boolean tag with a "negative" value
*/
public boolean tagIsLikeNo(String s) {
return tagIsLikeNo(TagDict.getInstance().xlate(s));
}
/**
* Retrieves if the given tag has a "negative" boolean value which means its value is
* one of
* <ul>
* <li><code>false</code></li>
* <li><code>no</code></li>
* <li><code>0</code></li>
* </ul>
* @param tagKey tag id returned by TagDict
* @return <code>true</code> if the tag value is a boolean tag with a "negative" value
*/
public boolean tagIsLikeNo(short tagKey) {
String val = getTag(tagKey);
if (val == null)
return false;
if (val.equals("no") || val.equals("false") || val.equals("0"))
return true;
return false;
}
public long getId() {
return id;
}
/**
* Returns the Id of the original OSM element on which this element was based.
* <p>
* The Id of the original element will be different from the Id of this
* element if this element uses a faked Id.
*/
public long getOriginalId() {
return originalId;
}
protected void setId(long id) {
this.id = id;
originalId = id;
}
public void setFakeId() {
id = FakeIdGenerator.makeFakeId();
}
public String toTagString() {
if (tags == null)
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (String nameval : tags) {
sb.append(nameval);
sb.append(',');
}
if (sb.length() > 1) {
sb.setLength(sb.length()-1);
}
sb.append(']');
return sb.toString();
}
/**
* Copy the tags of the other element which replaces all tags of this element.
*
* @param other The other element. All its tags will be copied to this
* element.
*/
public void copyTags(Element other) {
if (other.tags == null)
tags = null;
else
tags = other.tags.copy();
}
public String getName() {
return getTag("mkgmap:label:1");
}
public Map<String, String> getTagsWithPrefix(String prefix, boolean removePrefix) {
if (tags == null)
return Collections.emptyMap();
return tags.getTagsWithPrefix(prefix, removePrefix);
}
protected void removeAllTags() {
tags = null;
}
/**
* @return a Map iterator for the key + value pairs
*/
public Iterable<Map.Entry<String, String>> getTagEntryIterator() {
return new Iterable<Map.Entry<String, String>>() {
public Iterator<Map.Entry<String, String>> iterator() {
if (tags == null)
return Collections.emptyIterator();
return tags.entryIterator();
}
};
}
/**
* @return a Map iterator for the key + value pairs
*/
public Iterable<Map.Entry<Short, String>> getFastTagEntryIterator() {
return new Iterable<Map.Entry<Short, String>>() {
public Iterator<Map.Entry<Short, String>> iterator() {
if (tags == null)
return Collections.emptyIterator();
return tags.entryShortIterator();
}
};
}
protected String kind() {
return "unknown";
}
public String toBrowseURL() {
return "http://www.openstreetmap.org/" + kind() + "/" + id;
}
public Element copy() {
// Can be implemented in subclasses
throw new UnsupportedOperationException("unsupported element copy");
}
public String getDebugName() {
String name = getName();
if(name == null)
name = getTag("ref");
if(name == null)
name = "";
else
name += " ";
return name + "(OSM id " + getId() + ")";
}
}