001 /*
002 * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package de.kumpe.hadooptimizer.examples.painting;
017
018 import static java.lang.String.*;
019
020 import java.io.IOException;
021 import java.io.OutputStream;
022 import java.util.Locale;
023
024 import javax.xml.parsers.DocumentBuilder;
025 import javax.xml.parsers.DocumentBuilderFactory;
026 import javax.xml.transform.Transformer;
027 import javax.xml.transform.TransformerException;
028 import javax.xml.transform.TransformerFactory;
029 import javax.xml.transform.dom.DOMSource;
030 import javax.xml.transform.stream.StreamResult;
031 import javax.xml.xpath.XPath;
032 import javax.xml.xpath.XPathConstants;
033 import javax.xml.xpath.XPathFactory;
034
035 import org.apache.hadoop.conf.Configuration;
036 import org.apache.hadoop.fs.FileSystem;
037 import org.apache.hadoop.fs.Path;
038 import org.apache.hadoop.io.LongWritable;
039 import org.apache.hadoop.io.ObjectWritable;
040 import org.apache.hadoop.io.SequenceFile;
041 import org.w3c.dom.Document;
042 import org.w3c.dom.Element;
043
044 /**
045 * TODO document!
046 *
047 * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a>
048 */
049 public class AnimationSvgRenderer {
050 public static void main(final String[] args) throws Exception {
051 new AnimationSvgRenderer().run();
052 }
053
054 private Element[] triangles;
055 private DOMSource source;
056 private Transformer transformer;
057 private StreamResult result;
058 private String outputPath;
059
060 protected void run() throws Exception {
061 // parse the result-template
062 final DocumentBuilder documentBuilder = DocumentBuilderFactory
063 .newInstance().newDocumentBuilder();
064 final Document document = documentBuilder.parse(getClass()
065 .getResourceAsStream("/ResultTemplate (Animation).svg"));
066
067 // extract necessary elements
068 final XPath xPath = XPathFactory.newInstance().newXPath();
069 final Element triangle = (Element) xPath.evaluate(
070 "//path[@id='dreieck']", document, XPathConstants.NODE);
071 triangle.removeAttribute("id");
072 final Element parent = (Element) triangle.getParentNode();
073 parent.removeChild(triangle);
074
075 // create 50 triangles
076 triangles = new Element[50];
077 for (int i = 0; i < triangles.length; i++) {
078 triangles[i] = (Element) triangle.cloneNode(false);
079 parent.appendChild(triangles[i]);
080 }
081
082 final Element zyklus = (Element) xPath.evaluate(
083 "//tspan[@id='zyklus']", document, XPathConstants.NODE);
084 final Element bewertung = (Element) xPath.evaluate(
085 "//tspan[@id='bewertung']", document, XPathConstants.NODE);
086 final Element geschwindigkeit = (Element) xPath
087 .evaluate("//tspan[@id='geschwindigkeit']", document,
088 XPathConstants.NODE);
089 final Element punkt = (Element) xPath.evaluate("//path[@id='punkt']",
090 document, XPathConstants.NODE);
091
092 final String transform = punkt.getAttribute("transform");
093 final String[] parts = transform.split(",|\\(|\\)");
094 final double ox = Double.parseDouble(parts[1]);
095 final double oy = Double.parseDouble(parts[2]);
096
097 // initialize the transformer for writing the SVG-output
098 source = new DOMSource(document);
099 result = new StreamResult();
100 transformer = TransformerFactory.newInstance().newTransformer();
101
102 outputPath = "/home/baumbart/KIT/Animation/";
103
104 // open input
105 final Configuration conf = new Configuration();
106 final Path inputPath = new Path(
107 "file:///home/baumbart/KIT/de.kumpe.hadooptimizer.examples.painting.SvgRenderer-20110423-173603/output/part-r-00000");
108 final FileSystem inputFileSystem = inputPath.getFileSystem(conf);
109 final SequenceFile.Reader reader = new SequenceFile.Reader(
110 inputFileSystem, inputPath, conf);
111
112 final LongWritable key = new LongWritable();
113 final ObjectWritable value = new ObjectWritable();
114 while (reader.next(key, value)) {
115 final double[] values = (double[]) value.get();
116 final long cycle = (long) values[0];
117 System.out.println(cycle);
118 zyklus.setTextContent(String.format("Zyklus: %,d", cycle));
119 bewertung.setTextContent(String
120 .format("Bewertung: %.2f", values[3]));
121 geschwindigkeit.setTextContent("");
122
123 punkt.setAttribute(
124 "transform",
125 String.format(Locale.ENGLISH, "translate(%f,%f)", ox
126 + cycle * 550.541 / 1500000, oy - values[3] / 140
127 * 323.140));
128
129 configureTriangles(values);
130 writeSvgResultDocument(cycle);
131 }
132
133 }
134
135 private void configureTriangles(final double[] values) {
136 for (int i = 0; i < triangles.length; i++) {
137 // extract and clip the values
138 final double opacity = clip(values[7 * i + 5 + 0] / 312, 0, 1);
139 final double x1 = clip(values[7 * i + 5 + 1], 0, 312);
140 final double y1 = clip(values[7 * i + 5 + 2], 0, 312);
141 final double x2 = clip(values[7 * i + 5 + 3], 0, 312);
142 final double y2 = clip(values[7 * i + 5 + 4], 0, 312);
143 final double x3 = clip(values[7 * i + 5 + 5], 0, 312);
144 final double y3 = clip(values[7 * i + 5 + 6], 0, 312);
145
146 // set the coordinates
147 triangles[i].setAttribute(
148 "d",
149 format(Locale.US, "M %f,%f %f,%f %f,%f %1$f,%2$f z", x1,
150 y1, x2, y2, x3, y3));
151
152 // set the opacity
153 triangles[i]
154 .setAttribute(
155 "style",
156 format(Locale.US,
157 "fill:#000000;stroke:#00ffff;stroke-width:0.1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:0.75;fill-opacity:%f",
158 opacity));
159 }
160 }
161
162 private void writeSvgResultDocument(final long cycle) throws IOException {
163 // create the SVG-file
164 final Path outputPath = new Path(format("%s/result%06d.svg",
165 this.outputPath, cycle));
166 final FileSystem fileSystem = outputPath
167 .getFileSystem(new Configuration());
168 final OutputStream outputStream = fileSystem.create(outputPath);
169 result.setOutputStream(outputStream);
170
171 try {
172 // write the SVG-file
173 transformer.transform(source, result);
174 } catch (final TransformerException e) {
175 throw new RuntimeException(e);
176 }
177
178 outputStream.close();
179 }
180
181 private double clip(final double value, final double min, final double max) {
182 final double diff = max - min;
183 return Math.abs(Math.abs(value % (diff * 2)) - diff) + min;
184 }
185 }