[freeside-commits] branch master updated. 9d83064764df266d3e693cc75cdde8478498215a

Mark Wells mark at 420.am
Sat Mar 12 19:00:10 PST 2016


The branch, master has been updated
       via  9d83064764df266d3e693cc75cdde8478498215a (commit)
       via  5befe347dfac36159ab2f68a1487111eb97996dc (commit)
      from  096e5445242151d94c60453d2b55ed2dd57d5a58 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9d83064764df266d3e693cc75cdde8478498215a
Author: Mark Wells <mark at freeside.biz>
Date:   Sat Mar 12 18:59:26 2016 -0800

    fix squashing of capital letters in KML

diff --git a/httemplate/view/kml.cgi b/httemplate/view/kml.cgi
index 7eaaa2a..a156edc 100644
--- a/httemplate/view/kml.cgi
+++ b/httemplate/view/kml.cgi
@@ -6,6 +6,6 @@ $kml->Point( map { $_=>scalar($cgi->param($_)) } qw( name lat lon ) );
 
 #http_header('Content-Type' => 'application/vnd.google-earth.kml+xml' ); #kml
 http_header('Content-Type' => 'application/vnd.google-earth.kmz' ); #kmz
-( my $name = $cgi->param('name') ) =~ s/[^a-z0-9]/_/g; #perhaps too restrictive
+( my $name = $cgi->param('name') ) =~ s/[^a-z0-9]/_/gi; #perhaps too restrictive
 http_header('Content-Disposition' => "filename=$name.kmz" );
 </%init>

commit 5befe347dfac36159ab2f68a1487111eb97996dc
Author: Mark Wells <mark at freeside.biz>
Date:   Sat Mar 12 18:59:05 2016 -0800

    show map of svc_broadband and tower locations, #37802

