WEBVTT

00:00.000 --> 00:10.240
Fair while now, or alternatively have been kicking outside, so yeah, thanks for making

00:10.240 --> 00:16.760
the effort. I do appreciate that. Bit about me, so my name is James Milner. I'm a staff

00:16.760 --> 00:23.160
software engineer at a company called Nearform. I live in London, working remotely. Nearforms

00:23.160 --> 00:27.760
like a digital consultancy has a big history and opensource specifically in the kind of

00:27.760 --> 00:34.680
like Node.js ecosystem, and yeah, this is my territory as my personal project, but they're

00:34.680 --> 00:40.280
very supportive and they've helped me to come here today, so yeah, shout out to them.

00:40.280 --> 00:46.360
So, let's get started. What is territory? So, territory is an open source JavaScript

00:46.360 --> 00:52.760
library for drawing on web maps. So, the source is MIT license, and yeah, it's a JavaScript

00:52.760 --> 00:58.520
library, so it runs in the front end, in your browser, alongside your map, in your front end

00:58.520 --> 01:06.080
code, and it's for drawing on web maps. So, drawing is maybe a bit of a loaded term, or

01:06.080 --> 01:11.400
a loaded concept, so sometimes I think it just helps to have a tangible example to point

01:11.400 --> 01:17.800
to. So, the one that I give is, if in the UK, we have two companies, Zootpler, right

01:17.800 --> 01:23.480
move, they might also be present in other parts of Europe and beyond, but essentially

01:23.480 --> 01:28.880
their property search websites, so you can go to these websites, you can type in what

01:28.880 --> 01:34.120
you're looking for, you know, number of bedrooms or the location, and you can find places

01:34.120 --> 01:38.480
to buy or rent. And they also have a tool, both of them have a tool for allowing you to

01:38.480 --> 01:44.600
draw an area of interest on the map, and then only return Polygon, sorry, only return

01:44.600 --> 01:49.680
properties that exist within that Polygon or in that area of interest. So, that's the

01:49.680 --> 01:53.400
kind of thing that I'm talking about when I'm saying drawing on a web map, like Ditchery,

01:53.400 --> 01:59.720
the user, inputting, and drawing on the web map. And there's some prior art here, there's

01:59.720 --> 02:09.560
a few libraries that do this in varying degrees of functionality, and like how up to date,

02:09.560 --> 02:15.440
like how well maintained they are. The one that I was probably the most familiar with before

02:15.440 --> 02:24.840
starting to draw was MapboxGL Draw, which is for MapboxGL.js, a mapping library, and so

02:24.840 --> 02:30.840
in my previous role I was working on indoor mapping, indoor positioning, and we needed

02:30.840 --> 02:38.240
the way to basically create indoor maps, and so I was using MapboxGL Draw, and then after

02:38.240 --> 02:42.640
that company I kind of had some thoughts about like potentially like a different approach,

02:42.640 --> 02:47.680
or another way of kind of structuring like a drawing library, or things that I thought could

02:47.680 --> 02:56.000
potentially be worked on or improved on kind of the pire art. So, the kind of the goals

02:56.000 --> 03:04.240
of Tera Draw are that it's cross library support. So, kind of takes the approach of having

03:04.240 --> 03:08.640
like an adaptor pattern, so there's an adaptor for a bunch of different mapping libraries,

03:08.640 --> 03:14.320
which I'll come on to in more detail in a minute, but 90% of the code is in the core, and then

03:14.320 --> 03:20.640
these adaptors just are kind of like a little like an interstitial bit between the core

03:20.640 --> 03:26.800
territorial library and the mapping library. I wanted it to be customizable, so what I mean by that

03:26.800 --> 03:32.720
is you could create your own complex drawing modes, so people have all sorts of weird and

03:32.720 --> 03:38.240
wonderful requirements, and basically I wanted to be able to allow support for that, and similarly,

03:38.240 --> 03:44.640
if a new mapping library comes along, I wanted to be able to allow to create an adaptor for that

03:44.640 --> 03:50.880
fairly easily. So, yeah, just customizability and extensibility was kind of one of the initial goals.

03:52.080 --> 03:57.440
Keep styling, so basically being able to style every aspect of like the drawing experience,

03:58.160 --> 04:03.440
some of my previous experiences were like, you couldn't get a consistent look and feel,

04:03.440 --> 04:07.920
because you could only style like certain aspects of the drama trees that were being rendered,

