【问题标题】:Can the Repast NetworkBuilder be used in Geography and GIS Displays?Repast NetworkBuilder 可以在地理和 GIS 显示中使用吗?
【发布时间】:2017-08-24 04:08:59
【问题描述】:

流行的 Repast 僵尸教程使用 java 使用 NetworkBuilder,可让您可视化感染网络。我想知道是否有任何类似的东西可以与地理/GIS 上下文一起使用。或者,对我如何构建自己的想法有什么想法吗?例如,如果我的代理从 A 点移动到 B 点,我可以编写一个函数来绘制一个连接两者的向量吗?

【问题讨论】:

    标签: repast-simphony


    【解决方案1】:

    我编写了一个投影侦听器类,它将管理地理投影中的 Repast 网络对象,可以在 GIS 显示中可视化。附加的侦听器类可以放置在您的项目中,并在 ContextBuilder 中用于链接地理和网络投影,如下所示:

    GeographyParameters geoParams = new GeographyParameters(); 
    Geography geography = GeographyFactoryFinder.createGeographyFactory(null).createGeography("Geography", context, geoParams);
    
    NetworkBuilder<Object> netBuilder = new NetworkBuilder<Object>("Network", context, true);
    Network net = netBuilder.buildNetwork();
    
    GISNetworkListener netListener = new GISNetworkListener(context, geography, net);
    

    GIS NetworkListener 将地理和网络绑定在指定的上下文中,以便其中一个的更改将反映在另一个中。这将处理地理上的代理移动、添加和删除以及网络添加/删除边缘事件。如果您有多个网络,您可以为每个网络创建单独的侦听器实例。只要 Repast 网络和地理投影在您的代码中正常使用,就不需要额外的代码来更新投影之间的事件。

    要在 GIS 显示中可视化网络边缘,您需要创建一个扩展 RepastEdge 的简单边缘类,例如附加的 MyNetworkEdge 类。这只是因为显示向导需要一个用户类来设置样式。在显示中,您可以在代理类型对话框中选择 MyNetworkEdge 类,并指定线型或样式类,如附加的 MyNetworkStyle 类。要在 Repast 网络中创建链接,您需要使用 MyNetworkEdge 的添加和删除边缘方法,例如

    net.addEdge(new MyNetworkEdge(source, target));
    

    您当然可以根据需要向 MyNetworkEdge 类添加更多功能。

    ProjectionListener 类:

    package geography;
    
    import com.vividsolutions.jts.geom.Coordinate;
    import com.vividsolutions.jts.geom.GeometryFactory;
    import com.vividsolutions.jts.geom.LineString;
    import com.vividsolutions.jts.geom.MultiLineString;
    
    import repast.simphony.context.Context;
    import repast.simphony.space.gis.Geography;
    import repast.simphony.space.graph.Network;
    import repast.simphony.space.graph.RepastEdge;
    import repast.simphony.space.projection.ProjectionEvent;
    import repast.simphony.space.projection.ProjectionListener;
    
    /**
     * A ProjectionListener implementation for managing Repast network edges in a
     * Repast geography projection.  This listener responds to both geography event
     * and network events.
     * 
     * @author Eric Tatara
     *
     */
    public class GISNetworkListener implements ProjectionListener {
    
        Context context;
        Network network;
        Geography geography;
        GeometryFactory fac = new GeometryFactory();
    
        public GISNetworkListener(Context c, Geography g, Network n) {
            context = c;
            network = n;
            geography = g;
    
            network.addProjectionListener(this);
            geography.addProjectionListener(this);
        }
    
        @Override
        public void projectionEventOccurred(ProjectionEvent evt) {
    
            // When an object is moved in the geography, its network edges positions 
            // should be updated if the object has edges.
            if (evt.getType() == ProjectionEvent.OBJECT_MOVED){
                Iterable<RepastEdge> edges = network.getEdges(evt.getSubject());
    
                if (edges != null){
                    for (RepastEdge e : edges){
                        // Get the existing geometry for this edge
                        MultiLineString lineFeature = (MultiLineString)geography.getGeometry(e);
    
                        Coordinate sourceCoord = geography.getGeometry(e.getSource()).getCoordinate();
                        Coordinate targetCoord = geography.getGeometry(e.getTarget()).getCoordinate();
    
                        Coordinate coords[] = lineFeature.getCoordinates();
    
                        // Update the edge coordinates based on the source and target object 
                        // (agent) coordinates.
                        coords[0].setCoordinate(sourceCoord);
                        coords[1].setCoordinate(targetCoord);
                    }
                }
            }
    
            // When a Repast network edge is added, create a new MultiLineString geometry
            // to represent the edge in the geography.
            else if (evt.getType() == ProjectionEvent.EDGE_ADDED){  
                RepastEdge e = (RepastEdge)evt.getSubject();
    
                Coordinate sourceCoord = geography.getGeometry(e.getSource()).getCoordinate();
                Coordinate targetCoord = geography.getGeometry(e.getTarget()).getCoordinate();
    
                LineString lineString = fac.createLineString(new Coordinate[]{sourceCoord, 
                        targetCoord});
    
                MultiLineString mls = fac.createMultiLineString(new LineString[]{lineString});
    
                context.add(e);
                geography.move(e, mls);
            }
    
            // When a Repast edge remove event occurs, remove the edge geometry from the 
            // geography and the context.  This should also occur automatically when agents
            // are removed from a context or network.
            else if (evt.getType() == ProjectionEvent.EDGE_REMOVED){
                RepastEdge e = (RepastEdge)evt.getSubject();
    
                geography.move(e, null);
                context.remove(e);          
            }
        }
    }
    

    RepastEdge 类:

    package geography;
    
    import repast.simphony.space.graph.RepastEdge;
    
    public class MyNetworkEdge extends RepastEdge {
    
        public MyNetworkEdge(Object source, Object target){
            super(source, target, false);
        }
    
    }
    

    网络风格类:

    package geography;
    
    import gov.nasa.worldwind.render.SurfacePolyline;
    import gov.nasa.worldwind.render.SurfaceShape;
    
    import java.awt.Color;
    
    import repast.simphony.visualization.gis3D.style.SurfaceShapeStyle;
    
    /**
     * Style for MyNetworkEdges.
     * 
     * @author Eric Tatara
     *
     */
    public class MyNetworkStyle implements SurfaceShapeStyle<MyNetworkEdge>{
    
        @Override
        public SurfaceShape getSurfaceShape(MyNetworkEdge object, SurfaceShape shape) {
          return new SurfacePolyline();
        }
    
        @Override
        public Color getFillColor(MyNetworkEdge obj) {
            return null;
        }
    
        @Override
        public double getFillOpacity(MyNetworkEdge obj) {
            return 0;
        }
    
        @Override
        public Color getLineColor(MyNetworkEdge obj) {
            return Color.BLUE;
        }
    
        @Override
        public double getLineOpacity(MyNetworkEdge obj) {
            return 1.0;
        }
    
        @Override
        public double getLineWidth(MyNetworkEdge obj) {
            return 2;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 2021-05-25
      • 1970-01-01
      • 2015-05-30
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多