MATSIM
KMZWriter.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * KMZWriter.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.vis.kml;
22 
23 import java.io.BufferedWriter;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStreamWriter;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipOutputStream;
33 
34 import javax.xml.bind.JAXBContext;
35 import javax.xml.bind.JAXBException;
36 import javax.xml.bind.Marshaller;
37 
38 import org.apache.log4j.Level;
39 import org.apache.log4j.Logger;
41 
42 import net.opengis.kml.v_2_2_0.KmlType;
43 import net.opengis.kml.v_2_2_0.LinkType;
44 import net.opengis.kml.v_2_2_0.NetworkLinkType;
45 import net.opengis.kml.v_2_2_0.ObjectFactory;
46 
55 public class KMZWriter implements MatsimSomeWriter {
56 
57  private static final Logger log = Logger.getLogger(KMZWriter.class);
58 
59  private BufferedWriter out = null;
60 
61  private ZipOutputStream zipOut = null;
62 
63  private final Map<String, String> nonKmlFiles = new HashMap<String, String>();
64 
65  private final static Marshaller marshaller;
66 
67  private final static ObjectFactory kmlObjectFactory = new ObjectFactory();
68 
69  static {
70  try {
71  JAXBContext jaxbContext = JAXBContext.newInstance("net.opengis.kml.v_2_2_0");
72  marshaller = jaxbContext.createMarshaller();
73  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
74  } catch (JAXBException e) {
75  throw new RuntimeException(e);
76  }
77  }
78 
85  public KMZWriter(final String outFilename) {
86  log.setLevel( Level.INFO ) ;
87 
88  String filename = outFilename;
89  if (filename.endsWith(".kml") || filename.endsWith(".kmz")) {
90  filename = filename.substring(0, filename.length() - 4);
91  }
92 
93  try {
94  this.zipOut = new ZipOutputStream(new FileOutputStream(filename + ".kmz"));
95  this.out = new BufferedWriter(new OutputStreamWriter(this.zipOut, "UTF8"));
96  } catch (IOException e) {
97  e.printStackTrace();
98  }
99 
100  // generate the first KML entry in the zip file that links to the (later
101  // added) main-KML.
102  // this is required as GoogleEarth will only display the first-added KML in
103  // a kmz.
104  KmlType docKML = kmlObjectFactory.createKmlType();
105  NetworkLinkType nl = kmlObjectFactory.createNetworkLinkType();
106 
107  LinkType link = kmlObjectFactory.createLinkType();
108  link.setHref("main.kml");
109  nl.setLink(link);
110  docKML.setAbstractFeatureGroup(kmlObjectFactory.createNetworkLink(nl));
111 
112  writeKml("doc.kml", docKML);
113  }
114 
125  public void writeLinkedKml(final String filename, final KmlType kml) {
126  if (filename.equals("doc.kml")) {
127  throw new IllegalArgumentException(
128  "The filename 'doc.kml' is reserved for the primary kml.");
129  }
130  if (filename.equals("main.kml")) {
131  throw new IllegalArgumentException(
132  "The filename 'main.kml' is reserved for the main kml.");
133  }
134  writeKml(filename, kml);
135  }
136 
146  public void writeMainKml(final KmlType kml) {
147  writeKml("main.kml", kml);
148  }
149 
153  public void close() {
154  try {
155  this.out.close();
156  } catch (IOException e) {
157  e.printStackTrace();
158  }
159  }
160 
168  public void addNonKMLFile(final String filename, final String inZipFilename) throws IOException {
169  if (this.nonKmlFiles.containsKey(filename) && (inZipFilename.compareTo(this.nonKmlFiles.get(filename)) == 0)) {
170  log.warn("File: " + filename + " is already included in the kmz as " + inZipFilename);
171  return;
172  }
173  this.nonKmlFiles.put(filename, inZipFilename);
174  FileInputStream fis = new FileInputStream(filename);
175  try {
176  addNonKMLFile(fis, inZipFilename);
177  } finally {
178  fis.close();
179  }
180  }
181 
189  public void addNonKMLFile(final InputStream data, final String inZipFilename) throws IOException {
190  try {
191  // Allocate a buffer for reading the input files.
192  byte[] buffer = new byte[4096];
193  int bytesRead;
194  // Create a zip entry and add it to the zip.
195  ZipEntry entry = new ZipEntry(inZipFilename);
196  this.zipOut.putNextEntry(entry);
197 
198  // Read the file the file and write it to the zip.
199  while ((bytesRead = data.read(buffer)) != -1) {
200  this.zipOut.write(buffer, 0, bytesRead);
201  }
202  log.debug(entry.getName() + " added to kmz.");
203  } finally {
204  data.close();
205  }
206  }
207 
214  public void addNonKMLFile(final byte[] data, final String inZipFilename) throws IOException {
215  // Create a zip entry and add it to the zip.
216  ZipEntry entry = new ZipEntry(inZipFilename);
217  this.zipOut.putNextEntry(entry);
218  this.zipOut.write(data);
219  log.debug(entry.getName() + " added to kmz.");
220  }
221 
228  private void writeKml(final String filename, final KmlType kml) {
229  try {
230  ZipEntry ze = new ZipEntry(filename);
231  ze.setMethod(ZipEntry.DEFLATED);
232  this.zipOut.putNextEntry(ze);
233 
234  try {
235  marshaller.marshal(kmlObjectFactory.createKml(kml), out);
236  } catch (JAXBException e) {
237  e.printStackTrace();
238  }
239 
240  this.out.flush();
241 
242  } catch (IOException e) {
243  e.printStackTrace();
244  }
245  }
246 
247 }
final Map< String, String > nonKmlFiles
Definition: KMZWriter.java:63
void addNonKMLFile(final InputStream data, final String inZipFilename)
Definition: KMZWriter.java:189
void writeLinkedKml(final String filename, final KmlType kml)
Definition: KMZWriter.java:125
void writeKml(final String filename, final KmlType kml)
Definition: KMZWriter.java:228
static final Logger log
Definition: KMZWriter.java:57
void writeMainKml(final KmlType kml)
Definition: KMZWriter.java:146
KMZWriter(final String outFilename)
Definition: KMZWriter.java:85
static final ObjectFactory kmlObjectFactory
Definition: KMZWriter.java:67
static final Marshaller marshaller
Definition: KMZWriter.java:65
void addNonKMLFile(final byte[] data, final String inZipFilename)
Definition: KMZWriter.java:214
void addNonKMLFile(final String filename, final String inZipFilename)
Definition: KMZWriter.java:168