WEBVTT

00:00.000 --> 00:05.000
Hi.

00:05.000 --> 00:07.000
All right, great.

00:07.000 --> 00:08.000
Hello, everybody.

00:08.000 --> 00:12.800
My name is Brian Duggan, and I will be talking today about connecting the geospatial

00:12.800 --> 00:14.000
dots with Raku.

00:14.000 --> 00:16.000
This is a fast talk, only 10 minutes.

00:16.000 --> 00:18.000
So I'm going to go through things quickly,

00:18.000 --> 00:21.000
but the slides will all be available afterwards.

00:21.000 --> 00:23.000
But quick, quick poll.

00:23.000 --> 00:25.000
How many people here have used Raku?

00:25.000 --> 00:26.000
Oh, good.

00:26.000 --> 00:28.000
One, two, three.

00:28.000 --> 00:33.000
So I'm going to go through a lot of Raku syntax in this talk.

00:33.000 --> 00:37.000
But again, you can check out the slides afterwards if it doesn't make sense.

00:37.000 --> 00:38.000
Okay, so my name is Brian.

00:38.000 --> 00:41.000
I work at a company called Instacart in the US.

00:41.000 --> 00:44.000
We're a grocery technology company.

00:44.000 --> 00:46.000
We do grocery deliveries among other things.

00:46.000 --> 00:49.000
And we use geospatial data a lot.

00:49.000 --> 00:52.000
We have kind of a bottom-up geospatial culture there,

00:52.000 --> 00:57.000
where we use whatever tool is best to get the job done.

00:57.000 --> 01:01.000
Okay, so I'm going to go through a few different aspects of Raku,

01:01.000 --> 01:04.000
and how it can be used for a geospatial work.

01:04.000 --> 01:08.000
I'm going to talk a little bit about managing data with it,

01:08.000 --> 01:10.000
getting some open street map data,

01:10.000 --> 01:13.000
and then some visualization.

01:13.000 --> 01:16.000
I'm going to leaflet, which we just heard about in the last talk,

01:16.000 --> 01:22.000
and then a little bit of analysis with Dr.DB and Geos.

01:22.000 --> 01:25.000
And there will be some AI also, I promise.

01:26.000 --> 01:30.000
Okay, so a little bit about the Raku philosophy.

01:30.000 --> 01:34.000
One of our core community members, Damien Conway,

01:34.000 --> 01:37.000
had these things to say about the philosophy of the language.

01:37.000 --> 01:41.000
You know, we used to say there's more than one way to do it.

01:41.000 --> 01:44.000
With Raku, we say there's always more than one way to do it,

01:44.000 --> 01:46.000
but some ways are a little more equal than others.

01:46.000 --> 01:50.000
So we try to encourage better programming without forcing it.

01:50.000 --> 01:54.000
We used to say easy things should be easy and hard things should be possible,

01:54.000 --> 01:57.000
but now we say easy things should be trivial.

01:57.000 --> 02:02.000
Hard things should be easy and impossible things should just be hard.

02:02.000 --> 02:05.000
And then to be more a little more formal,

02:05.000 --> 02:08.000
we seek to support developers without getting in their way,

02:08.000 --> 02:11.000
so that whatever mental model works for you,

02:11.000 --> 02:15.000
you can translate into code.

02:15.000 --> 02:19.000
Okay, so let's start with making the easy things trivial.

02:19.000 --> 02:22.000
Anybody here use nominatum to get open street map data?

02:22.000 --> 02:24.000
Okay, so here's how you use it in Raku.

02:24.000 --> 02:28.000
You say use web service, nominatum, nom gives you an object.

02:28.000 --> 02:30.000
You say it's called nom.search.

02:30.000 --> 02:32.000
You put a colon after it.

02:32.000 --> 02:35.000
You can either use colon or parentheses for method calls,

02:35.000 --> 02:39.000
and then you get back data structure.

02:39.000 --> 02:41.000
Now let's use leaflet.

02:41.000 --> 02:43.000
Also pretty simple.

02:43.000 --> 02:47.000
We say use map leaflet and make a map object like that.

02:47.000 --> 02:49.000
And then we have a little for loop here.

02:49.000 --> 02:52.000
And if you look closely, you might notice that something's missing

02:52.000 --> 02:55.000
from the for loop, a variable.

02:55.000 --> 02:57.000
We have an implicit variable.

02:57.000 --> 02:59.000
It's called the topic variable.

