Radreise-Wiki:Km.pl

Aus Radreise-Wiki

Das Perl-Skript km.pl wird mit dem Streckennamen als Parameter aufgerufen. Die zugehörige Streckendatei muss bereits im text- und die Trackdatei im track-Verzeichnis vorhanden sein. Beispiel für einen Aufruf:

perl km.pl Donau

Das Skript berechnet die Kilometrierung des Roadbook und speichert das Ergebnis als Datei im Output-Verzeichnis (siehe ini.pl). Die Datei "Donau_new.tx" enthält das neue Roadbook und kann mit einem UTF8-fähigen Texteditor geöffnet und direkt in das Edit-Fenster des Streckenartikels kopiert werden.

Wenn man die Variable $changePlaceHm = 1 setzt, werden sämtliche Orts-Höhenmeter über die Höhendaten des Tracks neu berechnet.

Quellcode des Skripts:

use strict;

use Encode qw (encode decode);

my $smoothAlt      =  6;
my $changePlaceHm  =  1;
my $changeDistHm   =  1;
my $makeRetour     =  0; # not yet implemented
my $verbose        =  0;

#==================================
# Default Settings and Subroutines
push @INC, '.';
require "ini.pl";

my ($baseDir, $outDir, $username, $password, $encoding, $encAnsi, $encOut) = getIni();

my $dir_txt   = "$baseDir/text";
my $dir_trk   = "$baseDir/tracks";

my ($routeFileName, $routeFileName_e) = get_routeFileName (@ARGV);

my ($track, $rawTrack) = get_trackfile ($dir_trk, $routeFileName);

my @track    = @$track;
my @rawTrack = @$rawTrack;

#====================
# Glättung der Höhen

for (my $j = 1; $j <= $smoothAlt; $j++) {
	for (my $i = 1; $i < $#track ; $i++) {

		my $avgAlt = ($track[$i-1][2] + $track[$i][2] + $track[$i+1][2]) / 3;
		
		$track[$i][2] = $avgAlt;
	}
}

#======================
# Tracklänge berechnen
	
my $length = 0;

for (my $i = 0; $i < $#track ; $i++) {	

	my $dist = getDistance ( 
	
		$track[$i][0], 
		$track[$i][1], 
		$track[$i+1][0], 
		$track[$i+1][1] 
	);
		
	$length += $dist / 1000;
}

#=============================
# Gesamt-Höhenmeter berechnen

my ($HmSumUp, $HmSumDn) = getHmSum (0, $#track);

#=============================
# Ausgabe der Track-Statistik

my $length_s = sprintf "%0.0f", $length;
my $HmSumUp_s = sprintf "%0.0f", $HmSumUp;
my $HmSumDn_s = sprintf "%0.0f", $HmSumDn;

printf "Trackpunkte : %6d pt\n",   $#track + 1;
print encode $encOut, "| Länge = $length_s\n";
print encode $encOut, "| Höhenmeter (auf) = $HmSumUp_s<!-- Glättungsfaktor = $smoothAlt -->\n";
print encode $encOut, "| Höhenmeter (ab) = $HmSumDn_s\n";

# ==============
# Get Routefile

my ($fileContent, $pre_Roadbook, $Roadbook, $post_Roadbook) = 

	get_routefile ($dir_txt, $routeFileName);

if ($fileContent =~ /ERROR/) {

	die "$routeFileName not existent\n";
}

my @Roadbook = split "\n", $Roadbook;

# ===============
# Get Placemarks

my ($PlacemarksRaw, $Placemarks) = get_placemarks (@Roadbook);

my @Placemarks = @$PlacemarksRaw;

my @placeName;

my @touriInfo;

my @geodaten;
my @geodaten_lat;
my @geodaten_lon;

my @geodaten_alt;
my @geodaten_alt_real;
my @geodaten_alt_res;

my @geodaten_info;
my @geodaten_nearest_tp;
my @geodaten_dist_to_tp;

my @roadInfo;

my @kilometrierung;

my @kilometrierung_km;
my @kilometrierung_km_real;
my @kilometrierung_km_res;

my @kilometrierung_km_sum;
my @kilometrierung_km_sum_real;
my @kilometrierung_km_sum_res;

my @kilometrierung_hmup;
my @kilometrierung_hmup_real;
my @kilometrierung_hmup_res;

my @kilometrierung_hmup_sum;
my @kilometrierung_hmup_sum_real;
my @kilometrierung_hmup_sum_res;

my @kilometrierung_hmdn;
my @kilometrierung_hmdn_real;
my @kilometrierung_hmdn_res;

my @kilometrierung_hmdn_sum;
my @kilometrierung_hmdn_sum_real;
my @kilometrierung_hmdn_sum_res;

my @rest;

# =================================
# Check Placemarks except last one

for (my $i = 0; $i < $#Placemarks; $i++) {

	my ($placeName, $touriInfo, $geodaten, $roadInfo, $kilometrierung, $rest) = get_placemarkData ($Placemarks[$i]);

	if ($placeName) {

		if ($verbose) { print encode $encOut, "$placeName\n"; }
		#print encode $encOut, "\n";
		#print encode $encOut, "   $geodaten\n";
		#print encode $encOut, "   $kilometrierung\n";
		#print encode $encOut, "\n";

		push @placeName, $placeName;
		push @touriInfo, $touriInfo;
		push @geodaten, $geodaten;
		push @roadInfo, $roadInfo;
		push @kilometrierung, $kilometrierung;
		push @rest, $rest;

	} else { die "ERROR in get_placemarkData\n"; }


	# ===============
	# Check Geodaten

	my ($lat, $lon, $alt, $info) = get_geodaten ($geodaten[$i]);

	if ($lat) {

		my ($trackPoint, $distance) = getClosestPoint ( $lat, $lon, \@track );

		#print encode $encOut, "   $lat\n";
		#print encode $encOut, "   $lon\n";
		#print encode $encOut, "   $alt\n";
		#print encode $encOut, "   $trackPoint\n";
		#print encode $encOut, "   $distance\n";
		#print encode $encOut, "\n";

		push @geodaten_lat, $lat;
		push @geodaten_lon, $lon;
		push @geodaten_alt, $alt;
		push @geodaten_alt_real, sprintf "%.0f", $track[$trackPoint][2];
		push @geodaten_alt_res, $alt;
		push @geodaten_info, $info;
		push @geodaten_nearest_tp, $trackPoint;
		push @geodaten_dist_to_tp, $distance;

	} else { die "ERROR in get_geodaten\n"; }

	# =====================
	# Check Kilometrierung

	my ($km, $km_sum, $hmup, $hmdn, $hmup_sum, $hmdn_sum) = get_kilometrierung ($kilometrierung[$i]);

	if ($verbose) { print encode $encOut, "$kilometrierung[$i]\n"; }

	if ($km ne "x") {

		#print encode $encOut, "   $km\n";
		#print encode $encOut, "   $sum\n";
		#print encode $encOut, "   $hmup\n";
		#print encode $encOut, "   $hmdn\n";
		#print encode $encOut, "\n";

		push @kilometrierung_km,         $km;
		push @kilometrierung_km_res,     $km;

		push @kilometrierung_km_sum,     $km_sum;
		push @kilometrierung_km_sum_res, $km_sum;

		push @kilometrierung_hmup,       $hmup;
		push @kilometrierung_hmup_res,   $hmup;

		push @kilometrierung_hmdn,       $hmdn;
		push @kilometrierung_hmdn_res,   $hmdn;

		push @kilometrierung_hmup_sum,     $hmup_sum;
		push @kilometrierung_hmup_sum_res, $hmup_sum;

		push @kilometrierung_hmdn_sum,     $hmdn_sum;
		push @kilometrierung_hmdn_sum_res, $hmdn_sum;

	} else {
		print encode $encOut, "ERROR in get_kilometrierung: $placeName[$i]\n";
		die;
	}

}

# =====================
# Check last Placemark

my ($placeName, $touriInfo, $geodaten, $roadInfo) = get_lastPlacemarkData ($Placemarks[$#Placemarks]);

if ($placeName) {

	#print encode $encOut, "$placeName\n";
	#print encode $encOut, "\n";
	#print encode $encOut, "   $geodaten\n";
	#print encode $encOut, "\n";

	push @placeName, $placeName;
	push @touriInfo, $touriInfo;
	push @geodaten,  $geodaten;
	push @roadInfo,  $roadInfo;
	push @kilometrierung, "";
	push @rest,           "";

	push @kilometrierung_km,         "";
	push @kilometrierung_km_res,     "";

	push @kilometrierung_km_sum,     "";
	push @kilometrierung_km_sum_res, "";

	push @kilometrierung_hmup,       "";
	push @kilometrierung_hmup_res,   "";

	push @kilometrierung_hmdn,       "";
	push @kilometrierung_hmdn_res,   "";

	push @kilometrierung_hmup_sum,     "";
	push @kilometrierung_hmup_sum_res, "";

	push @kilometrierung_hmdn_sum,     "";
	push @kilometrierung_hmdn_sum_res, "";

} else { die "ERROR in get_lastPlacemarkData\n"; }

# =================================
# Check Geodaten of last Placemark

my ($lat, $lon, $alt, $info) = get_geodaten ($geodaten[$#geodaten]);

if ($lat) {

	my ($trackPoint, $distance) = getClosestPoint ( $lat, $lon, \@track );

	#print encode $encOut, "   $lat\n";
	#print encode $encOut, "   $lon\n";
	#print encode $encOut, "   $alt\n";
	#print encode $encOut, "   $trackPoint\n";
	#print encode $encOut, "   $distance\n";
	#print encode $encOut, "\n";

	push @geodaten_lat, $lat;
	push @geodaten_lon, $lon;
	push @geodaten_alt, $alt;
	push @geodaten_alt_real, sprintf "%.0f", $track[$trackPoint][2];
	push @geodaten_alt_res, $alt;
	push @geodaten_info, $info;
	push @geodaten_nearest_tp, $trackPoint;
	push @geodaten_dist_to_tp, $distance;

} else { die "ERROR in get_geodaten\n"; }

# =========================
# Calculate real Distances

my $sum_real;

for (my $i=0; $i < $#Placemarks; $i++) {

	my $km_real;

	for (my $j = $geodaten_nearest_tp[$i]; $j < $geodaten_nearest_tp[$i+1] ; $j++) {

		my $dist = getDistance ( $track[$j][0], $track[$j][1], $track[$j+1][0], $track[$j+1][1] ) / 1000;

		$km_real += $dist;
	}

	$sum_real += $km_real;

	push @kilometrierung_km_real, sprintf "%.1f", $km_real;
	push @kilometrierung_km_sum_real, sprintf "%.0f", $sum_real;
}

push @kilometrierung_km_real, "";
push @kilometrierung_km_sum_real, "";


# ==========================
# Calculate real Höhenmeter

my $sum_hmup;
my $sum_hmdn;

for (my $i=0; $i < $#Placemarks; $i++) {

	my ($hmup, $hmdn) = getHmSum ($geodaten_nearest_tp[$i], $geodaten_nearest_tp[$i+1]);

	$sum_hmup += $hmup;
	$sum_hmdn += $hmdn;

	push @kilometrierung_hmup_real, sprintf "%.0f", $hmup;
	push @kilometrierung_hmdn_real, sprintf "%.0f", $hmdn;
	push @kilometrierung_hmup_sum_real, sprintf "%.0f", $sum_hmup;
	push @kilometrierung_hmdn_sum_real, sprintf "%.0f", $sum_hmdn;
}

push @kilometrierung_hmup_real, "";
push @kilometrierung_hmdn_real, "";
push @kilometrierung_hmup_sum_real, "";
push @kilometrierung_hmdn_sum_real, "";


# =====================================
# Check ascending order of TrackPoints

for (my $i=0; $i<$#Placemarks; $i++) {

	if ( $geodaten_nearest_tp[$i] <= $geodaten_nearest_tp[$i+1] ) {

		#ok

	} else {

		print encode $encOut, "ERROR: Wrong TrackPoint Order in:\n";
		print encode $encOut, "   $placeName[$i] :: $geodaten_nearest_tp[$i]\n";
		print encode $encOut, "   $placeName[$i+1] :: $geodaten_nearest_tp[$i+1]\n\n";
	}
}

# ===================
# Summarize all Data

my $output = sprintf "%5s  %3s %4s %5s %5s %5s %5s %5s  %s",

	"tp#",
	"dist",
	"k",
	"k_s",
	"k_r",
	"k_s_r",
	"a",
	"a_r",
	"place";

if ($verbose) { print encode $encOut, "$output\n"; }

for (my $i=0; $i <= $#Placemarks; $i++) {

	my $output = sprintf "%5d %3.0f m %4s %5s %5s %5s %5s %5s  %s",

		$geodaten_nearest_tp[$i],
		$geodaten_dist_to_tp[$i],
		$kilometrierung_km[$i],
		$kilometrierung_km_sum[$i],
		$kilometrierung_km_real[$i],
		$kilometrierung_km_sum_real[$i],
		$geodaten_alt[$i],
		$geodaten_alt_real[$i],
		$placeName[$i];
	
	if ($verbose) { print encode $encOut, "$output\n"; }
}

if ($verbose) { print encode $encOut, "\n"; }

# ==================
# Summarize Changes

my $change;

my $output = sprintf "%5s  %3s %4s %5s %5s %5s %5s %5s  %s",

	"tp#",
	"dist",
	"k",
	"k_s",
	"k_r",
	"k_s_r",
	"a",
	"a_r",
	"place";

print encode $encOut, "$output\n";

for (my $i=0; $i <= $#Placemarks; $i++) {

	$kilometrierung_km_real[$i] =~ s/\./\,/;

	if ($kilometrierung_km[$i] eq $kilometrierung_km_real[$i]) {

		$kilometrierung_km[$i] = "";
		$kilometrierung_km_real[$i] = "";

	} else {
		
		$kilometrierung_km_res[$i] = $kilometrierung_km_real[$i];
		$change = 1; 
	}

	if ($kilometrierung_km_sum[$i] eq $kilometrierung_km_sum_real[$i]) {

		$kilometrierung_km_sum[$i] = "";
		$kilometrierung_km_sum_real[$i] = "";

	} else {
		
		$kilometrierung_km_sum_res[$i] = $kilometrierung_km_sum_real[$i];
		$change = 1;
	}

	if ($changePlaceHm) {

		if ($geodaten_alt[$i] eq $geodaten_alt_real[$i]) {

			$geodaten_alt[$i] = "";
			$geodaten_alt_real[$i] = "";

		} else {
			
			$geodaten_alt_res[$i] = $geodaten_alt_real[$i];
			$change = 1; 
		}

	} else {

		$geodaten_alt[$i] = "";
		$geodaten_alt_real[$i] = "";
	}

	if ($changeDistHm) {

		if ($kilometrierung_hmdn[$i] eq $kilometrierung_hmdn_real[$i]) {

			$kilometrierung_hmdn[$i] = "";
			$kilometrierung_hmdn_real[$i] = "";

		} else {
			
			$kilometrierung_hmdn_res[$i] = $kilometrierung_hmdn_real[$i];
			$change = 1; 
		}

		if ($kilometrierung_hmup[$i] eq $kilometrierung_hmup_real[$i]) {

			$kilometrierung_hmup[$i] = "";
			$kilometrierung_hmup_real[$i] = "";

		} else {
			
			$kilometrierung_hmup_res[$i] = $kilometrierung_hmup_real[$i];
			$change = 1; 
		}

		if ($kilometrierung_hmup_sum[$i] eq $kilometrierung_hmup_sum_real[$i]) {

			$kilometrierung_hmup_sum[$i] = "";
			$kilometrierung_hmup_sum_real[$i] = "";

		} else {
			
			$kilometrierung_hmup_sum_res[$i] = $kilometrierung_hmup_sum_real[$i];
			$change = 1; 
		}

		if ($kilometrierung_hmdn_sum[$i] eq $kilometrierung_hmdn_sum_real[$i]) {

			$kilometrierung_hmdn_sum[$i] = "";
			$kilometrierung_hmdn_sum_real[$i] = "";

		} else {
			
			$kilometrierung_hmdn_sum_res[$i] = $kilometrierung_hmdn_sum_real[$i];
			$change = 1; 
		}

	} else {
	}

	my $output = sprintf "%5d %3.0f m %4s %5s %5s %5s %5s %5s  %s",

		$geodaten_nearest_tp[$i],
		$geodaten_dist_to_tp[$i],
		$kilometrierung_km[$i],
		$kilometrierung_km_sum[$i],
		$kilometrierung_km_real[$i],
		$kilometrierung_km_sum_real[$i],
		$geodaten_alt[$i],
		$geodaten_alt_real[$i],
		$placeName[$i];
	
	print encode $encOut, "$output\n";
}

# ======================
# Write Changes to File


if ($change) {

	$fileContent = "";

	$fileContent .= $pre_Roadbook;


	for (my $i=0; $i < $#Placemarks; $i++) {

		$fileContent .= "=== $placeName[$i] ===\n";
		$fileContent .= "$touriInfo[$i]\n";
		$fileContent .= "{{Geodaten|$geodaten_lat[$i]|$geodaten_lon[$i]|$geodaten_alt_res[$i]|$geodaten_info[$i]}}\n";
		$fileContent .= "$roadInfo[$i]\n";

		if ($kilometrierung[$i] =~ /KilometrierungHm6/) {

			$fileContent .= "{{KilometrierungHm6|$kilometrierung_km_res[$i]|$kilometrierung_hmup_res[$i]|$kilometrierung_hmdn_res[$i]|$kilometrierung_km_sum_res[$i]|$kilometrierung_hmup_sum_res[$i]|$kilometrierung_hmdn_sum_res[$i]}}";

		} elsif ($kilometrierung[$i] =~ /KilometrierungHm/) {

			$fileContent .= "{{KilometrierungHm|$kilometrierung_km_res[$i]|$kilometrierung_km_sum_res[$i]|$kilometrierung_hmup_sum_res[$i]|$kilometrierung_hmdn_sum_res[$i]}}";

		} else {

			$fileContent .= "{{Kilometrierung|$kilometrierung_km_res[$i]|$kilometrierung_km_sum_res[$i]}}";
		}

		$fileContent .= "\n$rest[$i]";
	}

	$fileContent .= "=== $placeName[$#Placemarks] ===\n";
	$fileContent .= "$touriInfo[$#Placemarks]\n";
	$fileContent .= "{{Geodaten|$geodaten_lat[$#Placemarks]|$geodaten_lon[$#Placemarks]|$geodaten_alt_res[$#Placemarks]|$geodaten_info[$#Placemarks]}}\n";
	$fileContent .= "$roadInfo[$#Placemarks]";

	$fileContent .= $post_Roadbook;
	
	open  FOUT, "> $outDir/${routeFileName_e}_new.tx" or die $!;
	print FOUT encode ($encoding, $fileContent);
	close FOUT;

}

exit;


#==========================================================
#==========================================================

sub getHmSum {

	my ($tp_begin, $tp_end) = @_;

	if ($tp_end >= $#track) { $tp_end = $#track-1; }

	my $HmSumUp = 0;
	my $HmSumDn = 0;
	
	for (my $i = $tp_begin; $i <= $tp_end ; $i++) {

		my $alt_0 = $track[$i][2];
		my $alt_1 = $track[$i+1][2];
		
		my $diff  = $alt_1 - $alt_0;

		if ($diff < 0) { $HmSumDn += $diff * (-1); }
		if ($diff > 0) { $HmSumUp += $diff * (+1); }

	}

	return ($HmSumUp, $HmSumDn);
}