Core Interaction Lab: Week 12

Device Location

When a visitor to our websites grant us permission, we are able to access certain information about their computer (or phone) such as its webcam, microphone, or location. We're going to focus on location, as it relates to your Site Specific Website final project, and will allow us to build on the JavaScript we've already learned.

Computers perceive location in latitude (measuring north and south) and longitude (measuring east and west). Latitude is measured in degrees above or below the equator, from -90 (south pole) to 90 (north pole). Longitude is measured in degrees east or west of the prime meridian in Greenwich, England, from -180 to 180. The New School University Center, for example, has a latitude of 40.735487 and a longitude of -73.993598. If you enter those numbers into Google Maps, you'll see that the map centers where we'd expect it to. When we ask a computer to give us the location of the user, these are the kinds of numbers that we'll be getting back. We can do a great deal with this information, which is why it's required that the user approve our ability to access it.

Let's first see how we can ask a user for permission for their location. There are three parts: a function to call if the user allows us to access their location, another function to call if they don't, and finally the call to actually ask for their location.

function onSuccess(pos) {
    console.log(pos)
}

function onError() {
    console.log("User chose not to share their location")
}

navigator.geolocation.getCurrentPosition(onSuccess, onError)

If you haven't already accepted location access, refresh the page and accept. Now open the console. You'll see an object there. Expand it, and also expand the nested object called coords. You should now see the provided latitude and longitude of your computer.

If you have trouble running the code above, try another browser. Geolocation is still technically "experimental" in web browsers, meaning that a standard implementation hasn't yet been decided. This should all work in Google Chrome, though.

What can we do with a user's latitude and longitude? For starters, we can ask Google to give us an image of a map centered on the provided location:

var img = new Image();
img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" + pos.coords.latitude + "," + pos.coords.longitude + "&zoom=13&size=300x300&sensor=false";
document.body.appendChild(img);

Here, we take advantage of Google's static map API, which allows us to request an image of a map so long as we tell them the latitude and longitude. To use this, you will have to create an API key which you can do by following the static map link.

Another thing we can do is change the appearance of behavior of our site based on the user's location. Latitude and longitude are just numbers after all, much like the mouse's x position or the window's height. We can use them as inputs for any type of logic we want to perform. For example, we could make our website look different in the northern hemisphere vs. the southern hemisphere:

if (pos.coords.latitude > 0) {
    document.body.style.backgroundColor = "red"
} else {
    document.body.style.backgroundColor = "blue"
}

We could make this logic more complex and check to make sure a user is within a certain range of geocoordinates and only showing them information if they're in a certain part of the world:

if (pos.coords.latitude > 40.72 && pos.coords.latitude < 40.73 && pos.coords.longitude < -73.99 && pos.coords.longitude > -74) {
    console.log("You are (probably) in Colorado")
} else {
    console.log("You are not in Colorado")
}

In the above example, I used the website geojson.io to draw a rectangle over a map and get the latitude and longitude for the corners of the rectangle. Then I can write some JavaScript logic to make sure the position the user provides is within the coordinates of my rectangle. This is called "geofencing." I chose Colorado since it's more-or-less rectangle shaped - more complex geofences require more complex math, but you might find that a rectangle gets you far enough.

You could also do some rough distance measurement. Depending on where you are on the planet, 0.0001 degrees latitude/longitude can be anywhere from 4-11 meters. So let's say we wanted someone to get really close to a location before our website displayed some information. We could combine their location and our desired location into the distance formula and check if the distance is less than 0.0001, for example.

Let's work through this use case. Let's code a rough check to see if someone is able to see the Prison Ship Martyr's Monument in Fort Greene Park. It has a latitude of 40.69178 and a longitude of -73.97553. I searched for "distance formula javascript" in my search engine of choice and came up with this:

var a = x1 - x2;
var b = y1 - y2;

var c = Math.sqrt(a*a + b*b);

Which seems like it will work - I just need to define x1, x2, y1, and y2. I already have these numbers: one set of coordinates is my target point and the other is the user's current position. So we could plug those values in to our equation like so:

var x1 = pos.coords.latitude;
var y1 = pos.coords.longitude;
var x2 = 40.69178;
var y2 = -73.97553;

var a = x1 - x2;
var b = y1 - y2;

var c = Math.sqrt(a*a + b*b);

document.write(c);

Now that we know the distance, we can do whatever we want - put it in an if block to make sure it's below a threshold, use it as an input for font size, use it to change the volume of a sound clip... anything! It's important to keep in mind that we're not doing anything here that's beyond the idea of inputs and outputs we're already comfortable with. In this case, your inputs are just two numbers. You can do whatever math or logic you want to on these numbers and turn them into whatever outputs you want.

(Note that I am playing fast and loose with actual geographic math - latitude and longitude don't correlate directly to distance, and the regular distance formula doesn't totally apply here since our planet isn't flat. But it works well enough for our purposes.)