package aimax.osm.data.impl; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import aimax.osm.data.BoundingBox; import aimax.osm.data.EntityClassifier; import aimax.osm.data.MapBuilder; import aimax.osm.data.OsmMap; import aimax.osm.data.entities.EntityAttribute; import aimax.osm.data.entities.EntityViewInfo; import aimax.osm.data.entities.MapNode; public class DefaultMapBuilder implements MapBuilder { private static Logger LOG = Logger.getLogger("aimax.osm"); private DefaultMap result; private boolean nodeRefsWithoutDefsAdded; public DefaultMapBuilder() { result = new DefaultMap(); } public DefaultMapBuilder(DefaultMap map) { result = map; result.clear(); } /** {@inheritDoc} */ @Override public void setEntityClassifier(EntityClassifier<EntityViewInfo> classifier) { result.setEntityClassifier(classifier); } /** {@inheritDoc} */ @Override public void setBoundingBox(BoundingBox bb) { result.setBoundingBox(bb); } /** {@inheritDoc} */ @Override public boolean isNodeDefined(long id, BoundingBox bb) { MapNode node = result.getNode(id); boolean result = (node != null && node.hasPosition()); if (result && bb != null) result = bb.isInside(node.getLat(), node.getLon()); return result; } /** {@inheritDoc} */ @Override public boolean isNodeReferenced(long id) { MapNode node = result.getNode(id); return node != null && !node.getWayRefs().isEmpty(); } /** * {@inheritDoc} If a node with the same ID but without position has already * been added, it is redefined with the new data. */ @Override public void addNode(long id, String name, List<EntityAttribute> atts, float lat, float lon) { DefaultMapNode node = (DefaultMapNode) result.getNode(id); if (node == null || !node.hasPosition()) { if (node == null) node = new DefaultMapNode(id); node.setName(name); node.setAttributes(atts); node.setPosition(lat, lon); result.addNode(node); if (result.getNodeCount() % 500000 == 0) LOG.fine("Nodes: " + result.getNodeCount()); } } /** {@inheritDoc} */ @Override public boolean isWayDefined(long id) { return result.getWay(id) != null; } /** * {@inheritDoc} Ways with less than two way nodes are ignored. */ @Override public void addWay(long id, String name, List<EntityAttribute> atts, List<Long> wayNodeIds) { if (wayNodeIds.size() > 1) { DefaultMapWay way = new DefaultMapWay(id); way.setName(name); way.setAttributes(atts); List<MapNode> wayNodes = new ArrayList<MapNode>(wayNodeIds.size()); int i = 0; for (long nodeId : wayNodeIds) { DefaultMapNode node = (DefaultMapNode) result.getNode(nodeId); if (node == null) { node = new DefaultMapNode(nodeId); result.addNode(node); nodeRefsWithoutDefsAdded = true; } node.addWayRef(way, i++); wayNodes.add(node); } way.setNodes(wayNodes); result.addWay(way); if (result.getWayCount() % 50000 == 0) LOG.fine("Ways: " + result.getWayCount()); } } /** {@inheritDoc} */ @Override public boolean nodeRefsWithoutDefsAdded() { boolean result = nodeRefsWithoutDefsAdded; nodeRefsWithoutDefsAdded = false; return result; } /** {@inheritDoc} */ @Override public OsmMap buildMap() { result.compile(); if (!result.isEmpty()) LOG.fine("Loading completed. Ways: " + result.getWayCount() + ", Nodes: " + result.getNodeCount() + ", POIs: " + result.getPoiCount()); return result; } }