Indoor Maps on iOS: Advanced MapKit
In this MapKit tutorial, you’ll learn how to use Indoor Maps to map the inside of buildings, switch between different stories and find your location inside the building. By Alex Brown.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Indoor Maps on iOS: Advanced MapKit
25 mins
- Getting Started
- Understanding Indoor Maps
- What Is GeoJSON?
- What Is IMDF?
- Using the GeoJSON Format
- Modeling GeoJSON
- Decoding GeoJSON With MKGeoJSONDecoder
- Decoding the Archive
- Rendering Geometry on a Map
- Adding Overlays
- Adding Annotations
- Styling Map Geometry
- Selecting Levels
- Using Location With Indoor Maps
- Where To Go From Here?
Apple introduced Indoor Maps to MapKit in iOS 13. This program provides tools to map the inside of physical structures, allowing users to navigate a building from the inside.
In this tutorial, you’ll learn how to use Indoor Maps to add the location of the RazeWare office to a map. In the process, you’ll learn to:
- Parse Indoor Mapping Data Format (IMDF) data into models.
- Draw geometry from GeoJSON on a map.
- Style map geometry.
- Switch between different levels of a structure.
- Access indoor locations.
Are you ready for a full tour inside RazeWare HQ? Well, read on!
Getting Started
Download the starter project using the Download Materials button at the top or bottom of this tutorial. Open the starter project. Build and run to see what you’re working with.
For the less observant among you, it’s a map. :]
The starter project already contains the user interface, some model files and the IMDF archive you’ll work with. Right now, it’s not an overly inspiring app; it certainly wouldn’t get past the Apple Genius in app review. But you’re going to change that!
Understanding Indoor Maps
Before you start writing code, it’s important to know what kind of data you’re working with. In this tutorial, you’ll use two standards: GeoJSON and IMDF.
What Is GeoJSON?
GeoJSON is a format for representing geographic data structures. As the name implies, GeoJSON is based on the JSON format. The Internet Engineering Task Force (IETF) released it in 2015 to standardize the way programmers model geographical data.
GeoJSON supports a range of different geometry types defined using latitude and longitude pairs. You can combine the lat-long pairs to form more complex structures. A GeoJSON object may represent a:
- Geometry: A region of space.
- Feature: A spatially-bound entity.
- FeatureCollection: A list of Features.
Take a look at the building structure outlined in the map above. Each point in the geometry of the structure has a latitude and a longitude coordinate, the same way you’d have an x-y position in a Cartesian coordinate system. Each point is labeled from 1 to 6, representing the order in which they’re drawn. The column on the left shows the actual lat-long coordinates for each point.
The GeoJSON representation of this feature looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"stroke": "#101889",
"stroke-width": 2,
"stroke-opacity": 1,
"fill": "#98a1e6",
"fill-opacity": 0.5
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-121.80389642715454,
37.33966009140741
],
[
-121.80312395095825,
37.338790026148
],
[
-121.80198669433592,
37.33937007077421
],
[
-121.80222272872923,
37.33960891137705
],
[
-121.80301666259766,
37.33966009140741
],
[
-121.80331707000731,
37.33998423078978
],
[
-121.80389642715454,
37.33966009140741
]
]
]
}
}
]
}
You can recreate this exact structure yourself. Head over to geojson.io and paste the GeoJSON above into the editor on the right. Since each element in the array is a lat-long pair, the structure will appear in the same place as the image shown previously.
What Is IMDF?
Apple introduced the Indoor Mapping Data Format (IMDF) with iOS 13 as a new standard for modeling the inside of a structure. An IMDF archive contains a group of feature types that, when combined, can describe an indoor space including walls, doorways, stairs, levels and more. You usually create an IMDF archive by using third-party software to convert a detailed floor plan into IMDF.
IMDF Feature Types
You already know that IMDF archives are essentially a collection of GeoJSON files that, when combined, describe an indoor space. But how exactly does this work? You’ll find out next.
In Xcode, open the Project navigator and expand IMDF/Data. Each GeoJSON file has a name that corresponds to its feature type described in the IMDF documentation.
For example, occupant.geojson is a collection of Occupant types, building.geojson is a collection of Building types and so on. It’s as simple as that. :]
The main types you’ll look at in this tutorial are:
- Venue
- Unit
- Occupant
- Amenity
- Level
Now that you understand the tools you’ll be using, it’s time to put them to work!
Using the GeoJSON Format
Open occupant.geojson in the Project navigator. You’ll see that GeoJSON and IMDF really aren’t as scary as they sound.
Take a look at one of the occupants in the list:
{
"feature_type": "occupant",
"geometry": null,
"id": "5ac4bf40-2dbf-4bdb-9c39-495c442b7e39",
"properties": {
"address_id": null,
"alt_name": null,
"anchor_id": "76336b53-81c9-4c93-8f81-a4c008d54ba1",
"category": "office",
"display_point": {
"coordinates": [
-121.889609,
37.329678
],
"type": "Point"
},
"hours": "Su-Sa 09:00-17:00",
"name": {
"en": "Ray's Office"
},
"phone": "+14087924512",
"restriction": null,
"website": null,
"correlation_id": null
},
"type": "Feature"
}
This occupant describes Ray’s office. A valid occupant must define an id
, the feature_type
must have a value of occupant
and it must have a geometry
value of null
.
An occupant doesn’t need its own geometry, as it uses the geometry from the anchor that anchor_id
references inside properties
.
Still in occupant.geojson, copy the anchor_id
of the first occupant, then open anchor.geojson and search for the id. You’ll find the associated anchor feature inside.
All the other keys in properties
are metadata describing the occupant. In this article, the only key you’ll use is the name
but in a real-world situation, you could expand this to show your opening hours, phone number and website, if that information was relevant for your app.
Also, that’s not Ray’s real phone number, so don’t bother trying to call. :]
A great way to learn is to use the tools at geojson.io to explore GeoJSON further. You can draw geometry directly on a map and have it output the associated JSON.
A great way to learn is to use the tools at geojson.io to explore GeoJSON further. You can draw geometry directly on a map and have it output the associated JSON.
Next up, looking into how a GeoJSON file can be converted to an actual Swift model that you can work with in your code.