Quantcast
Channel: maps for developers - Medium
Viewing all articles
Browse latest Browse all 2230

A deep dive into Expressions with the Open University of Brazil

$
0
0
Explore the Open University of Brazil system with their custom-styled map.

By: Kalimar Maia

The Open University of Brazil is an educational network of public universities, regional governments, and the federal government to offer higher education online. Dr. Tel Amiel, his research team, and the team responsible for the Open University of Brazil (DED/CAPES) chose to migrate their interactive map of their university system from Leaflet to GL JS.

We wanted to improve the look and feel of the map experience. Mapbox GL-JS made the map load much faster and provided smooth in and out zooming. We were only comfortable migrating due to Mapbox’s open-source philosophy. — Dr. Tel Amiel, professor at the School of Education at the University of Brasilia and UNESCO Chair in Open Education

The updated map is part of a decentralized nationwide initiative to encourage openness in education and government. We worked with the team to implement Expressions for GL JS to ensure that the revamped map is customized and performant.

Expressions help you custom-style your data based on data property and zoom level. Implementing Expressions reduces the amount of code you need to write and cuts down on the number of layers needed in the map. Another plus: Expressions also allow you to organize and maintain your data flexibly.

The set-up

On the map, when a user clicks on a larger university its satellite centers appear:

Blue points are universities and the red points are satellite schools

We assumed each satellite center ties to one university to build this feature collection:

Here’s the way we show the satellite centers on the map:

A very brief intro to Expressions

You can suspect Expressions are involved when you see [] (arrays). Expressions are used in layout, paint, and filter properties to calculate the value of the particular property. Using Expressions here saves us the work of writing a lot of extra code. Without them, we would have to build a new FeatureCollectionthat found the relevant satellite school features and add them as a new layer on the map. With Expressions, we can iterate over all of the features and check if they match the conditions we ask.

Familiar with prefix notation? That’s when you perform arithmetic like this: + 1 2 instead of infix notation 1+2. That’s how Expressions work. Now imagine instead of 1 or 2 you have yet another expression. It takes a little practice reading because we write our statements across several lines but similar to + 1 2 we are writing "all", [expression1], [expression2]. We are using the "all" expression meaning all of the following statements will be Expressions which must be satisfied. All of the features in the collection will be evaluated. If they satisfy both Expressions then they will show up on the map. 👍

["==", ["get", "university], university] means “get the university property from this feature and tell me its value. If it matches the university name of the feature you clicked on, then you’re good.

["==", ["get", "type"], "satellite"] means “get the type property from this feature and check if it is the word “satellite”.

Ok done! Except…not really. Turns out we weren’t dealing with a one-to-many situation. The Open University is a many-to-many relationship.

So what does “many-to-many” even mean? In database parlance, many-to-many relationships look like this:

One university can be associated with several satellite centers. At the same time, one satellite center can be associated with several universities. Well darn. Looks like we’ll have to write some custom code that can deal with this, build a new FeatureCollection.

Turns out we can do this at least three different ways with Expressions.

Version 1 — nested key, value property

Here’s what three of our features look like. We have two universities and a satellite school with the property universities. The satellite school is associated with two different universities. That property has key, value pairs that correspond to the university name and the boolean true.

Plus the code for clicking on the University to show the related satellite schools:

This looks very similar to the previous example however there is a very different expression here that uses "has". We’re using the "has" expression to check if the "universities" property has a key that matches the name of the university. The satellite school above has the following universities property:

The keys are “UnB” and “UFMG”. That means the user could click on the University named “UnB” OR “UFMG” and that satellite school would appear.

This first method gets the job done, but it is very likely the person organizing this data is using a CSV file that gets converted to geoJSON and doesn’t have familiarity with key, value pairs. Let’s try to simplify our geoJSON file and avoid using the nesting.

Version 2: university names as properties

Let’s try to simplify our geoJSON file and avoid using the nesting. Here’s what features look like:

This looks somewhat similar to what we did with the embedded property except now we moved the features up a level and made them their own properties. This seems pretty reasonable for the end user. The only drawback is having as many columns in the CSV file as there are universities. If there are fifty universities, that starts to get pretty big. Let’s see how to implement this one:

This is very similar to Version 1. Now we are using the second implementation of "has". When you only specify [“has", university] you will have a feature that checks through all of the properties to see if any of them have the name of the university as a label. Can you parse the filter? If the feature "has"a property with the name that matches the university variable and its "type" is "satellite" then show it on the map.

Version 3 — university1, university2, etc as properties

For this strategy, we created properties called "university1" and "university2" assuming a satellite school could only be associated with two universities. Here are a couple of features:

This uses a very different approach so let’s see how we do the filtering:

Now we are getting into a nesting doll situation — hiding Expressions within Expressions. ["all", [expression1], [expression2]] now expands to ["all", ["any", [expression1], [expression2]], [expresssion2].

We have our old friends "all"and the second expression [“==”, "satellite", [“get", “type”]] but now we have a new Expression that uses the “any” operator. The “any” operator returns true if any of the Expressions that follow it are true.

The user clicks on a university and then we filter all of the features to see which ones might have that particular university. If the university name is present AND it’s a satellite school we show it on the map. We think this is the most straightforward solution.

We worked through all these examples with the University Team and in the end, they used them to implement their own custom solution using Expressions. To get started on your own custom-styled map, check out our Expressions for GL JS tutorial.

Kalimar Maia


A deep dive into Expressions with the Open University of Brazil was originally published in Points of interest on Medium, where people are continuing the conversation by highlighting and responding to this story.


Viewing all articles
Browse latest Browse all 2230

Trending Articles