Map中图层的控制是很多人首先关心的问题,因为根据业务来切换图层的状态是经常遇到的一种需求。
首先让我们看一下对图层可见性的控制,Layer本身就有一个visible属性,这个属性指示的就是当前图层是否在Map中显示。不管是MapServiceLayer还是GraphicLayer,如果设置了visible为false,那么在这个图层是不会被显示的。
除了控制图层是否显示,我们还可以控制图层的透明度,这是由Layer的alpha属性来控制的。这样我们可以将多个图层叠加复合显示,这时候会给用户一种复合的多信息量的地图:
图 22 多图层透明复合效果
另外,图层的叠放顺序也是一个经常遇到的问题,在ArcGIS Flex API中,后加入的地图被放置在最上层,同时,最底层的索引(index)为0。
图 23 Map中Layer的存放顺序
Map中有一个layers属性存放了地图中所有Layer的集合,另外还有layerIds属性存放了对应的所有Layer的id的集合,每当添加一个Layer到Map中的时候,ArcGIS Flex API会给这个图层一个id并存放到layerIds中保存。通过调用Map的reorderLayer方法可以给这些图层重新排序。
下面我们在Map中添加3个图层,并在点击地图的时候把最上层的图层移到底层,从而实现图层叠置顺序的改变:
这里RemoteObject的destination属性对应的是在“remoting-config.xml”中配置的Java类的id,这时,你就可以近似把这个名为roWind的RemoteObject对象当成Wind这个Java类了。通过roWind.getOperation("getEffectZones")你就可以“获得”Wind类的getEffectZones方法(实际上是一个Flex中的AbstractOperation对象),这个方法可以是带参数的。最后,通过调用AbstractOperation对象的send方法,你就相当于调用了服务器端Wind类的getEffectZones方法,接下来的事情就是去监听相应的ResultEvent事件从而去处理服务器端Java类返回的结果了。
下面是通过RemoteObject调用该Java类并返回的结果:
图 36 RemoteObject的使用
Flex应用是客户端应用,本身肯定是不能调用AO的,所谓调AO也就是将Flex端的数据发送到服务器上使用AO进行处理。我经常被问的一个问题就是:到底能不能用ArcGIS Flex API进行数据编辑,以前我一般回答不推荐使用Flex进行编辑。如果光从技术角度讲,我也曾经使用过WFS-T、GP服务、ADF等方法实现了编辑,所以实在要问我应该怎么在Flex中做数据编辑,我一般会说,那就自己做个Web应用去接收Flex发来的数据再解析、保存吧。
现在有了BlazeDS,上面的过程就可以被简化了。从上一小节我们已经知道如何使用BlazeDS来调用服务器端的Java方法,那么顺理成章,我们接着在这些方法中再调用AO[1] 就可以实现保存编辑等功能了。
比如我们在ArcGIS Flex API中使用Draw工具绘制了一个MapPoint,随即要把这个点保存到服务中,那么首先我们需要把这个MapPoint对象作为一个参数通过BlazeDS的AMF发送到服务器,在服务器端我们实现了这样一个Java类:
public class AGSServer
{
private IServerContext serverContext = null ;
public IServerContext getServerContext()
{
if ( serverContext==null )
{
try
{
ServerInitializer initializer = new ServerInitializer();
initializer.initializeServer("*", "wuyf", "pwd");
ServerConnection conn = new ServerConnection();
conn.connect("localhost");
IServerObjectManager som = conn.getServerObjectManager();
serverContext = som.createServerContext("Demo/demo", "MapServer");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
return serverContext;
}
public boolean addPoint(ASObject asObj)
{
boolean result = false ;
try
{
IServerContext serverContext = this .getServerContext();
IServerObject so = serverContext.getServerObject();
MapServer mapServer = (MapServer)so;
IFeatureLayer feaLayer =
(IFeatureLayer)mapServer.getLayer(mapServer.getMapName(0), 0);
IFeatureClass feaClass = feaLayer.getFeatureClass();
IFeature fea = feaClass.createFeature();
IPoint pt = AGSFlexToAOUtil.MapPointToAO(asObj, serverContext);
fea.setShapeByRef(pt);
fea.store();
mapServer.refreshServerObjects();
result = true ;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return result;
}
}
上面的代码主要功能就是在我本机的“Demo/demo”这个地图服务中使用AO接口保存点要素。其中addPoint方法是保存点要素的主要方法,其参数asObj对应的是Flex中的MapPoint,asObj是一个ASObject对象,它是一个继承自HashMap的类,所有Flex中的结构都会被映射成一系列的键值对应,然后发送到服务器。我们根据自己的需要,通过对ASObject对象的解析就可以得到相应的AO对象了。
这里我还新建了一个AGSFlexToAOUtil类专门用于转化ASObject对象到AO对象,MapPointToAO方法就是负责转化Flex中的MapPoint到AO的IPoint的,这个方法的代码如下:
static public IPoint MapPointToAO(ASObject asObj, IServerContext scxt) throws Exception
{
Point pt = (Point)scxt.createObject(Point.getClsid ());
double x = Double.valueOf (asObj.get("x").toString());
double y = Double.valueOf (asObj.get("y").toString());
pt.putCoords(x, y);
return pt;
}
类似的,我还分别构造了PolylineToAO、PolygonToAO方法用以转化Flex传来的Polyline、Polygon对象为AO对象。下面是在Flex中对地图服务图层进行编辑并保存后的效果:
图 37 通过调用AO保存客户端编辑
下面是使用ArcGIS Flex API开发的一个输电输气管道监控管理系统的Demo,让我们试着从这个Demo去直观地了解在面对具体的业务时,ArcGIS Flex API可以发挥什么样的作用。
图 38 查看温度分布
图 39 降水、美国国家气象局警报
图 40 查看输气管道的泄漏情况
图 41 查看输气泄漏的统计情况
图 42 查看调度指令并可在新窗口中查看外部MIS系统
图 43 查看实时的道路交通情况
[1] 注意在服务器应用中添加arcojects.jar包的支持