3.6 Marker Clustering
Markers aren’t entirely useful when they bunch up and overlap on one another. Fortunately, we can solve this issue with clustering.
1.Introduction2 lessons, 03:44
2.Maps4 lessons, 22:57
3.Markers7 lessons, 43:05
4.Creating a Widget1 lesson, 07:30
5.Services3 lessons, 19:48
6.Customizing Maps2 lessons, 04:06
3.6 Marker Clustering
So in the previous lesson, we found a way to do more advanced organization of our map markers. So now that we know how to dynamically find and remove markers, we need to be able to display several of them. And the problem with that is, is once you have several markers in a small area they can overlap onto each other. But we can fix this problem with clustering. So in our main script file, we have a loop that adds markers to random points on the page. We have a base lat and long but then we add a random number onto that to randomize its location. [BLANK_AUDIO] For each loop we add two markers, and we do that 40 times, so we have 80 markers onto the page. And as you can see at the zoom level, there's a couple of places where markers overlapping on to each other. And that makes some of these markers unclickable. So right here, I can click on this one, but when I want to get to the blue can behind it, it's a little more difficult to do so. And then as I zoom further out, the markers bunch up even more together. And if I zoom out even more, most of them are absolutely unclickable. So we can solve this issue by setting MarkerClusterering. So clustering doesn't come into google maps by default, you actually have to add an extra library. So this is an example of a cluster. We can see that we have this little circles that have these numbers in the center of them, and they represent how many markers are inside of that cluster. So if we click on this four, when we zoom in, we get these three right here. But then we also have more markers right here for this two cluster. And we click in, we see those two. And then as we zoom out, when the markers get closer, they clusterer in. So this is a much easier way of displaying markers onto the page. To set up clustering within Google Maps, you actually have to download a separate library because it doesn't come by default. So at this Google code website, the library is called Google Maps Utility Library V3. Now there's a ton of useful libraries listed here, such as the Day Night Overlay, but we're only interested in this MarkerClusterer. So we can click down here on the released versions, we can click on 1.0.2. Go to source, and then right here we have MarkerClusterer and the compiled version as well. Since we're just going to be working in a development environment, I'm going to take the uncompiled version. So I'm gonna copy this and I'm going to add it to our plunker. I'm gonna call it MarkerClusterer.js, and then I'm gonna paste in that code. And in my index.html file I'm going to add it right below my Google Maps reference. So now that we have this reference let's go into our Mapster library and we'll start setting up for our cluster. And a clusterer is an object that's constructed through a constructor function just like everything that we've worked with so far. And we're gonna add this marker clusterer as a property to our Mapster library. And the reason why we're going to set it as a property is because we need to access it within functions inside of the library. So we'll add it on as a property. And so we initialize it by saying newMarkerClusterer. And you can see that we don't actually say Google.Maps.MarkerClusterer. And this is because since it's in a separate library, it's not attached to the Google Maps namespace. So this constructor function will take the map that we're working with. It'll take in any of the markers that we want to cluster. In this case, we don't have anything, so we'll pass through an empty array. So to get these markers to clusterer up, we need to add them on to the cluster. So when we're adding markers down in our add marker function, we can tap into the MarkerClusterer. So the MarkerClusterer has an add marker function. And we just need to pass through the marker to get it onto the cluster. And you can see right here that we already have these clusters. We have these two stray markers right here but that's because they don't overlap onto anything, so they don't need to be clustered. But as we zoom out, they get sucked into the cluster. We have this marker right up here, and if we zoom further out, it gets sucked into the clusterer as well. And now you notice that the clusterer has actually changed colors, and that's because when clusters get more dense, you can change what color they are. And when we zoom out, we get even fewer clusters. And then we get to the top, we see the 81 total markers we have. And then if we click on a cluster, we get centered of all the smaller clusters in the area. And we can click on those clusters from there as well. So now you might be wondering how you control the color of the clusters. And just as we've passed through options to a marker, we can pass through options to the MarkerClusterer. So up in our constructor function, we can actually pass through an options. But currently we don't have any options being set for the MarkerClusterer. So where we do have our map options being set in our mapoptions.js file, we can set our property to set the clusterer options. If we just pass through ops.cluster, we can then customize our cluster. And then what we also can do, too, is we can check to see if we're using a clusterer in the first place. If there's a property for the cluster, then we'll initialize the clusterer library. If not, then we need to go down here to where we're adding our markers. And we need to also check for it down here as well. So in this case we haven't set any options for our MarkerClusterer yet, so it's going about it as it's not there. So to change that we'll go into Map Options, and then down here we'll set one for clusterer, and then automatically we can see that it's starting to clusterer up. And if we wanna set further options for our cluster, we can then create this options object. And within options we're gonna wanna set the styles. And the styles are an array of objects. And the reason why its an array is because its set up for the different densities. We saw the clusters change color as we zoomed higher up onto the map. And there's three types of densities that we're gonna be dealing with. There is small, medium and large. So the first object represents the small density, the second object the medium density, and the third one the large density. And right now we're not seeing any styles because we're setting the styles to blank. If we were to remove them, we see the small blue density clusterer. So what we're going to do is, is we're gonna switch the small clusterer density from being blue to an orange. So the first property we're putting into our style object is called URL. And this is similar to the icon property we deal with with markers. And I've just hot linked over to a MarkerClusterer, and that's m2. And we're not seeing anything, and that's because we need to set a height and a width. And once we have a height and a width set, we can see that we have our MarkerClusterer. And one thing we actually can do too is change the text color. And as ugly as it is we were able to change it to a red. And we also can change the text size. So by providing this first object literal, we're able to set the styles for setting the small density. And if we provide another object literal, we'll set it for the medium density. So we'll paste the object literal over, and then at the URL we'll change this to m1. And we'll get rid of the text color and the text size for this one. So now we'll zoom out, and we can see when we get to our medium density that our marker changed to a blue, and the smaller densities still have the orange color. So it's pretty easy to go through and set styles for our MarkerClusterer. But one thing we need to be aware of is now that we're using a cluster, removing our markers is a bit different. So down to the bottom of our main script file, I'm going to remove the marker with the ID of 2. And you can see that right now we have multiple IDs of 2. And anything that's the green rice marker should actually be removed from our map. But currently that's not happening. So right now we can console.log the marker that we're passing through the call back to make sure that we're actually evaluating that. And we can see in the console that we have all these markers that are the green, rice markers. So to make sure we're evaluating correctly, we'll do an if statement inside the remove by. And if the marker ID is equal to 2, then we'll console.log that marker. And we can see here in the console that we get all of these markers back. So if we're getting these markers, why aren't they removing from the map? So we'll go into our Mapster library and we'll check our removeBy function. And we can see that we're calling setMap to null. But now that we're using a MarkerClusterer, we actually need to call something different. So first we need to check to see if we're actually using a MarkerClusterer. So if we don't have a MarkerClusterer, we just wanna set the map to null. But if we do have a MarkerClusterer, we're gonna call another function. We're gonna call this.markercluster. And we're gonna call removeMarker, and we're gonna pass through the marker. But in this case is not working, and that's because the value of the this keyword. So we'll set a variable self to this and we'll change our this references to self. So now that we're checking for a map cluster, we can see that we don't get in those green rise markers on the map. So if you're using a MarkerClusterer you have to remove it from the clusterer to get it off the map. And if you're not using it, you can just call the set map function and set that to null. So far we've been able to add these functions onto this library and then just call them in this main script file. And since we know how this library is made, it's easy for us to tap into this API, but we might want to make it a bit easier for the everyday user to use it. And usually things like that are written as jQuery plugins and jQuery widgets. So in the next lesson we'll take this map library and we'll implement a jQuery widget with it.