I'm utilizing Google's Fusion Tables API in order to display outlines of counties on a map, and then fit it to any viewport. fitBounds() has worked so far for previous maps, but when I add in the Fusion Tables Layer, everything begins to get odd. The following code ends up zooming the map out to view all of North America despite the latitude range being around -87 to -89, and the longitude range being about 42 to 43:
function initMap() {
const API_KEY = <my api key>;
const MAP_KEY = <my map key>;
const map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(42.9065288383437, -88.35016674999997)
});
const style = [
{
featureType: 'all',
elementType: 'all',
stylers: [
{ saturation: 44 }
]
}
];
const styledMapType = new google.maps.StyledMapType(style, {
map: map,
name: 'Styled Map'
});
map.mapTypes.set('map-style', styledMapType);
map.setMapTypeId('map-style');
const layer = new google.maps.FusionTablesLayer({
query: {
select: "col4",
from: MAP_KEY
},
map: map,
styleId: 8,
templateId: 2
});
getTableCoordinates(
MAP_KEY,
API_KEY,
function (rows) {
if (rows.length !== 0) {
const bounds = new google.maps.LatLngBounds(null);
/*
Real examples of pair:
[ -87.8199, 42.621 ],
[ -87.4934, 42.123 ],
[ -87.815094, 42.558089 ],
etc.
There's about ~1000 of these, all extremely close in lat and lng.
*/
rows.forEach(function (pair) {
const boundary = new google.maps.LatLng(pair[0], pair[1]);
bounds.extend(boundary);
});
setMapBounds(map, bounds, map.getCenter());
google.maps.event.addDomListener(window, "resize", function() {
google.maps.event.trigger(map, "resize");
setMapBounds(map, bounds, map.getCenter());
});
}
}
)
}
function getTableCoordinates(mapKey, apiKey, callback) {
const apiLink = "https://www.googleapis.com/fusiontables/v2/query?";
const query = [
"SELECT",
"col4",
"FROM",
mapKey
]
.join("+");
$.ajax({
url: apiLink + "sql=" + query + "&key=" + apiKey,
dataType: "json"
})
.done(function (response) {
callback(
response
.rows
.map(function(row) {
return row[0].geometry.coordinates[0];
})
.reduce(function(a, b) {
return a.concat(b);
})
);
})
.fail(function () {
callback([]);
});
}
function setMapBounds(map, bounds, center) {
map.fitBounds(bounds);
if (center) {
google.maps.event.addListenerOnce(map, "bounds_changed",
(function (event) {
// Reset center since fitBounds can change it
map.setCenter(center);
})
);
}
}
I know that map() call looks funky, but it's returning all the valid coordinates I need. The data is fine, I've looked at the corner of the bounds, yet it still zooms it out so far.
A couple of issues:
Looks like pair[0], pair[1]
should be pair[1], pair[0]
(like your coordinates are longitude, latitude where the google.maps.LatLng
expects latitude, longitude).
Latitude of -87 is below the available tiles near the south pole. If I flip them I get locations near Milwaukee. (compare to your map center center: new google.maps.LatLng(42.9065288383437, -88.35016674999997))
this map.setCenter(center);
is causing weirdness in the setMapBounds
method if the center
is not the center of the bounds.
code snippet:
function initMap() {
const map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(42.9065288383437, -88.35016674999997)
});
const bounds = new google.maps.LatLngBounds(null);
// sample data
var rows = [
[-87.8199, 42.621],
[-87.4934, 42.123],
[-87.815094, 42.558089],
]
// note that .forEach is asynchronous
//rows.forEach(function(pair) {
for (var i = 0; i < rows.length; i++) {
var pair = rows[i];
const boundary = new google.maps.LatLng(pair[1], pair[0]);
var marker = new google.maps.Marker({
position: boundary,
map: map
})
bounds.extend(boundary);
} //);
var rect1 = new google.maps.Rectangle({
bounds: bounds,
fillOpacity: 0.5,
fillColor: "blue",
map: map
})
setMapBounds(map, bounds, /* map.getCenter() */ );
google.maps.event.addDomListener(window, "resize", function() {
google.maps.event.trigger(map, "resize");
setMapBounds(map, bounds, map.getCenter());
});
const style = [{
featureType: 'all',
elementType: 'all',
stylers: [{
saturation: 44
}]
}];
const styledMapType = new google.maps.StyledMapType(style, {
map: map,
name: 'Styled Map'
});
map.mapTypes.set('map-style', styledMapType);
map.setMapTypeId('map-style');
}
function setMapBounds(map, bounds, center) {
console.log("bounds=" + bounds.toUrlValue(6));
map.fitBounds(bounds);
if (center) {
google.maps.event.addListenerOnce(map, "bounds_changed",
(function(event) {
// Reset center since fitBounds can change it
map.setCenter(center);
})
);
}
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>