Social Recruiting: Google App Engine Experiments 3

My latest experiment is a “social hiring” tool built on top of Google App Engine: zenthousand.

We don’t have a tech talent crisis in America, we have a hiring crisis. Between clueless recruiters and the oblivious companies that rely on them, it’s no wonder nobody can hire effectively.

The thinking exhibited by a lot of employers is if you actually respond to a job post or are actively looking for a position, you must be a total loser. The race is on to hire people who don’t want a job. So, I decided to build a site that pulled in data from Github, Meetup, Stackoverflow, Behance, and other social networks developers gather on to allow people to search for so-called passive candidates. There are countless startups doing the exact same thing under the banner of social recruiting.

This didn’t deter me because last time I tried to build a startup it was something nobody else had done before. It turns out, doing something that’s been done half a dozen times is preferable–at least to investors. Plus, it really didn’t seem that hard to make. How is it that so many companies have raised rounds to do something seemingly so trivial? I wanted to find out.

It took about 3 weeks, but the end result is zenthousand. It’s rough, buggy, and features a useless and sparsely populated database. Still, it gets the point across. Sign up for an account and start searching for candidates based on location and skill set. Bookmark the ones you like so you can browse and annotate them later. Oh, and the paid options use Stripe for billing, but just use the free demo account to test it out. I don’t expect anyone to actually pay for this in its current state.

Building a service like this is like being a detective. Think about where developers hang out and what footprints they may leave. Then write an algorithm using publicly available APIs to extract this information and organize it in a searchable way.

The location search isn’t very accurate–try using no location for more results. I’m using Google’s beta search API which seems to have some bugs in it. Also, not a lot of Github profiles have location attached to them, so I have to spend a bit more time trying to sniff out where candidates are from. I have yet to run the Meetup and Stackoverflow crawlers either, so most profiles only have a Github profile attached.

Most social recruiting startups claim to use big data analysis to detect how skilled a candidate is in specific technology. This is absolute nonsense. No algorithm can overcome Dunning-Kruger. There is no substitute for an interview facilitated by someone with expertise in the area you are hiring for. That’s not to say big data algorithms aren’t useful for filtering candidates by what’s relevant to the user.

Zenthousand was a 3 week crash course in Google App Engine with Python, social network APIs, and finessing an interface with Twitter Bootstrap. As much as I’m infatuated with GAE as of late, I think a big data service like this is too expensive to run on it. If I take this project further, I’ll most likely re-write the GAE-specific parts, migrate to MongoDB, and move the whole thing to Google Compute Engine or a colo.

Displaying Maps in Unity3D

There have been a few recent examples of real-world maps displayed in Unity3D apps. The first one I noticed was the playfield in the infamous Halo 4 iPhone app that came out late last year. For unknown reasons, I was really into this game for a few months. I hung around my local 7-11 scanning bags of Doritos so much that I thought I was going to get arrested for shoplifting. Eventually this obsession led to me wanting to duplicate the map display used in the game. Here’s how I did it.

Google Maps Plug-In

Naturally the first place I looked was the Asset Store. It turns out there is a free Google Maps plug-in available. The only catch is that it requires UniWeb to work. UniWeb lets you call REST APIs and generally have more control over HTTP requests than Unity’s own WWW class allows. It can be a necessity if you’re using REST API calls but it restricts your code stripping options. This will bump up your binary size.

This asset’s sample scene works flawlessly. It downloads a map from the Google Static Map API and textures it on a cube. The code is clean and well documented, featuring the ability to request paths and markers to be added to the static map. Most attributes can be tweaked through the inspector–such as map resolution, location, etc.

I made a lot of changes to this package. I really wish it was open source. Free code assets really should be in most cases. I will try to isolate my changes into another C# file and post a Gist.

The first change I made was to add support for themed Static Maps. If you look at this wizard, you can see that there are a lot of styling options. This appears to be the same technique used in the Halo 4 app because with the right set of options you can get something that looks really close. Supporting styling in Unity3D is just a simple act of appending the style parameters to the end of the URL used by the Google Maps plug-in.

Displaying Markers in 3D

The next thing I wanted to do is display the markers as 3D objects on top of the map instead of having them inside the texture itself. This requires 3 steps:

  1. Determine where the markers are in pixel coordinates in the static map texture.
  2. Calculate the UV coordinate of the pixel coordinate.
  3. Calculate the world coordinate of the texel the UV coordinate resides at.

Step 1 can be tricky. You have to project the latitude and longitude of the marker with the Mercator projection Google Maps uses to get the pixel coordinate. Luckily, this guy already did it in PHP to create image maps from static maps. I adapted this code to C# and it works perfectly. You can grab the Google Maps utility functions here. (All this great free code on the net is making me lazy–but I digress)

Step 2 is easy. This code snippet does the trick. The only catch is that you have to flip the V so that it matches with how Unity uses UV coordinates.

Step 3 is also tricky. However, someone with much better math skills than I wrote a JavaScript method to compute the world coordinate from a UV coordinate. It searches through each triangle in the mesh and sees if the UV coordinate is contained inside it. If so, it then calculates the resultant world coordinate. The key to using this is to put the static map on a plane (the default scene in the plug-in uses a cube) and use the C# version of this function I wrote here.

3D objects floating over marker locations on a Google Static Map.

3D objects floating over marker locations on a Google Static Map.

Here’s the end result–in this case it’s a display for the Donut Dazzler prototype. 3D donuts are floating over real-world donut shops and cupcakes over cupcake bakeries. I got the locations from the Foursquare API. This is quite easy to do using UniWeb.

Slippy Maps

The aforementioned technique works great if you just want a static map to display stuff around the user’s current location. What if you want to be able to scroll around and see more map tiles, just like Google Maps when you move around with your mouse? This is called a Slippy Map. Slippy Maps are much more elaborate–they require dynamically downloading map tiles and stitching them together as the user moves around the world.

Thankfully Jonathan Derrough wrote an amazing free Slippy Map implementation for Unity3D. It really is fantastic. It displays markers in 3D and pulls map tiles from multiple sources–including OpenStreetMap and Bing/VirtualEarth. It doesn’t use Google Maps because of possible TOS violations.

I couldn’t find a way to style map tiles like Google Static Maps can. So the end result was impressive but kind of ugly. It is possible with OpenStreetMap to run your own tile server and run a custom renderer to draw styled tiles. I suspect that’s how Rescue Rush styles their OpenStreetMap tiles–unless they are doing some image processing on the client.

Either Or

For my prototype I ended up using Google Static Maps because Slippy Maps were overkill. Also, pulling tiles down from the servers seemed much slower than grabbing a single static map. I suppose I could add some tile caching, but in the end static maps worked fine for my purposes.

Keep in mind that Google Maps has some pretty fierce API usage costs. If your app goes viral, you will likely be on the hook for a huge bill. Which is why it might be worth figuring out how to style free OpenStreetMap tiles.