Adding Map Style Switching to Mapbox using Matestack

When providing map services to clients in a mapping application, it’s quite normal for them to want to have the option to view the geospatial data on different map styles. Views such as dark, light, transit, satellite, etc.

A couple of says ago, I saw some developers do this on a React project and I was shocked at how much code was required and how complex it was. Literally shocked. The changset listed in the git commit spanned a good number of pages.

That evening I added this very functionality to a mapping app that I maintain. The app was built with Rails 6 and Matestack. To Add this is was so very simple, low complexity and it took about 20 minutes.

In the Matestack view that serves up the map page, I added the menu style controls. This looks deceptively simple; behind the scenes it emits an event carrying map style data when a button is clicked.

def style_menu_partial
  div id: "style-menu" do
    onclick emit: "set_map_style", data: 'mapbox://styles/mapbox/satellite-v9' do
      bs_btn class: 'btn-sm', text: 'Satellite'
    end
    onclick emit: "set_map_style", data: 'mapbox://styles/mapbox/satellite-streets-v11' do
      bs_btn class: 'btn-sm', text: 'Satellite Streets'
    end
    onclick emit: "set_map_style", data: 'mapbox://styles/keithrowell/cks2myz68312b17p6133ihn7m' do
      bs_btn class: 'btn-sm', text: 'Regular'
    end
  end
end

In the onLoaded for the map javascript page, I registered an event to receive info about a map style to change to.

onLoaded() {
  MatestackUiCore.eventHub.$on("set_map_style", this.setMapStyle)
}

Also in the map javascript page, define the function that handles the data sent by the set_map_style event, setting the map style via the Mapbox GL API.

setMapStyle(style) {
  this.map.setStyle(style)
}

And here’s what I got.

Satellite Street View
Satellite Street View

So elegant and so easy. That’s Matestack.