I am looking to create a custom infoWindow in google maps and I believe creating an infoBox is a way to do this. However, I don't see any documentation or reference to infoBox on google map's documentation. Is this feature deprecated? Should I be using customized popup instead?
The InfoBox library was never part of the Google Maps Javascript API v3. It is a third party library and is still available on GitHub.
https://github.com/googlemaps/v3-utility-library/tree/master/archive/infobox
Note: it is also available in my GitHub account:
https://github.com/geocodezip/v3-utility-library/tree/master/archive/infobox
code snippet (basic example):
function initialize() {
var secheltLoc = new google.maps.LatLng(49.47216, -123.76307);
var myMapOptions = {
zoom: 15
,center: secheltLoc
,mapTypeId: google.maps.MapTypeId.ROADMAP
};
var theMap = new google.maps.Map(document.getElementById("map_canvas"), myMapOptions);
var marker = new google.maps.Marker({
map: theMap,
draggable: true,
position: new google.maps.LatLng(49.47216, -123.76307),
visible: true
});
var boxText = document.createElement("div");
boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
boxText.innerHTML = "City Hall, Sechelt<br>British Columbia<br>Canada";
var myOptions = {
content: boxText
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-140, 0)
,zIndex: null
,boxStyle: {
background: "url('tipbox.gif') no-repeat"
,opacity: 0.75
,width: "280px"
}
,closeBoxMargin: "10px 2px 2px 2px"
,closeBoxURL: "https://www.google.com/intl/en_us/mapfiles/close.gif"
,infoBoxClearance: new google.maps.Size(1, 1)
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
};
google.maps.event.addListener(marker, "click", function (e) {
ib.open(theMap, this);
});
var ib = new InfoBox(myOptions);
ib.open(theMap, marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#map_canvas {
width: 100%;
height: 100%;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src="https://cdn.jsdelivr.net/gh/googlemaps/v3-utility-library#master/archive/infobox/src/infobox.js"></script>
<div id="map_canvas"></div>
<p>
This example shows the "traditional" use of an InfoBox as a replacement for an InfoWindow.
Related
I have loaded geojson layer to google maps using the following code
map.data.loadGeoJson(
'http://localhost/pssp/assets/geojson/Empanel_Area_2019.geojson');
map.data.setStyle({
fillColor: 'red',
strokeColor: 'red',
strokeWeight: 1
});
)
When I try to add a marker on the data layer on the click event it will get added outside the data layer but not inside. how can I add a marker in side the polygons in the data layer.
I used the following code to add a marker on click event
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
}
Add a click listener to the DataLayer as well.
map.data.addListener('click', function(event) {
placeMarker(event.latLng);
});
proof of concept fiddle
code snippet:
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#info-box {
background-color: white;
border: 1px solid black;
bottom: 30px;
height: 20px;
padding: 10px;
position: absolute;
left: 30px;
}
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {
lat: -28,
lng: 137
}
});
// Load GeoJSON.
map.data.loadGeoJson('https://storage.googleapis.com/maps-devrel/google.json');
// Add some style.
map.data.setStyle(function(feature) {
return /** #type {google.maps.Data.StyleOptions} */ ({
fillColor: feature.getProperty('color'),
strokeWeight: 1
});
});
google.maps.event.addListener(map, 'click', function(event) {
console.log("on map:" + event.latLng.toUrlValue(6));
placeMarker(event.latLng);
});
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
}
// Set click event for each feature.
map.data.addListener('click', function(event) {
console.log("on polygon:" + event.latLng.toUrlValue(6));
placeMarker(event.latLng);
});
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>
I have a webpage that uses Google maps and the MarkerCluster API.
I need to be able to get all of the clusters on the map at a given zoom level. Take this code for example:
//Where the center of the screen will be
var center = new google.maps.LatLng(37.4419, -122.1419);
var options = {
'zoom': 13,
'center': center,
//Google map type
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
//Create the google map
var map = new google.maps.Map(document.getElementById("map"), options);
//Create the marker clusters, where markers is an array of lat and longs
var mc = new MarkerClusterer(map, markers);
//Print all of the clusters at zoom level 13
console.log(mc.getTotalClusters());
The problem is if there are 10 clusters at zoom level 13, but only 7 are inside of my screen's bounds, then the above code would only print out 7. I need a way to get access to all clusters, even if they're not on the screen.
Simple example of how the MarkerClusterer works:
https://googlemaps.github.io/js-marker-clusterer/examples/simple_example.html
Here are some references to the MarkerCluster API:
https://googlemaps.github.io/js-marker-clusterer/docs/reference.html
https://googlemaps.github.io/js-marker-clusterer/docs/examples.html
https://developers.google.com/maps/articles/toomanymarkers
Indeed, getTotalClusters function returns the number of clusters only for markers visible within a current viewport.
One option to get the total amount of clusters would be to disable the checking whether the marker is located within a current viewport by overriding the function that creates clusters:
MarkerClusterer.prototype.createClusters_ = function() {
if (!this.ready_) {
return;
}
for (var i = 0, marker; marker = this.markers_[i]; i++) {
//if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {
if (!marker.isAdded) {
this.addToClosestCluster_(marker);
}
}
};
Working example
MarkerClusterer.prototype.createClusters_ = function() {
if (!this.ready_) {
return;
}
for (var i = 0, marker; marker = this.markers_[i]; i++) {
//if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {
if (!marker.isAdded) {
this.addToClosestCluster_(marker);
}
}
};
function initMap(data) {
var center = new google.maps.LatLng(59.339025,18.065818);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0; i < data.photos.length; i++) {
var dataPhoto = data.photos[i];
var latLng = new google.maps.LatLng(dataPhoto.latitude,dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
markerCluster = new MarkerClusterer(map, markers, { imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m' });
google.maps.event.addListenerOnce(map, 'idle', function(){
console.log("Total number of clusters: " + markerCluster.getTotalClusters());
});
}
google.maps.event.addDomListener(window, 'load',
function(){
$.getJSON("https://gist.githubusercontent.com/vgrem/fb601469049c4be809ad4ea4bbcdc381/raw/data.json")
.success(function(data) {
initMap(data);
});
});
body {
margin: 0;
padding: 10px 20px 20px;
font-family: Arial;
font-size: 16px;
}
#map-container {
padding: 6px;
border-width: 1px;
border-style: solid;
border-color: #ccc #ccc #999 #ccc;
-webkit-box-shadow: rgba(64, 64, 64, 0.5) 0 2px 5px;
-moz-box-shadow: rgba(64, 64, 64, 0.5) 0 2px 5px;
box-shadow: rgba(64, 64, 64, 0.1) 0 2px 5px;
width: 600px;
}
#map {
width: 600px;
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://googlemaps.github.io/js-marker-clusterer/src/markerclusterer.js"></script>
<div id="map-container"><div id="map"></div></div>
Plunker
How do I re position the infowindow in a google map?
I would like the window to open under the marker with the little indent facing up towards to the marker.
Here is my code I thought the pixeloffset would be the option to change but not sure. When I adjust the y to 70 it shows up below the marker but how do I change the indent to flip around?
$infowindow = new google.maps.InfoWindow({
content: "Drag the map to re-center location",
pixelOffset: new google.maps.Size(0, 70), // want the window to open underneathe with the indent facing up
});
The behavior you are looking for is not (currently) supported by the native google.maps.InfoWindow. You can create a feature request in the issue tracker for the Google Maps JavaScript API v3.
For something that would work now, InfoBox might do what you are looking for, see the example in the documentation
code snippet:
function initialize() {
var secheltLoc = new google.maps.LatLng(49.47216, -123.76307);
var myMapOptions = {
zoom: 15,
center: secheltLoc,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var theMap = new google.maps.Map(document.getElementById("map_canvas"), myMapOptions);
var marker = new google.maps.Marker({
map: theMap,
draggable: true,
position: new google.maps.LatLng(49.47216, -123.76307),
visible: true
});
var boxText = document.createElement("div");
boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: white; padding: 5px; text-align: center;";
boxText.innerHTML = "Drag the map to re-center location";
var myOptions = {
content: boxText,
disableAutoPan: false,
maxWidth: 0,
pixelOffset: new google.maps.Size(-140, 0),
zIndex: null,
boxStyle: {
background: "url('http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/examples/tipbox.gif') no-repeat",
opacity: 0.75,
width: "280px"
},
closeBoxMargin: "10px 2px 2px 2px",
closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance: new google.maps.Size(1, 1),
isHidden: false,
pane: "floatPane",
enableEventPropagation: false
};
google.maps.event.addListener(marker, "click", function(e) {
ib.open(theMap, this);
});
var ib = new InfoBox(myOptions);
ib.open(theMap, marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
}
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<div id="map_canvas" style="width: 100%; height: 400px"></div>
<p>
This example shows the "traditional" use of an InfoBox as a replacement for an InfoWindow.
How can I customize the google maps api (v3 javascript) zoom buttons to my own image.
I am late at the party, but here is my two cents.
You have basically two options:
Option 1: You either create the controls using HTML/CSS yourself, which you can then place over the map to the correct position using position absolute or similar means. Even though this works in production, I don't like this, because your HTML/CSS for the element doesn't load at the same time than the map is displayed. Also you are separating your HTML/CSS code for the controls so it is harder to reuse the same map at different pages. e.g. "Did I forgot to add the controls?"
Option 2: You create a custom control which looks and feels the zoom controllers you like. Below is an code about this in practice.
In short, you need to first disable the normal UI controllers by calling:
var mapOptions = {
zoom: 12,
center: chicago,
/* Disabling default UI widgets */
disableDefaultUI: true // <-- see this line
}
And then you just create the controller and use it.
HTML:
...
<div id="map-canvas"></div>
...
CSS:
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px;
}
JavaScript:
var map;
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
/**
* The ZoomControl adds +/- button for the map
*
*/
function ZoomControl(controlDiv, map) {
// Creating divs & styles for custom zoom control
controlDiv.style.padding = '5px';
// Set CSS for the control wrapper
var controlWrapper = document.createElement('div');
controlWrapper.style.backgroundColor = 'white';
controlWrapper.style.borderStyle = 'solid';
controlWrapper.style.borderColor = 'gray';
controlWrapper.style.borderWidth = '1px';
controlWrapper.style.cursor = 'pointer';
controlWrapper.style.textAlign = 'center';
controlWrapper.style.width = '32px';
controlWrapper.style.height = '64px';
controlDiv.appendChild(controlWrapper);
// Set CSS for the zoomIn
var zoomInButton = document.createElement('div');
zoomInButton.style.width = '32px';
zoomInButton.style.height = '32px';
/* Change this to be the .png image you want to use */
zoomInButton.style.backgroundImage = 'url("http://placehold.it/32/00ff00")';
controlWrapper.appendChild(zoomInButton);
// Set CSS for the zoomOut
var zoomOutButton = document.createElement('div');
zoomOutButton.style.width = '32px';
zoomOutButton.style.height = '32px';
/* Change this to be the .png image you want to use */
zoomOutButton.style.backgroundImage = 'url("http://placehold.it/32/0000ff")';
controlWrapper.appendChild(zoomOutButton);
// Setup the click event listener - zoomIn
google.maps.event.addDomListener(zoomInButton, 'click', function() {
map.setZoom(map.getZoom() + 1);
});
// Setup the click event listener - zoomOut
google.maps.event.addDomListener(zoomOutButton, 'click', function() {
map.setZoom(map.getZoom() - 1);
});
}
function initialize() {
var mapDiv = document.getElementById('map-canvas');
var mapOptions = {
zoom: 12,
center: chicago,
/* Disabling default UI widgets */
disableDefaultUI: true
}
map = new google.maps.Map(mapDiv, mapOptions);
// Create the DIV to hold the control and call the ZoomControl() constructor
// passing in this DIV.
var zoomControlDiv = document.createElement('div');
var zoomControl = new ZoomControl(zoomControlDiv, map);
zoomControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_LEFT].push(zoomControlDiv);
}
initialize();
Note: This code doesn't contain any fancy icons and a like, just placeholders. Therefore, you might need to tune it to fit your needs. Moreover, remember to add HTML5 normal tags and script include for the google maps api v3 javascript. I added only <div id="map-canvas"></div> because a need for rest of the body is pretty obvious.
To see it live: Here is working jsfiddle example
Cheers.
After hours searching I found the solution
Just make sure you replace your API ID!
Enjoy!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 60%; width:60%; margin:20px auto; border:1px solid; padding-left:100px; }
</style>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=YOUR-MAP_API-ID&sensor=false®ion=AU">
</script>
<script type="text/javascript">
function HomeControl(controlDiv, map) {
google.maps.event.addDomListener(zoomout, 'click', function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 0){
map.setZoom(currentZoomLevel - 1);}
});
google.maps.event.addDomListener(zoomin, 'click', function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 21){
map.setZoom(currentZoomLevel + 1);}
});
}
var map;
var markersArray = [];
function initialize() {
var mapDiv = document.getElementById('map-canvas');
var myLatlng = new google.maps.LatLng(-33.90224, 151.20215);
var mapOptions = {
zoom: 15,
center: myLatlng,
Marker: true,
panControl: false,
zoomControl: false,
streetViewControl: false,
overviewMapControl: false,
mapTypeControl: false,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(mapDiv, mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Hello World!"
});
// Create the DIV to hold the control and
// call the HomeControl() constructor passing
// in this DIV.
var homeControlDiv = document.createElement('div');
var homeControl = new HomeControl(homeControlDiv, map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div id="zoomout" style="border:1px solid; width:150px; cursor:pointer; margin-bottom:20px;">ZOOM ME OUT</div>
<div id="zoomin" style="border:1px solid; width:150px; cursor:pointer; ">ZOOM ME IN</div>
</body>
</html>
I did it in the CSS way:
#map-container .gm-style > .gmnoprint > .gmnoprint { background: url(/images/map-zoom-controls.png) no-repeat center center !important; width: 42px !important; height: 68px !important; }
#map-container .gm-style > .gmnoprint > .gmnoprint > div > img { display: none !important; }
#map-container .gm-style > .gmnoprint > .gmnoprint div[title="Zoom in"] { top: 2px !important; left: 2px !important; width: 38px !important; height: 31px !important; }
#map-container .gm-style > .gmnoprint > .gmnoprint div[title="Zoom out"] { top: 35px !important; left: 2px !important; width: 38px !important; height: 30px !important; }
This is for a image that has:
width: 42px;
height: 68px;
Make your own adjustments.
ATTENTION
This applies only if you are using English version because of the title attributes.
This isn't possible. You can tweak their appearance a bit using a set of predefined option parameters or you can implement your custom map control that provides the same functionality as the zoom control.
For more information see this page.
UPDATED: Link fixed. Thanks for the feedback!
I have an infobox on a clickable polylines and polygons.
When I click any of them an invisible marker is created and the infoxbox pops up for it.
The problem is that when the infoxbox appears the map dissapears.
I don't get any javascript errors.
This is my code:
(I have commented out all infoxbox features apart of the content text)
google.maps.event.addListener(mapObject, 'click', function(event) {
var invisibleMarker = new google.maps.Marker({
position: new google.maps.LatLng(event.latLng),
map: map
});
var boxText = document.createElement("div");
boxText.style.cssText = "background: none; padding: 0;";
boxText.innerHTML = '<div style="margin: 0 0 20px 0;padding: 18px;background: white url(/media/images/map-marker-info-bg.gif) repeat-x top left;">' + content[0] + '</div>';
var myOptions = {
content: boxText
/*,latlng: event.latLng
,alignBottom: true
,pixelOffset: new google.maps.Size(-470, -20)
,boxStyle: {
background: "transparent url('/media/images/map-marker-info-arrow.png') no-repeat bottom right"
,opacity: 1
,width: "470px"
}
,closeBoxMargin: "18px 18px 2px 2px"
,closeBoxURL: "/media/images/map-marker-info-close.gif"
,infoBoxClearance: new google.maps.Size(5, 5)
,enableEventPropagation: false*/
};
var ib = new InfoBox(myOptions);
ib.open(map, invisibleMarker);
});
Can anybody help me resolve this issue?
Thank you
There are a couple of problems:
1) google.maps.event.addListener(mapObject, 'click', function(event)
You haven't provided your map creation code, but the variable mapObject should be a map object... That doesn't fit with any of your other references to the map object map.
2) new google.maps.LatLng(event.latLng)
You don't need to parse the event.LatLng value, it will already be a latitude/longitude value.
Here is a working example, with the corrections noted above. The InfoBox will output undefined because content[0] is undefined, but that can be any valid text you want.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body, #map_canvas {
margin: 0;
padding: 0;
height: 100%;
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<script type="text/javascript">
var map;
function test()
{
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
var invisibleMarker = new google.maps.Marker({
position: event.latLng,
map: map
});
var boxText = document.createElement("div");
boxText.style.cssText = "background: none; padding: 0;";
boxText.innerHTML = '<div style="margin: 0 0 20px 0;padding: 18px;background: white url(/media/images/map-marker-info-bg.gif) repeat-x top left;">' + content[0] + '</div>';
var myOptions = {
content: boxText
/*,latlng: event.latLng
,alignBottom: true
,pixelOffset: new google.maps.Size(-470, -20)
,boxStyle: {
background: "transparent url('/media/images/map-marker-info-arrow.png') no-repeat bottom right"
,opacity: 1
,width: "470px"
}
,closeBoxMargin: "18px 18px 2px 2px"
,closeBoxURL: "/media/images/map-marker-info-close.gif"
,infoBoxClearance: new google.maps.Size(5, 5)
,enableEventPropagation: false*/
};
var ib = new InfoBox(myOptions);
ib.open(map, invisibleMarker);
});
}
</script>
</head>
<body onload="test();">
<div id="map_canvas"></div>
</body>
</html>
I want to use similar styled InfoBox for my polylines but need to pass clicked position I think. In original simple code it was
infowindow.setContent(content[0]);
infowindow.position = event.latLng;
infowindow.open(map);
and it worked
I have no idea how to do it for InfoBox. I tried to use in InfoBox options:
latlng: event.latLng
and then:
var ib = new InfoBox(myOptions);
ib.setPosition(event.latLng);
ib.open(map, mapObject);
but I'm getting:
Error: anchor.getPosition is not a function
Source File: http://google-maps-utility-library-v3.googlecode.com/svn/tags/infobox/1.1.9/src/infobox.js