sentilo/sentilo

View on GitHub
sentilo-catalog-web/src/main/webapp/WEB-INF/jsp/common/include_script_maps_gmaps.jsp

Summary

Maintainability
Test Coverage
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@include file="/WEB-INF/jsp/common/taglibs.jsp"%>

<spring:eval expression="@sentiloConfigProperties.getProperty('sentilo.catalog.map.google.key')" var="apiKey"/>
<c:choose>
    <c:when test="${not empty apiKey}">
        <c:set var="mapsAPIUrl" value="${currentSchema}://maps.google.com/maps/api/js?v=3.41&libraries=places&language=en&key=${apiKey}"/>
    </c:when>
    <c:otherwise>
        <c:set var="mapsAPIUrl" value="${currentSchema}://maps.google.com/maps/api/js?v=3.41&libraries=places&language=en"/>
    </c:otherwise>
</c:choose>


<script type="text/javascript" src="${mapsAPIUrl}"></script>
<spring:url value="/static/js/gmap3.min.js" var="gmap3JS" />
<script type="text/javascript" src="${gmap3JS}"></script>
<spring:url value="/static/js/infobox.js" var="infoboxJS" />
<script type="text/javascript" src="${infoboxJS}"></script>
<spring:url value="/static/js/markerclusterer_packed.js" var="marketclusterJS" />
<script type="text/javascript" src="${marketclusterJS}"></script>
<spring:url value="/static/js/oms.min.js" var="omsJS" />
<script type="text/javascript" src="${omsJS}"></script>

