Have questions about buying, selling or renting during COVID-19? Learn more

Zillow Tech Hub

Tile It Up!

My favorite feature of the Google Maps Android API v2 is the ability to quickly and easily add TileOverlays to a map. Google really opened doors for the Android community with this feature. At Zillow, it allowed us to display content on that map that is relevant to a home search such as property lines and school attendance zones. With Google Maps Android API v1 we would have had to implement our own tiling layer perhaps with a Canvas overlay, which gets expensive for those with low-end phones with limited memory resources and could become expensive to maintain.

Google Maps V2 with the Property Line Data Overlay

The new TileOverlays is so easy utilize that our first tile overlay that Karen Milfeld, a fellow Android developer on our team, took literally an hour to implement and display data onto our maps. The first layer we added was property line data, which we had already generated PNG tiles for on the server-side. This meant that all Karen had to do after reviewing the documentation was define the getTileUrl( int x, int y, int zoom ) method for a UrlTileProvider to hit our server with an x and y coordinate and zoom level and then add the TileOverlay to the MapView. Keep in mind that the map projection of the tiles must match the one that Google uses. Google handled downloading the tiles, caching, and panning of the map for us. Frankly it was as simple as the following four lines of code:

// Create a URL tile provider for land parcels.
GoogleParcelUrlTileProvider parcelsTileProvider = 
    new GoogleParcelUrlTileProvider( PARCEL_TILE_IMAGE_SIZE, PARCEL_TILE_IMAGE_SIZE, parcelConfig );
// Create a new tile overlay options object and assign the tile provider to it
mParcelsTileOverlayOptions = new TileOverlayOptions();
mParcelsTileOverlayOptions.tileProvider( parcelsTileProvider );
// Add a new tile overlay to the map with the given options.
mParcelsTileOverlay = getMap().addTileOverlay( mParcelsTileOverlayOptions );

More recently we decided school boundaries were the next piece of useful data that we wanted to add for our users in the Android app. If you haven’t checked out our school data in our app, go ahead and give it a try (download our app from Google Play)!

School Boundaries on Google Maps v2

The Zillow team had created an internal API that defined tiles as an array of pixel points that we needed to draw to create a tile since the tile at x, y and zoom level z could be different based off your search criteria. This allowed Zillow.com, iOS, and Android to manage drawing and transferring the data for the various combination of attendance zone lines more efficiently that using PNGs. For our Android app, this meant that I had to define a TileProvider, and draw the tiles based off the point data that we got back. The heavy lifting was just making sure the tiles were drawn efficiently, but otherwise, it was just as clean as with the parcel data with a definition for getTile( int x, int y, int zoom ) for TileProvider. Then we plugged the following in to get it onto the map.

mSchoolBoundaryTileOverlayOptions = 
    new TileOverlayOptions().tileProvider( new SchoolBoundaryTileProvider( getContext() ) );
mSchoolBoundaryTileOverlay = getMap().addTileOverlay( mSchoolBoundaryTileOverlayOptions );

Google handles displaying the tiles and caching the tiles as you browsed, while we handled creating getting the data and creating the tile.

School Boundaries on Google Maps v2

There were a couple nuances that we had missed during our implementation. For a UrlTileProvider.getTileUrl, if there is an x, y, zoom combination that you don’t wish to provide a tile for, you must return null. However with the TileProvider.getTile, you must return NO_TILE – not null! Otherwise the TileProvider will keep making requests for the tile with an exponential backoff. We found that this ended up causing us to leak MapViews.

Keep in mind also that if you are going to draw your tiles client side (which we recommend for the sake of the user’s data plan) that you should cache the data you get for the points in case the tiles get blown away. At least then you still have the data if it is data that doesn’t change often.

If you interested in any part of the pipeline of getting this data into the API to display in our apps, check out the job openings we currently have at the company!

Tile It Up!