/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2016 HydroloGIS (www.hydrologis.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.library.kml;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.TreeSet;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import android.content.Context;
import eu.geopaparazzi.library.database.DefaultHelperClasses;
import eu.geopaparazzi.library.database.GPLog;
import eu.geopaparazzi.library.database.IImagesDbHelper;
import eu.geopaparazzi.library.database.Image;
/**
* A kmz exporter for notes, logs and pics.
*
* @author Andrea Antonello (www.hydrologis.com)
*/
@SuppressWarnings("nls")
public class KmzExport {
private final File outputFile;
private String name;
/**
* Constructor.
*
* @param name a name for the kmz.
* @param outputFile the path in which to create the kmz.
*/
public KmzExport(String name, File outputFile) {
this.name = name;
this.outputFile = outputFile;
}
/**
* Export.
*
* @param context the context to use.
* @param kmlRepresenters the list of data representers.
* @throws Exception if something goes wrong.
*/
public void export(Context context, List<KmlRepresenter> kmlRepresenters) throws Exception {
if (name == null) {
name = "Geopaparazzi Export";
}
/*
* write the internal kml file
*/
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
stringBuilder.append("<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\"\n");
stringBuilder.append("xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n");
stringBuilder.append("<Document>\n");
stringBuilder.append("<name>");
stringBuilder.append(name);
stringBuilder.append("</name>\n");
addMarker(stringBuilder, "red-pushpin", "http://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png", 20, 2);
addMarker(stringBuilder, "yellow-pushpin", "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png", 20, 2);
addMarker(stringBuilder, "bookmark-icon", "http://maps.google.com/mapfiles/kml/pal4/icon39.png", 16, 16);
addMarker(stringBuilder, "camera-icon", "http://maps.google.com/mapfiles/kml/pal4/icon38.png", 16, 16);
addMarker(stringBuilder, "info-icon", "http://maps.google.com/mapfiles/kml/pal3/icon35.png", 16, 16);
for (KmlRepresenter kmlRepresenter : kmlRepresenters) {
try {
stringBuilder.append(kmlRepresenter.toKmlString());
} catch (Exception e) {
GPLog.error(this, e.getLocalizedMessage(), e);
e.printStackTrace();
}
}
stringBuilder.append("</Document>\n");
stringBuilder.append("</kml>\n");
byte[] kmlBytes = stringBuilder.toString().getBytes(Charset.forName("UTF-8"));
/*
* start adding the kml part
*/
FileOutputStream fos = new FileOutputStream(outputFile);
ZipOutputStream zos = new ZipOutputStream(fos);
CRC32 crc = new CRC32();
String kmlName = "kml.kml";
crc.update(kmlBytes);
ZipEntry entry = new ZipEntry(kmlName);
entry.setMethod(ZipEntry.STORED);
entry.setCompressedSize(kmlBytes.length);
entry.setSize(kmlBytes.length);
entry.setCrc(crc.getValue());
zos.putNextEntry(entry);
zos.write(kmlBytes);
/*
* now add all images
*/
IImagesDbHelper imagesDbHelper = DefaultHelperClasses.getDefaulfImageHelper();
TreeSet<String> addedImages = new TreeSet<String>();
for (KmlRepresenter kmlRepresenter : kmlRepresenters) {
if (kmlRepresenter.hasImages()) {
List<String> imageIds = kmlRepresenter.getImageIds();
for (String imageId : imageIds) {
long id = Long.parseLong(imageId);
Image image = imagesDbHelper.getImage(id);
String imageName = image.getName();
if (!addedImages.add(imageName)){
// don't add double images
continue;
}
byte[] imageData = imagesDbHelper.getImageData(id);
crc.reset();
crc.update(imageData);
ZipEntry imageEntry = new ZipEntry(imageName);
imageEntry.setMethod(ZipEntry.STORED);
imageEntry.setCompressedSize(imageData.length);
imageEntry.setSize(imageData.length);
imageEntry.setCrc(crc.getValue());
zos.putNextEntry(imageEntry);
zos.write(imageData);
}
}
}
zos.close();
}
private void addMarker(StringBuilder sb, String alias, String url, int x, int y) throws IOException {
sb.append("<Style id=\"" + alias + "\">\n");
sb.append("<IconStyle>\n");
sb.append("<scale>1.1</scale>\n");
sb.append("<Icon>\n");
sb.append("<href>" + url + "\n");
sb.append("</href>\n");
sb.append("</Icon>\n");
sb.append("<hotSpot x=\"" + x + "\" y=\"" + y + "\" xunits=\"pixels\" yunits=\"pixels\" />\n");
sb.append("</IconStyle>\n");
sb.append("<ListStyle>\n");
sb.append("</ListStyle>\n");
sb.append("</Style>\n");
}
}