<<<<<<< HEAD package roadnetwork; import classes.Layer; import enums.SelectionType; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Point2D; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.io.StringReader; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import shapes.Rectangle2DExt; import trafficdefinition.TrafficDefinitionElement; /** * Class representing a road network. The network consists of edges and * junctions. */ public class RoadNetwork extends Layer<RoadNetworkElement> implements Serializable { private static final long serialVersionUID = 1L; /** * List of elements that have been deleted by the user. They are placed here * until the user permanently deletes them by using the 'Purge Deleted' * option. */ private List<RoadNetworkElement> deletedMapElements; /** * List containing the selected elements that have been deleted by the user. */ private List<RoadNetworkElement> selectedDeletedMapElements; /** * String containing the contents of the *.edg.xml file. It is stored here * to be used when creating a road network after the user has deleted some * of its elements. */ private String roadNetworkEdgesXML = ""; /** * String containing the contents of the *.nod.xml file. It is stored here * to be used when creating a road network after the user has deleted some * of its elements. */ private String roadNetworkNodesXML = ""; /** * Flag to define whether the deleted elements should be drawn or not. */ private transient boolean showDeleted = false; /** * The road network's bounds. */ Rectangle2DExt bounds = null; /** * Default constructor. * */ public RoadNetwork() { super(); deletedMapElements = new ArrayList<RoadNetworkElement>(); selectedDeletedMapElements = new ArrayList<RoadNetworkElement>(); } @Override public void AlterSelection(Rectangle transformedRectangle, SelectionType type) { switch (type) { // If we have a new selection clear the previous selection case New: SelectNoneElements(); // No break! case Add: super.AddToSelection(transformedRectangle); // Select the deleted elements if (showDeleted) { List<RoadNetworkElement> newlySelectedElements = super.RectangleHitTest(transformedRectangle, deletedMapElements); if (newlySelectedElements.size() > 0) { deletedMapElements.removeAll(newlySelectedElements); selectedDeletedMapElements.addAll(newlySelectedElements); } } break; case Remove: super.RemoveFromSelection(transformedRectangle); // Deselect the deleted elements if (showDeleted) { List<RoadNetworkElement> newlyDeselectedElements = super.RectangleHitTest(transformedRectangle, selectedDeletedMapElements); if (newlyDeselectedElements.size() > 0) { deletedMapElements.addAll(newlyDeselectedElements); selectedDeletedMapElements.removeAll(newlyDeselectedElements); } } break; } // Notify any listeners that the selection has changed NotifySelectionChanged(); } @Override public void DeleteSelectedElements() { List<Edge> edgesNeeded = new ArrayList<Edge>(); List<Junction> junctionsNeeded = new ArrayList<Junction>(); // Find in selection any edges that have dependent traffic elements // defined on them for (RoadNetworkElement e : selectedElements) { if (e instanceof Edge) { if (((Edge) e).HasDependentTrafficElements()) { edgesNeeded.add((Edge) e); } } } // For each edge, ask the user what to do for (Edge e : edgesNeeded) { String s = ""; // Get the edge's dependencies List<TrafficDefinitionElement> edgeDependencies = e.getDependentTrafficElements(); // Build a string with the edge's dependencies for(TrafficDefinitionElement tde: edgeDependencies){ s+="Name: " + tde.getName()+" Layer: "+tde.getLayer().getName()+"\n"; } // Ask the user if she wants to delete the dependencies or not // delete the edge if(JOptionPane.showConfirmDialog(null, "You have selected to delete edge " + e.id + "\nThe following traffic elements depend on this edge:\n"+s+"Should the edge be deleted anyway?")==JOptionPane.YES_OPTION){ // Delete dependencies for(TrafficDefinitionElement tde: edgeDependencies){ e.RemoveDependentTrafficElement(tde); tde.getLayer().DeleteTrafficElement(tde); } } else{ // Remove the edge from the selection elements.add(e); selectedElements.remove(e); } } // Find in selection any junctions that are needed // by edges that are left undeleted for (RoadNetworkElement j : selectedElements) { if (j instanceof Junction) { for (RoadNetworkElement e : elements) { if (e instanceof Edge) { Edge edge = (Edge) e; Junction junction = (Junction) j; if ((edge.getFrom().equals(junction.getId())) || (edge.getTo().equals(junction.getId()))) { junctionsNeeded.add(junction); } } } } } // Remove from selection the needed junctions for (Junction j : junctionsNeeded) { elements.add(j); selectedElements.remove(j); } deletedMapElements.addAll(selectedElements); selectedElements.clear(); // Recalculate the road network's bounds ReCalculateBounds(); // Notify any registered listeners that the road network has been // modified NotifyCollectionModified(); // Notify any registered listeners that the selection has changed NotifySelectionChanged(); } @Override public void Draw(Graphics2D g, double zoomFactor) { // Draw elements for (RoadNetworkElement e : elements) { try { e.Draw(g, zoomFactor, false, false); } catch (Exception ex) { ex.printStackTrace(); } } // Draw selected elements for (RoadNetworkElement e : selectedElements) { e.Draw(g, zoomFactor, false, true); } // Draw deleted elements if (showDeleted) { for (RoadNetworkElement e : deletedMapElements) { e.Draw(g, zoomFactor, true, false); } // Draw selected deleted elements for (RoadNetworkElement e : selectedDeletedMapElements) { e.Draw(g, zoomFactor, true, true); } } } /** * Finds the closest (non-deleted) edge to the specified point * * @param point * @return the closest edge to the specified point, or null if the network * has no edges */ public Edge findClosestEdge(Point2D.Double point) { Edge closestEdge = null; double minimumDistance = Float.MAX_VALUE; // Loop all edges in the road network for (Edge e : getEdges()) { double distance = e.DistanceFrom(point); if (distance < minimumDistance) { minimumDistance = distance; closestEdge = e; } } return closestEdge; } /** * Returns the road network's bounds (minimum and maximum dimensions) * * @return * @uml.property name="bounds" */ public Rectangle2DExt getBounds() { if (bounds == null) { ReCalculateBounds(); } return bounds; } /** * Returns all the deleted elements (selected or not) * * @return */ public List<RoadNetworkElement> getDeletedElements() { List<RoadNetworkElement> result = new ArrayList<RoadNetworkElement>(); result.addAll(deletedMapElements); result.addAll(selectedDeletedMapElements); return result; } /** * Returns all (non deleted) edges of the network * * @return */ public List<Edge> getEdges() { List<Edge> result = new ArrayList<Edge>(); for (RoadNetworkElement e : elements) { if (e instanceof Edge) { result.add((Edge) e); } } for (RoadNetworkElement e : selectedElements) { if (e instanceof Edge) { result.add((Edge) e); } } return result; } /** * Returns all (non deleted) junctions of the network * * @return */ public List<Junction> getJunctions() { List<Junction> result = new ArrayList<Junction>(); for (RoadNetworkElement e : elements) { if (e instanceof Junction) { result.add((Junction) e); } } for (RoadNetworkElement e : selectedElements) { if (e instanceof Junction) { result.add((Junction) e); } } return result; } @Override public List<RoadNetworkElement> getElements() { List<RoadNetworkElement> result = super.getElements(); if (showDeleted) { result.addAll(deletedMapElements); result.addAll(selectedDeletedMapElements); } return result; } /** * @return the roadNetworkEdgesXML * @uml.property name="roadNetworkEdgesXML" */ public String getRoadNetworkEdgesXML() { return roadNetworkEdgesXML; } /** * @return the roadNetworkNodesXML * @uml.property name="roadNetworkNodesXML" */ public String getRoadNetworkNodesXML() { return roadNetworkNodesXML; } @Override public void NotifySelectionChanged() { // If deleted elements are hidden then simply call the super class if (!showDeleted) { super.NotifySelectionChanged(); } // Else take into account the selected deleted elements else { List<RoadNetworkElement> allSelectedElements = new ArrayList<RoadNetworkElement>(); allSelectedElements.addAll(selectedElements); allSelectedElements.addAll(selectedDeletedMapElements); NotifySelectionChanged(allSelectedElements); } } /** * Permanently deletes any deleted elements. * */ public void PurgeDeleted() { ByteArrayOutputStream edgesOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream nodesOutputStream = new ByteArrayOutputStream(); // Remove deleted elements from edg.xml and nod.xml documents try { RemoveDeletedFromXMLDocuments(nodesOutputStream, edgesOutputStream); } catch (Exception e) { JOptionPane.showMessageDialog(null, "Error while purging deleted elements", "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } roadNetworkEdgesXML = edgesOutputStream.toString(); roadNetworkNodesXML = nodesOutputStream.toString(); // Clear the deleted elements from the lists deletedMapElements.clear(); selectedDeletedMapElements.clear(); // Recalculate the network's bounds ReCalculateBounds(); // Notify any registered listeners that the network is modified NotifyCollectionModified(); // Notify any registered listeners that the selection has changed NotifySelectionChanged(); } /** * Alters the xml documents contained in roadNetworkEdgesXMLDocument and * roadNetworkNodesXMLDocument to remove tags corresponding to elements that * have been deleted and places the resulting xml documents to the output * streams. * * @param nodeOutputStream * Stream that will contain the edg.xml document after the * deleted elements have been removed * @param edgeOutputStream * Stream that will contain the nod.xml document after the * deleted elements have been removed * @throws Exception * if anything goes wrong */ public void RemoveDeletedFromXMLDocuments(OutputStream nodeOutputStream, OutputStream edgeOutputStream) throws Exception { // Parse the edges and nodes XML documents DocumentBuilder parser; Document roadNetworkEdgesXMLDocument = null, roadNetworkNodesXMLDocument = null; parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); roadNetworkEdgesXMLDocument = parser.parse(new InputSource(new StringReader(roadNetworkEdgesXML))); roadNetworkNodesXMLDocument = parser.parse(new InputSource(new StringReader(roadNetworkNodesXML))); // Delete the user-deleted elements from the documents List<RoadNetworkElement> deletedElements = getDeletedElements(); Hashtable<String,String> deletedEdges = new Hashtable<String,String>(); Hashtable<String,String> deletedJunctions = new Hashtable<String,String>(); for (RoadNetworkElement e : deletedElements) { if (e instanceof Edge) { deletedEdges.put(e.getId(), ""); } else if(e instanceof Node){ deletedJunctions.put(e.getId(), ""); } } NodeList edges = roadNetworkEdgesXMLDocument.getDocumentElement().getElementsByTagName("edge"); NodeList junctions = roadNetworkNodesXMLDocument.getDocumentElement().getElementsByTagName("node"); int edgesLength = edges.getLength(); int junctionsLength = junctions.getLength(); // Find the xml elements that need to be deleted from the documents List<Node> edgesToDelete = new ArrayList<Node>(); List<Node> junctionsToDelete = new ArrayList<Node>(); for (int i = 0; i < edgesLength; i++) { Node edge = edges.item(i); String edgeNodeID = edge.getAttributes().getNamedItem("id").getNodeValue(); if(deletedEdges.containsKey(edgeNodeID)){ edgesToDelete.add(edge); } } for (int i = 0; i < junctionsLength; i++) { Node junction = junctions.item(i); String junctionNodeID = junction.getAttributes().getNamedItem("id").getNodeValue(); if(deletedJunctions.containsKey(junctionNodeID)){ junctionsToDelete.add(junction); } } // Remove the elements from the xml documents for (Node n : edgesToDelete) { roadNetworkEdgesXMLDocument.getDocumentElement().removeChild(n); } for (Node j : junctionsToDelete) { roadNetworkNodesXMLDocument.getDocumentElement().removeChild(j); } // Save the modified XML documents to the output streams TransformerFactory tranFactory = TransformerFactory.newInstance(); Transformer transformer = tranFactory.newTransformer(); Source edgeSource = new DOMSource(roadNetworkEdgesXMLDocument); Result edgeDestination = new StreamResult(edgeOutputStream); Source junctionSource = new DOMSource(roadNetworkNodesXMLDocument); Result junctionDestination = new StreamResult(nodeOutputStream); transformer.transform(edgeSource, edgeDestination); transformer.transform(junctionSource, junctionDestination); } @Override public void SelectAllElements() { super.SelectAllElements(); // Also select the deleted elements if they are not hidden if (showDeleted) { selectedDeletedMapElements.addAll(deletedMapElements); deletedMapElements.clear(); } NotifySelectionChanged(); } /** * Finds all (non-deleted) edges that intersect the given shape. * * @param s * @return list of edges that intersect the specified shape */ public List<Edge> SelectEdges(Shape s) { List<Edge> hitEdges = new ArrayList<Edge>(); for (Edge e : getEdges()) { if (e.Overlaps(s)) { hitEdges.add(e); } } return hitEdges; } @Override public boolean SelectElement(RoadNetworkElement element) { if (super.SelectElement(element)) { return true; } else { // TODO is there a bug here should be done only on show deleted? deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); if (deletedMapElements.contains(element)) { selectedDeletedMapElements.add((RoadNetworkElement) element); deletedMapElements.remove(element); return true; } else { return false; } } } @Override public void SelectInverseElements() { super.SelectInverseElements(); if (showDeleted) { List<RoadNetworkElement> temp = new ArrayList<RoadNetworkElement>(); temp.addAll(deletedMapElements); deletedMapElements.clear(); deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); selectedDeletedMapElements.addAll(temp); } NotifySelectionChanged(); } @Override public void SelectNoneElements() { super.SelectNoneElements(); deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); NotifySelectionChanged(); } /** * @param roadNetworkEdgesXML * the roadNetworkEdgesXML to set * @uml.property name="roadNetworkEdgesXML" */ public void setRoadNetworkEdgesXML(String roadNetworkEdgesXML) { this.roadNetworkEdgesXML = roadNetworkEdgesXML; } /** * @param roadNetworkNodesXML * the roadNetworkNodesXML to set * @uml.property name="roadNetworkNodesXML" */ public void setRoadNetworkNodesXML(String roadNetworkNodesXML) { this.roadNetworkNodesXML = roadNetworkNodesXML; } /** * @param showDeleted * the showDeleted to set * @uml.property name="showDeleted" */ public void setShowDeleted(boolean showDeleted) { this.showDeleted = showDeleted; ReCalculateBounds(); // Clear the selection if (!showDeleted) { deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); } NotifyCollectionModified(); NotifySelectionChanged(); } @Override public String toString() { return "Road Network"; } /** * Searches the road network to find a non-deleted edge with the specified * id. * * @param edgeID * @return The edge with the specified ID, or null if not found */ public Edge findEdge(String edgeID) { for (Edge e : getEdges()) { if (e.getId().equals(edgeID)) { return e; } } return null; } /** * Searches the road network to find a non-deleted junction with the * specified id. * * @param junctionID * @return The junction with the specified ID, or null if not found */ public Junction findJunction(String junctionID) { for (Junction j : getJunctions()) { if (j.getId().equals(junctionID)) { return j; } } return null; } /** * Undeletes the selected deleted elements. If an edge is being undeleted, * its starting anfd ending junctions are also undeleted. * */ public void UndeleteSelectedMapElements() { // Junctions that need to be undeleted List<Junction> junctionsNeeded = new ArrayList<Junction>(); // Find the junctions that are needed by edges that have been deleted for (RoadNetworkElement r : selectedDeletedMapElements) { if (r instanceof Edge) { Edge edge = (Edge) r; for (RoadNetworkElement j : deletedMapElements) { if (j instanceof Junction) { Junction junction = (Junction) j; if ((edge.getFrom().equals(junction.getId())) || (edge.getTo().equals(junction.getId()))) { junctionsNeeded.add(junction); } } } } } // Undelete the needed junctions for (Junction j : junctionsNeeded) { selectedElements.add(j); deletedMapElements.remove(j); } // Undelete selected deleted elements selectedElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); ReCalculateBounds(); NotifyCollectionModified(); NotifySelectionChanged(); } /** * Recalculates the road network bounds. This method is called whenever the * user deletes or undeletes some elements, or shows or hides the deleted * elements. * */ private void ReCalculateBounds() { // Get all the visible elements List<RoadNetworkElement> allElements = getElements(); // Find the bounds of all elements bounds = allElements.get(0).getBounds(); for (RoadNetworkElement e : allElements) { bounds.add(e.getBounds()); } // Add a border of 10% around the network double maxdim = Math.max(bounds.width, bounds.height); double widthenlargement = maxdim * 0.1; bounds.x -= maxdim * 0.05; bounds.y -= maxdim * 0.05; bounds.width += widthenlargement; bounds.height += widthenlargement; } ======= package roadnetwork; import classes.Layer; import enums.SelectionType; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Point2D; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.io.StringReader; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import shapes.Rectangle2DExt; import trafficdefinition.TrafficDefinitionElement; /** * Class representing a road network. The network consists of edges and * junctions. */ public class RoadNetwork extends Layer<RoadNetworkElement> implements Serializable { private static final long serialVersionUID = 1L; /** * List of elements that have been deleted by the user. They are placed here * until the user permanently deletes them by using the 'Purge Deleted' * option. */ private List<RoadNetworkElement> deletedMapElements; /** * List containing the selected elements that have been deleted by the user. */ private List<RoadNetworkElement> selectedDeletedMapElements; /** * String containing the contents of the *.edg.xml file. It is stored here * to be used when creating a road network after the user has deleted some * of its elements. */ private String roadNetworkEdgesXML = ""; /** * String containing the contents of the *.nod.xml file. It is stored here * to be used when creating a road network after the user has deleted some * of its elements. */ private String roadNetworkNodesXML = ""; /** * Flag to define whether the deleted elements should be drawn or not. */ private transient boolean showDeleted = false; /** * The road network's bounds. */ Rectangle2DExt bounds = null; /** * Default constructor. * */ public RoadNetwork() { super(); deletedMapElements = new ArrayList<RoadNetworkElement>(); selectedDeletedMapElements = new ArrayList<RoadNetworkElement>(); } @Override public void AlterSelection(Rectangle transformedRectangle, SelectionType type) { switch (type) { // If we have a new selection clear the previous selection case New: SelectNoneElements(); // No break! case Add: super.AddToSelection(transformedRectangle); // Select the deleted elements if (showDeleted) { List<RoadNetworkElement> newlySelectedElements = super.RectangleHitTest(transformedRectangle, deletedMapElements); if (newlySelectedElements.size() > 0) { deletedMapElements.removeAll(newlySelectedElements); selectedDeletedMapElements.addAll(newlySelectedElements); } } break; case Remove: super.RemoveFromSelection(transformedRectangle); // Deselect the deleted elements if (showDeleted) { List<RoadNetworkElement> newlyDeselectedElements = super.RectangleHitTest(transformedRectangle, selectedDeletedMapElements); if (newlyDeselectedElements.size() > 0) { deletedMapElements.addAll(newlyDeselectedElements); selectedDeletedMapElements.removeAll(newlyDeselectedElements); } } break; } // Notify any listeners that the selection has changed NotifySelectionChanged(); } @Override public void DeleteSelectedElements() { List<Edge> edgesNeeded = new ArrayList<Edge>(); List<Junction> junctionsNeeded = new ArrayList<Junction>(); // Find in selection any edges that have dependent traffic elements // defined on them for (RoadNetworkElement e : selectedElements) { if (e instanceof Edge) { if (((Edge) e).HasDependentTrafficElements()) { edgesNeeded.add((Edge) e); } } } // For each edge, ask the user what to do for (Edge e : edgesNeeded) { String s = ""; // Get the edge's dependencies List<TrafficDefinitionElement> edgeDependencies = e.getDependentTrafficElements(); // Build a string with the edge's dependencies for(TrafficDefinitionElement tde: edgeDependencies){ s+="Name: " + tde.getName()+" Layer: "+tde.getLayer().getName()+"\n"; } // Ask the user if she wants to delete the dependencies or not // delete the edge if(JOptionPane.showConfirmDialog(null, "You have selected to delete edge " + e.id + "\nThe following traffic elements depend on this edge:\n"+s+"Should the edge be deleted anyway?")==JOptionPane.YES_OPTION){ // Delete dependencies for(TrafficDefinitionElement tde: edgeDependencies){ e.RemoveDependentTrafficElement(tde); tde.getLayer().DeleteTrafficElement(tde); } } else{ // Remove the edge from the selection elements.add(e); selectedElements.remove(e); } } // Find in selection any junctions that are needed // by edges that are left undeleted for (RoadNetworkElement j : selectedElements) { if (j instanceof Junction) { for (RoadNetworkElement e : elements) { if (e instanceof Edge) { Edge edge = (Edge) e; Junction junction = (Junction) j; if ((edge.getFrom().equals(junction.getId())) || (edge.getTo().equals(junction.getId()))) { junctionsNeeded.add(junction); } } } } } // Remove from selection the needed junctions for (Junction j : junctionsNeeded) { elements.add(j); selectedElements.remove(j); } deletedMapElements.addAll(selectedElements); selectedElements.clear(); // Recalculate the road network's bounds ReCalculateBounds(); // Notify any registered listeners that the road network has been // modified NotifyCollectionModified(); // Notify any registered listeners that the selection has changed NotifySelectionChanged(); } @Override public void Draw(Graphics2D g, double zoomFactor) { // Draw elements for (RoadNetworkElement e : elements) { try { e.Draw(g, zoomFactor, false, false); } catch (Exception ex) { ex.printStackTrace(); } } // Draw selected elements for (RoadNetworkElement e : selectedElements) { e.Draw(g, zoomFactor, false, true); } // Draw deleted elements if (showDeleted) { for (RoadNetworkElement e : deletedMapElements) { e.Draw(g, zoomFactor, true, false); } // Draw selected deleted elements for (RoadNetworkElement e : selectedDeletedMapElements) { e.Draw(g, zoomFactor, true, true); } } } /** * Finds the closest (non-deleted) edge to the specified point * * @param point * @return the closest edge to the specified point, or null if the network * has no edges */ public Edge findClosestEdge(Point2D.Double point) { Edge closestEdge = null; double minimumDistance = Float.MAX_VALUE; // Loop all edges in the road network for (Edge e : getEdges()) { double distance = e.DistanceFrom(point); if (distance < minimumDistance) { minimumDistance = distance; closestEdge = e; } } return closestEdge; } /** * Returns the road network's bounds (minimum and maximum dimensions) * * @return * @uml.property name="bounds" */ public Rectangle2DExt getBounds() { if (bounds == null) { ReCalculateBounds(); } return bounds; } /** * Returns all the deleted elements (selected or not) * * @return */ public List<RoadNetworkElement> getDeletedElements() { List<RoadNetworkElement> result = new ArrayList<RoadNetworkElement>(); result.addAll(deletedMapElements); result.addAll(selectedDeletedMapElements); return result; } /** * Returns all (non deleted) edges of the network * * @return */ public List<Edge> getEdges() { List<Edge> result = new ArrayList<Edge>(); for (RoadNetworkElement e : elements) { if (e instanceof Edge) { result.add((Edge) e); } } for (RoadNetworkElement e : selectedElements) { if (e instanceof Edge) { result.add((Edge) e); } } return result; } /** * Returns all (non deleted) junctions of the network * * @return */ public List<Junction> getJunctions() { List<Junction> result = new ArrayList<Junction>(); for (RoadNetworkElement e : elements) { if (e instanceof Junction) { result.add((Junction) e); } } for (RoadNetworkElement e : selectedElements) { if (e instanceof Junction) { result.add((Junction) e); } } return result; } @Override public List<RoadNetworkElement> getElements() { List<RoadNetworkElement> result = super.getElements(); if (showDeleted) { result.addAll(deletedMapElements); result.addAll(selectedDeletedMapElements); } return result; } /** * @return the roadNetworkEdgesXML * @uml.property name="roadNetworkEdgesXML" */ public String getRoadNetworkEdgesXML() { return roadNetworkEdgesXML; } /** * @return the roadNetworkNodesXML * @uml.property name="roadNetworkNodesXML" */ public String getRoadNetworkNodesXML() { return roadNetworkNodesXML; } @Override public void NotifySelectionChanged() { // If deleted elements are hidden then simply call the super class if (!showDeleted) { super.NotifySelectionChanged(); } // Else take into account the selected deleted elements else { List<RoadNetworkElement> allSelectedElements = new ArrayList<RoadNetworkElement>(); allSelectedElements.addAll(selectedElements); allSelectedElements.addAll(selectedDeletedMapElements); NotifySelectionChanged(allSelectedElements); } } /** * Permanently deletes any deleted elements. * */ public void PurgeDeleted() { ByteArrayOutputStream edgesOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream nodesOutputStream = new ByteArrayOutputStream(); // Remove deleted elements from edg.xml and nod.xml documents try { RemoveDeletedFromXMLDocuments(nodesOutputStream, edgesOutputStream); } catch (Exception e) { JOptionPane.showMessageDialog(null, "Error while purging deleted elements", "Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } roadNetworkEdgesXML = edgesOutputStream.toString(); roadNetworkNodesXML = nodesOutputStream.toString(); // Clear the deleted elements from the lists deletedMapElements.clear(); selectedDeletedMapElements.clear(); // Recalculate the network's bounds ReCalculateBounds(); // Notify any registered listeners that the network is modified NotifyCollectionModified(); // Notify any registered listeners that the selection has changed NotifySelectionChanged(); } /** * Alters the xml documents contained in roadNetworkEdgesXMLDocument and * roadNetworkNodesXMLDocument to remove tags corresponding to elements that * have been deleted and places the resulting xml documents to the output * streams. * * @param nodeOutputStream * Stream that will contain the edg.xml document after the * deleted elements have been removed * @param edgeOutputStream * Stream that will contain the nod.xml document after the * deleted elements have been removed * @throws Exception * if anything goes wrong */ public void RemoveDeletedFromXMLDocuments(OutputStream nodeOutputStream, OutputStream edgeOutputStream) throws Exception { // Parse the edges and nodes XML documents DocumentBuilder parser; Document roadNetworkEdgesXMLDocument = null, roadNetworkNodesXMLDocument = null; parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); roadNetworkEdgesXMLDocument = parser.parse(new InputSource(new StringReader(roadNetworkEdgesXML))); roadNetworkNodesXMLDocument = parser.parse(new InputSource(new StringReader(roadNetworkNodesXML))); // Delete the user-deleted elements from the documents List<RoadNetworkElement> deletedElements = getDeletedElements(); Hashtable<String,String> deletedEdges = new Hashtable<String,String>(); Hashtable<String,String> deletedJunctions = new Hashtable<String,String>(); for (RoadNetworkElement e : deletedElements) { if (e instanceof Edge) { deletedEdges.put(e.getId(), ""); } else if(e instanceof Node){ deletedJunctions.put(e.getId(), ""); } } NodeList edges = roadNetworkEdgesXMLDocument.getDocumentElement().getElementsByTagName("edge"); NodeList junctions = roadNetworkNodesXMLDocument.getDocumentElement().getElementsByTagName("node"); int edgesLength = edges.getLength(); int junctionsLength = junctions.getLength(); // Find the xml elements that need to be deleted from the documents List<Node> edgesToDelete = new ArrayList<Node>(); List<Node> junctionsToDelete = new ArrayList<Node>(); for (int i = 0; i < edgesLength; i++) { Node edge = edges.item(i); String edgeNodeID = edge.getAttributes().getNamedItem("id").getNodeValue(); if(deletedEdges.containsKey(edgeNodeID)){ edgesToDelete.add(edge); } } for (int i = 0; i < junctionsLength; i++) { Node junction = junctions.item(i); String junctionNodeID = junction.getAttributes().getNamedItem("id").getNodeValue(); if(deletedJunctions.containsKey(junctionNodeID)){ junctionsToDelete.add(junction); } } // Remove the elements from the xml documents for (Node n : edgesToDelete) { roadNetworkEdgesXMLDocument.getDocumentElement().removeChild(n); } for (Node j : junctionsToDelete) { roadNetworkNodesXMLDocument.getDocumentElement().removeChild(j); } // Save the modified XML documents to the output streams TransformerFactory tranFactory = TransformerFactory.newInstance(); Transformer transformer = tranFactory.newTransformer(); Source edgeSource = new DOMSource(roadNetworkEdgesXMLDocument); Result edgeDestination = new StreamResult(edgeOutputStream); Source junctionSource = new DOMSource(roadNetworkNodesXMLDocument); Result junctionDestination = new StreamResult(nodeOutputStream); transformer.transform(edgeSource, edgeDestination); transformer.transform(junctionSource, junctionDestination); } @Override public void SelectAllElements() { super.SelectAllElements(); // Also select the deleted elements if they are not hidden if (showDeleted) { selectedDeletedMapElements.addAll(deletedMapElements); deletedMapElements.clear(); } NotifySelectionChanged(); } /** * Finds all (non-deleted) edges that intersect the given shape. * * @param s * @return list of edges that intersect the specified shape */ public List<Edge> SelectEdges(Shape s) { List<Edge> hitEdges = new ArrayList<Edge>(); for (Edge e : getEdges()) { if (e.Overlaps(s)) { hitEdges.add(e); } } return hitEdges; } @Override public boolean SelectElement(RoadNetworkElement element) { if (super.SelectElement(element)) { return true; } else { // TODO is there a bug here should be done only on show deleted? deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); if (deletedMapElements.contains(element)) { selectedDeletedMapElements.add((RoadNetworkElement) element); deletedMapElements.remove(element); return true; } else { return false; } } } @Override public void SelectInverseElements() { super.SelectInverseElements(); if (showDeleted) { List<RoadNetworkElement> temp = new ArrayList<RoadNetworkElement>(); temp.addAll(deletedMapElements); deletedMapElements.clear(); deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); selectedDeletedMapElements.addAll(temp); } NotifySelectionChanged(); } @Override public void SelectNoneElements() { super.SelectNoneElements(); deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); NotifySelectionChanged(); } /** * @param roadNetworkEdgesXML * the roadNetworkEdgesXML to set * @uml.property name="roadNetworkEdgesXML" */ public void setRoadNetworkEdgesXML(String roadNetworkEdgesXML) { this.roadNetworkEdgesXML = roadNetworkEdgesXML; } /** * @param roadNetworkNodesXML * the roadNetworkNodesXML to set * @uml.property name="roadNetworkNodesXML" */ public void setRoadNetworkNodesXML(String roadNetworkNodesXML) { this.roadNetworkNodesXML = roadNetworkNodesXML; } /** * @param showDeleted * the showDeleted to set * @uml.property name="showDeleted" */ public void setShowDeleted(boolean showDeleted) { this.showDeleted = showDeleted; ReCalculateBounds(); // Clear the selection if (!showDeleted) { deletedMapElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); } NotifyCollectionModified(); NotifySelectionChanged(); } @Override public String toString() { return "Road Network"; } /** * Searches the road network to find a non-deleted edge with the specified * id. * * @param edgeID * @return The edge with the specified ID, or null if not found */ public Edge findEdge(String edgeID) { for (Edge e : getEdges()) { if (e.getId().equals(edgeID)) { return e; } } return null; } /** * Searches the road network to find a non-deleted junction with the * specified id. * * @param junctionID * @return The junction with the specified ID, or null if not found */ public Junction findJunction(String junctionID) { for (Junction j : getJunctions()) { if (j.getId().equals(junctionID)) { return j; } } return null; } /** * Undeletes the selected deleted elements. If an edge is being undeleted, * its starting anfd ending junctions are also undeleted. * */ public void UndeleteSelectedMapElements() { // Junctions that need to be undeleted List<Junction> junctionsNeeded = new ArrayList<Junction>(); // Find the junctions that are needed by edges that have been deleted for (RoadNetworkElement r : selectedDeletedMapElements) { if (r instanceof Edge) { Edge edge = (Edge) r; for (RoadNetworkElement j : deletedMapElements) { if (j instanceof Junction) { Junction junction = (Junction) j; if ((edge.getFrom().equals(junction.getId())) || (edge.getTo().equals(junction.getId()))) { junctionsNeeded.add(junction); } } } } } // Undelete the needed junctions for (Junction j : junctionsNeeded) { selectedElements.add(j); deletedMapElements.remove(j); } // Undelete selected deleted elements selectedElements.addAll(selectedDeletedMapElements); selectedDeletedMapElements.clear(); ReCalculateBounds(); NotifyCollectionModified(); NotifySelectionChanged(); } /** * Recalculates the road network bounds. This method is called whenever the * user deletes or undeletes some elements, or shows or hides the deleted * elements. * */ private void ReCalculateBounds() { // Get all the visible elements List<RoadNetworkElement> allElements = getElements(); // Find the bounds of all elements bounds = allElements.get(0).getBounds(); for (RoadNetworkElement e : allElements) { bounds.add(e.getBounds()); } // Add a border of 10% around the network double maxdim = Math.max(bounds.width, bounds.height); double widthenlargement = maxdim * 0.1; bounds.x -= maxdim * 0.05; bounds.y -= maxdim * 0.05; bounds.width += widthenlargement; bounds.height += widthenlargement; } >>>>>>> origin/abdalla }