/* * ContinuousTreeToKML.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.phylogeography.tools; import dr.app.util.Arguments; import jebl.evolution.io.NexusImporter; import jebl.evolution.io.TreeImporter; import jebl.evolution.io.ImportException; import jebl.evolution.trees.RootedTree; import java.io.*; /** * @author Philippe Lemey * @author Andrew Rambaut * @author Marc A. Suchard */ public class ContinuousTreeToKML { public static final String HELP = "help"; public static final String ANNOTATION = "annotation"; public static final String ALTITUDE = "altitude"; public static final String MRSD = "mrsd"; public static final String SLICES = "slices"; public static final String SLICEBW = "slicebw"; public static final String SLICEMIDPOINT = "slicemidpoint"; private static final String commandName = "continuous_tree_to_kml"; private static final PrintStream progressStream = System.out; public static final String[] falseTrue = new String[] {"false","true"}; public static void printUsage(Arguments arguments) { arguments.printUsage(commandName, "[<inputTree-file-name>] [<output-file-name>]"); //TODO: set this right progressStream.println(); progressStream.println(" Example: " + commandName + " input.tre output.kml"); progressStream.println(); } public static void main(String[] args) { double altitude = 0; // altitutude of the root of the 3D trees double mostRecentDate = 2010; // required to convert heights to calendar dates String coordinateLabel = "loc"; boolean makeTreeSlices = false; double[] sliceTimes = null; double treeSliceBranchWidth = 3; boolean showBranchAtMidPoint = false; // shows complete branch for slice if time is more recent than the branch's midpoint Arguments arguments = new Arguments( new Arguments.Option[]{ new Arguments.StringOption(ANNOTATION, "location annotation label", "specifies the label used for location coordinates annotation [default=location]"), new Arguments.RealOption(ALTITUDE,"specifies the altitude of the root of the 3D tree [default=no 3D tree]"), new Arguments.RealOption(MRSD,"specifies the most recent sampling data in fractional years to rescale time [default=2010]"), new Arguments.StringOption(SLICES,"time","specifies a slice time-list [default=none]"), new Arguments.StringOption(SLICEMIDPOINT, falseTrue, false, "shows complete branch for sliced tree if time is more recent than the branch's midpoint [default=false"), new Arguments.Option(HELP, "option to print this message") }); try { arguments.parseArguments(args); } catch (Arguments.ArgumentException ae) { progressStream.println(ae); printUsage(arguments); System.exit(1); } if (args.length == 0 || arguments.hasOption(HELP)) { printUsage(arguments); System.exit(0); } if (arguments.hasOption(MRSD)) { mostRecentDate = arguments.getRealOption(MRSD); } if (arguments.hasOption(ALTITUDE)) { altitude = arguments.getRealOption(ALTITUDE); } String annotationLabel = arguments.getStringOption(ANNOTATION); if (annotationLabel != null){ coordinateLabel = annotationLabel; } String sliceString = arguments.getStringOption(SLICES); if (sliceString != null) { makeTreeSlices = true; try{ sliceTimes = DiscreteTreeToKML.parseVariableLengthDoubleArray(sliceString); } catch (Arguments.ArgumentException ae){ System.err.println("error reading slice heights"); ae.printStackTrace(); return; } makeTreeSlices = true; } if (arguments.hasOption(SLICEBW)) { treeSliceBranchWidth = arguments.getRealOption(SLICEBW); } String midpointString = arguments.getStringOption(SLICEMIDPOINT); if (midpointString != null && midpointString.compareToIgnoreCase("true") == 0) { showBranchAtMidPoint = true; } final String[] args2 = arguments.getLeftoverArguments(); String inputFileName = null; String outputFileName = null; switch (args2.length) { case 0: printUsage(arguments); System.exit(1); case 1: inputFileName = args2[0]; outputFileName = inputFileName + ".kml"; break; case 2: inputFileName = args2[0]; outputFileName = args2[1]; break; default: { System.err.println("Unknown option: " + args2[2]); System.err.println(); printUsage(arguments); System.exit(1); } } RootedTree tree = null; try { TreeImporter importer = new NexusImporter(new FileReader(inputFileName)); tree = (RootedTree)importer.importNextTree(); } catch (ImportException e) { e.printStackTrace(); return; } catch (IOException e) { e.printStackTrace(); return; } ContinuousKML exporter = new ContinuousKML(tree, inputFileName, altitude, mostRecentDate, coordinateLabel); try { BufferedWriter out1 = new BufferedWriter(new FileWriter(outputFileName)); StringBuffer buffer = new StringBuffer(); //we write the general tree stuff, but when making slices we do not include everything in the buffer compilation exporter.writeTreeToKML(); if (makeTreeSlices) { for (int i = 0; i < sliceTimes.length; i++) { // System.out.println(sliceTimes[i]); exporter.writeTreeToKML(sliceTimes[i], treeSliceBranchWidth, showBranchAtMidPoint); } } exporter.compileBuffer(buffer,makeTreeSlices); out1.write(buffer.toString()); out1.close(); } catch (IOException e) { e.printStackTrace(); return; } } }