如何在AnyLogic中创建圆形GIS Region及调用Java函数?
餐厅配送GIS区域问题解答
1. 圆形GIS Region创建与替代方案
AnyLogic没有原生的圆形GIS Region构造方法,因为GIS Region本质基于多边形实现。你可以用以下方案解决:
- 多边形近似圆形:生成顶点足够多的正多边形(比如36个顶点)模拟圆形,精度完全满足配送场景。用代码生成对应地理坐标的顶点列表,再初始化GIS Region。示例代码(餐厅坐标为
restaurantLat, restaurantLon,半径4km):int numVertices = 36; double radiusKm = 4; List<Point> circlePoints = new ArrayList<>(); Projection projection = gisMap.getProjection(); for (int i = 0; i < numVertices; i++) { double angle = Math.toRadians(i * 360.0 / numVertices); // 计算相对餐厅的偏移坐标(米) double dx = radiusKm * 1000 * Math.cos(angle); double dy = radiusKm * 1000 * Math.sin(angle); // 转换为地理坐标 Point planePoint = projection.toPlane(new Point(restaurantLon, restaurantLat)); Point geoPoint = projection.toGeo(new Point(planePoint.x + dx, planePoint.y + dy)); circlePoints.add(geoPoint); } GISRegion circularDeliveryArea = new GISRegion(circlePoints, projection); - 距离判断法(无需预定义区域):直接生成随机地理点,计算该点与餐厅的直线距离,小于4km则视为有效客户位置。示例代码:
// 生成随机点范围设为餐厅周围的大致矩形(可根据纬度调整偏移量) double minLon = restaurantLon - 0.05; double maxLon = restaurantLon + 0.05; double minLat = restaurantLat - 0.05; double maxLat = restaurantLat + 0.05; Point randomPoint = new Point(random(minLon, maxLon), random(minLat, maxLat)); double distanceKm = gisMap.getDistance(restaurantPoint, randomPoint) / 1000; if (distanceKm <= 4) { // 该点属于配送区域,生成客户 } - 转换绘制的Circle为GIS Region:如果你已经画了Circle形状,先获取它的顶点,再转换为地理坐标后创建GIS Region:
Circle drawnCircle = circle; // 你的Circle组件名称 List<Point> shapePoints = drawnCircle.getPoints(); Projection projection = gisMap.getProjection(); List<Point> geoPoints = new ArrayList<>(); for (Point p : shapePoints) { // 将Shape的屏幕坐标转换为地理坐标 Point geoPoint = gisMap.toGeo(p); geoPoints.add(geoPoint); } GISRegion circleRegion = new GISRegion(geoPoints, projection);
2. GIS Region的area()函数使用与形状转换
转换绘制形状为GIS Region
- 直接转换GIS多边形:如果是在GIS地图上绘制的
Polygon组件,直接通过代码初始化:
部分AnyLogic版本也支持在Polygon组件的属性面板中,直接将其类型设置为"GIS Region"。GISRegion myRegion = new GISRegion(polygon.getPoints(), gisMap.getProjection()); - 普通Shape转GIS Region:参考上面的Circle转换代码,核心是将Shape的屏幕坐标通过
gisMap.toGeo()转换为地理坐标,再传入GISRegion构造方法。
运行area()函数
GISRegion类自带area()方法,返回区域的平方米面积。使用示例:
// 假设已经有初始化好的GISRegion对象deliveryArea double areaSqM = deliveryArea.area(); double areaSqKm = areaSqM / 1000000; // 转换为平方公里 // 输出结果到控制台 traceln("配送区域面积:" + areaSqKm + " 平方公里");
代码可以放在模型启动事件(Main的onStartup)、自定义按钮的点击事件,或者需要计算面积的逻辑节点中,运行时会自动执行。
内容的提问来源于stack exchange,提问作者Nikhil Sathwik Kandregula
相关产品推荐
相关产品推荐

