- Implemented back end script for generating CSS maps.
- Made code more consistent across all versions.
- Finished CSS map timing code.
- Changed all .html => .php.
- Made styling of all web pages more consistent.
- Included lat/long in hash key for all cities (not just unknown) because
  there may be several different lat/long combinations that map to the same
  city name.
1 parent b88829b commit 86216bea2a7412e516c85427b88643dafcae198f
nstanger authored on 14 May 2006
Showing 8 changed files
View
63
Repositories/Maps/css_map.js
function load( startMillis, numEntries )
{
// Open the request. Setting the third argument to TRUE makes the
// request asynchronous, i.e., the browser doesn't wait.
http.open('GET', 'css_map.php?top=' + numEntries, true);
httpRequest.open('GET', 'css_map.pl?width=1024&height=520&top=' + numEntries, true);
// When we hear something from the server, call the handleResponse()
// function to find out what happened.
http.onreadystatechange = function ()
httpRequest.onreadystatechange = function ()
{
if(http.readyState == 4)
if(httpRequest.readyState == 4)
{
if (http.status == 200) // Did it work?
if (httpRequest.status == 200) // Did it work?
{
// Grab the response content.
var response = http.responseText;
document.getElementById( "map" ).innerHTML = httpRequest.responseText;
// Grab finishing time. We have to do this here rather than in
// the main part of the load() function because the map data
// are generated asynchronously.
var endTime = new Date();
document.getElementById( "timer" ).innerHTML =
'Page generated in ' +
( endTime - startMillis ) +
' ms.';
}
else
{
// Do some sort of error handling.
}
};
// Send the request.
http.send(null);
httpRequest.send(null);
 
 
GDownloadUrl( "google_map_generate_data.pl?top=" + numEntries,
function( data, responseCode )
{
var xml = GXml.parse( data );
var markerlist = xml.documentElement.getElementsByTagName( "marker" );
for ( var i = 0; i < markerlist.length; i++ )
{
var point = new GLatLng( parseFloat( markerlist[i].getAttribute( "lat" ) ),
parseFloat( markerlist[i].getAttribute( "long" ) ) );
map.addOverlay( createMarker( point, markerlist[i].getAttribute( "city" ),
markerlist[i].getAttribute( "abs" ), markerlist[i].getAttribute( "dl" ) ) );
}
// Grab finishing time. We have to do this here rather than in
// the main part of the load() function because the map data
// are loaded asynchronously.
var endTime = new Date();
var numUA = xml.documentElement.getAttribute( "ua" );
var numUD = xml.documentElement.getAttribute( "ud" );
document.getElementById( "timer" ).innerHTML =
'<span style="color:red;">' +
xml.documentElement.getAttribute( "dl" ) +
' downloads' + ( ( numUD > 0 ) ? ( ' (+' + numUD + ' unmappable)' ) : '' ) +
'</span> & <span style="color:blue;">' +
xml.documentElement.getAttribute( "abs" ) +
' abstracts' + ( ( numUD > 0 ) ? ( ' (+' + numUA + ' unmappable)' ) : '' ) +
'</span> from ' +
markerlist.length +
' cities (' +
xml.documentElement.getAttribute( "ips" ) +
' IP addresses), page generated in ' +
( endTime - startMillis ) +
' ms.';
} );
}
}
View
2
■■■
Repositories/Maps/css_map.php
<p>Stats current as of early afternoon 8 May 2006.</p>
 
<div id="timer">Loading&hellip;</div>
 
<div id="map" style="background-image:map_1024x520.jpg; width:1024px; height:520px;">
<div id="map" style="background-image:url(map_1024x520.jpg); width:1024px; height:520px; position:absolute; border:1px solid black;">
</div>
 
</body>
</html>
View
155
Repositories/Maps/css_map.pl 0 → 100755
#!/usr/bin/env perl
use strict;
use Time::HiRes qw( gettimeofday );
use CGI;
use DBI;
use Geo::IP;
use Geo::Proj4;
 
my ( $start_sec, $start_micro ) = gettimeofday;
my ($start_time) = ( $start_sec * 1000 ) + round( $start_micro / 1000 );
 
my ($page);
 
# Database connection.
my ($dsn) = "DBI:mysql:database=eprintstats;host=localhost";
my ($user_name) = "eprintstatspriv";
my ($password) = "AuldGrizzel";
my ( $connect, $query, %types, %unmapped, $stat, $row, $num_rows, $vtype );
 
# Geolocation database.
my ( $gi, $proj );
my ($gidb) = '/usr/local/share/GeoIP/GeoLiteCity.dat';
 
# Miscellaneous variables.
my ( $width, $height );
my ($x_offset) = 16986796.16;
my ($y_offset) = 8615499.05;
my ($max_x) = $x_offset * 2;
my ($max_y) = $y_offset * 2;
my ( %cities, %IPs );
my ($num_entries) = -1;
my ($num_hits) = 0;
my ( $ip, $count, $location );
my ( $city, $lat, $long, $x, $y ) = ( 0, 0, '', 0, 0 );
 
