OpenScales实现的思想:
先画一下大概的体系结构图:
下面先说一下OpenScales的大体实现思想,OpenScales将各种GIS上的类,如map,layer,bounds,control,handler都再封装一下,封装后的类继承自Group或者UIComponent,然后持有封装前的类作为属性。例如:FxBounds是对Bounds的封装,FxBounds继承自UIComponent,然后有一个属性是Bounds。这样的好处就使继承自UIComponent后可以直接写在MXML标签中,而且访问其bounds属性可以得到值。所以我们看到的主页面就是这样一种情况:
<fx1:FxMap id="fxmap" height="100%" width="100%" proxy="http://openscales.org/proxy.php?url=">
<fx1:FxMaxExtent west="5.60075" south="47.2441" east="15.425" north="55.0317" projection="EPSG:4326" />
<layer:FxWMS name="Germany" url="http://wms.wheregroup.com/cgi-bin/mapserv?map=/data/umn/germany/germany.map"
layers="Germany" format="image/jpeg" />
<fx1:FxExtent west="5.60075" south="47.2441" east="15.425" north="55.0317" projection="EPSG:4326" />
<mouse:FxDragHandler/>
<mouse:FxWheelHandler/>
<control:PanZoom x="10" y="10"/>
</fx1:FxMap>
application下加入FxMap(继承自Group),然后将layer,extent,control甚至handler(当然都是封装后的,例如layer封装成FxLayer)一股脑的以child的形式加入到FxMap中。不仅构建方便而且一目了然。
下面分析一下这些组件以child加入FxMap后如何发挥作用。这里最重要的代码就是FxMap的onCreationComplete函数,当FxMap和各种它的child都初始化完之后,将执行onCreationComplete函数,这个函数做了以下几件事:
1.初始化map,然后加入到FxMap里
this._map = new Map(this.width, this.height);
var mapContainer:SpriteVisualElement = new SpriteVisualElement();
this.addElementAt(mapContainer, 0);
mapContainer.addChild(this._map);
2.遍历FxMap的child,如果child的类型是:FxMaxExtent,则将FxMaxExtent的bounds属性赋给map的maxExtent属性。
this._map.maxExtent = (element as FxMaxExtent).bounds;
3.再次遍历FxMap的child,如果child的类型是:
FxLayer,则执行FxMap.addFxLayer,进而执行map.addLayer()。这也是最重要最复杂的一块,在后面详细讲
FxControl,则执行FxMap.map.addControl()
IControl,则执行FxMap.map.addControl(),
后两者的区别暂时还没研究
for(i=0; i<this.numElements; i++) {
element = this.getElementAt(i);
if (element is FxLayer) {
this.addFxLayer(element as FxLayer);
} else if (element is FxControl) {
this._map.addControl((element as FxControl).control);
} else if (element is IControl) {
this._map.addControl(element as IControl, false);
}
}
4.再遍历,如果是FXAbstractSecurity,将security和map,layer联系上,说明security也可以像layer、control什么的都以mxml标签的形式加入到FxMap里。使用起来很方便。
5.接下来的重要代码是:
if (mapCenter || (! isNaN(this._zoom))) {
this._map.moveTo(mapCenter, this._zoom);
}
说它重要是因为,显示图层的代码就在map.moveTo里。
加载第一个图层时执行完map.addlayer后就已经显示出来了,因为第一个图层被设置为baselayer,在setbaselayer函数中有map.moveTo,所以显示了出来。
而如果在FxMap中加了两个图层,第二个图层在执行map.addlayer时并不会显示,到上面的代码部分才会显示出来。
6.再次遍历,若果child中有FxExtent,则将map缩放到定义的FxExtent。
for(i=0; (!extentDefined) && (i<this.numElements); i++) {
element = this.getElementAt(i);
if (element is FxExtent) {
this._map.zoomToExtent((element as FxExtent).bounds);
extentDefined = true;
}
}
7.前面layer,extent,control都和map有上联系了,可是handler还没联系上,所以最后,调用setMapRecursively(this)。这个函数的作用就是,将FxMap下的child和child的child如果是control或者handler的都和map联系起来。这里就明白了为什么FxHandler以标签的形式加入到FxMap里就能体现它的功能。