Map your location

Before you can start using Indoor Location, you need to create a map of your space. This is for the Indoor Location SDK to know the shape and size of the space, as well as where the beacons are positioned.

Small caveat: the mapping wizard and the Location Builder API are currently iOS-only, so dust your iPhone off or borrow one from a friend. The mapping wizard takes just a few minutes—your Android-wielding colleagues won’t have time to notice you’re holding a forbidden device in your hands!

What’s ahead (aka Table of Contents)

The easiest way to create a map of a location is via the Estimote Indoor Location app.

You will need:

  • 1 x iPhone 4S or newer.
  • 1 x Estimote Account (sign up here).
  • 4 or more Estimote Location Beacons.

Install the app, open it up and it’ll guide you through the mapping process.

Once you’ve mapped your space, it will be uploaded to Estimote Cloud, where you can find it on the “Locations” tab. You can also edit it by drag-n-dropping the corners, fine-tuning your location’s setup for more accurate positioning.

This is great to get up and running quickly, so that you can start evaluating Indoor Location and prototyping your own app in almost no time.

Next: Build an app with Indoor SDK

The advanced way: Location Builder

Another approach is to map your space programmatically with the Indoor Location SDK. You will need to build a simple “configuration” app and use the SDK to set up the shape and size of your space, say where the beacons are, as well as make sure that the beacons themselves are configured properly.

You will need:

  • 1 x Mac computer with Xcode.
  • 1 x Estimote Account (sign up here).
  • Any number of Estimote Location Beacons (at least one per each wall recommended).

Start by creating a new Xcode project and adding the Indoor Location SDK to it.

All the code can go into the application:didFinishLaunching method of your AppDelegate—in other words, the Location Builder will execute as soon as you run the app, printing the output into the Xcode console. You don’t even need to connect your iOS device—Location Builder runs just fine in a simulator.

Let’s kick off by creating an EILLocationBuilder object:

let locationBuilder = EILLocationBuilder()
locationBuilder.setLocationName("Estimote's Mars office")
EILLocationBuilder *locationBuilder = [EILLocationBuilder new];
[locationBuilder setLocationName:@"Estimote's Mars office"];

Define shape and size

Start by drawing the contour of your space by defining its boundary points, (AKA “corners”):

    EILPoint(x: 0.00, y: 0.00),
    EILPoint(x: 0.00, y: 9.85),
    EILPoint(x: 4.56, y: 9.85),
    EILPoint(x: 4.56, y: 0.00)])
[locationBuilder setLocationBoundaryPoints:@[[EILPoint pointWithX:0.00 y:0.00],
                                             [EILPoint pointWithX:0.00 y:9.85],
                                             [EILPoint pointWithX:4.56 y:9.85],
                                             [EILPoint pointWithX:4.56 y:0.00]]];

A few things of note:

  • Each consecutive boundary point connects to the previous one (the first point connects to the last one), forming a boundary segment (AKA “wall”). The important implication is: the order in which you define points matters, so pay attention to it!
  • The origin of the coordinate system, i.e., the (0,0) point, is up to you. Note that the Indoor SDK will use the very same coordinate system when delivering position updates, so simply pick something that’s most handy for you.
  • The units the entire Indoor SDK operates with are always metric meters—and the Location Builder is no exception.

With all of that in mind, and looking back at the code snippet above … yes, that’s a simple 4.56 m x 9.85 m, rectangular room. (Don’t blame us, office space on Mars is really costly!)

Place the beacons

Now that you’ve mapped all the nooks and crannies of your space, time to set the beacons up:

    atBoundarySegmentIndex: 0, inDistance: 3.5, fromSide: .LeftSide)
    atBoundarySegmentIndex: 1, inDistance: 1.1, fromSide: .RightSide)
    atBoundarySegmentIndex: 2, inDistance: 5.7, fromSide: .LeftSide)
    atBoundarySegmentIndex: 3, inDistance: 2.4, fromSide: .RightSide)
[locationBuilder addBeaconWithIdentifier:@"ed19942889b711d44bb1e3eda5184833"
                              inDistance:3.5 fromSide:EILLocationBuilderLeftSide];
[locationBuilder addBeaconWithIdentifier:@"211884e42e45a6e37397d33076d1483e"
                              inDistance:1.1 fromSide:EILLocationBuilderRightSide];
[locationBuilder addBeaconWithIdentifier:@"d9db571ad6dce14013c21446460d4819"
                              inDistance:5.7 fromSide:EILLocationBuilderLeftSide];
[locationBuilder addBeaconWithIdentifier:@"9b66bca40167315563b7b62fe964e735"
                              inDistance:2.4 fromSide:EILLocationBuilderRightSide];