02:59.000 --> 03:00.000
It's called its dollar underscore.

03:00.000 --> 03:01.000
It's implied.

03:01.000 --> 03:03.000
So this is actually iterating through a list,

03:03.000 --> 03:06.000
and then it's extracting latitude and longitude

03:06.000 --> 03:10.000
from the elements of the hashes in the list.

03:10.000 --> 03:13.000
Okay, let's talk about bounding boxes.

03:13.000 --> 03:15.000
B bounding boxes can be kind of annoying

03:15.000 --> 03:18.000
because you never know which order the numbers are in.

03:18.000 --> 03:22.000
And so here's an example where we get the bounding box

03:22.000 --> 03:25.000
from the OSM response, and we get four numbers,

03:25.000 --> 03:28.000
but what we really want is two coordinate pairs.

03:28.000 --> 03:31.000
We can make those coordinate pairs with this slice syntax,

03:31.000 --> 03:35.000
which you can not only reorder the elements in your list,

03:35.000 --> 03:37.000
but you can also restructure them.

03:37.000 --> 03:40.000
So if you put a nested data structure within your brackets,

03:40.000 --> 03:43.000
you get back a nested data structure.

03:43.000 --> 03:47.000
So this takes the bounding box and turns it into two coordinates.

03:47.000 --> 03:54.000
So in the map leaflet project,

03:54.000 --> 03:58.000
we're basically mimicking all of the class hierarchies

03:58.000 --> 04:00.000
that are found on the JavaScript side.

04:00.000 --> 04:02.000
So all the attributes you have inheritance,

04:02.000 --> 04:04.000
just like you do in leaflet.

04:04.000 --> 04:07.000
The only difference is that we also have gradual typing in Raku.

04:07.000 --> 04:11.000
So we have a numeric type and a string type and a Boolean type.

04:11.000 --> 04:14.000
So that will give you a little bit more to work with

04:14.000 --> 04:18.000
to enforce some type constraints on your code.

04:18.000 --> 04:20.000
Okay, here's the AI.

04:20.000 --> 04:24.000
So let's draw a line from Philadelphia to Brussels.

04:24.000 --> 04:27.000
You can use LLM-DWIM, which stands for a do what I mean.

04:27.000 --> 04:31.000
You can configure it to use your large language model of choice.

04:31.000 --> 04:33.000
Put that string in.

04:33.000 --> 04:37.000
The at JSON gets expanded to a prompt that tells the LLM,

04:37.000 --> 04:39.000
please write everything as JSON.

04:39.000 --> 04:42.000
It's over and over again, so there really makes it into JSON.

04:43.000 --> 04:45.000
And then M. Show, and you can run this.

04:45.000 --> 04:50.000
So if you lines long, it will actually generate a line on your map.

04:50.000 --> 04:52.000
Overpass, anybody use overpass?

04:52.000 --> 04:53.000
Okay, cool.

04:53.000 --> 04:55.000
So it's got its own language.

04:55.000 --> 04:58.000
You do the same thing, use web service overpass,

04:58.000 --> 05:00.000
OP, and then you can send statements to it,

05:00.000 --> 05:03.000
get back JSON or XML.

05:03.000 --> 05:08.000
So here's, so if you thought bounding boxes were annoying,

05:08.000 --> 05:10.000
let's talk about coordinates.

05:11.000 --> 05:15.000
So for multi polygon, you have an array of polygons,

05:15.000 --> 05:19.000
where each polygon is an array of linear rings.

05:19.000 --> 05:22.000
Each linear ring is an array of coordinates.

05:22.000 --> 05:26.000
Each coordinate is an array of decimals.

05:26.000 --> 05:29.000
Okay, so you start off with this.

05:29.000 --> 05:32.000
GeoJSON, but what you really want to send it to overpass

05:32.000 --> 05:35.000
is also the latitude and longitude of switch.

05:35.000 --> 05:38.000
So you need to flatten them, and then you need to make a string

05:38.000 --> 05:39.000
and then concatenate them.

05:39.000 --> 05:42.000
Okay, so this is pretty easy.

05:42.000 --> 05:45.000
Again, the slides will be available afterwards,

05:45.000 --> 05:48.000
but essentially there are some very,

05:48.000 --> 05:51.000
there are some tourist constructs that you can use

05:51.000 --> 05:56.000
in order to, for instance, extract a vector from a multi-dimensional array.

