Subversion Repositories splitter

Rev

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

/*
 * Copyright (C) 2012, Gerd Petermann
 *
 * 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.splitter;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import uk.me.parabola.splitter.tools.Long2IntClosedMapFunction;
import uk.me.parabola.splitter.tools.OSMId2ObjectMap;
import uk.me.parabola.splitter.tools.SparseLong2IntMap;
import uk.me.parabola.splitter.writer.OSMWriter;

/**
 * Stores data that is needed in different passes of the program.
 *
 * @author GerdP
 *
 */

public class DataStorer {
        public static final int NODE_TYPE = 0;
        public static final int WAY_TYPE = 1;
        public static final int REL_TYPE = 2;

        private final int numOfAreas;

        private final Long2IntClosedMapFunction[] maps = new Long2IntClosedMapFunction[3];

        private final AreaDictionary areaDictionary;
        private final AreaIndex areaIndex;
        private SparseLong2IntMap usedWays = null;
        private final OSMId2ObjectMap<Integer> usedRels = new OSMId2ObjectMap<>();
        private boolean idsAreNotSorted;
        private OSMWriter[] writers;
        /**
         * map with relations that should be complete and are written to only one
         * tile
         */

        private final Long2ObjectOpenHashMap<Integer> oneDistinctAreaOnlyRels = new Long2ObjectOpenHashMap<>();
        private final OSMId2ObjectMap<Integer> oneTileOnlyRels = new OSMId2ObjectMap<>();

        /**
         * Create a dictionary for a given number of writers
         *
         * @param overlapAmount
         * @param numOfWriters
         *            the number of writers that are used
         */

        DataStorer(List<Area> areas, int overlapAmount) {
                this.numOfAreas = areas.size();
                this.areaDictionary = new AreaDictionary(areas, overlapAmount);
                this.areaIndex = new AreaGrid(areaDictionary);
                return;
        }

        public int getNumOfAreas() {
                return numOfAreas;
        }

        public AreaDictionary getAreaDictionary() {
                return areaDictionary;
        }

        public Area getArea(int idx) {
                return areaDictionary.getArea(idx);
        }

        public Area getExtendedArea(int idx) {
                return areaDictionary.getExtendedArea(idx);
        }

        public void setWriters(OSMWriter[] writers) {
                this.writers = writers;
        }

        public void setWriterMap(int type, Long2IntClosedMapFunction nodeWriterMap) {
                maps[type] = nodeWriterMap;
        }

        public Long2IntClosedMapFunction getWriterMap(int type) {
                return maps[type];
        }

        public AreaIndex getGrid() {
                return areaIndex;
        }

        public SparseLong2IntMap getUsedWays() {
                return usedWays;
        }

        public OSMId2ObjectMap<Integer> getUsedRels() {
                return usedRels;
        }

        public void setUsedWays(SparseLong2IntMap ways) {
                usedWays = ways;
        }

        public boolean isIdsAreNotSorted() {
                return idsAreNotSorted;
        }

        public void setIdsAreNotSorted(boolean idsAreNotSorted) {
                this.idsAreNotSorted = idsAreNotSorted;
        }

        public void restartWriterMaps() {
                for (Long2IntClosedMapFunction map : maps) {
                        if (map != null) {
                                try {
                                        map.close();
                                } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                        }
                }

        }

        public void switchToSeqAccess(File fileOutputDir) throws IOException {
                boolean msgWritten = false;
                long start = System.currentTimeMillis();
                for (Long2IntClosedMapFunction map : maps) {
                        if (map != null) {
                                if (!msgWritten) {
                                        System.out.println("Writing results of MultiTileAnalyser to temp files ...");
                                        msgWritten = true;
                                }
                                map.switchToSeqAccess(fileOutputDir);
                        }
                }
                System.out.println("Writing temp files took " + (System.currentTimeMillis() - start) + " ms");
        }

        public void finish() {
                for (Long2IntClosedMapFunction map : maps) {
                        if (map != null)
                                map.finish();
                }
        }

        public void stats(final String prefix) {
                for (Long2IntClosedMapFunction map : maps) {
                        if (map != null)
                                map.stats(prefix);
                }
        }

        public OSMWriter[] getWriters() {
                return writers;
        }

        public void storeRelationAreas(long id, AreaSet areaSet) {
                oneDistinctAreaOnlyRels.put(id, areaDictionary.translate(areaSet));
        }

        public Integer getOneTileOnlyRels(long id) {
                return oneTileOnlyRels.get(id);
        }

        /**
         * If the ids in oneTileOnlyRels were produced with a different set
         * of areas we have to translate the values
         *
         * @param distinctAreas
         *            list of distinct (non-overlapping) areas
         * @param distinctDataStorer
         */

        public void translateDistinctToRealAreas(DataStorer distinctDataStorer) {
                List<Area> distinctAreas = distinctDataStorer.getAreaDictionary().getAreas();
                Map<Area, Integer> map = new HashMap<>();
                for (Area distinctArea : distinctAreas) {
                        if (!distinctArea.isPseudoArea()) {
                                AreaSet w = new AreaSet();
                                for (int i = 0; i < getNumOfAreas(); i++) {
                                        if (this.areaDictionary.getArea(i).contains(distinctArea)) {
                                                w.set(i);
                                        }
                                }
                                map.put(distinctArea, this.areaDictionary.translate(w));
                        }
                }

                for (Entry<Long, Integer> e : distinctDataStorer.oneDistinctAreaOnlyRels.entrySet()) {
                        AreaSet singleArea =  distinctDataStorer.getAreaDictionary().getSet(e.getValue());
                        assert singleArea.cardinality() == 1;
                        int pos = singleArea.iterator().next();
                        if (!distinctAreas.get(pos).isPseudoArea()) {
                                Integer areaIdx = map.get(distinctAreas.get(pos));
                                if (areaIdx == null)
                                        throw new SplitFailedException("failed to find index for area " + distinctAreas.get(pos));
                                oneTileOnlyRels.put(e.getKey(), areaIdx);
                        } else {
                                oneTileOnlyRels.put(e.getKey(), AbstractMapProcessor.UNASSIGNED);
                        }

                }
        }
}