package edu.colostate.vchill.map;
import edu.colostate.vchill.Loader;
import edu.colostate.vchill.LocationManager;
import edu.colostate.vchill.ViewUtil;
import edu.colostate.vchill.map.MapInstruction.Shape;
import java.io.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
/**
* Parser for old-style map definition files.
*
* @author Jochen Deyke
* @version 2007-08-20
*/
public class MapTextParser {
private static final LocationManager lm = LocationManager.getInstance();
private double centerLatitude;
private double centerLongitude;
public MapTextParser() {
}
/**
* Parses a reader for map information
*
* @param reader The reader to parse
* @param base A base map to add to (optional)
* @return a List of instructions for drawing the map
* @throws IOException if an error is encountered while parsing
*/
public List<MapInstruction> parse(final Reader reader,
final List<MapInstruction> base) throws IOException {
{ //reset center
this.centerLongitude = lm.getLongitude();
this.centerLatitude = lm.getLatitude();
}
BufferedReader file = new BufferedReader(reader);
List<MapInstruction> result = (base == null ? new LinkedList<MapInstruction>() : base);
MapInstruction prevInstr = null;
while (file.ready()) {
String line = file.readLine();
if (line == null) break;
if (line.startsWith("\ufeff")) line = line.substring(1);
line = line.trim();
if (line.length() < 1) continue; //blank line
if (line.startsWith("#")) { //whole-line comment
line = line.substring(1);
if (line.startsWith("! center: ")) {
line = line.substring(10); //strip header
String[] tmp = line.split("[ \t]++");
this.centerLongitude = Double.parseDouble(tmp[0]);
this.centerLatitude = Double.parseDouble(tmp[1]);
}
} else { //<x y type [label]> format
String[] tmp = line.split("[ \t]++");
StringBuilder commentBuffer = new StringBuilder();
if (tmp.length > 3) { //end-of-line label
for (int i = 3; i < tmp.length; ++i) {
if (tmp[i].startsWith("#")) break; //comment mark; end of label
commentBuffer.append(tmp[i]).append(" ");
}
}
if (prevInstr != null && prevInstr.getType() == Shape.CIRCLE) { //radius - don't modify
result.add(prevInstr = new MapInstruction(
Double.parseDouble(tmp[0]),
Double.parseDouble(tmp[1]),
Shape.values()[Integer.parseInt(tmp[2])],
commentBuffer.toString().trim()));
} else {
double[] degrees = ViewUtil.getDegrees(Double.parseDouble(tmp[0]), Double.parseDouble(tmp[1]), this.centerLongitude, this.centerLatitude);
result.add(prevInstr = new MapInstruction(
degrees[0], degrees[1],
Shape.values()[Integer.parseInt(tmp[2])],
commentBuffer.toString().trim()));
}
}
} //end while
return result;
}
/**
* Parses a file for map information. If the specified file does not exist in the
* resource jar file, it is loaded from the local filesystem instead.
*
* @param filename The file to parse
* @param base A base map to add to (optional)
* @return a List of instructions for drawing the map
* @throws IOException if an error is encountered while parsing
*/
public List<MapInstruction> parse(final String filename,
final List<MapInstruction> base) throws IOException {
File file = new File(filename);
ClassLoader cl = Loader.class.getClassLoader();
JarInputStream jarIn = new JarInputStream(cl.getResourceAsStream("maps.jar"));
while (true) {
ZipEntry entry = jarIn.getNextEntry();
if (entry == null)
return parse(new InputStreamReader(new FileInputStream(file), "UTF-8"), base); //end of resource jar: file not found
if (entry.getName().equals(filename)) break;
}
return parse(new InputStreamReader(jarIn), base);
}
public static List<String> getListOfFiles() {
try {
ClassLoader cl = Loader.class.getClassLoader();
JarInputStream jarIn = new JarInputStream(cl.getResourceAsStream("maps.jar"));
LinkedList<String> names = new LinkedList<String>();
while (jarIn.available() > 0) {
ZipEntry entry = jarIn.getNextEntry();
if (entry == null) break;
String name = entry.getName();
if (name.endsWith(".map")) names.add(name);
}
return Collections.unmodifiableList(names);
} catch (Exception e) {
e.printStackTrace();
return Collections.unmodifiableList(new LinkedList<String>());
}
}
/**
* Filter for map files for the file open dialog
*/
public static class MapFileFilter implements FileFilter {
/**
* Accept only files ending in ".map"
*/
public boolean accept(final File pathname) {
if (pathname.isDirectory()) return false;
if (pathname.getName().endsWith(".map")) return true;
return false;
}
}
}