use of de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.ArrayListIter in project elki by elki-project.
the class KMLOutputHandler method writeOutlierResult.
private void writeOutlierResult(XMLStreamWriter xmlw, OutlierResult outlierResult, Database database) throws XMLStreamException {
Relation<PolygonsObject> polys = database.getRelation(TypeUtil.POLYGON_TYPE);
Relation<String> labels = DatabaseUtil.guessObjectLabelRepresentation(database);
xmlw.writeStartDocument();
xmlw.writeCharacters("\n");
xmlw.writeStartElement("kml");
xmlw.writeDefaultNamespace("http://earth.google.com/kml/2.2");
xmlw.writeStartElement("Document");
{
// TODO: can we automatically generate more helpful data here?
xmlw.writeStartElement("name");
xmlw.writeCharacters("ELKI KML output for " + outlierResult.getLongName());
// name
xmlw.writeEndElement();
writeNewlineOnDebug(xmlw);
// TODO: e.g. list the settings in the description?
xmlw.writeStartElement("description");
xmlw.writeCharacters("ELKI KML output for " + outlierResult.getLongName());
// description
xmlw.writeEndElement();
writeNewlineOnDebug(xmlw);
}
{
// TODO: generate styles from color scheme
for (int i = 0; i < NUMSTYLES; i++) {
Color col = getColorForValue(i / (NUMSTYLES - 1.0));
xmlw.writeStartElement("Style");
xmlw.writeAttribute("id", "s" + i);
writeNewlineOnDebug(xmlw);
{
xmlw.writeStartElement("LineStyle");
xmlw.writeStartElement("width");
xmlw.writeCharacters("0");
// width
xmlw.writeEndElement();
// LineStyle
xmlw.writeEndElement();
}
writeNewlineOnDebug(xmlw);
{
xmlw.writeStartElement("PolyStyle");
xmlw.writeStartElement("color");
// KML uses AABBGGRR format!
xmlw.writeCharacters(String.format("%02x%02x%02x%02x", col.getAlpha(), col.getBlue(), col.getGreen(), col.getRed()));
// color
xmlw.writeEndElement();
// out.writeStartElement("fill");
// out.writeCharacters("1"); // Default 1
// out.writeEndElement(); // fill
xmlw.writeStartElement("outline");
xmlw.writeCharacters("0");
// outline
xmlw.writeEndElement();
// PolyStyle
xmlw.writeEndElement();
}
writeNewlineOnDebug(xmlw);
// Style
xmlw.writeEndElement();
writeNewlineOnDebug(xmlw);
}
}
DoubleRelation scores = outlierResult.getScores();
Collection<Relation<?>> otherrel = new LinkedList<>(database.getRelations());
otherrel.remove(scores);
otherrel.remove(polys);
otherrel.remove(labels);
otherrel.remove(database.getRelation(TypeUtil.DBID));
ArrayModifiableDBIDs ids = DBIDUtil.newArray(scores.getDBIDs());
scaling.prepare(outlierResult);
for (DBIDIter iter = outlierResult.getOrdering().order(ids).iter(); iter.valid(); iter.advance()) {
double score = scores.doubleValue(iter);
PolygonsObject poly = polys.get(iter);
String label = labels.get(iter);
if (Double.isNaN(score)) {
LOG.warning("No score for object " + DBIDUtil.toString(iter));
}
if (poly == null) {
LOG.warning("No polygon for object " + DBIDUtil.toString(iter) + " - skipping.");
continue;
}
xmlw.writeStartElement("Placemark");
{
xmlw.writeStartElement("name");
xmlw.writeCharacters(score + " " + label);
// name
xmlw.writeEndElement();
StringBuilder buf = makeDescription(otherrel, iter);
xmlw.writeStartElement("description");
xmlw.writeCData("<div>" + buf.toString() + "</div>");
// description
xmlw.writeEndElement();
xmlw.writeStartElement("styleUrl");
int style = (int) (scaling.getScaled(score) * NUMSTYLES);
style = Math.max(0, Math.min(style, NUMSTYLES - 1));
xmlw.writeCharacters("#s" + style);
// styleUrl
xmlw.writeEndElement();
}
{
xmlw.writeStartElement("Polygon");
writeNewlineOnDebug(xmlw);
if (compat) {
xmlw.writeStartElement("altitudeMode");
xmlw.writeCharacters("relativeToGround");
// close altitude mode
xmlw.writeEndElement();
writeNewlineOnDebug(xmlw);
}
// First polygon clockwise?
boolean first = true;
for (Polygon p : poly.getPolygons()) {
if (first) {
xmlw.writeStartElement("outerBoundaryIs");
} else {
xmlw.writeStartElement("innerBoundaryIs");
}
xmlw.writeStartElement("LinearRing");
xmlw.writeStartElement("coordinates");
// Reverse anti-clockwise polygons.
boolean reverse = (p.testClockwise() >= 0);
ArrayListIter<double[]> it = p.iter();
if (reverse) {
it.seek(p.size() - 1);
}
while (it.valid()) {
double[] v = it.get();
xmlw.writeCharacters(FormatUtil.format(v, ","));
if (compat && (v.length == 2)) {
xmlw.writeCharacters(",50");
}
xmlw.writeCharacters(" ");
if (!reverse) {
it.advance();
} else {
it.retract();
}
}
// close coordinates
xmlw.writeEndElement();
// close LinearRing
xmlw.writeEndElement();
// close *BoundaryIs
xmlw.writeEndElement();
first = false;
}
writeNewlineOnDebug(xmlw);
// Polygon
xmlw.writeEndElement();
}
// Placemark
xmlw.writeEndElement();
writeNewlineOnDebug(xmlw);
}
// Document
xmlw.writeEndElement();
// kml
xmlw.writeEndElement();
xmlw.writeEndDocument();
}
Aggregations