Google I/O 2011: Map your business, inside and out

Google I/O 2011: Map your business, inside and out


Kenny: Hi, welcome to “Map your Business,
Inside and Out.” My name is Brendan Kenny.
I work with developer relations, uh, with Geo,
working the Maps API and the Earth API. Broadfoot:
Hi, I’m Chris Broadfoot. I work on the Developer
Relations team in Sydney, and I work on the Maps API. Uh, you can follow me
on Twitter at “broady,” and Brendan is “brendankenny.” And if you’d like to tweet
about this session, use these hash tags, so– #io2011 and #Geo. So now what are we gonna
talk about today? Uh, the title is “Map your Business,
Inside and Out.” Uh, what does that really mean? Let’s just have
a quick flick-through of what we’re going
to talk about. So first of all–
mapping business locations, so essentially mapping,
you know, all the locations of your business
or your store across the world, uh, and you’ll end up
with something like this. Then we’ll move on to seamless
overlay of floor plans, so if you have, uh, imagery– This is the Moscone Center.
This is the I/O floor plan. If you have something similar
for your own business, you can overlay that
on Google Maps and seamlessly integrate
with the Google base tiles. We’ll then move on
to annotating that map, so making it useful
for your users to find things indoors. And then also having
a quick look at searching
over indoor features. So you know,
often your users won’t know, you know, the exact location
of what they’re looking for. So this will
help them find it. And then we’ll have a look
at navigating indoors using Street View. So first of all–
mapping business locations. Uh, for this–for the purpose
of this talk, uh, we’re going to use
a case study, and that’s going to be Google. So basically we’re going to map all of Google’s office locations
around the world. So the first thing I did was I went to Google’s
corporate web site, and luckily I found
this JSON feed of all the offices– uh, all of Google’s offices. So basically it’s an array
with details about each office– you know, the office name,
latitude and longitude, the precise location, a nice address
for formatting, and a phone and fax number
in some cases. So the first thing
I wanted to do with this, uh, was import it
into Fusion Tables. So Fusion Tables
allows us to map, uh, many thousands of markers
really quickly and easily. You know,
obviously Google doesn’t have that many locations, but it allows us to map it
really, really simply. So importing into Fusion Tables is quite simple. It supports these data formats– CSV, Microsoft Excel, OpenDocument spreadsheet,
and KML. So I chose CSV for this, and I used a super-simple
Bash script. Uh, and the output of that was a nicely formatted CSV file. So I just hopped
into Fusion Tables, uh, you know,
went into the Import dialog, imported my CSV file, and I ended up
with a table like this. So you know, this–
this data format’s, uh, you know,
kind of interesting. But the first–
but what we want to do is put this on a map, right,
map each of these locations. So what I did was, you know,
I hit visualize map, and I end up with something
like this. So Fusion Tables allows us
to embed this really easily on–on my web site, uh, with just this embed tag. So Fusion Tables would
generate that tag for you, and I’ve actually used
that exact code on this slide. They’re HTML slides. So this is quite nice, because I can go over
and click on– you know, I can click
on a particular location, and I get some structured data
about this. Let’s just actually go
into zoom, back, normal– ’cause I think that’s mucking
with the… So I get some structured data. Um, but you know,
this is– this is not really useful
for your users, right? And you know, you might have
some other existing map data. You might have other markers
that represent other things. So what we can do
is embed this Fusion Table on a Google Maps API map. Now you can tell this is
a Google Maps API map, because I’ve styled it. So you may want
to style your map, you know, to suit
the colors of your business. You may want to brand the map
a little bit. You can turn off distracting
features and labels also. So you know, this gives
the same functionality as the Fusion Tables
iframe embed. Now as I click on a marker,
I get a little info window with the content
of that particular location. So this is really simple to do. It’s just these two lines
of code. I create
a new Fusion Tables layer, parse it in the table ID, and set the map. Um, but you know, this is–
this is still not really useful for your users. I mean, it might be pretty,
but you know, we’ve still got this quite,
you know, frankly ugly representation of that data
in that info window. Uh, so what I’ve created
is a library that makes this
really easy to do. So this is
the storelocator library, um, and it basically helps you create applications like this. You can use any data source. Uh, for example, if you have
an existing MySQL database, uh, you can easily hook that
into this library. But it’s super simple to use
with Fusion Tables. I’ve created a, uh, hook-in
for Fusion Tables into the store locator. So it really reduces
the lines of code to create, uh, store locator. And it also gives geolocation, so that the user is presented with a useful viewport
when they first visit the map. It has location search
including autocomplete. So yesterday we announced
the autocomplete functionality, which you can attach
to any text field. So you know if geolocation
doesn’t give a– you know,
a nice initial viewport, then they can search for their precise location. It has feature filtering, which I’m not actually
gonna show today. But if–you know, if your store
has particular features, uh, then the user can easily
filter using checkboxes. Also it gives support
for directions, so that they can easily find
your business, and a link into Street View. And this is not only
for store finder applications. It’s for any application
where you want to plot multiple, you know,
locations on a map, such as Google office
locations. And it’s going to be
open-sourced. Well, you know,
shortly after I/O, it will be available
at this link. We’re still waiting
on some functionality from Fusion Tables to make–
to make the– for the Fusion Tables stuff
to be really easy. So what does it look like? Um, you know,
it looks much like the, uh, basic Fusion Tables map. Um, but you can see here
immediately that the map is centered
on San Francisco. So basically the geolocation API
in the browser has told the store locator
that, you know, we’re located in San Francisco. And as I click on a location, you know, such as the Google
San Francisco office, I get a nice,
formatted info window, uh, with the address
and title, you know,
the name of the location. And for the purpose
of this talk, we’ve added Moscone West
as a location, you know, just to make it
a bit exciting. So you know, that’s still
not really compelling, right? Um, so you know, I’ve created this, uh,
store locator panel component. So you know, here I’ve put it
on the left. It’s just positioned using CSS. So you can put it
anywhere you like. Maybe on a mobile device,
you’d want to switch between the map and the panel. And so basically
it’s just that one line of code. I give the panel
the DOM element, so basically a div
that I’ve placed on the left, and the panel gives us some really nice functionality. So you know, once again, we’re centered
on San Francisco, but perhaps we want to look
at Mountain View. So I can go here,
hit Mountain View, and you know, the first location
is the Mountain View campus. So I can click on the left,
you know, to find the closest location, uh, to the–to the–
in the viewport. I can go and get directions
straightaway. So this is going to go
from downtown Mountain View to the Mountain View campus. And I can, you know,
drag directions, and the panel on the left
is updated. But let’s say, uh, you know– let’s go back to San Francisco. Uh… Oh, so we’ve got directions.
So you know, if the user decides they’re actually
in San Francisco, the directions are updated. So let’s close that off and zoom back in
on San Francisco. And you know, as I zoom in, um, you know, I get an outline on the Google Maps base tiles of the–the outline
of the Moscone Center. So the next thing
Brendan’s gonna talk about is overlaying a floor plan
on that outline. Kenny: Thanks. So as Chris was saying, we’re down at the level where,
uh, you can kind of see the–the outline
of the building, but not much information
is there. It’s kind of the, uh,
you know, we’ve got a typical Google Maps
building here. It’s, uh, pretty detailed
for Moscone West, um, but there’s no information about what’s going on inside. And so that’s what we want to–
we want to do. We want to overlay some kind
of floor plan on top of that, and we have
a lot of different options. And it turns out the options
are pretty much what’s available for overlaying
any information on top of Google Maps. Um, it’s just a matter of scale. Because JavaScript
has one numeric type, uh, its double-precision
floating point, um, it has enough precision
to, you know, specify geolocations well below, you know,
the pixel limit. So you can specify
georeference data, um, like, arbitrarily
as precise as you want. So we have two kind of classes of, uh, of ways
of overlaying data, and it’s pretty much the classic
computer imagery split, uh, between vector
and raster data. So first we can talk about
kind of vector floor plans. This is, uh, kind of a classic
vector graphic, where it’s just
a very simple line drawing. Um, and so typically, um, as most people already know, vector graphics are specified with kind of point data and then some kind
of connecting data that–that says that lines connect these points
or curves, or that the–the points
form a closed loop, uh, to make a polygon. Um, and the advantage of that
is that you get to specify with just a little bit of data, um, kind of detailed, uh, you know,
arbitrarily scalable images. Um, and that’s great, but as soon as you
start adding detail, you start kind of approaching
that limit where you– you–if you start drawing in,
like, you know, trees and–and bathrooms
and scale–uh, and stairs and that sort of thing,
you start approaching the point where you might as well
just kind of, uh, give kind of bitmap data
instead. So there is that–
that limit. But if you can keep
your drawing simple, it’s a great–great. Um, the other downside can be kind of parsing and computation time on the client side,
if that’s where it’s displayed. Um, the–the data comes in, but then depending
on how it’s displayed, uh, you know, it takes– whether it’s Canvas or WebGL or, um, you know,
if we go SVG or VML, that sort of thing,
it can take processing time. Um, so if we look at kind of
the simplest way to do vector data
in the Maps API, um, we start with kind of
the geometry classes. This is the polygon object, and there’s other things
like poly lines, that sort of thing. I don’t really know
what that’s supposed to be. We can say it’s, like,
kind of the view of a visitor in the lobby
of the Moscone Center. Um, and it’s really simple. You just provide a paths array, which is just an array of latitude and longitude
coordinates, um, and then you kind of give
styling information, based on the stroke
and the fill. And, uh, and then you
just add it to the map, and that’s literally it. Um, and you can make, you know–
you can start tracing out paths and outlines
and that sort of thing. And what’s great about this
is that because it’s– it’s added on–on, uh, it’s specified
on the client side, um, you can actually
kind of make dynamic data. So if, like a floor plan changed
based on the time of day or the time of year,
that sort of thing, um, there’s no reason
why you couldn’t just, you know, specify that latitude
and longitude array dynamically and–and give a different, uh, set of coordinates
for that polygon. So next up, uh, if you want to get
a little more complicated, you can actually use KML. And it’s–it’s just that simple
as you create a KML layer and give it a URL that points to your file
available online. And KML is great, especially if you already have
kind of a workflow that involves KML, if you have–if you use
kind of geospatial products that output KML, or if you use stuff
with Google Earth, you can use the exact same
KML file with Maps. Um, what’s interesting
about this is that because KML
can get quite complex, um, what happens is, is Google’s servers
actually fetch that KML file, uh, parse it,
draw it to tiles, and then send that
to the client. So, um, that’s great. That means, like,
older computers, um, and–and less-able browsers, um, have no problem with
kind of more complex files, um, but you do lose a little bit in kind of being able
to dynamically specify things. Uh, you can still do it
on the server, but it’s a little less flexible. Um, so that’s kind of the– the vector side of things. Um, if we think about, uh,
bitmap data, this KML kind of straddles that, because it comes down
as image tiles. And Fusion Tables kind of falls
into the same place, where it’s specified, um, it can be specified
with kind of shape files or other, uh, geographic stuff, but then it’s sent down
as tiles. So thinking
about raster floor plans, um, if you want something
like this, where you kind of have
this nice, uh, drawn, you know, quality where
somebody considered each pixel, um, especially this level is when you should
start thinking about kind of
raster floor plans, thinking about bitmap data. Um, so the benefits of this is that–is that the size
is constant, based on tile size. You know, the number of pixels
that you have are the number of pixels
you get, and you can actually specify
much more complex shapes, but it’s–you know,
the data size is fixed based on the number of pixels
you actually send. On the other hand,
it’s certainly not as dynamic. You’d have to do things
on the server side. Um, and–and it can be
quite a big bigger, if you just are giving
a very simple– if it was just a simple outline, um, you’d have to specify
every pixel, um, kind of instead. So the very simplest way to put a-an image on the map is–is the ground overlay, and it’s–it’s, uh,
it’s pretty much dead simple. You tell Maps
that I want this image, and I want it
in this BoundingBox, and it just puts it
on the screen. Um, and it takes care
of the fact– you know, as you scroll around,
it keeps the image in line. And as you zoom in,
it correctly places–places it. Um, and so that’s great. You know, it’s like 4 lines
of code, like 20 seconds. If you already have
existing imagery, um, this works really well. And in addition, uh, the–
the BoundingBox is flexible enough,
at this level especially, um, where the earth
is essentially flat or kind of local
elevation stuff takes– takes over, um, as opposed to kind of
larger-scale curvature, where you can essentially
just think of it as an affine transform to place that correctly,
uh, and keep it in line. Um, the problem is, as we zoom in, you can start to see the problem
with a single fixed image. Um, Maps handles it well, but there’s nothing you can do
when there’s no more pixel data. You start seeing the pixels
as you zoom in. Um, and so the–
the classic fix for this is the–is the image pyramid. It’s been around forever
from MIP Mapping to kind of those deep zoom
kind of things. Um, and the idea
is that you start with a high-resolution,
uh, image, and at successive levels, uh, you–you reduce the size, uh, and resample
to get some really nice, uh, lower, uh, higher zoom– let’s see,
zoomed-out imagery. Um, the nice thing is
because you’re off– you’re doing this offline, you can do, like, a really
high-quality resampling and keep things, you know,
really looking good. You’re not dependent on whatever
algorithm the browser uses to keep things real-time. The other nice thing
is that you can actually, uh, change the level of detail
as you zoom in and out. So for instance,
uh, like on Maps, when you start out at–
at a city level, you only see major features
of–of the city, but as you zoom in you start
to see building outlines. There’s nothing to prevent you
from doing that. You could start
with a very basic outline at the top level,
but as it–as somebody zooms in, you can start adding
kind of, you know, rooms, walls, and–
and other details from the sandbox area. So here’s that in action. Uh, it’s–it’s
the ImageMapType object. Um, and when you create it, the, uh, the most important part is this getTileUrl. This is the main functional
part of the class. Um, and what it says is, is when you add this to the map, and Maps loads a certain area
of the world, um, it asks this method– so at this coordinate pair
and at this zoom level, what image should I show? And so in that method
you would, uh, have some, uh, procedure
for determining a URL. And so on the server side, typically you have
a bunch of tiles. You’d have some kind
of systematic naming method, which we’ll get into
in a little bit, um, to return the proper tile, uh, and then you just insert it. And so what’s great about this
is we now see we’ve added
kind of dashed red lines here so you can see the tiles. At this level we have, you know,
five tiles make up this map. But as we zoom in, un, it actually loads new tiles, um, that have
higher detail level. The tile size stays fixed, but we get more detail
as we zoom in. And so now we can see that, uh, you can see
really nice, high-quality things
from the Android level. So, um, the–the final thing with adding this–this, uh, this raster data
for your floor plans is obviously the Moscone Center
has, uh, three different floors, and you might want
to explore those– those different levels
before you get there. So to do that, uh,
it’s actually pretty much exactly as straightforward
as you would think. You want to add these–
these maps. And as you select floor two
versus floor three, you want to hide the floors
you can’t see and show the floor that you
can–that you want to see. Um, so we take this–
this data, we–we generate–
generate that image pyramid, uh, for each floor. Um, and then… on the map itself
we just add these buttons, uh, that on a click event kind of change this variable,
this floor variable, um, and so change a diff–
show a different floor. And so the code to do this– uh, let’s see. There we go. So the floor–the code
to do this is–is really simple. So we have this kind of
floor variable just hanging out. And when a button is clicked, uh, it’s click handler
calls this changeFloor function with its floor number. Um, it sets the floor value, and then it does this–
this kind of tricky thing where it removes
the ImageMapType and then re-adds it. Um, and the reason– or the–what that does is
tells the Maps API just to, um… check all the–
the tile URLs again. Um, it’ll fetch
all the tile URLs again. And if they’ve changed, um, then they’ll load
a new image. And if they haven’t,
they’ll keep the same image. And it works well, because it actually works
with the browser cache. If–you know,
if it’s seen a tile before, it won’t fetch the tile again,
but it will check– it will change the URL. So here you can see– this is the getTileUrl
function again. Um, and it’s–it’s still
just coordinate and zoom level. But you see where we’re
redirecting it to, uh, another function
that has an idea of–of how floors
figure into things. And here it’s really simple. We just have kind of a level–
floor number, and then construct this, uh, this URL
out of that information. So… that makes it really easy. Like, Maps makes it really easy
to put that on the map. But what I’ve
kind of not mentioned is how you actually get
that imagery onto the map. If you’re, you know,
a geospatial professional, you’ve had that problem
figured out, you know, for decades now. Um, but if you, uh, just want to get
a floor plan on the map, uh, it’s not so easy. There’s–there’s tools,
but it’s kind of hard to tell what’s going on. So Chris is here to–
to help you out. Broadfoot: So as Brendan said, if you’re not an expert
in this stuff, uh, it’s kind of hard, right? Uh, so I’ve had, you know,
a bunch of people ask me– I started Google– at Google
about eight months ago, and I’ve had people ask me
how to do this stuff, and I kind of point them
towards these tools. But before I agreed
to do this talk, I’d not actually done it myself. Uh, shameful to admit,
but, you know, it’s hard. Right? Um, so you know, there’s tools to help you to do this stuff. There’s the great
gdal2tiles, uh, utility. You basically run it
from the command line. It’s a Python script. You know, it’s as simple
as specifying an input file
and an output directory, and it just goes and magically
generates these tiles for you. Pretty simple, huh? Um, and if that’s
not simple enough, there’s, uh, there’s a GUI to it
called MapTiler. And so that–
it’s pretty nice. If you’re interested
in this stuff, go check out MapTiler
at maptiler.org. But you know what? You know, we–we got this image
from our vendors for Google I/O. They basically did
all the fit-out. Um, but as you can see, you know, this image
doesn’t have any concept of where it is on the world. In fact, it’s not even
rotated correctly. So you know, this–
for this image to be placed on the map,
we need to rotate it at a particular, you know,
number of degrees, you know, resize it, and get the latitude
and longitude for the bottom left
and top right corners. So you know–
or we could use the gdal2tiles utility and georeference a few points, and it will go
and automatically, uh, you know, transform this image
to place on a map. So you know, all we need are these three coordinates. Pretty simple, huh? Right? So you know–
but I don’t know. I-I have no idea how to get,
you know, exact latitude and longitude
for this image. It’s a bit ridiculous, um, you know,
and would req–would req– would require a bit
of trial and error, I think. So I’ve created this, uh,
little tool, uh, called OverlayTiler. So it basically makes georeferencing
these images easy, and therefore helps you
generate tiles using the gdal utility. And once again,
it’s open source. I’ll upload it straight
after this talk to this URL on code.google.com. Um, but what does it look like? So basically–
let’s zoom out. So basically
it generates two commands. First of all, gdal_translate, which basically specifies
a bunch of control points, in this case
three control points, for the, you know,
top left, top right, and bottom right
of the image, and says what latitude
and longitudes at those pixel points. You know, you give it
an input file, and it outputs a GeoTIFF, basically a georeferenced image. So you know,
there’s no loss in quality. It just goes and adds some more
metadata to that image. And the second command
is gdal2tiles, which we talked about
a little prev–previously. You know, you tell it
what projection the source imagery is from, in this case because we’ve
given it ground control points, uh, on Google Maps, we’re using Web Mercator. And we say we want
to generate tiles from zoom 16 to 19. So you know, you could skip
this second step and use the MapTiler GUI. It will go
and actually figure out what appropriate zoom levels,
uh, should be generated. And it outputs
a nice directory of tiles and in fact
sample implementations using Google Maps
and OpenStreetMap with the overlay on it. So this is a nice little GUI. The first thing
I’m going to do is, uh, change the opacity of the layer, so I can see the base map
below it. And then I can just go
and simply drag these three
ground control points and move the overlay,
you know, into position. So if I can get that right… You know, and this is–
this is really WYSIWYG, right? Um, you know, the tiles
that are generated will look pretty–
pretty close to what’s, uh, what you’re seeing right here. Oh, let’s see if I can
get that right. Anyway, so you know,
if I bump the opacity back up, that’s basically what’s
gonna be generated. So this uses Canvas 2D to transform the image
inside the browser. Um, so you know, a similar
transformation will be done by gdal2tiles. So you know, now that
that’s all done, uh, we could–we could use
the exact same command for all the different floors, uh, because the images are of the same dimension. So next up, I’m going to talk about… annotating that indoor map. So you know, having
that base map is quite pretty. I mean, we’ve got, you know,
great floor plans here. Um, but let’s show some
of the features on the map. So basically here
I’ve added markers, uh, for each floor
and a bunch of sandbox sessions. And you know, I can hover over– let’s see, this is room 5,
room 4. Chrome’s over there. And I can also switch
the markers, depending on the–
the floor shown. Um, so what’s the code
for that like? So basically it’s data driven. So for each floor I define
a bunch of different features, uh, that have a latitude
and longitude and the title that’s shown
on hover. And for each floor, there’s a different set
of objects, and they’re switched on and off
as the floor changes. So the code for that
is on the right. I’ve modified
the changeLevel function to go and remove
the previously shown markers, you know, and then go and add
a bunch of different markers at the appropriate floor, and they’re just regular
Google Maps markers. So there’s nothing special
about doing it indoors. Um, so the next thing
I wanted to do was make this
a bit more exciting. Uh, I don’t know about you,
but, uh, the classic red pin doesn’t really excite me. So I’ve added two different
kinds of markers– blue ones
for the sandbox sessions and red ones for the–
uh, for the rooms. You know, you can get
the same interaction, because they’re just
regular Google Maps markers. Um, but you know, it’s–
it’s an absolute pain to have your users
hover over them to figure out what’s there, so you know, wouldn’t it be
great to have labels, just like there’s labels
on Google Maps streets and for various features
on the world? So you know, I’ve decided
to create another library to do this. So what does it do? Uh, it’s part of
the Google Maps Utility Library, which can be found–
oops, sorry. I thought I had a link there. But it’s part of
the Google Maps Utility Library, uh, which includes
popular libraries like MarkerClusterer. It provides dynamic rendering
of map labels using Canvas 2D. Uh, so you know,
the advantage of this is that you can, uh, dynamically change the text
and position of these markers in the process of creating
the Google I/O map, uh, on the mobile app. Uh, you know,
we were often asked, you know, move this marker
a bit here, you know,
move this label here, you know, switch these rooms–
kinda crazy. So this made it really,
really easy. There’s lots
of rendering options, font size, font face,
color, alignment– basically anything
Canvas can do. And there’s control
over which zoom levels show which labels. So this is really useful
for, you know, showing a different set
of labels at different zoom levels. So as you zoom out,
you probably want fewer labels, uh, so as not to clutter
the map. And it’s going
to be open source, and it will be available,
you know, at the Google Maps
Utility Library page. So what does it look like? This is a really simple label. Uh, you know,
I just say new MapLabel, give it a text
and a position, uh, you know,
bump the font size a little bit, you know, just for this demo. And the great thing
about this is as I zoom in, you know, the marker doesn’t get huge, uh, as if–as though
you’d just laid it on the– you know, on the base tiles
and generated tiles. So you don’t have to change
the size of the text for, you know, each–
each zoom level. It’s just going
to stay the same. So now a quick demo showing
how dynamic this is. I’ve just added a text box
in the top right of the map. And whenever I click on the map, you know, this text is going
to be used to add a new label. So this is floor three
of the Moscone Center. So we’ve got the keynote here– you know, “Android” up over here, and “Room 11.” So you know,
it makes it really easy to go and, uh, you know,
if your data changes a lot or you want to have
user-generated content, uh, for example,
if you, you know, have your office staff
go and be able to edit the map, this–this makes it
really possible. So I’ve just gone
and added labels for each of those markers. As before,
as I switch through the floors, the markers change. And you’ll notice, you know,
in a bunch of places I’ve got a label but no marker. And as you–as I zoom in, you’ll see I’ve added– in the previous zoom level,
there were no markers up in the sandbox, because it would be
too cluttered, and as I zoom in,
they just appear. And so they’re
also right-aligned. If they were center-aligned,
like in the default, the–the markers
would interfere and you wouldn’t be able
to read what’s there. So you know, these–these labels
are really flexible. Uh, and it was a huge win when we were making
the Google I/O map. So I’m gonna talk
a little bit now over–about searching over
indoor features. So you know,
often your users don’t know exactly, uh, you know,
the location of what they’re looking for. So I’m gonna demonstrate,
you know, a simple way to enable this. So you can see here I’ve got a little search box
in the top right. And basically
what this is gonna do– it’s going to filter the–
filter the markers on the map. So you know,
as I type in “room,” I’ll see all the rooms. Also, I think the toilets
are called washrooms, uh, you know,
press room, et cetera. You know, if I search
for “toilet,” I just see the toilets. “chrome” and “geo”– so I can see the Geo sandbox as well as, uh, the room
we’re in right now. I added a little bit
of metadata to that to say, you know,
this is Geo. So you know, this is–this is
all done on the client side. Uh, it’s really quick. It’s not exactly scalable. Uh, you might want to have– uh, have that text box actually, you know,
go and ping the server to go and bring back
new markers. And you know, for example, if I want to see, you know,
the toilets on every level, I can switch through them
as well. So the code for that’s
pretty simple. Um, I’ve gone and modified
that addMarker function we saw previously. And you know,
it’s basically a giant hack. It just goes and does regex over a bunch
of different fields and just filters–
filters the markers out. Um, so yeah, as I said,
not scalable– there’s definitely better ways
to do this, but it’s a really great feature
to add to a–to an indoor map. So Brendan’s gonna talk now
a bit about navigating indoors using Street View. Kenny: Yeah,
so Street View is great on maps, you know. If you are searching
for a place on a map, uh, it’s one thing to find
kind of the intersection or kind of which part
of the block something is on, but it’s another to actually
kinda go down into Street View and actually see kind of the facades
of different buildings. And it’s the same thing
with kind of indoor mapping, um, or really any kind of,
like, place where there is
no Street View coverage. Um, it could be parks. It could be, uh,
college campuses, what have you. Um, so it’s actually
extremely easy to use Street View, and I’ve been kind of sad
that there hasn’t– or to make custom Street Views,
and I’ve been kind of sad that there–there haven’t
been enough. But there is kind of
a barrier to entry, just in kind of–it looks
more complicated than it is. Um, so here’s a couple of really cool ones that have been done. Uh, this is an agency in France
called Digitas. Uh, and for their
Christmas card, they made these, uh, this kind of walkway
into their– into their office building. And they even did
this kind of, like, pseudo augmented reality thing
where they– they put these arrows and images
into the, uh, into the Street View panorama. And so you can see
only a few meters away– exciting. Exciting. And there we go. Hooray. Um, let’s see. Uh, and here’s one the same
agency did for Nissan, and they did this other
pretty cool effect where they actually did
kind of long exposure, uh, long exposure, so they
could write with, uh, with lights–
lights on a stick, so… So how do you make
your own Street View? No, thank you. So… Street View is done
actually, uh, pretty much the same way that, uh, Maps itself is done. It uses the exact same
projection that we use, the equirectangular projection, um, to map from a sphere, or a spheroid, uh, onto kind of a flat surface that we can tile
and represent easily with–with images. Um, so if you can kind of
imagine yourself at the center of a sphere
and looking in each direction, um, at every point
that you can address, uh, there’s–
there’s a certain color, and that–that becomes
your pixel element. Then we use kind of
that latitude-longitude grid, so we can actually give
that point a name. And when we unfold it, uh, it becomes
this rectangular image, just like a map, and we tile it
just like a map, and then we can use
that same, uh, kind of image pyramid technique
that we talked about earlier, um, to provide
more level of detail and really fast loading
on that first zoom level, but then progressive amounts
of detail as the user zooms in. So yesterday Chris and I
went downstairs, and we took some pictures
of the lobby and then used, uh, just kind of a popular
image-editing program to–to stitch ’em together. There’s–there’s a lot of these
available now, um, and this is just
the one that we chose. Um, it kind of starts
placing the images in place. Um, obviously, you know,
it’s not the– what you’d want to use, but it kind of shows you
how they start getting aligned to get the geometry correct. Um, there we go. Then once the images are
stitched together, it can do this kind
of geometric correction. So it actually aligns them
together, and you get the proper, uh, projection
to make things line up when we put it back
onto the surface of a virtual sphere. So the code to do this
is pretty easy. Um, it’s a little more
complicated than ImageMapType, just because we need
to provide, uh, not only a tile
for a certain location and zoom level, but also a Street View
node has a– kind of a location itself
in the world, so that we can kind of locate
them relative to each other and then link them together. Um, so in this–
so here we–we, uh, create a new
Street View panorama, which is the view. Uh, we pass it
these panel options. And the options just say, um,
that we want to start at this–at
the pano ID of lobby, the panoramic provider
that we’re about to give, uh, with the IDed lobby. And we–we say
the panoProvider, the object that’s actually gonna
provide the Street View data, um, is at this–
is this object right here. Um, so–well, it’s actually a
function that returns an object. But that’s–that role
is usually filled in by, uh, by Google Maps itself, and it requests that data
from, uh, from the Google Maps servers, but there’s no–no reason
that you can’t put your own custom object there
and kind of intercept those calls and then answer
with your own data, uh, which is what we’re
gonna do here. So that gets–
getCustomPanorama is a function that returns
an object that–that gives, uh, it’s– it has a location,
um, in the world, and at that location,
it has a kind of, uh, heading that points north. It has a pano ID, which is just a string that
we’re gonna use to identify it. And then it has this getTileUrl
you can see, which is that
same exact, uh, method that has–that provides
URLs for images for a certain view. Um, and finally,
so we just pass it once again
to a really simple, uh, method that just appends some strings and produces a URL that gives
the proper, uh, image URL for a certain zoom level and certain tile coordinates. It’s a little bit different
from latitude and longitude, uh, but it’s actually
the same. It’s just not the same
numeric scale. Um, so here we’ve taken that–
that tile– or that–sorry, that image
that we produced of the Moscone lobby, and we’ve made tiles of it, and then now we put it
in Street View. So this is just a normal
Street View with imagery that we provided. There’s a guy
kind of checking his phone. And there’s the–
the entranceway and escalators, et cetera. So now we have kind of a sense
of where we are. Um, but it–it also feels
kind of lonely, like I made a photo panorama in, like, 1997 in a Java applet. So, like, that’s cool,
but what’s really cool is having the notion
of–of Street View as this interconnected network, uh, that you can travel along
and get a sense of space. Um, so to do that, uh, we kind of augment
that panoProvider. This is the same
panoProvider object. Uh, we still have that lobby ID.
We still have a location. Um, we have a nice description
that shows up on a screen, but now we have
this links array, which is an array of objects
that describe the panoramas that
that location can link to. Um, so it hinges
on that pano ID again. So we’re gonna link
to the Android floor. Um, and it has a heading,
which we’ll just say those, uh, those nice
street markers that–that are overlaid
on the image, uh, should point at 262 degrees, uh, from north. It’s kind of a compass bearing. So–and then finally, this is just the same
getTileUrl. Nothing’s that different. And so what this
enables us to do is take
two different panoramas– we took this one originally– and now we can link
to the Android level… and go right upstairs and always go back down. I think–I don’t know. It’s a time-traveling
Street View. It’s cool. If you go in there,
Jane’s Addiction is playing. Um, so… I think we’re gonna tempt
the demo gods here and actually show you the–
the full kind of experience. So we start at the store locator level. Um, and we’re actually already
in San Francisco. So here’s the Moscone Center, and as we zoom in, we can start to see… our imagery already
overlaid on top. And… here we go. It’s loading. Um, here’s outside
the Moscone Center. We’ll point this way.
It’s a little prettier. And then if we–we now have
this custom link here, um, which is added
in the exact same way as we showed before, where we just link
to a public, uh, public Google Maps,
uh, panorama ID. Uh, so Street View imagery
actually resides on your own server. It’s provided by you. Um, and obviously,
we wouldn’t link to kind of arbitrary
Street View things, ’cause you know, you can put
anything you want on there. So I–you know. Um, but what you do instead
is when you get a panorama ID from Google Maps–
sorry, from Street View– so when somebody says, “I want
to see a Street View here,” you actually just, uh,
intercept that and add the same link
that we showed before. You just add a link
with the object that points to this location. And, uh, and you can always
head up to Android, um, go back to Moscone lobby, and exit again. And there we have it. You can even see–
actually, I didn’t mention this, but this is a really nice–
it just does this automatically for you. Because we were searching
for the Moscone Center, uh, and it put a marker
on the map, uh, Street View automatically
places that marker in the world correctly. So we can see–that’s what we
were searching for right there. Um, so that’s–
that’s all we have. So if you have any questions,
please come up to the mic, and we’ll be happy to–
to answer them. [applause] man: So a quick question– for all this sort of metadata
and stuff that we’d be creating
for our own apps, is there gonna be any way
to potentially feed that back into search results
or something else on the larger Google Maps? I’m thinking of, like,
stores at a mall or products inside a store,
where you have levels, a hierarchy of location.
Kenny: Right. Do you mean, like,
Google search proper? man: Yeah, in any way–
I mean, it’s sort of– you know, a lot of times
if you’re searching for a store within a mall…
Kenny: Right. man: it can be hard,
so if the mall decided, let’s make a detailed map…
Kenny: Right. man: how could that sort of
be bubbled back into– is that part of the plan or no?
Kenny: Yeah, you want to… Broadfoot: Um, so I don’t really
know too much about that. I work more from
the developer perspective, kind of enabling you to put this
on your own web site. man: Sure.
Broadfoot: Um, but yeah, I see that would potentially be,
you know, quite good for Google and users. Um, but yeah, I don’t know much.
Come talk to me after. man: Okay.
Kenny: Yeah, that’d be great. Um, business place pages,
you know, is a good place to start. man: Um, I just have
a similar question. To add, like, more media to– to, like, to the pins, like sound bites or video–
is that an easy thing to do, or is that something
in the works? Kenny: Yeah, it’s just HTML,
so you can put a click listener. You can do any sort of, uh,
event listener kind of thing and trigger, you know, audio.
You can put things. And, uh, and we didn’t
show this, but you can actually–it’s–
people are getting, uh, cool results from doing things. Instead of just
overlaying images, you can overlay a canvas
like Chris showed when he– when he, uh, georeferenced
that building. WebGL video–somebody made
a cool Mandelbrot explorer where you could zoom in
really far with Google Maps. Broadfoot: So if you’re going
to use the storelocator library, and I’d love you to, uh, there’s actually an event
that’s triggered whenever the stores– whenever the, you know,
selected store is changed, so you can hook into that,
maybe, you know, ping back to your server for,
you know, some more stuff, show it anywhere on the page. Kenny: Play your store’s
theme song. Broadfoot: Yeah.
Kenny: Yeah. man: For the custom Street View, is there any way to integrate
with the Pegman UI and get the blue lines
and stuff? Broadfoot: Uh, not really. I mean, that’s
a really hard problem. Kenny: Yeah.
Broadfoot: I mean, you could– you could show your own
overlay on top, but you know,
if they intersect, it’s, um, yeah, that’s not really–I mean,
that’s a really good question. man: So there’s no API level
support for that right now? Kenny: There’s no API level
of support. ‘Cause–so the–the blue lines
come down as image tiles, so they’re already prerendered
on the Google servers. So you’d kind of have to, like,
tell Google, I have a location
at this point. They would add it to the tile. So it’s not feasible
at this point, but you could certainly overlay
your own, you know, blue line on that segment,
and it would, you know– because they’re mostly
transparent pings, they would overlay
correctly together. man: So if we made
our own map tiles, then is there a way to use
the same Pegman that you use? Um, ’cause right now when you
drag in your Pegman, it comes up with
the Street Views of the road. But can we intercept
that somehow so that it’s seamless
for the user? Broadfoot: Yeah, actually, no.
You can’t–you can’t get, you know, the drag start
for the Pegman or something like that.
man: Okay. Broadfoot: But yeah,
that’s a great feature request. man: Okay, thanks. man: Actually,
about his previous question– I thought you could do stuff
like that with Fusion Tables. If I loaded a KML shape
into a Fusion Table, I could just fuse that in
and get it back and rendered… Kenny: Yeah, yeah. It’s just a matter of, uh,
you know, how interoperable they are. But if you want to replace it
completely with your own blue lines,
like, that’s–sure. man: Um, so my question was
a little bit different. So let’s say, uh, if we go
back to the Moscone view where you had all the, uh,
kiosks set up, and let’s say it’s
the conference– these rooms here,
and I wanted to click on one of those and get
what the next session was. Kenny: This one?
man: Um, in order for me– Broadfoot: Sure, um…
man: So in order for me to do that, I need to be able
to intercept that event and convert it
into the coordinate system that my original metadata is in.
So is that part of the API? Broadfoot: So–so you’re talking
about inside Street View, clicking it? man: Uh, whether it’s inside
of Street View– well, Street View
would be cool to, but, um, whatever metadata
I’ve overlaid on top… Broadfoot: Okay, sure.
man: or whatever visual– visualization
I happen to be using, I need to be able to convert
my gestures back into that entity, whether it’s
in a coordinate system that I’m dealing with, or you can link it directly
to one of the entities– I need something to latch onto,
so I know what it is that the user
is interacting with, so I can provide
the appropriate… Broadfoot: Sure. So have
you used the Google Maps– uh, the Google I/O map
on the Android app? man: I have not yet.
Broadfoot: Oh, so we’ve actually got some really nice
integration there. Whenever you click on–
on a marker pin on your phone, um, it actually, you know, uh, tells Android, the native app, that, you know,
something has been clicked. And some–you know,
a little thing slides out and shows you the sessions
that are coming up. man: So I don’t want to use
the markers, ’cause red or blue
or whatever–I hate ’em. Broadfoot: Right.
man: So let’s–let’s think about a conference room outline…
Broadfoot: Uh-huh, sure. man: right,
where I’m gonna book– I just want to book this room
that I’ve just clicked on. Broadfoot: Sure, okay, I mean,
you could use a polygon. And in the same way you could
listen to a click event. Um, or if, you know– or if polygons are even,
you know, too much to do, you could, you know, listen
to a click event on the map and send back those coordinates
to your own server, which could then maybe
send back, you know, what was clicked there,
or you could use Fusion Tables. man: [speaking indistinctly]
Broadfoot: Sorry? man: Your APIs
do the translation into the base
coordinate system, or… Kenny: Yeah, you can–
you can project back the latitude and longitude
coordinates, yeah. man: Okay. All right, Thanks.
Broadfoot: Sure. man: Even with rotation
and stuff like that in the map, you guys do the translation?
Kenny: Yes. Well, I mean, so–
so the Maps API doesn’t support rotation now.
man: [speaking indistinctly] Kenny: It does on mobile,
but–but, yes, that would– that would be added along–
when rotation is added, then, yes, definitely.
man: All right, thanks, guys. man: Um, are these cool features well-supported in
mobile, uh, browsers, uh, typically like Android
and iOS? Broadfoot: Uh, so what–
what specifically? man: Um, I mean,
most of the features– are–are they–
are they supported? Broadfoot: Sure.
I mean, so generally, the Google Maps API v3 was designed
with mobile in mind. Um, so you know,
things are really quick to render on mobile. Uh, you know, a lot of work
was done to reduce latency. And so all of these features
that are showing here are supported on mobile as well. In fact, you know, this map
that you’re seeing here is essentially the same
as the, uh, the map you see
on the Android I/O app. man: So, um, any thoughts on how to tell the user where they are
on this map? Because this room
is pretty nondescript, and I don’t know
that I’m in room 7. Broadfoot: Sure. Um, you know,
a lot of work has been done about indoor geolocation. Um, I don’t–I don’t really know too much about that. Um, you know, it’s quite coarse,
from what I understand. You know, but it’s… Kenny: Yeah, it’s
a really hard problem, because not–I mean,
not only are you kind of in a nondescript room, you’re also blocking
all the signals from things that want
to get to you. Um, so there are–I mean,
there are ways of doing things where you can actually
put kind of– essentially beacons
inside a building, but they’re all pretty much
custom solutions. There are also
really interesting ones where you can do kind of
machine vision, like, kind of figure out
where you are based on, like, if you actually take a picture,
but, um, but nothing automatic. It’s a hard problem,
and you know… man: Hopefully somebody will
figure out something cool. Thanks. man: Hi. Is it possible
to play some video in panorama mode
somewhere in the– the tile
in the Street View? Broadfoot: So–so the question
is, can I put video, uh, you know, on the map
or Street View? man: Yeah.
Broadfoot: Uh, sure. I mean, uh, we have a concept
of an overlay view in Google Maps,
which essentially lets you put any DOM element
on the map, and it can be attached to a particular latitude
and longitude. So it’ll be dragged around.
Um, that’s certainly possible. In Street View–not so much,
I think, yeah. Kenny: Yeah, it won’t be
correctly place. But, uh, there’s no reason–
I mean, because it’s just– It’s HTML. Like, there’s no
reason why you couldn’t insert into there–yeah.
man: I was just asking. Okay, thanks. Kenny: Great.
If there’s no more questions, thank you very much. [applause]

You May Also Like

About the Author: Oren Garnes

10 Comments

  1. Oh that overlay-tiler is just too convenient and cool! I had to do my building by hand. Take a screenshot of Google maps, import my vector floor map into Photoshop and rotate and scale until it fit, then get all the transformation values and move those back into to my master image frame before exporting tiles.

    It's also nice to see how much progress the Maps API v3 has improved over the last year. Developers don't need to do everything manually, like I did back then. Time to rewrite my maps…

  2. Can I create an interactive site where i have all my buddies, clients and business on the Google map? What is the legal limit? Can I have 1 million addresses mapped on my site?

  3. @ObjectOriented64 @magicfrog75 @esamsoe & others: Hi guys … Overlay Tiler UI is open sourced. The rest is still in progress. code.google.com/p/overlay-tile­r

  4. I don't understand how to use the data got from the overlay-tiler. Anyone please suggest me.

Leave a Reply

Your email address will not be published. Required fields are marked *