04:09.200 --> 04:13.280
and so that was kind of like something that I wanted to support from the outset,

04:13.280 --> 04:18.800
was being able to style kind of everything that's going on in the kind of drawing experience.

04:19.360 --> 04:25.440
And then the last thing is, it was just kind of this approach of like not having any

04:26.320 --> 04:32.160
additional runtime dependencies, not necessarily saying that that's like a better or, you know,

04:32.160 --> 04:37.040
isn't a superior approach, but it was more just like historically I've worked on a lot of projects

04:37.040 --> 04:42.400
where just you try and build something or you try and instill something and something just breaks,

04:42.400 --> 04:47.920
because especially in the like kind of node ecosystem, there's a lot of just like,

04:47.920 --> 04:53.360
you can end up in dependency how, and so just taking that approach kind of simplifies that and

04:53.360 --> 05:04.080
reduces the possibility of having those kind of issues. So there's a bunch of different,

05:04.080 --> 05:09.760
as I was kind of saying, Torrodros supports a bunch of different mapping libraries out the box,

05:09.760 --> 05:16.800
so the the six that are supported in the kind of, I guess, core library of Torrodros. So open there's

05:17.360 --> 05:25.680
leaflet, map lever, jl, js, Google Maps, mapbox, jl, js, and js, maps SDK for JavaScript.

05:27.120 --> 05:32.720
So the top three are open source and the bottom three are like proprietary, but yeah,

05:32.720 --> 05:39.200
so they're support for these these mapping libraries out the box. And as I said, it's possible

05:39.200 --> 05:45.520
if you have your own custom map rendering library, then it should in theory be possible to write

05:45.520 --> 05:53.040
your own adapter, as long as you can fulfill some basic criteria for the like interface for that

05:53.040 --> 06:02.720
adapter. And so it's quite rare, but there are scenarios where that kind of decoupling can be quite

06:02.720 --> 06:08.480
helpful. So say for example, you are using a mapping library and the underpinning services that

06:08.480 --> 06:13.280
power it change their pricing model and it no longer becomes viable for you to, like financially,

06:13.280 --> 06:18.400
it's not possible for you to keep using that library. Having that decoupling can be quite useful.

06:18.400 --> 06:23.440
Similarly, if the license changes for the underlying library and that's no longer compatible with

06:23.440 --> 06:28.720
your business or like your project or whatever you're trying to do, then that is another reason

06:28.720 --> 06:33.280
why you might want to swap that out. And then the other, I guess, more obvious thing is that

06:34.080 --> 06:39.200
different mapping libraries have different limitations or different feature sets. And so if there's

06:39.200 --> 06:44.080
something you need to do and then you realize like two or three years into a project that you

06:44.080 --> 06:51.200
can't do that in that specific mapping library, then just having that decoupling can be potentially

06:51.200 --> 06:57.920
quite useful. So this is the architecture or the kind of a basic overview of the architecture

06:57.920 --> 07:01.840
of Taugeau. So as I was saying, we've kind of got this, these adapters which are the kind of the

07:01.840 --> 07:11.520
Stinlayer at the front. They take in inputs like user input from the user. That goes into

07:11.520 --> 07:15.920
the mode. So there's we have a bunch of different built-in modes for different geometry types. So

07:17.120 --> 07:23.840
point, polygon, line string, circle, rectangle, and then there's some more sort of exotic ones that

07:23.840 --> 07:29.920
I will come onto later. And so these are just the modes and that's contains all the logic for like

07:30.000 --> 07:37.200
handling, you know, drawing those geometry types. And then it's all just backed by what was just

07:37.200 --> 07:42.640
called a store, which is essentially where all the geojson geometries are stored and then retrieved

07:42.640 --> 07:49.520
or and then updated. So yeah, it's just kind of like this three-tier approach, which I think

07:49.520 --> 07:58.640
works quite nicely and kind of isolates things quite nicely. We, there's no runtime dependencies

07:58.640 --> 08:05.280
that we do rely on a bunch of other open source tools for a lot of the development time functionality.

08:05.280 --> 08:12.080
So it's the whole library is written more or less exclusively in TypeScript. I just like types and I

08:12.080 --> 08:16.160
think it's kind of become a maybe a bit of an industry standard on JavaScript projects now.

08:18.400 --> 08:22.880
We use just, which is potentially maybe going like a little bit of fashion. It's the tick testing

08:22.960 --> 08:29.600
library. But for me, it works and has been relatively popular and people understand how it works.

