// License: GPL. For details, see LICENSE file. package indoor_sweepline; import java.util.Vector; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.Way; public class CorridorGeography { public CorridorGeography(DataSet dataSet) { this.dataSet = dataSet; } private static final double MIN_LENGTH = 10.; private void setExtraElements(CorridorPart.ReachableSide side, LatLon from, LatLon to, boolean extraWayUp, double minLength) { LatLon middleCoor = new LatLon((from.lat() + to.lat())/2., (from.lon() + to.lon())/2.); if (middleNode == null) { middleNode = new Node(middleCoor); dataSet.addPrimitive(middleNode); } else middleNode.setCoor(middleCoor); LatLon start = from; if (side == CorridorPart.ReachableSide.LEFT) { if (middleCoor.lat() < start.lat()) start = to; } else if (side == CorridorPart.ReachableSide.RIGHT) { if (start.lat() < middleCoor.lat()) start = to; } else if (side == CorridorPart.ReachableSide.FRONT) { if (start.lon() < middleCoor.lon()) start = to; } else if (side == CorridorPart.ReachableSide.BACK) { if (middleCoor.lon() < start.lon()) start = to; } double scale = Math.cos(middleCoor.lat() * (Math.PI/180.)); double length = Math.sqrt((start.lat() - middleCoor.lat()) * (start.lat() - middleCoor.lat()) + (start.lon() - middleCoor.lon()) * (start.lon() - middleCoor.lon()) * scale * scale) / 180. * 20000000.; double lengthFactor = length < minLength ? minLength / length : 1.; LatLon detachedCoor = new LatLon(middleCoor.lat() + (start.lon() - middleCoor.lon()) * scale * lengthFactor, middleCoor.lon() - (start.lat() - middleCoor.lat()) / scale * lengthFactor); if (detachedNode == null) { detachedNode = new Node(detachedCoor); dataSet.addPrimitive(detachedNode); } else detachedNode.setCoor(detachedCoor); Vector<Node> extraWayNodes = new Vector<>(); if (extraWayUp) { extraWayNodes.add(middleNode); extraWayNodes.add(detachedNode); } else { extraWayNodes.add(detachedNode); extraWayNodes.add(middleNode); } if (extraWay == null) { extraWay = new Way(); extraWay.setNodes(extraWayNodes); dataSet.addPrimitive(extraWay); } else extraWay.setNodes(extraWayNodes); } public void appendNodes(CorridorPart.Type type, CorridorPart.ReachableSide side, String level, LatLon from, LatLon to, ModelGeography target) { if (type == CorridorPart.Type.STAIRS_UP || type == CorridorPart.Type.STAIRS_DOWN) { setExtraElements(side, from, to, type == CorridorPart.Type.STAIRS_UP, MIN_LENGTH); target.appendNode(middleNode); detachedNode.removeAll(); extraWay.removeAll(); extraWay.put("highway", "steps"); extraWay.put("incline", "up"); extraWay.put("level", level); } else if (type == CorridorPart.Type.ESCALATOR_UP_LEAVING || type == CorridorPart.Type.ESCALATOR_UP_ARRIVING || type == CorridorPart.Type.ESCALATOR_UP_BIDIRECTIONAL || type == CorridorPart.Type.ESCALATOR_DOWN_LEAVING || type == CorridorPart.Type.ESCALATOR_DOWN_ARRIVING || type == CorridorPart.Type.ESCALATOR_DOWN_BIDIRECTIONAL) { setExtraElements(side, from, to, type == CorridorPart.Type.ESCALATOR_UP_LEAVING || type == CorridorPart.Type.ESCALATOR_UP_ARRIVING || type == CorridorPart.Type.ESCALATOR_UP_BIDIRECTIONAL, MIN_LENGTH); target.appendNode(middleNode); detachedNode.removeAll(); extraWay.removeAll(); extraWay.put("highway", "steps"); extraWay.put("incline", "up"); if (type == CorridorPart.Type.ESCALATOR_UP_LEAVING || type == CorridorPart.Type.ESCALATOR_DOWN_ARRIVING) extraWay.put("conveying", "forward"); else if (type == CorridorPart.Type.ESCALATOR_UP_ARRIVING || type == CorridorPart.Type.ESCALATOR_DOWN_LEAVING) extraWay.put("conveying", "backward"); else extraWay.put("conveying", "reversible"); extraWay.put("level", level); } else if (type == CorridorPart.Type.ELEVATOR) { setExtraElements(side, from, to, true, 0.); target.appendNode(middleNode); detachedNode.removeAll(); detachedNode.put("highway", "elevator"); extraWay.removeAll(); extraWay.put("highway", "footway"); extraWay.put("level", level); } else { if (extraWay != null) { extraWay.setDeleted(true); extraWay = null; } if (middleNode != null) { middleNode.setDeleted(true); middleNode = null; } if (detachedNode != null) { detachedNode.setDeleted(true); detachedNode = null; } } } private DataSet dataSet; private Node middleNode; private Node detachedNode; private Way extraWay; }