javascript - Google map 将信息框标记在完全相同的位置

标签 javascript google-maps

我不是程序员或开发人员。我面临一个问题,即谷歌地图信息框在完全相同的位置时不显示,(geocodezip)有一个非常好的解决方案,但我不知道如何修改我的代码。

这是我的代码

(function ($) {
var settings;
var element;
var map;
var markers = new Array();
var markerCluster;
var clustersOnMap = new Array();
var clusterListener;

var methods = {
    init: function (options) {
        element = $(this);

        var defaults = $.extend({
            enableGeolocation: false,
            pixelOffsetX     : -145,
            pixelOffsetY     : -200
        });

        settings = $.extend({}, defaults, options);

        google.maps.Map.prototype.setCenterWithOffset = function (latlng, offsetX, offsetY) {
            var map = this;
            var ov = new google.maps.OverlayView();

            ov.onAdd = function () {
                var proj = this.getProjection();
                var aPoint = proj.fromLatLngToContainerPixel(latlng);
                aPoint.x = aPoint.x + offsetX;
                aPoint.y = aPoint.y + offsetY;
                map.setCenter(proj.fromContainerPixelToLatLng(aPoint));
            }

            ov.draw = function () {
            };
            ov.setMap(this);
        };

        google.maps.visualRefresh = true;

        google.maps.event.addDomListener(window, 'load', loadMap);

        if (settings.filterForm && $(settings.filterForm).length !== 0) {
            $(settings.filterForm).submit(function (e) {
                var form = $(this);
                var action = $(this).attr('action');

                $.ajax({
                    type   : 'GET',
                    url    : action,
                    data   : form.serialize(),
                    success: function (data) {
                        element.aviators_map('removeMarkers');
                        element.aviators_map('addMarkers', {
                            locations: eval(data.locations),
                            types    : eval(data.types),
                            contents : eval(data.contents)
                        });
                    }
                });

                e.preventDefault();
            });
        }


        if (options.callback) {
            options.callback();
        }
        return $(this);
    },

    removeMarkers: function () {
        for (i = 0; i < markers.length; i++) {
            markers[i].infobox.close();
            markers[i].marker.close();
            markers[i].setMap(null);
        }

        markerCluster.clearMarkers();

        $.each(clustersOnMap, function (index, cluster) {
            cluster.cluster.close();
        });

        clusterListener.remove();
    },

    addMarkers: function (options) {
        markers = new Array();
        settings.locations = options.locations;
        settings.contents = options.contents;
        settings.types = options.types;

        renderElements();
    }
}

$.fn.aviators_map = function (method) {
    // Method calling logic
    if (methods[method]) {
        return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
    } else {
        $.error('Method ' + method + ' does not exist on Aviators Map');
    }
};

function loadMap() {
    var mapOptions = {
        zoom              : settings.zoom,
        mapTypeId         : google.maps.MapTypeId.ROADMAP,
        scrollwheel       : false,
        draggable         : true,
        mapTypeControl    : false,
        panControl        : false,
        zoomControl       : true,
        zoomControlOptions: {
            style   : google.maps.ZoomControlStyle.SMALL,
            position: google.maps.ControlPosition.LEFT_BOTTOM
        }
    };

    if (settings.enableGeolocation) {
        if (navigator.geolocation) {
            browserSupportFlag = true;
            navigator.geolocation.getCurrentPosition(function (position) {
                initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                map.setCenter(initialLocation);
            }, function () {
                mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
            });
        } else {
            browserSupportFlag = false;
            mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
        }
    } else {
        mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
    }

    map = new google.maps.Map($(element)[0], mapOptions);

    var dragFlag = false;
    var start = 0, end = 0;

    function thisTouchStart(e) {
        dragFlag = true;
        start = e.touches[0].pageY;
    }

    function thisTouchEnd() {
        dragFlag = false;
    }

    function thisTouchMove(e) {
        if (!dragFlag) {
            return
        }

        end = e.touches[0].pageY;
        window.scrollBy(0, ( start - end ));
    }

    var el = $('#map')[0];

    if (el.addEventListener) {
        el.addEventListener('touchstart', thisTouchStart, true);
        el.addEventListener('touchend', thisTouchEnd, true);
        el.addEventListener('touchmove', thisTouchMove, true);
    } else if (el.attachEvent){
        el.attachEvent('touchstart', thisTouchStart);
        el.attachEvent('touchend', thisTouchEnd);
        el.attachEvent('touchmove', thisTouchMove);
    }

    google.maps.event.addListener(map, 'zoom_changed', function () {
        $.each(markers, function (index, marker) {
            marker.infobox.close();
            marker.infobox.isOpen = false;
        });
    });

    renderElements();

    $('.infobox .close').live('click', function () {
        $.each(markers, function (index, marker) {
            marker.infobox.close();
            marker.infobox.isOpen = false;
        });
    });
}

function isClusterOnMap(clustersOnMap, cluster) {
    if (cluster === undefined) {
        return false;
    }

    if (clustersOnMap.length == 0) {
        return false;
    }

    var val = false;

    $.each(clustersOnMap, function (index, cluster_on_map) {
        if (cluster_on_map.getCenter() == cluster.getCenter()) {
            val = cluster_on_map;
        }
    });

    return val;
}

function addClusterOnMap(cluster) {
    // Hide all cluster's markers
    $.each(cluster.getMarkers(), (function () {
        if (this.marker.isHidden == false) {
            this.marker.isHidden = true;
            this.marker.close();
        }
    }));

    var newCluster = new InfoBox({
        markers               : cluster.getMarkers(),
        draggable             : true,
        content               : '<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>',
        disableAutoPan        : true,
        pixelOffset           : new google.maps.Size(-21, -21),
        position              : cluster.getCenter(),
        closeBoxURL           : "",
        isHidden              : false,
        enableEventPropagation: true,
        pane                  : "mapPane"
    });

    cluster.cluster = newCluster;

    cluster.markers = cluster.getMarkers();
    cluster.cluster.open(map, cluster.marker);
    clustersOnMap.push(cluster);
}

function renderElements() {

    $.each(settings.locations, function (index, location) {
        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(location[0], location[1]),
            map     : map,
            icon    : settings.transparentMarkerImage
        });

        marker.infobox = new InfoBox({
            content               : settings.contents[index],
            disableAutoPan        : false,
            maxWidth              : 0,
            pixelOffset           : new google.maps.Size(settings.pixelOffsetX, settings.pixelOffsetY),
            zIndex                : null,
            closeBoxURL           : "",
            infoBoxClearance      : new google.maps.Size(1, 1),
            position              : new google.maps.LatLng(location[0], location[1]),
            isHidden              : false,
            pane                  : "floatPane",
            enableEventPropagation: false
        });
        marker.infobox.isOpen = false;

        marker.marker = new InfoBox({
            draggable             : true,
            content               : '<div class="marker ' + settings.types[index] + '"><div class="marker-inner"></div></div>',
            disableAutoPan        : true,
            pixelOffset           : new google.maps.Size(-21, -58),
            position              : new google.maps.LatLng(location[0], location[1]),
            closeBoxURL           : "",
            isHidden              : false,
            pane                  : "floatPane",
            enableEventPropagation: true
        });
        marker.marker.isHidden = false;
        marker.marker.open(map, marker);
        markers.push(marker);

        google.maps.event.addListener(marker, 'click', function (e) {
            var curMarker = this;

            $.each(markers, function (index, marker) {
                // if marker is not the clicked marker, close the marker
                if (marker !== curMarker) {
                    marker.infobox.close();
                    marker.infobox.isOpen = false;
                }
            });

            if (curMarker.infobox.isOpen === false) {
                curMarker.infobox.open(map, this);
                curMarker.infobox.isOpen = true;
                map.setCenterWithOffset(curMarker.getPosition(), 100, -120);
            } else {
                curMarker.infobox.close();
                curMarker.infobox.isOpen = false;
            }
        });
    });

    markerCluster = new MarkerClusterer(map, markers, {
        gridSize: 40,
        styles: [
            {
                height   : 42,
                url      : settings.transparentClusterImage,
                width    : 42,
                textColor: 'transparent'
            }
        ]
    });

    clustersOnMap = new Array();

    clusterListener = google.maps.event.addListener(markerCluster, 'clusteringend', function (clusterer) {
        var availableClusters = clusterer.getClusters();
        var activeClusters = new Array();

        $.each(availableClusters, function (index, cluster) {
            if (cluster.getMarkers().length > 1) {
                activeClusters.push(cluster);
            }
        });

        $.each(availableClusters, function (index, cluster) {
            if (cluster.getMarkers().length > 1) {
                var val = isClusterOnMap(clustersOnMap, cluster);

                if (val !== false) {
                    val.cluster.setContent('<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>');
                    val.markers = cluster.getMarkers();
                    $.each(cluster.getMarkers(), (function (index, marker) {
                        if (marker.marker.isHidden == false) {
                            marker.marker.isHidden = true;
                            marker.marker.close();
                        }
                    }));
                } else {
                    addClusterOnMap(cluster);
                }
            } else {
                // Show all markers without the cluster
                $.each(cluster.getMarkers(), function (index, marker) {
                    if (marker.marker.isHidden == true) {
                        marker.marker.open(map, this);
                        marker.marker.isHidden = false;
                    }
                });

                // Remove old cluster
                $.each(clustersOnMap, function (index, cluster_on_map) {
                    if (cluster !== undefined && cluster_on_map !== undefined) {
                        if (cluster_on_map.getCenter() == cluster.getCenter()) {
                            // Show all cluster's markers/
                            cluster_on_map.cluster.close();
                            clustersOnMap.splice(index, 1);
                        }
                    }
                });
            }
        });

        var newClustersOnMap = new Array();

        $.each(clustersOnMap, function (index, clusterOnMap) {
            var remove = true;

            $.each(availableClusters, function (index2, availableCluster) {
                if (availableCluster.getCenter() == clusterOnMap.getCenter()) {
                    remove = false;
                }
            });

            if (!remove) {
                newClustersOnMap.push(clusterOnMap);
            } else {
                clusterOnMap.cluster.close();
            }
        });

        clustersOnMap = newClustersOnMap;
    });
}
})(jQuery);

