2024 twenty-four merry days of Perl Feed

Have fun with Map::Tube

Map::Tube - 2024-12-11

"Swiss Cottage Underground Station (Jubilee Line)" by hugh llewelyn is licensed under CC BY-SA 2.0 .

Map::Tube was one of my earliest submissions to CPAN and it's a project that's very close to my heart. Over the years, I've had the joy of writing about it and I've spoken about it at many conferences. I consider it my baby though I share it with many amazing contributors who have helped make it sleeker and more powerful. Each day, I'm thankful for the contributions of those who've made this project better. Many thanks also to everyone who has used used the library to build maps for cities around the world. As of today, there are 41 maps created by 11 contributors.

Inspiration behind the map

Our first window to open is about inspiration! The journey began with the idea to create a map for the London Tube, the famous underground rail network. The first map created was Map::Tube::London. As work on Map::Tube::London progressed, I realized there was an opportunity to build a framework so others could create map for their own cities. And so, Map::Tube was born. So now you know where the term Tube came from!

The first day's play: Let's get started

It's time to open the first window and dive in! To get started, you'll need to install the framework and at least one map. For today, let's stick with the London Tube.

$ cpanm -v Map::Tube

$ cpanm -v Map::Tube::London

Now it's time to get your hands dirty!

use v5.40;
use Map::Tube::London;

my $map = Map::Tube::London->new;
say $map->get_shortest_route('Baker Street', 'Wembley Park');

Opening the window to the route finder, you should see something like this:

Baker Street (Bakerloo, Circle, Hammersmith & City, Jubilee, Metropolitan), Finchley Road (Jubilee, Metropolitan), Wembley Park (Jubilee, Metropolitan)

Nice and easy, right?

If you're feeling a bit lazy and don't want to write the 4 lines perl, no worries, there's a shortcut! The Map::Tube::CLI distribution comes with a command line utility called map-tube.

Let's repeat today's fun with just one line using the command line tool: map-tube.

$ cpanm -v Map::Tube::CLI

$ map-tube --map London --start 'Baker Street' --end 'Wembley Park'
Baker Street (Bakerloo, Circle, Hammersmith & City, Jubilee, Metropolitan), Finchley Road (Jubilee, Metropolitan), Wembley Park (Jubilee, Metropolitan)

So what's inside the map? Peek behind the curtain

Curious about how it all works? Open the next window to peek inside! There's a package called Map::Tube::Cookbook, which is part of the Map::Tube distribution that explains everything that you need to know to create a new map.

I remember the first time I gave a presentation about Map::Tube at London Perl Workshop 2017. During the talk, I challenged the audience to create a map by the end of the workshop and win a prize. To my delight, we had <Map::Tube::Athens> by Errietta Kostala.

Can I create a map image? Yes you can!

Openning the next window, you'll find the answer: Yes, you can generate a map images in png format. Use the map-tube command line tool to make it happen:

$ cpanm -v Map::Tube::Plugin::Graph
$ map-tube --map London --generate_map

Or if you only want a particular line, like the Bakerloo Line, here's how you do it.

$ map-tube --map London --line Bakerloo --generate_map

This will create a file in your current directory called Bakerloo.png.

Build your own map server

Openning the next window reveals the magic behind creating a map server. With the help of Map::Tube::Server, setting up a map server is easy. Here's how to create your server with map-server.psgi:

use v5.40;
use Map::Tube::Server;
use Plack::Builder;

builder { mount '/map-tube/v1' => Map::Tube::Server->to_app; };

Once you've set it up, start your map server like this:

$ plackup map-server.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/

Let's make a call to the map server to repeat today's search i.e. finding the route from Baker Street to Wembley Park.

$ curl http://127.0.0.1:5000/map-tube/v1/shortest-route/london/baker%20street/wembley%20park
["Baker Street (Bakerloo, Circle, Hammersmith and City, Jubilee, Metropolitan)","Finchley Road (Jubilee, Metropolitan)","Wembley Park (Jubilee, Metropolitan)"]

Access the public API

Behind the next window, you'll find the public API! If you've have setup your map server, you can access the service through an API, using the distribution: Map::Tube::API. First set the MAP_BASE_URL environment variable.

$ export MAP_BASE_URL=http://127.0.0.1:5000

Now let's create a script, map-api.pl, to make the API call:

use v5.40;
use Data::Dumper;
use Map::Tube::API;

say Dumper($api->shortest_route({ map => 'london', start => 'Baker Street', end => 'Wembley Park' }));

It's time to make that API call:

$ perl map-api.pl
$VAR1 = [
      'Baker Street (Bakerloo, Circle, Hammersmith and City, Jubilee, Metropolitan)',
      'Finchley Road (Jubilee, Metropolitan)',
      'Wembley Park (Jubilee, Metropolitan)'
];

How about other maps? Open a new city!

Ready for a new adventure? Open the next window to discover how to install other city maps. To install a map, like Delhi, just do the following:

$ cpanm -v Map::Tube::Delhi

Or, if you're feeling adventurous and want to explore all the maps, use the distribution Task::Map::Tube::Metro to install them all at once.

$ cpanm -v Task::Map::Tube::Metro
Gravatar Image This article contributed by: Mohammad Sajid Anwar <mohammad.anwar@yahoo.com>