-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfind-kml-uniques
79 lines (70 loc) · 2.01 KB
/
find-kml-uniques
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use XML::Simple qw(:strict);
use Getopt::Long qw(GetOptions);
sub extractPlacemarks {
my @results = ();
my $xml = XMLin(shift(), ForceArray => 0, KeyAttr => [ 'id' ]);
my @documents = $xml->{Document};
foreach my $document (@documents) {
my @folders = $document->{Folder};
foreach my $folder (@folders) {
if (ref $folder ne 'ARRAY') {
$folder = [ $folder ];
}
foreach my $f (@{$folder}) {
my $s1 = $f->{name};
chomp($s1);
my @placemarks = $f->{Placemark};
foreach my $placemark (@placemarks) {
if (ref $placemark ne 'ARRAY') {
$placemark = [ $placemark ];
}
foreach my $p (@{$placemark}) {
my $s2 = $p->{name};
chomp($s2);
my $name = $s1 . '/' . $s2;
my $coordinates = $p->{Point}->{coordinates};
$coordinates =~ s/^\s+|\s+$//g;
my ($longitude, $latitude, $altitude) = split(',', $coordinates);
if (!defined($longitude) || !defined($latitude)) {
print "$name\n";
}
push(@results, [ $name, $longitude, $latitude ]);
}
}
}
}
}
return @results;
}
sub computeDistance {
my $lon1 = shift();
my $lat1 = shift();
my $lon2 = shift();
my $lat2 = shift();
my $dLat = deg2rad($lat2-$lat1);
my $dLon = deg2rad($lon2-$lon1);
my $a = sin($dLat/2.0) * sin($dLat/2.0) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2.0) * sin($dLon/2.0);
return 12742.0 * atan2(sqrt($a), sqrt(1-$a));
}
sub deg2rad {
return shift() * (3.14159265359 / 180.0)
}
Getopt::Long::Configure qw(gnu_getopt);
my $radius = 1;
GetOptions('radius|r=f' => \$radius) or die "Usage: $0 [-r radius] file.kml\n";
my @many = extractPlacemarks($ARGV[0]);
my @few = extractPlacemarks($ARGV[1]);
binmode STDOUT, ":encoding(UTF-8)";
MAIN: for (my $i = 0; $i < scalar(@many); $i++) {
for (my $j = 0; $j < scalar(@few); $j++) {
my $distance = computeDistance($many[$i][1], $many[$i][2], $few[$j][1], $few[$j][2]);
if ($distance <= $radius) {
next MAIN;
}
}
print $many[$i]->[0] . "\n";
}