Mapbox GL JS – Click and Hover Events

We just went over events in my mapbox gl js class at the University of Toronto. For fun, I updated the “GeoCV” map on my homepage to add these features. Here’s the JS code:

//Javascript File
mapboxgl.accessToken = '<INSERT YOUR ACCESS KEY HERE>';
var popup = null
var map = new mapboxgl.Map({
 container: 'map',
 style: 'mapbox://styles/mwidener/ciukh23bo000b2io4qrcq87s9',
 center: [-84.516476, 39.131658],
 zoom: 2.5
});

//academic_positions is a vector tile file stored on mapbox studio
//~~~FEATURES:~~~~
//Academic_Positions
//3 properties | This layer contains mostly Points
//Name  String
//Position  String
//Time Period  String

map.on('style.load', function(){
 map.addSource('academic_positions_src',{
 'type': 'vector',
 'url': 'mapbox://mwidener.ciulhf3s100662zmwys884b2b-0d75j'
 });

//display two layers ... both drawing from the vector tiles from 
//source: 'academic_provinces_src'
 map.addLayer({
 'id': 'academic_positions',
 'type': 'circle',
 'source': 'academic_positions_src',
 'interactive': true,
 'layout': {},
 'paint': {
 'circle-color': 'red',
 'circle-radius': 5,
 },
 'source-layer': 'Academic_Positions'
 });

 map.addLayer({
 'id': 'academic_positions_clicked',
 'type': 'circle',
 'source': 'academic_positions_src',
 'interactive': true,
 'layout': {},
 'paint': {
 'circle-color': 'red',
 'circle-radius': 6, //make point a little bigger after click
 },
 'source-layer': 'Academic_Positions',
 'filter': [ '==', 'Name', '' ] 
// start with a filter that doesn't select anything
 });

});

//an event where when there is a mouse click, 
//send the event data (represented by e) to a 
//function that does something

map.on('click', function(e) {
 //get the spatial features where your mouse is currently located. 
 //note we use the pixel location (e.point) and not lat/lon here.
 //also specify the feature we want to pay attention 
 //to - 'academic_positions'
 var features = map.queryRenderedFeatures(e.point, {
 layers: ['academic_positions']
 });
 if (!features.length) {
 return;
 }

 popup = new mapboxgl.Popup({
 closeButton: true,
 closeOnClick: true
 });

 //set a filter on the academic_positions_clicked layer 
 //so that the point we clicked on shows up
 map.setFilter('academic_positions_clicked',['==','Name',features[0].properties.Name]);
 //set the location of our popup to the 
 //lnglat of our click (note we use e.lnglat here and NOT e.point)
 popup.setLngLat(e.lngLat);
 //give the popup content
 popup.setHTML(
 "<b>" + features[0].properties.Name + "</b>" + 
 "<br>Michael's position: " + features[0].properties.Position +" "
 );
 //finally add the popup to the map
 popup.addTo(map);
 map.panTo(e.lngLat);
 });

//When the mouse moves over a spatial layer 
//we care about (e.g. a point) let's change the mouse cursor
map.on("mousemove", function(e) {
 //get the province feature underneath the mouse
 var features = map.queryRenderedFeatures(e.point, {
 layers: ["academic_positions"]
 });
 //if there's a point under our mouse, then do the following.
 if (features.length > 0) {
 //use the following code to change the 
 //cursor to a pointer ('pointer') instead of the default ('')
 map.getCanvas().style.cursor = (features[0].properties.Name !== null) ? 'pointer' : '';
 }
 //if there are no points under our mouse, 
 //then change the cursor back to the default
 else {
 map.getCanvas().style.cursor = '';
 }
});

 

And here’s the HTML:

<!DOCTYPE html>
<html>
<head>
 <meta charset=utf-8 />
 <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
 <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.26.0/mapbox-gl.js'></script>
 <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.26.0/mapbox-gl.css' rel='stylesheet' />
 <style>
 body { margin:0; padding:0; }
 #map { 
 position:absolute; 
 top:0; 
 bottom:0; 
 width:100%; 
 }
 .map-overlay {
 position: absolute;
 bottom: 0;
 right: 0;
 background: rgba(255, 255, 255, 0.8);
 margin-right: 10px;
 margin-bottom:24px;
 padding-left: 3px;
 padding-right:3px;
 padding-top:3px;
 padding-bottom:3px;
 font-family: Arial, sans-serif;
 border-radius: 5px;
 }


 </style>
</head>
<body>
 <div id='map' class='map'> </div>
 <!--<div id='map'></div>-->
 <div class='map-overlay' id='features'><b><center> Click on a red point <br> to see where <br> Michael has been! </b></center></div>
 <script src='./geocv.js'></script>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *