Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
93 lines (73 sloc) 2.37 KB
#!/usr/bin/env perl
#
# Restaurant location data:
# https://docs.mongodb.org/getting-started/shell/import-data/
#
# mongod --auth
# mongo -u gene -p --authenticationDatabase "admin"
#
use strict;
use warnings;
use YAML;
use MongoDB;
use Algorithm::TravelingSalesman::BitonicTour;
use Math::Geometry::Planar;
use Statistics::R;
my $borough = shift || 'Manhattan';
my $grade = shift || 'A';
my $score = shift // 70;
my $config = shift || 'creds.yaml';
my $db = 'test.restaurants';
my $cfg = YAML::LoadFile($config);
my $client = MongoDB::MongoClient->new(
host => $cfg->{mongo}{dbhost},
db_name => $cfg->{mongo}{dbname},
username => $cfg->{mongo}{dbuser},
password => $cfg->{mongo}{dbpass},
);
# Select the relevant documents
my $criteria = {
borough => $borough,
'grades.grade' => $grade,
'grades.score' => { '$gt' => 0 + $score },
# cuisine => qr/american/i,
};
my $collection = $client->ns($db);
my $docs = $collection->find($criteria);
my $tsp = Algorithm::TravelingSalesman::BitonicTour->new;
my %coord_name; # Index of coordinates to restaurant names
# Add the points to the TSP object and coordinate index
while ( my $doc = $docs->next) {
my @point = @{ $doc->{address}{coord} };
$tsp->add_point(@point);
$coord_name{ join ',', @point } = $doc->{name};
}
my ( undef, @coords ) = $tsp->solve;
my $i = 0; # Counter
print "Optimal path:\n";
for my $coord (@coords) {
my $key = join ',', @$coord;
printf "\t%d. %s [%s]\n", ++$i, $coord_name{$key}, $key;
}
# Find the path polygon centroid
my $polygon = Math::Geometry::Planar->new;
$polygon->points( [ @coords[ 1 .. $#coords ] ] );
my $centroid = $polygon->centroid;
# Produce a map with points and path
print "Producing map...\n";
my $R = Statistics::R->new();
$R->run( 'library(ggmap)' );
my $file = "$0.png";
$R->run( "png('$file')" );
$R->set( 'X', [ map { $_->[0] } @coords ] );
$R->set( 'Y', [ map { $_->[1] } @coords ] );
$R->run( 'df <- data.frame( X, Y )' );
$R->run( "names(df) <- c( 'lon', 'lat' )" );
$R->run( "centroid <- get_googlemap( center = c( $centroid->[0], $centroid->[1] ), zoom = 12 )" );
my $gg_cmd = 'ggmap( centroid, aes( lon, lat ) )';
$gg_cmd .= ' + geom_point( data = df, colour = "darkred" )';
$gg_cmd .= ' + geom_path( data = df, color = "darkgray", size = 0.5 )';
$R->run($gg_cmd);
$R->run( 'dev.off()' );
$R->stop();
print "Done.\n";