Changing inclusion of country/state labels at different zoom levels? - google-maps

In Google Maps static API (and the other APIs as far as I can tell), at zoom level 7 the country label for USA disappears and at zoom level 8 the labels for individual states disappear.
I am interested in generating maps at zoom level 8 but retaining the country and state labels. I realise the labels are not entirely appropriate to this zoom level but I would like them to be visible if you happened to view the map at the appropriate location.
Is there any way of acheiving this with the Google Maps API?
I have tried
style=feature:administrative.country|element:labels|visibility:on&stylefeature:administrative.province|element:labels|visibility:on
but this doesn't add the labels I want at zoom level 8. My suspicion is that this simply can't be done, but maybe someone knows a workaround.

You can't use styled maps to change that. But you can add them yourself to the map at the higher zoom levels.
proof of concept fiddle
proof of concept with all 50 states, but probably need to tweak some of the locations
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(35.9, -97.092877),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
document.getElementById('zoom').innerHTML = "zoom="+map.getZoom();
google.maps.event.addListener(map, 'click', function(e) {
console.log(e.latLng.toUrlValue(6));
});
// 35.930648,-97.166119
var myOptions = {
content: "OKLAHOMA",
boxStyle: {
border: "none",
textAlign: "center",
fontSize: "14pt",
width: "50px",
color: "grey"
},
disableAutoPan: true,
pixelOffset: new google.maps.Size(-25, 0),
position: new google.maps.LatLng(36.05, -97.4),
closeBoxURL: "",
isHidden: false,
pane: "mapPane",
enableEventPropagation: true
};
var ibLabel = new InfoBox(myOptions);
google.maps.event.addListener(map, 'zoom_changed', function() {
console.log("zoom=" + map.getZoom());
document.getElementById('zoom').innerHTML = "zoom=" + map.getZoom();
if (map.getZoom() == 8) {
ibLabel.open(map);
} else {
ibLabel.close();
}
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 98%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/infobox/src/infobox.js"></script>
<div id="zoom"></div>
<div id="map_canvas"></div>

Related

Make a map element blank, disappear (Google Maps JavaScript API, v3)

There are many calls for help with the maps API where a blank white div is undesirable. In my case it's desirable.
I know how to make a map appear.
map.setCenter(new google.maps.LatLng(latitude, longitude));
I know how to make directions appear.
directionsService.route(request, function(result, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
Occasionally I just want the map element to "go white." Later I want to put a map or directions back in there.
I've tried this:
$('#map').empty();
It works, but after that I can never make a map appear again. What's the correct way?
I suppose I could make and delete map instances but this bug report says each destroyed map instance leaks 2MB memory, and Google officially discourages the practice (here and here). I'd really rather not overlay a white rectangle, or make the map display:none. Is there no better way?
(My application is a map next to an address entry form. When sufficient detail has been entered, a map automatically appears. If the field contents are deleted, the map goes blank again.)
I would just set the map div's innerHTML to "".
document.getElementById('map_canvas').innerHTML = "";
(but $("#map_canvas").empty(); works as well)
Once you do that you need to recreate and reinitialize the map object.
map = new google.maps.Map(document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
proof of concept fiddle
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var displayMap = true;
google.maps.event.addDomListener(document.getElementById('btn'), 'click', function() {
if (displayMap) {
document.getElementById('map_canvas').innerHTML = "";
} else {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
displayMap = !displayMap;
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input type="button" id="btn" value="toggle map" />
<div id="map_canvas"></div>
Set the map visibility to hidden.
Better yet, use a class.
CSS:
.map-hide {
visibility: hidden;
}
jQuery:
$('#map').addClass('map-hide');
$('#map').removeClass('map-hide');
JavaScript (IE10+):
document.getElementById("map").classList.add('map-hide');
document.getElementById("map").classList.remove('map-hide');
Add the class to blank the map. Remove it when rendering the map.
Adding and removing a class is better in case multiple parts of the code turn visibility on or off for different reasons.
Setting a map's visibility to hidden is better than setting its display to none, which can permanently ruin map rendering. I saw one clue to this in the docs about Map.fitBounds() breaking.

Google Maps V3: turning landmark infowindows off

How can I remove the info-windows but keep the actual landmark visible? I just don't want the actual info-window to appear when the landmark is clicked because I have markers around landmarks and sometimes the landmarks are accidentally clicked instead.
Those are called clickableIcons.
To turn off the InfoWindows, set the MapOption clickableIcons: false.
From the documentation
:
clickableIcons | Type: boolean
When false, map icons are not clickable. A map icon represents a point of interest, also known as a POI. By default map icons are clickable.
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
clickableIcons: false
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>

multiple rectangles in Google Maps from SQL database

I am trying to create multiple rectangles with info windows on a Google Map. I have followed the pattern used for multiple markers found at Generating Google Maps markers From Database
I first used that example and used one of the lat and one of long to display icons on the map. That worked. Then I change the code to rectangles and added bounds. But no rectangles appear on the map. I tried to hard code one of the rectangles on the map and one rectangle appeared.
I also made sure that the description to be used in the infowindow did not have any links in. I found that to be a problem if I was passing a link in the data variable. But I could get the link to work if I add the variable with a link at the point of the creation of the infowindow content.
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var markers = [
<asp:Repeater ID="rptMarkers" runat="server">
<ItemTemplate>
{
"title": '<%# Eval("Quad_Name") %>',
"north": '<%# Eval("poly_north") %>',
"east": '<%# Eval("poly_east") %>',
"south": '<%# Eval("poly_south") %>',
"west": '<%# Eval("poly_west") %>',
"description": '<%# Eval("smqcomment") %>'
}
</ItemTemplate>
<SeparatorTemplate>
,
</SeparatorTemplate>
</asp:Repeater>
];
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(41.78768535298007, -99.96481875),
zoom: 7,
mapTypeId: google.maps.MapTypeId.HYBRID
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
map: map,
bounds: {
north: data.north,
south: data.south,
east: data.east,
west: data.west
}
});
(function (rectangle,data) {
google.maps.event.addListener(rectangle, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map,rectangle);
});
})(rectangle,data);
}
}
</script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<div id="dvMap" style="width: 960px; height: 532px"></div>
Any help would be great thanks.
I get a javasript error on your live page: js:31 InvalidValueError: setBounds: not a LatLngBounds or LatLngBoundsLiteral: in property south: not a number. You need to translate the strings in your JSON into numbers before using them to construct google.maps.Rectangle objects.
To open an infowindow on a rectangle, you need to set the position of the infowindow. The syntax infoWindow.open(map, rectangle) doesn't apply to rectangles, that only applies to markers (at least for API objects), see the documentation for more information.
position contains the LatLng at which this info window is anchored. Note: An InfoWindow may be attached either to a Marker object (in which case its position is based on the marker's location) or on the map itself at a specified LatLng. Opening an info window on a marker will automatically update the position.
(function(rectangle, data) {
google.maps.event.addListener(rectangle, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.setPosition(rectangle.getBounds().getCenter());
infoWindow.open(map);
});
})(rectangle, data);
code snippet:
window.onload = function() {
var mapOptions = {
center: new google.maps.LatLng(41.492537, -99.901813),
zoom: 6,
mapTypeId: google.maps.MapTypeId.HYBRID
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
map: map,
bounds: {
north: parseFloat(data.north),
south: parseFloat(data.south),
east: parseFloat(data.east),
west: parseFloat(data.west)
}
});
(function(rectangle, data) {
google.maps.event.addListener(rectangle, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.setPosition(rectangle.getBounds().getCenter());
infoWindow.open(map);
});
})(rectangle, data);
}
}
var markers = [
{
"title": 'Andrews',
"north": '42.75001',
"east": '-103.625',
"south": '42.62501',
"west": '-103.75',
"description": 'Andrews description',
}
,
{
"title": 'Arlington',
"north": '41.50001',
"east": '-96.25001',
"south": '41.37501',
"west": '-96.37501',
"description": '<img src="http://snr.unl.edu/csd-esic/download/geologysoils/digitalgeologicmapscleaned/Arlington/Arlington_Quad.jpg" height="400">',
}
,
{
"title": 'Ashland East',
"north": '41.12501',
"east": '-96.25001',
"south": '41.00001',
"west": '-96.37501',
"description": '<img src="http://snr.unl.edu/csd-esic/download/geologysoils/digitalgeologicmapscleaned/Ashland_East/Ashland_East_Quad.jpg" height="400"">',
}
,
{
"title": 'Beaver Wall',
"north": '43.00001',
"east": '-102.625',
"south": '42.87501',
"west": '-102.75',
"description": 'Beaver Wall description',
}
];
html,
body,
#dvMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="dvMap"></div>
I see that geocodezip updated the code in their original answer to the question. Two things are new
First the defining of the bounds applied the function of parseFloat() to each of the coordinates. I am not sure that was necessary since I have been able to get icons or polygons to draw with the coordinates without this function.
I think what really solved the problem was adding the line of code
var bounds = new google.maps.LatLngBounds();
I am not actually sure what this is doing beside defining the variable "bounds" but it seems to have solved my problem.
Thanks geocodezip!