<script type="text/javascript">
    // Default infobox pixel offsets for detailed view cases
    var defaultInfoboxPixelOffset_Y_A = -265;
    var defaultInfoboxPixelOffset_Y_B = -330;
    var defaultInfoboxPixelOffset_Y_C = -390;

    var mc;
    var oms;
    
    var lineSymbol = {
      path: 'M 0,-0.5 0,0.5',
      scale: 6,
      strokeWeight: 3,
      strokeColor: '#FFFFFF'
    };
            
    var polyOptions = {        
        icons: [{
          icon: lineSymbol,
          offset: '100%'
        }],                
        strokeColor: "#25adee",                
        strokeOpacity: 0.5
    };
                    
    var zoomChanged = false;
    var result_map = {};

    var boxOptions = {
            maxWidth: 0,
            pixelOffset: new google.maps.Size(-140, -420), // offset for infobox without scroll: default
            zIndex: null,
            alignBottom: false,
            boxStyle: {
                background: "transparent",
                color: "#ffffff",
                opacity: 0.9,
                width: "600px",
                padding: "4px",
                borderRadius: "4px",
                fontSize: "11px",
                whiteSpace: "nowrap",
                textAlign: "center"
            },
            closeBoxURL: "",
            infoBoxClearance: new google.maps.Size(50, 50),
            isHidden: false,
            pane: "floatPane",
            disableAutoPan:false, //Infobox must be displayed entirely within the map's visible area
            enableEventPropagation: false
    };

    var clusterStyles = [[{
        url: clusterImgsPath+'poi-group.png',
        width: 53,
        height: 53,
        anchorText: [-12, -12],
        textColor: '#ffffff'
      }, {
        url: clusterImgsPath+'poi-group2.png',
        width: 56,
        height: 56,
        anchorText: [-11, -11],
        textColor: '#ffffff'        
      }, {
        url: clusterImgsPath+'poi-group3.png',
        width: 66,
        height: 66,
        anchorText: [-14, -14],
        textColor: '#ffffff'        
      }, {
        url: clusterImgsPath+'poi-group4.png',
        width: 78,
        height: 78,
        anchorText: [-18, -18],        
        textColor: '#ffffff'        
      }, {
        url: clusterImgsPath+'poi-group5.png',
        width: 90,
        height: 90,
        anchorText: [-18, -18],        
        textColor: '#ffffff'        
      }]];
    
    function setInfowindowMustBeClosed(close) {
        infowindowMustBeClosed = close;
    }
    
    function showMapControls() {
        $('#map_controls').show();
    };
    
    function hideMapControls() {
        $('#map_controls').hide();
    };
    
    function initializeStreetView(map) {
      
        var sv = map.getStreetView();
        var svChangeVisibilityCallback = function () {
            if (sv.getVisible()) {
                hideMapControls();
            } else {
                showMapControls();
            }
        };
        google.maps.event.addListener(sv, 'visible_changed', svChangeVisibilityCallback);
    };
    
    function initializeMapControls() {
        var map_pos = $('#map_canvas_1').offset();        
        $('#map_controls').css({
            position:'absolute',
            top: map_pos.top + 10
        });
    };
    
    function initializeGeoCoder() {
        geocoder = new google.maps.Geocoder();
    };
    
    function initialize() {
                    
        map = $('#map_canvas_1').gmap3('get');
    
        initializeGeoCoder();
    
        marker = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
        });
        
        var image = {
            url: '${imgSpot}',
            size: new google.maps.Size(22, 22),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(0, 22)
        };
        
        marker.setIcon(image);                
        
        initializeStreetView(map);
    
        // La funcion initialize se llama tanto al recargar la página como al hacer un filtrado por tipo de componente
        // Esto implica que en caso de existir un mc anterior, debemos o bien eliminar los markers que ya tiene fijados
        // antes de crear un MarkerClustered nuevo, o bien reutilizar el ya existente.
        if(!infowindow){
            infowindow = new InfoBox(boxOptions);
        }
        
        if(!mc){            
            mc = new MarkerClusterer(map,[],{ maxZoom: defaultMaxZoomCluster , styles: clusterStyles[0]});            
        }    

        if(!oms){                        
            oms = new OverlappingMarkerSpiderfier(map,{markersWontMove: true, markersWontHide: true, keepSpiderfied: true, legWeight: 0});                     
        }

        google.maps.event.addListener(map, 'click', function(e) {    
            if (e.placeId) {
                // Since we don't want show Google Maps Place Poi Infowindows
                // Lets stop the event!
                e.stop();
            }
            
            closeInfoWindow();
            
            if (isModalLayerVisible()) {
                hideModalLayer();    
            }
        });    
        
        // These two controls change map options to turn off panning/zooming when the mouse enters the infobox
        // and so the infobox scrollbar could work. 
        $(document).delegate("div#infobox", "mouseenter", function() {
            map.setOptions({
               draggable: false,
               scrollwheel: false
            });                
        });

        $(document).delegate("div#infobox", "mouseleave", function() {
            map.setOptions({
                draggable: true,
                scrollwheel: true
            });               
        });
    }

    function createComponentMarker(component) {
        const position = new google.maps.LatLng(component.centroid.latitude, component.centroid.longitude);

        var poi = new google.maps.Marker({
            map: (component.options?null:map),
            position: position
        });

        poi.options = {
            id: component.id,
            name: component.name,
            type: component.type,
            iconName: component.icon,
            title: component.icon
        };

        poi.setPosition(position);
        poi.setIcon(getPOIImage(component));

        if(component.route){
            poi.options.route = component.route;
        }

        return poi;
    };

    function getPOIImage(data) {        
        return {
            url: data && data.icon ? '${iconsPath}/' + data.icon + '-poi.png' : '${defaultIcon}',
            size: new google.maps.Size(28, 30),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(0, 30)
        };
    };
            
    function printMobileComponent(poi){
        if(poi.options.route){
            var latLngPoints = [];
                                            
            for(var i = 0; i < poi.options.route.length; i++) {
                var location = poi.options.route[i].location;
                var latLng = new google.maps.LatLng(location.latitude, location.longitude);                                        
                
                var polylineMarker = new google.maps.Marker({
                    position: latLng,
                    icon: getMobilePOIImage(i, poi),                        
                    map: map
                });
                polylineMarker.options = {
                    id: poi.options.id,
                    name: poi.options.name,
                    iconName: poi.options.iconName,
                    number: i,
                    routeMarker: true,
                    type: poi.options.type,
                    to:poi.options.route[i].toTime,
                    from:poi.options.route[i].fromTime
                }
                polylineMarkers.push(polylineMarker);    
                addPolylineMarkerListener(polylineMarker);
                latLngPoints.push(latLng);                    
            }                                                                                        
                            
            var colors = ["#00C8A9"];
            
            for(var i = 0; i < latLngPoints.length - 1; i++){
                polylines[polylines.length] = new google.maps.Polyline({
                    path: [latLngPoints[i], latLngPoints[i+1]],
                    strokeColor: colors[i%colors.length],
                    strokeOpacity: 0.5,
                    strokeWeight: 4,
                    map: map
                });
            }                                                                
        }            
    };
    
    function addPolylineMarkerListener(polylineMarker){
        google.maps.event.addListener(polylineMarker,'click', function(event) {
            closeInfoWindow();                                                            
            fillInfoWindow(polylineMarker, event);                                            
        });
    };
     
    function getMobilePOIImage(i, poi) {    
        var total = poi.options.route.length;
        var mobileEndIcon = '${iconsPath}/' + poi.options.iconName + '-poi.png';
        var mobileBeginningIcon = '${iconsPath}/' + 'mobile-poi.png';
        var imgUrl = i == total-1 ? mobileEndIcon : mobileBeginningIcon;
        var size = i == total-1 ? 25 : 12;
        var anchorx = i == total-1 ? 0 : 7;
        var anchory = i == total-1 ? 25 : 7;
        
        var image = {
              url: imgUrl,
              size: new google.maps.Size(size,size),
              origin: new google.maps.Point(0, 0),
              anchor: new google.maps.Point(anchorx, anchory) ,
              scaledSize: new google.maps.Size(size, size)
        };
        
        return image;
    }
    
    function buildPopup(content, poi) {
        if(!infowindow){
            infowindow = new InfoBox(boxOptions);
        }

        infowindow.setContent(content);
        infowindow.open(map, poi);
    }
    
    function closePopup() {                
        infowindow.close(map, this);            
    }

    function fillInfoWindowPixelOffset(elementsCount, poi, boxOptions) {
        var numRows = parseInt((elementsCount / 2) + (elementsCount%2));
        var pixelOffset_x = (poi.multiCoordinates) ? -300 : -290;
        var pixelOffset_y = -290;
        
        if (numRows <= 1) {
            pixelOffset_y = defaultInfoboxPixelOffset_Y_A;
        } else if (numRows == 2) {
            pixelOffset_y = defaultInfoboxPixelOffset_Y_B;
        } else if (numRows >= 3) {
            pixelOffset_y = defaultInfoboxPixelOffset_Y_C;
        }
        
        if (poi.routeMarker) {
            var iconSize = poi.icon.size;
            if (iconSize.width === 12) {
                pixelOffset_x = pixelOffset_x - 15;
                pixelOffset_y = pixelOffset_y + iconSize.width;
            }
        }
        
        if (poi.multiCoordinates) {
            pixelOffset_y = pixelOffset_y + 25;
        }
        
        boxOptions.pixelOffset = new google.maps.Size(pixelOffset_x, pixelOffset_y);
    }
        
    
    function initClusterElements(){            
        // Can only be one listener registered and associated with the click event, therefore, before registering
        // a new listener, we must do a call to remove all previous listeners on the specified event.
        oms.clearListeners('click');
        
        oms.addListener('click', function(poi, event) {

            infowindowMustBeClosed = true;
            
            if (infowindow && isModalLayerVisible()) {
                updateModalLayer(poi.options.id);
            }
            
            closeInfoWindow();                            
            poiClicked = true;                
            fillInfoWindow(poi, event);
           });

        mc.repaint();
    };
    
    
    // Init smap_init function
    function smap_init(loadOnInit) {
    
        function initializeTypeAheadResults() {
            labels = [];
            result_map = {};
        };
    
        $(window).resize(function() {
            initializeMapControls();
        });
        initializeMapControls();
        
        var address = $('#address');
        var locate = $('#locate');
        
        address.tooltip({
            placement: 'bottom',
            title: emptyListMsg,
            trigger: 'manual'
        });
    
        initialize();
    
        locate.tooltip({
            placement: 'right',
            title: locateMeMsg,
            trigger: 'hover'
        });
    
        locate.click(function () {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(
                function (position) {
                    var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                    map.setZoom(defaultZoomLevel);
                    marker.setPosition(location);
                    map.setCenter(location);
                    updateMarkers(location);
                },
                function (error) {
                },
                {
                    timeout: 10000
                });
            }
        });
        
        address.typeahead({
            source: function (query, process) {
                initializeTypeAheadResults();
                function storeTypeAheadResults(results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        address.tooltip('hide');
                        $.each(results, function (index, item) {
                            result_map[item.formatted_address] = item;
                            labels.push(item.formatted_address);
                        });
                        return process(labels);
                    } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
                        address.tooltip('show');
                    }
                }
                geocoder.geocode({ 'address': query }, storeTypeAheadResults);
            },
            updater: function (item) {
                var location = new google.maps.LatLng(result_map[item].geometry.location.lat(), result_map[item].geometry.location.lng());
                marker.setPosition(location);
                map.setCenter(location);
                map.setZoom(defaultZoomLevel);
                updateMarkers(location);
            },
        });
    
        address.keypress(function (event) {
            switch (event.keyCode) {
                case 9: // tab
                case 13: // enter
                    event.preventDefault();
                    manualSearch();
                    break;
            }
        });
    
        $('#search').click(function () {
            manualSearch();
        });
        
        function updateMyPosition(result) {
            var location = new google.maps.LatLng(result.geometry.location.lat(), result.geometry.location.lng());
            map.setZoom(defaultSearchZoom);
            var radius = 50000 / Math.pow(2, (map.getZoom() - 10));            
            marker.setPosition(location);
            map.setCenter(location);
            getPlaces();
            address.val(result.formatted_address);
        };
    
        function manualSearch() {
            geocoder.geocode({
                'address': address.val()
            }, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    address.tooltip('hide');
                    if (results[0]) {
                        updateMyPosition(results[0]);
                    }
                }
                if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
                    address.tooltip('show');
                }
            });
        };        
        
                
        google.maps.event.addListener(map, 'zoom_changed', function () {            
            zoomChanged = true;
        });
    
        google.maps.event.addListener(map, 'idle', function () {
            infowindowMustBeClosed = false;
            if(!poiClicked){
                if(marker.getPosition() == undefined) {
                    updateMarkers(map.getCenter(),true);
                } else if (zoomChanged) {
                    updateMarkers(new google.maps.LatLng(marker.getPosition().lat(), marker.getPosition().lng()));
                }
            }
            zoomChanged = false;
            poiClicked = false;
        });
            
        if(loadOnInit) {
            updateMarkers(map.getCenter(), true);
        }
        
    };
    // End smap_init function
    

    /**
     * Function used by the component detail page to display it on map (public and admin page).
     * @param latitude: map center latitude
     * @param longitude: map center longitude
     * @param coordinates: component coordinates array where each element has the format latK lngK. 
     * Its length, and if it is closed, dictates how to display the component (polygon, polyline or marker) 
     * @param icon: icon to use when coordinates represents a POI
     */
    function initializeMap(mapOptions) {
        var map = $('#map_canvas');

        var options = {
            center : new google.maps.LatLng(mapOptions.latitude, mapOptions.longitude),
            zoom : defaultZoomLevel,
            mapTypeId : google.maps.MapTypeId.ROADMAP,
            mapTypeControl : true,
            panControl : false,
            mapTypeControlOptions : {
                style : google.maps.MapTypeControlStyle.DROPDOWN_MENU
            },
            navigationControl : true,
            scrollwheel : true,
            fullscreenControl : false,
            streetViewControl : true,
            styles: [{
                "featureType": "poi",
                "stylers": [{ "visibility": "simplified" }]
            }]
        };
    
        addGeometricElementToMap(map, mapOptions.latitude, mapOptions.longitude, mapOptions.coordinates, mapOptions.icon, options);
        
    };
    
    function addGeometricElementToMap(map, latitude, longitude, coordinates, icon, options){
        // If coordinates length equals to 1, it represents a POI
        // Otherwise it is a polyline or polygon 
        
        var mapOptions = {
            map : {    options : options }    
        };
        
        var polyOptions = {            
          strokeColor: "#0000FF",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: "#0000FF",
          fillOpacity: 0.35            
        };
        
        if(coordinates.length == 1){                    
            var poiImage = icon ? getPOIImage({'icon' : icon}) : getPOIImage();    
            var element = {
                latLng : [ latitude, longitude ],
                options : {    icon : poiImage }
            };
    
            $.extend( mapOptions, {    marker : element} );
            
        }else{                                      
            var elementPath = [];
            for (var i = 0; i < coordinates.length; i++) {
                var vertexCoord = coordinates[i].split(' ');                         
                elementPath.push(new google.maps.LatLng(vertexCoord[0], vertexCoord[1]));    
            }
            
            $.extend( polyOptions, {path: elementPath} );            
            var element = {options:polyOptions};            
            
            if(coordinates[0] == coordinates[coordinates.length-1]){
                $.extend( mapOptions, {    polygon : element} );                    
            }else{
                $.extend( mapOptions, {    polyline : element} );    
            }            
        }
        
        map.gmap3(mapOptions);
    }

    /**
     * Function used by the home page to initialize and display the initial map
     * @ selector: selector to retrieve via jQuery the map div
     */
    function initializeHomeMap(selector) {

        $('#bluescreen').hide();

        var visibilityOn = { "visibility" : "on"};
        var visibilityOff = {"visibility" : "off"};
        var bgColor = defaultBgHomeMapColor;
        var lightness = {"lightness" : 10};
        var saturation = {"saturation" : -49};

        $(selector).gmap3(
                {
                    map : {
                        options : {
                            center : defaultMapCenter,
                            zoom : defaultZoomLevel,
                            mapTypeId : google.maps.MapTypeId.ROADMAP,
                            mapTypeControl : false,
                            navigationControl : false,
                            scrollwheel : false,
                            fullscreenControl : false,
                            streetViewControl : false,
                            //Added to disable controls
                            zoomControl : false,
                            panControl : false,
                            //ends
                            styles : [ {
                                        "stylers" : [ visibilityOn, bgColor, saturation ]
                                    }, {
                                        "featureType" : "road.highway",
                                        "stylers" : [ bgColor, saturation, lightness ]
                                    }, {
                                        "featureType" : "road.arterial",
                                        "stylers" : [ bgColor, saturation, lightness, visibilityOn ]
                                    }, {
                                        "featureType" : "road.local",
                                        "stylers" : [ bgColor, saturation, lightness ]
                                    }, {
                                        "featureType" : "poi",
                                        "stylers" : [ visibilityOff ]
                                    }, {
                                        "elementType" : "labels",
                                        "stylers" : [ visibilityOff ]
                                    } ]
                        }
                    }
                });
    };

    /**
     * Function used by the component map page to initialize and display the map
     * @ selector: selector to retrieve via jQuery the component map div
     * @ center: initial center to display the map
     * @ zoom: initial zoom to display the map
     */
    function initializeComponentMap(mapProperties) {
         
         const mapCenter = (mapProperties.center?mapProperties.center:defaultMapCenter);
         const zoomLevel = (mapProperties.zoom?mapProperties.zoom:defaultZoomLevel);
         
         $(mapProperties.selector).gmap3({
            map : {
                options : {
                    center : mapCenter,
                    zoom : zoomLevel,
                    mapTypeId : google.maps.MapTypeId.STREET,
                    mapTypeControl : true,
                    navigationControl : false,
                    panControl : false,
                    scrollwheel : true,
                    fullscreenControl : false,
                    streetViewControl : true,
                    styles : [ {
                        "featureType" : "poi",
                        "stylers" : [ {    "visibility" : "simplified"} ]
                    }, {
                        "elementType" : "labels.icon",
                        "stylers" : [ {    "visibility" : "off"} ]
                    } ]
                }
            }
        });

        smap_init();
        showMapControls();
    };

    // **************************************************************
    // Input location map
    // **************************************************************

    function clearOverlay() {        
        if (mc) {
            mc.clearMarkers();
        }

        if(oms){
            oms.clearMarkers();            
        }
        
        
        for (var i = 0; i < polylineMarkers.length; i++) {
           polylineMarkers[i].setMap(null);
        }
        polylineMarkers = [];    
        
        for (var i = 0; i < polylines.length; i++) {
            polylines[i].setMap(null);        
            polylines[i].setPath(polylineMarkers);
        }
        
        polylines = [];
    }

    function updateSearchedPosition(location) {
        if (marker) {
            marker.setMap(null);
        }

        var markerOptions = {
            map : map,
            draggable : true,
            animation : google.maps.Animation.DROP,
        };

        marker = new google.maps.Marker({
            options : markerOptions,
        });

        google.maps.event.addListener(marker, 'dragend', function() {
            updateSearchedPosition(marker.getPosition());
            geocodeAddress(marker.getPosition());
        });
        
        var image = {
            url: '${imgSpot}',
            size: new google.maps.Size(22, 22),
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(0, 22)
        };

        marker.setIcon(image);

        map.setZoom(defaultSearchZoomLevel);        
        marker.setPosition(location);
        map.setCenter(location);

        $('#latitude').val(location.lat());
        $('#longitude').val(location.lng())

    };

    function initializeAddressTypeAhead(address) {

        map = $('#input_location_map_canvas').gmap3('get');

        function manualSearch() {
            if (address.val()) {
                geocoder.geocode({'address' : address.val() }, 
                  function delegate(results, status) {
                    if (status == google.maps.GeocoderStatus.OK && results[0]) {
                        var location = buildLatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
                        updateSearchedPosition(location);
                    }
                });
            }
        };
        

        function initializeTypeAheadResults() {
            labels = [];
            result_map = {};
        }

        if(!geocoder) {
            initializeGeoCoder();
        }

        address.typeahead({
            source : function(query, process) {
                initializeTypeAheadResults();
                function storeTypeAheadResults(results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        $.each(results, function(index, item) {
                            result_map[item.formatted_address] = item;
                            labels.push(item.formatted_address);
                        });
                        return process(labels);
                    }
                }
                geocoder.geocode({'address' : query}, storeTypeAheadResults);
            },
            updater : function(item) {
                var location = buildLatLng(result_map[item].geometry.location.lat(),    result_map[item].geometry.location.lng());
                map.setCenter(location);
                map.setZoom(defaultInputLocationZoomLevel);
                updateSearchedPosition(location);
                return item;
            },
        });

        address.keypress(function(event) {
            switch (event.keyCode) {
            case 9: // tab
            case 13: // enter
                event.preventDefault();
                manualSearch();
                break;
            }
        });
    }

    /**
     * Function used to initialize and show map on the component pages (public and admin).     
     */
    function initializeInputLocationMap() {

        $('#input_location_map_canvas').gmap3({
            map : {
                options : {
                    center : defaultMapCenter,
                    zoom : defaultInputLocationZoomLevel,
                    mapTypeId : google.maps.MapTypeId.STREET,
                    mapTypeControl : true,
                    navigationControl : false,
                    scrollwheel : true,
                    fullscreenControl : false,
                    streetViewControl : true
                }
            }
        });
        map = $('#input_location_map_canvas').gmap3('get');

        var locate = $('#locate');
        locate.tooltip({
            placement : 'right',
            title : locateMeMsg,
            trigger : 'hover'
        });

        locate.click(function() {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(
                        function(position) {
                            var location = buildLatLng(position.coords.latitude, position.coords.longitude);
                            geocodeAddress(location);
                            updateSearchedPosition(location);
                        }, function(error) {
                        }, {
                            timeout : 10000
                        });
            }
        });

        initializeAddressTypeAhead($('#locationaddress'));
    }
    
    //Funcions globals
    
    function getCenterCoordinates(){
        return [map.getCenter().lat(), map.getCenter().lng()];
    }
    
    function buildLatLng(latitude, longitude) {
        return new google.maps.LatLng(latitude, longitude);
    }

    function centerMap(center_location) {
        map.setCenter(center_location);
    }
    
    function isGeocodeSuccess(results, status) {
        return status == google.maps.GeocoderStatus.OK && results[0];
    }
    
    function formatGeocodeAddress(results, headerResume) {
        return results[0].formatted_address;
    }
    
    function buildGeocoder() {
        return new google.maps.Geocoder();
    }
    
    function getBoundsForSearchElements(){            
        // offsetx is the distance we want to expand the bounds on the x-axis, in pixels. 
        // offsety is the distance  we want to expand the bounds on the y-axis, in pixels.         
        var factor = getExtendFactor();
        var offsetx = factor * $(".map2").width();
        var offsety = factor * $(".map2").height();
        
        var scale = Math.pow(2, map.getZoom());
        var pixelOffset = new google.maps.Point((offsetx/scale) || 0,(offsety/scale) ||0);
        
        var projection = map.getProjection();
        var bounds = map.getBounds();
        var swPoint = bounds.getSouthWest();
        var nePoint = bounds.getNorthEast();
        
        var swPointPixels = projection.fromLatLngToPoint(swPoint);
        var nePointPixels = projection.fromLatLngToPoint(nePoint);
        
        var newSwPointPixels = new google.maps.Point(swPointPixels.x - pixelOffset.x, swPointPixels.y + pixelOffset.y);
        var newNePointPixels = new google.maps.Point(nePointPixels.x + pixelOffset.x, nePointPixels.y - pixelOffset.y);
        var newSwPoint = projection.fromPointToLatLng(newSwPointPixels);
        var newNePoint = projection.fromPointToLatLng(newNePointPixels);
        
        var newBounds = new google.maps.LatLngBounds(newSwPoint, newNePoint);        
        return newBounds.toUrlValue();
    }
    
    function addMarkerToMap(poi) {
        oms.addMarker(poi);
        mc.addMarker(poi);
    }
    
    function doAfterAddMarkersToMap(){
        initClusterElements();
    }
    
        
    // -->
</script>