I have a google map implementation in Ionic2. Map and geolocation works fine. The errors occured only after I tried to implement custom controls/button into the map. I followed this link:
https://developers.google.com/maps/documentation/javascript/examples/control-custom
This is my js code (Constructor):
constructor(navController, platform, app) {
this.navController = navController;
this.platform = platform;
this.app = app;
platform.ready().then(() => {
this.initializeMap();
});
}
Custom control:
CenterControl(controlDiv, map){
// Set CSS for the control border.
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '2px solid #fff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to recenter the map';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior.
var controlText = document.createElement('div');
controlText.style.color = 'rgb(25,25,25)';
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.lineHeight = '38px';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.innerHTML = 'Center Map';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map to Chicago.
controlUI.addEventListener('click', function() {
map.setCenter(chicago);
});
}
Map Initialization:
initializeMap() {
let locationOptions = {timeout: 10000, enableHighAccuracy: true};
navigator.geolocation.getCurrentPosition(
(position) => {
let options = {
// /new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(document.getElementById("map_canvas"), options);
var centerControlDiv = document.createElement('div');
var centerControl = new CenterControl(centerControlDiv, options);
centerControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
},
(error) => {
console.log(error);
}, locationOptions
);
}
My index.html:
<script src="http://maps.google.com/maps/api/js?key=<MY API KEY>"></script>
The error message given was this:
Where line 87 refers to:
var centerControl = new CenterControl(centerControlDiv, options);
I'm unable to set "CenterControl(){}" as "function CenterControl(){}" as I would encounter syntax error in that case.
I would define CenterControl like this:
export class CenterControl {
constructor(controlDiv, map){
(...)
}
}
instead of
CenterControl(controlDiv, map) {
(...)
}
and import then when you want to use it... Don't forget the export keyword.
Edit
If it's a method of your class, simply call it this way:
this.CenterControl(centerControlDiv, options);
centerControlDiv.index = 1;
this.map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I have created two CustomControls, however, the settings for the first are duplicated on the 2nd button. I'm sure this mistake is a novice one. Most of the examples I've been able to find show only one button or they are adding controls to markers. Any guidance would be much appreciated!
<html>
<head>
<title>Current Location</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
</head>
<body onload= "start()">
<script>
function CustomControl(controlDiv, map, deviceID) {
// Set CSS for the control border
var controlUI = document.createElement('div');
//controlUI.style.backgroundColor = '#f00c0c';
controlUI.style.backgroundColor = '#ffffff';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '1px';
controlUI.style.borderColor = '#ccc';
controlUI.style.borderRadius = "23px";
controlUI.style.height = '33px';
controlUI.style.marginTop = '5px';
controlUI.style.marginLeft = '-6px';
controlUI.style.paddingTop = '1px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to change settings';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'sans-serif';
controlText.style.fontSize = '10px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '8px';
controlText.style.marginTop = '10px';
controlText.innerHTML = 'Settings';
controlUI.appendChild(controlText);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI, 'click', function () {
url = "http://excite.bounceme.net/profile.html;
window.location = url;
});
}
function CustomControl1(controlDiv, map, deviceID) {
// Set CSS for the control border
var controlUI1 = document.createElement('empty');
//controlUI1.style.backgroundColor = '#f00c0c';
controlUI1.style.backgroundColor = '#ffffff';
controlUI1.style.borderStyle = 'solid';
controlUI1.style.borderWidth = '1px';
controlUI1.style.borderColor = '#ccc';
controlUI1.style.borderRadius = "23px";
controlUI1.style.height = '33px';
controlUI1.style.marginTop = '5px';
controlUI1.style.marginLeft = '-6px';
controlUI1.style.paddingTop = '1px';
controlUI1.style.cursor = 'pointer';
controlUI1.style.textAlign = 'center';
controlUI1.title = 'Click to plot course';
controlDiv.appendChild(controlUI1);
// Set CSS for the control interior
var controlText1 = document.createElement('empty');
controlText1.style.fontFamily = 'sans-serif';
controlText1.style.fontSize = '10px';
controlText1.style.paddingLeft = '4px';
controlText1.style.paddingRight = '8px';
controlText1.style.marginTop = '10px';
controlText1.innerHTML = 'Plot Route';
controlUI.appendChild(controlText1);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI1, 'click', function () {
url = "http://excite.bounceme.net/settings.html";
window.location = url;
});
}
function start(){
var map;
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 39.833, lng: -98.585},
zoom: 12
});
var customControlDiv = document.createElement('div');
var customControl = new CustomControl(customControlDiv, map,deviceID);
customControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(customControlDiv);
var customControlDiv1 = document.createElement('empty');
var customControl1 = new CustomControl(customControlDiv1, map,deviceID);
customControlDiv1.index = 2;
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(customControlDiv1);
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"> </script>
<script src="https://maps.googleapis.com/maps/api/js?key=yourkeygoeshere4&callback=initMap"
async defer></script>
</body>
</html>
You have a typo in your code. You are creating two copies of the class CustomControl, you never create the CustomControl1 class.
working code snippet (you had one other syntax error):
function CustomControl(controlDiv, map, deviceID) {
// Set CSS for the control border
var controlUI = document.createElement('div');
//controlUI.style.backgroundColor = '#f00c0c';
controlUI.style.backgroundColor = '#ffffff';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '1px';
controlUI.style.borderColor = '#ccc';
controlUI.style.borderRadius = "23px";
controlUI.style.height = '33px';
controlUI.style.marginTop = '5px';
controlUI.style.marginLeft = '-6px';
controlUI.style.paddingTop = '1px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to change settings';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'sans-serif';
controlText.style.fontSize = '10px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '8px';
controlText.style.marginTop = '10px';
controlText.innerHTML = 'Settings';
controlUI.appendChild(controlText);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI, 'click', function() {
url = "http://excite.bounceme.net/profile.html";
window.location = url;
});
}
function CustomControl1(controlDiv, map, deviceID) {
// Set CSS for the control border
var controlUI1 = document.createElement('empty');
//controlUI1.style.backgroundColor = '#f00c0c';
controlUI1.style.backgroundColor = '#ffffff';
controlUI1.style.borderStyle = 'solid';
controlUI1.style.borderWidth = '1px';
controlUI1.style.borderColor = '#ccc';
controlUI1.style.borderRadius = "23px";
controlUI1.style.height = '33px';
controlUI1.style.marginTop = '5px';
controlUI1.style.marginLeft = '-6px';
controlUI1.style.paddingTop = '1px';
controlUI1.style.cursor = 'pointer';
controlUI1.style.textAlign = 'center';
controlUI1.title = 'Click to plot course';
controlDiv.appendChild(controlUI1);
// Set CSS for the control interior
var controlText1 = document.createElement('empty');
controlText1.style.fontFamily = 'sans-serif';
controlText1.style.fontSize = '10px';
controlText1.style.paddingLeft = '4px';
controlText1.style.paddingRight = '8px';
controlText1.style.marginTop = '10px';
controlText1.innerHTML = 'Plot Route';
controlUI1.appendChild(controlText1);
// Setup the click event listeners
google.maps.event.addDomListener(controlUI1, 'click', function() {
url = "http://excite.bounceme.net/settings.html";
window.location = url;
});
}
function start() {
var map;
var deviceID = "A";
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 39.833,
lng: -98.585
},
zoom: 12
});
var customControlDiv = document.createElement('div');
var customControl = new CustomControl(customControlDiv, map, deviceID);
customControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(customControlDiv);
var customControlDiv1 = document.createElement('div');
var customControl1 = new CustomControl1(customControlDiv1, map, deviceID);
customControlDiv1.index = 2;
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(customControlDiv1);
}
google.maps.event.addDomListener(window, "load", start);
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>
I try to position the Google Maps searchbox variable. A list shows all markers and under those markers there should be the searchbox. As the list grows the searchbox moves down. I use this library: Angular Google Maps
There is a directive called <ui-gmap-search-box>. But it must be inside <div id="map_canvas"> </div> and the list is outside of that div.
I think you should use the custom control functions provided by the Google Maps API.
You can position your controls on the top left corner of your maps, and create click event listeners for your control and do your work from there.
Refer to the documentation for more information on Custom Controls.
Also, I made some quick changes to this sample, and made this example here. Hope it helps.
var map;
//var chicago = new google.maps.LatLng(41.85, -87.65);
/**
* The CenterControl adds a control to the map that recenters the map on Chicago.
* This constructor takes the control DIV as an argument.
* #constructor
*/
controlUIs = [];
function CenterControl(controlDiv, map) {
locations = [new google.maps.LatLng(37.7833, -122.4167),
new google.maps.LatLng(37.3382, -121.8863),
new google.maps.LatLng(37.4223662, -122.0839445),
new google.maps.LatLng(37.8694772, -122.2577238),
new google.maps.LatLng(37.7919615, -122.2287941),
new google.maps.LatLng(37.6256441, -122.0413544)
];
for (var i = 0; i < locations.length; i++) {
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '2px solid #fff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to recenter the map';
controlUIs[i] = controlUI;
controlDiv.appendChild(controlUIs[i]);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.color = 'rgb(25,25,25)';
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.lineHeight = '38px';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.innerHTML = 'Location ' + i;
controlText.location = locations[i];
controlUIs[i].appendChild(controlText);
// Setup the click event listeners: simply set the map to
// Chicago
google.maps.event.addDomListener(controlUIs[i], 'click', function(click) {
map.setCenter(click.target.location)
});
}
}
function initialize() {
var mapDiv = document.getElementById('map-canvas');
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(37.6326196, -122.1568744)
}
map = new google.maps.Map(mapDiv, mapOptions);
// Create the DIV to hold the control and
// call the CenterControl() constructor passing
// in this DIV.
var centerControlDiv = document.createElement('div');
var centerControl = new CenterControl(centerControlDiv, map);
centerControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_LEFT].push(centerControlDiv);
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<div id="map-canvas"></div>
I used the Google Maps API Search box instead of the library's search box.
main.js:
var searchBox = function() {
var input = document.getElementById('autocomplete');
var searchBox = new google.maps.places.SearchBox(input);
google.maps.event.addListener(searchBox, 'places_changed', function() {
});
}; // end searchBox
The function searchBox() is executed in $scope.init().
index.html:
<input id="autocomplete" ng-model="newPlace" type="text">
I have the below code in openlayers
<script defer="defer" type="text/javascript">
var map = new OpenLayers.Map('map');
var wms = new OpenLayers.Layer.WMS("OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0", { layers: 'basic' });
var dm_wms = new OpenLayers.Layer.WMS(
"Canadian Data",
"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap",
{
layers: "bathymetry,land_fn,park,drain_fn,drainage," +
"prov_bound,fedlimit,rail,road,popplace",
transparent: "true",
format: "image/png"
}, { isBaseLayer: true }
);
var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
map.setBaseLayer(vectorLayer);
OpenLayers.Geometry.Point(77.391026, 28.535516), { some: 'data' }, { externalGraphic: 'Image/map-icons/Banquet_and_Marriage_halls.png', graphicHeight: 21, graphicWidth: 21 });
var center = new OpenLayers.Geometry.Point(77.391026, 28.535516);
center.transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
map.setCenter(new OpenLayers.LonLat(77, 28), 4);
var markers = new OpenLayers.Layer.Markers("Markers");
var ll = new OpenLayers.LonLat(77.391026, 28.535516);
var popupClass = OpenLayers.Popup.Anchored;
var popupContentHTML = '<div style="height:40px;">Hello Noida</div>';
addMarker(ll, popupClass, popupContentHTML, true);
ll = new OpenLayers.LonLat(74.613647, 30.914007);
popupClass = OpenLayers.Popup.Anchored;
popupContentHTML = '<div style="height:40px;">Hello Punjab</div>';
addMarker(ll, popupClass, popupContentHTML, true);
map.addLayers([wms, dm_wms, markers]);
var feature;
var popup = null;
function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow) {
feature = new OpenLayers.Feature(markers, ll);
feature.closeBox = closeBox;
feature.popupClass = popupClass;
feature.data.popupContentHTML = popupContentHTML;
feature.data.overflow = (overflow) ? "auto" : "hidden";
var marker = feature.createMarker();
var markerClick = function (evt) {
//alert(popup);
if (popup != null)
popup.hide();
popup = this.createPopup(this.closeBox);
popup.contentSize = new OpenLayers.Size(10, 20);
map.addPopup(popup);
popup.show();
};
marker.events.register("mousedown", feature, markerClick);
markers.addMarker(marker);
}
</script>
And every thing works fine if I remove the map.setCenter(). BUt when I try to use it in my code, my map sudddenly disappears.
I also get the follwoing error in my console window:
Cannot call method 'containsLonLat' of null
I've tried every possible method on this website, but did not reach any where.. What can be the problem?
I think you put an extra Bracket in you code, try map.setCenter(new OpenLayers.LonLat(77, 28), 4); to see if it works or not.
Use leaflet https://leafletjs.com/
var map = L.map('mapid').setView([77.391026, 28.535516], 16);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attributionControl: true
}).addTo(map);
reference: https://leafletjs.com/examples/quick-start/
I have 2 Google maps on the same page and I am looking to add the same button to a map that already has one.
This button is to close the overlay that Google maps launches in, basically an exit button.
The Button works fine on the first map but I cant get the second one to work D:!
I know I have to change the variables because that's what I had to do to get 2 maps on one page. Also if someone else is good in Google Maps API v3 can you tell me why I need the "map" variable in the function HomeControl(controlDiv, map) { line?
Here is my code:
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 = '<strong>Home</strong>';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map to Chicago.
google.maps.event.addDomListener(controlUI, 'click', function() {
document.getElementById('light').style.display='none';
document.getElementById('fade').style.display='none';
});
}
function detectBrowser() {
var useragent = navigator.userAgent;
var mapdivMap = document.getElementById("light");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdivMap.style.width = '100%';
mapdivMap.style.height = '100%';
initialize();
} else {
mapdivMap.style.width = '600px';
mapdivMap.style.height = '100%';
initialize();
}
};
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(43.464258,-80.52041),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('light'),
mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title: 'Waterloo'
});
// 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);
homeControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);
}
//*******************************************************
//************ Conestoga Map Page JavaScript ************
//*******************************************************
function Map2(Map2Div, map2) {
// Set CSS styles for the DIV containing the control
// Setting padding to 5 px will offset the control
// from the edge of the map.
Map2Div.style.padding = '5px';
// Set CSS for the control border.
var Map2UI = document.createElement('div');
Map2UI.style.backgroundColor = 'white';
Map2UI.style.borderStyle = 'solid';
Map2UI.style.borderWidth = '2px';
Map2lUI.style.cursor = 'pointer';
Map2UI.style.textAlign = 'center';
Map2UI.title = 'Click to set the map to Home';
Map2Div.appendChild(Map2UI);
// Set CSS for the control interior.
var Map2Text = document.createElement('div');
Map2Text.style.fontFamily = 'Arial,sans-serif';
Map2Text.style.fontSize = '12px';
Map2Text.style.paddingLeft = '4px';
Map2Text.style.paddingRight = '4px';
Map2Text.innerHTML = '<strong>Home</strong>';
Map2UI.appendChild(Map2Text);
// Setup the click event listeners: simply set the map to Chicago.
google.maps.event.addDomListener(MapUI2, 'click', function() {
document.getElementById('light').style.display='none';
document.getElementById('fade').style.display='none';
});
}
function detectBrowser2() {
var useragent2 = navigator.userAgent;
var mapdivMap2 = document.getElementById("light");
if (useragent2.indexOf('iPhone') != -1 || useragent2.indexOf('Android') != -1 ) {
mapdivMap2.style.width = '100%';
mapdivMap2.style.height = '100%';
initialize2();
} else {
mapdivMap2.style.width = '600px';
mapdivMap2.style.height = '100%';
initialize2();
}
};
function initialize2() {
var mapOptions2 = {
zoom: 8,
center: new google.maps.LatLng(43.464258,-80.52041),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map2 = new google.maps.Map(document.getElementById('light'),
mapOptions2);
var marker2 = new google.maps.Marker({
position: map.getCenter(),
map: map2,
title: 'Waterloo'
});
// Create the DIV to hold the control and call the HomeControl() constructor
// passing in this DIV.
var Map2Div = document.createElement('div');
var Map2 = new Map2(Map2Div, map2);
Map2Div.index = 1;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(Map2Div);
}
I'm trying to use MarkerClusterer to clusterize the markers on my map.
The problem is that I'm not using default markers (google.maps.Marker), but instead a custom class which hinerits from google.maps.OverlayView.
Unfortunately it seems that the library has been developed assuming the use of basic markers, in fact I get errors because my class does not implement methods defined in google.maps.Marker.
Is it possible to use the MarkerClusterer by keeping my custom markers?
EDIT: it was a lot easier than I expected, I solved by implementing 2 methods in my custom class:
setVisible() and getPosition()
in order to help others the following is my complete interface (without full implementation):
BFPushpin = function(config)
{
this.setMap(config.map);
this.set("position", config.position);
// other settings...
};
// my class extends google.maps.OverlayView
BFPushpin.prototype = new google.maps.OverlayView();
BFPushpin.prototype.getBounds = function()
{
return new google.maps.LatLngBounds(this.position, this.position);
};
BFPushpin.prototype.getPoint = function()
{
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
BFPushpin.prototype.getSuperContainer = function()
{
var panes = this.getPanes();
return jQuery(panes ? panes.overlayImage : "");
};
BFPushpin.prototype.getContainer = function()
{
// return inner container
};
BFPushpin.prototype._generatePopupContent = function()
{
// return markup for the popupwindow
};
BFPushpin.prototype._addListeners = function()
{
// add handlers for the pushpin
};
BFPushpin.prototype.onAdd = function()
{
// customize content here
};
BFPushpin.prototype.onRemove = function()
{
// remove pin container here
};
BFPushpin.prototype.draw = function()
{
// set display style here
};
BFPushpin.prototype.setVisible = function(visible)
{
// set display block or hidden
};
BFPushpin.prototype.getPosition = function()
{
return this.position;
};
Or just define the functions that the MarkerClusterer expects on the marker. setMap and getPosition() and some other ones.
You should probably define your new marker class in such a way that it also inherits from google.maps.Marker (i.e. that it implements its interface). It is logical that MarkerClusterer uses this interface - it has to suppose the markers are markers in order to work with them :-)
Hopefully this will also help people trying to get this solution to work. Thanks #daveoncode for the example. I was able to modify it to get it working for me:
renderMap() {
const mapProperties = {
center: new google.maps.LatLng(34.0234, -84.6155),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.mapElement.nativeElement, mapProperties);
let markers = [];
for (let i=0; i<this._sitesList.length; i++) {
let bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon)
);
let position = new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon);
let html = this.makeHtmlForSitePanel(i, this._sitesList[i]); // I have a function to return html for my OverlayView panels here.
markers.push( this.generateSitePanel(bounds, html, this.map, position) );
}
var markerCluster = new MarkerClusterer(this.map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
generateSitePanel(bounds, html, map, position) {
SitePanel.prototype = new google.maps.OverlayView();
function SitePanel (bounds, html, map, position) {
this.bounds_ = bounds;
this.set('position', position);
this.html_ = html;
this.map_ = map;
this.div_ = null;
this.setMap(map);
}
SitePanel.prototype.getBounds = function() {
return new google.maps.LatLngBounds(this.position, this.position);
};
SitePanel.prototype.getPoint = function() {
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
SitePanel.prototype.getSuperContainer = function(){
var panes = this.getPanes();
return $(panes ? panes.overlayImage : '');
};
SitePanel.prototype.getContainer = function()
{
// return inner container
// I don't have anything for this one
};
SitePanel.prototype.getPosition = function() {
return this.position;
};
SitePanel.prototype.onAdd = function() {
var div = document.createElement('div');
div.className = 'tooltip-container-';
div.innerHTML = this.html_;
div.style.position = 'absolute';
this.div_ = div;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
};
SitePanel.prototype.draw = function() {
var overlayProjection = this.getProjection();
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 20 + 'px';
};
SitePanel.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
return new SitePanel(bounds, html, map, position);
}