Subversion Repositories splitter

Rev

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

/*
 * Copyright (c) 2014, 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 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.solver;

import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import uk.me.parabola.splitter.AbstractMapProcessor;
import uk.me.parabola.splitter.Node;
import uk.me.parabola.splitter.RoundingUtils;
import uk.me.parabola.splitter.Utils;
import uk.me.parabola.splitter.Way;

import java.awt.geom.Path2D;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * Class to read a polygon description file (OSM)
 * Expected input are nodes and ways. Ways with
 * tag name=* and mapid=nnnnnnnn should describe polygons
 * which are used to calculate area lists.  
 * @author GerdP
 *
 */

class PolygonDescProcessor extends AbstractMapProcessor {
        private Long2ObjectOpenHashMap<Node> nodes = new Long2ObjectOpenHashMap<>();
        private final List<PolygonDesc> polygonDescriptions = new ArrayList<>();
        private final int shift;

        public PolygonDescProcessor(int resolution) {
                this.shift = 24 - resolution;
        }

        @Override
        public void processNode(Node n){
                // round all coordinates to be on the used grid.
                int lat = RoundingUtils.round(n.getMapLat(), shift);
                int lon = RoundingUtils.round(n.getMapLon(), shift);
                double roundedLat = Utils.toDegrees(lat);
                double roundedLon = Utils.toDegrees(lon);
               
                Node rNode = new Node();
                rNode.set(n.getId(),roundedLat,roundedLon);
                nodes.put(rNode.getId(), rNode);
               
        }

        @Override
        public void processWay(Way w){
                String name = w.getTag("name");
                if (name == null){
                        System.out.println("name missing, ignoring way " + w.getId());
                        return;
                }
                String mapIdString = w.getTag("mapid");
                if (mapIdString == null){
                        System.out.println("mapid missing, ignoring way " + w.getId());
                        return;
                }
                int mapId;
                try{
                        mapId = Integer.parseInt(mapIdString);
                } catch (NumberFormatException e){
                        System.out.println("invalid mapid in way " + w.getId());
                        return;
                }
                Path2D path = null;
                for (long ref : w.getRefs()){
                        Node n = nodes.get(ref);
                        if (n != null){
                                if (path == null){
                                        path = new Path2D.Double();
                                        path.moveTo(n.getMapLon(), n.getMapLat());
                                } else
                                        path.lineTo(n.getMapLon(), n.getMapLat());
                        }
                }
                PolygonDesc pd = new PolygonDesc(name, new Area(path), mapId);
                polygonDescriptions.add(pd);
        }

        @Override
        public boolean endMap(){
                nodes = null;
                System.out.println("found " + polygonDescriptions.size() + " named polygons");
                return true;
        }
       
        public List<PolygonDesc> getPolygons() {
                return polygonDescriptions;
        }
}