08:30.560 --> 08:36.240
So that was kind of the choice there. Webpack for local development. So there's like a local

08:36.240 --> 08:40.160
environment where you can just experiment with all the different drawing modes and all the different

08:43.280 --> 08:48.320
adapters locally if you just want to like change something and play around with things. Then

08:48.320 --> 08:54.160
that all is backed by like webpack just bundles at all and makes it all possible. And then lastly,

08:54.160 --> 08:59.360
use a thing called micro bundle, which is quite a niche project, but I find it really useful. It's just

08:59.360 --> 09:04.480
for like it does the actual, it creates the actual end bundle that gets put onto NPM, like the

09:04.480 --> 09:11.600
node package manager. But it just sorts out a lot of the complicated aspects of like delivering

09:12.320 --> 09:18.400
like a JavaScript package on NPM essentially. So that's why we use that.

09:20.800 --> 09:25.760
Let's have a little look at like how you can get started with Todoror. So the simplest thing

09:26.800 --> 09:33.600
probably is, well, if you have an existing project, you can use NPM to install Todoror into your project

09:34.400 --> 09:39.440
just NPM install Todoror. You also need an adaptor, which will be like a separate package,

09:39.440 --> 09:44.320
which I'll show you how you install those different adapters later on, but the core library is just

09:44.320 --> 09:51.040
Todoror, or you can use yarn or like other node JavaScript package managers if you want,

09:51.040 --> 09:57.920
does you know, whichever one you're using is fine. The actual project is available at my

09:57.920 --> 10:04.640
GitHub handle, which is James Elmone, a four-slash Todoror. There's docs in there, there's API documentation,

10:05.280 --> 10:11.920
the whole project basically lives in there. And then lastly, there's websites, just Todoror.io.

10:12.960 --> 10:20.000
Looks a little something like this, but it's essentially quite similar to, if you've ever used

10:20.000 --> 10:27.120
GiaJson.io, kind of a fairly comparable sort of set of functionality, but helps just demonstrate

10:28.000 --> 10:37.520
how Todoror would work in like an end project. So at the top is like the bunch, the different modes,

10:37.520 --> 10:43.440
and then the geometries that you're seeing on the screen are the output of like using those modes.

10:43.440 --> 10:48.080
There's also some other modes that we a bit more like are saying a bit more exotic, that aren't

10:48.080 --> 10:53.600
like on here that will come onto later, but it's just showing you the basic functionality of like

10:53.600 --> 10:58.240
point line polygon. We have like a free hand mode if you want to draw like a free hand polygon.

10:59.760 --> 11:04.080
Yeah, so that's, and that's just something you can just, if you just want to get a high level

11:04.080 --> 11:08.720
sense of like what Todoror does, you can just go on that website and just play around with it.

11:12.800 --> 11:20.400
And then at like a code level, this is just an example using map Libra. So lines one to six,

11:20.400 --> 11:29.440
we're just instantiating a map Libra map, give it like a center, some styling, give it a specific zoom

11:29.440 --> 11:36.240
level, that instantiates the map. And then once that's finished loading, then we can instantiate Todoror.

11:36.240 --> 11:42.160
So we start a new Todoror instance, we give it an adaptor in this case the map Libra adaptor,

11:43.200 --> 11:47.520
and then we just give it an array of all the modes that we want to instantiate with. So in this case

11:47.680 --> 11:54.160
on line 11, we just instantiate like just to keep things simple, simple, we just instantiate

11:54.160 --> 12:00.960
polygon mode. And that will, in this case, we just have snapping, which is like a piece of functionality

12:00.960 --> 12:06.080
that we support, so you know, snapping to whilst you're drawing, snapping to other polygon

12:06.080 --> 12:13.120
vertices that you've drawn. And then the end we just start the whole instance and that kicks everything

12:13.840 --> 12:22.800
off. That's like a simplified version of what that looks like, but it's hard to, you know,

12:22.800 --> 12:30.720
fit too much code on one slide, so hopefully you'll forgive me. So the project's been going for

12:30.720 --> 12:36.480
about two and just over two and a half years, and all of that time it's kind of been in alpha

12:37.200 --> 12:41.920
and then beta. It's kind of just for a long time like tinkering with a lot of stuff and just trying

12:42.800 --> 12:48.400
to get things right. So this month we finally just released like a version one and that kind of

12:48.400 --> 12:55.920
like solidifies the foundation for the kind of the future of the project and hopefully like give some

