#!/usr/bin/perl -w
#
# Copyright (C) 2004 Christoph Berg <cb@df7cb.de>
#
# Part of this file originate from example.pl from the MapMarker distribution:
#   Author  :  Guillaume Leclanche (Mo-Ize) <mo-ize@nul-en.info>
#   Version :  2.0 beta 1
#   Date    :  08 Feb 2003
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# 2003-12-01 cb: uses @ARGV
# 2004-07-04 cb: cleaned up code, introduced config file
# see debian/changelog for further entries

use strict;
use warnings;
use Getopt::Long;

use IrcMarkers::File;
use IrcMarkers::Map;

# Debug
#use Data::Dumper;

my $VERSION = "v0.5";

sub VERSION_MESSAGE {
	print "IrcMarkers $VERSION (C) 2004 Christoph Berg <cb\@df7cb.de>, GNU GPL.\n";
}

sub HELP_MESSAGE {
	VERSION_MESSAGE();
	print <<EOT;
usage: $0 [options] config [inputmap outputmap]
-q             be quiet
-o command     configuration command
-x west/east   latitude bounds of input map
-y south/north longitude bounds of input map
EOT
	exit 0;
}

my $config = IrcMarkers::File->new;

my ($x, $y);
GetOptions(
	'x=s' => \$x,
	'y=s' => \$y,
	'q' => \$config->{quiet},
	'o=s' => sub { $config->parse($_[1]); },
	help => sub { HELP_MESSAGE(); },
	version => sub { VERSION_MESSAGE(); exit(0); },
) or HELP_MESSAGE();

HELP_MESSAGE() unless $ARGV[0];
$config->read($ARGV[0]);

if($x) { # after $config->read so -x can override lon
	$x =~ /(.*)\/(.*)/ or die "invalid -x format";
	($config->{west}, $config->{east}) = ($1, $2);
}
if($y) {
	$y =~ /(.*)\/(.*)/ or die "invalid -y format";
	($config->{south}, $config->{north}) = ($1, $2);
}

$config->{read} = $ARGV[1] if $ARGV[1];
$config->{write} = $ARGV[2] if $ARGV[2];

die "no input map" unless $config->{read};
die "no output map" unless $config->{write};

my $map = IrcMarkers::Map->new($config);

foreach my $marker (keys %{$config->{markers}}) {
	my $item = $config->{markers}->{$marker};
	$map->add($marker) if $item->{lat};
	$config->compute_boundingbox($item) if $item->{visible};
}

if($config->{link_color} and $config->{gpg}) {
	$config->get_gpg_links();
}

$config->set_line_style();
if($config->{links}) {
	foreach my $nr (0 .. @{$config->{links}} - 1) {
		my $link = $config->{links}->[$nr];
		print "$link->{src} <-> $link->{dst}\n" unless $config->{quiet};
		#$map->link($link->{src}, $link->{dst}, $link->{link_color});
		$link->{x0} = $config->{markers}->{$link->{src}}->{x};
		$link->{y0} = $config->{markers}->{$link->{src}}->{y};
		$link->{x1} = $config->{markers}->{$link->{dst}}->{x};
		$link->{y1} = $config->{markers}->{$link->{dst}}->{y};
		$config->draw_line_new($link);
	}
}
#foreach my $link (keys %{$config->{links}}) {
#	next unless $config->{markers}->{$link};
#	foreach my $target (keys %{$config->{links}->{$link}}) {
#		next unless $config->{markers}->{$target};
#		print "$link <-> $target\n" unless $config->{quiet};
#		$map->link($link, $target, $config->{link_color});
#	}
#}

$map->compute_overlap() if($config->{overlap_correction});
$map->draw();
if($config->{yxlabels}) {
	foreach my $nr (0 .. @{$config->{yxlabels}} - 1) {
		my $label = $config->{yxlabels}->[$nr];
		print "label \"$label->{text}\" at $label->{y}, $label->{x}\n";
		$map->draw_label_new($label);
		$config->compute_boundingbox($label);
	}
}
$map->write($config->{write});

if(not $config->{quiet} and $config->{min_x}) {
	print "Area used by markers is (approximately): ".
		"y: $config->{min_y}..$config->{max_y} ".
		"x: $config->{min_x}..$config->{max_x}\n";
}

__END__

=head1 NAME

B<ircmarkers> - place markers on maps at given coordinates

