package com.revolsys.record.io.format.openstreetmap.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import com.revolsys.geometry.model.Geometry;
import com.revolsys.geometry.model.LineString;
import com.revolsys.geometry.model.Point;
import com.revolsys.identifier.Identifier;
import com.revolsys.record.io.format.xml.StaxReader;
public class OsmWay extends OsmElement {
public OsmWay() {
}
public OsmWay(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,
final Geometry geometry) {
super(id, visible, version, changeset, timestamp, user, uid, tags);
setGeometryValue(geometry);
}
public OsmWay(final OsmDocument document, final StaxReader in) {
super(in);
final List<Point> points = new ArrayList<>();
while (in.skipToChildStartElements(WAY_XML_ELEMENTS)) {
final QName name = in.getName();
if (name.equals(TAG)) {
parseTag(in);
} else if (name.equals(ND)) {
parseNodRef(document, points, in);
} else {
in.skipSubTree();
}
}
setGeometry(points);
}
public OsmWay(final OsmElement element) {
super(element);
}
public OsmWay(final StaxReader in) {
super(in);
}
@Override
public Identifier getIdentifier() {
final long id = getId();
return new OsmWayIdentifier(id);
}
public boolean isArea() {
if ("yes".equals(getString("area"))) {
return true;
} else if (Arrays.asList("bare_rock", "fell", "glacier, landuse=grass", "grassland", "heath",
"mud", "scree", "sand", "scrub", "tree", "wetland", "wood").contains(getTag("natural"))) {
return true;
}
return false;
}
private void parseNodRef(final OsmDocument document, final List<Point> points,
final StaxReader in) {
final long nodeId = in.getLongAttribute(null, "ref");
final Point point = document.getNodePoint(nodeId);
if (point != null && !point.isEmpty()) {
points.add(point);
}
in.skipToEndElement(ND);
}
protected void setGeometry(final List<Point> points) {
Geometry geometry;
if (points.isEmpty()) {
geometry = OsmConstants.WGS84_2D.point();
} else if (points.size() == 1) {
geometry = points.get(0);
} else {
final LineString line = OsmConstants.WGS84_2D.lineString(points);
if (isArea() && line.isClosed()) {
geometry = OsmConstants.WGS84_2D.polygon(line);
} else {
geometry = line;
}
}
setGeometryValue(geometry);
}
}