📄 citycontext.java
字号:
/*〤opyright 2008 Nick MallesonThis file is part of RepastCity.RepastCity 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 (at your option) any later version.RepastCity 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 RepastCity. If not, see <http://www.gnu.org/licenses/>. */package repastcity.citycontext;import java.util.HashMap;import com.vividsolutions.jts.geom.Coordinate;import com.vividsolutions.jts.geom.Geometry;import com.vividsolutions.jts.geom.GeometryFactory;import com.vividsolutions.jts.geom.Point;import com.vividsolutions.jts.operation.distance.DistanceOp;import repast.simphony.context.DefaultContext;import repast.simphony.space.gis.Geography;import repast.simphony.space.graph.Network;import repast.simphony.space.graph.RepastEdge;import repastcity.ContextCreator;public class CityContext extends DefaultContext<Object> { // These are used so we can keep a link between Roads (in the RoadGeography) and Edges in the RoadNetwork private HashMap<RepastEdge<?>, String> edgeIDs_KeyEdge; // Stores the TOIDs of edges (Edge as key) private HashMap<String, RepastEdge<?>> edgeIDs_KeyID; // Stores the TOIDs of edges (TOID as key) /** * Constructs a CityContextContext and creates a Geography (called RoadNetworkGeography) which is * part of this context. */ public CityContext() { super("CityContext"); // Very important otherwise repast complains System.out.println("CityContext: Building city context"); this.edgeIDs_KeyEdge = new HashMap<RepastEdge<?>, String>(); this.edgeIDs_KeyID = new HashMap<String, RepastEdge<?>>();// /* Create a geography to display the sub-contexts of the city. */// GeographyParameters<Object> geoParams = new GeographyParameters<Object>();// GeographyFactoryFinder.createGeographyFactory(null).createGeography("CityGeography", this, geoParams); } public void createSubContexts() { this.addSubContext(new RoadContext()); this.addSubContext(new JunctionContext()); this.addSubContext(new HouseContext()); } /** * Actually creates the road network. Runs through the RoadGeography and generate nodes from the * end points of each line. These nodes are added to the RoadNetwork (part of the JunctionContext) * as well as to edges. */ public void buildRoadNetwork() { System.out.println("CityContext: building road network"); // Get the geographies and the network Geography<Road> roadGeography = (Geography<Road>) ContextCreator.getRoadGeography(); Geography<Junction> junctionGeography= (Geography<Junction>) ContextCreator.getJunctionGeography(); JunctionContext junctionContext = (JunctionContext) ContextCreator.getJunctionContext(); Network<Junction> roadNetwork = (Network<Junction>) ContextCreator.getRoadNetwork(); // Create a GeometryFactory so we can create points/lines from the junctions and roads (this is so they can be displayed on the same display to check if the network has been created successfully) GeometryFactory geomFac = new GeometryFactory(); // Iterate through all roads Iterable<Road> roadIt = roadGeography.getAllObjects(); for (Road road:roadIt) { // Create a LineString from the road so we can extract coordinates Geometry roadGeom = roadGeography.getGeometry(road); Coordinate c1 = roadGeom.getCoordinates()[0]; // First coord (XXXX - check coorinates are in this order) Coordinate c2 = roadGeom.getCoordinates()[roadGeom.getNumPoints()-1]; // Last coord // Create Junctions from these coordinates and add them to the JunctionGeography (if they haven't been created already) Junction junc1 = new Junction(c1, road); Junction junc2 = new Junction(c2, road); // Check if the Junctions are already in the context, if not then add them. if (junctionContext.existsInContext(junc1)) { // A Junction with those coordinates (c1) is already in the context, get it so we can add an edge to it junc1 = junctionContext.getJunctionWithCoordinates(c1); } else { // Junction does not exit junctionContext.add(junc1); Point p1 = geomFac.createPoint(c1); junctionGeography.move(junc1, p1); } if (junctionContext.existsInContext(junc2)) { junc2 = junctionContext.getJunctionWithCoordinates(c2); } else { junctionContext.add(junc2); Point p2 = geomFac.createPoint(c2); junctionGeography.move(junc2, p2); } // Tell the road object who it's junctions are road.addJunction(junc1); road.addJunction(junc2); // Tell the junctions about this road junc1.addRoad(road); junc2.addRoad(road); // Create an edge between the two junctions, assigning a weight equal to it's length RepastEdge<Junction> edge = new RepastEdge<Junction>(junc1, junc2, false, roadGeom.getLength()); // Store the road's TOID in a dictionary (one with edges as keys, one with id's as keys) try { this.edgeIDs_KeyEdge.put(edge, (String) road.getIdentifier()); this.edgeIDs_KeyID.put((String) road.getIdentifier(), edge); } catch (Exception e) { System.err.println(e.getMessage()); } if (!roadNetwork.containsEdge(edge)) { roadNetwork.addEdge(edge); } else { System.err.println("CityContext: buildRoadNetwork: for some reason this edge that has just been created already exists in the RoadNetwork!"); } } // for road: } /* Gets the ID String associated with a given edge. Useful for linking RepastEdges with spatial objects (i.e. Roads). */ public String getIDFromEdge(RepastEdge<Junction> edge) { String id = ""; try { id = (String) this.edgeIDs_KeyEdge.get(edge); } catch (Exception e) { System.err.println("CityContext: getIDDromEdge: Error, probably no id found for edge "+edge.toString()); System.err.println(e.getStackTrace()); } return id; } /* Get the edge with the given ID */ public RepastEdge<?> getEdgeFromID(String id) { RepastEdge<?> edge = null; try { edge = this.edgeIDs_KeyID.get(id); } catch (Exception e) { System.err.println("CityContext: getEdgeDromID: Error, probably no edge found for id "+id); System.err.println(e.getStackTrace()); } return edge; } /* Returns the road which is crosses the given coordinates * (Actually it just returns the *nearest* road to the coords) */ public Road findRoadAtCoordinates (Coordinate coord) { GeometryFactory geomFac = new GeometryFactory(); Geography<?> roadGeography = ContextCreator.getRoadGeography(); // Use a buffer for efficiency Point point = geomFac.createPoint(coord); Geometry buffer = point.buffer(0.01); // XXXX - Parameter double minDist = 999999999.9; Road nearestRoad = null; for (Road road:roadGeography.getObjectsWithin(buffer.getEnvelopeInternal(), Road.class)) { DistanceOp distOp = new DistanceOp(point, roadGeography.getGeometry(road)); double thisDist = distOp.distance(); if (thisDist < minDist) { minDist = thisDist; nearestRoad = road; } // if thisDist < minDist } // for nearRoads if (nearestRoad == null) { System.err.println("CityContext: findRoadAtCoordinates: ERROR: couldn't find a road at these coordinates:\n\t"+ coord.toString()); } return nearestRoad; } public Road findRoadWithID(String id) { Geography<Road> roadGeography = (Geography<Road>) ContextCreator.getRoadGeography(); for (Road road:roadGeography.getAllObjects()) { if (road.getIdentifier().equals(id)) return road; } System.err.println("CityContext: findRoadWithID: Error, couldn't find a road woth id: "+id); return new Road(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -