⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rideplot

📁 GPS Ride Plot软件转换一个下载的GPS轨迹
💻
字号:
#!/usr/bin/perl# #	rideplot - convert a GPS track to a graph/map image#	Copyright (c) 2000-2001 by Ian Kluft##	This is copyrighted Open Source software.  The author permits#	redistribution under the terms of the GNU General Public License#	(GPL) version 2.  ( http://www.fsf.org/copyleft/gpl.html )  The#	author requests that enhancements should be contributed back in#	order to extend the original software distribution.##	For details about rideplot see http://rideplot.sourceforge.net/##	This software converts track and waypoint data downloaded from a #	GPS into a PNG image which graphically represents the track#	like a map.  The resulting image may then be edited with GIMP or#	another image editor to produce custom maps based on GPS-recorded#	courses previously travelled.##	Perl POD embedded documentation is included at the bottom of the file.#       Simon G Modifications.#	---------------------	#	$date is now yyyy/mm/dd instead of mm/dd/yyyy. #	cos 20020523 is bigger than 05232002 !! And# 	much easier with mathematic calculations.##	Options that require an extra value if used were made a requirement#  	instead of an option. ;)#	All units are metric but there is a nonmetric option. --nonmetric#	All internal coordinates are now in DEGREES(dd.dddd...)##	Multi-format input data added #	-> GPSTRANS, GARDOWN, GD2 (deg mins), GD2d (-f 1 (Degrees)), PCX5.##	Mapblast retrieval url for a background map ! with an#	Option to get it and save it to a file. --map-get=str##	Track has a transparent background for easy merging.#	Option for inverted speed colors. --color=2# 	Option for an output file. --output=<FILE>#	Option to include the name beside the waypoints. --waypoint-name#	Option to merge the Waypoints with the Track. --waypoint-merge#	Help option --help that displays the embedded POD ducumentation.## 	FIXED: --brush-color option didn't work. Error with parsing of option value##	by Simon G junk@simong.net May 2002.#	Dated: 2002-05-27 yyyy-mm-dd#use GD;			# Graphics libraryuse POSIX qw( atan asin cos sin sqrt strftime);use Date::Calc qw( Delta_DHMS Decode_Date_US Decode_Month Add_Delta_DHMS );use Getopt::Long;	# Command line optionsuse Pod::Usage; 	# Help uses the embedded POD documentationuse Image::EXIF;        # Extracts EXIF information from photorequire LWP::UserAgent;	# Http GET etc.use Data::Dumper;use strict;use vars qw( $debug $deg $pi $km_per_mile $nonmetric $dist_m $x_scale $y_scale	     $image $max_x $max_y $white $black $blue $dot_brush $dot_fg $dot_bg $scale	     @data $avg_lat $lat_scale $maxlat $minlat $maxlon $minlon $point $mb_scale	     $mid_lat $mid_lon $data_format $img_x $img_y $londist $latdist $map_url $map_file $map_get	     $maxspeed $use_color @sp_color @sp_brush $maxwidth $maxheight	     $speed_cutoff $cutoff_count $brush_width $brush_color $output_file	     @waypoints $waypoint_file $waypoint_width $waypoint_fill $waypoint_name $waypoint_merge 	     $photo_dir @photos @mapped_photos  $photo_idx $imap_file $transparent);# convert degrees/min/sec to decimal degrees.sub dms2deg{	my ( $str ) = @_;	$debug and print STDERR "dms2deg coordinate: $str\n";	if ( $data_format =~ /gpstrans/ ) {		# GPSTRANS		if ( $str =~ /^-{0,1}[0-9]+\.[0-9]+$deg$/o ) {			return 0.0 + $str;		}		if ( $str =~ /^(-{0,1})([0-9]+)$deg([0-9]+\.[0-9]+)\'$/o ) {			return ( 0.0 + $2 + $3/60.0) * (($1 eq "-") ? -1.0 : 1.0 );		}		if ( $str =~ /^(-{0,1})([0-9]+)$deg([0-9]+)\'([0-9]+\.[0-9]+)\"$/o ) {			return ( 0.0 + $2 + $3/60.0 + $4/3600.0 ) * (($1 eq "-") ? -1.0 : 1.0 );		}		$debug and print STDERR "dms2deg: misformatted coordinate: $str\n";		return undef;		# END GPSTRANS	} else {		die "$0 dms2deg: Unknown data_format $data_format\n";	}}# convert N S E W degrees/min to decimal degrees.sub dm2deg{	my ( $str ) = @_;	$debug and print STDERR "dm2deg coordinate: $str\n";	if (( $data_format =~ /gd/ ) or ( $data_format =~ /gardown/ )) {		# GD2		if ( $str =~ /^([NSEW])([0-9]+)$/o ) {			return 0.0 + $2 * ((($1 eq "S") or ($1 eq "W")) ? -1.0 : 1.0 );		}		if ( $str =~ /^([NSEW])([0-9]+)\s([0-9]+\.[0-9]+)$/o ) {			return ( 0.0 + $2 + $3/60.0 ) * ((($1 eq "S") or ($1 eq "W")) ? -1.0 : 1.0 );		}		$debug and print STDERR "dm2deg: misformatted coordinate: $str\n";		return undef;		# END GD2	} else {		die "$0 dm2deg: Unknown data_format $data_format\n";	}}# convert latitude/longitude to x/ysub ll2xy{	my ( $lat, $lon, $maxlat, $minlat, $maxlon, $minlon, $max_x, $max_y )		= @_;	my ( $x, $y );	$x = int (( $lon - $minlon ) / ( $maxlon - $minlon ) * $max_x )+$brush_width+1;	$y = $max_y - ( int (( $lat - $minlat ) / ( $maxlat - $minlat ) * $max_y ))+$brush_width+1;	$debug and print STDERR "ll2xy: lat=$lat lon=$lon max_x=$max_x max_y=$max_y x=$x y=$y\n";	return ( $x, $y );}sub interpolate{    my ($prevtime, $timestr, $photo_time, $prevlat, $prevlon, $lat, $lon) = @_;        my ($interplat, $interplon);    # Do linear interpretation        # Get total difference in seconds    # compute time in seconds    my @ttime = Delta_DHMS( datetime2array( $prevtime ),			 datetime2array( $timestr ));    my $tsec = $ttime[0]*86400 + $ttime[1]*3600 + $ttime[2]*60 +	$ttime[3];    # compute delta time in seconds    my @dtime = Delta_DHMS( datetime2array( $prevtime ),			 datetime2array( $photo_time ));    my $dsec = $dtime[0]*86400 + $dtime[1]*3600 + $dtime[2]*60 +	$dtime[3];    $interplat = $prevlat + ( $lat - $prevlat ) * $dsec  / $tsec;    $interplon = $prevlon + ( $lon - $prevlon ) * $dsec  / $tsec;     return ($interplat, $interplon);}# convert degrees to radians for trig functionssub deg2rad{	$_[0] * $pi / 180.0;}# convert radians to degrees for trig functionssub rad2deg{	$_[0] * 180.0 / $pi;}# compute distancesub dist{	my ( $lat1, $lon1, $lat2, $lon2 ) = @_;	$debug and print STDERR "debug: dist ( $lat1, $lon1, $lat2, $lon2 )\n";	# note: this great-circle forula should not be used near the poles	# see http://users.netonecom.net/~rburtch/geodesy/datm_faq.html#2.1		# Earth radius is estimated for each leg (Why? Because we can!)	my $earth_radius = 6378.0 - 21.0 * sin(deg2rad(($lat1+$lat2)/2.0));		# differences in lattitude and longitude	my $dlat = abs($lat1-$lat2);	my $dlon = abs($lon1-$lon2);	# compute great-circle distance	my $a = sin(deg2rad($dlat/2.0)) * sin(deg2rad($dlat/2.0))		+ cos(deg2rad($lat1))		* cos(deg2rad($lat2))		* sin(deg2rad($dlon/2.0)) * sin(deg2rad($dlon/2.0));	my $c = 2.0 * asin(sqrt($a));	# convert distance in radians on Earth-surface arc to meters	$debug and print STDERR "distance (m) = "		.($earth_radius * $c * 1000.0)		.", c = $c, a = $a, dlat = $dlat, dlon = $dlon\n";	return $earth_radius * $c * 1000.0;}# parse date and time into an array Date::Calc can use# yyyy/mm/dd hh:mm:sssub datetime2array{	my ( $datetime ) = @_;	$datetime =~ /([0-9]{4})\/([0-9]{2})\/([0-9]{2})\s+([0-9]{2}):([0-9]{2}):([0-9]{2})/;	return ( $1, $2, $3, $4, $5, $6 );}# Decode MMM text to month number nnsub decodemonth{	my ($txtmonth) = @_;	$debug and print STDERR "Txtmonth = $txtmonth \n";	my $monthnum = Decode_Month($txtmonth);	if ( length($monthnum) == 1 ) { $monthnum = "0$monthnum" } # Convert single digits to 2 digits	return $monthnum;}sub get_photo_info{    my $strftime_offset = strftime "%z", localtime;    my $tz_offset = ( $strftime_offset / 100.0 ) * (-1.0);        my $dir = shift;    chdir( $dir ) or die "Failed to chdir: $!";    my $exif = new Image::EXIF;    my @file_names = glob("dsc*.jpg");    my @photos_tmp; # list of photo information    my $file;    foreach $file (@file_names)    {	$debug && print STDERR "Get photo: $file\n";	$exif->file_name($file);	my $image_info = $exif->get_image_info(); # hash reference    	my $str_buffer = $image_info->{"Image Created"};	my ($date, $time) = split ' ', $str_buffer;	$date =~ s/:/\//g;	my $timestr = "$date $time";	my @ltime = datetime2array($timestr);	# Photos have local timestamp. Change them to have GMT time	# Get's the local timezone from the System or environment	# The "-2" is the skew for the digital camera. Once again, this is hard coded and needs to	# be changed.	my @ntime = Add_Delta_DHMS( @ltime, 0,$tz_offset,-2,0);    	my $photo_timestr = sprintf ("%04d/%02d/%02d %02d:%02d:%02d" ,$ntime[0],$ntime[1],$ntime[2],$ntime[3],$ntime[4],$ntime[5]);	$debug && print STDERR "$file |",$photo_timestr, "|\n";	push @photos_tmp, [$photo_timestr , $file];    }    return @photos_tmp;}# Syncronizes photos based upon prevtime and current timestr# Accesses photo data based upon global information.sub sync_photos{    my ($prevtime, $timestr, $prevlat, $prevlon, $lat, $lon) = @_;    # This subroutine is accessing global variables. And doesn't return anything. Should modularize this    my $continue = 1;    $debug && print STDERR "Continue: $continue. photo_idx $photo_idx \n";    while ( $photo_idx < $#photos && $continue == 1 )    {	my $time_photo = ${$photos[$photo_idx]}[0];	my $photo_name = ${$photos[$photo_idx]}[1];	$debug && print STDERR "Prevtime: ", $prevtime ,"\n";	$debug && print STDERR "Photo timestamp: ", $time_photo ,"\n";	$debug && print STDERR "Timestr: ", $timestr ,"\n";	if ( $time_photo ge $prevtime    && $time_photo lt $timestr )	{	    # We have a photo taken during tracklog collection.	    	    # Interpolate the lat and lon for this photo based upon time	    # prevtime, timestr, photo_time, prevlat, prevlon, lat, lon	    my ($interplat, $interplon) = interpolate( $prevtime, $timestr,						       ${$photos[$photo_idx]}[0],						       $prevlat, $prevlon,						       $lat, $lon);	    push @mapped_photos, [ $interplat, $interplon, $photo_name  ];	    $photo_idx++;	} 	elsif ( $time_photo lt $prevtime )	{	    $photo_idx++;	}	elsif ( $time_photo gt $timestr )	{	    $continue = 0;	}	else 	{	    $continue = 0;	}		$debug && print STDERR "Incremented on photo_idx: $photo_idx. Total: $#photos\n";	    }    return;}sub get_map {	my $ua = LWP::UserAgent->new;	#$ua->agent('Mozilla/5.0');  # Set the user-agent. May not be needed.	$ua->env_proxy();            # Set Proxy settings from enviornment HTTP_PROXY or CGI_HTTP_PROXY	print STDERR "Getting background map ...";	my $request = HTTP::Request->new('GET', $map_url );	my $response = $ua->request($request, $map_get );	print STDERR "  Done.\n";}# initialize constants$pi = 4.0 * atan(1);$deg='

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -