The Spaces Project is an application containing a selection of guided activity tours designed to educate participants about various elements of nature. In this post I will cover the development steps I took during the second phase of creating the Pollinator Tours for the Spaces app.


This post will cover the following development steps I took while creating this project

Step 2:


The Focus

The idea behind the creation of the Spaces Project was to create a tour experience that would teach users about pollinators. These tours would guide users to various points of interest around a physical location while encouraging them to observe natural elements that contribute to the survival and habits of pollinators. The intended take away would be a fun and memorable experience that would lead users to appreciate pollinators and their important role in our world.

This project is primarily intended to be used by families with elementary school aged children. Upon arriving at the tour location each family would be given an iPad running the Spaces Project and as a group would be guided by the app to travel from location to location completing activities.

Having little experience developing programs for mobile devices and having zero experience developing for Apple/IOS, I was excited for the new challenge. In this phase of development, I acquired an iPad and Mac, allowing me to start testing the functionality of the program on the mobile device it was intended to run on.


GPS

In the first phase of development for this project I put together a basic framework for taking in values for latitude and longitude, then placing a map marker on a map based on the relative position of the latitude/longitude values compared to the latitude/longitude of the map boundaries. In this phase of development I was able to acquire an iPad, allowing me to access actual GPS data and test the program in some actual field tests. These initial tests yielded mixed results. The initial field tests informed me that my code was successfully accessing the GPS data for the iPad and using that data to place the map marker on the map. However, it also informed me that I needed to do some additional research on latitude, longitude, and GPS values.

In my initial tests I primarily used whole numbers, or occasionally a whole number with a single digit to the right of the decimal point as my latitude and longitude values. Once I started testing the app on an iPad, I noticed that the map marker wasn’t moving at all to spite the GPS data changing each time I moved. I quickly realized that the issue was with the scale I was using, rather than a problem with the GPS or map marker placement code. A little research showed that 1 degree of latitude covers about 69 miles. The map area for the Pollinators Tour was about 800ft long, which comes out to roughly 0.15 miles. So having the boundaries of my map area set to cover 3 latitude degrees meant that I would have had to travel miles in order to see any movement change in the position of the map marker. Clearly, I needed to rework my GPS code to deal with extremely small values, rather than whole numbers.

At this point I also discovered that latitude/longitude values are typically displayed in one of two formats, Decimal Degrees and Degrees Minutes Seconds formats. So, I wrote some code to convert incoming GPS data into both of these formats, as well as break it down into smaller and more specific unit types. This allowed me to narrow down the important and usable portions of data and leave out the rest. For instance, since the north and south boundaries of the map area both fell within the 40-degree latitude, my code would disregard that value and only compare the data to the right of the decimal place.

With these new upgrades to my GPS code, I was able to refine the functionality of the map marker placement, and with that successfully got the map marker to move around the map as I walked. This new refined code allowed me to get accurate map marker placement within about a 10-foot margin of error. 10 feet may sound like a large margin of error at first glance, but it comes out to about 0.00189 of a mile (1 mile being 1/69th of a latitude degree).


Camera

With an iPad to test the program on, I was now ready to start testing and refining the camera activities. Thankfully the code to access my PC webcam worked the same way on an iPad, although some quirks did pop up non the less. The first bug I encountered was that the regular orientation of an iPad’s camera is apparently different than that of my webcam. So, when I opened the camera activity on an iPad, the image displayed to the screen was sideways and backward. I was easily able to fix this issue by simply rotating and flipping the canvas used to render the camera feed, thus making it display correctly when run on the iPad.

The next bug I encountered was with the second camera activity, the selfie screen. I found that the method I was using to save images from the camera feed and convert them into pictures was only saving information from the render canvas I used to display the camera feed to the screen. This meant that anything that the camera was not directly capturing, such as the selfie overlay, did not appear in the final saved image. With a little tinkering I found a way to save a snapshot of the entire device screen instead of the camera feed. Though this created a new problem for me. Although this method was now capturing the camera feed and the selfie overlay, it was also capturing any buttons, menus, or text currently displayed to the screen. Who wants to have selfies that also contain the camera menus and buttons in the shot? Probably not the users, was my though. I once again got to tinkering and after a short time figured out a way to get the program to turn off everything on the screen other than the camera feed and the selfie overlay while the picture was being saved. Then the program would automatically turn the buttons and menus back on as soon as it finished saving the selfie picture.

