/* * Copyright ©2019 Hal Perkins. All rights reserved. Permission is * hereby granted to students registered for University of Washington * CSE 331 for use solely during Spring Quarter 2019 for purposes of * the course. No other use, copying, distribution, or modification * is permitted without prior written consent. Copyrights for * third-party components of this work must be honored. Instructors * interested in reusing these course materials should contact the * author. */ package pathfinder; import graph.Graph; import graph.Node; import pathfinder.datastructures.Path; import pathfinder.datastructures.Point; import pathfinder.parser.CampusBuilding; import pathfinder.parser.CampusPath; import pathfinder.parser.CampusPathsParser; import java.util.*; /* In the pathfinder homework, the text user interface calls these methods to talk to your model. In the campuspaths homework, your graphical user interface will ultimately make class to these methods (through a web server) to talk to your model the same way. This is the power of the Model-View-Controller pattern, two completely different user interfaces can use the same model to display and interact with data in different ways, without requiring a lot of work to change things over. */ /** * This class represents the connection between the view and controller and the model * for the pathfinder and campus paths applications. */ public class ModelConnector { private WeightedGraph campus; private Map names; private Map locations; private Map buildings; public static final boolean DEBUGGING = false; /** * Creates a new {@link ModelConnector} and initializes it to contain data about * pathways and buildings or locations of interest on the campus of the University * of Washington, Seattle. When this constructor completes, the dataset is loaded * and prepared, and any method may be called on this object to query the data. */ public ModelConnector() { this.buildings = new HashMap(); names = new HashMap(); List buildings = CampusPathsParser.parseCampusBuildings(); List paths = CampusPathsParser.parseCampusPaths(); locations = new HashMap(); campus = new WeightedGraph(); for (CampusBuilding building : buildings) { names.put(building.getShortName(), building.getLongName()); double bx = building.getX(); double by = building.getY(); Point p = new Point(bx, by); locations.put(building.getShortName(), p); campus.addNode(p); this.buildings.put(p, building); } for (CampusPath path : paths) { Point b1 = new Point(path.getX1(), path.getY1()); if (!campus.containsNode(b1)) { campus.addNode(b1); } Point b2 = new Point(path.getX2(), path.getY2()); if (!campus.containsNode(b2)) { campus.addNode(b2); } campus.addEdge(b1, b2, path.getDistance()); campus.addEdge(b2, b1, path.getDistance()); } } /** * @param shortName The short name of a building to query. * @return {@literal true} iff the short name provided exists in this campus map. */ public boolean shortNameExists(String shortName) { return names.containsKey(shortName); } /** * @param shortName The short name of a building to look up. * @return The long name of the building corresponding to the provided short name. * @throws IllegalArgumentException if the short name provided does not exist. */ public String longNameForShort(String shortName) { if (!names.containsKey(shortName)) { throw new IllegalArgumentException(); } return names.get(shortName); } /** * @return The mapping from all the buildings' short names to their long names in this campus map. */ public Map buildingNames() { return names; } /** * Finds the shortest path, by distance, between the two provided buildings. * * @param startShortName The short name of the building at the beginning of this path. * @param endShortName The short name of the building at the end of this path. * @return A path between {@code startBuilding} and {@code endBuilding}, or {@literal null} * if none exists. * @throws IllegalArgumentException if {@code startBuilding} or {@code endBuilding} are * {@literal null}, or not valid short names of buildings in * this campus map. */ public Path findShortestPath(String startShortName, String endShortName) { if (startShortName == null || endShortName == null || !names.containsKey(startShortName) || !names.containsKey(endShortName)) { throw new IllegalArgumentException(); } Point startPoint = locations.get(startShortName); Point endPoint = locations.get(endShortName); return campus.findShortestPath(startPoint, endPoint); } /** * Returns the campus graph * * @return This campus graph */ public Graph getGraph() { checkRep(); return campus; } /** * Throws an exception if the rep invariant is violated. */ private void checkRep() { assert campus != null; assert campus.getNumEdges() >= 0 && campus.getNumNodes() >= 0; if (DEBUGGING) { Map> nodes = campus.getNodes(); if (!nodes.isEmpty()) { for (Point name : nodes.keySet()) { assert name != null; } for (Node n : nodes.values()) { assert n != null; } } } } }