How to set google map zoom to fit the screen & position infobox labels depending on the area of polygon

547 Views Asked by At

I am using google map's FusionTablesLayer and polygon to set layers of USA states. I am having problem in integrating following 2 things :

a) Set zoom property, so map will fit to the screen. I know map doesn't accept zoom value in decimal. Is there any other way to do this?

b) Positioning labels (i.e state name) depending on the area of state. For eg. California state label should be on the polygon whereas New Jersey state label should be below the polygon area.

Expected output :

enter image description here

Current State :

enter image description here

My code :

var map;
var clientId = '{CLIENT_ID}';
var apiKey = '{API_KEY}';
var scopes = 'https://www.googleapis.com/auth/fusiontables';
var zoom = 4;
var labels = [];
var USAStates = '';
var infobox = {};
jQuery.get( "http://recruiters.wpsitesbuilder.com/wp-json/myplugin/v1/firms_data", function( data ) {
    USAStates = jQuery.parseJSON(data);
}).done(function( data ) {
    function initMap() {
        var latlng = new google.maps.LatLng(37.09024, -95.712891);
        var myOptions = {
            zoom: zoom,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            disableDefaultUI: true,
            disableDoubleClickZoom: false,
            draggable: true,
            keyboardShortcuts: true,
            panControl:true,
            zoomControl:false,
            zoomControlOptions: {
                style: google.maps.ZoomControlStyle.SMALL
            },
            mapTypeControl:false,
            scaleControl:false,
            scrollwheel: false,
            streetViewControl:false,
            overviewMapControl:true,
            rotateControl:false,
            mapTypeControlOptions: {
                mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
            }
        };
        var styles=[{featureType:"administrative",elementType:"all",stylers:[{hue:"#000000"},{lightness:-100},{visibility:"off"}]},{featureType:"landscape",elementType:"all",stylers:[{color:"#2c8ecd"},{visibility:"on"}]},{featureType:"landscape",elementType:"geometry",stylers:[{saturation:-100},{lightness:-3},{visibility:"on"},{color:"#2c8ecd"}]},{featureType:"landscape",elementType:"labels",stylers:[{hue:"#000000"},{saturation:-100},{lightness:-100},{visibility:"off"}]},{featureType:"poi",elementType:"all",stylers:[{hue:"#ff0000"},{saturation:-100},{lightness:-100},{visibility:"off"}]},{featureType:"road",elementType:"all",stylers:[{visibility:"off"}]},{featureType:"road",elementType:"geometry",stylers:[{hue:"#ff0000"},{saturation:-100},{lightness:26},{visibility:"off"}]},{featureType:"road",elementType:"labels",stylers:[{hue:"#ffffff"},{saturation:-100},{lightness:100},{visibility:"off"}]},{featureType:"road.highway",elementType:"all",stylers:[{visibility:"off"}]},{featureType:"road.highway.controlled_access",elementType:"all",stylers:[{visibility:"off"}]},{featureType:"road.local",elementType:"all",stylers:[{hue:"#ffffff"},{saturation:-100},{lightness:100},{visibility:"on"}]},{featureType:"transit",elementType:"all",stylers:[{visibility:"off"}]},{featureType:"transit",elementType:"geometry",stylers:[{visibility:"off"}]},{featureType:"transit",elementType:"labels",stylers:[{hue:"#ff0000"},{lightness:-100},{visibility:"off"}]},{featureType:"water",elementType:"geometry",stylers:[{saturation:-100},{lightness:100},{visibility:"on"},{color:"#2c8ecd"}]},{featureType:"water",elementType:"labels",stylers:[{hue:"#000000"},{saturation:-100},{lightness:-100},{visibility:"off"}]}];
        var styledMap = new google.maps.StyledMapType(styles, {name: "Styled Map"});
        var styledMap = new google.maps.StyledMapType(styles, {name: "Styled Map"});
        var map = new google.maps.Map(document.getElementById("map"), myOptions);
        map.mapTypes.set('map_style', styledMap);
        map.setMapTypeId('map_style');
        var tableId = '17aT9Ud-YnGiXdXEJUyycH2ocUqreOeKGbzCkUw';
        var USAStateslayer = new google.maps.FusionTablesLayer({
            query: {
                select: 'geometry',
                from: tableId
            },
            options: {
                suppressInfoWindows: true
            },
            styles: [{
                polygonOptions: {
                    fillColor: '#ffffff',
                    fillOpacity: 1,
                    strokeColor: '#2c8ecd'
                }
            }],
            clickable: true
        });
        filterMap(USAStateslayer, tableId, map, USAStates);

        USAStateslayer.setMap(map);
        map.setCenter(latlng);

        jQuery.each(USAStates, function(key, value){
            var content = '<div class="infobox-content-container"><span class="state-name">'+value.state+'</span></div>';
            if(value.firms !== undefined) {
                content = '<div class="infobox-content-container"><span class="total-firms">'+value.firms+'</span><br /> Firms <br /> <span class="state-name">'+value.state+'</span></div>';
            }
            infobox = new InfoBox({
                content: content,
                boxStyle: {
                    border: "none",
                    textAlign: "center",
                    backgroundColor:"none",
                    fontSize: "8pt",
                    width: "50px",
                    color: '#000000',
                    'margin-top': "-25px"
                 },
                disableAutoPan: true,
                pane: "floatPane",
                pixelOffset: new google.maps.Size(-25, 0),
                position: new google.maps.LatLng(value.latitude,value.longitude),
                closeBoxURL: "",
                isHidden: false,
                enableEventPropagation: true
            });
            labels.push(infobox);
            labels[labels.length-1].open(map);
        });
    }

    // Filter the map based on checkbox selection.
      function filterMap(layer, tableId, map, USAStates) {

        layer.setOptions({styles:generateStyle(USAStates, map)});

      }

      // Generate a where clause from the checkboxes. If no boxes
      // are checked, return an empty string.
      function generateStyle(USAStates, map) {
        //default-style,gray
        var style=[{
           polygonOptions: {
                fillColor: '#ffffff',
                strokeWeight: 1,
                fillOpacity: 1,
                strokeColor: '#2c8ecd'
            }
        }];

       var styles={
         //open stores
         open:{polygonOptions: {
            fillColor: "#be2026"
          }},
        //closed stores
         closed:{polygonOptions: {
            fillColor: "#fff"
          }}
        };

        var selected={open:[],closed:[]};
        var stores = [];

        if(jQuery('#find-firms-container .selected-firms-list>span').length > 0) {
            jQuery('#find-firms-container .selected-firms-list>span').each(function(){
                var stateName = jQuery(this).text();
                stores.push(stateName);
            });
        }

        //populate the selected-object with the names of the stores
        jQuery.each(stores,function(i,o){
          var storeName = o.replace(/'/g, '\\\'');
            selected['open'].push(storeName);
        });
        //add a style for non-empty properties of the selected-object
        jQuery.each(selected,function(i,o){
           if(o.length){
             style.push(jQuery.extend(styles[i],{where:"'name' IN ('" + o.join("','") + "')"}));
           }
        });
        var i = 0;
        jQuery.each(USAStates, function(key, value){
            var color = '#000000';
            if(jQuery.inArray(value.state, selected.open) !== -1) {
               color = '#ffffff';
            }
            if(labels[i] !== undefined) {
                labels[i].boxStyle_.color= color;
                labels[i].open(map);
            }
            i++;
        });

        return style;
    }

    initMap();
});
1

There are 1 best solutions below

0
On

Not sure if this helps but in the documentation it states that you should should explicitly set the size of the element div for the #map styling.

meta name="viewport" content="initial-scale=1.0, user-scalable=no"

Also there is a meta tag for the viewport with a content that you can set the initial scale. Maybe playing with the initial scale will interact with zoom?

<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
  /* Always set the map height explicitly to define the size of the div
   * element that contains the map. */
  #map {
    height: 100%;
  }
  /* Optional: Makes the sample page fill the window. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>