What’s going on here? We simply take some beacons and define:

  • Which wall they’re placed on. That’s the atBoundarySegmentIndex parameter. The indexes start with “0” for the first wall, meaning the one define by the first and the second boundary point. Second wall = boundary segment index “1”, defined by the second and the third point, and so on, and so forth.
  • Where exactly they’re placed on that wall. That’s the inDistance and fromSide parameters. Think about them this way: if you stand inside the room, in front of the wall, and look straight at it: left is LeftSide and right is RightSide, and the distance is the distance from that side to the beacon.
  • Which exactly beacon is that. That’s the addBeaconWithIdentifier part. You can find the identifiers of your beacons on or with the Estimote app.

Tip: You can use as many beacons per wall as you want, or you can have some walls with none at all. In general, we recommend at least one beacon per each wall, positioned in the middle of it. For longer walls, we recommend roughly one beacon every four meters, or 13 feet.

Keep in mind: Indoor Location requires the beacons to be placed at about chest-height, that’s when the positioning works best! You can experiment with putting them a bit higher if that’d help maintain the line-of-sight to the beacons. If you do experiment, make sure to put them all at the same height!

Important: While the Indoor Location wizard takes care of automatically configuring your beacons for you, with the Location Builder approach that’s something you need to take care of yourself. Simply use the Estimote app to enable the Indoor Location broadcasting.

Make sure the beacons are configured properly, or the positioning accuracy will be greatly reduced, or it will not work at all!

Measure and set magnetic orientation

Indoor Location is powered not just by beacons, but also by the multitude of sensors available in your device—including the compass. Because of that, we need to define the magnetic orientation of your space:

[locationBuilder setLocationOrientation:50];

How to determine what number to put there? Like this:

  1. Go inside the space, and orient yourself along the [0,1] vector, or in other words, along the Y axis of your location. (This forum post might come in handy to better understand what exactly this means.)
  2. Open the iOS compass app and read the value it shows. Note that due to magnetic fluctuations, it might be a good idea to measure this in multiple parts of the location, and take an average, or the most common value.
  3. Put it as the parameter of the setLocationOrientation invocation.

Upload location metadata to Estimote Cloud

We’re almost done! As the last step, we’ll order the Location Builder to build a map of our location based on all the data we’ve provided so far, and then we’ll upload the map to your Estimote Cloud account:

let location =

ESTConfig.setupAppID("<App ID>", andAppToken: "<App Token>")
let addLocationRequest = EILRequestAddLocation(location: location)
addLocationRequest.sendRequestWithCompletion { (location, error) in
    if error != nil {
        NSLog("Error when saving location: \(error)")
    } else {
        NSLog("Location saved successfully: \(location.identifier)")
EILLocation *location = [locationBuilder build];

[ESTConfig setupAppID:@"<App ID>" andAppToken:@"<App Token>"];
EILRequestAddLocation *addLocationRequest = [[EILRequestAddLocation alloc] initWithLocation:location];
[addLocationRequest sendRequestWithCompletion:^(EILLocation *location, NSError *error) {
    if (error) {
        NSLog(@"Error when saving location: %@", error);
    } else {
        NSLog(@"Location saved successfully: %@", location.identifier);

Replace the placeholder App ID and App Token values with your own ones, which you can generate here:
(an idea for the name of the app: “Indoor Location Builder”)

That’s it! You can run your location-building app now on your device or in a simulator, and you should end up with a brand new location in your Estimote Cloud account.

Next: Build an app with Indoor SDK

Editing location metadata with Estimote Cloud API

Sometimes you might want to edit an existing location. You can do that with the Estimote Cloud API. For example, let’s see how we can go about modifying the magnetic orientation of the location, so that the Indoor SDK knows where north/south/east/west is in your space.

First, let’s fetch the current location metadata. This will be our base for the modifications.

$ LOCATION_IDENTIFIER=my-office-i8k # replace with the identifier of your location
$ APP_ID=my-location-builder-app # replace with your own credentials
$ APP_TOKEN=8abdf2f1deb68d35ad3342511e88d094 # replace with your own credentials
    -u $APP_ID:$APP_TOKEN \
    -H "Accept: application/json" > my_location.json

Remember that you can generate credentials (app ID and token) to access the Cloud API on:

As for the location identifier, you can find it under “Show Indoor Locations” on:

The curl command above will download the current location metadata to the my_location.json file. Let’s open this file and modify the orientation:

  "identifier": "my-office-i8k",
  "name": "My office",
  "orientation": 10,

Now, we’ll simply upload the new metadata to Estimote Cloud, replacing the previous ones:

    -u $APP_ID:$APP_TOKEN \
    -H "Accept: application/json" -H "Content-Type: application/json" \
    -X PUT -d @my_location.json

And that’s it!