#!/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;