Huge Google Maps Controls (Possible Bug)

Huge Google Maps Controls (Possible Bug?)

Turns out this isn't a bug. See more here:

Aug 13, 2018 03:56PM Reported Issue Google Maps JavaScript API weekly
channel (3.34) will be using the larger control UI.

As we are seeing increases of touch operations on various devices, we
adjusted the control UI to fit for both finger touches and mouse
clicks.

It's possible to opt out of this by loading the API with v=quarterly,
v=3, v=3.33 or v=3.32. Note: requests to retired version will receive
the default channel, see 1.

If you have any requests or other issues concerning the new control UI
please let us know.

1 https://issuetracker.google.com/112519576

Use v=quarterly, v=3, v=3.33 or v=3.32 when loading the API to use smaller controls.

EDIT:

Refer to answer from @Jonny van Beek on how to scale Google map's controls to the size of your choosing.

Refer to answers from @garethdn and @Peter (below) to find out how to replace Google's large controls with your own custom controls.

Refer to @Dutchmanjonny's post (below) for latest and correct solution to this problem.

Google maps custom control always appears below the default controls

  • One idea/option (not optimal but does sort of what you want).
  1. Put the pan control in the TOP_LEFT controls position.
  2. Put the custom control at index -1 (before all the normal controls) in LEFT_TOP

from the documentation: Positioning Custom Controls:
...snip...

The API places controls at each position by the order of an index property; controls with a lower index are placed first. For example, two custom controls at position BOTTOM_RIGHT will be laid out according to this index order, with lower index values taking precedence. By default, all custom controls are placed after placing any API default controls. You can override this behavior by setting a control's index property to be a negative value. Custom controls cannot be placed to the left of the logo or to the right of the copyrights.

  var mapOptions = {
zoom: 12,
center: chicago,
disableDefaultUI: true,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.RIGHT_TOP
},
scaleControl: true,
panControl: true,
panControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
streetViewControl: true,
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
},
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
}
}

map = new google.maps.Map(mapDiv, mapOptions);
var homeControl = new HomeControl(homeControlDiv, map);

map.controls[google.maps.ControlPosition.LEFT_TOP].push(homeControlDiv);

example

  • A second option, would be to create a custom zoom control, then you can control the order (I couldn't figure out how to access the pre-defined Google Maps controls, only to put the custom control(s) before or after them).

example custom zoom/pan control from this question on SO

  var PanControl = new geocodezip.web.PanControl(map);
PanControl.index = -2;
var homeControl = new HomeControl(homeControlDiv, map);
homeControlDiv.index = -1;
map.controls[google.maps.ControlPosition.LEFT_TOP].push(PanControl);
map.controls[google.maps.ControlPosition.LEFT_TOP].push(homeControlDiv);

Example with a modified ZoomPanControl (just the pan control)

code snippet with code from above example:

var map = null;
var chicago = new google.maps.LatLng(41.850033, -87.6500523);

/**
* The HomeControl adds a control to the map that simply
* returns the user to Chicago. This constructor takes
* the control DIV as an argument.
* @constructor
*/
function HomeControl(controlDiv, map) {

// Set CSS styles for the DIV containing the control
// Setting padding to 5 px will offset the control
// from the edge of the map
controlDiv.style.padding = '5px';

// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to set the map to Home';
controlDiv.appendChild(controlUI);

// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Arial,sans-serif';
controlText.style.fontSize = '12px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.innerHTML = '<b>Home</b>';
controlUI.appendChild(controlText);

// Setup the click event listeners: simply set the map to
// Chicago
google.maps.event.addDomListener(controlUI, 'click', function() {
map.setCenter(chicago)
});

}

function initialize() {
// Create the DIV to hold the control and
// call the HomeControl() constructor passing
// in this DIV.
var homeControlDiv = document.createElement('div');


var mapDiv = document.getElementById('map-canvas');
var mapOptions = {
zoom: 12,
center: chicago,
disableDefaultUI: true,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.RIGHT_TOP
},
scaleControl: true,
panControl: false,
streetViewControl: true,
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
},
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_TOP
}
}

map = new google.maps.Map(mapDiv, mapOptions);
var PanControl = new geocodezip.web.PanControl(map);
PanControl.index = -2;
var homeControl = new HomeControl(homeControlDiv, map);
homeControlDiv.index = -1;
map.controls[google.maps.ControlPosition.LEFT_TOP].push(PanControl);
map.controls[google.maps.ControlPosition.LEFT_TOP].push(homeControlDiv);

}

google.maps.event.addDomListener(window, 'load', initialize);

