StringTokenizer st = null;
String tok = null;
pushback = false;
int idx;
OMPoly omp = null;
OMLine oml = null;
MIFPoint ompoint = null;
OMText omtext = null;
boolean ismultiple = false;
OMGraphicList aList = new OMGraphicList();
// a vector of omgraphics for regions that allows adding and
// deleting
Vector omgs = new Vector();
MAIN_LOOP: while (true) {
if (!pushback) {
// if it's null then there's no more
if ((st = getTokens(br)) == null)
break MAIN_LOOP;
tok = st.nextToken();
} else {
pushback = false; // pushback was true so make it
// false so it doesn't happen twice
}
SWITCH: switch (action) {
case PROCESS_HEADER:
if (isSame(tok, DATA_WORD)) {
action = PROCESS_DATA;
} else if (isSame(tok, VERSION_WORD)) {
} else if (isSame(tok, DELIMITER_WORD)) {
} else if (isSame(tok, COORDSYS_WORD)) {
// check the CoordSys header, OpenMap only
// directly
// supports LatLong type of coordsys
String coordSysLine = COORDSYS_WORD;
while (st.hasMoreElements()) {
coordSysLine += " " + st.nextElement();
}
String goodCoordSys = COORDSYS_WORD + " "
+ LATLONG_COORDSYS_DEF;
if (goodCoordSys.length() < coordSysLine.length()) {
coordSysLine = coordSysLine.substring(0,
goodCoordSys.length());
} else {
goodCoordSys = goodCoordSys.substring(0,
coordSysLine.length());
}
// check that the CoordSys header matches the MIF
// specification for LatLong type
if (!isSame(coordSysLine, goodCoordSys)) {
Debug.error("MIFLoader file has coordinate system: "
+ coordSysLine + ", requires " + goodCoordSys);
// raise error, as the coordsys header was
// invalid
throw new MIFException("File appears to contain objects with an incompatible coordinate system (Must be Lat/Lon).");
}
}
break SWITCH;
case PROCESS_DATA:
omgs.clear();
if (isSame(tok, PLINE_WORD)) {
tok = st.nextToken();
if (isSame(tok, MULTIPLE_WORD)) {
multiple = Integer.parseInt(st.nextToken());
multicnt = 0;
action = PROCESS_MULTIPLE;
ismultiple = true;
} else {
number = Integer.parseInt(tok);
ptarray = new float[number + number];
count = 0;
action = PROCESS_PLINE;
}
} else if (isSame(tok, REGION_WORD)) {
multiple = Integer.parseInt(st.nextToken());
multicnt = 0;
action = PROCESS_REGION_HEADER;
} else if (isSame(tok, LINE_WORD)) {
float lon1 = Float.parseFloat(st.nextToken());
float lat1 = Float.parseFloat(st.nextToken());
float lon2 = Float.parseFloat(st.nextToken());
float lat2 = Float.parseFloat(st.nextToken());
oml = new OMLine(lat1, lon1, lat2, lon2, OMGraphicConstants.LINETYPE_STRAIGHT);
action = PROCESS_POST_LINE;
} else if (isSame(tok, POINT_WORD)) // handle a MIF
// POINT primitive
{
// get the coordinates
float lon1 = Float.parseFloat(st.nextToken());
float lat1 = Float.parseFloat(st.nextToken());
// construct the OM graphic
ompoint = new MIFPoint(lat1, lon1, pointVisible);
st = getTokens(br);
// set the graphics attributes
this.processSymbolWord(st, ompoint);
// add to the graphic list for this layer
aList.add(ompoint);
action = PROCESS_DATA;
} else if (isSame(tok, TEXT_WORD)) // handle a MIF
// TEXT primitive
{
String textString = "";
// if the actual text is not on the same line as
// the primitive declaration
if (st.countTokens() < 1) {
// get the next line
st = getTokens(br);
}
// build up the display text string,
while (st.hasMoreTokens()) {
textString += st.nextToken();
}
if (textString.length() >= 1) {
// remove any surrounding " characters
textString = textString.substring(1,
textString.length() - 1);
}
// get the next line, it contains the coordinates
st = getTokens(br);
float lon1 = Float.parseFloat(st.nextToken());
float lat1 = Float.parseFloat(st.nextToken());
/* float lon2 = */Float.parseFloat(st.nextToken());
/* float lat2 = */Float.parseFloat(st.nextToken());
// create the OMGraphic for the text object
omtext = new MIFText(lat1, lon1, textString, OMText.JUSTIFY_CENTER, textVisible);
// the next line contains the text attributes
st = getTokens(br);
// set the attributes agains the omgraphic
this.processFontWord(st, omtext);
// add to the layers graphic list
aList.add(omtext);
action = PROCESS_DATA;
}
break SWITCH;
// We have a line, tok is the first coord and the next
// token is the second
case PROCESS_PLINE:
idx = count + count;
ptarray[idx + 1] = Float.parseFloat(tok);
ptarray[idx] = Float.parseFloat(st.nextToken());
count++;
if (count == number) {
omp = new OMPoly(ptarray, OMGraphic.DECIMAL_DEGREES, OMGraphic.LINETYPE_STRAIGHT);
aList.add(omp);
if (!ismultiple) {
action = PROCESS_POST_PLINE;
} else {
omgs.add(omp);
action = PROCESS_MULTIPLE;
}
}
break SWITCH;
case PROCESS_MULTIPLE:
multicnt++;
if (multicnt > multiple) { // No more multiples so we
// can pushback
pushback = true;
multiple = 0;
action = PROCESS_POST_PLINE;
break SWITCH;
}
number = Integer.parseInt(tok);
count = 0;
ptarray = new float[number + number];
action = PROCESS_PLINE;
break SWITCH;
case PROCESS_POST_PLINE:
if (isSame(tok, PEN_WORD)) {
if (ismultiple) {
processPenWord(st, omgs);
} else {
processPenWord(st, omp);
}
} else if (isSame(tok, SMOOTH_WORD)) {
// Smooth unimplemented
} else {
ismultiple = false;
pushback = true;
action = PROCESS_DATA;
}
break SWITCH;
// SCN to support lines
case PROCESS_POST_LINE:
if (isSame(tok, PEN_WORD)) {
processPenWord(st, oml);
aList.add(oml);
} else {
ismultiple = false;
pushback = true;
action = PROCESS_DATA;
}
break SWITCH;
case PROCESS_REGION_HEADER: // This processes the number
// at the top of each region
// sub-block
multicnt++;
if (multicnt > multiple) {
multiple = 0;
action = PROCESS_POST_REGION;
// Add this point the region is finished so add
// the
// vector contents to list
int len = omgs.size();
for (int i = 0; i < len; i++) {
aList.add((OMGraphic) omgs.elementAt(i));
}
break SWITCH;
}
number = Integer.parseInt(tok);
count = 0;
ptarray = new float[number + number];
latpts = new float[number];
lonpts = new float[number];
action = PROCESS_REGION;
break SWITCH;
case PROCESS_REGION:
idx = count + count;
lonpts[count] = ptarray[idx + 1] = Float.parseFloat(tok);
latpts[count] = ptarray[idx] = Float.parseFloat(st.nextToken());
count++;
if (count == number) {
// This polygon is complete so add it and process
// the next
// Use this code if we just want polygons which is
// much
// faster
if (accurate) {
omgs.add(new OMSubtraction(latpts, lonpts));
} else {
// Produces accurate MapInfo type rendering
// but very
// slow with complex regions like streets
int end = latpts.length - 1;
for (int i = 0; i < end; i++) {
omgs.add(new OMLine(latpts[i], lonpts[i], latpts[i + 1], lonpts[i + 1], OMGraphic.LINETYPE_STRAIGHT));
}
omgs.add(new OMLine(latpts[end], lonpts[end], latpts[0], lonpts[0], OMGraphic.LINETYPE_STRAIGHT));
}
action = PROCESS_REGION_HEADER;
}
break SWITCH;