Subversion Repositories splitter

Rev

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

package uk.me.parabola.splitter;

import crosby.binary.BinaryParser;
import crosby.binary.Osmformat;
import crosby.binary.file.FileBlockPosition;


import it.unimi.dsi.fastutil.shorts.ShortArrayList;

import java.util.List;

public class BinaryMapParser extends BinaryParser {
        // How many elements to process before displaying a status update
        private static final int NODE_STATUS_UPDATE_THRESHOLD = 10000000;
        private static final int WAY_STATUS_UPDATE_THRESHOLD = 1000000;
        private static final int RELATION_STATUS_UPDATE_THRESHOLD = 100000;
        private static final short TYPE_DENSE = 0x1;
        private static final short TYPE_NODES = 0x2;
        private static final short TYPE_WAYS = 0x4;
        private static final short TYPE_RELS = 0x8;
        private final ShortArrayList blockTypes = new ShortArrayList();
        private final ShortArrayList knownBlockTypes;
       
        private short blockType = -1;
        private int blockCount = -1;
        private long nodeCount;
        private long wayCount;
        private long relationCount;    
        private boolean skipTags;
        private boolean skipNodes;
        private boolean skipWays;
        private boolean skipRels;
        private boolean isStartNodeOnly;
        short wantedTypeMask = 0;
       
        BinaryMapParser(MapProcessor processor, ShortArrayList knownBlockTypes) {
                this.processor = processor;
                this.knownBlockTypes = knownBlockTypes;
                this.skipTags = processor.skipTags();
                this.skipNodes = processor.skipNodes();
                this.skipWays = processor.skipWays();
                this.skipRels = processor.skipRels();
                this.isStartNodeOnly = processor.isStartNodeOnly();
               
                if (skipNodes == false){
                        wantedTypeMask |= TYPE_DENSE;
                        wantedTypeMask |= TYPE_NODES;
                }
                if (skipWays == false)
                        wantedTypeMask |= TYPE_WAYS;
                if (skipRels == false)
                        wantedTypeMask |= TYPE_RELS;
        }
        MapProcessor processor;

        public ShortArrayList getBlockList(){
                return blockTypes;
        }
       
        @Override
    public boolean skipBlock(FileBlockPosition block) {
                blockCount++;
                if (knownBlockTypes != null){
                        blockType = knownBlockTypes.getShort(blockCount);
                        if (blockType != 0 && (blockType & wantedTypeMask) == 0)
                                return true;
                }
                else if (blockType != -1){
                        //System.out.println("previous block contained " + blockType );
                        blockTypes.add(blockType);
                }
                blockType = 0;
        // System.out.println("Seeing block of type: "+block.getType());
        if (block.getType().equals("OSMData"))
            return false;
        if (block.getType().equals("OSMHeader"))
            return false;
        System.out.println("Skipped block of type: " + block.getType());
        return true;
    }
       
        @Override
        public void complete() {
                blockTypes.add(blockType);
                // End of map is sent when all input files are processed.
                // So do nothing.
        }

        // Per-block state for parsing, set when processing the header of a block;
        @Override
        protected void parseDense(Osmformat.DenseNodes nodes) {
                blockType |= TYPE_DENSE;
                if (skipNodes)
                        return;
                long last_id = 0, last_lat = 0, last_lon = 0;
                int j = 0;
                int maxi = nodes.getIdCount();
                Node tmp = new Node();
                for (int i=0 ; i < maxi; i++) {
                        long lat = nodes.getLat(i)+last_lat; last_lat = lat;
                        long lon = nodes.getLon(i)+last_lon; last_lon = lon;
                        long id =  nodes.getId(i)+last_id; last_id = id;
                        double latf = parseLat(lat), lonf = parseLon(lon);

                        if (!isStartNodeOnly)
                                tmp = new Node();
                        tmp.set(id, latf, lonf);

                        if (!isStartNodeOnly && !skipTags) {
                                if (nodes.getKeysValsCount() > 0) {
                                        while (nodes.getKeysVals(j) != 0) {
                                                int keyid = nodes.getKeysVals(j++);
                                                int valid = nodes.getKeysVals(j++);
                                                tmp.addTag(getStringById(keyid),getStringById(valid));
                                        }
                                        j++; // Skip over the '0' delimiter.

                                }
                        }
                        processor.processNode(tmp);
                        CountNode(tmp.getId());
                }
        }

