要完全从0开始实现3D环境下的Map Control当然也可以,不过既然已经有了ArcGIS Server Flex API的Map Control,并且还有一整套现成的功能,那么将ArcGIS Server Flex API的Map Control加到PV3D的环境中是一个不错的选择。
但是要实现也不是非常容易的事情,在测试的过程中发现了一些问题。
①3D环境下显示Map Control必须保证同样添加到2D环境下,但是无法隐藏2D环境下的Map Control,或者是隐藏了2D环境下的Map Control,3D环境下显示的Map Control默认事件(双击、滚轮、移动)就无效;
②在Map Control上绘制图形对象会发生偏移,和鼠标点击的位置不一致。
最终的解决方法:将Map Control作为Plane的MovieMaterial,Map Control并不是直接加到MovieMaterial中,而是通过MovieClip,并且用一个ParentMovie Clip处理2D环境下的Map Control的隐藏,这样既能在2D环境下隐藏Map Control,还会保证Map Control在3D环境下保留原先的功能。
//add esri map control to pv3d environment
movie.addChild(map);
mat = new MovieMaterial(movie, true, true, false, new Rectangle(0, 0, m_pv3dwidth, m_pv3dheight));
mat.smooth=true;
m_baseMapPlane = new Plane(mat, m_pv3dwidth, m_pv3dheight, 20, 20);
//make esri map control invisible in flex 2d environment
movieParent.addChild(movie);
movieParent.alpha = 0;
pv3d.rawChildren.addChild(movieParent);
图形的绘制要在Map Control没有变形的时候进行,能够保证所绘即所得。
柱状图(createBarChartHeatMap)、饼状图(createPieChartHeatMap)的实现原理:通过QueryTask查询出需要做专题的对象,通过PV3D绘制出3D的柱状(Cube 3D object)、饼状(Cylinder 3D object)。考虑到柱状图和饼状图的三维效果,要对Cube、Cylinder不同面以不同的方式渲染。
柱状专题图
//create chart map materia list
matList.addMaterial(red, "front");
matList.addMaterial(red, "back");
matList.addMaterial(blue, "left");
matList.addMaterial(blue, "right");
matList.addMaterial(green, "top");
matList.addMaterial(green, "bottom");
var pvCube:Cube = new Cube(matList, 20, 2 * pv3dz, 20);
饼状专题图
var pvCylinder:Cylinder = new Cylinder(null, pv3dz / 1.5, 15, 20, 1, pv3dz / 1.5, true, true);
var bottomMaterial:ColorMaterial = new ColorMaterial(0xff0000);
var middleMaterial:ColorMaterial = new ColorMaterial(0x0000ff);
var topMaterial:ColorMaterial = new ColorMaterial(0xff0000);
var i:int;
//this is the bottom face
for (i = 0; i < 18; i++)
{
pvCylinder.geometry.faces[i].material = bottomMaterial;
}
//the middle of the cylinder
for (i = 18; i < pvCylinder.geometry.faces.length - 18; i++)
{
pvCylinder.geometry.faces[i].material = middleMaterial;
}
//the top
for (i = pvCylinder.geometry.faces.length - 18; i <
pvCylinder.geometry.faces.length; i++)
{
pvCylinder.geometry.faces[i].material = topMaterial;
}
看看结果什么样