/* Copyright (c) 2013-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Victor Olaya (Boundless) - initial implementation
*/
package org.locationtech.geogig.osm.internal.history;
import static javax.xml.stream.XMLStreamConstants.END_DOCUMENT;
import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
import java.io.InputStream;
import javax.annotation.Nullable;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.vividsolutions.jts.geom.Envelope;
/**
* Example changeset:
*
* <pre>
* <code>
* <?xml version="1.0" encoding="UTF-8"?>
* <osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
* <changeset id="1100" user="BMO_2009" uid="26" created_at="2009-10-10T20:02:09Z" closed_at="2009-10-10T20:02:21Z" open="false" min_lat="48.4031818" min_lon="-4.4631203" max_lat="48.4058698" max_lon="-4.4589401">
* <tag k="created_by" v="bulk_upload.py/17742 Python/2.5.2"/>
* <tag k="comment" v="second test upload of BMO data - see http://wiki.openstreetmap.org/wiki/BMO"/>
* </changeset>
* </osm>
* </code>
* </pre>
*/
class ChangesetScanner {
private XMLStreamReader reader;
public ChangesetScanner(InputStream changesetStream) throws XMLStreamException,
FactoryConfigurationError {
this.reader = XMLInputFactory.newFactory().createXMLStreamReader(changesetStream, "UTF-8");
reader.nextTag();
reader.require(START_ELEMENT, null, "osm");
reader.nextTag();
}
@Nullable
public Changeset parseNext() throws XMLStreamException {
if (reader.getEventType() == END_ELEMENT && reader.getLocalName().equals("osm")) {
return null;
}
Changeset changeset = parse(reader);
return changeset;
}
/**
* Example changeset:
*
* <pre>
* <code>
* <?xml version="1.0" encoding="UTF-8"?>
* <osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
* <changeset id="1100" user="BMO_2009" uid="26" created_at="2009-10-10T20:02:09Z" closed_at="2009-10-10T20:02:21Z" open="false" min_lat="48.4031818" min_lon="-4.4631203" max_lat="48.4058698" max_lon="-4.4589401">
* <tag k="created_by" v="bulk_upload.py/17742 Python/2.5.2"/>
* <tag k="comment" v="second test upload of BMO data - see http://wiki.openstreetmap.org/wiki/BMO"/>
* </changeset>
* </osm>
* </code>
* </pre>
*/
private Changeset parse(XMLStreamReader reader) throws XMLStreamException {
reader.require(START_ELEMENT, null, "changeset");
Changeset changeset = new Changeset();
changeset.setId(Long.valueOf(reader.getAttributeValue(null, "id")));
changeset.setUserName(reader.getAttributeValue(null, "user"));
String uid = reader.getAttributeValue(null, "uid");
if (uid != null) {
changeset.setUserId(Long.valueOf(uid));
}
changeset.setOpen(Boolean.valueOf(reader.getAttributeValue(null, "open")));
changeset.setCreated(ParsingUtils.parseDateTime(reader
.getAttributeValue(null, "created_at")));
if (!changeset.isOpen()) {
changeset.setClosed(ParsingUtils.parseDateTime(reader.getAttributeValue(null,
"closed_at")));
}
changeset.setWgs84Bounds(parseWGS84Bounds(reader));
while (true) {
int tag = reader.next();
if (tag == END_ELEMENT) {
String tagName = reader.getLocalName();
if (tagName.equals("changeset")) {
break;
}
} else if (tag == START_ELEMENT) {
String tagName = reader.getLocalName();
if ("tag".equals(tagName)) {
String key = reader.getAttributeValue(null, "k");
String value = reader.getAttributeValue(null, "v");
if ("comment".equals(key)) {
changeset.setComment(value);
} else if (key != null && value != null) {
changeset.getTags().put(key, value);
}
}
} else if (tag == END_DOCUMENT) {
throw new IllegalStateException("premature end of document");
}
}
reader.require(END_ELEMENT, null, "changeset");
reader.nextTag();
return changeset;
}
/**
* Extracts bounds from:
*
* <pre>
* <code>
* <changeset min_lat="48.4031818" min_lon="-4.4631203" max_lat="48.4058698" max_lon="-4.4589401">
* </code>
* </pre>
*/
private static @Nullable Envelope parseWGS84Bounds(XMLStreamReader reader) {
String minLat = reader.getAttributeValue(null, "min_lat");
String minLon = reader.getAttributeValue(null, "min_lon");
String maxLat = reader.getAttributeValue(null, "max_lat");
String maxLon = reader.getAttributeValue(null, "max_lon");
if (minLat == null || minLon == null || maxLat == null || maxLon == null) {
return null;
}
return ParsingUtils.parseWGS84Bounds(minLat, minLon, maxLat, maxLon);
}
}