Flex创建带有空间信息的椭圆(Polygon)
运行环境:Flash Builder 4.0+Arcgis API for Flex Version 2.1类库
本来在ArcGIS Flex API中是不能直接画椭圆的polygon的,后来想到调用GP服务画椭圆,但是效率很低下,画一个椭圆要花个好几秒,最直接的办法就是自己创建
1 private function CreateLocalEllpise(centerPoint:MapPoint,prolateAxis:Number,minorAxis:Number,includedAngle:Number):Polygon
2 {
3 var cX:Number=centerPoint.x;
4 var cY:Number=centerPoint.y;
5
6 var paramB:Number=includedAngle*Math.PI/180;
7 var paramH:Number=0.02;
8 var paramR:Number=0;
9
10 if(prolateAxis>=minorAxis)
11 {
12 paramR=Math.pow(prolateAxis,2)/minorAxis;
13 }
14 else
15 {
16 paramR=Math.pow(minorAxis,2)/prolateAxis;
17 }
18
19 var paramA:Number=Math.acos(1-(paramH/paramR));
20 var startAngle:Number=0;
21 var pointArray:Array=new Array();
22 while(startAngle<(2*Math.PI))
23 {
24
25 var dx:Number = cX + prolateAxis * Math.cos(startAngle) * Math.cos(paramB) - minorAxis * Math.sin(startAngle) * Math.sin(paramB);
26 var dy:Number = cY + prolateAxis * Math.cos(startAngle) * Math.sin(paramB) + minorAxis * Math.sin(startAngle) * Math.cos(paramB);
27
28 var myPoint:MapPoint=new MapPoint();
29 myPoint.x=dx;
30 myPoint.y=dy;
31
32 pointArray.push(myPoint);
33
34 startAngle+=paramA;
35 }
36
37 var myPg:Polygon=new Polygon();
38 myPg.addRing(pointArray);
39
40 return myPg;
41
42 }
43
2 {
3 var cX:Number=centerPoint.x;
4 var cY:Number=centerPoint.y;
5
6 var paramB:Number=includedAngle*Math.PI/180;
7 var paramH:Number=0.02;
8 var paramR:Number=0;
9
10 if(prolateAxis>=minorAxis)
11 {
12 paramR=Math.pow(prolateAxis,2)/minorAxis;
13 }
14 else
15 {
16 paramR=Math.pow(minorAxis,2)/prolateAxis;
17 }
18
19 var paramA:Number=Math.acos(1-(paramH/paramR));
20 var startAngle:Number=0;
21 var pointArray:Array=new Array();
22 while(startAngle<(2*Math.PI))
23 {
24
25 var dx:Number = cX + prolateAxis * Math.cos(startAngle) * Math.cos(paramB) - minorAxis * Math.sin(startAngle) * Math.sin(paramB);
26 var dy:Number = cY + prolateAxis * Math.cos(startAngle) * Math.sin(paramB) + minorAxis * Math.sin(startAngle) * Math.cos(paramB);
27
28 var myPoint:MapPoint=new MapPoint();
29 myPoint.x=dx;
30 myPoint.y=dy;
31
32 pointArray.push(myPoint);
33
34 startAngle+=paramA;
35 }
36
37 var myPg:Polygon=new Polygon();
38 myPg.addRing(pointArray);
39
40 return myPg;
41
42 }
43
这个是最初写的代码,将上面画出椭圆,作为query.Geometry,在querytask和query中进行intersect操作时会报错,报错信息如下: fault code:400 Unable to perform query. Please check your parameters.但进行contains操作不会报错。这个其实是个很恶心的错误,在用querytask时如果报错很多都是这个错误,仅从这里是看不出来的,我们从ArcServer的日志下手吧,日志中有这样的错误信息:“Polygon does not close properly”;说明我们的polygon几何类型没有闭合,对上述代码进行改进
代码
1 private function CreateLocalEllpise(centerPoint:MapPoint,prolateAxis:Number,minorAxis:Number,includedAngle:Number):Polygon
2 {
3 var cX:Number=centerPoint.x;
4 var cY:Number=centerPoint.y;
5
6 var paramB:Number=includedAngle*Math.PI/180;
7 var paramH:Number=0.02;
8 var paramR:Number=0;
9
10 if(prolateAxis>=minorAxis)
11 {
12 paramR=Math.pow(prolateAxis,2)/minorAxis;
13 }
14 else
15 {
16 paramR=Math.pow(minorAxis,2)/prolateAxis;
17 }
18
19 var paramA:Number=Math.acos(1-(paramH/paramR));
20 var startAngle:Number=0;
21 var pointArray:Array=new Array();
22 var starPoint:MapPoint=new MapPoint();
23 while(startAngle<(Math.PI*2))
24 {
25
26 var dx:Number = cX + prolateAxis * Math.cos(startAngle) * Math.cos(paramB) - minorAxis * Math.sin(startAngle) * Math.sin(paramB);
27 var dy:Number = cY + prolateAxis * Math.cos(startAngle) * Math.sin(paramB) + minorAxis * Math.sin(startAngle) * Math.cos(paramB);
28
29 var myPoint:MapPoint=new MapPoint();
30 if(startAngle==0)
31 {
32 starPoint.x=dx;
33 starPoint.y=dy;
34 }
35
36
37 myPoint.x=dx;
38 myPoint.y=dy;
39
40
41 pointArray.push(myPoint);
42
43 startAngle+=paramA;
44 }
45 pointArray.push(starPoint);
46 var myPg:Polygon=new Polygon();
47 myPg.addRing(pointArray);
48
49 return myPg;
50 }
51
2 {
3 var cX:Number=centerPoint.x;
4 var cY:Number=centerPoint.y;
5
6 var paramB:Number=includedAngle*Math.PI/180;
7 var paramH:Number=0.02;
8 var paramR:Number=0;
9
10 if(prolateAxis>=minorAxis)
11 {
12 paramR=Math.pow(prolateAxis,2)/minorAxis;
13 }
14 else
15 {
16 paramR=Math.pow(minorAxis,2)/prolateAxis;
17 }
18
19 var paramA:Number=Math.acos(1-(paramH/paramR));
20 var startAngle:Number=0;
21 var pointArray:Array=new Array();
22 var starPoint:MapPoint=new MapPoint();
23 while(startAngle<(Math.PI*2))
24 {
25
26 var dx:Number = cX + prolateAxis * Math.cos(startAngle) * Math.cos(paramB) - minorAxis * Math.sin(startAngle) * Math.sin(paramB);
27 var dy:Number = cY + prolateAxis * Math.cos(startAngle) * Math.sin(paramB) + minorAxis * Math.sin(startAngle) * Math.cos(paramB);
28
29 var myPoint:MapPoint=new MapPoint();
30 if(startAngle==0)
31 {
32 starPoint.x=dx;
33 starPoint.y=dy;
34 }
35
36
37 myPoint.x=dx;
38 myPoint.y=dy;
39
40
41 pointArray.push(myPoint);
42
43 startAngle+=paramA;
44 }
45 pointArray.push(starPoint);
46 var myPg:Polygon=new Polygon();
47 myPg.addRing(pointArray);
48
49 return myPg;
50 }
51
这句话为什么要取0.02?因为这是经验参数吧,一般取值范围在0.01-0.03之间都可以