05:56.000 --> 06:01.000
You can also call the double arrows or a hyperoperator,

06:01.000 --> 06:02.000
which is like map.

06:02.000 --> 06:05.000
It operates on every element of the array.

06:05.000 --> 06:07.000
You say array hyper dot reverse.

06:07.000 --> 06:09.000
It flips the coordinate pairs for you.

06:09.000 --> 06:11.000
You're getting your latitude and longitude in the right order.

06:11.000 --> 06:14.000
And finally, the star star at the end,

06:14.000 --> 06:16.000
you're familiar with list flattening,

06:16.000 --> 06:18.000
but what if you have a really nested structure,

06:18.000 --> 06:21.000
you want to not just flatten a little, but flatten everything?

06:21.000 --> 06:23.000
So we call that bulldozing.

06:23.000 --> 06:26.000
And the double star in a row will flatten everything out,

06:26.000 --> 06:29.000
so you have polygons that you can send to your query.

06:29.000 --> 06:31.000
And so this is the end result.

06:31.000 --> 06:34.000
This gets all the OSM nodes on the U.O.B campus.

06:34.000 --> 06:36.000
I'm going to go a little faster here.

06:36.000 --> 06:38.000
I get through the rest.

06:38.000 --> 06:40.000
Does this building look familiar?

06:40.000 --> 06:43.000
Okay, so this is the building that we're in right now.

06:43.000 --> 06:45.000
It actually has an inner linear ring,

06:45.000 --> 06:48.000
which I discovered when I was making the slides.

06:48.000 --> 06:52.000
And deck GL is very nice.

06:52.000 --> 06:53.000
Anybody use deck GL.

06:53.000 --> 06:57.000
Very nice library for rendering things in 3D.

06:57.000 --> 07:02.000
If you pass a little bit of JavaScript to one of your attributes,

07:02.000 --> 07:07.000
then you can compute the height, and you can conditionally color it.

07:07.000 --> 07:11.000
So it's pretty straightforward.

07:11.000 --> 07:16.000
The previous code will render all the buildings on the U.O.B campus in 3D.

07:16.000 --> 07:18.000
So it's pretty handy.

07:18.000 --> 07:21.000
And let's go through a few things about analysis,

07:21.000 --> 07:22.000
really quickly.

07:22.000 --> 07:24.000
Anybody use deck TV?

07:24.000 --> 07:26.000
Okay, also great.

07:26.000 --> 07:28.000
It's geospatial tool.

07:28.000 --> 07:30.000
You can use duct TV from Raku.

07:30.000 --> 07:32.000
You say it's called Duckie.

07:32.000 --> 07:33.000
You say use Duckie.

07:33.000 --> 07:35.000
And then D will give you an object.

07:35.000 --> 07:38.000
And then you can say D dot query.

07:38.000 --> 07:40.000
You can set an SQL back.

07:40.000 --> 07:42.000
And then you get your rows.

07:42.000 --> 07:44.000
It's also column oriented.

07:44.000 --> 07:47.000
So you can just extract a column from your results set.

07:47.000 --> 07:50.000
It's got really great spatial features.

07:50.000 --> 07:54.000
So let's look at another example here.

07:54.000 --> 07:58.000
Again, on the U.O.B campus, we get the campus in a G.O.J.

07:58.000 --> 07:59.000
Sun file.

07:59.000 --> 08:03.000
You can actually query the G.O.J. Sun file from DuckDB.

08:03.000 --> 08:05.000
And then you can use all these spatial operators

08:05.000 --> 08:12.000
to basically calculate the square meters for every building on campus and sort.

08:12.000 --> 08:15.000
But if you don't want to use DuckDB,

08:15.000 --> 08:21.000
you can also use the underlying library geos directly.

08:21.000 --> 08:22.000
Anybody use geos?

08:22.000 --> 08:23.000
Any chance?

08:23.000 --> 08:24.000
Okay.

08:24.000 --> 08:30.000
So geos, amazing library has a C plus plus API.

08:30.000 --> 08:35.000
And Raku supports the native call interface.

08:35.000 --> 08:38.000
Basically bindings to that API.

08:38.000 --> 08:44.000
So here's an example of loading some WKT data into an object.

08:44.000 --> 08:45.000
That's dollar point.

08:45.000 --> 08:47.000
And then looking at the X.

08:48.000 --> 08:53.000
And you can see it gets the type of the geometry.

