ircmarkers/0000775000000000000000000000000012220600510010074 5ustar ircmarkers/debian/0000775000000000000000000000000012220600470011323 5ustar ircmarkers/debian/README.Debian0000664000000000000000000000073212220600136013365 0ustar Debian README for ircmarkers ============================ This package provides a TrueType font in /usr/share/ircmarkers/fixed_01.ttf. Many other fonts are available in the ttf-* packages. Note that fixed_01.ttf only supports a limited selection of unicode characters. If you are looking for a replacement, /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf from ttf-dejavu-core is a good choice. -- Christoph Berg Tue, 26 May 2009 22:50:50 +0200 ircmarkers/debian/control0000664000000000000000000000170612220600136012731 0ustar Source: ircmarkers Section: graphics Priority: extra Maintainer: Christoph Berg Build-Depends: debhelper (>= 5) Standards-Version: 3.8.1 Vcs-Browser: http://svn.df7cb.de/ircmarkers/trunk/ Vcs-Svn: http://svn.df7cb.de/ircmarkers/trunk/ Homepage: http://www.df7cb.de/projects/ircmarkers/ Package: ircmarkers Architecture: any Depends: libgd-gd2-perl, ${shlibs:Depends}, ${misc:Depends} Suggests: gnupg, ttf-dejavu-core Description: place markers on maps at given coordinates 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". Tag: field::geography, implemented-in::perl, interface::commandline, role::program, scope::utility, use::TODO, use::entertaining, works-with-format::jpg, works-with-format::png, works-with::image:raster ircmarkers/debian/dirs0000664000000000000000000000013612220600136012206 0ustar usr/bin usr/lib/ircmarkers usr/share/perl5/IrcMarkers usr/share/ircmarkers usr/share/man/man1 ircmarkers/debian/NEWS0000664000000000000000000000041012220600136012014 0ustar ircmarkers (0.10-1) unstable; urgency=low * ircmarkers now supports exporting its config in pisg(1) syntax, so you can share the per-nickname part of the config files for both programs. -- Christoph Berg Fri, 28 Jul 2006 19:06:06 +0200 ircmarkers/debian/changelog0000664000000000000000000001100112220600470013166 0ustar ircmarkers (0.14-3) unstable; urgency=low * Set POD encoding utf8. (Closes: #724087) -- Christoph Berg Wed, 25 Sep 2013 17:28:02 +0200 ircmarkers (0.14-2) unstable; urgency=low * Suggest ttf-dejavu-core, our fixed_01.ttf doesn't support the more fancy unicode characters. (Closes: 528220) -- Christoph Berg Tue, 26 May 2009 22:40:33 +0200 ircmarkers (0.14-1) unstable; urgency=low * Support coordinates in N 51° 11.123 E 006° 25.846 and similar formats. -- Christoph Berg Fri, 21 Mar 2008 16:46:02 +0100 ircmarkers (0.13-1) unstable; urgency=low * Allow + prefix on coordinates. -- Christoph Berg Sat, 24 Nov 2007 15:26:16 +0100 ircmarkers (0.12-2) unstable; urgency=low * Support DEB_BUILD_OPTIONS=nostrip (Closes: #437232). -- Christoph Berg Sat, 11 Aug 2007 12:58:28 +0200 ircmarkers (0.12-1) unstable; urgency=low * Fix segfault when all markers are outside the visible area, and print warning in that case. * The -x and -y documentation was mixed up in the --help output. Spotted by Andreas Gockel. -- Christoph Berg Wed, 20 Dec 2006 16:08:28 +0100 ircmarkers (0.11-1) unstable; urgency=low * Support Maidenhead (QTH) locator format. * Do not bark on markers without coordinates. * Draw US-AU links across the Pacific. -- Christoph Berg Fri, 3 Nov 2006 16:41:57 +0100 ircmarkers (0.10-2) unstable; urgency=low * Move to Priority: extra. * Add debtags to debian/control. -- Christoph Berg Fri, 22 Sep 2006 14:28:33 +0200 ircmarkers (0.10-1) unstable; urgency=low * Add option for data export in pisg(1) syntax. -- Christoph Berg Fri, 28 Jul 2006 17:00:19 +0200 ircmarkers (0.9-1) unstable; urgency=low * Add recv-keys option. * Fix overlap.c memory allocator and clean up code. * Update copyright stuff. -- Christoph Berg Wed, 22 Feb 2006 01:46:11 +0100 ircmarkers (0.8-1) unstable; urgency=low * Disable non-functional help_convert_crop code. * Non-native package. -- Christoph Berg Fri, 16 Dec 2005 00:55:23 +0100 ircmarkers (0.7) unstable; urgency=low * Support markers without label (thanks to Torbjörn Svensson for the suggestion). * Bump Standards-Version. * Finally an upload after 0.6 being used locally for a year... -- Christoph Berg Sun, 4 Dec 2005 22:11:31 +0100 ircmarkers (0.6) unreleased; urgency=low * Could previously not draw markers with lat = 0. * Add support for HTML image maps. * Marker labels do not have to be unique anymore. * Compute better bounding box. * Compute links per marker instead per key. * Code cleanup. * Add debian/watch. -- Christoph Berg Sun, 14 Nov 2004 01:51:42 +0100 ircmarkers (0.5) unstable; urgency=low * Fix several parsing bugs. * Links take color as option, support link_color none. * Computes rough bounding box (requested by Uli Martens). -- Christoph Berg Sat, 18 Sep 2004 13:34:10 +0200 ircmarkers (0.4) unstable; urgency=low * Allow arbitrary whitespace in config (requested by Uli Martens). * Fix center_lon check (requested by Elmar Hoffmann). * Support ~/ in file names. * Support negative label positions. -- Christoph Berg Tue, 7 Sep 2004 02:46:50 +0200 ircmarkers (0.3) unstable; urgency=low * Suggests: gnupg. * Removed unused dependency on libttf2. * Colors/borders/fonts/dotsize/shape configurable per marker. * Support all GD file formats. * Accept -o on command line. * Catch error for non-existing map. * Fix error in sinusoidal projection. * Complain about some unreasonable map defintions (thanks to Elmar Hoffmann for these suggestions). * Non-marker labels (for headlines etc). * Manpage: provide pointers to freely available maps. * Wrote INSTALL, example.map, and README.Debian files. -- Christoph Berg Wed, 1 Sep 2004 21:35:09 +0200 ircmarkers (0.2) unstable; urgency=low * Added view_lat/view_lon (thanks to Alexander Wirt for suggesting this). * Made size of output map configurable. * Added pointers to sites with coordinates to manpage. * Created Debian package (Closes: #262120). * Sponsored upload by Alexander Wirt -- Christoph Berg Sat, 31 Jul 2004 15:29:25 +0200 ircmarkers (0.1) unstable; urgency=low * Initial Release. -- Christoph Berg Sat, 10 Jul 2004 18:56:37 +0200 ircmarkers/debian/copyright0000664000000000000000000000556412220600136013267 0ustar This package was debianized by Christoph Berg on Sat, 10 Jul 2004 18:56:37 +0200. Upstream Author: Christoph Berg Copyright: Copyright (C) 2004, 2005, 2006 Christoph Berg 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 /usr/share/common-licenses/GPL; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA IrcMarkers is an improved version of MapMarkers. Copyright (C) 2002, 2003 Guillaume Leclanche (Mo-Ize) This program has been really inspired by two programs: * xplanet (http://xplanet.sourceforge.net). I have reused xplanet's overlap correction algorithm, and have ported it to C (which makes it quite faster than the C++ xplanet corrector). * Image::WorldMap (http://www.astray.com/WorldMap/) Author: Léon Brocard The module API comes from this perl module. The font provides with this package, fixed_01.ttf, has been created by the Orgdot team, http://www.orgdot.com/aliasfonts/. (c) 2001 http://www.orgdot.com: you can copy, use, modify and distribute this code and/or artwork for educational, commercial or recreational use. all we ask is that you include this copyright notice in the materialyou distribute. for compiled code, you will need to make accessible this copyright notice somewhere in the distribution, and/or via a link on the web. there are several reasons for this caveat - the most important being that open source is based on one main principle: what you find and use, others should also have access to. don't keep it to yourself! this software is provided by the author and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. in no event shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. ircmarkers/debian/compat0000664000000000000000000000000212220600136012520 0ustar 5 ircmarkers/debian/rules0000775000000000000000000000170312220600136012403 0ustar #!/usr/bin/make -f # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 VERSION=$(shell dpkg-parsechangelog 2>&1|egrep ^Version|cut -d " " -f 2) build: build-stamp build-stamp: dh_testdir $(MAKE) VERSION="ircmarkers $(VERSION)" touch build-stamp clean: dh_testdir rm -f build-stamp configure-stamp $(MAKE) clean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) install DESTDIR=$(CURDIR)/debian/ircmarkers # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure ircmarkers/debian/watch0000664000000000000000000000014212220600136012350 0ustar version=2 http://www.df7cb.de/projects/ircmarkers/packages/ircmarkers_([0-9.-]*)(?:.orig)?.tar.gz ircmarkers/fixed_01.ttf0000664000000000000000000012325012220600136012221 0ustar @OS/2Tk{pVPCLTP6cmap΅ncvt ߍ8fpgm3Oglyfrl44*hdmx( heads!,6hhea7d$hmtxvx8kernloca-`maxpD3 nameJ postY prepХC& 9RJiJaq 0K%{ `%Yq  9 R J i J a q www.orgdot.com www.orgdot.comfixed_v01fixed_v01RegularRegularfixed_v01fixed_v01Macromedia Fontographer 4.1 fixed_v01Macromedia Fontographer 4.1 fixed_v01Macromedia Fontographer 4.1 8/17/2001Macromedia Fontographer 4.1 8/17/2001Fixedv01Fixedv01@,vE %E#ah#h`D->-,XX[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y[Y@ EhDEhDEhDEhDEhDEhDEhDF+F+EhDEhDq V@ @ Fv/7? q>,S@ @ Fv/7?–,,Ԗ  @\@        Fv/7?@g @!        Fv/7?>J?@@Fv/7?>>X, @A@        Fv/7?–>>,X>X,#@i$$@%    # "! #" !  Fv/7?–J g@+ @      Fv/7?Ԗ,@A@       Fv/7?X>>v@7@       Fv/7?>–JԖK@@Fv/7?–JJ,,Ԗ @:@     Fv/7?–J,–U@!@ Fv/7?>–>X {@7@       Fv/7?–J> @?@       Fv/7?–>, g@) @     Fv/7?@E@      Fv/7?–>X>, b@* @     Fv/7?>> f@* @    Fv/7?>,@N@          Fv/7?>,ԖK@@Fv/7?–J q@/@     Fv/7?XJX> @D@       Fv/7?–J@N@       Fv/7?Ԗ@S@         Fv/7?–>>ԖԖ,,S@@ Fv/7?–|| @B@       Fv/7?||  #3#3#3#3#3#!3#3#3#;#–,–,,ԖԖ @?@      Fv/7?Ԗ @D@       Fv/7?X a@* @     Fv/7?–JΊ p@.@     Fv/7?–>>–X>XԖ, p@.@     Fv/7?,ԖX@>@      Fv/7?>–J–J b@* @    Fv/7?– z@6@      Fv/7?X– w@6@      Fv/7?>,|F@O@      Fv/7? v@0@       Fv/7?–J–J q@.@     Fv/7?XJJ q@.@     Fv/7?XJ,–J c@* @     Fv/7?>@A@       Fv/7? a@) @     Fv/7?–@A@       Fv/7?>@?@      Fv/7?XX#@j$$@%    # "! #"!   Fv/7?–>XX|@B@      Fv/7? @S@         Fv/7?,,@@@Fv/7?X–@e @!           Fv/7?&Jx@7@      Fv/7?@L@        Fv/7/–XԖ–@_ @!      Fv/7?>@[@         Fv/7?–ԖJԖԖԖ @F@      Fv/7?–J,ΊΖ, @K@        Fv/7/–ڐJJԐR>@@Fv/7? @O@       Fv/7?–Jږ,X, @O@       Fv/7?–Jږ,X,@J@     Fv/7?J ,X,Ԑ@^@           Fv/7?,J,XԐ @H@       Fv/7?–JD,,XR@@@       Fv/7?–>–J,X@K@       Fv/7?XԖ,8>Ԗ@P@        Fv/7?–Ԗ @F@            Fv/7?– @D@        Fv/7?X,,@K@     Fv/7? @@@        Fv/7?X–x@3@      Fv/7? @O@       Fv/7?–Jږ–J, @O@       Fv/7?–Jږ–J,@J@     Fv/7?J ,DJ@^@           Fv/7?,J–DJ @H@       Fv/7?–JD,–J~, }@?@      Fv/7/–JJ @E@           Fv/7?–Ԗ, @E@           Fv/7?–Ԗ,@L@        Fv/7?X @B@         Fv/7?–>, @T@      Fv/7?–J–Ԗ@G@          Fv/7?XԖ,,PFԖԖ @V@       Fv/7?–JږΊ, @V@       Fv/7?–JږΊ,@Q@       Fv/7?J ,D@e @!       Fv/7?,JD @O@     Fv/7?–JD,Ί~ @I@     Fv/7?–J,ԖΊ~@Q@       Fv/7?–Ԗ–> @X@     Fv/7?– @D@        Fv/7?X,,@K@     Fv/7? @@@        Fv/7?X–@9@     Fv/7?& @O@       Fv/7?–Jږ–J, @O@       Fv/7?–Jږ–J,@J@     Fv/7?J ,DJ@^@           Fv/7?,J–DJ @H@       Fv/7?–JD,–J~ e@) @      Fv/7/ @S@        Fv/7?– –  @E@           Fv/7?–Ԗ, @E@           Fv/7?–Ԗ,@L@        Fv/7?X @B@         Fv/7?–>,@P@     Fv/7?–>XX|, w@3@      Fv/7?–J–Ԗ@M@     Fv/7?–>,XX|F, u@7@         Fv/7?XX>,~~~~nd h 6 b  ^x$D@vH 8 hH !J!"#v$f%R%&^'('(`)***+V+,`,-P../|0"012Z234d5B567,789,9:~;;0>?@@ABC>DTEEFG\H`HIJK~KLMMN`ORPDQ.R<S"STUVWbXNY YZ[\]:^R_F`:a(b:c"cdefghRiRjjklmnopqrstuvwnxJy2zz{|}~zd>*qXX,,,,{  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~ overscore>  !"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdfhe lCixkgjmnopqrstuvwyz{|}~~   & 0    & 0jjjjj  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~o                    H H  <7MACR@ 0,X`ufixed_v01 7FIXR00 _<EEpj$ @ rircmarkers/INSTALL0000664000000000000000000000235712220600136011140 0ustar Installing IrcMarkers --------------------- Debian: apt-get install ircmarkers That will install IrcMarkers itself and its dependencies. The "gnupg" package is optional (but will probably already be installed). Other: Get ircmarkers_x.y.tar.gz from http://www.df7cb.de/projects/ircmarkers/packages/ Unpack, build, and install it: tar xfz ircmarkers_x.y.tar.gz cd ircmarkers-x.y make make install (Obviously, the last step needs to be executed as root.) IrcMarkers requires the GD2 perl library to run. Check your OS's manual on how to install that package. If you want to install it from source, go to http://www.boutell.com/gd/. If you want to use the "map of trust" feature, install GnuPG (http://www.gnupg.org/). Using IrcMarkers ---------------- You need a map in mercator or sinusoidal projection. The IrcMarkers manpage contains some pointers. The example.map file contains a short config file to get started with. Upgrading IrcMarkers -------------------- In versions prior to 0.3, some settings that are now local to a marker were global and could hence be specified at any place in the config. Now, fonts and color definitions etc. have to be placed *before* marker definitions. -- Christoph Berg, Sat Oct 2 17:48:33 CEST 2004 ircmarkers/Makefile0000664000000000000000000000267712220600136011554 0ustar NAME=ircmarkers INSTALL_PROGRAMM=install #DEBUG=-DDEBUG VERSION=$(shell dpkg-parsechangelog 2>&1 | perl -ne 'print $$1 if /^Version: ([^-]*)/') TGZ=$(NAME)_$(VERSION).orig.tar.gz TGZ_DIR=$(NAME)-$(VERSION) all: overlap ircmarkers.1 overlap: overlap.c gcc -g -O2 -Wall $(DEBUG) -o overlap overlap.c ircmarkers.1: ircmarkers pod2man --release="$(NAME)" --center="User Documentation" $< > $@ ircmarkers.man: ircmarkers.1 nroff -man $< > $@ ircmarkers.html: ircmarkers pod2html --title="$<" $< > $@ install: overlap ircmarkers.1 $(INSTALL_PROGRAMM) -D ircmarkers $(DESTDIR)/usr/bin/ircmarkers $(INSTALL_PROGRAMM) -D -m 664 IrcMarkers/File.pm $(DESTDIR)/usr/share/perl5/IrcMarkers/File.pm $(INSTALL_PROGRAMM) -D -m 664 IrcMarkers/Map.pm $(DESTDIR)/usr/share/perl5/IrcMarkers/Map.pm $(INSTALL_PROGRAMM) -D overlap $(DESTDIR)/usr/lib/ircmarkers/overlap $(INSTALL_PROGRAMM) -D -m 664 fixed_01.ttf $(DESTDIR)/usr/share/ircmarkers/fixed_01.ttf $(INSTALL_PROGRAMM) -D -m 664 ircmarkers.1 $(DESTDIR)/usr/share/man/man1/ircmarkers.1 tags: ctags ircmarkers IrcMarkers/*.pm overlap.c clean: rm -f overlap ircmarkers.1 ircmarkers.man ircmarkers.html tags pod2htm* example.jpg dist: [ ! -f ../$(TGZ) ] [ -d debian ] && fakeroot debian/rules clean mkdir ../$(TGZ_DIR) cp -a . ../$(TGZ_DIR) rm -rf ../$(TGZ_DIR)/debian find ../$(TGZ_DIR) -name .svn | xargs rm -rf cd .. && tar cvz -f $(TGZ) $(TGZ_DIR) rm -rf ../$(TGZ_DIR) .PHONY: all install tags clean dist ircmarkers/overlap.c0000664000000000000000000001550712220600136011724 0ustar /* * overlap.c is part of IrcMarkers * Copyright (C) 2004, 2005, 2006 Christoph Berg * * 2004-07-04: Modified to read from stdin * * Original copyright: * MapMarkers, perl modules to create maps with markers. * Copyright (C) 2002 Guillaume Leclanche (Mo-Ize) * * 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. */ #include #include #include #define min(x,y) (x < y ? x : y) #define max(x,y) (x > y ? x : y) enum align_e { RIGHT = 0, LEFT, ABOVE, BELOW, CENTER, }; struct box { int left; int right; int top; int bottom; int width; int height; }; struct marker { unsigned int id; unsigned int x; unsigned int y; int alignment; struct box dot; struct box txt; #ifdef DEBUG int orig_txt_x; int orig_txt_y; #endif }; static int nb_markers; static unsigned int image_width; static unsigned int image_height; static int offset; static struct marker *markers; static int box_overlap(struct box *label, struct box *b) { int width, height; if (label->left > b->right || label->right < b->left) return 0; if (label->top > b->bottom || label->bottom < b->top) return 0; if (label->left > b->left) width = min(b->right, label->right) - label->left; else width = min(b->right, label->right) - max(b->left, label->left); if (label->top > b->top) height = min(b->bottom, label->bottom) - label->top; else height = min(b->bottom, label->bottom) - max(b->top, label->top); return width * height; } static int overlap(unsigned int id_current, struct box *b) { int total_overlap = 0; int i; for (i = 0; i < nb_markers; i++) { if (i == id_current) continue; total_overlap += box_overlap(b, &(markers[i].txt)); total_overlap += box_overlap(b, &(markers[i].dot)); } return total_overlap; } static int border_overlap(struct box *m) { int ordinate_overhang, abscissa_overhang; ordinate_overhang = (image_width - m->right < 0 ? image_width - m->right : -min(0, m->left)); abscissa_overhang = (image_height - m->bottom < 0 ? image_height - m->bottom : -min(0, m->top)); return ordinate_overhang * m->width + abscissa_overhang * m->height + ordinate_overhang * abscissa_overhang; } void align(struct box *b, struct marker *m, int a) { switch (a) { case RIGHT: b->left = m->x + offset + m->dot.width/2; b->top = m->y - m->txt.height/2; break; case LEFT: b->left = m->x - offset - m->txt.width - m->dot.width/2; b->top = m->y - m->txt.height/2; break; case ABOVE: b->left = m->x - m->txt.width/2; b->top = m->y - offset - m->txt.height - m->dot.height/2; break; case BELOW: b->left = m->x - m->txt.width/2; b->top = m->y + offset + m->dot.height/2; break; case CENTER: b->left = m->x - m->txt.width/2; b->top = m->y - m->txt.height/2; break; default: assert(0); } b->width = m->txt.width; b->height = m->txt.height; b->right = b->left + b->width; b->bottom = b->top + b->height; } static void correctOverlap(void) { /* initialize each individual Marker's bounding box */ int i; for (i = 0; i < nb_markers; i++) { struct box b[5]; int max_overlap = 0, a = 0; #if DEBUG fprintf(stderr, "Marker %d: %d\n", i, markers[i].dot.height); #endif for (a = 0; a <= 4; a++) { align(b+a, markers+i, a); int total_overlap = border_overlap(b+a) + overlap(i, b+a); #if DEBUG fprintf(stderr, "\tTry alignment %d: Overlap = %d %d %d\n", a, total_overlap, b[a].left, b[a].bottom); #endif if (a == 0 || total_overlap < max_overlap) { markers[i].alignment = a; max_overlap = total_overlap; } if (total_overlap == 0) break; } markers[i].txt = b[markers[i].alignment]; } } int main(int argc, char* argv[]) { int i = 0; int alloc_markers = 4; /* invalid number of args */ if (argc != 4) { fprintf(stderr, "invalid number of args\n"); return(1); } nb_markers = 0; image_width = atoi(argv[1]); image_height = atoi(argv[2]); offset = atoi(argv[3]); markers = malloc( alloc_markers * sizeof(struct marker) ); assert(markers); /* Read the data and store them into the struct table */ for (nb_markers = 0; !feof(stdin); nb_markers++) { if(nb_markers >= alloc_markers) { void *nm; alloc_markers <<= 2; nm = realloc(markers, alloc_markers * sizeof(struct marker)); assert(nm); markers = nm; } i = scanf("%u\t%u\t%u\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", &(markers[nb_markers].id), &(markers[nb_markers].x), &(markers[nb_markers].y), &(markers[nb_markers].dot.left), &(markers[nb_markers].dot.right), &(markers[nb_markers].dot.top), &(markers[nb_markers].dot.bottom), &(markers[nb_markers].dot.width), &(markers[nb_markers].dot.height), &(markers[nb_markers].txt.left), &(markers[nb_markers].txt.right), &(markers[nb_markers].txt.top), &(markers[nb_markers].txt.bottom), &(markers[nb_markers].txt.width), &(markers[nb_markers].txt.height)); if (i == -1) continue; if (i != 15) assert(0); #ifdef DEBUG markers[nb_markers].orig_txt_x = markers[nb_markers].txt.left; markers[nb_markers].orig_txt_y = markers[nb_markers].txt.bottom; #endif } correctOverlap(); /* Now write the resulting data to stdout */ for (i = 0; i < nb_markers; i++) { printf("%u\t%+d\t%+d\n", markers[i].id, markers[i].txt.left, markers[i].txt.bottom); #if DEBUG fprintf(stderr, "label %d moved %+d %+d (alignment %d)\n", i, markers[i].orig_txt_x - markers[i].txt.left, markers[i].orig_txt_y - markers[i].txt.bottom, markers[i].alignment); #endif } return 0; /* give back control to perl */ } /* vim:sw=4:et */ ircmarkers/TODO0000664000000000000000000000067512220600136010600 0ustar 14:39 Myon: ich hab ne alternative berechnung für overlap.c 14:39 overlapX = abs(min(one["right"], two["right"]) - max(one["left"], two["left"])) 14:39 overlapY = abs(max(one["bottom"], two["bottom"]) - min(one["top"], two["top"])) 14:40 Myon: top/bottom wird von unten gezählt, left/right von links * adapt pisg's addalias.pl * view_* in pixels * coordinates wraparound (i.e. not necessary to replace -20 by 340) ircmarkers/IrcMarkers/0000775000000000000000000000000012220600136012142 5ustar ircmarkers/IrcMarkers/Map.pm0000664000000000000000000003223412220600136013221 0ustar # Copyright (C) 2004-2008 Christoph Berg # # This file originated from the mapmarkers distribution: # # MapMarkers, perl modules to create maps with markers. # Copyright (C) 2002-2003 Guillaume Leclanche (Mo-Ize) # # 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. package IrcMarkers::Map; use strict; use warnings; use GD; use IPC::Open2; # Some file-global vars my $pi = 3.1415926535898; my $degtorad = 0.017453292519943; my $radtodeg = 57.295779513082; # create 24bit images GD::Image->trueColor(1); # Class method, creates a new map sub new { my($class, $config) = @_; # open input map my $file = $config->{read} || die "no file to read from"; $file =~ /\.([^.]+)$/; my $type = lc $1; die "File not found: $file" unless -f $file; if ($type eq "gd" or $type eq "gd1") { $config->{IMAGE} = GD::Image->newFromGd($file); } elsif ($type eq "gd2") { $config->{IMAGE} = GD::Image->newFromGd2($file); } elsif ($type eq "gif") { $config->{IMAGE} = GD::Image->newFromGif($file); } elsif ($type eq "jpg" or $type eq "jpeg") { $config->{IMAGE} = GD::Image->newFromJpeg($file); } elsif ($type eq "png") { $config->{IMAGE} = GD::Image->newFromPng($file); } elsif ($type eq "xbm") { $config->{IMAGE} = GD::Image->newFromXbm($file); } elsif ($type eq "xpm") { $config->{IMAGE} = GD::Image->newFromXpm($file); } else { die "Unsupported input image format $type"; } die "Error while reading $file: $!" unless $config->{IMAGE}; # we *should* have undef here on error, but apparently haven't?! # Let's get pixel width and height of the map ($config->{w}, $config->{h}) = $config->{IMAGE}->getBounds(); # check coordinates die "western latitude greater than eastern" if $config->{west} >= $config->{east}; die "latitude range greater than 360 degrees" if $config->{east} - $config->{west} > 360; die "southern longitude greater than northern" if $config->{south} >= $config->{north}; die "longitude range greater than 180 degrees" if $config->{north} - $config->{south} > 180; # handle view_* if ($config->{view_west} or $config->{view_south} or $config->{view_width} or $config->{view_height}) { $config->{view_west} = $config->{west} unless defined $config->{view_west}; $config->{view_east} = $config->{east} unless defined $config->{view_east}; $config->{view_north} = $config->{north} unless defined $config->{view_north}; $config->{view_south} = $config->{south} unless defined $config->{view_south}; die "view_west is outside of map" if $config->{view_west} < $config->{west}; die "view_east is outside of map" if $config->{view_east} > $config->{east}; die "view_south is outside of map" if $config->{view_south} < $config->{south}; die "view_north is outside of map" if $config->{view_north} > $config->{north}; my $w = $config->{w} * ($config->{view_east} - $config->{view_west}) / ($config->{east} - $config->{west}); my $h = $config->{h} * ($config->{view_north} - $config->{view_south}) / ($config->{north} - $config->{south}); if($config->{view_width}) { # scale image if($config->{view_height}) { # don't keep aspect ratio if user requests otherwise ($w, $h) = ($config->{view_width}, $config->{view_height}); } else { ($w, $h) = ($config->{view_width}, $h * ($config->{view_width} / $w)); } } else { if($config->{view_height}) { ($w, $h) = ($w * ($config->{view_height} / $h), $config->{view_height}); } } my $image = new GD::Image($w, $h); $image->copyResampled($config->{IMAGE}, 0, 0, ($config->{view_west} - $config->{west}) / ($config->{east} - $config->{west}) * $config->{w}, ($config->{view_north} - $config->{north}) / ($config->{south} - $config->{north}) * $config->{h}, $w, $h, $config->{w} * ($config->{view_east} - $config->{view_west}) / ($config->{east} - $config->{west}), $config->{h} * ($config->{view_north} - $config->{view_south}) / ($config->{north} - $config->{south}) ); ($config->{west}, $config->{east}, $config->{south}, $config->{north}) = ($config->{view_west}, $config->{view_east}, $config->{view_south}, $config->{view_north}); undef $config->{IMAGE}; # free old image $config->{IMAGE} = $image; ($config->{w}, $config->{h}) = $config->{IMAGE}->getBounds(); } # handle projection system if ($config->{projection} eq 'mercator') { # degree per pixel RESolution $config->{xres} = ($config->{east} - $config->{west}) / $config->{w}; $config->{yres} = ($config->{north} - $config->{south}) / $config->{h}; } elsif ($config->{projection} eq 'sinusoidal') { die "center_lon must be defined for sinusoidal maps" unless defined $config->{center_lon}; # These 2 are not in pixels, but in absolute coordinates. To get pixels, they should be multiplied by $xres. $config->{Xleft} = ($config->{west} - $config->{center_lon}) * cos($config->{north} * $degtorad); $config->{Xright} = ($config->{east} - $config->{center_lon}) * cos($config->{south} * $degtorad); # number of unitary graduation / pixel for x (RESolution) $config->{xres} = ($config->{Xright} - $config->{Xleft}) / $config->{w}; # number of degrees / pixel for y $config->{yres} = ($config->{north} - $config->{south}) / $config->{h}; } else { die("ERROR: $config->{projection}: This projection system is not supported yet."); } $config->{LABELS} = []; bless $config, $class; } sub coord2pixel { my $config = shift; my ($lat, $lon) = @_; my($x, $y, $X0); my $vis = 1; if ($config->{projection} eq 'mercator') { # pixel values, sprintf rounds to nearest $x = sprintf("%d", ($lon - $config->{west}) / $config->{xres}); $y = sprintf("%d", ($config->{north} - $lat) / $config->{yres}); $vis = 0 if ($lon > $config->{east} or $lon < $config->{west} or $lat > $config->{north} or $lat < $config->{south}); } elsif ($config->{projection} eq 'sinusoidal') { # absolute X $X0 = ($lon - $config->{center_lon}) * cos($lat * $degtorad); # pixel values $x = sprintf("%d", ($X0 - $config->{Xleft}) / $config->{xres}); $y = sprintf("%d", ($config->{north} - $lat) / $config->{yres}); $vis = 0 if ($X0 < $config->{Xleft} or $X0 > $config->{Xright} or $lat > $config->{north} or $lat < $config->{south}); } return ($x, $y, $vis); } sub labelsize { my $config = shift; my $label = shift; # Calculate the label bounds needed later by the overlap corrector my @tmp = GD::Image->stringFT($config->{IMAGE}->colorResolve(0, 0, 0), $label->{font}, $label->{ptsize}, 0, 0, 0, $label->{text}); #$label->{labelx}, $label->{labely}, $label->{text}); $label->{LABEL_BOUNDS} = \@tmp; } sub compute_overlap { my($config) = @_; # We execute the program in order to be able to read its output # 3 is the offset: space between dot and text my $command = sprintf "$config->{overlap} $config->{w} $config->{h} 3"; my $pid = open2(\*R, \*W, $command) or die "open2: $!"; for(my $m = 0; $m < @{$config->{markers}}; $m++) { my $marker = $config->{markers}->[$m]; next unless $marker->{visible}; next if $marker->{text} eq ""; my $ref = $marker->{LABEL_BOUNDS} or die; # TODO: use real bounds here printf W ("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $m, $marker->{x}, $marker->{y}, $marker->{x} - $marker->{dot_size}, $marker->{x} + $marker->{dot_size}, $marker->{y} - $marker->{dot_size}, $marker->{y} + $marker->{dot_size}, 2 * $marker->{dot_size}, 2 * $marker->{dot_size}, $marker->{x} + $ref->[0], # left x $marker->{x} + $ref->[2], # right x $marker->{y} + $ref->[5], # upper y $marker->{y} + $ref->[1], # lower y $ref->[2] - $ref->[0], # width $ref->[1] - $ref->[5] # height ); } close(W); # Analyse the output while () { /(\d+)\t([+-]\d+)\t([+-]\d+)/ or warn "unknown overlap output: $_"; $config->{markers}->[$1]->{labelx} = $2; $config->{markers}->[$1]->{labely} = $3; } close(R); } sub draw_label_new { my ($config, $item, $geom_args) = @_; my ($x, $y, $text) = ( $item->{labelx}, # label upper left abscissa $item->{labely}, # label upper ordinate $item->{text} ); my $image = $config->{IMAGE}; my $font = $item->{font} || $config->{font}; my $fontsize = $item->{ptsize} || $config->{ptsize}; if($geom_args) { $item->{labelx} = $x = $x =~ /^-/ ? $config->{w} + $x - $item->{LABEL_BOUNDS}->[2] : $x; $item->{labely} = $y = $y =~ /^-/ ? $config->{h} + $y : $y - $item->{LABEL_BOUNDS}->[5]; } my $b = $item->{label_border} ? $item->{label_border} : $config->{label_border}; if (ref $b) { # might be -1 my $bordercolor = $image->colorResolve(@$b); $image->stringFT($bordercolor, $font, $fontsize, 0, $x+1, $y+1, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x-1, $y-1, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x+1, $y-1, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x-1, $y+1, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x+1, $y, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x-1, $y, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x, $y-1, $text); $image->stringFT($bordercolor, $font, $fontsize, 0, $x, $y+1, $text); } # And finally draw the text in the middle my $fontcolor = $image->colorResolve(@{$item->{label_color} || $config->{label_color}}); my @bounds = $image->stringFT($fontcolor, $font, $fontsize, 0, $x, $y, $text); $item->{LABEL_BOUNDS} = \@bounds; # save bounds for imagemap } sub draw_dot_new { my($config, $marker) = @_; my ($x, $y, $image) = ($marker->{x}, $marker->{y}, $config->{IMAGE}); my $dotcolour = $image->colorResolve(@{$marker->{dot_color}}); my $dotborder = (ref $marker->{dot_border} ? $image->colorResolve(@{$marker->{dot_border}}) : undef); if ($marker->{dot_shape} eq 'dot') { # core of the dot # draw concentric circles until the requested radius is reached for (my $rayon = 0; $rayon <= $marker->{dot_size}; $rayon++) { $image->arc($x, $y, $rayon, $rayon, 0, 360, $dotcolour); } $image->arc($x,$y, $marker->{dot_size}+1, $marker->{dot_size}+1, 0, 360, $dotborder) if defined $dotborder; } else { # circle $image->arc($x,$y, $marker->{dot_size}+1, $marker->{dot_size}+1, 0, 360, $dotborder) if defined $dotborder; $image->arc($x,$y, $marker->{dot_size}, $marker->{dot_size}, 0, 360, $dotcolour); $image->arc($x,$y, $marker->{dot_size}+1, $marker->{dot_size}+1, 0, 360, $dotborder) if defined $dotborder; } } sub set_line_style { my $config = shift; for(my $i = 25; $i >= 0; $i--) { push @{$config->{line_style}}, $config->{IMAGE}->colorResolve(10*$i, 10*$i, 10*$i); } $config->{IMAGE}->setStyle(@{$config->{line_style}}); } sub draw_line_new { my ($config, $item) = @_; my $image = $config->{IMAGE}; my $color = $image->colorResolve(@{$item->{link_color} || $config->{link_color}}); $image->line($item->{xs}, $item->{ys}, $item->{xd}, $item->{yd}, $color); #$image->line($item->{xs}, $item->{ys}, $item->{xd}, $item->{yd}, gdStyled); } sub write { my($config, $file) = @_; my $image = $config->{IMAGE}; $file =~ /\.([^.]+)$/; my $format = lc $1; my $data; if ($format eq "gd" or $format eq "gd1") { $data = $image->gd; } elsif ($format eq "gd2") { $data = $image->gd2; } elsif ($format eq "gif") { $data = $image->gif; } elsif ($format eq "jpg" or $format eq "jpeg") { $data = $image->jpeg; } elsif ($format eq "png") { $data = $image->png; } elsif ($format eq "wbmp") { $data = $image->wbmp; } else { die "Unsupported output image format $format"; } open (SVG, ">$file") or die "$file: $!"; binmode SVG; print SVG $data; close SVG; } sub compute_boundingbox { # compute bounding box my $config = shift; my $item = shift; warn "box?" unless my $ref = $item->{LABEL_BOUNDS}; #$y = $config->{h} + $y if $y < 0; #$x = $config->{w} + $x if $x < 0; $config->{min_x} = $ref->[0] if not defined $config->{min_x} or $ref->[0] < $config->{min_x}; $config->{max_x} = $ref->[2] if not defined $config->{max_x} or $ref->[2] > $config->{max_x}; $config->{min_y} = $ref->[5] if not defined $config->{min_y} or $ref->[5] < $config->{min_y}; $config->{max_y} = $ref->[1] if not defined $config->{max_y} or $ref->[1] > $config->{max_y}; } sub write_imagemap { my $config = shift; open MAP, ">$config->{imagemap}" or die "$config->{imagemap}: $!"; my $mapname = $config->{write}; $mapname =~ /([^\/]+)\.[^\/.]+$/; # get basename $mapname = $1 if $1; print MAP "\n"; foreach my $marker (@{$config->{markers}}, @{$config->{yxlabels}}) { next unless $marker->{href} and $marker->{LABEL_BOUNDS}; my $ref = $marker->{LABEL_BOUNDS}; printf MAP "\"%s\"\n", $ref->[6], # left x $ref->[7], # upper y $ref->[2], # right x $ref->[3], # lower y $marker->{href}, $marker->{text}; } print MAP "\n"; close MAP; } # transitional stub sub get_gpg_links { IrcMarkers::File::get_gpg_links(@_); } 1; ircmarkers/IrcMarkers/File.pm0000664000000000000000000002661312220600136013367 0ustar # Copyright (C) 2004-2008 Christoph Berg # # 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. package IrcMarkers::File; use strict; use warnings; use IO::File; sub despace { my $s = shift; $s =~ s/\s+/ /g; return $s; } sub parse_coord { $_ = shift; s/^[NE+]\s*//; s/^[SW-]\s*/-/; s/[°'"]+/ /g; # noise s/,/./g; s/(\d+) +([\d.]+)/$1 + $2 \/ 60.0/e; s/([\d.]+) +([\d.]+)/$1 + $2 \/ 3600.0/e; return $_; } sub new { my $config = { # default values projection => 'mercator', west => -180, north => 90, east => 180, south => -90, #center_lon => 0, dot_color => [255, 255, 255], dot_border => [0, 0, 0], dot_size => 2, dot_shape => 'dot', label_color => [255, 255, 0], label_border => [0, 0, 0], link_outside => 0, link_color => [255, 128, 0], #sign1_color => [100, 100, 100], link_style => 'solid', font => '/usr/share/ircmarkers/fixed_01.ttf', ptsize => 6, quiet => 0, overlap => '/usr/lib/ircmarkers/overlap', overlap_correction => 1, help_convert_crop => 0, }; bless $config; } sub default_options { # this will be obsolete if all items are deOOified my $config = shift; my $item = shift; $item->{dot_color} ||= $config->{dot_color}; $item->{dot_border} ||= $config->{dot_border}; $item->{dot_size} ||= $config->{dot_size}; $item->{dot_shape} ||= $config->{dot_shape}; $item->{label_color} ||= $config->{label_color}; $item->{label_border} ||= $config->{label_border}; $item->{font} ||= $config->{font}; $item->{ptsize} ||= $config->{ptsize}; $item->{link_color} ||= $config->{link_color}; # only for links } sub parser_warn { my $config = shift; my $text = shift; my $loc = $config->{file} ? "$config->{file}:$." : "-o"; warn "$loc: $text\n"; } sub parse_options { my $config = shift; my $item = shift; die "huh?" unless ref $item; my $markernr = shift; # defined for markers, undef for yxlabels/links my $opt = shift; while($opt ne '') { # loop over options $opt =~ s/^\s+|#.*//g; last unless $opt ne ''; if(defined $markernr and $opt =~ s/^gpg[ :](?:0x)?([0-9a-f]{16})//i) { # ':' is deprecated old syntax my $k = uc $1; if($config->{gpg}->{$k} and $config->{gpg}->{$k} ne $markernr) { warn "$config->{file}.$.: key $k already associated with $config->{gpg}->{$k}, overwriting with $markernr\n"; } $config->{gpg}->{$k} = $markernr; $config->{gpg_not_found}->{$k} = $markernr; # local options } elsif($opt =~ s/^dot_colou?r (\d+) (\d+) (\d+)//) { $item->{dot_color} = [$1, $2, $3]; } elsif($opt =~ s/^dot_border (no(ne)?|off)//) { $item->{dot_border} = -1; } elsif($opt =~ s/^dot_border (\d+) (\d+) (\d+)//) { $item->{dot_border} = [$1, $2, $3]; } elsif($opt =~ s/^dot_size (\d+)//) { $item->{dot_size} = $1; } elsif($opt =~ s/^dot_shape (dot|circle)//) { $item->{dot_shape} = $1; } elsif($opt =~ s/^label_colou?r (\d+) (\d+) (\d+)//) { $item->{label_color} = [$1, $2, $3]; } elsif($opt =~ s/^label_border (no(ne)?|off)//) { $item->{label_border} = -1; } elsif($opt =~ s/^label_border (\d+) (\d+) (\d+)//) { $item->{label_border} = [$1, $2, $3]; } elsif($opt =~ s/^font (\S+)//) { die "font file not found: $1" unless -f $1; $item->{font} = $1; $item->{font} =~ s!^~/!$ENV{HOME}/!; } elsif($opt =~ s/^(?:font|pt)size (\d+)//) { $item->{ptsize} = $1; } elsif($opt =~ s/^(?:link|sign2)_colou?r (\d+) (\d+) (\d+)//) { $item->{link_color} = [$1, $2, $3]; } elsif($opt =~ s/^(?:link|sign2)_colou?r (no(ne?)|off)//) { delete $item->{link_color}; # (mostly) pisg options } elsif($opt =~ s/^alias "(.*?)"//) { $item->{alias} = $item->{alias} ? "$item->{alias} $1" : $1; } elsif($opt =~ s/^alias (\S+)//) { $item->{alias} = $item->{alias} ? "$item->{alias} $1" : $1; } elsif($opt =~ s/^(href|(?:big)?pic|sex) ("?)(\S+)\2//) { $item->{$1} = $3; # error } else { $config->parser_warn("unknown option: $opt"); last; } } } my $markernr = 0; my $labelnr = 0; my $linknr = 0; sub parse { my $config = shift; $_ = shift; s/^\s+//; if(/^#include [<"](.+)[">]/) { # include next config file $config->read($1); return; } return if /^(#|$)/; s/^([^"]+)/despace($1)/e; # compress space outside of quotes s/([^"]+)$/despace($1)/e; # global options if(/^read (.+)/) { $config->{read} = $1; $config->{read} =~ s!^~/!$ENV{HOME}/!; } elsif(/^write (.+)/) { $config->{write} = $1; $config->{write} =~ s!^~/!$ENV{HOME}/!; } elsif(/^(lon|west_east) (.+)\/(.+)/) { $config->{west} = $2; $config->{east} = $3; } elsif(/^(lat|south_north) (.+)\/(.+)/) { $config->{south} = $2; $config->{north} = $3; } elsif(/^view_(lon|west_east) (.+)\/(.+)/) { $config->{view_west} = $2; $config->{view_east} = $3; } elsif(/^view_(lat|south_north) (.+)\/(.+)/) { $config->{view_south} = $2; $config->{view_north} = $3; } elsif(/^view_width (.+)/) { $config->{view_width} = $1; } elsif(/^view_height (.+)/) { $config->{view_height} = $1; } elsif(/^projection (mercator|sinusoidal)/) { $config->{projection} = $1; } elsif(/^center_lon (.+)/) { $config->{center_lon} = $1; } elsif(/^link_outside (on|yes)/) { $config->{link_outside} = 1; } elsif(/^link_outside (off|no)/) { $config->{link_outside} = 0; } elsif(/^sign1_colou?r (no(ne)?|off)$/) { delete $config->{sign1_color}; } elsif(/^sign1_colou?r (\d+) (\d+) (\d+)$/) { $config->{sign1_color} = [$1, $2, $3]; } elsif(/^imagemap (\S+)/) { $config->{imagemap} = $1; } elsif(/^overlap (.+)/) { $config->{overlap} = $1; } elsif(/^overlap_correction (on|yes)/) { $config->{overlap_correction} = 1; } elsif(/^overlap_correction (off|no)/) { $config->{overlap_correction} = 0; } elsif(/^pisg/) { $config->{pisg} = 1; } elsif(/^recv(?:-keys)/) { $config->{recv} = 1; } elsif(/^quiet (on|yes)/) { $config->{quiet} = 1; } elsif(/^quiet (off|no)/) { $config->{quiet} = 0; # link } elsif(/"([^"]*)"\s+\s+"([^"]+)"(.*)/) { # -> is old syntax my ($src, $dst, $opt) = ($1, $2, $3); my $srcnr = $config->{markerindex}->{$src}; my $dstnr = $config->{markerindex}->{$dst}; unless(defined $srcnr and defined $dstnr) { $config->parser_warn("both link endpoints must be defined"); next; } $config->{links}->[$linknr] = { src => $srcnr, dst => $dstnr, arrow => '<->' }; $config->default_options($config->{links}->[$linknr]); $config->parse_options($config->{links}->[$linknr], undef, $opt); $linknr++; # marker definitions } elsif(/^([NS+-]? ?[\d.,°]+) ([EW+-]? ?[\d.,°]+) "([^"]*)"(.*)/ or # N 51° 11.123 E 006° 25.846 /^([NS+-]? ?\d*[° ]+[\d.,]+'?) ([EW+-]? ?\d*[° ]+[\d.,]+'?) "([^"]*)"(.*)/ or # N 51° 34' 11.123 E 006° 29' 25.846 /^([NS+-]? ?\d*[° ]+\d+[' ][\d.,]+"?) ([EW+-]? ?\d*[° ]+\d+[' ][\d.,]+"?) "([^"]*)"(.*)/) { my ($lat, $lon, $text, $opt) = (parse_coord($1), parse_coord($2), $3, $4); my $nr = $config->{markerindex}->{$text}; if(not defined $nr or $config->{markers}->[$nr]->{lat}) { # create new marker when coordinates are already there $nr = $markernr++; } $config->{markers}->[$nr]->{text} = $text; $config->{markers}->[$nr]->{lat} = $lat; $config->{markers}->[$nr]->{lon} = $lon; $config->{markerindex}->{$text} = $nr; $config->default_options($config->{markers}->[$nr]); $config->parse_options($config->{markers}->[$nr], $nr, $opt); } elsif(/^([A-Z]{2}\d{2}[A-Z]{2}) "([^"]*)"(.*)/i) { # Maidenhead locator my ($loc, $text, $opt) = ($1, $2, $3); my ($p1, $p2, $p3, $p4, $p5, $p6) = unpack 'AAAAAA', uc($loc); ($p1, $p2, $p3, $p4, $p5, $p6) = (ord($p1)-ord('A'), ord($p2)-ord('A'), ord($p3)-ord('0'), ord($p4)-ord('0'), ord($p5)-ord('A'), ord($p6)-ord('A') ); my $lat = ($p2*10) + $p4 + (($p6+0.5)/24) - 90; my $lon = ($p1*20) + ($p3*2) + (($p5+0.5)/12) - 180; my $nr = $config->{markerindex}->{$text}; if(not defined $nr or $config->{markers}->[$nr]->{lat}) { # create new marker when coordinates are already there $nr = $markernr++; } $config->{markers}->[$nr]->{text} = $text; $config->{markers}->[$nr]->{lat} = $lat; $config->{markers}->[$nr]->{lon} = $lon; $config->{markerindex}->{$text} = $nr; $config->default_options($config->{markers}->[$nr]); $config->parse_options($config->{markers}->[$nr], $nr, $opt); } elsif(/^"([^"]*)"(.*)/) { # marker with options my ($text, $opt, $i) = ($1, $2); my $nr = $config->{markerindex}->{$text}; if(not defined $nr) { $nr = $markernr++; $config->{markers}->[$nr]->{text} = $text; } $config->default_options($config->{markers}->[$nr]); $config->parse_options($config->{markers}->[$nr], $config->{markerindex}->{$text}, $opt); } elsif(/^label ([+-]?\d+) ([+-]?\d+) "([^"]+)"(.*)/) { $config->{yxlabels}->[$labelnr] = { labely => $1, labelx => $2, text => $3 }; my $opt = $4; $config->default_options($config->{yxlabels}->[$labelnr]); $config->parse_options($config->{yxlabels}->[$labelnr], undef, $opt); $labelnr++; } elsif(/^polygon ([+-]?\d+) ([+-]?\d+) "([^"]+)"(.*)/) { # TODO # everything else is a globally applied local option or a syntax error } else { $config->parse_options($config, undef, $_); } } sub read { my $config = shift; my $file = shift || die "read: no filename"; $file =~ s!^~/!$ENV{HOME}/!; $config->{file} = $file; my $fh = IO::File->new($file) or die "$file: $!"; while (<$fh>) { chomp; $config->parse($_); } close $fh; return $config; } sub get_gpg_links { my $config = shift; my $keys = join ' ', keys %{$config->{gpg}}; if ($config->{recv}) { system "gpg --recv-keys $keys"; } open GPG, "gpg --list-sigs --with-colon --fixed-list-mode --fast-list-mode $keys |" or die "gpg: $!"; my ($key, $src); while() { chomp; next if /^(rev|sub|tru|uat):/; if(/^pub::\d+:\d+:([0-9A-F]+):/) { $key = $1; warn "$key not related to any marker - did you use the long (16 char) keyid?\n" unless defined $config->{gpg}->{$key}; $src = $config->{gpg}->{$key}; delete $config->{gpg_not_found}->{$key}; } elsif(/^sig:::\d+:([0-9A-F]+):/) { next unless defined $config->{gpg}->{$1}; # target not on map next if $key eq $1; # self-sig $config->{gpg_links}->{$config->{gpg}->{$1}}->{$src} = 1; } else { warn "unknown gpg output: $_"; } } foreach my $key (keys %{$config->{gpg_not_found}}) { warn "$config->{gpg_not_found}->{$key}: key $key was not found in gpg's keyring\n"; } foreach my $source (keys %{$config->{gpg_links}}) { next unless $config->{link_outside} or $config->{markers}->[$source]->{visible}; foreach my $target (keys %{$config->{gpg_links}->{$source}}) { next unless $config->{link_outside} or $config->{markers}->[$target]->{visible}; my ($arrow, $color); if($config->{gpg_links}->{$target}->{$source}) { # bidirectional link next if $target gt $source; # process only once $color = $config->{link_color}; $arrow = "<->"; } else { $color = $config->{sign1_color} or next; # don't draw unidirectional links $arrow = "-->"; } next if not defined $config->{markers}->[$source]->{lat}; next if not defined $config->{markers}->[$target]->{lat}; push @{ $config->{links} }, { src => $source, dst => $target, link_color => $color, arrow => $arrow }; } } } 1; ircmarkers/example.map0000664000000000000000000000153112220600136012232 0ustar # example config file for IrcMarkers, process with "ircmarkers example.map" # input/output filename read world.jpg write example.jpg # it's a world map lat -90/90 lon -180/180 # uncomment the following to cut out Germany from the big map #view_lat 44/56 #view_lon 4/20 # ...and resize it #view_width 200 #font /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf #fontsize 8 # we want green labels label_color 0 255 0 # some markers and labels to put on the map 49.2532 7.0425 "Myon" 50.8574 6.4585 "formorer" label 15 5 "#debian.de map" # some PGP keys; uncomment the following lines to put a link on the map. # use "gpg --recv " to fetch the keys from a keyserver #"Myon" gpg B46B923B6D8ABE71 #"formorer" gpg D35BBC99BC7D020A # remove the first '#' from the following line to include another config file ##include "other_coordinates.map" ircmarkers/ircmarkers0000775000000000000000000003717312220600400012175 0ustar #!/usr/bin/perl -w # # Copyright (C) 2003-2008 Christoph Berg # # Part of this file originate from example.pl from the MapMarker distribution: # Author : Guillaume Leclanche (Mo-Ize) # Version : 2.0 beta 1 # Date : 08 Feb 2003 # # See the pod section at the end of this file for copyright details. # 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; my $VERSION = "0.14"; sub VERSION_MESSAGE { print "IrcMarkers $VERSION (C) 2003-2008 Christoph Berg , GNU GPL.\n"; } sub HELP_MESSAGE { VERSION_MESSAGE(); print <new; my ($x, $y); GetOptions( 'x=s' => \$x, 'y=s' => \$y, 'q' => \$config->{quiet}, 'o=s' => sub { $config->parse($_[1]); }, crop => \$config->{help_convert_crop}, help => sub { HELP_MESSAGE(); }, version => sub { VERSION_MESSAGE(); exit(0); }, ) or HELP_MESSAGE(); HELP_MESSAGE() unless $ARGV[0]; $config->read($ARGV[0]); if($config->{pisg}) { foreach my $marker (@{$config->{markers}}) { next unless $marker->{text}; print "{text}\""; print " alias=\"$marker->{alias}\"" if $marker->{alias}; print " link=\"$marker->{href}\"" if $marker->{href}; print " pic=\"$marker->{pic}\"" if $marker->{pic}; print " bigpic=\"$marker->{bigpic}\"" if $marker->{bigpic}; print " sex=\"$marker->{sex}\"" if $marker->{sex}; print ">\n"; } exit 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}; ## Print a correct 'convert -crop' command. More info at convert(1) #if ($config->{help_convert_crop}) { # use Image::Size; # my $type; # ($config->{w}, $config->{h}, $type) = imgsize($config->{read}); # # # fallback # $config->{view_west} = $config->{west} unless defined $config->{view_west}; # $config->{view_east} = $config->{east} unless defined $config->{view_east}; # $config->{view_north} = $config->{north} unless defined $config->{view_north}; # $config->{view_south} = $config->{south} unless defined $config->{view_south}; # # # print the info # printf("\$ convert -crop %dx%d+%d+%d %s new.%s\n", # $config->{w}, # width # $config->{h}, # height # $config->{w} * ($config->{view_east} - $config->{view_west}) / ($config->{east} - $config->{west}), # x # $config->{h} * ($config->{view_north} - $config->{view_south}) / ($config->{north} - $config->{south}), # y # $config->{read}, # src file # lc $type, # file type # ); # # exit; #} my $map = IrcMarkers::Map->new($config); foreach my $marker (@{$config->{markers}}) { next unless $marker->{lat}; ($marker->{x}, $marker->{y}, $marker->{visible}) = $config->coord2pixel($marker->{lat}, $marker->{lon}); next unless $marker->{visible}; if ($marker->{text} ne "") { ($marker->{labelx}, $marker->{labely}) = ($marker->{x} + $marker->{dot_size} + 3, $marker->{y} + $marker->{dot_size}); # TODO: make '3' configurable? print "$marker->{text} at $marker->{lat}, $marker->{lon} ($marker->{y}, $marker->{x})\n" unless $config->{quiet}; } else { print "$marker->{lat}, $marker->{lon} ($marker->{y}, $marker->{x})\n" unless $config->{quiet}; } } if($config->{link_color} and $config->{gpg}) { $config->get_gpg_links(); } $config->set_line_style(); if($config->{links}) { foreach my $link (@{$config->{links}}) { my $src = $config->{markers}->[$link->{src}]; my $dst = $config->{markers}->[$link->{dst}]; print "$src->{text} $link->{arrow} $dst->{text}\n" unless $config->{quiet}; if ($src->{lon} > $dst->{lon}) { ($src, $dst) = ($dst, $src); } ($link->{xs}, $link->{ys}) = ($src->{x}, $src->{y}); ($link->{xd}, $link->{yd}) = ($dst->{x}, $dst->{y}); if ($src->{lon} - $dst->{lon} < -180) { # cross-Pacific links ($link->{xd}) = $config->coord2pixel($dst->{lat}, $dst->{lon}-360); $config->draw_line_new($link); ($link->{xs}) = $config->coord2pixel($src->{lat}, $src->{lon}+360); $link->{xd} = $dst->{x}; } $config->draw_line_new($link); } } if($config->{markers}) { my $visible; foreach my $marker (@{$config->{markers}}) { next unless $marker->{visible}; $visible = 1; $config->labelsize($marker); $map->draw_dot_new($marker); } print "warning: all markers are outside the visible area\n" unless $visible or $config->{quiet}; $map->compute_overlap() if($config->{overlap_correction}); foreach my $marker (@{$config->{markers}}) { next unless $marker->{visible}; next if $marker->{text} eq ""; $map->draw_label_new($marker); $config->compute_boundingbox($marker); } } if($config->{yxlabels}) { foreach my $label (@{$config->{yxlabels}}) { print "label \"$label->{text}\" at $label->{labely}, $label->{labelx}\n" unless $config->{quiet}; $config->labelsize($label); $map->draw_label_new($label, 1); $config->compute_boundingbox($label); } } $map->write($config->{write}); if($config->{imagemap}) { $map->write_imagemap(); } if(not $config->{quiet} and defined $config->{min_x}) { $config->{max_y} = $config->{h} if $config->{max_y} > $config->{h}; $config->{max_x} = $config->{w} if $config->{max_x} > $config->{w}; print "Area used by markers is: ". "y: $config->{min_y}..$config->{max_y} ". "x: $config->{min_x}..$config->{max_x}\n"; } __END__ =encoding utf8 =head1 NAME B - place markers on maps at given coordinates =head1 SYNOPSIS B [-q] [-o command] [-y I -x I] F [F F] =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 file to read markers and options from. This parameter is mandatory. =item F Read input map from F. Supported formats are .gif, .jpg/jpeg, .png, .xbm, .xpm, and the libgd-Formats .gd/gd1 and .gd2. =item F Write output map to F. 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 =item -x I 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 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 I "I" =item I I "I" I =item I "I" I =item "I" I Place marker with label I on map at given coordinates. Use negative values for south/east, positive for north/west. This (decimal) format is compatible with the xplanet syntax. 49.2532 7.0425 "Myon" Alternative formats recognized are: N51°11.123 E006°25.846 N 51 11.123 E 006 25.846 N 51° 11' 7.38" E 006° 25' 50.76" The noise characters °'" are optional. Also recognized are Maidenhead (QTH) locators. JN39PF "Myon" =item label I I "I" =item label I I "I" I Place a label at position I/I (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 Associate GnuPG/PGP I 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 This is the long, 16 character keyid. To retrieve it, use C. =item label_color I =item label_border I|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 Full pathname to the .ttf font used for the labels. Default is font F. =item fontsize|ptsize I Size in points of the labels. Default is fontsize 6. =item dot_color I =item dot_border I|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 of the dots. Default is 2. =item dot_shape dot|circle Dots are filled (dot) or hollow (circle). Default is dot. =item href I Link target to use in an imagemap. =item alias|pic|bigpic|sex I Options for export to pisg(1), see the B option below. =back =head2 Link Definition and Options =over =item "I" <-> "I" =item "I" <-> "I" I Draw a link between I and I. =item link_color|sign2_color I|none Color of the lines drawn between the markers. Default is link_color 255 128 0. =back =head2 Global Options =over =item read F Read input map from F. Supported formats are .jpg and .png. =item write F Write output map to F. Supported formats are .jpg, .png, .gd1, .gd2, and .wbmp. =item lat|south_north I =item lon|west_east I Declare input map dimensions. Default is lat -90/90, lon -180/180. B 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 =item view_lon|view_west_east I Only show part of the map in the output. Default is to show the whole map. =item view_width I =item view_height I Size of output map. Default is input map, or size of part selected. =item projection mercator|sinusoidal =item center_lon I
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|none Color of the lines drawn for uni-directional GnuPG/PGP signatures. Default is link_color none. =item imagemap F Write HTML image map to F. The map contains areas for all markers and labels with a href option. The name of the imagemap is the basename of the output map with the extension stripped. =item overlap F Full pathname to the binary that moves the labels around to reduce overlap. Default is overlapcorrector F. 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 pisg Instead of writing a map, print a config file suitable for pisg(1), most useful with B I. The exported marker options are B, B, B, B, and B (the latter as B). =item recv-keys Call gpg --recv-keys (most useful with B). =item quiet on|off Be quiet. Default is quiet off. =item #include "F" Read auxillary config file. =item # comment Anything else starting with a # character is a comment. =back =head1 EXAMPLES B 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 N 51° 11.123 E 006° 25.846 "GC1ACE3" #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 or IrcMarkers view_* functions. Please report bugs in IrcMarkers using the Debian bug tracking system. The IrcMarkers bug page is at B. =head1 SEE ALSO =head2 Library used =over =item * L - GD version 2 =back =head2 Programs related to IrcMarkers =over =item * MapMarkers: http://www.nul-en.info/mapmarkers/ - IrcMarkers' predecessor =item * xplanet(1): http://xplanet.sourceforge.net/ =item * Image::WorldMap: http://www.astray.com/WorldMap/ =item * pisg(1): http://pisg.sourceforge.net/ =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 . 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. Rico Gloeckner suggested to support Maidenhead locators. The IrcMarkers homepage is at B. =head1 COPYRIGHT AND LICENSE Copyright (C) 2003-2008 Christoph Berg 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; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA IrcMarkers is an improved version of MapMarkers. Copyright (C) 2002, 2003 Guillaume Leclanche (Mo-Ize) 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