/**
* @param {string} tagName
* @param {Object.<string, string>} properties
* @returns {Node}
*/
function CreateElement(tagName, properties) {
var elem = document.createElement(tagName);
for (var prop in properties) {
if (prop == "style")
elem.style.cssText = properties[prop];
else if (prop == "class")
elem.className = properties[prop];
else
elem.setAttribute(prop, properties[prop]);
}
return elem;
}

/**
* @constructor
* @param {google.maps.Map} map
*/
function PanControl(map) {
this.map = map;
this.originalCenter = map.getCenter();

var t = this;
var panContainer = CreateElement("div", {
'style': "position: relative; padding: 5px;"
});

//Pan Controls
var PanContainer = CreateElement("div", {
'style': "position: relative; left: 2px; top: 5px; width: 56px; height: 56px; padding: 5px; overflow: hidden;"
});
panContainer.appendChild(PanContainer);
var div = CreateElement("div", {
'style': "width: 56px; height: 56px; overflow: hidden;"
});
div.appendChild(CreateElement("img", {
'alt': ' ',
'src': 'http://maps.gstatic.com/intl/en_ALL/mapfiles/mapcontrols3d5.png',
'style': "position: absolute; left: 0px; top: -1px; -moz-user-select: none; border: 0px none; padding: 0px; margin: 0px; width: 59px; height: 492px;"
}));
PanContainer.appendChild(div);

div = CreateElement("div", {
'style': "position: absolute; left: 0px; top: 19px; width: 18.6667px; height: 18.6667px; cursor: pointer;",
'title': 'Pan left'
});
google.maps.event.addDomListener(div, "click", function() {
t.pan(PanDirection.LEFT);
});
PanContainer.appendChild(div);
div = CreateElement("div", {
'style': "position: absolute; left: 37px; top: 19px; width: 18.6667px; height: 18.6667px; cursor: pointer;",
'title': 'Pan right'
});
google.maps.event.addDomListener(div, "click", function() {
t.pan(PanDirection.RIGHT);
});
PanContainer.appendChild(div);
div = CreateElement("div", {
'style': "position: absolute; left: 19px; top: 0px; width: 18.6667px; height: 18.6667px; cursor: pointer;",
'title': 'Pan up'
});
google.maps.event.addDomListener(div, "click", function() {
t.pan(PanDirection.UP);
});
PanContainer.appendChild(div);
div = CreateElement("div", {
'style': "position: absolute; left: 19px; top: 37px; width: 18.6667px; height: 18.6667px; cursor: pointer;",
'title': 'Pan down'
});
google.maps.event.addDomListener(div, "click", function() {
t.pan(PanDirection.DOWN);
});
PanContainer.appendChild(div);
div = CreateElement("div", {
'style': "position: absolute; left: 19px; top: 19px; width: 18.6667px; height: 18.6667px; cursor: pointer;",
'title': 'Reset center'
});
google.maps.event.addDomListener(div, "click", function() {
t.map.setCenter(t.originalCenter);
});
PanContainer.appendChild(div);

return panContainer;
}

/** @param {PanDirection} direction */
PanControl.prototype.pan = function(direction) {
var panDistance = 50;
if (direction == PanDirection.UP || direction == PanDirection.DOWN) {
panDistance = Math.round(this.map.getDiv().offsetHeight / 2);
this.map.panBy(0, direction == PanDirection.DOWN ? panDistance : -1 * panDistance);
} else {
panDistance = Math.round(this.map.getDiv().offsetWidth / 2);
this.map.panBy(direction == PanDirection.RIGHT ? panDistance : -1 * panDistance, 0);
}
}

/** @enum */
var PanDirection = {
LEFT: 0,
RIGHT: 1,
UP: 3,
DOWN: 4
}

window["geocodezip"] = window["geocodezip"] || {};
window["geocodezip"]["web"] = window["geocodezip"]["web"] || {};
window["geocodezip"]["web"]["PanControl"] = PanControl;
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>

<div id="map-canvas"></div>

Google Maps API - Customising the Appearance of certain controls

It turns it was an issue with the latest 3.34 release of the Google Maps JavaScript API. I've managed to revert to the previous version for now, e.g. http://maps.google.com/maps/api/js?v=3.33&key=xxxxxxx

Google Maps v3 performance issues

The reason for that is that google maps api it's not the same javascript as google maps application is using.

If you take a look at the resulting map you can see that your map created with the api, is created by multiple divs, each div is one map tile image.
During zooming every single tile has to be re-rendered with a new image.
Also in the network tab you can see that you are downloading map tiles as images.

On the other hand, google maps application has one canvas element, and during zooming you are not downloading images but vector data (in some google format kind) and they are rendered into the canvas. Canvas object is natively supported and is less expensive than replacing images using DOM elements.



Related Topics



Leave a reply



Submit