        @Override
        protected void parseNodes(List<Osmformat.Node> nodes) {
                if (nodes.size() == 0)
                        return;
                blockType |= TYPE_NODES;
                if (skipNodes)
                        return;
                for (Osmformat.Node i : nodes) {
                        Node tmp = new Node();
                        for (int j=0 ; j < i.getKeysCount(); j++)
                                tmp.addTag(getStringById(i.getKeys(j)),getStringById(i.getVals(j)));
                        long id = i.getId();
                        double latf = parseLat(i.getLat()), lonf = parseLon(i.getLon());

                        tmp.set(id, latf, lonf);

                        processor.processNode(tmp);
                        CountNode(tmp.getId());
                }
        }


        @Override
        protected void parseWays(List<Osmformat.Way> ways) {
                long numways = ways.size();
                if (numways == 0)
                        return;
                blockType |= TYPE_WAYS;
                if (skipWays)
                        return;
                for (Osmformat.Way i : ways) {
                        Way tmp = new Way();
                        if (skipTags == false){
                                for (int j=0 ; j < i.getKeysCount(); j++)
                                        tmp.addTag(getStringById(i.getKeys(j)),getStringById(i.getVals(j)));
                        }
                        long last_id=0;
                        for (long j : i.getRefsList()) {
                                tmp.addRef(j+last_id);
                                last_id = j+last_id;
                        }

                        long id = i.getId();
                        tmp.set(id);

                        processor.processWay(tmp);
                        countWay(i.getId());
                }
        }



        @Override
        protected void parseRelations(List<Osmformat.Relation> rels) {
                if (rels.size() == 0)
                        return;
                blockType |= TYPE_RELS;
                if (skipRels)
                        return;
                for (Osmformat.Relation i : rels) {
                        Relation tmp = new Relation();
                        if (skipTags == false){
                                for (int j=0 ; j < i.getKeysCount(); j++)
                                        tmp.addTag(getStringById(i.getKeys(j)),getStringById(i.getVals(j)));
                        }
                        long id = i.getId();
                        tmp.set(id);

                        long last_mid=0;
                        for (int j =0; j < i.getMemidsCount() ; j++) {
                                long mid = last_mid + i.getMemids(j);
                                last_mid = mid;
                                String role = getStringById(i.getRolesSid(j));
                                String etype=null;

                                if (i.getTypes(j) == Osmformat.Relation.MemberType.NODE)
                                        etype = "node";
                                else if (i.getTypes(j) == Osmformat.Relation.MemberType.WAY)
                                        etype = "way";
                                else if (i.getTypes(j) == Osmformat.Relation.MemberType.RELATION)
                                        etype = "relation";
                                else
                                        assert false; // TODO; Illegal file?

                                tmp.addMember(etype,mid,role);
                        }
                        processor.processRelation(tmp);
                        countRelation(tmp.getId());
                }
        }

        @Override
        public void parse(Osmformat.HeaderBlock block) {

                for (String s : block.getRequiredFeaturesList()) {
                        if (s.equals("OsmSchema-V0.6")) continue; // OK.
                        if (s.equals("DenseNodes")) continue; // OK.
                        throw new UnknownFeatureException(s);
                }

                if (block.hasBbox()) {
                        final double multiplier = .000000001;
                        double rightf = block.getBbox().getRight() * multiplier;
                        double leftf = block.getBbox().getLeft() * multiplier;
                        double topf = block.getBbox().getTop() * multiplier;
                        double bottomf = block.getBbox().getBottom() * multiplier;

                        System.out.println("Bounding box "+leftf+" "+bottomf+" "+rightf+" "+topf);

                        Area area = new Area(
                                        Utils.toMapUnit(bottomf),
                                        Utils.toMapUnit(leftf),
                                        Utils.toMapUnit(topf),
                                        Utils.toMapUnit(rightf));
                        processor.boundTag(area);
                }
        }

        private void CountNode(long id) {
                nodeCount++;
                if (nodeCount % NODE_STATUS_UPDATE_THRESHOLD == 0) {
                        System.out.println(Utils.format(nodeCount) + " nodes processed... id=" + id);
                }

        }

        private void countWay(long id)  {
                wayCount++;
                if (wayCount % WAY_STATUS_UPDATE_THRESHOLD == 0) {
                        System.out.println(Utils.format(wayCount) + " ways processed... id=" + id);
                }
        }

        private void countRelation(long id)  {
                relationCount++;
                if (relationCount % RELATION_STATUS_UPDATE_THRESHOLD == 0) {
                        System.out.println(Utils.format(relationCount) + " relations processed... id=" + id);
                }
        }

}