Fair while now, or alternatively have been kicking outside, so yeah, thanks for making
the effort. I do appreciate that. Bit about me, so my name is James Milner. I'm a staff
software engineer at a company called Nearform. I live in London, working remotely. Nearforms
like a digital consultancy has a big history and opensource specifically in the kind of
like Node.js ecosystem, and yeah, this is my territory as my personal project, but they're
very supportive and they've helped me to come here today, so yeah, shout out to them.
So, let's get started. What is territory? So, territory is an open source JavaScript
library for drawing on web maps. So, the source is MIT license, and yeah, it's a JavaScript
library, so it runs in the front end, in your browser, alongside your map, in your front end
code, and it's for drawing on web maps. So, drawing is maybe a bit of a loaded term, or
a loaded concept, so sometimes I think it just helps to have a tangible example to point
to. So, the one that I give is, if in the UK, we have two companies, Zootpler, right
move, they might also be present in other parts of Europe and beyond, but essentially
their property search websites, so you can go to these websites, you can type in what
you're looking for, you know, number of bedrooms or the location, and you can find places
to buy or rent. And they also have a tool, both of them have a tool for allowing you to
draw an area of interest on the map, and then only return Polygon, sorry, only return
properties that exist within that Polygon or in that area of interest. So, that's the
kind of thing that I'm talking about when I'm saying drawing on a web map, like Ditchery,
the user, inputting, and drawing on the web map. And there's some prior art here, there's
a few libraries that do this in varying degrees of functionality, and like how up to date,
like how well maintained they are. The one that I was probably the most familiar with before
starting to draw was MapboxGL Draw, which is for MapboxGL.js, a mapping library, and so
in my previous role I was working on indoor mapping, indoor positioning, and we needed
the way to basically create indoor maps, and so I was using MapboxGL Draw, and then after
that company I kind of had some thoughts about like potentially like a different approach,
or another way of kind of structuring like a drawing library, or things that I thought could
potentially be worked on or improved on kind of the pire art. So, the kind of the goals
of Tera Draw are that it's cross library support. So, kind of takes the approach of having
like an adaptor pattern, so there's an adaptor for a bunch of different mapping libraries,
which I'll come on to in more detail in a minute, but 90% of the code is in the core, and then
these adaptors just are kind of like a little like an interstitial bit between the core
territorial library and the mapping library. I wanted it to be customizable, so what I mean by that
is you could create your own complex drawing modes, so people have all sorts of weird and
wonderful requirements, and basically I wanted to be able to allow support for that, and similarly,
if a new mapping library comes along, I wanted to be able to allow to create an adaptor for that
fairly easily. So, yeah, just customizability and extensibility was kind of one of the initial goals.
Keep styling, so basically being able to style every aspect of like the drawing experience,
some of my previous experiences were like, you couldn't get a consistent look and feel,
because you could only style like certain aspects of the drama trees that were being rendered,
and so that was kind of like something that I wanted to support from the outset,
was being able to style kind of everything that's going on in the kind of drawing experience.
And then the last thing is, it was just kind of this approach of like not having any
additional runtime dependencies, not necessarily saying that that's like a better or, you know,
isn't a superior approach, but it was more just like historically I've worked on a lot of projects
where just you try and build something or you try and instill something and something just breaks,
because especially in the like kind of node ecosystem, there's a lot of just like,
you can end up in dependency how, and so just taking that approach kind of simplifies that and
reduces the possibility of having those kind of issues. So there's a bunch of different,
as I was kind of saying, Torrodros supports a bunch of different mapping libraries out the box,
so the the six that are supported in the kind of, I guess, core library of Torrodros. So open there's
leaflet, map lever, jl, js, Google Maps, mapbox, jl, js, and js, maps SDK for JavaScript.
So the top three are open source and the bottom three are like proprietary, but yeah,
so they're support for these these mapping libraries out the box. And as I said, it's possible
if you have your own custom map rendering library, then it should in theory be possible to write
your own adapter, as long as you can fulfill some basic criteria for the like interface for that
adapter. And so it's quite rare, but there are scenarios where that kind of decoupling can be quite
helpful. So say for example, you are using a mapping library and the underpinning services that
power it change their pricing model and it no longer becomes viable for you to, like financially,
it's not possible for you to keep using that library. Having that decoupling can be quite useful.
Similarly, if the license changes for the underlying library and that's no longer compatible with
your business or like your project or whatever you're trying to do, then that is another reason
why you might want to swap that out. And then the other, I guess, more obvious thing is that
different mapping libraries have different limitations or different feature sets. And so if there's
something you need to do and then you realize like two or three years into a project that you
can't do that in that specific mapping library, then just having that decoupling can be potentially
quite useful. So this is the architecture or the kind of a basic overview of the architecture
of Taugeau. So as I was saying, we've kind of got this, these adapters which are the kind of the
Stinlayer at the front. They take in inputs like user input from the user. That goes into
the mode. So there's we have a bunch of different built-in modes for different geometry types. So
point, polygon, line string, circle, rectangle, and then there's some more sort of exotic ones that
I will come onto later. And so these are just the modes and that's contains all the logic for like
handling, you know, drawing those geometry types. And then it's all just backed by what was just
called a store, which is essentially where all the geojson geometries are stored and then retrieved
or and then updated. So yeah, it's just kind of like this three-tier approach, which I think
works quite nicely and kind of isolates things quite nicely. We, there's no runtime dependencies
that we do rely on a bunch of other open source tools for a lot of the development time functionality.
So it's the whole library is written more or less exclusively in TypeScript. I just like types and I
think it's kind of become a maybe a bit of an industry standard on JavaScript projects now.
We use just, which is potentially maybe going like a little bit of fashion. It's the tick testing
library. But for me, it works and has been relatively popular and people understand how it works.
So that was kind of the choice there. Webpack for local development. So there's like a local
environment where you can just experiment with all the different drawing modes and all the different
adapters locally if you just want to like change something and play around with things. Then
that all is backed by like webpack just bundles at all and makes it all possible. And then lastly,
use a thing called micro bundle, which is quite a niche project, but I find it really useful. It's just
for like it does the actual, it creates the actual end bundle that gets put onto NPM, like the
node package manager. But it just sorts out a lot of the complicated aspects of like delivering
like a JavaScript package on NPM essentially. So that's why we use that.
Let's have a little look at like how you can get started with Todoror. So the simplest thing
probably is, well, if you have an existing project, you can use NPM to install Todoror into your project
just NPM install Todoror. You also need an adaptor, which will be like a separate package,
which I'll show you how you install those different adapters later on, but the core library is just
Todoror, or you can use yarn or like other node JavaScript package managers if you want,
does you know, whichever one you're using is fine. The actual project is available at my
GitHub handle, which is James Elmone, a four-slash Todoror. There's docs in there, there's API documentation,
the whole project basically lives in there. And then lastly, there's websites, just Todoror.io.
Looks a little something like this, but it's essentially quite similar to, if you've ever used
GiaJson.io, kind of a fairly comparable sort of set of functionality, but helps just demonstrate
how Todoror would work in like an end project. So at the top is like the bunch, the different modes,
and then the geometries that you're seeing on the screen are the output of like using those modes.
There's also some other modes that we a bit more like are saying a bit more exotic, that aren't
like on here that will come onto later, but it's just showing you the basic functionality of like
point line polygon. We have like a free hand mode if you want to draw like a free hand polygon.
Yeah, so that's, and that's just something you can just, if you just want to get a high level
sense of like what Todoror does, you can just go on that website and just play around with it.
And then at like a code level, this is just an example using map Libra. So lines one to six,
we're just instantiating a map Libra map, give it like a center, some styling, give it a specific zoom
level, that instantiates the map. And then once that's finished loading, then we can instantiate Todoror.
So we start a new Todoror instance, we give it an adaptor in this case the map Libra adaptor,
and then we just give it an array of all the modes that we want to instantiate with. So in this case
on line 11, we just instantiate like just to keep things simple, simple, we just instantiate
polygon mode. And that will, in this case, we just have snapping, which is like a piece of functionality
that we support, so you know, snapping to whilst you're drawing, snapping to other polygon
vertices that you've drawn. And then the end we just start the whole instance and that kicks everything
off. That's like a simplified version of what that looks like, but it's hard to, you know,
fit too much code on one slide, so hopefully you'll forgive me. So the project's been going for
about two and just over two and a half years, and all of that time it's kind of been in alpha
and then beta. It's kind of just for a long time like tinkering with a lot of stuff and just trying
to get things right. So this month we finally just released like a version one and that kind of
like solidifies the foundation for the kind of the future of the project and hopefully like give some
signal to other people that it's like you can rely on it to some extent to in your projects.
And so like one of the big changes in version one is essentially previously all the adapters
were like baked into the core territorial module or the core territorial package sorry.
But that has like some that was essentially causing issues for certain people things like
um type script types or like missing for like somebody would be using I don't know if the
leaflet adapter and they'd be getting complaints about like missing type script types for like the open
layers adapter and it's like well that person doesn't care about open layers like they shouldn't
have to, right? So it's basically like the thought process was just to basically terrible with that
out and then just have a module per adapter. And so now you just install the adapter with the
map library that you're using and then you install the territorial on side that and then you can just
use those those two together um yeah it also just helps like in or enforce like decoupling between
the adapters and territorial itself um which is a nice side effect I think um the other thing was like
I was saying earlier about this kind of a bit more like exotic mode can I use this laser yes I can
um and so there's a few extra modes that have just come in and like recently so one of them is
uh this is set to mode which is a bit like allows you to draw like a sector of a circle basically like
like you know a control like a semi circle um and then also sense mode which is similar like
kind of the same premise but like a doughnut so you control like a doughnut essentially um and these
two are kind of actually requested on the basis of like um this was for like uh there's uh one of
the guys who's using the project are like mountain rescue and one of the things that they do is like
they want to know they have like various uh CCTV cameras that have like certain field of view like
vision and so basically they can draw out and say like the field of view of a given camera
in the in the mountains basically um and so this basically helps the map out so it sounds quite
niche and like why would you have any of that but so I just wanted to kind of try and give some reasoning
whether um so they use it for that essentially which is quite cool and the last one is uh
those are the diamond bits actually we call this like angled rectangle mode so tarot draw for long
time has had like a rectangle mode where you can draw a rectangle but it's always oriented from like
north um like because the map is generally oriented north unless you've like rotated it or something
and so angled rectangle mode just allows you to draw like a rectangle or any like arbitrary
orientation essentially um so that's just like another mode that there's kind of now baked into
total and yeah as we're saying like there's also opportunity to build your own custom modes if you
want to do kind of weird and wacky things so I've built some modes for like doing um
client side routing so if you have like a complex so you could use if for example the example I
had was like basically just converted a bunch of OSN roads data into geojson and then was basically
just doing like clients allowing you to draw out client side roots using tarot draw as like a
kind of custom mode and then another example was like using the um there's a there's a model
called like segment anything model which like matter released which is can basically like pull out
features essentially from like an image and so then using that to like being able to like pull out
you could click on a building and it would generate the like polygon for the building essentially
again it's like a kind of custom mode integral um so yeah that's uh new modes and then at custom modes
also some like uh new kind of additions to uh configuration of existing modes that were potentially
quite interesting so one of them is like called like validation and so validation is basically
sometimes you want to prohibit users from creating polygons or points or like any kind of geometry
that doesn't add here to some sort of like uh like validity rules or best practice or whatever it
might be so in this case it's about like you don't want to have a polygon that's self intersecting
there's various reasons why you probably wouldn't want self intersecting polygons in your like
database or whatever it might be um but you can actually like this is just free form so you could
essentially just do anything in here and this just allows you to prevent creating data that you feel is
invalid essentially um and then the next one is about like snapping so
total support is snapping for a little while but there's kind of been some improvements to
um kind of how that works so like one of the nice things is you've always been able to snap to
the um coordinates of a polygon so like the vertices of a polygon so for example like
basically the corners here um but now we also just support snapping to like an arbitrary
place on any of the lines of the polygon as well um so for example here this is just snap to like
somewhere along this line here essentially um and so a lot of people find that useful um so
that's something that we added support for um the other thing that we've kind of been working on
it's it's tricky I wouldn't say it's perfect but it's at least kind of like the foundation for
supporting like drawing on essentially like globes um which basically just requires you to um
like when you're drawing on a web Macator map and you draw a square or a circle or whatever it
might be when you actually place that on a globe because like you if you yeah it's this
you end up with a scenario where like it's no longer circular it's no longer rectangular because when
you project like something that's been drawn on a 2D web Macator map onto a globe it loses the
property of being circular or a rectangular and vice versa if you draw a circle on a globe
and you project it down onto a map it's going to look like more like an oval basically um and so
now tarot draw has basic support in its modes for um drawing on on globe essentially but yeah
it's not perfect but we're working on it community um so we've been really lucky to have like quite a few
people uh getting involved so we've had 24 unique contributors over the last two and a half years
there's 48 this is just some data I just pulled out of like GitHub insights but there's 48
repositories that depending on it um 590 stars yeah obviously it's a bit of a vanity metric but
it's just always nice to see people taking an interest in something you're working on and similarly
64 forks again just nice to see people checking out the code um but yeah if you want to get involved
appreciate like any feedback you might have either on this talk or the um on any of the functionality
of tarot draw itself I feel free to just you know you can kind of speak to me afterwards um or
yeah feel free to write an issue on GitHub if you find bugs or you find there's a feature that you
feel is missing um yeah feel free to share it if you know people that might benefit from using
the project and yeah obviously we always welcome contributors um to tarot draw itself so please
feel free to check out the code um start hacking around and if there's something that you feel
like you could fix then I've just encouraged you to have a go um yeah I think that's me thanks
questions
yeah at the moment it only supports um 2D and well there's multiple reasons for that one of
which is the GIAs and specification only supports two dimensional data by default I think
um so it would be because it all backed the like the whole store concept is like everything is stored
in GIAs and like everything is exported in GIAs and so you'd have to come up with a way to like
represent that data but that kind of third what is said coordinate it's like you can't do that without
breaking the GIAs and specification really and so you'd have to come up with it like it could be
plot like you could add it as like a property in the property like basically as metadata like that
said property but um yeah by default it doesn't support like three dimensional drawing out the box
yeah so the question was um do you plan on adding support for translating rotating scaling um
so it does actually we do it does actually have support I didn't show it but we do actually have
support for so there's one of the modes is select mode and you can select polygon and then you can then
you can modify all the coordinates but you can also do scaling, rotating and just move like
translation like just moving as well so it does support it but you have to enter like a select mode
select the polygon and then start playing it so yeah thanks there's a great question
yeah sure yeah yeah no it's a good question so the question is do does tarot draw
do the rendering or is it kind of um does it offload it to the mapping library to render the actual
data so yeah as I'm saying all the data is in um geojson and so essentially what happens is
is each of the adapters has a way to render geojson data via the underlying library so if you use
like leaflet it will use the leaflet method for like rendering geojson um so yeah it's offloaded
to the the library itself like we don't overlay like a web jail canvas and start doing stuff
or anything like that no yeah it's really it's a greedy yeah that is really interesting so
the question is about um like styling across multiple different mapping libraries is that
like a good summary yeah they're like how do you so the the the the the answer is um it's actually
like it's quite fortunate really because a lot of the mapping libraries actually have quite
similar levels of functionality so you can generally feel like the basic styling you can
style consistently across like all the different mapping libraries quite like relatively easily
it gets more complicated when you do like more obviously like more complex styling so if you have
things like like one example is that I've we've wanted to do for ages is like dashed lines
and so there's just one it's like for some reason like map map libre doesn't support dashed lines
or it doesn't support dashed lines but it doesn't support like dashed lines that are
based like powered by data if that makes sense so you can dynamically change the how the gaps
between all the dashes and all this kind of stuff so um yeah you're kind of the problem is
like one of the side effects of um supporting all the libraries is you're kind of tied to like
the lowest common denominator if that makes sense because you have to you can't just add support
for like things that the other libraries don't also support so yeah it's a bit of a problem but
seems to work okay for the basic stuff yeah
I missed the like first part of the question so with snapping like how much can you
the questions like how much can you configure it so yeah good question so you can do
coordinate snapping so that's a snapping to the vertices of like other let's say like polygons
that you're you've drawn you can snap to the line kind of like as I was sharing but there's also
we have a thing called like two custom and so two custom is essentially like a function and then
like it just expects you to return some coordinate so in two custom you could snap to an external
data set or you could snap to let's say or you could snap to like right angles there's an example
like if you just wanted to only draw like right angled polygons and so there is a way to allow
if you really want like really bespoke custom snapping behavior then they have this like two
custom function that allows you to snap to like anything you want basically so two custom is like a
is a feature within terror draw but then if you wanted then it's up to you to decide like
the minutia of like how what you want to snap to basically yeah thanks