IndoorAtlas Beta – track phone from another device

As you may have seen on YouTube I’ve recently been experimenting with the beta of IndoorAtlas, a service that allows a smartphone to use its magnetometer to determine its position within a building by measuring fluctuations to the Earth’s magnetic field caused by metal building materials;

I’m not so much interested in using IndoorAtlas to make a location aware smartphone app, but instead in using it to provide indoor positioning to a Unity application that displays to an Oculus Rift. To do this I had to make the positioning data available to devices other than the phone itself; the IndoorAtlas API allows a device to obtain its own position, but not to make this position available to other devices (obviously there are privacy concerns involved here!).

So as a quick hack (I believe the research term is ‘proof of concept’) I modified the example Eclipse project that comes with the IndoorAtlas Android API download to additionally submit the position data that the phone receives to a MySQL database on one of my servers, which can then be accessed by whatever I see fit. I borrowed a lot of code from here.

On the phone, it’s simply a case of editing the onServiceUpdate method to build a HTTP POST (with the relevant data as POST parameters) & to send it to a piece of server side PHP which adds or updates the details for the particular phone to the database. The PHP looks something like this;

<?php

// array for JSON response
$response = array();

// check for required fields in POST data
if (isset($_POST['deviceId']) && isset($_POST['buildingId']) && isset($_POST['levelId']) && isset($_POST['floorplanId']) && isset($_POST['latitude']) && isset($_POST['longitude']) && isset($_POST['x']) && isset($_POST['y'])	&& isset($_POST['i']) && isset($_POST['j']) && isset($_POST['heading']) && isset($_POST['probability']) && isset($_POST['roundtrip']) && isset($_POST['time'])) {

	// extract data from POST into variables
	$deviceId = $_POST['deviceId'];
	$buildingId = $_POST['buildingId'];
	$levelId = $_POST['levelId'];
	$floorplanId = $_POST['floorplanId'];
	$latitude = $_POST['latitude'];
	$longitude = $_POST['longitude'];
    $x = $_POST['x'];
    $y = $_POST['y'];
    $i = $_POST['i'];
    $j = $_POST['j'];
    $heading = $_POST['heading'];
    $probability = $_POST['probability'];
	$roundtrip = $_POST['roundtrip'];
    $time = $_POST['time'];

	// include database connect class
	require_once __DIR__ . '/db_connect.php';

 	// connect to the database
 	$db = new DB_CONNECT();

	// check whether primary key already exists
	$result = mysql_query("SELECT * FROM devicelocations WHERE deviceId = '$deviceId';");
	$arr = mysql_fetch_array($result);

	// If the select statement returns the empty set, sizeof will return 1. Otherwise sizeof will return 28 (14 columns in a row).

	// if the deviceID does not already exist in the database, do an INSERT
	if (sizeof($arr) == 1) {
		$result = mysql_query("INSERT INTO devicelocations (deviceId, buildingId, levelId, floorplanId, latitude, longitude, x, y, i, j, heading, probability, roundtrip, time) VALUES ('$deviceId', '$buildingId', '$levelId', '$floorplanId', '$latitude', '$longitude', '$x', '$y', '$i', '$j', '$heading', '$probability', '$roundtrip', '$time');");
	}
	// if the deviceID does already exist in the database, do an UPDATE
	else {
		$result = mysql_query("UPDATE devicelocations SET buildingId = '$buildingId', levelId = '$levelId', floorplanId = '$floorplanId', latitude = '$latitude', longitude = '$longitude', x = '$x', y = '$y', i = '$i', j = '$j', heading = '$heading', probability = '$probability', roundtrip = '$roundtrip', time = '$time' WHERE deviceId = '$deviceId';");
	}

    // check if row inserted or not
    if ($result) {
        // successfully inserted into database
        $response["success"] = 1;
        $response["message"] = "Entry successfully inserted or updated.";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // failed to insert row
        $response["success"] = 0;
        $response["message"] = "Entry was not successfully inserted or updated.";

        // echoing JSON response
        echo json_encode($response);
    }

} else {
    // required POST field is missing
    $response["success"] = 0;
    $response["message"] = "Required POST field(s) missing";

    // echoing JSON response
    echo json_encode($response);
}

?>

Once the data are in the database, I can access them from pretty much anything I want. As a quick test I put together a simple Web page that displays the floor plan image with a red dot to represent the phone’s last known location as well as dumping the data in text form;

map

The PHP for this page looks something like this (it’s a quick hardcoded hack, but you get the idea);

<?php

echo "<head>";
echo "<meta http-equiv='refresh' content='2.5'>";
echo "</head>";

require_once __DIR__ . '/db_connect.php';

$db = new DB_CONNECT();

$result = mysql_query("SELECT * FROM devicelocations");

$arr = mysql_fetch_array($result);

$deviceId = ($arr[0]);
$buildingId = ($arr[1]);
$levelId = ($arr[2]);
$floorplanId = ($arr[3]);
$latitude = ($arr[4]);
$longitude = ($arr[5]);
$x = ($arr[6]);
$y = ($arr[7]);
$i = ($arr[8]);
$j = ($arr[9]);
$heading = ($arr[10]);
$probability = ($arr[11]);
$roundtrip = ($arr[12]);
$time = ($arr[13]);

echo "<div style='position: relative; left: 0; top: 0;'>";
echo "<img src='map.gif' style='position: relative; top: 0; left: 0;'/>";
echo "<img src='splodge.png' width = 1% style='position: absolute; top: ";
echo ($j)/10;
echo "; left: ";
echo ($i)/10;
echo ";'/>";
echo "</div>";

echo "deviceId: ";
echo $deviceId;
echo "<br/>";
echo "buildingId: ";
echo $buildingId;
echo "<br/>";
echo "levelId: ";
echo $levelId;
echo "<br/>";
echo "floorplanId: ";
echo $floorplanId;
echo "<br/>";
echo "latitude: ";
echo $latitude;
echo "<br/>";
echo "longitude: ";
echo $longitude;
echo "<br/>";
echo "x: ";
echo $x;
echo "<br/>";
echo "y: ";
echo $y;
echo "<br/>";
echo "i: ";
echo $i;
echo "<br/>";
echo "j: ";
echo $j;
echo "<br/>";
echo "heading: ";
echo $heading;
echo "<br/>";
echo "probability: ";
echo $probability;
echo "<br/>";
echo "roundtrip: ";
echo $roundtrip;
echo "<br/>";
echo "time: ";
echo $time;

?>

Next will be to modify a player/camera controller in Unity so that it moves according to the position of the phone!

unity