在带有旋转的angularjs谷歌地图中显示100多个标记
我一直在使用ngMap和我的angularjs代码来显示标记。然而,对于100多个标记,我注意到性能有相当大的下降,主要与ng重复和双向绑定有关。我想添加带有自定义HTML元素的标记,类似于CustomMarker,但使用普通标记,并在需要时从controller进行修改 面临的挑战:在带有旋转的angularjs谷歌地图中显示100多个标记,angularjs,google-maps,ng-map,Angularjs,Google Maps,Ng Map,我一直在使用ngMap和我的angularjs代码来显示标记。然而,对于100多个标记,我注意到性能有相当大的下降,主要与ng重复和双向绑定有关。我想添加带有自定义HTML元素的标记,类似于CustomMarker,但使用普通标记,并在需要时从controller进行修改 面临的挑战: 我有SVG图像,需要根据条件动态着色(这些SVG不是单路径图像,因此当我将其与Symbol一起使用时,似乎无法正常工作) 这些是车辆标记,因此应支持旋转 我通过创建带有覆盖的CustomMarker解决了这个问题
我通过创建带有覆盖的CustomMarker解决了这个问题,然后将仅存在于当前地图边界中的标记添加到地图中,这样地图就不会滞后 下面是我实现它的代码片段
createCustomMarkerComponent();
/**
* options : [Object] : options to be passed on
* - position : [Object] : Google maps latLng object
* - map : [Object] : Google maps instance
* - markerId : [String] : Marker id
* - innerHTML : [String] : innerHTML string for the marker
**/
function CustomMarker(options) {
var self = this;
self.options = options || {};
self.el = document.createElement('div');
self.el.style.display = 'block';
self.el.style.visibility = 'hidden';
self.visible = true;
self.display = false;
for (var key in options) {
self[key] = options[key];
}
self.setContent();
google.maps.event.addListener(self.options.map, "idle", function (event) {
//This is the current user-viewable region of the map
var bounds = self.options.map.getBounds();
checkElementVisibility(self, bounds);
});
if (this.options.onClick) {
google.maps.event.addDomListener(this.el, "click", this.options.onClick);
}
}
function checkElementVisibility(item, bounds) {
//checks if marker is within viewport and displays the marker accordingly - triggered by google.maps.event "idle" on the map Object
if (bounds.contains(item.position)) {
//If the item isn't already being displayed
if (item.display != true) {
item.display = true;
item.setMap(item.options.map);
}
} else {
item.display = false;
item.setMap(null);
}
}
var supportedTransform = (function getSupportedTransform() {
var prefixes = 'transform WebkitTransform MozTransform OTransform msTransform'.split(' ');
var div = document.createElement('div');
for (var i = 0; i < prefixes.length; i++) {
if (div && div.style[prefixes[i]] !== undefined) {
return prefixes[i];
}
}
return false;
})();
function createCustomMarkerComponent() {
if (window.google) {
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.setContent = function () {
this.el.innerHTML = this.innerHTML;
this.el.style.position = 'absolute';
this.el.style.cursor = 'pointer';
this.el.style.top = 0;
this.el.style.left = 0;
};
CustomMarker.prototype.getPosition = function () {
return this.position;
};
CustomMarker.prototype.getDraggable = function () {
return this.draggable;
};
CustomMarker.prototype.setDraggable = function (draggable) {
this.draggable = draggable;
};
CustomMarker.prototype.setPosition = function (position) {
var self = this;
return new Promise(function () {
position && (self.position = position); /* jshint ignore:line */
if (self.getProjection() && typeof self.position.lng == 'function') {
var setPosition = function () {
if (!self.getProjection()) {
return;
}
var posPixel = self.getProjection().fromLatLngToDivPixel(self.position);
var x = Math.round(posPixel.x - (self.el.offsetWidth / 2));
var y = Math.round(posPixel.y - self.el.offsetHeight + 10); // 10px for anchor; 18px for label if not position-absolute
if (supportedTransform) {
self.el.style[supportedTransform] = "translate(" + x + "px, " + y + "px)";
} else {
self.el.style.left = x + "px";
self.el.style.top = y + "px";
}
self.el.style.visibility = "visible";
};
if (self.el.offsetWidth && self.el.offsetHeight) {
setPosition();
} else {
//delayed left/top calculation when width/height are not set instantly
setTimeout(setPosition, 300);
}
}
});
};
CustomMarker.prototype.setZIndex = function (zIndex) {
if (zIndex === undefined) return;
(this.zIndex !== zIndex) && (this.zIndex = zIndex); /* jshint ignore:line */
(this.el.style.zIndex !== this.zIndex) && (this.el.style.zIndex = this.zIndex);
};
CustomMarker.prototype.getVisible = function () {
return this.visible;
};
CustomMarker.prototype.setVisible = function (visible) {
if (this.el.style.display === 'none' && visible) {
this.el.style.display = 'block';
} else if (this.el.style.display !== 'none' && !visible) {
this.el.style.display = 'none';
}
this.visible = visible;
};
CustomMarker.prototype.addClass = function (className) {
var classNames = this.el.className.trim().split(' ');
(classNames.indexOf(className) == -1) && classNames.push(className); /* jshint ignore:line */
this.el.className = classNames.join(' ');
};
CustomMarker.prototype.removeClass = function (className) {
var classNames = this.el.className.split(' ');
var index = classNames.indexOf(className);
(index > -1) && classNames.splice(index, 1); /* jshint ignore:line */
this.el.className = classNames.join(' ');
};
CustomMarker.prototype.onAdd = function () {
this.getPanes().overlayMouseTarget.appendChild(this.el);
// this.getPanes().markerLayer.appendChild(label-div); // ??
};
CustomMarker.prototype.draw = function () {
this.setPosition();
this.setZIndex(this.zIndex);
this.setVisible(this.visible);
};
CustomMarker.prototype.onRemove = function () {
this.el.parentNode.removeChild(this.el);
// this.el = null;
};
} else {
setTimeout(createCustomMarkerComponent, 200);
}
}
createCustomMarkerComponent();
/**
*选项:[对象]:要传递的选项
*-位置:[对象]:谷歌地图定位对象
*-map:[对象]:谷歌地图实例
*-markerId:[字符串]:标记id
*-innerHTML:[字符串]:标记的innerHTML字符串
**/
功能自定义标记(选项){
var self=这个;
self.options=options |{};
self.el=document.createElement('div');
self.el.style.display='block';
self.el.style.visibility='hidden';
self.visible=true;
self.display=false;
for(变量输入选项){
自[键]=选项[键];
}
self.setContent();
google.maps.event.addListener(self.options.map,“idle”,函数(事件){
//这是地图的当前用户可查看区域
var bounds=self.options.map.getBounds();
checkElementVisibility(自、边界);
});
if(this.options.onClick){
google.maps.event.addDomListener(this.el,“click”,this.options.onClick);
}
}
函数checkElementVisibility(项、边界){
//检查标记是否在视口中,并相应地显示标记-由地图对象上的google.maps.event“idle”触发
if(边界包含(项目位置)){
//如果项目尚未显示
如果(item.display!=true){
item.display=true;
setMap(item.options.map);
}
}否则{
item.display=false;
item.setMap(空);
}
}
var supportedTransform=(函数getSupportedTransform(){
var前缀='transform webkitttransform mozortransform msTransform'.split('');
var div=document.createElement('div');
for(var i=0;i