/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*
*
* Author: Steve Ratcliffe
* Create date: 02-Sep-2007
*/
package uk.me.parabola.mkgmap.general;
import java.util.Arrays;
import uk.me.parabola.imgfmt.ExitException;
/**
* Represents the mapping between the Garmin map levels and the built-in
* resolutions. The resolutions go from 1 to 24 and the levels start at 0 and
* are defined by the map maker. For each level you assign a resolution to it.
* The resolution for each level must be lower than that of the level below.
*
* As an example you might have the following level=resolution pairs:
* 0=24, 1=22, 2=20, 3=19.
*
* Note that level 0 is the most detailed level, whereas 24 is the most detailed
* resolution.
*
* The highest numbered level must be empty and cover the whole map.
*
* @author Steve Ratcliffe
*/
public class LevelInfo implements Comparable<LevelInfo> {
public static final String DEFAULT_LEVELS = "0:24, 1:22, 2:20, 3:18, 4:16";
private final int level;
private final int bits;
// Set if this is a top level, use this when the format is supplying its own
// top level.
private boolean top;
public LevelInfo(int level, int bits) {
this.level = level;
this.bits = bits;
}
/**
* Convert a string into an array of LevelInfo structures.
*/
public static LevelInfo[] createFromString(String levelSpec) {
String[] desc = levelSpec.split("[, \\t\\n]+");
LevelInfo[] levels = new LevelInfo[desc.length];
int count = 0;
for (String s : desc) {
String[] keyVal = s.split("[=:]");
if (keyVal == null || keyVal.length < 2) {
throw new ExitException("Error: incorrect level specification " + levelSpec);
}
try {
int key = Integer.parseInt(keyVal[0]);
if (key < 0 || key > 16)
throw new ExitException("Error: Level value out of range 0-16: " + s + " in levels specification " + levelSpec);
int value = Integer.parseInt(keyVal[1]);
if (value <= 0 || value > 24)
throw new ExitException("Error: Resolution value out of range 0-24: " + s + " in levels specification " + levelSpec);
levels[count] = new LevelInfo(key, value);
} catch (NumberFormatException e) {
throw new ExitException("Error: Levels specification not all numbers: " + levelSpec + " check " + s);
}
count++;
}
Arrays.sort(levels);
// If there are more than 8 levels the map can cause the
// garmin to crash.
if (levels.length > 8)
throw new ExitException("Too many levels, the maximum is 8");
return levels;
}
/**
* Returns a string representation of the object. In general, the
* <code>toString</code> method returns a string that
* "textually represents" this object.
*
* @return a string representation of the object.
*/
public String toString() {
return "L" + level + " B" + bits;
}
public int getLevel() {
return level;
}
public int getBits() {
return bits;
}
public boolean isTop() {
return top;
}
public void setTop(boolean top) {
this.top = top;
}
/**
* These things sort so that the highest level number is the lowest. OK
* so its a bit wierd.
*
* @param other The LevelInfo to compare to.
* @return Zero if they are equal and 1 if the object is greater and -1
* otherwise.
*/
public int compareTo(LevelInfo other) {
if (other.getLevel() == getLevel())
return 0;
if (other.getLevel() > getLevel())
return 1;
else
return -1;
}
}