城市仿真软件:MATSim_(12).MATSim高级功能与插件
MATSim 的插件系统允许用户扩展软件的基本功能,以满足特定的研究和应用需求。插件可以添加新的行为模型、数据处理工具、可视化功能等。插件的开发基于 Java 语言,使用 Maven 作为构建工具。MATSim 的插件系统设计得非常灵活,用户可以根据需要选择和组合不同的插件。每个插件都是一个独立的 Maven 项目,包含以下主要部分:pom.xml: 描述插件的依赖关系和构建配置。src/main
MATSim高级功能与插件
1. 插件系统概述
MATSim 的插件系统允许用户扩展软件的基本功能,以满足特定的研究和应用需求。插件可以添加新的行为模型、数据处理工具、可视化功能等。插件的开发基于 Java 语言,使用 Maven 作为构建工具。MATSim 的插件系统设计得非常灵活,用户可以根据需要选择和组合不同的插件。
1.1 插件的基本结构
每个插件都是一个独立的 Maven 项目,包含以下主要部分:
-
pom.xml: 描述插件的依赖关系和构建配置。
-
src/main/java: 存放插件的 Java 源代码。
-
src/main/resources: 存放配置文件、数据文件等资源。
-
src/main/config: 存放 MATSim 配置文件,如
config.xml。 -
src/main/analysis: 存放分析脚本和结果处理代码。
1.2 创建插件项目
要创建一个新的 MATSim 插件项目,可以使用以下步骤:
-
初始化 Maven 项目:
使用 Maven 命令行工具初始化一个新的项目。在命令行中,执行以下命令:
mvn archetype:generate -DgroupId=com.example -DartifactId=matsim-plugin-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false -
配置 pom.xml:
在生成的
pom.xml文件中,添加 MATSim 依赖和其他必要的依赖。例如:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>matsim-plugin-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>MATSim Plugin Example</name> <url>http://matsim.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <matsim.version>12.0</matsim.version> </properties> <dependencies> <dependency> <groupId>org.matsim</groupId> <artifactId>matsim</artifactId> <version>${matsim.version}</version> </dependency> <!-- 其他依赖 --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1-jre</version> </dependency> </dependencies> </project> -
编写插件代码:
在
src/main/java目录下创建插件的主类。例如,创建一个名为MyPlugin的类:package com.example.matsim.plugin.example; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; import org.matsim.core.controler.OutputDirectoryHierarchy.OverwriteFileSetting; public class MyPlugin { public static void main(String[] args) { // 读取配置文件 Config config = ConfigUtils.loadConfig("path/to/config.xml"); // 创建控制器 Controler controler = new Controler(config); // 添加插件模块 controler.addOverridingModule(new MyModule()); // 设置输出目录策略 controler.getConfig().controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists); // 运行仿真 controler.run(); } } -
配置插件模块:
在
src/main/java目录下创建一个名为MyModule的类,实现org.matsim.core.config.ReflectiveModule接口,以配置插件模块:package com.example.matsim.plugin.example; import org.matsim.core.config.ReflectiveModule; public class MyModule extends ReflectiveModule { @Override public void install() { // 注册插件组件 bind(MyComponent.class).asEagerSingleton(); } } -
编写插件组件:
在
src/main/java目录下创建一个名为MyComponent的类,实现所需的插件功能。例如,创建一个简单的组件来记录仿真过程中的事件:package com.example.matsim.plugin.example; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.ActivityEndEvent; import org.matsim.api.core.v01.events.EventHandler; import org.matsim.api.core.v01.events.PersonEntersVehicleEvent; import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; import org.matsim.api.core.v01.population.Person; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.api.experimental.events.EventsManagerImpl; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; import org.matsim.core.events.handler.EventManager; import org.matsim.core.mobsim.framework.MobsimAfterSimStepListener; import org.matsim.core.mobsim.framework.MobsimListener; import org.matsim.core.mobsim.framework.events.MobsimAfterSimStepEvent; import java.util.HashMap; import java.util.Map; public class MyComponent implements EventHandler, MobsimListener, MobsimAfterSimStepListener { private final EventsManager eventsManager; private final Map<Id<Person>, Integer> personActivityCountMap; public MyComponent(EventsManager eventsManager) { this.eventsManager = eventsManager; this.personActivityCountMap = new HashMap<>(); this.eventsManager.addHandler(this); } @Override public void reset(int iteration) { personActivityCountMap.clear(); } @Override public void handleEvent(ActivityEndEvent event) { Id<Person> personId = event.getPersonId(); personActivityCountMap.put(personId, personActivityCountMap.getOrDefault(personId, 0) + 1); } @Override public void notifyMobsimAfterSimStep(MobsimAfterSimStepEvent event) { System.out.println("Simulation step: " + event.getIteration()); System.out.println("Person activity count: " + personActivityCountMap); } @Override public void notifyMobsimStartup(EventManager manager) { System.out.println("MyComponent started"); } @Override public void notifyMobsimShutdown() { System.out.println("MyComponent shutdown"); } public static void main(String[] args) { EventsManager eventsManager = new EventsManagerImpl(); MyComponent myComponent = new MyComponent(eventsManager); MatsimEventsReader eventsReader = new MatsimEventsReader(eventsManager); eventsReader.readFile("path/to/events.xml.gz"); } }
2. 事件处理与监听
MATSim 的事件处理机制允许开发者在仿真过程中捕获和处理各种事件,如活动结束、车辆进入交通等。通过实现 EventHandler 接口,用户可以自定义事件处理逻辑。此外,MobsimListener 接口提供了在仿真开始和结束时执行特定操作的能力。
2.1 事件处理
事件处理是 MATSim 仿真的一个核心机制。以下是一个简单的例子,展示了如何处理 ActivityEndEvent 事件:
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import org.matsim.api.core.v01.events.EventHandler;
import org.matsim.api.core.v01.population.Person;
import java.util.Map;
import java.util.HashMap;
public class ActivityEndEventHandler implements EventHandler {
private final Map<Id<Person>, Integer> personActivityCountMap;
public ActivityEndEventHandler() {
this.personActivityCountMap = new HashMap<>();
}
@Override
public void handleEvent(ActivityEndEvent event) {
Id<Person> personId = event.getPersonId();
personActivityCountMap.put(personId, personActivityCountMap.getOrDefault(personId, 0) + 1);
}
@Override
public void reset(int iteration) {
personActivityCountMap.clear();
}
public Map<Id<Person>, Integer> getActivityCounts() {
return personActivityCountMap;
}
}
2.2 事件监听
事件监听器可以在仿真开始和结束时执行特定的操作。以下是一个简单的例子,展示了如何在仿真开始和结束时记录日志:
package com.example.matsim.plugin.example;
import org.matsim.core.mobsim.framework.MobsimListener;
import org.matsim.core.mobsim.framework.events.MobsimAfterSimStepEvent;
import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent;
public class SimulationLogger implements MobsimListener, MobsimAfterSimStepListener {
@Override
public void notifyMobsimStartup(EventManager manager) {
System.out.println("Simulation started");
}
@Override
public void notifyMobsimShutdown() {
System.out.println("Simulation ended");
}
@Override
public void notifyMobsimAfterSimStep(MobsimAfterSimStepEvent event) {
System.out.println("Simulation step: " + event.getIteration());
}
}
3. 数据处理与分析
MATSim 提供了丰富的数据处理和分析工具,用户可以通过插件扩展这些功能。常见的数据处理任务包括读取和写入事件文件、处理仿真结果、生成报告等。
3.1 读取事件文件
读取 MATSim 仿真生成的事件文件是一个常见的数据处理任务。以下是一个简单的例子,展示了如何读取事件文件并处理 ActivityEndEvent 事件:
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import org.matsim.api.core.v01.events.EventHandler;
import org.matsim.api.core.v01.population.Person;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.events.MatsimEventsReader;
import java.util.Map;
import java.util.HashMap;
public class EventFileReader {
public static void main(String[] args) {
EventsManager eventsManager = EventsUtils.createEventsManager();
ActivityEndEventHandler handler = new ActivityEndEventHandler();
eventsManager.addHandler(handler);
MatsimEventsReader eventsReader = new MatsimEventsReader(eventsManager);
eventsReader.readFile("path/to/events.xml.gz");
Map<Id<Person>, Integer> activityCounts = handler.getActivityCounts();
System.out.println("Activity counts: " + activityCounts);
}
}
3.2 处理仿真结果
处理仿真结果是分析仿真数据的重要步骤。以下是一个简单的例子,展示了如何读取仿真生成的出行文件并计算出行距离的平均值:
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.api.core.v01.population.Route;
import org.matsim.core.router.util.TravelDisutility;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.io.IOUtils;
import org.matsim.core.utils.misc.OptionalTime;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;
import org.matsim.core.utils.geometry.transformations.Transformation;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
public class TripDistanceAnalyzer {
private final Map<Id<Person>, List<Double>> personTripDistances;
public TripDistanceAnalyzer() {
this.personTripDistances = new HashMap<>();
}
public void processTrips(String tripsFile) throws IOException {
BufferedReader reader = IOUtils.getBufferedReader(tripsFile);
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",");
if (parts.length >= 4) {
Id<Person> personId = Id.createPersonId(parts[0]);
double distance = Double.parseDouble(parts[3]);
personTripDistances.computeIfAbsent(personId, k -> new ArrayList<>()).add(distance);
}
}
}
public Map<Id<Person>, Double> calculateAverageTripDistances() {
Map<Id<Person>, Double> averageDistances = new HashMap<>();
for (Map.Entry<Id<Person>, List<Double>> entry : personTripDistances.entrySet()) {
double totalDistance = entry.getValue().stream().mapToDouble(Double::doubleValue).sum();
double averageDistance = totalDistance / entry.getValue().size();
averageDistances.put(entry.getKey(), averageDistance);
}
return averageDistances;
}
public static void main(String[] args) throws IOException {
TripDistanceAnalyzer analyzer = new TripDistanceAnalyzer();
analyzer.processTrips("path/to/trips.csv");
Map<Id<Person>, Double> averageDistances = analyzer.calculateAverageTripDistances();
System.out.println("Average trip distances: " + averageDistances);
}
}
4. 可视化与输出
MATSim 提供了多种可视化和输出工具,用户可以通过插件扩展这些功能。常见的可视化任务包括生成地图、轨迹图、热图等。输出任务包括生成 CSV 文件、GeoJSON 文件等。
4.1 生成地图
生成地图是可视化仿真结果的一种常用方法。以下是一个简单的例子,展示了如何生成一个包含道路网络和活动点的地图:
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.Node;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.network.io.MatsimNetworkReader;
import org.matsim.core.router.util.TravelDisutility;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.core.utils.geometry.transformations.Transformation;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;
import org.matsim.core.utils.io.IOUtils;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MapGenerator {
private final Network network;
private final Map<Id<Node>, Point> nodePoints;
private final Transformation transformation;
public MapGenerator(Network network, Transformation transformation) {
this.network = network;
this.transformation = transformation;
this.nodePoints = new HashMap<>();
for (Node node : network.getNodes().values()) {
Point point = transformation.transform(MGC.coord2Point(node.getCoord()));
nodePoints.put(node.getId(), point);
}
}
public SimpleFeatureCollection createNetworkFeatures() {
GeometryFactory geomFactory = JTSFactoryFinder.getGeometryFactory();
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
typeBuilder.setName("Link");
typeBuilder.setCRS(MGC.getCRS("EPSG:4326"));
typeBuilder.add("the_geom", Point.class);
typeBuilder.add("link_id", String.class);
SimpleFeatureType type = typeBuilder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
List<SimpleFeature> features = new ArrayList<>();
for (Link link : network.getLinks().values()) {
Point start = nodePoints.get(link.getFromNode().getId());
Point end = nodePoints.get(link.getToNode().getId());
Point midPoint = geomFactory.createPoint(start.getCoordinate().mid(end.getCoordinate()));
featureBuilder.add(midPoint);
featureBuilder.add(link.getId().toString());
SimpleFeature feature = featureBuilder.buildFeature(null);
features.add(feature);
}
return new org.geotools.data.collection.ListFeatureCollection(type, features);
}
public void generateMap(String shapefile) throws IOException {
SimpleFeatureCollection networkFeatures = createNetworkFeatures();
File file = new File(shapefile);
FileDataStoreFinder.getDataStore(file).createSchema(networkFeatures.getSchema());
Style style = SLD.createSimpleStyle(networkFeatures.getSchema());
MapContent map = new MapContent();
map.setTitle("Network Map");
Layer layer = new FeatureLayer(networkFeatures, style);
map.addLayer(layer);
StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
JMapFrame mapFrame = new JMapFrame(map);
mapFrame.setSize(800, 600);
mapFrame.enableToolBar();
mapFrame.enableLayerTable();
mapFrame.setVisible(true);
}
public static void main(String[] args) throws IOException {
Config config = ConfigUtils.loadConfig("path/to/config.xml");
Network network = new MatsimNetworkReader(config.network()).read();
Transformation transformation = TransformationFactory.getTransformation("WGS84", "EPSG:4326");
MapGenerator mapGenerator = new MapGenerator(network, transformation);
mapGenerator.generateMap("path/to/network.shp");
}
}
4.2 生成 CSV 文件
生成 CSV 文件是### 4.2 生成 CSV 文件
生成 CSV 文件是输出仿真结果的一种常用方法。MATSim 提供了多种工具来帮助用户生成和处理 CSV 文件,用户可以通过插件扩展这些功能。以下是一个简单的例子,展示了如何生成一个包含仿真过程中活动结束事件的 CSV 文件:
4.2.1 读取和处理事件
首先,我们需要读取仿真生成的事件文件,并处理 ActivityEndEvent 事件,将相关数据存储在一个数据结构中。我们已经在前面的章节中展示了如何读取事件文件,这里将重点放在生成 CSV 文件的部分。
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import org.matsim.api.core.v01.events.EventHandler;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.events.MatsimEventsReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
public class ActivityEndEventProcessor {
private final Map<Id<ActivityEndEvent>, ActivityEndEvent> activityEndEvents;
public ActivityEndEventProcessor() {
this.activityEndEvents = new HashMap<>();
}
public void processEvents(String eventsFile) {
EventsManager eventsManager = EventsUtils.createEventsManager();
ActivityEndEventHandler handler = new ActivityEndEventHandler();
eventsManager.addHandler(handler);
MatsimEventsReader eventsReader = new MatsimEventsReader(eventsManager);
eventsReader.readFile(eventsFile);
this.activityEndEvents.putAll(handler.getActivityEndEvents());
}
public Map<Id<ActivityEndEvent>, ActivityEndEvent> getActivityEndEvents() {
return activityEndEvents;
}
public static void main(String[] args) {
ActivityEndEventProcessor processor = new ActivityEndEventProcessor();
processor.processEvents("path/to/events.xml.gz");
Map<Id<ActivityEndEvent>, ActivityEndEvent> activityEndEvents = processor.getActivityEndEvents();
System.out.println("Activity end events: " + activityEndEvents);
}
}
4.2.2 生成 CSV 文件
接下来,我们编写一个方法来生成 CSV 文件,将处理后的 ActivityEndEvent 事件数据写入文件中。
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
public class CSVWriter {
public void writeActivityEndEventsToCSV(Map<Id<ActivityEndEvent>, ActivityEndEvent> activityEndEvents, String csvFile) throws IOException {
try (FileWriter writer = new FileWriter(csvFile)) {
// 写入 CSV 文件的头
writer.append("person_id,activity_type,end_time,link_id\n");
// 写入每个事件的数据
for (ActivityEndEvent event : activityEndEvents.values()) {
writer.append(event.getPersonId().toString())
.append(",")
.append(event.getActType())
.append(",")
.append(Double.toString(event.getTime()))
.append(",")
.append(event.getLinkId().toString())
.append("\n");
}
}
}
public static void main(String[] args) throws IOException {
ActivityEndEventProcessor processor = new ActivityEndEventProcessor();
processor.processEvents("path/to/events.xml.gz");
Map<Id<ActivityEndEvent>, ActivityEndEvent> activityEndEvents = processor.getActivityEndEvents();
CSVWriter csvWriter = new CSVWriter();
csvWriter.writeActivityEndEventsToCSV(activityEndEvents, "path/to/activity_end_events.csv");
System.out.println("CSV file generated successfully at path/to/activity_end_events.csv");
}
}
4.2.3 综合示例
为了更好地理解整个流程,以下是一个综合示例,展示了如何从事件文件中读取 ActivityEndEvent 事件,并将其写入 CSV 文件中。
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.ActivityEndEvent;
import org.matsim.api.core.v01.events.EventHandler;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.events.MatsimEventsReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
public class ActivityEndEventToCSV {
private final Map<Id<ActivityEndEvent>, ActivityEndEvent> activityEndEvents;
public ActivityEndEventToCSV() {
this.activityEndEvents = new HashMap<>();
}
public void processEvents(String eventsFile) {
EventsManager eventsManager = EventsUtils.createEventsManager();
ActivityEndEventHandler handler = new ActivityEndEventHandler();
eventsManager.addHandler(handler);
MatsimEventsReader eventsReader = new MatsimEventsReader(eventsManager);
eventsReader.readFile(eventsFile);
this.activityEndEvents.putAll(handler.getActivityEndEvents());
}
public void writeActivityEndEventsToCSV(String csvFile) throws IOException {
try (FileWriter writer = new FileWriter(csvFile)) {
// 写入 CSV 文件的头
writer.append("person_id,activity_type,end_time,link_id\n");
// 写入每个事件的数据
for (ActivityEndEvent event : activityEndEvents.values()) {
writer.append(event.getPersonId().toString())
.append(",")
.append(event.getActType())
.append(",")
.append(Double.toString(event.getTime()))
.append(",")
.append(event.getLinkId().toString())
.append("\n");
}
}
}
public static void main(String[] args) throws IOException {
ActivityEndEventToCSV processor = new ActivityEndEventToCSV();
processor.processEvents("path/to/events.xml.gz");
processor.writeActivityEndEventsToCSV("path/to/activity_end_events.csv");
System.out.println("CSV file generated successfully at path/to/activity_end_events.csv");
}
}
5. 高级功能
MATSim 的高级功能包括多模式交通仿真、动态交通管理、多代理仿真等。这些功能可以通过插件系统进行扩展和定制,以满足复杂的仿真需求。
5.1 多模式交通仿真
多模式交通仿真允许用户在同一个仿真中模拟多种交通模式,如私人汽车、公共交通、自行车和步行等。以下是一个简单的例子,展示了如何添加多模式交通仿真支持:
package com.example.matsim.plugin.example;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.Population;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.Controler;
import org.matsim.core.population.io.PopulationReader;
import org.matsim.core.population.io.PopulationWriter;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime;
import org.matsim.core.trafficmonitoring.TrafficMonitoringConfigGroup;
import org.matsim.core.trafficmonitoring.TrafficMonitoringUtils;
import org.matsim.core.trafficmonitoring.TrafficStats;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;
import org.matsim.core.utils.geometry.transformations.Transformation;
import org.matsim.core.router.util.TravelDisutility;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.router.util.LeastCostPathCalculator;
import org.matsim.core.router.util.Dijkstra;
import org.matsim.core.router.util.TravelDisutilityFactory;
import org.matsim.core.router.util.TravelTimeCalculator;
import org.matsim.core.router.util.FreeSpeedTravelTime;
import org.matsim.core.router.util.TravelDisutility;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.router.util.LeastCostPathCalculator;
import org.matsim.core.router.util.Dijkstra;
import org.matsim.core.router.util.TravelDisutilityFactory;
import org.matsim.core.router.util.TravelTimeCalculator;
import org.matsim.core.router.util.FreeSpeedTravelTime;
import org.matsim.core.router.util.TravelDisutility;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.router.util.LeastCostPathCalculator;
import org.matsim.core.router.util.Dijkstra;
import org.matsim.core.router.util.TravelDisutilityFactory;
import org.matsim.core.router.util.TravelTimeCalculator;
import org.matsim.core.router.util.FreeSpeedTravelTime;
public class MultiModeSimulation {
public static void main(String[] args) {
// 读取配置文件
Config config = ConfigUtils.loadConfig("path/to/config.xml");
// 创建场景
Scenario scenario = ScenarioUtils.loadScenario(config);
// 获取网络和人口
Network network = scenario.getNetwork();
Population population = scenario.getPopulation();
// 创建控制器
Controler controler = new Controler(scenario);
// 添加多模式交通支持
controler.addOverridingModule(new MultiModeModule());
// 设置输出目录策略
controler.getConfig().controler().setOverwriteFileSetting(OverwriteFileSetting.deleteDirectoryIfExists);
// 运行仿真
controler.run();
}
}
class MultiModeModule extends ReflectiveModule {
@Override
public void install() {
// 注册多模式交通组件
bind(TravelDisutility.class).to(FreeSpeedTravelTime.class);
bind(TravelTime.class).to(FreeSpeedTravelTime.class);
bind(LeastCostPathCalculator.class).to(Dijkstra.class);
bind(TravelDisutilityFactory.class).toInstance(new TravelDisutilityFactory() {
@Override
public TravelDisutility createTravelDisutility(TravelTime travelTime) {
return new FreeSpeedTravelTime();
}
});
}
}
6. 插件发布与共享
开发完插件后,用户可以将其发布到 Maven 中央仓库或其他私有仓库,以便其他用户可以轻松地使用和依赖这些插件。
6.1 发布到 Maven 中央仓库
-
配置
pom.xml:确保
pom.xml文件中包含必要的发布配置,如distributionManagement和scm信息。<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>matsim-plugin-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>MATSim Plugin Example</name> <url>http://matsim.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <matsim.version>12.0</matsim.version> </properties> <dependencies> <dependency> <groupId>org.matsim</groupId> <artifactId>matsim</artifactId> <version>${matsim.version}</version> </dependency> <!-- 其他依赖 --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1-jre</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <version>3.0.0</version> <configuration> <repositoryId>central</repositoryId> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> </configuration> </plugin> </plugins> </build> <distributionManagement> <repository> <id>sonatype-nexus-staging</id> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> </repository> <snapshotRepository> <id>sonatype-nexus-snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> </snapshotRepository> </distributionManagement> <scm> <url>https://github.com/yourusername/matsim-plugin-example</url> <connection>scm:git:https://github.com/yourusername/matsim-plugin-example.git</connection> <developerConnection>scm:git:https://github.com/yourusername/matsim-plugin-example.git</developerConnection> </scm> </project> -
发布插件:
使用 Maven 命令行工具发布插件。在命令行中,执行以下命令:
mvn clean deploy
6.2 发布到私有仓库
如果用户希望将插件发布到私有仓库,可以按照以下步骤进行:
-
配置
pom.xml:修改
pom.xml文件中的distributionManagement配置,指向私有仓库的 URL。<distributionManagement> <repository> <id>your-private-repo</id> <url>https://your-private-repo.example.com/repository/maven-releases/</url> </repository> <snapshotRepository> <id>your-private-repo</id> <url>https://your-private-repo.example.com/repository/maven-snapshots/</url> </snapshotRepository> </distributionManagement> -
发布插件:
使用 Maven 命令行工具发布插件。在命令行中,执行以下命令:
mvn clean deploy
7. 总结
通过 MATSim 的插件系统,用户可以轻松地扩展和定制软件的基本功能,以满足特定的研究和应用需求。本文档介绍了插件的基本结构、创建插件项目、事件处理与监听、数据处理与分析、可视化与输出以及插件的发布与共享。希望这些内容能帮助用户更好地理解和使用 MATSim 的插件系统。

更多推荐




所有评论(0)