Google Maps API V3 (JS): Multiple directions on one map

I know this question has been answered before, but unfortunately, all links to demos/explanation pages are dead at the moment.
I would like to use the Google Maps API V3 to plot two directions (one for driving and one for walking) on the same map. If possible, I would like to use Google's default 'directions' lines, since these look nicer than the polylines.
Does anybody know how to do this? Any help is greatly appreciated!
Here is an example that I have made in the past for this. The trick is multiple DirectionsRenderer instances.
var MAP,
DIRECTIONSRENDERER1,
DIRECTIONSRENDERER2,
USER,
PLACE1,
PLACE2;
function displayDirections1(result, status) {
DIRECTIONSRENDERER1.setDirections(result)
}
function displayDirections2(result, status) {
DIRECTIONSRENDERER2.setDirections(result)
}
function getDirections(location, displayCallback) {
//https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsRequest
var request = {
travelMode: google.maps.TravelMode.DRIVING,
origin: USER,
destination: location
};
//https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsService
var service = new google.maps.DirectionsService();
service.route(request, displayCallback);
}
//Set up the map
function initialize() {
var mapOptions = {
zoom: 6,
//I used the center of the USA
center: new google.maps.LatLng(38.8282, -98.5795)
};
//Make the map
MAP = new google.maps.Map(document.getElementById('map'), mapOptions);
DIRECTIONSRENDERER1 = new google.maps.DirectionsRenderer({
map: MAP
})
DIRECTIONSRENDERER2 = new google.maps.DirectionsRenderer({
map: MAP
})
//Make marker for User location
//NOTE: for testing, the user position is fixed
USER = new google.maps.LatLng(38.8282, -98.5795);
new google.maps.Marker({
label: 'U',
cursor: "User Location",
position: USER,
map: MAP
});
//used for this demo
document.getElementById("latitude").textContent = USER.lat();
document.getElementById("longitude").textContent = USER.lng();
//Make marker for Place1 (location is arbitrary)
PLACE1 = new google.maps.LatLng(37, -97);
new google.maps.Marker({
label: '1',
cursor: "Place 1",
position: PLACE1,
map: MAP
});
//Make marker for Place2 (location is arbitrary)
PLACE2 = new google.maps.LatLng(39, -102);
new google.maps.Marker({
label: '2',
cursor: "Place 2",
position: PLACE2,
map: MAP
});
document.getElementById("p1button").addEventListener("click", function(e) {
getDirections(PLACE1, displayDirections1);
});
document.getElementById("p2button").addEventListener("click", function(e) {
getDirections(PLACE2, displayDirections2);
});
//Trigger map redraw when dom element is resized
google.maps.event.addDomListener(window, 'resize', function() {
google.maps.event.trigger(MAP, 'resize');
});
//Preserve map perspective when after resize
google.maps.event.addListener(MAP, 'resize', function() {
var center = MAP.getCenter();
google.maps.event.addListenerOnce(MAP, 'center_changed', function() {
MAP.setCenter(center);
});
});
}
//runs the code to set up demo
initialize();
html,
body,
#map {
height: 100%;
width: 100%;
border-width: 0;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<b>Your location:</b>
<br/>
<span>Latitude: </span><span id="latitude"></span>
<br/>
<span>Longitude: </span><span id="longitude"></span>
<br/>
<br/>
<button id="p1button">Directions to Place1</button>
<button id="p2button">Directions to Place2</button>
<div id="map"></div>