12:55.920 --> 13:02.560
signal to other people that it's like you can rely on it to some extent to in your projects.

13:03.200 --> 13:12.400
And so like one of the big changes in version one is essentially previously all the adapters

13:12.400 --> 13:19.040
were like baked into the core territorial module or the core territorial package sorry.

13:21.040 --> 13:26.480
But that has like some that was essentially causing issues for certain people things like

13:27.280 --> 13:33.600
um type script types or like missing for like somebody would be using I don't know if the

13:33.600 --> 13:38.080
leaflet adapter and they'd be getting complaints about like missing type script types for like the open

13:38.080 --> 13:43.920
layers adapter and it's like well that person doesn't care about open layers like they shouldn't

13:43.920 --> 13:48.400
have to, right? So it's basically like the thought process was just to basically terrible with that

13:48.400 --> 13:54.880
out and then just have a module per adapter. And so now you just install the adapter with the

13:54.880 --> 13:58.960
map library that you're using and then you install the territorial on side that and then you can just

13:58.960 --> 14:07.600
use those those two together um yeah it also just helps like in or enforce like decoupling between

14:07.600 --> 14:16.960
the adapters and territorial itself um which is a nice side effect I think um the other thing was like

14:16.960 --> 14:21.760
I was saying earlier about this kind of a bit more like exotic mode can I use this laser yes I can

14:22.400 --> 14:28.480
um and so there's a few extra modes that have just come in and like recently so one of them is

14:28.480 --> 14:33.840
uh this is set to mode which is a bit like allows you to draw like a sector of a circle basically like

14:33.840 --> 14:40.640
like you know a control like a semi circle um and then also sense mode which is similar like

14:40.640 --> 14:47.520
kind of the same premise but like a doughnut so you control like a doughnut essentially um and these

14:47.600 --> 14:55.440
two are kind of actually requested on the basis of like um this was for like uh there's uh one of

14:55.440 --> 14:59.760
the guys who's using the project are like mountain rescue and one of the things that they do is like

14:59.760 --> 15:06.560
they want to know they have like various uh CCTV cameras that have like certain field of view like

15:07.120 --> 15:12.400
vision and so basically they can draw out and say like the field of view of a given camera

15:13.040 --> 15:19.760
in the in the mountains basically um and so this basically helps the map out so it sounds quite

15:19.760 --> 15:23.200
niche and like why would you have any of that but so I just wanted to kind of try and give some reasoning

15:23.200 --> 15:28.000
whether um so they use it for that essentially which is quite cool and the last one is uh

15:29.200 --> 15:33.680
those are the diamond bits actually we call this like angled rectangle mode so tarot draw for long

15:33.680 --> 15:41.360
time has had like a rectangle mode where you can draw a rectangle but it's always oriented from like

15:41.440 --> 15:46.800
north um like because the map is generally oriented north unless you've like rotated it or something

15:48.080 --> 15:55.120
and so angled rectangle mode just allows you to draw like a rectangle or any like arbitrary

15:55.120 --> 16:00.480
orientation essentially um so that's just like another mode that there's kind of now baked into

16:00.480 --> 16:06.400
total and yeah as we're saying like there's also opportunity to build your own custom modes if you

16:06.400 --> 16:12.400
want to do kind of weird and wacky things so I've built some modes for like doing um

16:13.440 --> 16:19.680
client side routing so if you have like a complex so you could use if for example the example I

16:19.680 --> 16:26.400
had was like basically just converted a bunch of OSN roads data into geojson and then was basically

16:26.400 --> 16:32.240
just doing like clients allowing you to draw out client side roots using tarot draw as like a

16:32.240 --> 16:40.800
kind of custom mode and then another example was like using the um there's a there's a model

16:40.800 --> 16:46.800
called like segment anything model which like matter released which is can basically like pull out

16:47.360 --> 16:52.080
features essentially from like an image and so then using that to like being able to like pull out

16:52.080 --> 16:56.000
you could click on a building and it would generate the like polygon for the building essentially

16:56.640 --> 17:03.600
again it's like a kind of custom mode integral um so yeah that's uh new modes and then at custom modes

17:06.480 --> 17:15.280
also some like uh new kind of additions to uh configuration of existing modes that were potentially

17:15.280 --> 17:19.760
quite interesting so one of them is like called like validation and so validation is basically

17:20.320 --> 17:27.920
sometimes you want to prohibit users from creating polygons or points or like any kind of geometry

