/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM 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. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.util.geo.maps.osm; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import de.tud.kom.p2psim.api.scenario.ConfigurationException; import de.tud.kom.p2psim.api.util.geo.maps.Node; import de.tud.kom.p2psim.api.util.geo.maps.Way; import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tudarmstadt.maki.simonstrator.api.Monitor; import de.tudarmstadt.maki.simonstrator.api.Monitor.Level; public class OSMReader extends DefaultHandler { private static HashMap loadedMaps = new HashMap(); private OSMMap map; private STATE state = STATE.INITIAL; private Vector idList = new Vector(); private String name; private boolean boundsFound = false; private boolean firstNode = true; private HashMap options = new HashMap(); private Long nodeId; public OSMReader() { map = new OSMMap(); } public OSMReader(OSMMap osmMap) { this.map = osmMap; } public OSMMap getMap() { return map; } public static void loadMap(String filename, OSMMap map) { File osmFile = new File(filename); if (!osmFile.exists()) throw new ConfigurationException("Couldn't find OSM file: " + filename); try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); SAXParser parser; parser = parserFactory.newSAXParser(); OSMReader reader = new OSMReader(map); File mapFile = new File(filename); InputStream mapIn = new FileInputStream(mapFile); if (filename.endsWith(".bz2")) { mapIn = new BZip2CompressorInputStream(mapIn); } parser.parse(mapIn, reader); reader.postProcessing(); } catch (Exception e) { e.printStackTrace(); } } private void postProcessing() { removeOutOfBoundNodes(map); } public void removeOutOfBoundNodes(OSMMap map) { Iterator iter = map.getWays().iterator(); int size = map.getWays().size(); OSMWay way; while (iter.hasNext()) { way = (OSMWay)iter.next(); for (Node node : way.getNodes()) { if (node == null || !checkBounds(map, node.getPosition())) { iter.remove(); break; } } } Monitor.log(OSMReader.class, Level.INFO, "Removed " + (size - map.getWays().size()) + " of " + size + " ways."); } private boolean checkBounds(OSMMap map, PositionVector pos) { if (pos.getX() > map.getMaxPosition().getX()) return false; if (pos.getY() > map.getMaxPosition().getY()) return false; if (pos.getX() < map.getMinPosition().getX()) return false; if (pos.getY() < map.getMinPosition().getY()) return false; return true; } private static enum STATE { INITIAL, NODES, WAYS; } @Override public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if (state.equals(STATE.WAYS)) { if ("nd".equals(qName)) { idList.add(Long.parseLong(attrs.getValue("ref"))); } else if ("tag".equals(qName)) { if (attrs.getValue("k").equals("name")) { name = attrs.getValue("v"); } options.put(attrs.getValue("k"), attrs.getValue("v")); } } else if (state.equals(STATE.NODES)) { if ("tag".equals(qName)) { options.put(attrs.getValue("k"), attrs.getValue("v")); } } else { if ("node".equals(qName)) { UTM utmCoord = UTMConversion.latLon2UTM(Double.parseDouble(attrs.getValue("lat")), Double.parseDouble(attrs.getValue("lon"))); PositionVector nodePosition = utmCoord.getPosition(); if (!boundsFound) { PositionVector minLonLat = map.getMinPosition(); PositionVector maxLonLat = map.getMaxPosition(); if (firstNode) { firstNode = false; minLonLat.replace(nodePosition); maxLonLat.replace(nodePosition); } else { if (nodePosition.getX() < minLonLat.getX()) minLonLat.setEntry(0, nodePosition.getX()); if (nodePosition.getY() < minLonLat.getY()) minLonLat.setEntry(1, nodePosition.getY()); if (nodePosition.getX() > maxLonLat.getX()) maxLonLat.setEntry(0, nodePosition.getX()); if (nodePosition.getY() > maxLonLat.getY()) maxLonLat.setEntry(1, nodePosition.getY()); map.setMinPosition(minLonLat); map.setMaxPosition(maxLonLat); } } nodeId = Long.parseLong(attrs.getValue("id")); options = new HashMap(); map.addNode(nodeId, nodePosition); state = STATE.NODES; } else if ("way".equals(qName)) { if (!boundsFound) { // Assume that all nodes come in front of the way definitions and make // the bounds final at this point to get a consistent map boundsFound = true; } idList = new Vector(); options = new HashMap(); state = STATE.WAYS; } else if ("bounds".equals(qName)) { boundsFound = true; // UTM minUtmCoord = UTMConversion.latLon2UTM(Double.parseDouble(attrs.getValue("minlat")), Double.parseDouble(attrs.getValue("minlon"))); UTM maxUtmCoord = UTMConversion.latLon2UTM(Double.parseDouble(attrs.getValue("maxlat")), Double.parseDouble(attrs.getValue("maxlon"))); map.setMinPosition(minUtmCoord.getPosition()); map.setMaxPosition(maxUtmCoord.getPosition()); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("way".equals(qName)) { state = STATE.INITIAL; map.addWay(name, idList, options); } else if ("node".equals(qName)) { state = STATE.INITIAL; map.getNode(nodeId).setAttributes(options); } } public static void main(String... args) { OSMMap map = null; File osmFile = new File(args[0]); if (!osmFile.exists()) throw new ConfigurationException("Couldn't find OSM file: " + args[0]); try { SAXParserFactory parserFactory = SAXParserFactory.newInstance(); SAXParser parser; parser = parserFactory.newSAXParser(); OSMReader reader = new OSMReader(); parser.parse(osmFile, reader); reader.postProcessing(); map = reader.getMap(); System.out.println("Filename: " + args[0]); System.out.println("maxlat: " + map.getMaxPosition().getY()); System.out.println("minlon: " + map.getMinPosition().getY()); System.out.println("maxlat: " + map.getMaxPosition().getX()); System.out.println("minlon: " + map.getMinPosition().getX()); } catch (Exception e) { e.printStackTrace(); } } }