这是地理编码压缩代码

Google Maps Multiple markers with the exact same location Not working

非常感谢

最佳答案

这个解决方案很棒,但我会考虑使用 Overlapping Marker Spiderfier库来处理同一位置的标记。您可以将其与标记聚类器库结合使用,不会出现任何问题。这样,您也不会失去查看同一位置实际上有多少标记的能力 - 在我看来,它为您提供了一个很棒的 UI。

要使用重叠标记 Spiderfier,请在 html 中的主 js 文件之前包含脚本文件。然后在你的js中,创建 OverlappingMarkerSpiderfier 的实例对象:

var oms = new OverlappingMarkerSpiderfier(map); 
/*in your case I'd do this after you initialize the `map` object, 
 *and declare the `oms` globally, like you do with your other global objects
 */

然后,当创建标记时,您希望将标记添加到 oms通过 addMarker() 对象方法。因此,在您的情况下将以下行添加到 renderElements() click 之后的函数您为 marker 声明的事件监听器:

oms.addMarker(marker);

最后,请确保还清除 oms 中的标记。对象时removeMarkers()通过向该函数添加以下内容来调用代码中的函数:

oms.clearMarkers();

关于javascript - Google map 将信息框标记在完全相同的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19476470/

相关文章:

javascript - 打印带有图像的 Div

javascript - 受控禁用按钮 Material UI - React JS

android - Android 上的路线 API

java - Android Maps API 版本 1 到版本 2 的迁移

Javascript 闭包行为在运行时很奇怪

javascript - 如何从 Array/Angular 中的元素获取最小值

javascript - 如何在对象更改时生成 Jquery 事件?

javascript - 谷歌地图 API 错误 : RefererNotAllowedMapError in android device

ruby - 当我尝试调用 Google Geocode API 时出现 SSL 错误

google-maps - Google Places/Maps API - 快速事实文本?