Disable indoor view of buildings in Google Maps Street View

I'm working on a project which displays a bunch of markers on Google Maps and allows the user to search and get relevant information about the locations. I haven't disabled Street View, as I'd like to give the user the possibility to see the building from the outside.
For certain locations, however, when going into Street View mode, Google Maps immediately shows the indoor of an adjacent business. What I'd like to have is the ability to completely disable indoor view on my application.
Is anyone aware of a certain setting in the Google Maps API that would do that or perhaps a clever hack to solve the issue? I haven't honestly found anything.
In the experimental version (currently v=3.21) there is now a StreetViewSource that can be provided in a StreetViewLocationRequest
StreetViewSource class
google.maps.StreetViewSource class
Identifiers to limit Street View searches to selected sources.
Constant
DEFAULT Uses the default sources of Street View, searches will not be limited to specific sources.
OUTDOOR Limits Street View searches to outdoor collections only.
example of request without source: google.maps.StreetViewSource.OUTDOOR (fiddle)
example of request with source: google.maps.StreetViewSource.OUTDOOR (fiddle)
code snippet (with source: OUTDOOR):
/*
* Click the map to set a new location for the Street View camera.
*/
var map;
var panorama;
function initMap() {
var myLatlng = new google.maps.LatLng(51.343364, 12.378962999999999);
var sv = new google.maps.StreetViewService();
panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'));
// Set up the map.
map = new google.maps.Map(document.getElementById('map'), {
center: myLatlng,
zoom: 16,
streetViewControl: false
});
// Set the initial Street View camera to the center of the map
sv.getPanorama({
location: myLatlng,
radius: 50,
source: google.maps.StreetViewSource.OUTDOOR
}, processSVData);
// Look for a nearby Street View panorama when the map is clicked.
// getPanoramaByLocation will return the nearest pano when the
// given radius is 50 meters or less.
map.addListener('click', function(event) {
sv.getPanorama({
location: event.latLng,
radius: 50
}, processSVData);
});
}
function processSVData(data, status) {
if (status === google.maps.StreetViewStatus.OK) {
var marker = new google.maps.Marker({
position: data.location.latLng,
map: map,
title: data.location.description
});
panorama.setPano(data.location.pano);
panorama.setPov({
heading: 270,
pitch: 0
});
panorama.setVisible(true);
marker.addListener('click', function() {
var markerPanoID = data.location.pano;
// Set the Pano to use the passed panoID.
panorama.setPano(markerPanoID);
panorama.setPov({
heading: 270,
pitch: 0
});
panorama.setVisible(true);
});
} else {
console.error('Street View data not found for this location.');
}
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map" style="width: 45%; height: 100%;float:left"></div>
<div id="pano" style="width: 45%; height: 100%;float:left"></div>