Subversion Repositories display

Rev

Rev 471 | 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 java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.imgfmt.app.trergn.Polygon;
import uk.me.parabola.util.MultiHashMap;

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 int mapIndex;
        private List<City> cities;
        private List<Country> countries;
        private List<Region> regions;
        private MultiHashMap<String, Street> streets = new MultiHashMap<>();
        private Map<Integer,String> labels;
    private Map<Integer, Point> pois = new HashMap<>();
    private Map<Integer, Map<Integer,Polygon>> namedPolygons = new HashMap<>();
        private int subHeaderOffset;

        public MapDetails(int mapIndex) {
                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);
        fetchNamedPolygons(mapReader);
        }

        private void fetchStreets(MapReader mapReader) {
                List<RoadDef> roads = mapReader.getRoads();
                for (RoadDef rd : roads) {
                        List<City> roadCities;
                        if (rd.getCities().isEmpty())
                                roadCities = Collections.singletonList(null);
                        else
                                roadCities = rd.getCities();
                        Label[] names = rd.getLabels();
                        for (Label lbl : names) {
                                if (lbl == null)
                                        continue;
                                String name = lbl.getText();
                                for (City city : roadCities) {
                                        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.WITHOUT_EXT_TYPE_DATA);
        for (Point p : points) {
            int key = (p.getSubdiv().getNumber() << 8) + p.getNumber();
            Point old = pois.put(key, p);
            assert old == null;
        }
    }

    private void fetchNamedPolygons(MapReader mapReader) {
        List<Polygon> polygons = mapReader.shapesForLevel(0, MapReader.WITHOUT_EXT_TYPE_DATA);
        for (Polygon p : polygons) {
                if (p.getLabel().getLength() > 0) {
                int subdiv = p.getSubdiv().getNumber() ;
                Map<Integer, Polygon> map = namedPolygons.get(subdiv);
                if (map == null) {
                        map = new HashMap<>();
                        namedPolygons.put(subdiv, map);
                }
                Polygon old = map.put(p.getNumber(), p);
                if (old != null)
                        assert old == null;
                }
        }
    }

        private void fetchCityNames(MapReader mapReader) {
                Map<Integer, City> nameMap = new HashMap<>();
                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);
        }

        public Polygon getShape(int subdiv, int number) {
                Map<Integer, Polygon> map = namedPolygons.get(subdiv);
                if (map != null)
                        return map.get(number);
                return null;
        }
}