08:53.000 --> 08:57.000
Here's a little bit of a bigger example.

08:57.000 --> 09:04.000
So in this case, we're getting all of the points on the polygon

09:04.000 --> 09:07.000
that are surrounding the city of Brussels.

09:07.000 --> 09:12.000
And then we're trying to find the two points that are farthest apart from each other.

09:12.000 --> 09:17.000
So not super complicated, but just complicated enough that it takes a few seconds.

09:17.000 --> 09:21.000
And so here's an example of how to do that.

09:21.000 --> 09:27.000
You can call at points.commonations of two to get all the pairs of points.

09:27.000 --> 09:31.000
And then you can find all the distances just by doing, you know,

09:31.000 --> 09:34.000
node pairs dot map, A dot distance to B.

09:34.000 --> 09:38.000
But what's also nice is that if you have a lot of CPUs,

09:38.000 --> 09:43.000
and you're doing a lot of points, then you might want to use all your CPUs

09:43.000 --> 09:45.000
and do this in parallel.

09:45.000 --> 09:47.000
So to do that, you just add this word hyper.

09:47.000 --> 09:51.000
And hyper takes your sequence and turns it into a hyper sequence

09:51.000 --> 09:54.000
and fans it out across all of your threads,

09:54.000 --> 09:57.000
multi-threaded and multi core operations.

09:57.000 --> 10:00.000
You can send parameters like the batch size and the degree.

10:00.000 --> 10:05.000
And there's another similar one if you want to preserve the order.

10:06.000 --> 10:09.000
Okay, so that was a quick intro to Raku.

10:09.000 --> 10:10.000
How you might like to use it.

10:10.000 --> 10:12.000
We saw some useful modules.

10:12.000 --> 10:15.000
We saw gradual typing, hash and list slices.

10:15.000 --> 10:18.000
We saw some class hierarchies generated JavaScript.

10:18.000 --> 10:21.000
We were able to call C using native call.

10:21.000 --> 10:24.000
We did some parallel operations.

10:24.000 --> 10:28.000
So it's pretty good for like what looks like a scripting language.

10:28.000 --> 10:30.000
It's got a lot of stuff going on.

10:30.000 --> 10:34.000
There's a lot more stuff that I didn't cover, including all the different ways

10:34.000 --> 10:37.000
to run external processes, connect with the standard in,

10:37.000 --> 10:38.000
or standard out.

10:38.000 --> 10:40.000
There's a lot, by the way, the coordinates that we loaded.

10:40.000 --> 10:42.000
Those were actually rational numbers.

10:42.000 --> 10:45.000
So you can do precise rational arithmetic on them.

10:45.000 --> 10:49.000
0.01 plus 0.02 is actually equal to 0.03.

10:49.000 --> 10:52.000
But you can also do floats.

10:52.000 --> 10:55.000
And in the final example with GOS, we're actually using native types.

10:55.000 --> 10:57.000
Those are doubles that take up 64 bits.

10:57.000 --> 10:59.000
So you can do anything in between.

10:59.000 --> 11:02.000
And there's a lot more concurrency besides just,

11:02.000 --> 11:05.000
besides hyper.

11:05.000 --> 11:06.000
So that's it.

11:06.000 --> 11:09.000
And there's also grammars, which is a topic for another day.

11:09.000 --> 11:12.000
If you are interested in learning more or want to chat with us,

11:12.000 --> 11:16.000
come stop by the Pro and Rockus stand and visit the website,

11:16.000 --> 11:17.000
Rockus.org.

11:17.000 --> 11:18.000
Thank you very much.

11:18.000 --> 11:25.000
Good.

11:25.000 --> 11:26.000
Good.

11:26.000 --> 11:27.000
Good.

11:27.000 --> 11:28.000
Time for a question?

11:28.000 --> 11:29.000
One question.

11:33.000 --> 11:35.000
Is it faster?

11:35.000 --> 11:39.000
You know, fast depends on the problem that you're trying to solve.

11:39.000 --> 11:44.000
So if you're using, it has support for concurrency.

11:44.000 --> 11:47.000
So those operations that are using like the GOS,

11:47.000 --> 11:50.000
the limiting factor that is going to be the GOS operations.

11:50.000 --> 11:52.000
But otherwise, there's definitely,

11:52.000 --> 11:55.000
there's a little bit of overhead for sure.

11:55.000 --> 11:57.000
All right.

