4283d5a3a4e6840536e08301ea63de25b6245b1c
[potlatch2.git] / net / systemeD / potlatch2 / tools / Circularise.as
1 package net.systemeD.potlatch2.tools {
2         import net.systemeD.halcyon.Map;
3         import net.systemeD.halcyon.connection.Way;
4         import net.systemeD.halcyon.connection.Node;
5
6         public class Circularise {
7
8                 public static function circularise(way:Way,map:Map):void {
9                         if (way.length<4) { return; }
10
11                         var a:Node=way.getNode(0);
12                         var b:Node=way.getNode(way.length-1);
13                         if (a!=b) { return; }
14
15                         // Find centre-point
16                         // ** should be refactored to be within Way.as, so we can share with WayUI.as
17                         var patharea:Number=0;
18                         var cx:Number=0; var lx:Number=b.lon;
19                         var cy:Number=0; var ly:Number=b.latp;
20                         var i:uint,j:uint,n:Node;
21                         for (i=0; i<way.length; i++) {
22                                 n=way.getNode(i);
23                                 var sc:Number = (lx*n.latp-n.lon*ly);
24                                 cx += (lx+n.lon )*sc;
25                                 cy += (ly+n.latp)*sc;
26                                 patharea += sc;
27                                 lx=n.lon; ly=n.latp;
28                         }
29                         patharea/=2;
30                         cx/=patharea*6;
31                         cy/=patharea*6;
32
33                         // Average distance to centre
34                         var d:Number=0; var angles:Array=[];
35                         for (i=0; i<way.length; i++) {
36                                 d+=Math.sqrt(Math.pow(way.getNode(i).lon -cx,2)+
37                                                          Math.pow(way.getNode(i).latp-cy,2));
38                         }
39                         d=d/way.length;
40                         
41                         // Move each node
42                         for (i=0; i<way.length-1; i++) {
43                                 n=way.getNode(i);
44                                 var c:Number=Math.sqrt(Math.pow(n.lon-cx,2)+Math.pow(n.latp-cy,2));
45                                 n.setLonLatp(cx+(n.lon -cx)/c*d,
46                                              cy+(n.latp-cy)/c*d);
47                         }
48
49                         // Insert extra nodes to make circle
50                         // clockwise: angles decrease, wrapping round from -170 to 170
51                         i=0;
52                         var clockwise:Boolean=way.clockwise;
53                         var diff:Number, ang:Number;
54                         while (i<way.length-1) {
55                                 j=(i+1) % way.length;
56                                 var a1:Number=Math.atan2(way.getNode(i).lon-cx,way.getNode(i).latp-cy)*(180/Math.PI);
57                                 var a2:Number=Math.atan2(way.getNode(j).lon-cx,way.getNode(j).latp-cy)*(180/Math.PI);
58
59                                 if (clockwise) {
60                                         if (a2>a1) { a2=a2-360; }
61                                         diff=a1-a2;
62                                         if (diff>20) {
63                                                 for (ang=a1-20; ang>a2+10; ang-=20) {
64                                                         way.insertNode(j,map.connection.createNode({},
65                                                                 map.latp2lat(cy+Math.cos(ang*Math.PI/180)*d),
66                                                                 cx+Math.sin(ang*Math.PI/180)*d));
67                                                         j++; i++;
68                                                 }
69                                         }
70                                 } else {
71                                         if (a1>a2) { a1=a1-360; }
72                                         diff=a2-a1;
73                                         if (diff>20) {
74                                                 for (ang=a1+20; ang<a2-10; ang+=20) {
75                                                         way.insertNode(j,map.connection.createNode({},
76                                                                 map.latp2lat(cy+Math.cos(ang*Math.PI/180)*d),
77                                                                 cx+Math.sin(ang*Math.PI/180)*d));
78                                                         j++; i++;
79                                                 }
80                                         }
81                                 }
82                                 i++;
83                         }
84                 }
85         }
86 }