Building a College Map Application with Electron & Mapbox

Tyler Brown Cifu Shuster
Pacific Sky
Published in
7 min readNov 23, 2016

--

Hello World!

My name’s Tyler Shuster and I develop code here at Pacific Sky. I call myself a writer. I write code, prose, poetry, philosophy; basically, whatever I can find the time to do. I’m increasingly passionate about what I do and this blog is an attempt to share some of my process to fellow developers. I also hope it will give you a little more insight into what Pacific Sky does. I’ll be going into the metaphorical nuts and bolts of the trade and won’t avoid technical terms though I’ll link where I can for further learning.

Most of the code on which I work is for websites, a number of which you can see in our portfolio. However, another sector in which we work is applications. This will probably be the subject of another blog post, but suffice it for now to say that I develop applications with web technology, using HTML, CSS, JavaScript, and SVG as exclusively as possible.

I’ve had the distinct pleasure in the last few months of working with College Options and Enterprise High School. Tim Warkentin at College Options contacted us a while back asking if we would be able to develop a map application that would run on a touch screen. The basic idea behind this map is that high school students will be able to explore their options for colleges within California.

Requirements & Assumptions

  • Windows 10 environment
  • 1920x1080 resolution
  • Support touch events
  • Internet connectivity
  • List all colleges & universities in CA with information
  • Costs
  • Student Body Sizes
  • Degrees available
  • Enrollment videos

Platform

To build this, the natural choice for me was the Electron platform. As I mentioned before, I write using web technology when possible. That’s partially because of my experience, but also because of my philosophy. Electron is a wrapper that allows developers to write HTML, CSS, and JavaScript that runs as its own application. There’s some debate about Electron’s feasibility in making native apps because it’s a wrapper, but in the end it worked and it worked well, and that’s the only real benchmark.

For the map itself I used the excellent Mapbox platform. I chose it for a couple reasons: philosophical; their commitment to open source is admirable, technological; their API is a dream to use as opposed to Google Maps, financial; it’s free for our scale of project, historical; I’ve used it (a little) before. The API works well with GeoJSON sources and Mapbox GL JS is super-fast, supports touch events, and of course is written in the same language as the rest of the app. If you’re not familiar with GeoJSON, it’s a data format for geographical information that can be parsed in JavaScript.

Process

The first thing to do was to coerce the data provided by our contact, Tim Warkentin. Tim’s been great to work with and provided all the data we needed. In this case it came in the form of four spreadsheets, each with data about the schools. I converted these to GeoJSON using Atom on the CSV file. I felt like that was a faster approach than writing a script to convert it. Here’s a sample of the GeoJSON data:

[{"type": "Feature","geometry": {"type": "Point","coordinates": [-121.750944, 38.537281]},"properties": {"marker-symbol": "college-uc","title": "UC Davis","address": "1 Shields Ave., Davis, CA","video": "https://youtube.com/embed/PAwB_t_iM7U","degrees-offered": ["Bachelor's", "Master's", "Doctorate"],"student-population": 34508,"student-ratio": 18,"city-size": "Suburb: Small","campus-housing": true,"tuition-2016": 13951,"housing-2016": 14571,"expenses-on-campus-2016": 34377,"expenses-off-campus-2016": 29243,"average-scholarship": 15547,"collegeType": "uc"}}]

The coordinates I retrieved using a batch geocoder.

The next step was to wire the skeleton of the application together. This was my first Electron project so I used a tool called Neutron to bootstrap some of the work. (Honestly, I mostly chose to use Neutron because of its live reloading. In the end it proved invaluable for pre-processing, linting, and packaging. I’ll probably build my own toolchain in the future but for a beginner it’s been really helpful.) By running npm start in a Neutron directory, Electron will start the application and automatically build when files in the src directory change.

How it Works

When the application starts, it bootstraps a couple dependencies, requires the index.html file, and prevents new windows from opening (because people like to do what they’re not allowed to do).

The index.html pulls in the Mapbox API, jQuery, the fonts, the Vimeo API, and prevents the display from scaling. Initial testing proved that without the meta viewport tag declaring user-scalable=no, a five-finger spread on the screen would scale the whole interface. This is part of Webkit(Electron's engine)’s default behavior. The index also contains the skeleton including the filter icons, the wrappers for various dynamic elements, and an SVG compass (the north needle changes as the map rotates via a CSS transform). Finally the page requires the utilities scripts and the main scripts.

The main script opens the GeoJSON file with the colleges’ information, performs some transforms and stores it in memory. From there it initializes the Mapbox API. We’re using a modified base streets style that reduces the amount of data displayed, essentially limiting it to road and city names. The base layer from OpenStreetMap also has many college campuses on it, which I highlighted. A few notes about the implementation:

First, the bounds of the map are dynamic. The map is bounded to only view California (again, people like to do what they’re not allowed to), but there’s a college called Palo Verde College on the border of California and Arizona. When zoomed all the way out, the user needs to be able to see this college, even if the college pane is open. When zooming in, we don’t want the user to scroll into Arizona. There’s a listener on the map zoom event that dynamically sets the maximum eastward bound.

Second, the pitch of the map is also dynamic. When zoomed all the way out, the user is looking directly down at the state. When zoomed all the way in, the user is looking at a perspective of the landscape as if they were about a mile in the air and looking out about fifteen miles.

Zooming into a college

This is achieved via a helper function that calculates the pitch based on the zoom level, and fires every time the zoom level changes.

There are four different kinds of colleges: CSU, UC, Private, and Community. Users need to be able to visually distinguish between these when looking at the map. Users also need to be able to sort the list of colleges by type, the action of doing which needs to filter the displayed icons. Between some simple jQuery and Mapbox API filters, this was pretty simple to accomplish.

Filtering colleges by type

I had to include the icons for each college type in Mapbox studio when I created the style so that they’d be available when the GeoJSON was inserted, hence the marker-symbol property.

There’s also a ‘visible’ filter. This filter reduces the list on the right to only show colleges that are within the user’s viewport. This is accomplished via listeners on the zoomend, move, and rotate events on the map that query visible features.

When a user taps on a college icon, the pane on the left slides out if it’s not visible already, and a pane for the college slides into view. Subsequent colleges push up existing panes, which can be opened accordion-style.

Students can review information and open video modals if available. When a number of colleges are selected, clicking ‘compare colleges’ displays a table with the selected colleges’ data.

Conclusion

I’m currently working on a management and web-based interface for this application so that it can be used at any number of schools, and so that the data can be updated as cost or other information changes over time.

This project couldn’t have been a success without the work of I’m sure thousands of people: the contributors to OpenStreetMap data, the Mapbox developers and community, the NodeJS & Electron community, the jQuery team, and the Neutron community — not even to mention the hundreds of organizations involved in the tools upon which the mentioned were build. I’m proud to have worked on this application because of the strength of the open-source community which enabled it. Pacific Sky is the one getting paid for the project, but I hope that the work I’ve done here can be used by others and distributed across California, if not adapted to many other states.

--

--