Rev 3408 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2009.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* 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.
*/
package uk.me.parabola.imgfmt.app.map;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.Area;
import uk.me.parabola.imgfmt.app.lbl.City;
import uk.me.parabola.imgfmt.app.lbl.Country;
import uk.me.parabola.imgfmt.app.lbl.LBLFileReader;
import uk.me.parabola.imgfmt.app.lbl.Region;
import uk.me.parabola.imgfmt.app.lbl.Zip;
import uk.me.parabola.imgfmt.app.net.NETFileReader;
import uk.me.parabola.imgfmt.app.net.RoadDef;
import uk.me.parabola.imgfmt.app.trergn.Point;
import uk.me.parabola.imgfmt.app.trergn.Polygon;
import uk.me.parabola.imgfmt.app.trergn.Polyline;
import uk.me.parabola.imgfmt.app.trergn.RGNFileReader;
import uk.me.parabola.imgfmt.app.trergn.Subdivision;
import uk.me.parabola.imgfmt.app.trergn.TREFileReader;
import uk.me.parabola.imgfmt.app.trergn.Zoom;
import uk.me.parabola.imgfmt.fs.DirectoryEntry;
import uk.me.parabola.imgfmt.fs.FileSystem;
import uk.me.parabola.imgfmt.fs.ImgChannel;
import uk.me.parabola.imgfmt.sys.ImgFS;
/**
* This is a view of a .img file when we are reading it. The {@link Map}
* class is the equivalent for writing.
*
* @author Steve Ratcliffe
*/
public class MapReader
implements Closeable {
private final TREFileReader treFile
;
private final RGNFileReader rgnFile
;
private final LBLFileReader lblFile
;
private final NETFileReader netFile
;
public static final boolean WITH_EXT_TYPE_DATA =
true;
public static final boolean WITHOUT_EXT_TYPE_DATA =
false;
private final Deque
<Closeable> toClose =
new ArrayDeque
<Closeable>();
public MapReader
(String filename
) throws FileNotFoundException {
FileSystem fs = ImgFS.
openFs(filename
);
saveForClose
(fs
);
List<DirectoryEntry
> entries = fs.
list();
// Find the TRE entry
String mapname =
null;
for (DirectoryEntry ent : entries
) {
if ("TRE".
equals(ent.
getExt())) {
mapname = ent.
getName();
break;
}
}
if (mapname ==
null)
throw new FileNotFoundException("No TRE entry in img file");
ImgChannel chan = fs.
open(mapname +
".TRE",
"r");
treFile =
new TREFileReader
(chan
);
saveForClose
(treFile, chan
);
chan = fs.
open(mapname +
".RGN",
"r");
rgnFile =
new RGNFileReader
(chan
);
saveForClose
(rgnFile, chan
);
chan = fs.
open(mapname +
".LBL",
"r");
lblFile =
new LBLFileReader
(chan
);
saveForClose
(lblFile, chan
);
// The NET file is optional
NETFileReader nr
;
try {
chan = fs.
open(mapname +
".NET",
"r");
nr =
new NETFileReader
(chan
);
nr.
setLabels(lblFile
);
nr.
setCities(lblFile.
getCities());
nr.
setZips(lblFile.
getZips());
saveForClose
(nr
);
} catch (FileNotFoundException e
) {
nr =
null;
}
netFile = nr
;
rgnFile.
setNetFile(netFile
);
rgnFile.
setLblFile(lblFile
);
}
/**
* Get a list of all the points for a given level.
* @param level The level, lower numbers are the most detailed.
*/
public List<Point> pointsForLevel
(int level,
boolean withExtType
) {
List<Point> points =
new ArrayList<Point>();
Subdivision
[] subdivisions = treFile.
subdivForLevel(level
);
for (Subdivision sd : subdivisions
) {
List<Point> subdivPoints = rgnFile.
pointsForSubdiv(sd, withExtType
);
points.
addAll(subdivPoints
);
}
return points
;
}
public Zoom
[] getLevels
() {
return treFile.
getMapLevels();
}
public String[] getCopyrights
(){
return treFile.
getCopyrights(lblFile
);
}
/**
* Get a list of all the lines for a given level.
* @param level The level, lower numbers are the most detailed.
*/
public List<Polyline
> linesForLevel
(int level
) {
ArrayList<Polyline
> lines =
new ArrayList<Polyline
>();
Subdivision
[] subdivisions = treFile.
subdivForLevel(level
);
for (Subdivision div : subdivisions
) {
List<Polyline
> subdivLines = rgnFile.
linesForSubdiv(div
);
lines.
addAll(subdivLines
);
}
return lines
;
}
public List<Polygon> shapesForLevel
(int level
) {
ArrayList<Polygon> shapes =
new ArrayList<Polygon>();
Subdivision
[] subdivisions = treFile.
subdivForLevel(level
);
for (Subdivision div : subdivisions
) {
List<Polygon> subdivShapes = rgnFile.
shapesForSubdiv(div
);
shapes.
addAll(subdivShapes
);
}
return shapes
;
}
public void close
() throws IOException {
for (Closeable c : toClose
)
Utils.
closeFile(c
);
}
private void saveForClose
(Closeable c1,
Closeable c2
) {
saveForClose
(c1
);
saveForClose
(c2
);
}
private void saveForClose
(Closeable c
) {
toClose.
push(c
);
}
public List<City
> getCities
() {
return lblFile.
getCities();
}
public List<Country
> getCountries
() {
return lblFile.
getCountries();
}
public List<Region> getRegions
() {
return lblFile.
getRegions();
}
public List<Zip
> getZips
() {
// need to be joined with zip information from the addresses
// where are the addresses stored?
return lblFile.
getZips();
}
public Area getTreBounds
() {
return treFile.
getBounds();
}
public java.
util.
Map<Integer,
String> getLabels
() {
return lblFile.
getLabels();
}
public List<RoadDef
> getRoads
() {
if (netFile ==
null)
return Collections.
emptyList();
return netFile.
getRoads();
}
public int getEncodingType
(){
return lblFile.
getEncodingType();
}
}