Subversion Repositories display

Rev

Rev 314 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2011.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 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 test.display.check;

import uk.me.parabola.imgfmt.app.Label;
import uk.me.parabola.imgfmt.app.lbl.City;
import uk.me.parabola.imgfmt.app.lbl.Country;
import uk.me.parabola.imgfmt.app.lbl.Region;
import uk.me.parabola.imgfmt.app.map.MapReader;
import uk.me.parabola.imgfmt.app.net.RoadDef;
import uk.me.parabola.imgfmt.app.trergn.Point;
import uk.me.parabola.util.MultiHashMap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static test.display.check.Log.checkNotNull;
import static test.display.check.Log.error;

/**
 * Holds details of a particular map.
 * Mostly things read with the map reader.
 *
 * @author Steve Ratcliffe
 */

public class MapDetails {
        private final int mapId;
        private int mapIndex;
        private List<City> cities;
        private List<Country> countries;
        private List<Region> regions;
        private MultiHashMap<String, Street> streets = new MultiHashMap<String, Street>();
        private Map<Integer,String> labels;
    private Map<Integer, Point> pois = new HashMap<Integer, Point>();
        private int subHeaderOffset;

        public MapDetails(int mapId, int mapIndex) {
                this.mapId = mapId;
                this.mapIndex = mapIndex;
        }

        public void check() {
                checkCities();
                checkRegions();
        }

        private void checkRegions() {
                int number = 0;
                for (Region r : regions) {
                        if (number != 0) {
                                Country country = r.getCountry();
                                checkNotNull(country, "region %d: country null", number);
                        }
                        number++;
                }
        }

        private void checkCities() {
                int number = 0;
                for (City c : cities) {
                        number++;
                        checkNotNull(c, "City %d\n", number);
                        if (c.getLblOffset() == 0)
                                error("map %d: city %d: no name; index %d", mapIndex, number, c.getIndex());

                        if (c.getIndex() == 0)
                                error("map %d: city %d: index is zero; name=%s", mapIndex, number, c.getName());
                }
        }

        public void readMap(MapReader mapReader) {
                this.cities = mapReader.getCities();
                this.regions = mapReader.getRegions();
                this.countries = mapReader.getCountries();

                fetchCityNames(mapReader);

                labels = mapReader.getLabels();

                fetchStreets(mapReader);
        fetchPois(mapReader);
        }

        private void fetchStreets(MapReader mapReader) {
                List<RoadDef> roads = mapReader.getRoads();
                for (RoadDef rd : roads) {
                        Label[] names = rd.getLabels();
                        for (Label lbl : names) {
                                if (lbl == null)
                                        continue;
                                String name = lbl.getText();
                                City city = rd.getCity();

                                String cityName = null;
                                int rcn = 0;
                                if (city != null) {
                                        cityName = city.getName();
                                        rcn = city.getRegionCountryNumber();
                                }

                                Street street = new Street();
                                street.setName(name);
                                street.setMapIndex(mapIndex);
                                street.setCityName(cityName);
                                if (rcn != 0) {
                                        if ((rcn & 0x4000) == 0) {
                                                Region region = regions.get(rcn);
                                                street.setRegionName(region.getLabel().getText());
                                                Country country = region.getCountry();
                                                street.setCountryName(country.getLabel().getText());
                                        } else {
                                                // A country
                                                Country country = countries.get((rcn & 0x3fff));
                                                street.setCountryName(country.getLabel().getText());
                                        }
                                }

                                // do we need to clean the name first?
                                streets.add(name, street);
                        }
                }
        }

    private void fetchPois(MapReader mapReader) {
        List<Point> points = mapReader.pointsForLevel(0, MapReader.WITH_EXT_TYPE_DATA);
        for (Point p : points) {
            int key = (p.getSubdiv().getNumber() << 8) + p.getNumber();
            pois.put(key, p);
        }
    }

        private void fetchCityNames(MapReader mapReader) {
                Map<Integer, City> nameMap = new HashMap<Integer, City>();
                for (City c : cities) {
                        if (c.getLblOffset() == 0) {
                                int key = (c.getSubdivNumber()<<8) + (c.getPointIndex() & 0xff);
                                nameMap.put(key, c);
                        }
                }
                List<Point> points = mapReader.pointsForLevel(0, MapReader.WITHOUT_EXT_TYPE_DATA);
                for (Point p : points) {
                        int key = (p.getSubdiv().getNumber() << 8) + (p.getNumber() & 0xff);
                        City city = nameMap.get(key);
                        if (city != null) {
                                city.setLabel(p.getLabel());
                        }
                }
        }

        public City getCity(int localCityNum) {
                City city = cities.get(localCityNum - 1);
                assert city.getIndex() == localCityNum;
                return city;
        }

        public String getLabelText(int lbl) {
                return labels.get(lbl);
        }

        public int getCountryFromRegion(int n) {
                Region region = regions.get(n);
                Country country = region.getCountry();
                return country.getIndex();
        }

        public List<Street> getStreetsWithName(String name) {
                return streets.get(name);
        }

        public int getSubHeaderOffset() {
                return subHeaderOffset;
        }

        public void setSubHeaderOffset(int subHeaderOffset) {
                this.subHeaderOffset = subHeaderOffset;
        }

        public String getRegionName(int region) {
                if (region == 0)
                        return "";
                return regions.get(region).getLabel().getText();
        }

        public String getCountryName(int country) {
                if (country == 0)
                        return "";
                return countries.get(country).getLabel().getText();
        }

    public Point getPoint(int subdiv, int number) {
        int key = (subdiv << 8) + number;
        return pois.get(key);
    }
}