17:27.920 --> 17:35.920
that doesn't add here to some sort of like uh like validity rules or best practice or whatever it

17:35.920 --> 17:40.320
might be so in this case it's about like you don't want to have a polygon that's self intersecting

17:41.040 --> 17:47.040
there's various reasons why you probably wouldn't want self intersecting polygons in your like

17:47.040 --> 17:52.400
database or whatever it might be um but you can actually like this is just free form so you could

17:52.400 --> 17:58.480
essentially just do anything in here and this just allows you to prevent creating data that you feel is

18:00.160 --> 18:07.040
invalid essentially um and then the next one is about like snapping so

18:07.040 --> 18:11.360
total support is snapping for a little while but there's kind of been some improvements to

18:11.680 --> 18:17.280
um kind of how that works so like one of the nice things is you've always been able to snap to

18:17.920 --> 18:25.760
the um coordinates of a polygon so like the vertices of a polygon so for example like

18:25.760 --> 18:32.080
basically the corners here um but now we also just support snapping to like an arbitrary

18:32.640 --> 18:37.840
place on any of the lines of the polygon as well um so for example here this is just snap to like

18:38.720 --> 18:44.880
somewhere along this line here essentially um and so a lot of people find that useful um so

18:45.840 --> 18:53.920
that's something that we added support for um the other thing that we've kind of been working on

18:54.400 --> 18:59.200
it's it's tricky I wouldn't say it's perfect but it's at least kind of like the foundation for

18:59.280 --> 19:06.080
supporting like drawing on essentially like globes um which basically just requires you to um

19:08.240 --> 19:12.320
like when you're drawing on a web Macator map and you draw a square or a circle or whatever it

19:12.320 --> 19:19.920
might be when you actually place that on a globe because like you if you yeah it's this

19:20.960 --> 19:25.840
you end up with a scenario where like it's no longer circular it's no longer rectangular because when

19:25.920 --> 19:31.360
you project like something that's been drawn on a 2D web Macator map onto a globe it loses the

19:31.360 --> 19:36.400
property of being circular or a rectangular and vice versa if you draw a circle on a globe

19:36.400 --> 19:43.040
and you project it down onto a map it's going to look like more like an oval basically um and so

19:43.040 --> 19:52.560
now tarot draw has basic support in its modes for um drawing on on globe essentially but yeah

19:52.640 --> 20:01.200
it's not perfect but we're working on it community um so we've been really lucky to have like quite a few

20:01.200 --> 20:08.720
people uh getting involved so we've had 24 unique contributors over the last two and a half years

20:09.840 --> 20:16.000
there's 48 this is just some data I just pulled out of like GitHub insights but there's 48

20:16.880 --> 20:23.600
repositories that depending on it um 590 stars yeah obviously it's a bit of a vanity metric but

20:23.600 --> 20:28.800
it's just always nice to see people taking an interest in something you're working on and similarly

20:28.800 --> 20:36.000
64 forks again just nice to see people checking out the code um but yeah if you want to get involved

20:37.200 --> 20:44.000
appreciate like any feedback you might have either on this talk or the um on any of the functionality

20:44.080 --> 20:49.920
of tarot draw itself I feel free to just you know you can kind of speak to me afterwards um or

20:51.360 --> 20:56.000
yeah feel free to write an issue on GitHub if you find bugs or you find there's a feature that you

20:56.000 --> 21:01.280
feel is missing um yeah feel free to share it if you know people that might benefit from using

21:01.280 --> 21:08.400
the project and yeah obviously we always welcome contributors um to tarot draw itself so please

21:08.400 --> 21:13.760
feel free to check out the code um start hacking around and if there's something that you feel

21:13.760 --> 21:24.400
like you could fix then I've just encouraged you to have a go um yeah I think that's me thanks

21:32.400 --> 21:34.400
questions

21:35.360 --> 21:56.000
yeah at the moment it only supports um 2D and well there's multiple reasons for that one of

21:56.000 --> 22:01.440
which is the GIAs and specification only supports two dimensional data by default I think

22:01.760 --> 22:08.800
um so it would be because it all backed the like the whole store concept is like everything is stored

22:08.800 --> 22:15.200
in GIAs and like everything is exported in GIAs and so you'd have to come up with a way to like

22:15.200 --> 22:23.520
represent that data but that kind of third what is said coordinate it's like you can't do that without

22:23.520 --> 22:28.080
breaking the GIAs and specification really and so you'd have to come up with it like it could be

