package com.revolsys.record.io.format.openstreetmap.model;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.revolsys.datatype.DataTypes;
import com.revolsys.geometry.model.Geometry;
import com.revolsys.io.PathName;
import com.revolsys.record.AbstractRecord;
import com.revolsys.record.RecordState;
import com.revolsys.record.io.format.xml.StaxReader;
import com.revolsys.record.schema.FieldDefinition;
import com.revolsys.record.schema.RecordDefinition;
import com.revolsys.record.schema.RecordDefinitionImpl;
import com.revolsys.util.Property;
public class OsmElement extends AbstractRecord implements OsmConstants {
public static final RecordDefinition RECORD_DEFINITION;
static {
final RecordDefinitionImpl recordDefinition = new RecordDefinitionImpl(
PathName.newPathName("/osm/record"));
recordDefinition.addField("id", DataTypes.LONG);
recordDefinition.addField("visible", DataTypes.BOOLEAN);
recordDefinition.addField("version", DataTypes.INT);
recordDefinition.addField("changeset", DataTypes.LONG);
recordDefinition.addField("timestamp", DataTypes.DATE_TIME);
recordDefinition.addField("user", DataTypes.STRING);
recordDefinition.addField("uid", DataTypes.INT);
recordDefinition.addField("tags", DataTypes.MAP);
recordDefinition.addField("geometry", DataTypes.GEOMETRY);
recordDefinition.setGeometryFieldName("geometry");
recordDefinition.setGeometryFactory(WGS84_2D);
RECORD_DEFINITION = recordDefinition;
}
private long changeset = -1;
private Geometry geometry;
private long id;
private Map<String, String> tags = Collections.emptyMap();
private Date timestamp = new Date(0);
private int uid = -1;
private String user = "";
private int version = -1;
private boolean visible = true;
public OsmElement() {
}
public OsmElement(final long id, final boolean visible, final int version, final long changeset,
final Date timestamp, final String user, final int uid, final Map<String, String> tags) {
this.id = id;
this.visible = visible;
this.version = version;
this.changeset = changeset;
this.timestamp = timestamp;
this.user = user;
this.uid = uid;
this.tags = tags;
}
public OsmElement(final OsmElement element) {
setInfo(element);
}
public OsmElement(final StaxReader in) {
this.id = in.getLongAttribute(null, "id");
this.visible = in.getBooleanAttribute(null, "visible");
this.version = in.getIntAttribute(null, "version");
this.changeset = in.getIntAttribute(null, "changeset");
this.user = in.getAttributeValue(null, "user");
this.uid = in.getIntAttribute(null, "uid");
}
public synchronized void addTag(final String key, final String value) {
if (Property.hasValue(key)) {
if (key.length() <= 255) {
if (Property.hasValue(value)) {
if (value.length() <= 255) {
if (this.tags.isEmpty()) {
this.tags = new HashMap<>();
}
this.tags.put(key, value);
} else {
throw new IllegalArgumentException("Value length " + key.length() + " must be <= 255");
}
} else {
removeTag(key);
}
} else {
throw new IllegalArgumentException("Value length " + value.length() + " must be <= 255");
}
} else {
throw new IllegalArgumentException("Key cannot be null or the emptry string");
}
}
public void addTags(final Map<String, String> tags) {
if (tags != null && !tags.isEmpty()) {
for (final Entry<String, String> tag : tags.entrySet()) {
final String key = tag.getKey();
final String value = tag.getValue();
addTag(key, value);
}
}
}
@Override
public OsmElement clone() {
return (OsmElement)super.clone();
}
public long getChangeset() {
return this.changeset;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Geometry> T getGeometry() {
return (T)this.geometry;
}
public long getId() {
return this.id;
}
@Override
public RecordDefinition getRecordDefinition() {
return RECORD_DEFINITION;
}
@Override
public RecordState getState() {
return RecordState.NEW;
}
public String getTag(final String name) {
if (this.tags == null) {
return null;
} else {
return this.tags.get(name);
}
}
public Map<String, String> getTags() {
return new HashMap<>(this.tags);
}
public Date getTimestamp() {
return this.timestamp;
}
public int getUid() {
return this.uid;
}
public String getUser() {
return this.user;
}
@SuppressWarnings("unchecked")
@Override
public <V> V getValue(final int index) {
Object value = null;
switch (index) {
case 0:
value = this.id;
break;
case 1:
value = this.visible;
break;
case 2:
value = this.version;
break;
case 3:
value = this.changeset;
break;
case 4:
value = this.timestamp;
break;
case 5:
value = this.user;
break;
case 6:
value = this.uid;
break;
case 7:
value = this.tags;
break;
case 8:
value = this.geometry;
break;
}
return (V)value;
}
public int getVersion() {
return this.version;
}
@Override
public int hashCode() {
return (int)(this.id ^ this.id >>> 32);
}
public boolean hasTags() {
return this.tags != null && !this.tags.isEmpty();
}
@Override
public boolean isState(final RecordState state) {
return state == RecordState.NEW;
}
public boolean isTagged() {
return this.tags != null && !this.tags.isEmpty();
}
public boolean isVisible() {
return this.visible;
}
protected void parseTag(final StaxReader in) {
final String key = in.getAttributeValue(null, "k");
final String value = in.getAttributeValue(null, "v");
addTag(key, value);
in.skipToEndElement(TAG);
}
public void removeTag(final String key) {
if (this.tags.containsKey(key)) {
this.tags.remove(key);
if (this.tags.isEmpty()) {
this.tags = Collections.emptyMap();
}
}
}
public void setChangeset(final long changeset) {
this.changeset = changeset;
}
@Override
public void setGeometryValue(final Geometry geometry) {
if (geometry == null) {
this.geometry = null;
} else {
this.geometry = geometry.convertGeometry(WGS84_2D, geometry.getAxisCount());
}
}
public void setId(final long id) {
this.id = id;
}
public void setInfo(final OsmElement element) {
setId(element.getId());
setChangeset(element.getChangeset());
setTimestamp(element.getTimestamp());
setUid(element.getUid());
setUser(element.getUser());
setVersion(element.getVersion());
setTags(element.getTags());
}
@Override
public RecordState setState(final RecordState state) {
return getState();
}
public void setTags(final Map<String, String> tags) {
this.tags = Collections.emptyMap();
addTags(tags);
}
public void setTimestamp(final Date timestamp) {
this.timestamp = timestamp;
}
public void setTimestamp(final long timestamp) {
setTimestamp(new Date(timestamp));
}
public void setUid(final int uid) {
this.uid = uid;
}
public void setUser(final String user) {
this.user = user;
}
@Override
public boolean setValue(final FieldDefinition fieldDefinition, final Object value) {
final String propertyName = fieldDefinition.getName();
Property.setSimple(this, propertyName, value);
return true;
}
public void setVersion(final int version) {
this.version = version;
}
public void setVisible(final boolean visible) {
this.visible = visible;
}
}