$page = new CGI;
print $page->header( -type => "text/html", -Pragma => 'no-cache' );
$num_entries = $page->param('top');
 
$gi = Geo::IP->open( $gidb, GEOIP_STANDARD )
or die "Unable to open GeoIP database $gidb\n";
 
$proj = Geo::Proj4->new( proj => "robin", ellps => "sphere", lon_0 => 10 )
or die "parameter error: " . Geo::Proj4->error . "\n";
 
$width = $page->param('width');
$height = $page->param('height');
 
$connect = DBI->connect( $dsn, $user_name, $password, { RaiseError => 1 } );
 
$types{'download'} = $types{'abstract'} = 0;
$unmapped{'download'} = $unmapped{'abstract'} = 0;
$query = "SELECT ip, view_type, COUNT(*) AS count
FROM view
GROUP BY ip, view_type
ORDER BY count DESC" . ( ( $num_entries > 0 ) ? " LIMIT $num_entries" : '' );
 
$stat = $connect->prepare($query);
$stat->execute();
$num_rows = $stat->rows;
 
if ( $num_rows > 0 )
{
$num_entries = $num_rows if ( $num_entries < 1 );
 
while ( $row = $stat->fetchrow_hashref() )
{
$ip = $row->{'ip'};
$count = $row->{'count'};
$vtype = $row->{'view_type'};
 
$IPs{$ip} = 1;
 
$location = $gi->record_by_addr($ip);
 
if ( defined($location) )
{
$lat = $location->latitude;
$long = $location->longitude;
$city = (
( $location->city eq '' )
? 'Unknown'
: $location->city
) . " ($lat, $long)";
( $x, $y ) = $proj->forward( $lat, $long );
$x = round( ( $x + $x_offset ) / $max_x * $width );
$y = round( ( $y_offset - $y ) / $max_y * $height );
 
if ( !defined( $cities{$city} ) )
{
$cities{$city}{'lat'} = $lat;
$cities{$city}{'long'} = $long;
$cities{$city}{'abstract'} = 0;
$cities{$city}{'download'} = 0;
print
'<div style="position:absolute; width:3px; height:3px; left:'
. ( $x - 1 )
. 'px; top:'
. ( $y - 1 )
. 'px; background-color:'
. ( ( $vtype eq 'abstract' ) ? 'blue' : 'red' )
. ';"></div>' . "\n";
}
$cities{$city}{$vtype} += $count;
$types{$vtype} += $count;
 
$cities{$city}{'x'} = $x;
$cities{$city}{'y'} = $y;
}
else
{
$unmapped{$vtype} += $count;
}
}
}
 
$stat->finish();
$connect->disconnect();
 
# Need to wait until we have all the counts before writing the summary data out.
print
'<div style="position:absolute; left:1px; top:1px; font-size:small;"><span style="color:red;">'
. $types{'download'}
. ' downloads'
. (
( $unmapped{'download'} > 0 ) ? " (+$unmapped{'download'} unmappable)"
: ''
)
. '</span><br /><span style="color:blue;">'
. $types{'abstract'}
. ' abstracts'
. (
( $unmapped{'abstract'} > 0 ) ? " (+$unmapped{'abstract'} unmappable)"
: ''
)
. '</span><br />from '
. scalar( keys %cities )
. ' cities<br />('
. scalar( keys %IPs )
. ' IP addresses)</div>' . "\n";
 
my ( $finish_sec, $finish_micro ) = gettimeofday();
my ($finish_time) = ( $finish_sec * 1000 ) + round( $finish_micro / 1000 );
 
print '<div style="position:absolute; left:1px; bottom:1px; font-size:small;">';
print 'Map generated in ' . ( $finish_time - $start_time ) . ' ms</div>' . "\n";
 
sub round
{
my ($n) = shift;
return int( $n + 0.5 * ( $n <=> 0 ) );
}
View
6
Repositories/Maps/gd_map.php
<p>Stats current as of early afternoon 8 May 2006.</p>
 
<div id="timer">Loading&hellip;</div>
 
<p>
<div>
<?php
echo '<img id="map" src="gd_map.pl?width=1024&amp;height=520&amp;top='
. ( ( isset( $_REQUEST['top'] ) ) ? $_REQUEST['top'] : 10 )
. '" onLoad="imageLoaded('
. ( ( (float)$start_micro + (float)$start_sec ) * 1000 )
. ')" width="1024" height="520" alt="Small version loading --- please wait..." />';
. ')" width="1024" height="520" alt="" style="border:1px solid black;" />';
?>
</p>
</div>
 
</body>
</html>
View
Repositories/Maps/gd_map.pl
View
Repositories/Maps/google_map.js
View
Repositories/Maps/google_map.php
View
Repositories/Maps/google_map_generate_data.pl