22:28.080 --> 22:33.440
plot like you could add it as like a property in the property like basically as metadata like that

22:33.440 --> 22:40.400
said property but um yeah by default it doesn't support like three dimensional drawing out the box

22:40.400 --> 23:01.440
yeah so the question was um do you plan on adding support for translating rotating scaling um

23:01.440 --> 23:05.920
so it does actually we do it does actually have support I didn't show it but we do actually have

23:06.000 --> 23:11.920
support for so there's one of the modes is select mode and you can select polygon and then you can then

23:11.920 --> 23:19.200
you can modify all the coordinates but you can also do scaling, rotating and just move like

23:19.200 --> 23:24.720
translation like just moving as well so it does support it but you have to enter like a select mode

23:24.720 --> 23:30.000
select the polygon and then start playing it so yeah thanks there's a great question

23:30.080 --> 23:48.480
yeah sure yeah yeah no it's a good question so the question is do does tarot draw

23:48.480 --> 23:54.400
do the rendering or is it kind of um does it offload it to the mapping library to render the actual

23:54.720 --> 24:01.440
data so yeah as I'm saying all the data is in um geojson and so essentially what happens is

24:01.440 --> 24:10.000
is each of the adapters has a way to render geojson data via the underlying library so if you use

24:10.000 --> 24:17.680
like leaflet it will use the leaflet method for like rendering geojson um so yeah it's offloaded

24:17.680 --> 24:22.720
to the the library itself like we don't overlay like a web jail canvas and start doing stuff

24:22.720 --> 24:39.920
or anything like that no yeah it's really it's a greedy yeah that is really interesting so

24:39.920 --> 24:48.960
the question is about um like styling across multiple different mapping libraries is that

24:48.960 --> 24:55.200
like a good summary yeah they're like how do you so the the the the the answer is um it's actually

24:55.200 --> 24:59.680
like it's quite fortunate really because a lot of the mapping libraries actually have quite

24:59.680 --> 25:04.880
similar levels of functionality so you can generally feel like the basic styling you can

25:05.520 --> 25:11.680
style consistently across like all the different mapping libraries quite like relatively easily

25:11.680 --> 25:16.720
it gets more complicated when you do like more obviously like more complex styling so if you have

25:16.800 --> 25:23.120
things like like one example is that I've we've wanted to do for ages is like dashed lines

25:23.120 --> 25:30.240
and so there's just one it's like for some reason like map map libre doesn't support dashed lines

25:30.240 --> 25:34.880
or it doesn't support dashed lines but it doesn't support like dashed lines that are

25:35.680 --> 25:44.080
based like powered by data if that makes sense so you can dynamically change the how the gaps

25:44.160 --> 25:48.640
between all the dashes and all this kind of stuff so um yeah you're kind of the problem is

25:48.640 --> 25:54.080
like one of the side effects of um supporting all the libraries is you're kind of tied to like

25:54.080 --> 25:58.720
the lowest common denominator if that makes sense because you have to you can't just add support

25:58.720 --> 26:03.680
for like things that the other libraries don't also support so yeah it's a bit of a problem but

26:03.680 --> 26:09.680
seems to work okay for the basic stuff yeah

26:14.320 --> 26:30.480
I missed the like first part of the question so with snapping like how much can you

26:30.480 --> 26:37.040
the questions like how much can you configure it so yeah good question so you can do

26:37.840 --> 26:43.120
coordinate snapping so that's a snapping to the vertices of like other let's say like polygons

26:43.200 --> 26:47.840
that you're you've drawn you can snap to the line kind of like as I was sharing but there's also

26:47.840 --> 26:53.600
we have a thing called like two custom and so two custom is essentially like a function and then

26:54.400 --> 27:01.600
like it just expects you to return some coordinate so in two custom you could snap to an external

27:01.600 --> 27:06.800
data set or you could snap to let's say or you could snap to like right angles there's an example

27:06.800 --> 27:14.000
like if you just wanted to only draw like right angled polygons and so there is a way to allow

27:14.000 --> 27:18.960
if you really want like really bespoke custom snapping behavior then they have this like two

27:18.960 --> 27:31.520
custom function that allows you to snap to like anything you want basically so two custom is like a

27:31.520 --> 27:37.120
is a feature within terror draw but then if you wanted then it's up to you to decide like

27:37.840 --> 27:45.680
the minutia of like how what you want to snap to basically yeah thanks

