A Problem With Proximity Based Apps

Intro

This is not a battle between flat geometry and spherical geometry to calculate distances between points. This falls somewhere between a rant, my thoughts on the subject, and how we can improve proximity based applications to return relevant results.

Proximity is the state of being accurately close to something. In our case we have an individual trying to find the closest fast-food location while driving (I know you shouldn’t be using your phone when driving, but let’s make an exception). An app uses the individual’s location, its latitude and longitude, to determine the closest burger shack. The nearest five locations are sent back and our individual is on their way to grubbing down.

The biggest problem I have noticed with location based recommendations, is that they fail to take into consideration the distance between two points on a map (arc length) versus the distance between two points while driving (linear). The distance is NOT the same. By simply calculating the two points a map, the distance will tend to be much shorter because there are no streets, directions, or obstacles. While driving there are factors such as speed, traffic, and one-way streets to take into consideration.

Imagine driving on a road with an app’s suggested location on your left hand side over the freeway but the shortest path to this location is to go down the road for 3 miles then another 3 miles back, when the closest location is actually 4 miles down the road.

Flat Geometry

Lets examine this by first calculating the distance between two points while driving. My starting location is in a parking lot at 37.3879242, -121.9821091. To get to the nearest IN-N-Out burger (37.3610039,-122.0248489), I have to drive down a street which takes me out of the way, then get on the freeway, and make a couple more turns. The shortest possible path according to Google Maps is 5.1 miles [1].

driving between two points

Spherical Geometry

Now we compute this using the Haversine Forumla, a commonly used spherical formula in navigation, to find the distance between two points on a sphere. For the sake of brevity, the result is 2.996 miles [2]. The first downfall is the precession of the Earth’s radius; it is rounded to 3961 miles, which is optimized for locations around 39 degrees from the equator (roughly the latitude of Washington DC, USA). A more precise number is difficult to calculate because the Earth is not perfectly spherical, so no single value serves as an exact radius. I think that locations in a radius are most useful when they simply act as a reference, not as a directive.

The Difference

Comparing the two results, the difference between them is huge…at 2.104 miles. And this is only for locations within a radius of 10 miles. The distance between two points in a radius of 50 miles would be increasingly less accurate when driving because the number of required turns would increase. We can think of all these turns as the sum of the two shorter sides of triangles (not hypotenuse). While using spherical geometry is a straight shot because there are no extra deltas (it’s the hypotenuse).

Then again computing the latter is significantly easier and faster than the prior. Tools such as MongoDB’s geospacial queries [3] makes distance calculation easy and flexible but lack one thing, the shortest path. The most optimal solution would be combining spherical geometry with a shortest path algorithm such as Dijkstras [4] to determine to nearest location the with shortest route. While the shortest path is not necessary for all use cases, it matters the most when you are driving to your destination.

Just remember, “Fast is fine, but accuracy is everything.”

[1] http://goo.gl/maps/Vc67E
[2] http://andrew.hedges.name/experiments/haversine/
[3] http://docs.mongodb.org/manual/core/geospatial-indexes/#geospatial-indexes-distance-calculation
[4] http://en.wikipedia.org/wiki/Dijkstra’s_algorithm

Advertisement

Disable Android Lint – Google Analytics API key problem in Eclipse

If you have encountered your Google Analytics data not being sent to the server, you know how frustrating it can be waiting until the next day and seeing no results in the dashboard. Here are a couple things I encountered in my search for this and some great solutions the problem.

The first is about encoding the GA key. Do not encode the dashes in the ga_trackingId string. Doing so will prevent you from seeing any data in your reports. This can be a big problem because the Android Lint offers this as one of their ‘improvements’ :

