95a31d3524272f6de0532d0e01fc41348637e33e
[freeside.git] / httemplate / search / svc_broadband-map.html
1 <& /elements/header.html, 'Broadband Search Results' &>
2   
3 <& elements/gmap.html, features => \@features, overlays => \@overlays &>
4
5 <& /elements/footer.html &>
6 <%init>
7
8 die "access denied" unless
9   $FS::CurrentUser::CurrentUser->access_right('List services');
10
11 my $conf = new FS::Conf;
12
13 my @features; # geoJSON structure
14
15 # accept all the search logic from svc_broadband.cgi...
16 my %search_hash;
17 if ( $cgi->param('magic') eq 'unlinked' ) {
18   %search_hash = ( 'unlinked' => 1 );
19 } else {
20   foreach (qw( custnum agentnum svcpart cust_fields )) {
21     $search_hash{$_} = $cgi->param($_) if $cgi->param($_);
22   }
23   foreach (qw(pkgpart routernum towernum sectornum)) {
24     $search_hash{$_} = [ $cgi->param($_) ] if $cgi->param($_);
25   }
26 }
27
28 if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
29   $search_hash{'order_by'} = "ORDER BY $1";
30 }
31
32 my $sql_query = FS::svc_broadband->search(\%search_hash);
33
34 my %routerbyblock = ();
35
36 my @rows = qsearch($sql_query);
37 my %sectors;
38 my %towers;
39 my %tower_coord;
40 my %tower_bounds;
41 foreach my $svc_broadband (@rows) {
42   # don't try to show it if coords aren't set
43   next if !$svc_broadband->latitude || !$svc_broadband->longitude;
44   # coerce coordinates to numbers
45   my @coord = (
46     $svc_broadband->longitude + 0,
47     $svc_broadband->latitude + 0,
48   );
49   push @coord, $svc_broadband->altitude + 0
50     if length($svc_broadband->altitude); # it's optional
51
52   push @features,
53   {
54     id        => 'svc_broadband/'.$svc_broadband->svcnum,
55     geometry  => {
56       type        => 'Point',
57       coordinates => \@coord,
58     },
59     properties => {
60       content => include('.svc_broadband', $svc_broadband),
61     },
62   };
63   # look up tower location and draw connecting line
64   next if !$svc_broadband->sectornum;
65   my $sector = $sectors{$svc_broadband->sectornum} ||= $svc_broadband->tower_sector;
66   my $towernum = $sector->towernum;
67   my $tower = $towers{$towernum};
68
69   if (!$tower) {
70     $tower = $towers{$towernum} = $sector->tower;
71     $tower_coord{$towernum} =
72       [ $tower->longitude + 0,
73         $tower->latitude + 0,
74         ($tower->altitude || 0) + 0,
75       ];
76
77   }
78
79   if ( $tower->latitude and $tower->longitude ) {
80     push @features,
81     {
82       geometry => {
83         type        => 'LineString',
84         coordinates => [ \@coord, $tower_coord{$towernum} ],
85       },
86       properties  => {
87         style       => {
88           strokeColor  => ($tower->color || 'green'),
89           strokeWeight => 2,
90         },
91       },
92     };
93
94     # also extend tower's ROI to include this point
95     # (this is experimental; might get better results using the centroid of
96     # all connected services or something)
97     my $bounds = $tower_bounds{$towernum} ||= {
98       east => $tower->longitude,
99       west => $tower->longitude,
100       north => $tower->latitude,
101       south => $tower->latitude,
102     };
103     if ($coord[0] > $bounds->{east}) {
104       $bounds->{east} = $coord[0];
105     } elsif ($coord[0] < $bounds->{west}) {
106       $bounds->{west} = $coord[0];
107     }
108     if ($coord[1] > $bounds->{north}) {
109       $bounds->{north} = $coord[1]
110     } elsif ($coord[1] < $bounds->{south}) {
111       $bounds->{south} = $coord[1]
112     }
113
114   } # if tower has coords
115 } # foreach $svc_broadband
116
117 # if we were given a towernum or sectornum, ensure that the map includes
118 # that tower/sector, even if there are no services
119
120 foreach my $towernum ($cgi->param('towernum')) {
121   next if $towernum !~ /^\d+$/;
122   next if exists($towers{$towernum});
123   $towers{$towernum} = FS::tower->by_key($towernum);
124 }
125
126 foreach my $sectornum ($cgi->param('sectornum')) {
127   next if $sectornum !~ /^\d+$/;
128   next if exists($sectors{$sectornum});
129   $sectors{$sectornum} = FS::tower_sector->by_key($sectornum)
130     or die "bad sectornum $sectornum";
131   # and put it on the tower list also
132   my $towernum = $sectors{$sectornum}->towernum;
133   if (!exists($towers{$towernum})) {
134     $towers{$towernum} = FS::tower->by_key($towernum);
135   }
136 }
137
138 # if the tower/sector was included in the search, but has no services, set
139 # default bounds around it of 1 minute in each direction
140 my $default_bounds = 0.017;
141
142 foreach my $tower (values(%towers)) {
143   my $towernum = $tower->towernum;
144   $tower_coord{$towernum} ||= [ $tower->longitude + 0,
145                                 $tower->latitude + 0,
146                                 ($tower->altitude || 0) + 0
147                               ];
148 warn encode_json($tower_coord{$towernum});
149   my $bounds = $tower_bounds{$towernum}
150            ||= { 'north' => $tower->latitude + $default_bounds,
151                  'south' => $tower->latitude - $default_bounds,
152                  'east'  => $tower->longitude + $default_bounds,
153                  'west'  => $tower->longitude - $default_bounds,
154                };
155   # add some padding for easier reading
156   my $dx = 0.1 * ($bounds->{east} - $bounds->{west});
157   my $dy = 0.1 * ($bounds->{north} - $bounds->{south});
158   $bounds->{east} += $dx; 
159   $bounds->{west} -= $dx;
160   $bounds->{north} += $dy;
161   $bounds->{south} -= $dy;
162   push @features,
163   {
164     id        => 'tower/'.$towernum,
165     geometry  => {
166       type        => 'Point',
167       coordinates => $tower_coord{$towernum},
168     },
169     properties => {
170       style     => {
171         icon => {
172           path        => undef,
173           url         => $fsurl.'images/antenna-square-21x51.png',
174           anchor      => { x => 10, y => 4 }
175         },
176       },
177       content   => include('.tower', $tower),
178       bounds    => $tower_bounds{$towernum},
179     },
180   };
181 }
182
183 my @overlays;
184 foreach my $sector (values %sectors) {
185   if ( length($sector->image) > 0 ) {
186     my $o = {
187       url => $fsurl.'view/sector_map-png.cgi?' . $sector->sectornum
188     };
189     foreach (qw(south north west east)) {
190       $o->{$_} = $sector->get($_) + 0;
191     }
192     push @overlays, $o;
193   };
194 };
195 </%init>
196 <%def .svc_broadband>
197 % my $svc = shift;
198 % my @label = $svc->cust_svc->label;
199 <H3>
200   <a target="_blank" href="<% $fsurl %>view/svc_broadband.cgi?<% $svc->svcnum %>">
201     <% $label[0] |h %> #<% $svc->svcnum %> | <% $label[1] %>
202   </a>
203 </H3>
204 % my $cust_main = $svc->cust_main;
205 <a target="_blank" href="<% $fsurl %>view/cust_main.cgi?<% $cust_main->custnum %>">
206 <& /elements/small_custview.html, {
207   cust_main => $svc->cust_main,
208   #url => $fsurl.'view/cust_main.cgi',
209 } &>
210 </a>
211 </%def>
212 <%def .tower>
213 % my $tower = shift;
214 % my $can_edit = $FS::CurrentUser::CurrentUser->access_right('Configuration');
215 <H3>
216 % if ( $can_edit ) {
217   <a target="_blank" href="<% $fsurl %>edit/tower.html?<% $tower->towernum %>">
218 % }
219 Tower #<% $tower->towernum %> | <% $tower->towername %>
220 % if ( $can_edit ) {
221   </a>
222 % }
223 </H3>
224 </%def>