Subversion Repositories mkgmap

Rev

Rev 2641 | 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();
        }
}