package me.osm.gazetter.striper.readers; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import me.osm.gazetter.striper.readers.RelationsReader.Relation.RelationMember; import me.osm.gazetter.striper.readers.RelationsReader.Relation.RelationMember.ReferenceType; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class RelationsReader extends DefaultHandler { private static final String TAG_NAME = "relation"; private RelationsHandler[] handlers; private HashSet<String> drop; public static class Relation { public long id; public List<RelationMember> members = new ArrayList<>(); public Map<String, String> tags = new HashMap<>(); public static class RelationMember { public long ref; public String role; public ReferenceType type; public static enum ReferenceType { NODE, WAY, RELATION } } } public static interface RelationsHandler { void handle(Relation rel); } public RelationsReader(HashSet<String> drop){ this.drop = drop; }; private Relation relation = null; public void read(InputStream is, RelationsHandler... handlers) { this.handlers = handlers; try { SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); saxParser.parse(is, this); } catch (Exception e) { throw new RuntimeException("Parsing failed for: " + is, e); } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals(TAG_NAME)) { this.relation = new Relation(); this.relation.id = Long.valueOf(attributes.getValue("id")); } if(qName.equals("member") && this.relation != null) { RelationMember m = new RelationMember(); m.ref = Long.valueOf(attributes.getValue("ref")); m.type = ReferenceType.valueOf(attributes.getValue("type").toUpperCase()); if(!attributes.getValue("role").isEmpty()) { m.role = attributes.getValue("role"); } this.relation.members.add(m); } if(qName.equals("tag") && this.relation != null) { this.relation.tags.put(attributes.getValue("k"), attributes.getValue("v")); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.equals(TAG_NAME)) { if(!drop(this.relation)) { for(RelationsHandler handler : handlers) { handler.handle(this.relation); } } this.relation = null; } } private final boolean drop(Relation rel) { return !this.drop.isEmpty() && this.drop.contains("r" + rel.id); } }