Transcript
[ Music ]
>> Hi, everyone.
[ Applause ]
>> I'm Vicki Murley and I'm the
Engineering Manager for the
MapKit JS Team.
This is Session 212, Introducing
MapKit JS.
So, when iPhone came out more
than ten years ago, it really
changed the game, and it
introduced us all to what we now
kind of know as this app
ecosystem.
And it's funny to think about,
because for so many of us, apps
are such an integral part of our
daily lives, but before there
were apps, there were websites.
If your company was founded
before iPhone, your whole
company may have started as a
website, and even today, if you
have an app, you might be using
a website to reach a larger
audience or even just a
different audience of people.
So, lots of developers out
there, just like you, have a
website and an app.
And the WWDC site is a great
example.
We have this site and there's an
accompanying app, which you're
probably using to find your way
around the conference center, as
you're on the go, here this
week.
So, at Apple, we've been really
lucky that we have been able to
show Apple Maps on our own
websites for a little while now.
This is a page on the WWDC site,
which is showing you other
events around the convention
center.
If you've ever used Find My
iPhone of iCloud.com, you've
seen Apple Maps on a website.
And if you've ever searched for
a retail store, again, an
example of Apple Maps on a
website.
So, most of you out there are
probably used to using MapKit
inside your apps, and today,
we're making MapKit JS available
to you for your websites.
[ Applause ]
So, this week at WWDC, we're
making a MapKit JS Beta
available, and this is the same
library that we have been using
on our production websites.
Every web mapping library out
there, has a free tier of usage.
Like some number of requests
that you get for free, and
MapKit JS Beta is no different.
So, you -- as part of the MapKit
JS Beta, you're getting 250,000
map initializations, and 25,000
service requests.
That includes geocoding, search,
search auto-complete, and
directions.
And often these free usage tiers
are specified over some period
of time, like per year, per
month, per week.
For the MapKit JS Beta, we're
making this amount of free usage
available to you per day.
[ Applause ]
So, that's a good amount.
And -- but if you need more for
your particular use case or your
business, you can contact us.
There's a form online.
Just fill it out and submit it,
and we will receive that
request.
To use MapKit JS, you need a
key, and you can get that by
signing into your developer
account, and go to the
Certificates, ID's, and Profiles
Panel.
And you can get a key there,
just like you would for any
other service in your developer
account.
There's a limited number of keys
available for the MapKit JS
Beta, so I suggest you go and
get one as soon as possible.
Once you get a key and start
using MapKit JS, I mean, I'm
biased because I work on it, but
I think there's a lot of things
that you're going to really like
about it.
The first thing is, it lets you
unify on one map provider, for
both your app and your website.
So, we've noticed lots of you
are using Apple Maps inside your
apps.
Now, you'll be able to use Apple
Maps everywhere.
The MapKit JS APIs, are really
inspired by the APIs that you're
already using inside native
MapKit, but they're using
conventions that are familiar to
web developers.
So, they should be easy for you
to adapt.
Also, MapKit JS really brings
the Apple Maps experience to web
pages.
It's localized and in 32
languages with full right to
left support.
It's accessible via keyboard
access and with voiceover.
It has the beautiful cartography
that we all know and love in
Apple Maps.
And it has support for native
gestures like Pinch to Zoom,
Two-Finger Rotation, and also
Shift, and Two Finger Scroll to
zoom in.
It also uses something that's
called Adaptive Rendering Modes.
So, what that means is, there's
a couple different modes in
which the map can be rendered.
The first is Client-Side
Rendering, and this is a full
WebGL engine that is rendering
the map on the client.
And this allows us to do lots of
things, like these very, smooth
transitions as users pinch to
zoom or shift two-finger scroll
to zoom in.
You'll see the labels fading in
and out as we transition between
zoom levels, just like on
native.
Also, Client-Side Rendering
gives us full control over the
labels on the map.
So, we can enable features such
as Rotation, where I'm rotating
the map with two-fingers, but
the labels are staying
horizontal as I rotate.
Finally, with CSR, we have the
marker style annotations that
you're used to seeing on iOS.
And the title of this annotation
is My Marker.
If I select this annotation, the
subtitle will appear, but it
would overlap that label that is
beneath it.
So, with Client-Side Rendering,
and full control over the
labels, we can just collide that
label out and remove it so that
the labels on the map never
overlap the text for your
annotations.
And even as users are zooming in
and out, and the map labels are
changing all over the place, the
map labels are never going to
overlap your annotation labels.
In fact, if you have a draggable
annotation and the user is
picking it up and moving it all
over the map, labels are never
going to overlap your annotation
labels.
So, this is one of the rendering
modes, Client-Side Rendering.
But web code can run anywhere,
and not all devices are created
equal.
So, for those times when your
users may be running on a low
performance configuration, maybe
an old device, we have a
different mode that we call
Labels Only Client-Side
Rendering.
And what this is, it's a grid of
image tiles that show the base
map, with a layer of WebGL
labels over the top of it.
So, we can still give as many
users as possible these great
features like rotation and label
collisions, in a
high-performance way.
In your users' configuration
does not support WebGL at all,
they get something that we call
Server-Side Rendering, which is
a grid of tiles, tile images,
and in this case, the labels are
actually part of the image.
So, adaptive rendering modes are
pretty cool because there is an
ideal mode for every client
configuration out there.
And we choose the best mode for
your user automatically.
So, you don't have to decide
whether to use the WebGL
version, or the tile version, or
whatever.
We run a quick test and give
that user the best mode for
their configuration.
In our experience so far, most
users are getting Client-Side
Rendering or Labels Only
Client-Side Rendering.
So, that's a quick introduction
to MapKit JS.
And now, to tell you more about
using the API, I'm going to hand
it off to Julien Quint.
[ Applause ]
>> Thank you, Vicki.
Let's get down to the technical
details of using MapKit JS for
your website.
We will see how to set up a map.
We will see how to navigate an
annotate this map so that you
can show your own data.
And finally, we'll see how to
enable rich interactions with
additional services.
To set up your map, you need to
go through these four steps.
First step is to import MapKit
JS.
Here you see a script tag that
you can add somewhere on your
page.
And the URL of the MapKit JS
script includes a version
number.
We follow the semantic
versioning system where the
first number is the major
version number, which is updated
if breaking changes are
introduced.
The second number is a minor
version number, so when bugs are
fixed, when new features are
added or when performance
improvements take place, we
update this number.
And finally, for urgent patches,
we update the patch number.
You can specify and X instead of
a specific number for the minor
or the patch version, and we
recommend that you use this
Version 5.0.X to get started so
that you will get urgent bug
fixes on our first public
release.
In order to be able to show a
map on your website, you will
need to tell your page -- to
tell MapKit where to show that
map.
So, in order to do that, you can
use an HTML element that will be
the container for your map.
So, in this case, I'm using a
development which is usually a
very good candidate for that.
I give it an ID so that I can
refer back to it easily.
And one thing that is very
important is to set its size,
because the map doesn't have a
size of its own, so it will just
use the size of the elements
that it is part of.
So, if you have a development
that I represented here with a
gray background, a map will be
shown inside that element.
If your element size changes,
then your map size will change
as well.
So, I have set up an element for
my map.
The next step is to initialize
MapKit JS.
So, we just saw that you need a
key to be able to use MapKit JS,
and in initializing MapKit, you
get your authorization callback
so that you will be able to use
the services that MapKit JS
provides.
And most importantly, to show
the actual map on your websites.
And the last point is to create
a map object, here using the Map
Constructor from MapKit.
I give it the idea of the
container where the map will
show.
And this is what happens.
We have a map showing on our
sites.
This is the different map.
We didn't pass any other
parameters, so it will show a
different region and the
different control.
You can see the controls in the
corners.
You can see the Compass for
rotation.
The Zoom control.
The Map Type Control on the top,
etcetera.
This was a pretty large area,
but if you're on a page where
you want to show only a very
small map, these controls can
use a lot of valuable space, so
by default, when your map size
is below a certain width or
height, we will toggle these
controls off automatically.
On touch devices, the situation
is a little bit different.
We don't really need to show the
-- some of the controls like the
Zoom or the Compass, because we
have gestures to change the
rotation of the map or to zoom
in.
So again, we don't really need
to use up that space by showing
these controls, and we turn them
off by default.
Note that the Apple logo and the
legal text are always present.
These are the difference for the
controls, but you can also set
these control visibilities
yourself.
Some controls are so-called
Adaptive Controls.
This includes the Compass and
the Scale.
This means that depending on the
platform, they will behave in a
slightly different manner.
So, on iOS, the Compass control
is not shown by default, but if
the map rotates, then we will
show it indicate where North is
pointing.
And the Scale is an indicator of
the units of distance on your
map.
And we show it only when the
user is zooming in and out.
So, here, we can see the -- when
we have zooming and rotation, we
can see the Compass appear and
disappear in the bottom right
corner.
And the Scale appear and
disappear in the top left
corner.
Of course, we can also select
these controls to be always
visible or always hidden.
The rest of the controls have a
binary state, so they can be
hidden or set to be visible by
setting a Boolean property.
In this example, we show the
controls that do not show by
default on desktop, such as the
User Location Control which
appears in the bottom right of
the window.
Here, I've selected it.
So now, the user location is
tracked, and you can see the
user location in the center of
the map.
And the Scale is shown at the
top let, because I marked it to
Always Visible.
We can go further in configuring
these controls.
In order to match better the
color scheme of your page, you
can set the tint of the map.
And this changes the color of
the user controls.
So, you can see, for instance,
the -- all of the controls of
the map.
You can see the user control is
now highlighted in red because I
set this tint color to a red
color.
You can use any CSS color value
here.
The MapKit will use your
[inaudible] language
configuration, so that it will
adapt itself to the language
that your user expects.
You can also set that language
into the initialization code or
you can even set it on the fly
using the language property.
So here, I've set it to Japanese
so that I'm sure -- so that I
can show the map, as well as the
controls in Japanese.
So, you can see the North
indicator for instance in the
Compass has been replaced, and
the units are not in -- using
the metric system which is more
traditional in Japan, than using
miles or years.
If you set your language to a
right to left language, such as
Hebrew in this example, or
Arabic, the controls are also
mirrored to match your users'
expectations.
So, the controls are the way --
are some of the ways that your
users can interact with the map,
but again, also in turn
directly.
As I said, we can use touch
events on touch enabled device.
On this stuff, you can use the
Track Pad for some of the
gestures, and you can also use
the mouse to click and pan the
map, or double-tap for instance,
to zoom in on the map.
You can also disable these
interactions directly, by
setting the Zoom Enabled, Scroll
Enabled, or Rotate Enabled
property to be false.
So, for instance, in the case
where you have this very small
map as I showed earlier, you
might want to make sure that the
user doesn't accidentally move
the map around to be sure that
it always shows the right area.
And you would set these
properties to false, which would
make the map static.
Now, that we know how to set up
the map on our page, we want to
make sure that we show some
interesting content.
So, we can do that by navigating
around the world to show a
specific area, but also to
annotate the map to call
attention to the region that we
are showing.
We'll see how to set the center
in the region, how to add
annotations to the map to mark
locations, and how to cover the
-- some areas of the map with
overlays.
So, starting with the center and
the region of the map, again,
this is the default map.
And it shows the default region,
which is zooming out at the
minimum possible level.
And centering the map on, zero,
zero, latitude and longitude.
You probably want to show a more
specific area of the world.
So, for this example, I want to
focus on Rio de Janeiro in
Brazil.
And to do that, I will set the
center of my map to the
coordinate of Rio de Janeiro.
So, you can see on the right,
that the map center has moved to
show Rio at is center.
But setting the center of the
map does not change the scale.
So, at this scale, we are always
still not very much in focus
because we can see all of South
America, for instance.
So, let's zoom in a little bit.
And in order to do that, I will
set a region.
So, a coordinate region is made
up of a center, which is
represented by these dots at the
center of the map, as well as a
latitude and longitude span.
So here, I have represented the
region as this dotted box.
But we will not that the map --
the region that is set
ultimately on your map, will be
bigger than the region that you
asked for because we need to
make sure that it fits entirely
within the bounds that you have
set for your map.
So, in this case, I need to add
some padding, north and south of
the region to be able to show
the -- all of the region that
was specified.
So, in terms of putting the
MapKit JS framework -- the
center is set to a MapKit
coordinator object which is a
latitude and longitude pair.
In the Coordinate Region, to set
the region of the map, is an
object that contains two member,
a center which is also a
coordinate and a coordinate span
which is a latitude delta and a
longitude delta there.
How did I come up with the
region or with the coordinates
that I showed you in these
screen shots?
There are many ways to decide on
regions and coordinates.
You can look them up on
Wikipedia and help put them in
your code.
You could get them from some
database that has some
geographical information.
But one way that you can also
get this information, is to use
MapKit Services that includes
Geocoding and Search.
So, Geocoding lets you look at a
place and will return your
coordinate in a region.
So, in these previous examples,
I used the geocoding from MapKit
JS to look at the coordinate in
the region for Rio de Janeiro
and this is what I set on my
map.
You can also use search to
search for places.
And it will return not only the
coordinates of these places, but
also bounding region that you
can set on your map, to make
sure that it encloses all of the
results.
Another way to quickly set a
region on your map that is very
convenient, is a method called
Show Items.
We will see now how to add
annotations and overlays on your
map, and by calling Show Items,
we will make sure that we have a
region that encloses these items
so that they are all visible to
your user.
I will note that region changes
may be animated, so that you can
provide a nice animation.
Or you can set the region
instantly.
Because these things, changing
the regions, changing the
center, etcetera, can be done
from your code but can also be
done by the user as a result of
interactions you want to be able
to react to these interactions.
And we -- and the Map Object
allows you to listen to user
events such as region changes,
when they begin, when they end,
since they can be animated.
And also, when gestures such as
coding, zooming, rotations begin
and end.
We follow the model of DOM Event
Handling, so you will have the
familiar method such as Add
Event Listener and Remove Event
Listener, the name of the event,
and you get past an event object
with the parameters of the
event.
So, for instance, if I wanted to
refresh my map with some new
information every time the user
has mapped to a different area,
I can listen to region change
and events, and that will let me
know that the map has settled to
a new place, and I can now use
the region of that map to
compute which information I
wanted to show at this stage.
Now, that we know how to set up
a map, let's add some our own
information on it.
And we can do that with
annotations and overlay.
We'll start with annotations.
And MapKit JS provides three
kinds of annotations.
The first one, you've had a
quick peek at it, which is the
Marker Annotation.
You can customize annotations
further than the -- what the
marker annotation provides by
using images, or even DOM
Elements that will have
completely customizable
appearance.
The marker annotations are the
most useful annotations that
MapKit JS provide as they also
have lots of rich interaction
built-in.
And there's lots of styling
options.
So, they are analogous to the
marker annotations that that you
may have seen already on iOS.
They have a built-in animation
for selection and deselection.
And they automatically collide
out the underlying map labels as
we've seen before.
So here, when I select my
annotation, the label for the
exit of the station is hidden to
make room for the subtitle.
Marker annotations -- the
appearance of marker annotation
also adapts itself automatically
to the rendering mode that has
been selected by MapKit JS for
your map.
So, we've seen that if we have
Client-Side Rendering Mode or
Label Only Client-Side Rendering
Mode, we are able to hide
labels, so we can display the
title and the subtitle of your
annotations on the map.
And this is what is shown on the
left-hand side.
If you have Server-Side
Rendering, the labels are built
into tiles and we cannot hide
them.
So, if you see the map on the
right-hand side, we see that we
have many more labels because
none of them have been hidden.
So, in order to be able to show
our annotations legibly, we only
show the annotation balloon and
the labels are not shown on the
map.
We can still see the title and
the subtitle of these
annotations when we select them
by using a callout bubble as in
this example.
And custom annotations, will
also make use of these callout
bubble to show the title and
subtitle.
Finally, the market annotations
provide a lot of standing
options.
So, this is the default for
market annotation.
You create an annotation with a
coordinate and some properties
such as title and subtitle, and
this is the basic default
rendering.
You have glyph image which is a
pin shown in the balloon, and it
comes up with a red color.
You can change that color to any
CSS color value.
So, here, I've used a green
color for my balloon.
You can also change the color of
the glyph.
So, the glyph can only have one
color.
So, in this case, I switched
from the default white to a
yellow color.
You can change the image of the
glyph.
So, from the default pin that is
provided by MapKit JS, to any
raster image that you can
provide.
So, in this case, I've provided
this image.
You can give several sources for
your images for different pixel
ratios.
When the annotation is selected,
it becomes bigger, so you have
more room to show more details
in your glyph.
So, in this case, we can also
specify a selected glyph image,
which is different from the
original one.
Finally, instead of an image,
you can change the glyph by
using some text.
We recommend that you stick to
very, short strings such as one
to three characters, and in this
case, I'm just using the Letter
M.
When the glyph text and the
glyph image are both specified,
then the glyph text is shown.
So, now that we know how to
display marker annotations, we
can go crazy and put a lot of
annotations on our map.
So, this is the result of doing
searches for cafes and bars in
Paris.
And I've styled them slightly
differently to distinguish them
from one another.
But the problem is that there is
a very dense number of
annotations in the same area.
Fortunately, we have two ways in
MapKit JS to deal with this sort
of clutter.
The first one is to set a
display priority property on
annotations.
What this means is that when two
annotations collide, the
annotation with the highest
display property, which is a
number, will collide out the
annotation with the lowest
display priority.
So, in this case, we can see
that many annotations have been
collided out.
When you zoom in and out, these
collisions run again, so that
zooming in for instance, will
let you discover more
annotations.
And when they have the same
display priority, we will use
the one that appears at the
bottom of the screen as the more
-- as the one with the highest
priority.
Another way to deal with
clutter, is to use clustering
instead of these display
priorities.
So, in this case, when two
annotations that have the same
clustering identifier, which is
a property that can be set on
marker annotations, and is a
simple string, when two
annotations that collide and
have the same clustering
identifier, they are replaced by
a single annotation that will
represent both of them, or more
than two of them of course if
more than two annotations
collide.
So, in this case, we see that
some of the annotations can be
shown by themselves because they
have no neighbor, but in the
dense areas in the center, we
have clustered several
annotations together.
When a cluster is created, we
use a marker annotation to
represent it and we use the
glyph to show how many
annotations are in the cluster.
You can also change the behavior
-- not the behavior, the
appearance of your clusters, by
specifying a new style or a new
kind of annotation.
And now, we'll do a small demo
to show these annotations in
action.
So, in this demo, which should
appear here -- in this demo, we
will use a map and the data that
we will display is Bigfoot
Sightings that Have Occurred in
this Area.
So, after this session, or maybe
this weekend when you are done
with the conference, you can
maybe go explore the woods of
Northern California and see if
you can find Bigfoot.
I have created a map which I
have initialized in the manner
that I've displayed in the
previous slides.
And what I have done, is I have
gathered a list of Bigfoot
annotations -- of Bigfoot
sightings, sorry, including the
location, the year in which they
occurred, and some other
information.
So, what I will want to do is I
will want to use these
annotations, show them on the
map, with marker annotation.
So, let me start by creating a
function to translate a sighting
object which has all these
properties, into a marker
annotation.
So, when I get a sighting, I
want the coordinate of the
sighting to be used as the
coordinate of my marker
annotation.
And these sightings have several
other properties, such as the
year of the sighting, which I
will display in the title.
This comes from a database put
together by the Bigfoot Field
Researchers Organization.
So, I will show the idea so that
if you are interested in more
details about that sighting, you
can go look at that database and
find even more information.
And finally, I'm ready to create
a marker annotation with that
coordinate and these options
that I've created.
So, now that I know how to set
up a marker annotation for a
sighting, I will get the
sightings that I've prepared.
And with this list of sightings,
I will create an annotation for
each of them.
I will then make sure that my
sightings are shown on the map.
My annotations are shown on the
map.
And I will use the Show Items
method, which is very convenient
because not only it ensures that
the items are visible, but also
that they are added to the map.
And since I'm doing a webpage, I
can also add some extra
information on my page such as
how many sightings there were in
this area.
So, let me make sure that I save
and by reloading, I now see a
map with 60 sightings on it.
So, all of these annotations are
sightings and we run into the
problem that I've just
highlighted which is that in
this park area, I can see lots
of sightings happening, and they
all overlap each other.
And even as I zoom in, I can see
that there's still lots of
clutter, so I will clean that up
using the Display Priority
Property on Annotations.
So, in order to choose a display
priority, what I will use is I
will use a very important
property of the sightings which
is whether they were clear
sightings.
So, if someone really, really
saw bigfoot, or maybe they just
heard it or saw some traces of
it.
So, I have this clear flag which
I will use to set my display
priority.
Display priorities a number and
these priorities can be pretty
arbitrary.
So, we provide predefined
values, such as required,
meaning that your annotation
must always be shown on the map,
but also, high and low display
priority.
So, when the sighting is clear,
I will set a high display
priority.
When it's not, I will set a low
display priority.
And finally, I will also encode
that information as the color of
my annotation so that the users
can understand better why an
annotation was shown or now.
So, when it's brown, it's a
clear annotation and when it's
great, it was not so clear.
So, let's see the difference
that this makes.
So, now you can see that the map
is much cleaner because all of
the collisions have been a
result.
You can see that some of the
annotations are brown.
So, these are the clear
sightings.
These are probably the ones that
are the most interesting ones to
visit first.
But you can also see that if I
zoom in on the map, then new
sightings are being revealed.
So, your users can explore the
map and find out about where
they can hope to see Bigfoot.
I will conclude by this demo, by
adding, another piece of
information to my map.
I will change the glyph to be
either an icon of Bigfoot which
I've prepared.
So, this is a simple PNG image
which I will use for the clear
sightings, and in case the
sighting is not so clear, I will
make that more explicit by
setting the glyph text to be a
question mark.
And now, what I can see, is that
these questionable sightings are
a question mark.
And the Bigfoot sightings that
are really clear, have the
Bigfoot icon.
So, this includes the first
demo.
Thank you.
[ Applause ]
So, in this demo, we show how to
create marker annotations from
JavaScript objects, how to set
the display priority of
annotations to unclutter our
map, and how to style these
annotations with colored glyph
image, glyph text, so that we
can translate the information
that we have onto the map.
Sometimes, market annotation is
very convenient, but may not be
exactly what you want to use on
your map.
For instance, if you want to use
the logo of your company and it
has more than one color, then
you cannot choose a glyph image
because it's restricted to just
one color.
Sometimes the shape of the
annotation is not really the one
that you are going for, so in
this case, you may provide
images to represent your
annotations instead.
So, in this case, I have the
small sticker look to mark
places where -- which I have
visited recently.
So, I can use a raster image for
these annotations.
The title and subtitle are shown
in a callout bubble, just like
in Server-Side Rendering for
marker annotations.
And to create an image
annotation, this is very similar
to a marker annotation, but with
the additional property that
much be provided which is the
URL for the images.
And here, you can see two
different URLs for two different
pixel ratios.
Another way that I could
represent a notation is using
the classic pin example.
And pins usually come up in many
different colors.
And the problem is that if I
want to provide a lot of
different colors, I will need to
provide a lot of different
images.
And this can quickly become
unmanageable.
So instead, what I can do is I
can use a custom annotation.
And in this case, instead of an
image, I will use any DOM
Element to represent my
annotation.
And these elements are created
on demand for your annotations.
So, let's see an example.
Here, if I wanted to do just
some color for any pin that
shows up on my map, then I will
create an annotation with a
coordinate [inaudible].
And a third parameter which is a
function that we will return a
DOM Element for that annotation.
So, in this case, I will use a
Canvas Element.
I create a Canvas Element.
I get .Context.
I drew a pin image in that
Canvas.
I changed the head of the pin to
the color that I want, and I
returned to Canvas.
And this is the Canvas that is
shown on the map for this
annotation.
So, these were the three kinds
of annotations that you could
use.
But sometimes you want to show
more than just a single location
or a set of single locations.
Sometimes you want to call -- to
show complete areas on your map.
And to do that, we have overlays
and we have -- we provide three
different kinds of overlays.
And here are some examples of
how you could use them.
With a circle overlay, you can
show all of the distances -- or
the distances from a point.
With a polyline overlay, we can
show a route between two points.
And you can highlight
geographical areas such as a
state, the boundaries of a
country or a city, etcetera,
using a polygon overlay.
So, here is an example of a
circle overlay.
So, now I'm in Brussels and I've
centered my map on the Manneken
Pis.
And this is right in the center
of the city and this is a very
nice place to walk around.
So, by using concentric circles
around my location of increasing
radius, I can see walking
distances.
So, here I've created overlays
with their coordinates, and the
second parameter that you need
to give to a circle overlay, is
a radius expressed in meter.
So here, every overlay has a
radius starting from 400 meters,
increasing by 400 meters.
So, 400, 800, etcetera.
So, I can see in the right, that
there is a museum for comic
strip art.
That sounds interesting.
And it looks like it could be
between 1200 and then 1600
meters.
So, about 10 to 15 minutes'
walk.
One important thing that I can
do with overlays, is I can also
style them.
So here, to represent this style
of overlay, I can use a MapKit
Style Object, which has several
properties such as the line
width, the line depth, the
stroke color which again, can be
any CSS color.
By default, circle overlays are
filled with blue color, but in
this case, I want them to be
transparent.
So, I set the field color to be
null.
I have decided that I want to go
visit this comic strip museum,
and MapKit JS as we will show,
has services that can give you
walking and driving directions
between two points.
So, in this case, I've asked for
directions from where I was, the
Manneken Pis, to where I want to
go.
I receive as a result, a route
which I represent on this map
using a polyline overlay.
And a polyline overlay is a list
of points.
So, these are all coordinates
linked to each other.
I can style them by setting the
Stroke Opacity for instance, or
a thick line width to make sure
that it shows up on my map.
And the last example is a
polygon overlay.
This is very useful to do for
instance data visualization.
And here I have a map of the
United States where every state
is an overlay of its own.
A polygon overlay is defined
again by a list of points, but
this -- in this case, the shape
is closed and filled.
You can even specify lists of
lists of points to -- for more
complex scenarios.
So, for instance, if you have
enclaves and exclaves, which is
often the case with real
geographical areas.
Annotations and overlays can
also have an extra piece of
information added to them, which
is this data property.
So, in this example, I want to
show the population of every
state of the United States.
I can show it as a color, which
gives me a rough idea of the
population.
But I can also add some
additional data so that if the
user selects one of the
overlays, so in this case, the
State of Texas, I can show that
the actual population is over 20
million people.
And overlays are selectable just
like annotations.
To show overlays such as the
route that I showed you or to
show all of the states, we need
a lot of data, we need a lot of
points, so for the states, we
had thousands and thousands of
points.
So, a convenient way to get that
data into your program, is to
use GeoJSON Import.
So, if you have a GeoJSON data
file, then you can import it
automatically using MapKit JS.
Annotations and overlays are
created.
So, in this example, this was a
different data file, which
contained a lot of UFO
sightings.
And this is just a detail of the
map.
So, you can see there are lots
of these sightings.
And all of these annotations and
overlays are created
automatically and can of course
be customized using some
delegate methods.
Finally, these -- since these
annotations and these overlays
can be selected by users, you
want to listen to events from
them, as well as you could from
the map.
So, you can listen to selection
and the selection events.
And we've also seen earlier that
annotations could be dragged, so
you can listen to dragging
events.
And again, this uses the Add
Event Listener Method.
So, for instance, you can use
Add Event Listener to listen to
select events from the map,
which will tell you when an
annotation or an overlay has
been selected.
And we will see an example of
that in the demo.
The next section is Enabling
Rich Interactions with Services,
and for this section, I will
give the mic to Melody.
[ Applause ]
>> MapKit JS provides you with
access to three services,
Geocoding, Search, and
Directions.
I'll step through examples of
each of those, but before that,
I'll tell you what they have in
common.
You can use the services in a
similar way, with four easy
steps.
You first create the service
object, then you specify the
request parameters and options,
then you make the request, and
finally, handle the asynchronous
response via a callback
function.
So first, let's talk about the
Geocoder.
Here's an example of how you can
use the Geocoder, and it has two
methods: Lookup and Reverse
Lookup.
So, this is if have you an
address or a place, and you want
to find the coordinate, or if
you have the opposite.
You have a coordinate and you
want to find the address.
So, the first step is to create
your object, which you can
optionally provide at Gets User
Location parameter.
This will allow you to provide
more context to the geocoder.
This is useful in the case where
there are places with the same
name in multiple locations.
For example, if you're using the
geocoder here, you'll be most
likely to return Brisbane,
California instead of Brisbane,
Australia.
Next, you build the requests.
Here, we're using this
convention center.
And then you can handle the
response.
As we mentioned before, the
geocoder can easily be used to
place marker annotations.
So, here we're adding a marker
annotation to the map.
And then here we have an example
of the reverse lookup where we
have a coordinate, and we want
to find the address for the
place.
So, that's the geocoder.
Next up we have service context.
So, as I mentioned before, you
can provide a Gets User Location
parameter, but you can also
provide coordinate and region to
search.
This is useful to provide the
most relevant results to your
user.
So, that's where places are in
multiple locations with the same
name, or you can provide your
search results, closer to the
user.
Here's an example of how you can
use the Search Service.
It's an example for finding
coffee nearby the user.
So first, you create your
service object.
Then you build your request
using query like coffee.
You can also do something more
specific like a specific name of
a coffee shop that you have.
And then you can handle the
results, which can easily be
displayed using annotation since
sometimes you return multiple
results.
And you can use the coordinate
as well as the title to populate
the fields of annotation.
And then finally, we
simultaneously add and display
the annotations using the Map
Show Items method.
So, this is useful if you have
your full query that you want to
send in the request, but if you
have a Search Bar that you want
to respond to user input, you
can use the Search Autocomplete
Method.
With Search Autocomplete, you
can provide a partial query to
the user - to the service, and
then save your user some
keystrokes by providing
suggestions which you can then
use to complete a search.
And the last service is
directions.
Similarly, to the other
services, you create your
directions object.
You can choose to provide a
language which will then return
the route steps in that provided
language.
If you don't provide a language,
the language provided to the
MapKit initialization function
will be used.
And if that's not provided, the
browser's preferred language
will be used.
Then you build your request
using two required fields: the
origin and the destination.
These can be coordinates,
addresses, or places.
By default, the transportation
type is by automobile.
You can switch this using the
transport enum to walking
directions.
We won't keep that, because
that's a really far way to walk,
but we will use Request
Alternate Routes.
You can use this to provide
multiple options to your users.
This way we can display
different routes instead of the
default of one optimal route.
And then finally, you can
display your results on the map.
Here we have polyline overlays
as you've seen earlier.
And you also get a set of route
steps as well as the distance
and the travel time.
So, those are the services.
Now, that you're more familiar
with them, Julien will come back
up for a demo.
[ Applause ]
>> Thank you, Melody.
So, we will pick up where we
left off and we will continue
building our Bigfoot Finder.
And there's one things that's
really missing from this finder,
is that even though it can tell
us where we are, and it can tell
us where Bigfoot is, it doesn't
yet tell us how to get there.
So, I'm going to add some
directions from All Current
Location, which is the McEnery
Convention Center, to these
Bigfoot locations.
I will use the MapKit JS
direction services to do that.
I will use polyline overlays to
draw them.
But the first thing I need to do
is I need to make sure that the
user - I need to find a way so
that the user can tell me which
one of these sightings they want
to see.
So, well, this one is selected,
so that's probably the one that
the user wants to see, right?
So, this is what we will do.
We will use the Select Event
Listener from the map to listen
to annotation selections from
the user.
And when an annotation is
selected, that means they might
be interested in knowing how to
see that specific location.
So, we will request a route and
draw it so that they can see how
to get there.
And then finally, we will let
them also select one of the
routes from the options that are
returned by Direction Services
and display more information
about each of these routes.
So, let's start by setting up
our Event Listener.
So, we listen to the select
events from the map, which tells
us when an annotation or an
overlay is selected.
So, this is the property of the
event, object that I received.
And if annotation has a value,
then that means that this
annotation was just selected.
So, there is only one annotation
overlay selected at a time, in
MapKit.
So, there is no ambiguity here.
This is the one that we want to
go to.
So, I will show routes to that
annotation.
Showing our route means drawing
it on the map.
So, let's set up a polyline
overlay to draw a route on the
map.
So, first off, I will start by
defining a style that I will use
for all my routes, setting some
opacity and some line width to
make sure that the route stands
out.
The default color is blue, which
is fine for the moment, so
that's what we will use.
And just like we did a function
that created annotations on
demand for citing objects, here
we'll create overlays on demand
for routes.
So, a route that is returned by
the MapKit JS Direction Service,
contains a lot of information
including a path which is a list
of steps that you can take to go
from A to B.
And each list of steps, itself
contains a list of points.
And if you remember to create a
polyline overlay, I want a list
of points.
So, now that I have a list of -
list of points, I will reduce it
to a single list so that I will
put all of - the path steps one
after the other.
This is the list of points that
I want to create my polyline
overlay.
This is the style that I just
defined above, that I want my
overlay to show up as.
And later, I will let the user
select this overlay to see more
information.
So, I will keep around all of
the route object, in the Data
Properties so that I can display
the distance of the estimated
travel time.
I know how to draw these
overlays, so now I know - I need
to request them from the
service.
So, here we go.
This is a little bit longer but
not so bad.
I first need to create a
directions object.
I will just use the current
language for the directions.
So, the default is fine.
So now, when I'm requesting a
route to a specific annotation
or rather, routes to a specific
annotation, I will clean up my
map first because maybe I've
shown routes to a different
place before.
So, if I query the other list
property of my map, it tells me
which overlays are currently
added to the map, and I can
remove them by using the Remove
Overlays Method.
So, now I have a clean map, and
I can display new routes.
I'm building my request for the
origin.
I will hot code this place, the
McEnery Convention Center.
Again, I could put coordinates
for instance, instead, but this
is much more convenience.
For the destination, I will use
coordinate because I have them.
They are the coordinate of the
annotation that was given as a
parameter.
And I want to show all of the
possible - not all of the
possible but the several
possible routes to this point.
So, I make sure that My Request
Alternate Routes Property's set
to true.
Now, that my request has been
created, I can execute it on the
Direction Services using the
Route Method.
Things can go wrong when you do
these kind of queries.
So, we must make sure that we
have a way to handle errors when
they occur.
So, in this case, I will fall
back to show a default route
that I've created and it's just
a straight line.
So, if we see a straight line,
then we know we're in trouble.
But let's focus, let's be
positive and focus on the cases
where the request succeeds, and
in this case, I will have a list
of routes and I will create a
new polyline overlay for every
one of them.
I will use my trusty Show Items
Method on the map to add these
routes and make sure that they
are being shown by setting the
region to enclose the routes.
And let me introduce a couple
more options in that method.
The first one is Animate,
because I wanted to make sure
that there is a smooth animation
from the current region of the
map to the one where the routes
are shown.
And finally, I will also add
some padding so that I can keep
some of the context and not
constrict the region too much
around the routes.
So, I'm now ready to request
routes from the - this
convention center to an
annotation.
So, let's select this one again.
And now that my annotation has
been selected, the request has
been made.
I see that I have three
different results.
So, they share a part of the
route, but then they diverge in
the end.
And they start from our current
location, the convention center.
So, I think this is right.
Yes, that looks right.
I have got three results.
So now, I might be interested in
knowing more about what's the
difference in travel time or
distance.
So, I can use selection to do
that.
But if I select a route, the
only thing that happens is that
my annotation has been
deselected because there is only
one selection at a time.
The problem here is that there
is no default behavior for
overlays being selected.
So, let's implement our own.
What we will do is we will
highlight these overlays and
then display their information
on the side bar.
So, in order to highlight these
overlays, I will create a new
style for highlighting overlays.
So, let's put it here, along
with my old style.
So, this style will keep the
same opacity.
We will make the line figure and
we will make it purple so that
it stands out from the other
ones.
But now, we need to apply this
style to my overlay once it's
selected.
Fortunately, I already have an
event handler for selections.
And up to that point, we were
only interested in listening to
annotation being selected.
But now we will just add a new
-- we will add plans to this
function.
Oops.
So now, if annotation is
selected, I still do the same
thing that I was doing, but if
an overlay's selected, I will
change its style to be the
selected route style that I've
just defined, so that it is
highlighted.
So, let's see this in action.
We can use a different one.
I'm feeling lucky.
And now, we can see that we can
select the routes to - from the
list of routes that have - that
has been provided.
I haven't implemented showing
the data yet.
Let's see if I select another
route.
What happens is that there is
nothing happening by default
when an overlay's selected, but
there is nothing happening by
default when an overlay is
deselected.
So, I have to implement that
part of the behavior as well.
So, in this case, I will add a
new event listener for deselect
events.
So, when an overlay is
deselected, then I will switch
its style to the default one.
So, this should fix my issue.
So, let's try again.
I have a route here.
And if I select again, I do the
same place because here we have
two overlays on top of each
other.
This will select the other
overlay.
And the deselection event
handler is working, so, my
previous highlighting has
disappeared, and now, the new
selection is shown correctly.
So, this seems to be working
pretty well.
Here is another example.
So again, I can select these
routes.
But now I want to know more
about them.
I want to know what are the
driving directions, how long it
takes to use one of the routes
versus another, etc. So, this is
very simple to do because all of
the - everything that I need is
already in place.
I have saved data on my
overlays, and I have Event List
now for Selection and
Deselection.
So, when the overlay's selected,
I will show the data in the
sidebar.
So, this is just classic.
Now, we are really into web
development land where we have a
bunch of the time we went to --
format it into some HTML, so I
won't go over the details.
But the detail that we have is
the one that is associated with
the overlay.
And it gets shown when the
overlay's selected.
And I will not make the same
mistake about this this
selection, so I will directly
hide the data when the overlay's
deselected so that I don't have
several routes appearing at
once.
So, let's try again.
Let's go back.
I like this example.
So again, I will select this
route.
And now that the route is
selected, we can see on the
right-hand side that we have
some additional information.
This is a quick name for the
route.
So, this is the route that goes
from Mount Hamilton Road.
It's 70 kilometers long and
under ideal driving conditions,
it should take me an hour and 32
minutes to reach there.
And here are all the steps that
I can follow to get to my
destination.
I could see what this one looks
like.
It's actually longer in distance
but it should get me there
faster.
So, there we are.
We have built a Bigfoot Finder
and -- that lets us select where
we want to go and tells us where
we are going to go.
[ Applause ]
Thank you.
Quick recap.
We've seen how to react to user
events.
So, in this case, selection and
deselection.
We've got driving directions
from the MapKit JS Service.
We've used polyline overlays to
render these driving directions.
And we've added our own behavior
for the selection of overlays
since there is no specific
behavior provided by default.
So, there is plenty more to talk
about MapKit JS, but we only
have one hour.
So, I will stop here.
But I hope that we have made a
good case for MapKit JS,
delivering a top-notch map
experience for the web.
That it lets you unify on a
single map provider with a
familiar and flexible API.
So, if you have on your team
people who have used the native
MapKit API, this would feel
right at home, because the same
concepts apply.
And web developers will be happy
to see that the APIs are also
tailored to match JavaScript.
So, I will remind you that you
need the MapKit JS Key to be
able to use MapKit JS.
So, please go to the developer
portal, get your key, and try it
out today.
If you want to know more about
MapKit JS, you can find the
documentation and sample code at
this URL.
And if you want to know more
about this session, you have
this URL for the session itself.
We have accompanying video that
will take you step-by-step
through getting and using a
MapKit JS Key.
And finally, we have labs
happening on Wednesday morning
and Friday morning, so you can
come to talk to the whole MapKit
JS team to ask us questions
about MapKit JS.
Thank you very much.
[ Applause ]