Map Software
For our maps, there will be two main visual components: the basemap, and our custom building layers. The basemap will be used to display the general area around the building including campus, and other immediate surroundings. Our custom building layers will show the floor plans of the River Building and include labels for each room, and colour coding for various rooms to indicate what their use is, or if they are off limits.
For the purposes of our map, we will restrict the viewable area to just the Carleton campus.
Mapbox
Mapbox produces various tools and open source libraries for creating and displaying Map data. For the web, they publish the open source Mapbox GL JS (Github repo) library for displaying maps. They also provide similar open source SDKs for Android and iOS.
The basemap will be streamed to clients in a “vector tile” format. The map layer is split into multiple tiles at all different zoom levels and stored on a server and sent to the client as vector data which is then rendered by the client. Luckily, Mapbox’s libraries and SDK’s handle this for us! For all three clients (web, Android, iOS) we just need to load the correct layers using the respective libraries.
On the web, this can be handled by adding a vector source as a layer through Mapbox GL JS.
Our custom layers will be represented as GeoJson objects. GeoJson is a standard format for representing geospatial data as Json. Each floor will be its own “FeatureCollection” which will contain the polygons for all the features on that given floor. The Mapbox client libraries have built-in support for rendering GeoJson so we don’t need to do any special work there.
Simple start guides:
- Web: https://docs.mapbox.com/mapbox-gl-js/example/simple-map/
- Android: https://docs.mapbox.com/android/maps/examples/create-a-simple-map-view/
- iOS: https://docs.mapbox.com/ios/maps/examples/simple-map-view/
Selecting Floors
Loading our floor layers is easy however we’d like to be able to select which floor we want to see the layout of. Unfortunately, there is no built-in way to do this Mapbox’s libraries, but it’s trivial to implement. On each respective platform we just need to add some type of overlay on top of our map view. A stack of buttons that display each floor number, for example. We can then just set up the buttons to show/hide layers depending on which floor is selected.
Styling
Our basemaps will use either a light or dark theme (depending on the theme being used by the client, i.e. dark will be used the match a dark theme in a mobile app). These themes are clean, minimalistic, and really good looking.
Our custom layers will be featured on top and can feature more colours. What types of colours we’ll use will determine on the identity package produced by the design team at a later time. These styles can be applied uniformly across all platforms using built-in functions (themes are expressed as Json) so there won’t be any extra work needed to style our maps.
Geometry
Each floor will be represented using three layers: a FillLayer, a LineLayer, and a SymbolLayer. The FillLayer will represent the area of each room and hallway. The LineLayer will represent the walls of each room (as well as the doors, where there is a gap in the lines). The SymbolLayer will represent specific points of interest such as water fountains.
To keep the dataset as simple as possible, all the data for each floor and each layer will be stored as a single FeatureCollection
where each feature has a property that specifies which floor the feature belongs to. When the layer is displayed on the map (via the floor selector), the layer can simply filter for the floor number that is required and then filter for the type of feature required (i.e. MultiPolygon, MultiLineString, or Point features).
An additional Polygon feature will be included to display as the "outline" of the building (depending on which floor is being displayed).
Feature Properties
fid
: A unique id for the feature
floor
: Which floor the feature belongs to (1
, 2
, or 3
)
available
: Whether this feature is available for use during the hackathon (true
, false
)
label
: Whether to display a text label for this feature
symbolize
: Whether to display an image symbol for this feature
name
: The name to use when displaying a label
Rooms (MultiPolygon/MultiLineString)
type
: The type of element the feature represents (one of "room"
, "hallway"
, "washroom"
, "stairs"
, "elevator"
, null
)
room
: The number of the room, also used to identify this room when cross-referencing with event data
Points of interest (Points)
type
: What type of point this is (one of "water"
, "food"
, "sponsor"
)
Development Notes
Labeling Upcoming Events (and other labeling things)
As part of our GeoJson that defines our floor layout, we can include extra attributes that can be displayed as labels (such as room numbers), however this information is generally static. If we want to display dynamic label info, such as highlighting a room with an upcoming event, we can implement an API endpoint on the server (as part of the schedule/announcements API?) that simply returns a simple object describing the location of the room, its name, its floor, and the name/time of the event. This information can then be displayed as a marker. (Our marker might only contain text, not necessarily an image icon).
Mapbox handles all label drawing for us, so when we display our “featured” marker on top of our data layers we don’t have to worry about any text overlap. Mapbox will draw it in a way so that all labels are readable without overlap.
Other Interactive Components
Other than being able to zoom and pan around the map, it would be nice to allow the user to tap/click on rooms on the map to view a popup showing more information, such as upcoming events in that room, or any other details.
Maps can be set up to handle on click events.
Floor Selection
In order to allow users to select which floor they'd like to view, we will provide a overlaid selection bar on the top right-hand side of the map view. The selection bar will just be a vertical stack of "buttons" that the user can tap to toggle which floor is currently visible.
On the technical side, the full data set for the building will be stored as a Feature Collection (as outlined in the Geometry section) in a .geojson
file. Each feature has a floor
property which indicates which floor the feature belongs to. When the user selects another floor, we can simply filter the features in the layer which will hide/show only the features that we want. The .geojson
file will be loaded as a GeoJsonSource
which can then be used for multiple layers. There will be 3 layers: a FillLayer, a LineLayer, and a SymbolLayer. Each layer will eventually filter for only the matching type of geometry (MultiPolygon, MultiLineString, and Points, respectively) but for now, we will start with only a FillLayer and LineLayer using all of the polygon data that we have.
Currently we will only need to handle displaying 3 different floors, but our code should be able to handle any arbitrary number of floors should we ever need to add/remove floors or display other floorplans (such as the tunnel layouts) which would have different floor selection considerations.
At this point in time (mid-July) we won't worry about the quality of our selection bar's aesthetics, or the aesthetics of the floor plans. All we need is to be able to load floor plans and switch between several of them.
Another thing to take into consideration when determining how to load the .geojson
file into the map is that these .geojson
file will need to be able to be updated dynamically in the future, so they should be loaded from the filesystem, rather than strictly hardcoded into the app (that way the app could download new data and replace the data stored in the filesystem). The actual downloading/replacing does not need to be implemented yet, as we don't have the API endpoints to work with, but designing the app with this in mind will make work easier down the line.
Room Availability
Rooms can be marked as being (un)available independently of the type of the room. This provides more flexibility in styling the map to better convey that a room might be "temporarily unavailable". This will be set as one of the properties in the feature.
Last updated on