view release on metacpan or search on metacpan
examples/html_gmap_hires_sample view on Meta::CPAN
'pharmacy',
'open24',
],
base_output_headers => ['Id',
'Latitude',
'Longitude',
'Store Name',
'Pharmacy',
'Open 24 Hours',
],
legend_field1 => 'pharmacy',
legend_field2 => 'open24',
param_fields => {
pharmacy => ['all:All', 'Yes', 'No'],
open24 => ['all:All', 'Yes', 'No'],
},
gmap_key => $gmap_key,
temp_dir => qq[/usr/local/demo/html/demo/tmp],
temp_dir_eq => qq[http://localhost:8080/demo/tmp],
);
# Display
lib/HTML/GMap.pm view on Meta::CPAN
my $session_dir = $self->temp_dir . '/sessions';
my $session =
CGI::Session->new('file', $session_id, {Directory => $session_dir});
if ($session_id && $session_id ne $session->id) {
croak("Cannot create session!");
}
$self->session_id($session->id);
$self->session($session);
$self->legend_field1($params{legend_field1});
$self->legend_field2($params{legend_field2});
my $max_hires_display =
exists $params{max_hires_display}
? $params{max_hires_display}
: 100;
$self->max_hires_display($max_hires_display);
my $center_latitude =
exists $params{center_latitude}
? $params{center_latitude}
lib/HTML/GMap.pm view on Meta::CPAN
);
return $piechart_icon_size;
}
# Function :
# Arguments : \@info ([$icon_url, $label, $count], ...)
# Returns : $html
# Notes :
sub generate_piechart_legend_html {
my ($self, $info_ref) = @_;
my @sorted_info = sort {
if ( ($a->[1] eq 'Clustered' || $a->[1] eq 'Other')
&& ($b->[1] eq 'Clustered' || $b->[1] eq 'Other')) {
$a cmp $b;
}
elsif (($a->[1] eq 'Clustered' || $a->[1] eq 'Other')
&& ($b->[1] ne 'Clustered' && $b->[1] ne 'Other')) {
1;
lib/HTML/GMap.pm view on Meta::CPAN
$html .= qq[</table>\n];
return $html;
}
# Function :
# Arguments : \%markers
# Returns : $html
# Notes :
sub generate_hires_legend_html {
my ($self, $rows_ref, $type) = @_;
my $legend_field1 = $self->legend_field1;
my $legend_field2 = $self->legend_field2;
my $temp_dir_eq = $self->temp_dir_eq;
my $session_id = $self->session_id;
my $multiples_icon_url =
"$temp_dir_eq/Multiple-icon-$session_id-0-0-0.png";
my $legend_info;
my @legend_markers;
if ($type eq 'hires') {
$legend_info = qq[(The coordinates with overlapping data points
are displayed as <img src="$multiples_icon_url">.)];
my %legend_markers;
foreach my $key (keys %$rows_ref) {
foreach my $row_ref (@{$rows_ref->{$key}->{rows}}) {
my $icon_url = $row_ref->{icon_url};
my $legend_field1_value = $row_ref->{$legend_field1};
my $legend_field2_value = $row_ref->{$legend_field2};
$legend_markers{$icon_url}{count}++;
$legend_markers{$icon_url}{text} = join(
'; ',
map { s/^(.{5}).+/$1 .../; $_; } $legend_field1_value,
$legend_field2_value
);
}
}
foreach my $icon_url (
sort { $legend_markers{$b}{count} <=> $legend_markers{$a}{count} }
keys %legend_markers
) {
my $text = $legend_markers{$icon_url}{text};
push @legend_markers,
{ icon_url => $icon_url,
icon_size => 11,
text => $text,
};
}
}
else {
$legend_info = qq[];
@legend_markers = @$rows_ref;
}
my $html;
$html .= qq[<table>\n];
$html .= qq[<tr>\n];
$html .= qq[<td colspan="2">
$legend_info<br/>
</td>\n];
$html .= qq[</tr>\n];
foreach my $legend_marker (@legend_markers) {
my $icon_url = $legend_marker->{icon_url};
my $icon_size = $legend_marker->{icon_size};
my $text = $legend_marker->{text};
$html .= qq[<tr>\n];
$html .= qq[<td align="left">
<img height="$icon_size" src="$icon_url"/> $text
</td>\n];
$html .= qq[</tr>\n];
}
$html .= qq[</table>\n];
return $html;
}
lib/HTML/GMap.pm view on Meta::CPAN
# Function :
# Arguments : $data_ref
# Returns : $html
# Notes :
sub generate_hires_details_html {
my ($self, $key_ref) = @_;
my $data_ref = $key_ref->{rows};
my $legend_field1 = $self->legend_field1;
my $legend_field2 = $self->legend_field2;
my $session = $self->session;
my $temp_dir_eq = $self->temp_dir_eq;
my %icon_urls;
my $total_count = 0;
foreach my $row_ref (@$data_ref) {
my $icon_url = $row_ref->{icon_url};
my $legend_field1_value = $row_ref->{$legend_field1};
my $legend_field2_value = $row_ref->{$legend_field2};
$icon_urls{$icon_url}{count}++;
$icon_urls{$icon_url}{text} = join(
'; ', map { s/^(.{5}).+/$1 .../; $_; } $legend_field1_value,
$legend_field2_value
);
$total_count++;
}
my $html;
$html .= qq[<table>\n];
$html .= qq[<tr>\n];
$html .= qq[<th align="left" width="50%">Total Count</th>
lib/HTML/GMap.pm view on Meta::CPAN
$self->{install_dir} = $value if @_ > 1;
return $self->{install_dir};
}
sub install_dir_eq {
my ($self, $value) = @_;
$self->{install_dir_eq} = $value if @_ > 1;
return $self->{install_dir_eq};
}
sub legend_field1 {
my ($self, $value) = @_;
$self->{legend_field1} = $value if @_ > 1;
return $self->{legend_field1};
}
sub legend_field2 {
my ($self, $value) = @_;
$self->{legend_field2} = $value if @_ > 1;
return $self->{legend_field2};
}
sub max_hires_display {
my ($self, $value) = @_;
$self->{max_hires_display} = $value if @_ > 1;
return $self->{max_hires_display};
}
sub messages {
my ($self, $value) = @_;
lib/HTML/GMap.pm view on Meta::CPAN
my $prototype_js_file_eq =
$self->install_dir_eq . '/' . $self->prototype_js_file;
my %vars = (
# HTML variables
cgi_header => $cgi_header,
header => $self->_content($self->header),
footer => $self->_content($self->footer),
page_title => $self->page_title,
legend => undef,
param_fields_with_values => \@param_fields_with_values,
messages => $self->messages,
gmap_key => $self->gmap_key,
gmap_main_css_file_eq => $gmap_main_css_file_eq,
gmap_main_js_file_eq => $gmap_main_js_file_eq,
prototype_js_file_eq => $prototype_js_file_eq,
container_height_pix => $self->image_height_pix + 20,
container_width_pix => $self->image_width_pix + 450,
center_width_pix => $self->image_width_pix + 0,
display_cluster_slices => $initial_format eq 'xml-piechart' ? 1 : 0,
lib/HTML/GMap.pm view on Meta::CPAN
# Function :
# Arguments : $\@data
# Returns : \%xml_ref
# Notes : This is a private method.
sub _generate_hires_xml_data {
my ($self, $data_ref) = @_;
my @base_sql_fields = @{$self->base_sql_fields};
my $legend_field1 = $self->legend_field1;
my $legend_field2 = $self->legend_field2;
my $session = $self->session;
my $temp_dir = $self->temp_dir;
my $temp_dir_eq = $self->temp_dir_eq;
my $session_id = $self->session_id;
my $max_hires_display = $self->max_hires_display;
my $markers_ref = {};
my $max_data_count = 0;
lib/HTML/GMap.pm view on Meta::CPAN
# Process marker hash to generate cumulative information
my $xml_ref = {};
# If there are more than max_hires_display markers, cluster data and display low res view
# *** Override $markers_ref and $max_data_count ***
if (scalar(keys %$markers_ref) > $max_hires_display) {
($markers_ref, $max_data_count) = $self->_cluster_data($data_ref);
$self->_add_hires_icon_urls($markers_ref);
my $lowres_legend_marker_count = 5;
my $density_icon_prefix = "Density-icon-$session_id";
my $icon = GD::Icons->new(
shape_keys => [":default"],
shape_values => ["_large_square"],
color_keys => [":default"],
color_values => ["#0009ff"],
sval_keys => [0 .. $lowres_legend_marker_count - 1],
icon_dir => $temp_dir,
icon_prefix => $density_icon_prefix,
);
$icon->generate_icons;
my @lowres_legend_markers;
foreach my $i (0 .. $lowres_legend_marker_count - 1) {
my $icon_url = "$temp_dir_eq/$density_icon_prefix-0-0-$i.png";
my $text =
int($i * $max_data_count / $lowres_legend_marker_count) + 1
. ' to '
. int(($i + 1) * $max_data_count / $lowres_legend_marker_count)
. ' points';
my $icon_size = 22;
push @lowres_legend_markers,
{ icon_url => $icon_url,
icon_size => $icon_size,
text => $text,
};
}
foreach my $key (keys %{$markers_ref}) {
my ($latitude, $longitude) = split(':', $key);
my $data_ref = $markers_ref->{$key}->{rows};
my $data_count = scalar(@$data_ref);
my $density_icon_index =
int(($data_count / $max_data_count) *
($lowres_legend_marker_count - 1));
my $icon_url =
"$temp_dir_eq/$density_icon_prefix-0-0-$density_icon_index.png";
my $icon_size = 22;
my $details_on_click =
$self->generate_hires_details_html($markers_ref->{$key});
my $row_ref = {
latitude => $latitude,
longitude => $longitude,
icon_url => $icon_url,
icon_size => $icon_size,
details_on_click => $details_on_click,
messages_on_click => '',
legend_on_click => '',
};
push(@{$xml_ref->{marker}}, $row_ref);
}
my $legend = $self->generate_hires_legend_html(
\@lowres_legend_markers,
'lowres'
);
my $meta_data_ref = {
messages_by_default => $self->messages,
details_by_default => '[Click an icon for details ...]',
legend_by_default => $legend,
};
push(@{$xml_ref->{meta_data}}, $meta_data_ref);
}
# Else
else {
$self->_add_hires_icon_urls($markers_ref);
# my $multiples_icon_prefix = "Multiple-icon-$session_id";
# my $icon = GD::Icons->new(
lib/HTML/GMap.pm view on Meta::CPAN
my $details_on_click =
$self->generate_hires_details_html($markers_ref->{$key});
my $row_ref = {
latitude => $latitude,
longitude => $longitude,
icon_url => $icon_url,
icon_size => $icon_size,
details_on_click => $details_on_click,
messages_on_click => '',
legend_on_click => '',
};
push(@{$xml_ref->{marker}}, $row_ref);
}
my $legend = $self->generate_hires_legend_html($markers_ref, 'hires');
my $meta_data_ref = {
messages_by_default => $self->messages,
details_by_default => '[Click icons for details ...]',
legend_by_default => $legend
};
push(@{$xml_ref->{meta_data}}, $meta_data_ref);
}
return $xml_ref;
}
# Function :
# Arguments : \%markers_ref
# Returns : 1
# Notes : This is a private method.
sub _add_hires_icon_urls {
my ($self, $markers_ref) = @_;
my $legend_field1 = $self->legend_field1;
my $legend_field2 = $self->legend_field2;
my $session = $self->session;
my $hires_shape_keys = $self->hires_shape_keys;
my $hires_shape_values = $self->hires_shape_values;
my $hires_color_keys = $self->hires_color_keys;
my $hires_color_values = $self->hires_color_values;
my $temp_dir = $self->temp_dir;
my $temp_dir_eq = $self->temp_dir_eq;
my $session_id = $self->session_id;
# Create icon set and store in row_refs
my %legend_field1_values;
my %legend_field2_values;
foreach my $key (keys %{$markers_ref}) {
my $data_ref = $markers_ref->{$key}->{rows};
foreach my $row_ref (@$data_ref) {
$legend_field1_values{$row_ref->{$legend_field1}} = 1
if exists $row_ref->{$legend_field1};
$legend_field2_values{$row_ref->{$legend_field2}} = 1
if exists $row_ref->{$legend_field2};
}
}
my @legend_field1_values = sort keys %legend_field1_values;
my @legend_field2_values = sort keys %legend_field2_values;
my $small_icon_prefix = "Small-icon-$session_id";
my $icon = GD::Icons->new(
color_keys => $hires_color_keys ? $hires_color_keys : \@legend_field2_values,
color_values => $hires_color_values,
shape_keys => $hires_shape_keys ? $hires_shape_keys : \@legend_field1_values,
shape_values => $hires_shape_values,
sval_keys => [":default"],
icon_dir => $temp_dir,
icon_prefix => $small_icon_prefix,
);
$icon->generate_icons;
foreach my $key (keys %{$markers_ref}) {
my $data_ref = $markers_ref->{$key}->{rows};
foreach my $row_ref (@$data_ref) {
$row_ref->{icon_url} = "$temp_dir_eq/"
. $icon->icon(
$row_ref->{$legend_field1},
$row_ref->{$legend_field2}, ':default' # GD::Icons uses first color, then shape
);
}
}
return 1;
}
# Function :
# Arguments : $\@data
# Returns : \%xml_ref
lib/HTML/GMap.pm view on Meta::CPAN
my $details_on_click =
$self->generate_piechart_details_html($markers_ref->{$key});
my $row_ref = {
latitude => $latitude,
longitude => $longitude,
icon_url => $icon_url,
icon_size => $icon_size,
details_on_click => $details_on_click,
messages_on_click => '',
legend_on_click => '',
};
push(@{$xml_ref->{marker}}, $row_ref);
}
my $legend_info =
$self->_generate_piechart_legend_info(\%all_cluster_values);
my $legend = $self->generate_piechart_legend_html($legend_info);
my $meta_data_ref = {
messages_by_default => $self->messages,
details_by_default => '[Click a pie chart for details ...]',
legend_by_default => $legend
};
push(@{$xml_ref->{meta_data}}, $meta_data_ref);
return $xml_ref;
}
# Function :
# Arguments : \@data
# Returns : (\%markers, $max_data_count)
# Notes :
lib/HTML/GMap.pm view on Meta::CPAN
}
return (\%markers, $max_data_count);
}
# Function :
# Arguments : \%all_cluster_values (key: $label, value: count), \%color_table (key: $label, value: color)
# Returns : $html
# Notes :
sub _generate_piechart_legend_info {
my ($self, $data_ref) = @_;
my $session = $self->session;
my $color_table_ref = $session->param('color_table');
my $temp_dir = $self->temp_dir;
my $temp_dir_eq = $self->temp_dir_eq;
my @legend_data;
foreach my $label (
sort { $data_ref->{$b} <=> $data_ref->{$a} }
keys %{$data_ref}
) {
my $count = $data_ref->{$label};
my $color = $color_table_ref->{$label};
my $icon_file = "$temp_dir/Legend-icon-$color.png";
my $icon_url = "$temp_dir_eq/Legend-icon-$color.png";
lib/HTML/GMap.pm view on Meta::CPAN
[75, 25],
);
my $graph = GD::Graph::pie->new(15, 15)
or croak("Cannot create an GD::Graph object!");
$graph->set(
'3d' => 0,
'labelclr' => 0,
'axislabelclr' => 0,
'legendclr' => 0,
'valuesclr' => 0,
'textclr' => 0,
'start_angle' => 180,
'accentclr' => 'dgray',
'dclrs' => [$color, 'white'],
) or croak($graph->error);
my $icon = $graph->plot(\@icon_data)
or croak($graph->error); # Convert to GD object
open(IMG, ">$icon_file")
or croak("Cannot write file ($icon_file): $!");
binmode IMG;
print IMG $icon->png;
close IMG;
}
push @legend_data, [$icon_url, $label, $count];
}
return \@legend_data;
}
# Function :
# Arguments : $data_ref (an array ref of two equal-length arrays is needed)
# Returns : 1
# Notes : This is a private method.
sub _make_piechart_icon {
my ($self, $data_ref, $color_ref, $max_data_count) = @_;
lib/HTML/GMap.pm view on Meta::CPAN
);
# Generate pie chart and render it as a GD object
my $graph = GD::Graph::pie->new($piechart_icon_size, $piechart_icon_size)
or $self->error("Cannot create an GD::Graph object!");
$graph->set(
'3d' => 0,
'labelclr' => 0,
'axislabelclr' => 0,
'legendclr' => 0,
'valuesclr' => 0,
'textclr' => 0,
'start_angle' => 180,
'accentclr' => 'dgray',
'dclrs' => $color_ref,
) or $self->error($graph->error);
my $graph_as_gd = $graph->plot($data_ref) or $self->error($graph->error);
# Generate a temp file and print it out
lib/HTML/GMap.pm view on Meta::CPAN
'pharmacy',
'open24',
],
base_output_headers => ['Id',
'Latitude',
'Longitude',
'Store Name',
'Pharmacy',
'Open 24 Hours',
],
legend_field1 => 'pharmacy',
legend_field2 => 'open24',
param_fields => {
pharmacy => ['all:All', 'Yes', 'No'],
open24 => ['all:All', 'Yes', 'No'],
},
gmap_key => $gmap_key,
temp_dir => qq[/usr/local/demo/html/demo/tmp],
temp_dir_eq => qq[http://localhost:8080/demo/tmp],
);
$gmap->display;
lib/HTML/GMap.pm view on Meta::CPAN
Parameter Description Format
--------- ----------- ------
initial_format Initial display format (xml-piechart|xml-hires) scalar
db_access_params Database access params arrayref
([datasource, username, password])
base_sql_table Base SQL table (or table join) to build final scalar
SQL queries from
base_sql_fields Fields that will be retrieved by the arrayref
SQL statement
base_output_headers Headers that will be output in results arrayref
legend_field1 For hires display, first field to fold on scalar
(Required only for xml-hires)
legend_field2 For hires display, second field to fold on scalar
(Required only for xml-hires)
cluster_field For pie chart display, the field to fold on scalar
(Required only for xml-piechart)
param_fields Param fields to include as filters arrayref
gmap_key Google Maps API key scalar
temp_dir Temporary directory to store images scalar
and session files
temp_dir_eq URL-equivalent to access files in temp_dir scalar
=head2 Group 2 - Optional parameters
lib/HTML/GMap/Files.pm view on Meta::CPAN
overflow: auto;
}
div.details_info {
padding: 4px;
height: 110px;
width: 240px;
overflow: auto;
}
div.legend_info {
padding: 4px;
height: 490px;
width: 180px;
font-weight: bold;
overflow: auto;
}
div.float_right {
clear: right;
display: inline;
lib/HTML/GMap/Files.pm view on Meta::CPAN
<body>
[% header %]
<h1>[% page_title %]</h1>
<table align="center" class="container">
<tr>
<td>
<div class="sub_header">Legend: </div>
<div id="legend" class="legend_info"></div>
<p/>
<div id="legend_message"></div>
</td>
<td>
<div id="map" style="height: [% image_height_pix %]px; width: [% image_width_pix %]px">
Loading map ...
</div>
</td>
<td>
<div class="sub_header">Status: </div>
lib/HTML/GMap/Files.pm view on Meta::CPAN
return 1;
}
// Start refresh (clear overlays and messages)
function startRefresh() {
// Clear existing overlays
map.clearOverlays();
document.getElementById("status").innerHTML = 'Moving ...';
document.getElementById("legend").innerHTML = '';
document.getElementById("legend_message").innerHTML = '';
document.getElementById("details").innerHTML = '';
}
// Refresh display (clear overlays, send an AJAX request, process request)
function doRefresh(event) {
var drawGrid = varStore.drawGrid;
// Clear existing overlays
map.clearOverlays();
lib/HTML/GMap/Files.pm view on Meta::CPAN
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var lat = parseFloat(markers[i].getAttribute("latitude"));
var lng = parseFloat(markers[i].getAttribute("longitude"));
var iconUrl = markers[i].getAttribute("icon_url");
var iconSize = markers[i].getAttribute("icon_size");
var messagesOnClick = markers[i].getAttribute("messages_on_click");
var detailsOnClick = markers[i].getAttribute("details_on_click");
var legendOnClick = markers[i].getAttribute("legend_on_click");
var point = new GLatLng(lat, lng);
addMarker(point, iconUrl, iconSize, legendOnClick, detailsOnClick, messagesOnClick);
document.getElementById("details").innerHTML = '[Click on an icon on the map for details ...]';
}
var metaData = xml.documentElement.getElementsByTagName("meta_data"); // Only one present
var legendByDefault = metaData[0].getAttribute("legend_by_default");
var detailsByDefault = metaData[0].getAttribute("details_by_default")
var messagesByDefault = metaData[0].getAttribute("messages_by_default")
if (legendByDefault) {
document.getElementById("legend").innerHTML = legendByDefault;
}
if (detailsByDefault) {
document.getElementById("details").innerHTML = detailsByDefault;
}
if (messagesByDefault) {
document.getElementById("messages").innerHTML = messagesByDefault;
}
document.getElementById("status").innerHTML = "Ready";
}
// Utility function to add a marker
function addMarker(point, iconUrl, iconSize, legendOnClick, detailsOnClick, messagesOnClick) {
var icon = createIcon(iconUrl, iconSize);
var marker = new GMarker(point, icon);
if (legendOnClick) {
GEvent.addListener(marker, "click", function() {
document.getElementById("legend").innerHTML = legendOnClick;
})
};
if (detailsOnClick) {
GEvent.addListener(marker, "click", function() {
document.getElementById("details").innerHTML = detailsOnClick;
})
};
if (messagesOnClick) {
lib/HTML/GMap/Tutorial.pm view on Meta::CPAN
'pharmacy',
'open24',
],
base_output_headers => ['Id',
'Latitude',
'Longitude',
'Store Name',
'Pharmacy',
'Open 24 Hours',
],
legend_field1 => 'pharmacy',
legend_field2 => 'open24',
param_fields => {
pharmacy => ['all:All', 'Yes', 'No'],
open24 => ['all:All', 'Yes', 'No'],
},
gmap_key => qq[.... <gmap_key> ....],
temp_dir => qq[/usr/local/panzea/html/demo/tmp],
temp_dir_eq => qq[http://localhost:8080/demo/tmp],
);
# Display
lib/HTML/GMap/Tutorial.pm view on Meta::CPAN
I<base_sql_table, base_sql_fields & base_output_headers>
These three parameters describe how the data is stored in the database.
"base_sql_table" describes the name of the table. This can be a clause consisting of JOINs. However, for simplicity and speed, it is recommended to use a single denormalized table. This parameter is passed on as a string (scalar).
Every time the map is moved, a request is made to the server for data corresponding to the location where the map is then placed. The server returns an XML document with the relevant information. "base_sql_fields" describes which fields are returned ...
For each column name passed on by "base_sql_fields", a header is provided by the "base_output_headers" parameter. These headers are used in display. This parameter is passed on as an array ref.
I<legend_field1 & legend_field2>
In hires mode, each data point has two attributes, first of which determines the icon used for the data point on the map and the second one determines the color of the icon used. "legend_field1" and "legend_field2" describe the two columns that are u...
I<param_fields>
This parameter describes the parameter fields that are going to be used as filters. It is passed on as a hash ref.
In this example, first parameter field is "pharmacy". The keys come from base_sql_fields. The value for pharmacy is an array ref which contains the values that will be displayed for the filter parameter as a drop-down list.
pharmacy => ['all:All', 'Yes', 'No']
There are three values 'all:All", 'Yes' and 'No'.
lib/HTML/GMap/Tutorial.pm view on Meta::CPAN
Same as previous example.
I<base_sql_table, base_sql_fields & base_output_headers>
Same as previous example. Please see "cluster_field" param below for additional information.
I<cluster_field>
In piechart mode, pie charts are prepared by the count of data points by a single attribute. In this example, the number of physicians with a particular specialty is used to make pie charts. "cluster_field" describes the field which is used to cluste...
"cluster_field" in piechart mode is analogous to "legend_field1" and "legend_field2" in hires mode. This field must be among the fields retrieved by "base_sql_fields".
I<param_fields>
Same as previous example.
I<gmap_key>
Same as previous example.
I<temp_dir & temp_dir_eq>