AnyLogic中追踪行驶卡车所在GIS区域的问题及进阶需求
AnyLogic GIS区域追踪与Agent统计问题排查
问题描述
我在地图上设置了一系列GIS Point,Truck Agent会在这些点之间随机行驶。地图内存在一系列互不重叠的GIS Region(类似县/州级区域),我希望追踪Truck在行驶过程中所处的GIS Region。
我的方案是在Truck Agent中创建一个名为county的GIS Region变量,将代码放在On step字段而非On startup字段,代码如下:
county = main.map.searchFirstRegion(address);
现在出现以下错误:
main cannot be resolved address cannot be resolved to a variable
我是AnyLogic新手,请问如何排查这些错误?
额外需求:
若将每个GIS Region设置为County Agent,我不确定如何计算该Agent的变量,即统计当前处于该GIS Region内的所有Truck Agent总和(如区域内卡车数量、总货运重量)。
一、错误排查与修复
1. 解决main cannot be resolved错误
- 确认顶层主Agent(包含地图的那个Agent)的名称确实是
main。如果主Agent改名了,比如叫MainModel,代码里的main要同步改成对应名称。 - 如果Truck Agent嵌套在其他子Agent中,不能直接用
main访问顶层Agent,改用getMain()方法,代码调整为:county = getMain().map.searchFirstRegion(...);
2. 解决address cannot be resolved to a variable错误
searchFirstRegion()方法需要的是当前Truck的位置信息,而非未定义的address变量。你可以直接用this指代Truck Agent本身(移动Agent自带位置属性),或者明确传递坐标:// 方式1:直接传递Truck对象 county = getMain().map.searchFirstRegion(this); // 方式2:传递坐标值 county = getMain().map.searchFirstRegion(getX(), getY());
3. 额外注意事项
- 将代码放在On step字段是合理的,能实时追踪位置变化,但可根据模型需求调整执行频率,避免性能浪费。
- 确保地图组件的名称确实是
map,如果地图改名,代码里也要对应修改。
二、County Agent统计实现方案
如果把每个GIS Region封装为County Agent,统计区域内卡车数量、总货运重量可按以下两种方式实现:
方法一:Truck主动上报(性能更优)
前置准备
- 在主Agent中创建
Map<GISRegion, County>类型的变量(比如叫regionToCounty),遍历所有GIS Region,为每个Region创建对应的County Agent,并将Region与County的映射关系存入该Map。 - 在Truck Agent中添加
lastCounty变量(类型为County),记录上一次所在的County。
- 在主Agent中创建
实时更新逻辑(放在Truck的On step字段)
// 获取当前所在的GIS Region GISRegion currentRegion = getMain().map.searchFirstRegion(this); // 通过映射关系找到对应的County Agent County currentCounty = getMain().regionToCounty.get(currentRegion); // 当所在区域变化时更新统计数据 if (currentCounty != lastCounty) { // 离开上一个区域时,减少对应统计值 if (lastCounty != null) { lastCounty.truckCount--; lastCounty.totalCargoWeight -= this.cargoWeight; } // 进入新区域时,增加对应统计值 if (currentCounty != null) { currentCounty.truckCount++; currentCounty.totalCargoWeight += this.cargoWeight; } // 更新上一次所在区域记录 lastCounty = currentCounty; }
方法二:County Agent主动扫描(实现简单)
- 在County Agent中添加变量:
int truckCount、double totalCargoWeight,分别记录区域内卡车数量和总货运重量。 - 添加循环事件:设置合适的执行间隔(比如1秒),在事件中编写统计代码:
注意:这种方法适合小规模模型,若卡车数量较多,频繁扫描会影响性能。// 统计区域内卡车数量 truckCount = getMain().trucks.stream() .filter(truck -> this.gisRegion.contains(truck.getX(), truck.getY())) .count(); // 统计区域内总货运重量 totalCargoWeight = getMain().trucks.stream() .filter(truck -> this.gisRegion.contains(truck.getX(), truck.getY())) .mapToDouble(truck -> truck.cargoWeight) .sum();
内容的提问来源于stack exchange,提问作者Jack Nelson
相关产品推荐
相关产品推荐

