// License: GPL. For details, see LICENSE file.
package relcontext.relationfix;
import static org.openstreetmap.josm.tools.I18n.tr;
import org.openstreetmap.josm.command.ChangeCommand;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.RelationMember;
/**
* @see http://wiki.openstreetmap.org/wiki/Relation:boundary
*/
public class BoundaryFixer extends MultipolygonFixer {
public BoundaryFixer() {
super("boundary", "multipolygon");
}
/**
* For boundary relations both "boundary" and "multipolygon" types are applicable, but
* it should also have key boundary=administrative to be fully boundary.
* @see http://wiki.openstreetmap.org/wiki/Relation:boundary
*/
@Override
public boolean isFixerApplicable(Relation rel) {
return super.isFixerApplicable(rel) && "administrative".equals(rel.get("boundary"));
}
@Override
public boolean isRelationGood(Relation rel) {
for (RelationMember m : rel.getMembers()) {
if (m.getType().equals(OsmPrimitiveType.RELATION) && !"subarea".equals(m.getRole())) {
setWarningMessage(tr("Relation without ''subarea'' role found"));
return false;
}
if (m.getType().equals(OsmPrimitiveType.NODE) && !("label".equals(m.getRole()) || "admin_centre".equals(m.getRole()))) {
setWarningMessage(tr("Node without ''label'' or ''admin_centre'' role found"));
return false;
}
if (m.getType().equals(OsmPrimitiveType.WAY) && !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) {
setWarningMessage(tr("Way without ''inner'' or ''outer'' role found"));
return false;
}
}
clearWarningMessage();
return true;
}
@Override
public Command fixRelation(Relation rel) {
Relation r = rel;
Relation rr = fixMultipolygonRoles(r);
boolean fixed = false;
if (rr != null) {
fixed = true;
r = rr;
}
rr = fixBoundaryRoles(r);
if (rr != null) {
fixed = true;
r = rr;
}
return fixed ? new ChangeCommand(rel, r) : null;
}
private Relation fixBoundaryRoles(Relation source) {
Relation r = new Relation(source);
boolean fixed = false;
for (int i = 0; i < r.getMembersCount(); i++) {
RelationMember m = r.getMember(i);
String role = null;
if (m.isRelation()) {
role = "subarea";
} else if (m.isNode()) {
Node n = (Node) m.getMember();
if (!n.isIncomplete()) {
if (n.hasKey("place")) {
String place = n.get("place");
if (place.equals("state") || place.equals("country") ||
place.equals("county") || place.equals("region")) {
role = "label";
} else {
role = "admin_centre";
}
} else {
role = "label";
}
}
}
if (role != null && !role.equals(m.getRole())) {
r.setMember(i, new RelationMember(role, m.getMember()));
fixed = true;
}
}
return fixed ? r : null;
}
}