=head1 SYNOPSIS

B<ircmarkers> [-q] [-o command] [-y I<south/north> -x I<west/east>] F<config> [F<inputmap> F<outputmap>]

=head1 DESCRIPTION

IrcMarkers takes a map in .png or .jpg format and a list of coordinates
and labels in xplanet format and places markers on the map.
It was written to generate user maps of IRC channels.

GnuPG/PGP key ids can be associated with each marker, to create "maps of trust".

IrcMarkers reads its configuration and the list of markers from a config file.
The most important options (map to read/write, map dimensions) can be specified
on the command line. Settings on the command line override settings in the
config file.

=head1 OPTIONS

=over

=item F<config>

Config file to read markers and options from. This parameter is mandatory.

=item F<inputmap>

Read input map from F<inputmap>. Supported formats are .gif, .jpg/jpeg, .png,
.xbm, .xpm, and the libgd-Formats .gd/gd1 and .gd2.

=item F<outputmap>

Write output map to F<outputmap>. Supported formats are .gif, .jpg/jpeg, .png,
.gd/gd1, .gd2, and .wbmp.

=item -q

Be quiet. Per default, IrcMarkers prints which labels and links are placed on
the map.

=item -y I<south/north>

=item -x I<west/east>

Declare input map dimensions. Unless specified otherwise in the config file,
the map is assumed to be in mercator projection. -y specifies the lower/upper
latitude coordinates, -x the left/right edge longitude. Per default, the map is
assumed to be a world map (-y -90/90 -x -180/180).

=item -o I<command>

Evaluate a configuration command. It will be executed before any commands in
the config file (i.e. it will not override commands there).

=back

=head1 CONFIG FILE SYNTAX

The following directives can be used in the config file:

=head2 Marker and Label Definitions

=over

=item I<lat> I<lon> "I<marker>"

=item I<lat> I<lon> "I<marker>" I<options>

=item "I<marker>" I<options>

Place marker with label I<marker> on map at given (decimal) coordinates.
Use negative values for south/east, positive for north/west.
This format is compatible with the xplanet syntax.
The following is a marker for Myon in Germany:

B<49.2532 7.0425 "Myon">

=item label I<y> I<x> "I<text>"

=item label I<y> I<x> "I<text>" I<options>

Place a label at position I<y>/I<x> (in pixels). Useful for headlines etc.
Using negative values will count from the bottom/right border in X11's
-geometry style.

=back

=head2 Marker and Label Options

The following options can be specified per marker or globally (except gpg).
Global options set defaults for all following marker definitions.

=over

=item gpg I<keyid>

Associate GnuPG/PGP I<keyid> with the marker. If two keys have signed each
other, and both markers are visible on the map, a link will be drawn between
the markers. Multiple keyids can be given. Example:

B<"Myon" gpg B46B923B6D8ABE71 gpg C5AF774A58510B5A>

B<Note:> This is the long, 16 character keyid. To retrieve it, use C<gpg
--list-key --with-colon>.

=item label_color I<R G B>

=item label_border I<R G B>|none

Color of the labels placed on the map. Default is label_color 255 255 0,
label_border 0 0 0. The border can be removed by specifying the "none" color.

=item font F<fontfile>

Full pathname to the .ttf font used for the labels. Default is
font F</usr/share/ircmarkers/fixed_01.ttf>.

=item ptsize I<size>

Size in points of the labels. Default is ptsize 6.

=item dot_color I<R G B>

=item dot_border I<R G B>|none

Color of the dots placed on the map. Default is dot_color 255 255 255,
dot_border 0 0 0.

=item dot_size I<size>

Size of the dots. Default is 2.

=item dot_shape dot|circle

Dots are filled (dot) or hollow (circle). Default is dot.

=back

=head2 Link Definition and Options

=over

=item "I<marker1>" <-> "I<marker2>"

=item "I<marker1>" <-> "I<marker2>" I<options>

Draw a link between I<marker1> and I<marker2>.

=item link_color|sign2_color I<R G B>|none

Color of the lines drawn between the markers. Default is link_color 255 128 0.

=back

=head2 Global Options

=over

=item read F<inputmap>

Read input map from F<inputmap>. Supported formats are .jpg and .png.

=item write F<outputmap>

Write output map to F<outputmap>. Supported formats are .jpg, .png, .gd1, .gd2,
and .wbmp.

