#!/usr/bin/perl
use warnings;
use strict;
use CGI::Carp qw/fatalsToBrowser/;
use POSIX qw/ceil floor/;
use Image::Magick;
use Math::Trig;
use Time::HiRes qw/gettimeofday/;
use Data::Dumper;
use DBI;
# The x size of the exported image
use constant XSIZE => 2048;
# The outer border size (between the furthest system and the frame)
use constant BORDER => 20;
#Connect to mysql
my $dbh = DBI->connect('DBI:mysql:database=evemap', 'eve', 'dbp');
#Create image for later
my $image = Image::Magick->new;
print "Content-Type:Image/JPEG\n\n";
sub get_systems {
my ($xadd, $yadd, $scale) = @_;
my $sth = $dbh->prepare(' SELECT m.systemName,m.x,m.z,(m.security+1),m.hub,r.regionName,m.regionID
FROM mapSystems AS m
INNER JOIN mapRegions AS r
ON m.regionID = r.regionID
ORDER BY m.y ASC');
$sth->execute();
my %systems;
while (my @system = $sth->fetchrow_array()) {
my $x = ($system[1] + $xadd) * $scale + BORDER;
my $y = ($system[2] + $yadd) * $scale + BORDER;
$systems{$system[0]} = {
X => $x,
Y => $y,
NAME => $system[0],
SEC => $system[3],
HUB => $system[4],
REGIONNAME => $system[5],
REGIONID => $system[6]};
}
$sth->finish;
return \%systems;
}
sub get_regions {
my ($xadd, $yadd, $scale) = @_;
my $sth = $dbh->prepare(' SELECT regionName, regionID, x, z
FROM mapRegions');
$sth->execute();
my %regions;
while (my @region = $sth->fetchrow_array) {
my $x = ($region[2] + $xadd) * $scale + BORDER;
my $y = ($region[3] + $yadd) * $scale + BORDER;
$regions{$region[0]} = {
NAME => $region[0],
ID => $region[1],
X => $x,
Y => $y };
}
$sth->finish;
return \%regions;
}
sub get_jumps {
my $sth = $dbh->prepare(' SELECT m.systemName, m2.systemName
FROM mapSystemJumps as j
INNER JOIN mapSystems as m
ON j.fromSystemID = m.systemID
INNER JOIN mapSystems as m2
ON j.toSystemID = m2.systemID');
$sth->execute();
my @jumps;
while (my @jump = $sth->fetchrow_array) {
push @jumps, [@jump];
}
$sth->finish;
return \@jumps;
}
sub get_min_max {
my $sth = $dbh->prepare('SELECT max(x), max(z), min(x), min(z) FROM mapSystems');
$sth->execute();
my @maxes = $sth->fetchrow_array;
$sth->finish;
my $xrange = $maxes[0] - $maxes[2];
my $yrange = $maxes[1] - $maxes[3];
my $scale = (XSIZE - BORDER*2) / $xrange;
my $ysize = ceil(($yrange/$xrange)*XSIZE);
my $x = $image->Set( size => XSIZE . "x$ysize");
die "$x" if $x;
$x = $image->ReadImage('xc:#141430'); die "$x" if $x;
return {
XMIN => abs($maxes[2]),
YMIN => abs($maxes[3]),
SCALE => $scale,
};
}
sub adjust_regions {
my $regions = shift;
my @sorted = sort { $regions->{$a}->{'Y'} <=> $regions->{$b}->{'Y'} } keys %{$regions};
my $buffery = -50000;
for (@sorted) {
if ($buffery >= $regions->{$_}->{'Y'} - (XSIZE/102.4)) {
$regions->{$_}->{'Y'} += (XSIZE/102.4);
}
$buffery = $regions->{$_}->{'Y'};
}
}
sub draw_jumps {
my ($jumps, $systems) = @_;
for (@{$jumps}) {
my $x1 = $systems->{$_->[0]}->{'X'};
my $x2 = $systems->{$_->[1]}->{'X'};
my $y1 = $systems->{$_->[0]}->{'Y'};
my $y2 = $systems->{$_->[1]}->{'Y'};
$image->Draw(
primitive => 'line',
stroke => 'rgba(130,130,130,230)',
points => "$x1,$y1 $x2,$y2" );
}
}
sub draw_regions {
my $regions = shift;
for (keys %{$regions}) {
my $x = $image->Annotate(
font => '/usr/share/fonts/COPRGTB.TTF',
text => $regions->{$_}->{'NAME'},
fill => 'black',
stroke => "rgba(0,0,0,100)",
strokewidth => XSIZE / 341.3,
align => 'center',
x => $regions->{$_}->{'X'},
y => $regions->{$_}->{'Y'},
pointsize => XSIZE / 113.8 );
die $x if $x;
$x = $image->Annotate(
font => '/usr/share/fonts/COPRGTB.TTF',
text => $regions->{$_}->{'NAME'},
fill => 'rgba(255,255,255,60)',
align => 'center',
x => $regions->{$_}->{'X'},
y => $regions->{$_}->{'Y'},
pointsize => XSIZE / 113.8 );
die $x if $x;
}
}
sub draw_systems {
my ($systems, $dim) = @_;
for (keys %{$systems}) {
my $dix = $systems->{$_}->{'X'};
my $diy = $systems->{$_}->{'Y'};
my $s = $systems->{$_}->{'SEC'};
my ($r,$g,$b);
if (sprintf("%.1f", $s) >= 1.5) {
$s -= 1.5;
$s *= 4;
# Highsec
($r, $g, $b) = ($s*74+60, $s*4+241, 255);
} elsif (sprintf("%.1f", $s) >= 1.1) {
$s -= 1.1;
$s *= 5;
# Lowsec
($r, $g, $b) = ($s*50+85, 255, $s*58+57);
} else {
$s *= 1.81;
# Unsec
($r, $g, $b) = (255, $s*54, $s*54);
}
# Dims unusable / empire systems
my $region = $systems->{$_}->{'REGIONNAME'};
my $system = $_;
for (@{$dim}) {
if (lc($_->[0]) eq lc($region)) {
if ($systems->{$system}->{'SEC'} >= $_->[1]) {
($r, $g, $b) = ($r/$_->[2], $g/$_->[2], $b/$_->[2]);
}
}
}
my $dscale = XSIZE / 1024;
if ($systems->{$_}->{'HUB'} eq 'true') { $dscale *= 1.2; };
my $x = $image->Draw(
primitive => 'circle',
stroke => "rgba(" . ($r/2) . "," . ($g/2) . "," . ($b/2) . ",150)",
strokewidth => 2,
fill => "rgb($r,$g,$b)",
points => "$dix,$diy " . ($dix-$dscale) . ",$diy");
die "$x" if $x;
};
}
sub draw_test_sp {
my ($regions, $systems, $sov) = @_;
}
# This gets the minimum and maximum x and y co-ordinates for systems in order to scale them
# correctly to our window
my $maxes = get_min_max();
my $systems = get_systems($maxes->{'XMIN'}, $maxes->{'YMIN'}, $maxes->{'SCALE'});
my $regions = get_regions($maxes->{'XMIN'}, $maxes->{'YMIN'}, $maxes->{'SCALE'});
my $jumps = get_jumps();
# Adjusts region co-ordinates so names do not overlap
adjust_regions($regions);
# To dim areas, you must specify the region name, which sec systems to dim above, and the dim divisor
my @dim = (
['J7HZ-F', 0, 3],
['A821-A', 0, 3],
['UUA-F4', 0, 3]);
draw_test_sp($regions, $systems);
draw_jumps($jumps, $systems);
draw_systems($systems, \@dim);
draw_regions($regions);
binmode STDOUT;
my $x = $image->Write('jpg:-');
die $x if $x;