diff --git a/httemplate/images/antenna-square-21x51.png b/httemplate/images/antenna-square-21x51.png
new file mode 100644
index 0000000..0ba5e73
Binary files /dev/null and b/httemplate/images/antenna-square-21x51.png differ
diff --git a/httemplate/search/elements/gmap.html b/httemplate/search/elements/gmap.html
new file mode 100644
index 0000000..8b070eb
--- /dev/null
+++ b/httemplate/search/elements/gmap.html
@@ -0,0 +1,123 @@
+<%args>
+ at features
+</%args>
+<%doc>
+Generic Google Maps front end.
+
+<& /elements/gmap.html,
+  features => [
+    { id => 'svc_acct/12',
+      geometry => {
+        type        => 'Point',
+        coordinates => [ -86, 40 ], # optionally altitude as the third coord
+      },
+      properties => {
+        # see https://developers.google.com/maps/documentation/javascript/3.exp/reference#Data.StyleOptions
+        style => {
+          icon => {
+            scale => 4,
+            fillColor => 'orange',
+          }
+        },
+        # content of popup info box (might AJAX this later)
+        content => '<a href="view/svc_acct.cgi?12">username at example.com</a>',
+      }
+    }, # end of feature
+  ],
+&>
+
+</%doc>
+<%init>
+foreach (@features) {
+  $_->{type} = 'Feature';
+  # any other per-feature massaging can go here
+}
+my $tree = {
+  type => 'FeatureCollection',
+  features => \@features
+};
+
+</%init>
+<div id="map_canvas"></div>
+
+<style type="text/css">
+html { height: 100% }
+
+body { height: 100%; margin: 0px; padding: 0px }
+
+#map_canvas { height: 100%; }
+</style>
+
+<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3">
+</script>
+
+<script type="text/javascript">
+
+var data_geojson = <% encode_json($tree) %>;
+
+var baseStyle = {
+  clickable: true,
+  icon: {
+    path: google.maps.SymbolPath.CIRCLE,
+    scale: 4,
+    fillColor: 'green',
+    fillOpacity: 1,
+    strokeColor: 'black',
+    strokeWeight: 1,
+  },
+};
+
+var featureStyle = function(feature) {
+  // jQuery.extend(): merge properties of objects
+  // 'true' makes it a deep copy; start the merge with {} so that
+  // baseStyle doesn't get overwritten
+  return $.extend(true, {}, baseStyle, feature.getProperty('style'));
+};
+
+var map;
+function initMap() {
+  var canvas = $('#map_canvas');
+  map = new google.maps.Map(canvas[0], { zoom: 6 });
+  try {
+    map.data.addGeoJson(data_geojson);
+  } catch(ex) {
+    console.log(ex.toString);
+    debugger;
+  }
+
+  // construct bounds around all of the features
+  var bounds = new google.maps.LatLngBounds;
+  map.data.forEach(function(feature) {
+    var g = feature.getGeometry();
+    if (g.getType() == 'Point') {
+      bounds.extend(g.get());
+    } else if (g.getArray) {
+      g.getArray().forEach(function(point) { bounds.extend(point); });
+    }
+  });
+
+  map.fitBounds(bounds);
+  map.data.setStyle(featureStyle);
+
+  var info = new google.maps.InfoWindow;
+  map.data.addListener('click', function(ev) {
+    var feature = ev.feature;
+    if ( feature.getGeometry().getType() == 'Point' ) {
+      // then pop up an info box with the feature content
+      info.close();
+      info.setPosition(feature.getGeometry().get());
+      info.setContent(feature.getProperty('content'));
+      info.open(map);
+    }
+
+    // snap to feature ROI if it has one
+    if ( feature.getProperty('bounds') ) {
+      map.fitBounds( feature.getProperty('bounds') );
+    }
+
+  }); // addListener()
+}
+
+$().ready( initMap );
+</script>
+
diff --git a/httemplate/search/svc_broadband-map.html b/httemplate/search/svc_broadband-map.html
new file mode 100755
index 0000000..4c660b0
--- /dev/null
+++ b/httemplate/search/svc_broadband-map.html
@@ -0,0 +1,178 @@
+<& /elements/header.html, 'Broadband Search Results' &>
+  
+<& elements/gmap.html, features => \@features &>
+
+<& /elements/footer.html &>
+<%init>
+
+die "access denied" unless
+  $FS::CurrentUser::CurrentUser->access_right('List services');
+
+my $conf = new FS::Conf;
+
+my @features; # geoJSON structure
+
+# accept all the search logic from svc_broadband.cgi...
+my %search_hash;
+if ( $cgi->param('magic') eq 'unlinked' ) {
+  %search_hash = ( 'unlinked' => 1 );
+} else {
+  foreach (qw( custnum agentnum svcpart cust_fields )) {
+    $search_hash{$_} = $cgi->param($_) if $cgi->param($_);
+  }
+  foreach (qw(pkgpart routernum towernum sectornum)) {
+    $search_hash{$_} = [ $cgi->param($_) ] if $cgi->param($_);
+  }
+}
+
+if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+  $search_hash{'order_by'} = "ORDER BY $1";
+}
+
+my $sql_query = FS::svc_broadband->search(\%search_hash);
+
+my %routerbyblock = ();
+
+my @rows = qsearch($sql_query);
+my %sectors;
+my %towers;
+my %tower_coord;
+my %tower_bounds;
+foreach my $svc_broadband (@rows) {
+  # don't try to show it if coords aren't set
+  next if !$svc_broadband->latitude || !$svc_broadband->longitude;
+  # coerce coordinates to numbers
+  my @coord = (
+    $svc_broadband->longitude + 0,
+    $svc_broadband->latitude + 0,
+  );
+  push @coord, $svc_broadband->altitude + 0
+    if length($svc_broadband->altitude); # it's optional
+
+  push @features,
+  {
+    id        => 'svc_broadband/'.$svc_broadband->svcnum,
+    geometry  => {
+      type        => 'Point',
+      coordinates => \@coord,
+    },
+    properties => {
+      content => include('.svc_broadband', $svc_broadband),
+    },
+  };
+  # look up tower location and draw connecting line
+  next if !$svc_broadband->sectornum;
+  my $sector = $sectors{$svc_broadband->sectornum} ||= $svc_broadband->tower_sector;
+  my $towernum = $sector->towernum;
+  my $tower = $towers{$towernum};
+
+  if (!$tower) {
+    $tower = $towers{$towernum} = $sector->tower;
+    $tower_coord{$towernum} =
+      [ $tower->longitude + 0,
+        $tower->latitude + 0,
+        ($tower->altitude || 0) + 0,
+      ];
+
+  }
+
+  my $tower = $towers{$towernum};
+  if ( $tower->latitude and $tower->longitude ) {
+    push @features,
+    {
+      geometry => {
+        type        => 'LineString',
+        coordinates => [ \@coord, $tower_coord{$towernum} ],
+      },
+      properties  => {
+        style       => {
+          strokeColor  => ($tower->color || 'green'),
+          strokeWeight => 2,
+        },
+      },
+    };
+
+    # also extend tower's ROI to include this point
+    # (this is experimental; might get better results using the centroid of
+    # all connected services or something)
+    my $bounds = $tower_bounds{$towernum} ||= {
+      east => $tower->longitude,
+      west => $tower->longitude,
+      north => $tower->latitude,
+      south => $tower->latitude,
+    };
+    if ($coord[0] > $bounds->{east}) {
+      $bounds->{east} = $coord[0];
+    } elsif ($coord[0] < $bounds->{west}) {
+      $bounds->{west} = $coord[0];
+    }
+    if ($coord[1] > $bounds->{north}) {
+      $bounds->{north} = $coord[1]
+    } elsif ($coord[1] < $bounds->{south}) {
+      $bounds->{south} = $coord[1]
+    }
+
+  } # if tower has coords
+} # foreach $svc_broadband
+
+foreach my $tower (values(%towers)) {
+  my $towernum = $tower->towernum;
+  my $bounds = $tower_bounds{$towernum};
+  # add some padding for easier reading
+  my $dx = 0.1 * ($bounds->{east} - $bounds->{west});
+  my $dy = 0.1 * ($bounds->{north} - $bounds->{south});
+  $bounds->{east} += $dx; 
+  $bounds->{west} -= $dx;
+  $bounds->{north} += $dy;
+  $bounds->{south} -= $dy;
+  push @features,
+  {
+    id        => 'tower/'.$towernum,
+    geometry  => {
+      type        => 'Point',
+      coordinates => $tower_coord{$towernum},
+    },
+    properties => {
+      style     => {
+        icon => {
+          path        => undef,
+          url         => $fsurl.'images/jcartier-antenna-square-21x51.png',
+          anchor      => { x => 10, y => 4 }
+        },
+      },
+      content   => include('.tower', $tower),
+      bounds    => $tower_bounds{$towernum},
+    },
+  };
+}
+
+</%init>
+<%def .svc_broadband>
+% my $svc = shift;
+% my @label = $svc->cust_svc->label;
+<H3>
+  <a target="_blank" href="<% $fsurl %>view/svc_broadband.cgi?<% $svc->svcnum %>">
+    <% $label[0] |h %> #<% $svc->svcnum %> | <% $label[1] %>
+  </a>
+</H3>
+% my $cust_main = $svc->cust_main;
+<a target="_blank" href="<% $fsurl %>view/cust_main.cgi?<% $cust_main->custnum %>">
+<& /elements/small_custview.html, {
+  cust_main => $svc->cust_main,
+  #url => $fsurl.'view/cust_main.cgi',
+} &>
+</a>
+</%def>
+<%def .tower>
+% my $tower = shift;
+% my $can_edit = $FS::CurrentUser::CurrentUser->access_right('Configuration');
+<H3>
+% if ( $can_edit ) {
+  <a target="_blank" href="<% $fsurl %>edit/tower.html?<% $tower->towernum %>">
+% }
+Tower #<% $tower->towernum %> | <% $tower->towername %>
+% if ( $can_edit ) {
+  </a>
+% }
+</H3>
+</%def>
diff --git a/httemplate/search/svc_broadband.cgi b/httemplate/search/svc_broadband.cgi
index 8561977..6bf4f08 100755
--- a/httemplate/search/svc_broadband.cgi
+++ b/httemplate/search/svc_broadband.cgi
@@ -105,5 +105,9 @@ my $html_init = include('/elements/email-link.html',
                   'search_hash' => \%search_hash,
                   'table' => 'svc_broadband' 
                 );
+$html_init .= ' | ' .
+  '<a href="' .
+  $fsurl . 'search/svc_broadband-map.html?' . $cgi->query_string .
+  '">' . emt('View a map of these services') . '</a>';
 
 </%init>

-----------------------------------------------------------------------

Summary of changes:
 httemplate/images/antenna-square-21x51.png |  Bin 0 -> 1475 bytes
 httemplate/search/elements/gmap.html       |  123 +++++++++++++++++++
 httemplate/search/svc_broadband-map.html   |  178 ++++++++++++++++++++++++++++
 httemplate/search/svc_broadband.cgi        |    4 +
 httemplate/view/kml.cgi                    |    2 +-
 5 files changed, 306 insertions(+), 1 deletion(-)
 create mode 100644 httemplate/images/antenna-square-21x51.png
 create mode 100644 httemplate/search/elements/gmap.html
 create mode 100755 httemplate/search/svc_broadband-map.html




More information about the freeside-commits mailing list