After these bugs were resolved, the last upgrade to the camera was a very simple one. I added a “next camera” button and functionality which allowed the user to change which camera the device used to display a camera feed to the screen. This allowed the user to switch between using the forward and rear facing iPad cameras.


Progress Puzzle

Around this time during one of the development meetings for the project, the Spaces team asked me to create another new feature they were referring to as the Progress Puzzle. The basic premise of this function would be to give the user access to a screen displaying a pollinator and various objects which represent habitat elements that pollinators require in order to survive. At the beginning of the program the progress puzzle would either be mostly blank or would only display outlines of the pollinator and habitat elements. As the users completed each activity, the habitat element corresponding to the activity would appear or would fill in with color. This would give the users an idea of a goal to complete at the start of the program as well as a sense of progress toward that goal throughout the program. I build a placeholder demo of this functionality using some cartoon trees, flowers, butterflies, and bees.

Photo Gallery

Another new feature that the Spaces team requested at this time was a photo gallery. This gallery would be a screen that would display all the pictures the user had taken with the camera throughout the program. To create this functionality, I used a copy of the glossary template I created earlier and added some extra code to link it to the camera. This new code allowed the gallery to replace its images with pictures anytime the camera took a new picture. I also added code to allow the gallery to auto populate its pictures with any photos previously saved to a specific location in previous playthroughs of the project.


Map

The next feature I created was central to the functionality of the pollinator tours, that was the map feature. The map was meant to function with the GPS code I covered earlier in order to guide the users from place to place for each activity. I knew from previous tests that I could get the map marker to move around the map based on GPS location of the iPad in relation to the latitude/longitude of the map boundaries. I then built location markers which would display an image for the location of each activity in the program. The user can click on any of these location markers to open a full screen view of the location image along with the locations name. When the map marker representing the user’s location on the map arrives at the location they are being directed to for the next activity, the program automatically closes the map and moved to the next slide in the tour.

After my first field test out to the tour location, I realized that I needed to refine the latitude/longitude values I was using for my map boundaries. The map worked as expected, but was off by a bit, leading to a mismatch between the activity locations on the map vs their real-world locations. I decided to build a function into the code to make debugging this mismatch issue easier to fix without countless trips to the real-world tour location. This debug function let me give each map location their real-world latitude/longitude and used a variation on the map marker placement code to place the map locations in the correct positions relative to the map boundaries.

At this point I also added a small feature that would rotate the arrow used for the map marker so that it always faced the same direction as the iPad relative to north.


Map Rotation

The program up to this point had all the functionality required to successfully build, test, and deploy the first pollinator tour. The team was able to successfully load the app onto a few iPads and run some users through the tour with great results. At which point I was asked to start work on the second pollinator tour for the app. Most of the development for this second tour came together smoothly, but a new and challenging issue arose in the final steps of development.

Unlike the map for the first tour, which aligned neatly parallel to the latitude/longitude lines, the second map was screwed at about 45 degrees from these lines. Although at first glance this wouldn’t seem to be an issue, the GPS code did not handle it as well as expected. Since I built the original GPS and map marker placement code to use minimum and maximum latitude/longitude values for the map boundaries, having a map with corners that didn’t share a common boundary value meant that the code skewed the marker placement values. It took me a bit of trial and error, but eventually I figured out a bit of code I could add to the GPS code to factor a rotation matrix value into the final stages of map placement calculations. This code allowed me to inform the GPS that the map was skewed from the normal latitude/longitude lines. This solution would fix the GPS placement used in the new tours map without breaking the functionality of the original tours map, since they both run off the same code.


 

* The Transforming Outdoor Places into Learning Spaces project was made possible in part by the National Science Foundation, grant #1811424. The views, findings, conclusions, or recommendations expressed in this blog do not necessarily represent those of the National Science Foundation. *