Replace “-” with an “en dash” character (–,&&;#8211;)?

Do not let Lint encode the dashes in your GA key! It will break Google Analytics.

The second is a precaution measure that will make sure you are not sending old or corrupt data to the GA server. If you are offline and using your app, events are added to a queue and then stored in a local database, but never fired due to lack of connection. This can cause some problems with events never firing. So to clean the local GA database file, use the following:

File analyticsDB = new File(c.getApplicationInfo().dataDir + “/databases/”, “google_analytics.db”);

if (analyticsDB.exists()) { analyticsDB.delete(); }

And last but not least, the most important piece of advice. No one dared to mention that once you clean your project, it will switch it back to the en_dash encoding. To fix this encoding problem follow these steps (Note this is specifically for Eclipse on a Mac but i’m sure the settings are located in a similar place for PC):

  1. Go into your preferences (on Mac for it’s Eclipse -> Preferences)
  2. Go to Android
  3. Go to Lint error Checking
  4. You can either disable Lint checker completely or disable just the en_dash thing (what I did)
  5. Find the one called “TypographyDashes” under Usability:Typography or search “dash” inside the search box. It should come up with TypographyDashes.
  6. Highlight it and turn it to “Ignore” under the severity
  7. From there click ‘apply’ and then allow it to re-lint.

Credit:

http://stackoverflow.com/questions/11399443/google-analytics-v2-sdk-for-android-easytracker-giving-errors

http://blog.blundell-apps.com/google-analytics-common-problems-and-fixes/

WampServer Problems with Skype on Port 80

For those who have tried to start WampServer with Skype already running, you might have been faced with the yellow icon in the windows notification area and WAMP not starting. This is because Skype is using Port 80 and 443 as alternatives for incoming connections and apache wants to listen to Port 80 as well, therefore causing WAMP to not start up.

To disable Skype from using Port 80 and 443, go to Tools > Options > Advanced > Connection, then uncheck the ‘Use port 80 and 443 as alternatives for incoming connections’.

Screenshot of disabling port 80 in Skype

Now close Skype, and restart WAMP by left clicking the WAMP icon in the system notifications and selecting ‘Restart All Services’ under ‘Quick Admin’.

My suggestion to anyone who is having this problem is close all other programs that might be listening to Port 80 on your computer and then open up WAMP.

Nexus 4 has arrived! Initial impressions

After a long two week wait, Google has brightened my day with this beautiful box (see below).

image

Here is a quick overall rating on the Nexus 4 components:

Performance: 5/5
Extremely fast and fluid. Never hiccupped even once throughout heavy daily use. Helps that it’s running 4.2.1.

Battery Life: 3.5/5
Four hours on WiFi and GPS have drained my fully charged battery to 42%. This beast is power hungry but is expected for these specs and screen.

Screen Quality: 5/5
Clean, crisp and bright

Screen Size: 4/5
Akward space on the sides for some apps. Doesn’t feel as big as it should because of the dedicated spot for buttons at the bottom. [Update] On a second thought, after using it for a week the screen size is perfect!

Camera: 3.5/5
Crisp, clear daytime shots. Up close night time shots are too white/bleached when using flash. Not as good as the iPhone 5 camera for night shots

Overall: 4/5
Although it has some mishaps, it’s overall an amazing phone.

My initial impression as soon as i opened the box was the phone’s weight. It feels extremely light, almost too light, but is quite solid unlike the iPhone 5. After using the phone for a couple hours I got the feeling that the screen is a bit too wide. In a way it feels like I am using one of the wide blackberries from 2006. Its probably an illusion because of the way the buttons are displayed on the bottom of the screen. [Note: I’ve come from using a long line of Android phones with hardware buttons on the bottom]. But after about a weeks use the screen size has grown on me and is ideal.

To keep it short, those upgrading to the Nexus 4 from a 2.3 android device or a smartphone of about two years, the transition is going to take a week or so but you will absolutely fall in love with the phone in the process.

Nexus 4 Launch

“Imagine that this had happened in a brick and mortar store: you wait in line for a new product, you get inside, you get the product, you go to the checkout, then the cash register breaks, so the manager takes the item that you were going to purchase and puts it back on the shelf, and tells you to try again. So, you fight through the crowd again to get the product, then as you’re walking to the checkout, the manager takes the item and puts it back on the shelf, but this time when you go back, the shelf is empty. That’s what happened to many people in the Play Store today.”

Google IO 2012 SOLD OUT in under 30min! – Registration Disappointment This Year

This year’s registration sold out in under 30 minutes with academia tickets selling out in under 15!

Long story cut short, my request goes in 7:00:03, sorry no tickets are available after 5 minutes of staring at the dreadful ajax loader. 15minutes later all academia tickets sold out. I had hope high hopes this year. /rant

Congradulations to everyone that scored one and now I leave you with the screenshot that will stuck in my head for the rest of the year.

Migrating a previous Drupal 6 Installation

*Edit: I’m in the process of adding more information and images to the tutorial*

Before we begin:

For this tutorial I’m using MAMP and a previous installation of Drupal 6. We are going to be moving the previous Drupal installation onto a new computer and reinstantiating it so it is identical to the previous install. To do this you need the previous installation folder and a backup of the SQL database.

Now lets start.

Copy your Drupal site folder into the htdocs folder of MAMP (or htdocs of whichever local web development environment you are using).

Navigate to the “default” folder which is located in /htdocs/sites/default.

Make a new folder on your desktop called “default”. (The purpose of this step is to avoid getting the privilege errors when using a drupal installation that was originally used on another computer or one that does not have privileges allowed on your computer. This can be bypassed by chmod 755 your “default” folder but it does not always work for everyone so this is an alternative way).

If a “files” folder exists in your “default” folder, copy over the “files” folder from /sites/default/ into your “default” folder on the desktop.

Navigate back to /htdocs/sites/default and open up default.settings.php from in your favorite text editor. Save it as default.settings.php and as settings.php in your “default” folder on your desktop.

Now delete the “default folder” in /htdocs/sites/ and copy over the “default” folder from your desktop into /htdocs/sites/  (What this essential does is get rid of the restricted permission on the default folder and allow you to have full rwx control since you created the folder).

Open up your preferences page in MAMP and click on the phpMyAdmin page. Go to the ‘privileges’ tab, then click add new user.

Select a username, in this case you can call it “drupal”. In the Host drop down box choose local and it should fill in the field with “localhost”. Choose no password from the password drop down (less secure), or use text field if you wish to use a password.

In the Database for user box, select the second option, “Create database with same name and…” then scroll down to the bottom and hit go.

You should have a user and database with the name drupal created (you can see the database name on the left).

Now back to the “default” folder in /sites/ open up the settings.php and scroll down to the $db_url variable. It should look like this  $db_url = ‘mysql://username:password@localhost/databasename’;

Change the $db_url variable to match your database information you previously created. Mine looks like this  $db_url = ‘mysql://drupal@localhost/drupal’;

You are now ready to install your drupal site.

Navigate to your browser and type localhost:8888 in your url bar.

Drupal should start the installation page.

On the page asking for database information, enter the information you previously created.

On the next page, the information you choose is up to you (the admin email, password, etc…)

Your drupal installation should now be complete. The only thing left to do is import your previous database information into the new drupal database.

To migrate your previous .sql databse go to phpMyAdmin and select the drupal databse on the left hand side. Now go to the import tab (rightmost one) and choose the file location of your previously exported .sql database. Hit go and you should be set.