Image-Maps-Plot-FromLatLong

 view release on metacpan or  search on metacpan

FromLatLong.pm  view on Meta::CPAN

package Image::Maps::Plot::FromLatLong; # where in the world are London.pm members?

our $VERSION = 0.12;
our $DATE = "Thu 17 November 18:50 2004";
use 5.006;
use strict;
use warnings;
use Image::Magick;
use File::Basename;
use Data::Dumper;


use Config;

=head1 NAME

Image::Maps::Plot::FromLatLong - plots points on Mercator Projection world/regional map

=head1 SYNOPSIS

	use Image::Maps::Plot::FromLatLong;

	# Get ready
	$m = new Image::Maps::Plot::FromLatLong (
		MAP=>"THE WORLD",
		PATH=>"C:/out.html",	# Extension is irrelevant
		FONT=>"C:/winnt/fonts/arial.ttf",
	);

	# Now, Create an HTML page with images:
	$m->create_html;
	# Or just the image
	$m->create_imagefile;
	# Or get a reference to an image blob:
	$m->get_blob;

	# Create HTML pages of all maps in the db, with index
	my $m = new Image::Maps::Plot::FromLatLong(
		FONT=>'c:/winnt/fonts/arial.ttf',
	);
	$m->all("C:/");

	# Add a map
	$Image::Maps::Plot::FromLatLong::MAPS{"LONDON AREA"} = {
		FILE =>	'C:\PhotoWebServer\Perl\site\lib\Image\Maps\Plot\london_bourghs.jpg',
		DIM	 => [650,640],
		SPOTSIZE => 5,
		ANCHOR_PIXELS => [447,397],		# Greenwich on the pixel map
		ANCHOR_LATLON => [51.466,0],	# Greenwich lat/lon
		ANCHOR_NAME	  => 'Greenwich',
		ANCHOR_PLACE  => 'Observatory',
		ONEMILE		=> 19.5,			# 1 km = .6 miles  (10km=180px = 10miles=108px)
	};


	# Add a user to the db
	$m->load_db (".earth.dat");
	$m->add_entry ('Ike Elben Goddard','Hungary','H-1165');
	$m->save_db (".aliyah.dat");

	# Create map content on the fly:
	$maker = new Image::Maps::Plot::FromLatLong(
		MAP	=> "THE WORLD",
		FONT=>'c:/winnt/fonts/arial.ttf',
		PATH	=> "/Two.foo",
		DBFILE	=> undef,
		LOCATIONS => {
		  'Lee' => {

FromLatLong.pm  view on Meta::CPAN

	$self->{PATH} = $path.$name;
	$self->{IMGPATH} = $name.'.jpg';

	# Try to load the image into our object
	die "There is no option for a map of $self->{MAP}" if not exists $MAPS{$self->{MAP}};
	if (not -e $MAPS{$self->{MAP}}->{FILE}){
		warn "No map for $self->{MAP} at $MAPS{$self->{MAP}}->{FILE}: $!" ;
		return undef;
	}

	$self->_load_map or die "Could not read map from $MAPS{$self->{MAP}}->{FILE}: $!";

	$self->_populate;
	return $self->_save;
}




=head1 METHOD create_blob

Creates an image and return a reference to it's BLOB.

Requires that the C<PATH> field be set (see L<CONSTRUCTOR>).

=cut

sub create_blob { my $self=shift;
	if ($self->{PATH}){
		my ($name,$path,$suffix) = fileparse($self->{PATH},'(\.[^.]*)?$' );
		$self->{PATH} = $path.$name;
		$self->{IMGPATH} = $name.'.jpg';
	}

	# Try to load the image into our object
	if (not exists $MAPS{$self->{MAP}}){
		warn "There is no option for a map of $self->{MAP}";
		return undef;
	}
	if (not -e $MAPS{$self->{MAP}}->{FILE}){
		warn "No map for $self->{MAP}: $!" ;
		return undef;
	}
	if (not $self->_load_map){
		warn "Could not read map from $MAPS{$self->{MAP}}->{FILE}: $!";
		return undef;
	}

	$self->_populate;
	return \$self->{IM}->ImageToBlob();
}




#
# Just loads the map specified in the FILE field of MAP array
# field specified by the calling object's MAP field.
#
sub _load_map { my $self=shift;
	$self->{IM} = Image::Magick->new;
	my $err = $self->{IM}->Read($MAPS{$self->{MAP}}->{FILE});
	warn "Load map error: $err ($!)" if $err;
	return $err? undef:1;
}


=head1 METHOD all (base_path,base_url,title, blurb)

A method that produces all available maps, and an index page with thumbnails.

It accepts four arguments, a path at which files can be built,
a filename prefix (see L<"new">), a title, and blurb to add beneath the list of hyperlinks to the maps.

If no base path is supplied, the C<PATH> field is used.

An index page will be produced, linking to the following files for each map:

=over 4

m_C<MAPNAME>.jpg
m_C<MAPNAME>_t.jpg
m_C<MAPNAME>.html

=back

where MAPNAME is ... the name of the map.  The C<m_> prefix is held in the instance variable C<FNPREFIX>.
You may also wish to look at and adjust the instance variable C<CREATIONTXT>.

=cut

sub all { my ($caller, $fpath,$fnprefix,$title,$blurb) = (@_);
	die "'all' is now a method!" if not ref $caller;
	$fpath = $caller->{PATH} unless $fpath;
	die "Please supply a PATH directory (first argument)" if not defined $fpath;
	die "No such directory as suppiled: $fpath" unless -d $fpath;
	if ($fpath !~ /(\/|\\)$/){$fpath.="/";}
	$fnprefix = '' if not defined $fnprefix;
	if (not defined $title) {
		$title = "London.pm";
	}
	if (not defined $blurb) {
		$blurb =
		"These maps were created on ".(scalar localtime)." by ".__PACKAGE__;
		$blurb .=", available on <A href='http://search.cpan.org'>CPAN</A>, from data last updated on $DATE."
		."<P>Maps originate either from the CIA (who placed them in the public domain), or unknown sources (defunct personal pages on the web)."."<BR><HR><P><SMALL>Copyright (C) <A href='mailto:lGoddard\@CPAN.Org'>Lee Goddard</A> 2001 - available under the...
	};
	my $self = bless {};
	$self->{HTML} = '';
	$self->_add_html_top("$title Maps Index");
	$self->{HTML} .= "<H1>$title Maps<HR></H1>\n";

	foreach my $map (keys %MAPS){
		$map =~ /(\w+)$/;
		die "Error making filename: didn't match regex" if not defined $1;
		$_ = __PACKAGE__;
		my $mapmaker = new (__PACKAGE__,{
			MAP=>$map,
			PATH=>$fpath.$fnprefix.$1,
			FONT=>$caller->{FONT},
			THUMB_SIZE => $caller->{THUMB_SIZE},

FromLatLong.pm  view on Meta::CPAN

	die "Passed bad filepath to create_thumbnail <$path>: $!" if not defined $path or not -e $path;
	$size = $self->{THUMB_SIZE} if not defined $size;
	$size = 75 if not defined $size;

	# Create the thumbnail from it, where the biggest side is 50 px
	my $outpath = $path;
	$outpath =~ s/\.jpg$/_t.jpg/;
	my $thumb = Image::Thumbnail->new(
		inputpath => $path,
		size => $size,
		outputpath => $outpath,
		CHAT => $self->{chat},
		create => 1,
	);
	return ($thumb->{x},$thumb->{y});
}


#
# Make @LAT and @LON to get length of a degree
#
sub _make_latlon {
	LAT:{
		my $i = 0;
		foreach (@_LAT){
			for my $j (0..4){
				last LAT if $i+$j>90;
				$LAT[$i+$j] = $_;
			}
			$i += 5;
		}
	}

	LON:{
		my $i = 0;
		foreach (@_LON){
			for my $j (0..4){
				last LON if $i+$j>90;
				$LON[$i+$j] = $_;
			}
			$i += 5;
		}
	}
}

=head1 ADDING MAPS

A future version may allow you to pass map data to the constructor.
In the meantime, adding maps is not in itself a big deal, perl-wise. Add a new key to
the C<%MAPS> hash, with the value of an anonymous hash with the content listed below.

=over 4

=item FILE

scalar file name of Mercator Projection map.

=item DIM

anon array of dimensions of map in pixels [x,y].
You could create DIM on the fly using C<Image::Magick>, but there's probably no point, as you're
almost certainly going to have to edit the map to align it with longitude and latitude
(if you find a stock of public-domain maps that are already aligned, please drop
the author a line).

=item SPOTSIZE

scalar number for the size of the map-marker spots, in pixels

=item ANCHOR_PIXELS

anon array of the pixel location of the arbitrary anchor pont [x,y]

=item ANCHOR_LATLON

anon array of the latitude/longitude of the arbitrary anchor pont [x,y]

=item ANCHOR_NAME

scalar name of the anchor, when marked on map

=item ANCHOR_PLACE

scalar place name of the anchor, when marked on map

=item ONEMILE

scalar representation of 1 mile in pixels

=back

=head1 NOTES ON LATITUDE AND LONGITUDE

After L<http://www.mapblast.com/myblast/helpFaq.mb#2|http://www.mapblast.com/myblast/helpFaq.mb#2>:

=over 4

Zero degrees latitude is the equator, with the North pole at 90 degrees latitude and the South pole at -90 degrees latitude.
one degree is approximately 69 miles. Greenwich, England is at 51.466 degrees north of the equator.

Zero degrees longitude goes through Greenwich, England.
Again, Each 69 miles from this meridian represents approximately 1 degree of longitude.
East/West is plus/minus respectively.

=back

Actually, latitude and longitude vary depending upon the degree in hand:
see L<The Compton Encyclopdedia|http://www.comptons.com/encyclopedia/ARTICLES/0100/01054720_A.html#P17> for more information.

=head1 CAVEATS

The exmaple map, london_postcodes.jpg, is inaccurate.

Whilst degrees of latitude are accurate to two decimal places, Degrees of
longitude are taken to be 69 miles: this isn't quite right - see
L<NOTES ON LATITUDE AND LONGITUDE>. This will be adjusted in a later version.

All images must be JPEGs - PNG or other support could easily be added.

=head1 REVSIONS

=over 4

=item 1.2

Corrected a slight mis-positioning of points.

Replaced GD with Image::Magick as I was seeing terrible JPEG output
with GD.

Replaced support for non-maintained C<Image::GD::Thumbnail> with
C<Image::Thumbnail>; evaluate a require of this at run time rather
than using the apparently still shakey pragmas.

Added methods to create just images and to return references to image blobs.

=item 1.0

Don't remember.

=item 0.25

Clean IMG path and double-header bugs

=item 0.23

Added more documentation; escaping of href text

=item 0.22

Added thumbnail images to index page

=back

=head1 SEE ALSO

perl(1); L<Image::Magick|http://www.ImageMagick.org> (C<http://www.ImageMagick.org>); L<File::Basename>; L<Acme::Pony>; L<Data::Dumper>; L<WWW::MapBlast>; L<Image::Thumbnail>

=head1 THANKS

Thanks to the London.pm group for their test data and insipration, to Leon for his patience with all that mess on the list, to Philip Newton for his frankly amazing knowledge of international postcodes.

Thanks also to the CIA, L<About.com|http://wwww.about.com>, L<The University of Texas|http://www.lib.utexas.edu/maps>,
and L<The Ordnance Survey|http://www.ordsvy.gov.uk/freegb/index.htm#maps>
for their public-domain maps.

=head1 AUTHOR

Lee Goddard <lgoddard -at- cpan -point- org>

=head1 COPYRIGHT

Copyright (C) Lee Goddard, 2001.  All Rights Reserved.

This module is supplied and may be used under the same terms as Perl itself.

The public domain maps provided with this distribution are the property of their respective copyright holders.

=cut

1;

__END__

matlab:

axesm('mapprojection','mercator'); displaym( worldhi(mask));



( run in 0.604 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )