use of de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject 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();
}
use of de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject in project elki by elki-project.
the class PolygonVisualization method processNewResult.
@SuppressWarnings("unchecked")
@Override
public void processNewResult(VisualizerContext context, Object result) {
VisualizationTree.findNewResultVis(context, result, Relation.class, ScatterPlotProjector.class, (rel, p) -> {
if (!TypeUtil.POLYGON_TYPE.isAssignableFromType(rel.getDataTypeInformation())) {
return;
}
if (RelationUtil.dimensionality((Relation<? extends PolygonsObject>) rel) != 2) {
return;
}
// Assume that a 2d projector is using the same coordinates as the
// polygons.
final VisualizationTask task = //
new VisualizationTask(this, NAME, rel, rel).level(//
VisualizationTask.LEVEL_DATA - 10).with(UpdateFlag.ON_DATA);
context.addVis(rel, task);
context.addVis(p, task);
});
}
use of de.lmu.ifi.dbs.elki.data.spatial.PolygonsObject in project elki by elki-project.
the class SimplePolygonParser method parseLine.
/**
* Parse a single line.
*
* @return {@code true} if the line was read successful.
*/
private boolean parseLine() {
cureid = null;
curpoly = null;
curlbl = null;
polys.clear();
coords.clear();
labels.clear();
Matcher m = COORD.matcher(reader.getBuffer());
for (; /* initialized by nextLineExceptComments */
tokenizer.valid(); tokenizer.advance()) {
m.region(tokenizer.getStart(), tokenizer.getEnd());
if (m.find()) {
try {
double c1 = ParseUtil.parseDouble(m.group(1));
double c2 = ParseUtil.parseDouble(m.group(2));
if (m.group(3) != null) {
double c3 = ParseUtil.parseDouble(m.group(3));
coords.add(new double[] { c1, c2, c3 });
} else {
coords.add(new double[] { c1, c2 });
}
continue;
} catch (NumberFormatException e) {
LOG.warning("Looked like a coordinate pair but didn't parse: " + tokenizer.getSubstring());
}
}
// Match polygon separator:
// FIXME: Avoid unnecessary subSequence call.
final int len = tokenizer.getEnd() - tokenizer.getStart();
if (//
POLYGON_SEPARATOR.length() == len && reader.getBuffer().subSequence(tokenizer.getStart(), tokenizer.getEnd()).equals(POLYGON_SEPARATOR)) {
if (!coords.isEmpty()) {
polys.add(new Polygon(new ArrayList<>(coords)));
}
continue;
}
String cur = tokenizer.getSubstring();
// First label will become the External ID
if (cureid == null) {
cureid = new ExternalID(cur);
} else {
labels.add(cur);
}
}
// Complete polygon
if (!coords.isEmpty()) {
polys.add(new Polygon(coords));
}
curpoly = new PolygonsObject(polys);
curlbl = (haslabels || !labels.isEmpty()) ? LabelList.make(labels) : null;
return true;
}
Aggregations