Javascript GoogleMapsV3:使用自定义标记进行聚类
我想用它把地图上的标记组合起来。 问题是我没有使用默认标记(google.maps.Marker),而是使用了一个自定义类,它从google.maps.overlyview中删除。 不幸的是,这个库似乎是在假设使用基本标记的情况下开发的,事实上,我会出错,因为我的类没有实现在google.maps.Marker中定义的方法。 是否可以通过保留我的自定义标记来使用标记聚类器 编辑:这比我预期的要简单得多,我通过在自定义类中实现两个方法解决了这个问题: setVisible()和getPosition() 为了帮助他人,以下是我的完整界面(未完全实现):Javascript GoogleMapsV3:使用自定义标记进行聚类,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,我想用它把地图上的标记组合起来。 问题是我没有使用默认标记(google.maps.Marker),而是使用了一个自定义类,它从google.maps.overlyview中删除。 不幸的是,这个库似乎是在假设使用基本标记的情况下开发的,事实上,我会出错,因为我的类没有实现在google.maps.Marker中定义的方法。 是否可以通过保留我的自定义标记来使用标记聚类器 编辑:这比我预期的要简单得多,我通过在自定义类中实现两个方法解决了这个问题: setVisible()和getPositio
您可能应该以这样一种方式定义新的marker类:它也继承自
google.maps.marker
(即,它实现其接口)。MarkerClusterer使用此接口是合乎逻辑的-必须假设标记是标记才能使用它们:-)或者只定义MarkerClusterer在标记上期望的功能。setMap和getPosition()以及其他一些解决方案。希望这也能帮助尝试使用此解决方案的人。感谢@daveoncode提供的示例。我能够对其进行修改,使其为我工作:
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);
}
renderMap(){
常量映射属性={
中心:新google.maps.LatLng(34.0234,-84.6155),
缩放:10,
mapTypeId:google.maps.mapTypeId.ROADMAP
};
this.map=new google.maps.map(this.mapeElement.nativeElement,mapProperties);
让标记=[];
对于(设i=0;这很危险,因为你永远不知道未来版本/其他库和方法等可以使用哪些方法。不知道,因为你只是在实现API中非常可用的标记接口,你不应该有问题。MarkerClusterer只关心获取项的位置并能够设置它的可见性/映射。我对你的解决方案有点困惑。我正在尝试做类似的事情,我有一个自定义覆盖,它“继承”自OverlayView,我通过在draw函数中枚举我自己制作的对象列表,将标记作为标记绘制在上面。那么你如何协调“标记”的使用在这里,集群功能正常?是否为每个标记呈现一个完整的覆盖?
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);
}