=item lat|south_north I<south/north>

=item lon|west_east I<west/east>

Declare input map dimensions. Default is lat -90/90, lon -180/180.

B<Note:> It is possible to use "unusual" values like lon 0/360 if you adjust
the coordinates as well. (-20 becomes 340 etc.)

=item view_lat|view_south_north I<south/north>

=item view_lon|view_west_east I<west/east>

Only show part of the map in the output. Default is to show the whole map.

=item view_width I<pixels>

=item view_height I<pixels>

Size of output map. Default is input map, or size of part selected.

=item projection mercator|sinusoidal

=item center_lon I<center>

Map projection. Default is mercator.
center_lon is only used for sinusoidal projection.
There is no default for center_lon.

=item link_outside on|off

Whether to draw lines to markers that are not visible on the map. Default is
link_outside off.

=item sign1_color I<R G B>|none

Color of the lines drawn for uni-directional GnuPG/PGP signatures. Default is
link_color none.

=item overlap F<overlapcorrector>

Full pathname to the binary that moves the labels around to reduce overlap.
Default is overlapcorrector F</usr/lib/ircmarkers/overlap>.
Chances are that you only need to change that parameter if you are debugging
the overlap corrector.

=item overlap_correction on|off

Whether to use the overlap corrector or not. Default is overlap_correction on.
Turn it off if you have really many labels.

=item quiet on|off

Be quiet. Default is quiet off.

=item #include "F<configfile>"

Read auxillary config file.

=item # comment

Anything else starting with a # character is a comment.

=back

=head1 EXAMPLES

B<ircmarkers -x -10.4/29.4 -y 32/72 coordinates.txt europe.jpg mutt-eu.jpg>

	read dl.jpg
	write debian.de.jpg
	lat 44/56
	lon 4/20
	label_color 0 255 0
	49.2532 7.0425 "Myon"
	50.8574 6.4585 "formorer" label_color 255 255 0
	#include "debian.de.txt"
	#include "debian.de.keys"

=head1 BUGS

The GD library keeps a raw bitmap of the map in memory. Big maps will use lots
of memory. Precompute the map you are going to use, i.e. downsample it to the
target size using Imagemagick's I<convert> or IrcMarkers view_* functions.

Please report bugs in IrcMarkers using the Debian bug tracking system. The
IrcMarkers bug page is at http://bugs.debian.org/ircmarkers.

=head1 SEE ALSO

=head2 Library used

=over

=item *

L<GD(3)> - GD version 2

=back

=head2 Programs similar to IrcMarkers

=over

=item *

MapMarkers: http://www.nul-en.info/mapmarkers/ - IrcMarkers' predecessor

=item *

xplanet: http://xplanet.sourceforge.net/

=item *

Image::WorldMap: http://www.astray.com/WorldMap/

=back

=head2 Locating coordinates

=over

=item *

http://www.multimap.com/ - online maps to everywhere

=item *

http://www.calle.com/world/ - directory of cities and towns in world

=item *

http://tiger.census.gov/cgi-bin/mapbrowse-tbl - United States

=item *

http://www.ckdhr.com/dns-loc/finding.html - more pointers

=back

=head2 Maps

=over

=item *

http://visibleearth.nasa.gov/cgi-bin/viewrecord?11656 - nice copyright-free world map

=item *

http://www.elho.net/misc/xplanet/ - compilation of suitable maps from NASA

=back

=head1 AUTHOR

IrcMarkers was written by Christoph Berg <cb@df7cb.de>.
You can find me (Myon) on ircnet/freenode/oftc.

Thanks go to Uli Martens for the "map of trust" idea.

Alexander Wirt suggested the capability to draw selected parts of the map.

Elmar Hoffmann suggested several error checks and config options.

The IrcMarkers homepage is at B<http://www.df7cb.de/projects/ircmarkers/>.

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2004 Christoph Berg <cb@df7cb.de>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License with the
Debian GNU/Linux distribution in file F</usr/share/common-licenses/GPL>; if not,
write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA

IrcMarkers is an improved version of MapMarkers.

Copyright (C) 2003 Guillaume Leclanche (Mo-Ize) <mo-ize@nul-en.info>

The font provided with this package, fixed_01.ttf, has been created by the
Orgdot team, http://www.orgdot.com/aliasfonts/.

(C) 2001 http://www.orgdot.com
