In last post I was described how to get current location and show it as marker in the map. Let's think a scenario which is you have to show lot of markers in the map. In this case map going to be the fill with markers and user can't get an idea on looking at the map. This going to be loose the user experience. So solution for this kind of a requirement is group the markers in the map. There are various approaches for achieve the solution for this. Today I'm going to explain one method belongs to Clustering which is MarkerClusterer. Clustering is simplifies your data visualization by consolidating data that are nearby each other on the map in an aggregate form.
The MarkerClusterer is a client side library. This use grid-based clustering to a collection of markers. It works by iterating though the markers in the collection that you wish to cluster and adding each one into the closest cluster if it is within in a minimum square pixel bounds. For demo this approach I used the previous post implementation as basement. Actually this is a extending the previous post implementation.
To develop marker clusterer in your application first you have to reference it in your HTML page. You can download the markerclusterer.js from here. Other than there is no any changes in the HTML page from the previous post.
The MarkerClusterer is a client side library. This use grid-based clustering to a collection of markers. It works by iterating though the markers in the collection that you wish to cluster and adding each one into the closest cluster if it is within in a minimum square pixel bounds. For demo this approach I used the previous post implementation as basement. Actually this is a extending the previous post implementation.
To develop marker clusterer in your application first you have to reference it in your HTML page. You can download the markerclusterer.js from here. Other than there is no any changes in the HTML page from the previous post.
<!DOCTYPE html> <html> <head> <title>Map View</title> <link href="style/jquery.mobile-1.4.2.css" rel="stylesheet" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <div data-role="page" id="map-page" data-url="map-page"> <div data-role="header"> <span style="align-content:center;">Map</span> </div> <div data-role="content" data-position="fixed" id="map_canvas"> <!-- map loads here... --> </div> <div data-role="footer"> Footer </div> </div> <!--Jquery--> <script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script> <!--Jquery Mobile--> <script type="text/javascript" src="scripts/jquery.mobile-1.4.2.js"></script> <!--Cordova--> <script type="text/javascript" src="scripts/cordova.js"></script> <!--Google Map--> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=true&"></script> <!--Google Map Marker Cluster--> <script type="text/javascript" src="scripts/markerclusterer.js"></script> <!--Map View--> <script type="text/javascript" src="scripts/JS/MapView.js"></script> <script type="text/javascript"> $(document).ready( function () { var mapView = new PhoneGapMapApp.MapView(); mapView.init(); } ); </script> </body> </html>
PhoneGapMapApp = {} PhoneGapMapApp.MapView = function () { this._map = null; this._currentLocation = null; this._locations = null; this._markerClusterer = null; } PhoneGapMapApp.MapView.prototype = { init: function () { this._defaultLocation = new google.maps.LatLng(6.5006036, 80.2711642); this._attachEventHandlers(); }, /** * Attach event handlers. */ _attachEventHandlers: function () { document.addEventListener("deviceready", this._onDeviceReady(this), false); }, /** * device APIs are available. */ _onDeviceReady: function (obj) { console.log('device ready'); obj._getRealContentHeight(); obj._loadMap(); obj._identifyCurrentLocation(); obj._loadLocationData(); obj._loadMapMarkers(); }, /** * Setup the content hieght. */ _getRealContentHeight: function () { var header = $.mobile.activePage.find("div[data-role='header']:visible"); var footer = $.mobile.activePage.find("div[data-role='footer']:visible"); var content = $.mobile.activePage.find("div[data-role='content']:visible:visible"); var viewport_height = $(window).height(); var content_height = viewport_height - header.outerHeight() - footer.outerHeight(); if ((content.outerHeight() - header.outerHeight() - footer.outerHeight()) <= viewport_height) { content_height -= (content.outerHeight() - content.height()); } $('#map_canvas').height(content_height); }, /** * create map. */ _loadMap: function () { var myOptions = { zoom: 4, center: this._defaultLocation, mapTypeId: google.maps.MapTypeId.ROADMAP }; this._map = new google.maps.Map(document.getElementById('map_canvas'), myOptions); }, /** * Identify current location. */ _identifyCurrentLocation: function () { if (navigator.geolocation) { browserSupportFlag = true; var that = this; var currentPositionCallback = function (position) { that._identifyCurrentLocationCompleted(position); }; var noGeolocationCallback = function () { that._handleNoGeolocation(browserSupportFlag); }; navigator.geolocation.getCurrentPosition( currentPositionCallback, noGeolocationCallback, { 'enableHighAccuracy': true, 'timeout': 20000 }); } else { browserSupportFlag = false; this._handleNoGeolocation(browserSupportFlag); } }, /** * Handles the situation when current location not found * or not allow from the user for access current location. */ _handleNoGeolocation: function (errorFlag) { this.goTo(this._defaultLocation); }, /** * Current location identify operation success callback. */ _identifyCurrentLocationCompleted: function (position) { this._currentLocation = new google.maps.LatLng( position.coords.latitude, position.coords.longitude); this.goTo(this._currentLocation); }, /** * Show current location in the map. */ goTo: function (position) { this._setMarkerForLocation(position); this._map.setCenter(position); }, /** * Set marker for location. */ _setMarkerForLocation: function (latLng) { var marker = new google.maps.Marker({ position: latLng, map: this._map, title: "You are here !!!" }); }, /** * Load markers for the map. */ _loadMapMarkers: function () { if (this._locations != null) { this._displayParksListInMap(); } }, /** * Create marker list from location details. */ _displayParksListInMap: function () { var markers = []; for (var locationIndex = 0; locationIndex < this._locations.length; locationIndex++) { var location = this._locations[locationIndex]; var marker = null; //Add new location to the markers var latLng = new google.maps.LatLng ( location.LocationLatitude, location.LocationLongitude ) marker = new google.maps.Marker ({ position: latLng, title: location.LocationName }); markers.push(marker); } this._initializeMarkerClusterer(markers); }, /** * Initialize marker cluster view in the map. */ _initializeMarkerClusterer: function (markers) { this._markerClusterer = new MarkerClusterer( this._map, markers, { maxZoom: 18, gridSize: 15 }); }, /** * Create local static data. */ _loadLocationData: function () { var location = {}; var locations = new Array(); location = { LocationID: 01, LocationName: 'Asiri Surgical Hospital', LocationLongitude: 79.880167, LocationLatitude: 6.894737 }; locations.push(location); location = { LocationID: 02, LocationName: 'The Asiri Central Hospital', LocationLongitude: 79.8658391, LocationLatitude: 6.9205805 }; locations.push(location); location = { LocationID: 03, LocationName: 'Majestic City', LocationLongitude: 79.8547562, LocationLatitude: 6.8940211 }; locations.push(location); location = { LocationID: 04, LocationName: 'Liberty Plaza', LocationLongitude: 79.8515386, LocationLatitude: 6.911252 }; locations.push(location); this._locations = locations; } }