Google Maps Store Locator 在面板中显示距离

Google Maps Store Locator Display distance in Panel

我正在使用这个版本的商店定位器https://github.com/googlemaps/js-store-locator

我想在用户提交搜索输入(输入位置)后显示到每个位置的距离。 https://googlemaps.github.io/js-store-locator/examples/panel.html

我尝试在 http://pastebin.com/ZGrWN6ib

的第 441 行创建 storeLocator.Store.prototype.distanceTo 的副本
storeLocator.Store.prototype.distanceTo = function(a) {
        var b = this.getLocation(),
            c = storeLocator.toRad_(b.lat()),
            d = storeLocator.toRad_(b.lng()),
            b = storeLocator.toRad_(a.lat()),
            e = storeLocator.toRad_(a.lng());
        a = b - c;
        d = e - d;
        c = Math.sin(a / 2) * Math.sin(a / 2) + Math.cos(c) * Math.cos(b) * Math.sin(d / 2) * Math.sin(d / 2);
        return 12742 * Math.atan2(Math.sqrt(c), Math.sqrt(1 - c))
    };

我可以传递第一个参数,但第二个参数 var b = this.getLocation() 一直显示为未定义

我可以查看是否设置了用户位置,如果设置了 运行 功能?或者我需要连接到其中一位听众吗?

        if(!this.getLocation()){
            return 0;
        }
        else {
            var b = this.getLocation(),
                c = storeLocator.toRad_(b.lat()),
                d = storeLocator.toRad_(b.lng()),
                b = storeLocator.toRad_(a.lat()),
                e = storeLocator.toRad_(a.lng());
            a = b - c;
            d = e - d;
            c = Math.sin(a / 2) * Math.sin(a / 2) + Math.cos(c) * Math.cos(b) * Math.sin(d / 2) * Math.sin(d / 2);
            return 12742 * Math.atan2(Math.sqrt(c), Math.sqrt(1 - c));
        }

您正在使用 this.getLocation(),这意味着您的文件必须是 storeLocator.Store.prototype

getLocation() 方法可能属于 the store-locator.min.js,它应该包含在您的 html 文件中,也许这就是您找不到 getLocation() 方法的原因。

在 Google 地图 GitHub 示例页面中,store-locator.min.js 包含在 the panel.html 文件中。

this example folder开始,你可以看到文件的结构。

知道了!所以如果你想在商店列表视图中显示距离,你可以这样做:

先美化一下store-locator.min.js file for easier reading with something like http://jsbeautifier.org/

然后修改这部分函数storeLocator.Panel.prototype.init_

           if (b.geometry) {

                this.directionsFrom_ = b.geometry.location;
                a.directionsVisible_ && a.renderDirections_();
                var c = a.get("view");
                c.highlight(null);
                var d = c.getMap();
                b.geometry.viewport ? d.fitBounds(b.geometry.viewport) : (d.setCenter(b.geometry.location), d.setZoom(12));
                c.refreshView();
                a.listenForStoresUpdate_();

                // New Addition
                // You will need to create helper functions to set the cookie, i will include below

                storeLocator.setCookie("searchAddy",b.geometry.location,1);

                // End New Addition

            } else a.searchPosition(b.name)

然后在storeLocator.Panel.prototype.stores_changed

的正上方添加这个函数
storeLocator.Panel.prototype.ifDistanceFrom = function(b) {

        var str = storeLocator.getCookie('searchAddy'); 

        var regex = /\((-?[0-9]+\.[0-9]+), (-?[0-9]+\.[0-9]+)\)/g;
        var latlonArray = [];

        var match = regex.exec(str);
        while (match) {
            latlonArray.push({
                "lat" : match[1],
                "lon" : match[2]
            });
            match = regex.exec(str);
        };

        var a = new google.maps.LatLng(latlonArray[0].lat,latlonArray[0].lon),
            b = b.getLocation(),
            c = storeLocator.toRad_(b.lat()),
            d = storeLocator.toRad_(b.lng()),
            b = storeLocator.toRad_(a.lat()),
            e = storeLocator.toRad_(a.lng());
        a = b - c;
        d = e - d;
        c = Math.sin(a / 2) * Math.sin(a / 2) + Math.cos(c) * Math.cos(b) * Math.sin(d / 2) * Math.sin(d / 2);
        return 12742 * Math.atan2(Math.sqrt(c), Math.sqrt(1 - c));

}; 

现在修改这部分函数storeLocator.Panel.prototype.stores_changed

        for (var b = function() {
                a.highlight(this.store, !0)
            }, e = 0, f = Math.min(10, c.length); e < f; e++) {
            var g = c[e].getInfoPanelItem();
            g.store = c[e];

            // New Addition
            if(storeLocator.checkCookie() != null) {
                var distance = this.ifDistanceFrom(g.store);
                $(g).find('input').val(distance.toFixed(1));
            }
            else {
                $(g).find('.dist-span').hide();
            }
            // End New Addition

            d && c[e].getId() == d.getId() && $(g).addClass("highlighted");
            g.clickHandler_ || (g.clickHandler_ = google.maps.event.addDomListener(g, "click", b));
            this.storeList_.append(g)
        }

最后修改你的Data Feed文件DataSource.prototype.parse_函数

DataSource.prototype.parse_ = function(csv) {

  var stores = [];
  var rows = csv.split('\n');
  var headings = this.parseRow_(rows[0]);

  for (var i = 1, row; row = rows[i]; i++) {
    row = this.toObject_(headings, this.parseRow_(row));

    var features = new storeLocator.FeatureSet;

    // If you have features
    features.add(this.FEATURES_.getById('featureName1-' + featureName1));

    // New Addition
    var distInput = "<span class='dist-span'>Distance: <input class='dist-input' value='' size='2' type='text' /> mi.</span>"
    // End New Addition
    var position = new google.maps.LatLng(row.Ycoord, row.Xcoord);

    var shop = this.join_([row.Street_add], ', ');

    var locality = row.Locality+', '+row.State+' '+row.Postcode;
    var store = new storeLocator.Store(row.Fcilty_typ, position, features, {
      title: row.Fcilty_nam,
      // New Addition
      address: this.join_([shop, locality, distInput], '<br>'),
      // End New Addition
      hours: row.Hrs_of_bus
    });
    stores.push(store);
  }
  return stores;
};

以下是您需要添加到 store-locator.min.js 以设置 cookie 的辅助函数。

storeLocator.setCookie = function(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+d.toUTCString();
    document.cookie = cname + "=" + cvalue + "; " + expires;
    // alert('Cookie set: '+ cvalue);
};

storeLocator.getCookie = function (cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    };
    return "";
};

storeLocator.checkCookie = function () {
    var a = storeLocator.getCookie("searchAddy");
    if (a != "") {
        return 1;
    } 
    else {
        return null;
    }
};

DataSource.prototype.parse_ 函数中,我在 misc 参数中添加了一个新的 div 元素,并将商店 ID 用作唯一 div class .

var id = row.name.toLowerCase().replace(/[\. ,:-]+/g, '-');
var position = new google.maps.LatLng(row.latitude, row.longitude);
var locality = this.join_([row.state, row.postal_code], ', ');
var store = new storeLocator.Store(id, position, features, {
    title: row.name,
    address: this.join_([row.street, locality], '<br>'),
    phone: row.phone_number,
    misc: '<div class="distance '+id+'"></div>',
});

然后在 DataSource.prototype.toObject_ 中,我刚刚添加了一些 jQuery 用于在搜索位置时更新文本。

var panelDiv = document.getElementById('panel');
var panel = new storeLocator.Panel(panelDiv, {
    view: view
});

google.maps.event.addListener(panel, 'geocode', function(result) {
    panel.stores.forEach(function(store){
        var distance = Math.round(store.distanceTo(result.geometry.location));
        jQuery('.distance').each(function(){
            if (jQuery(this).hasClass(store.getId())) {
                jQuery(this).text(distance);
            }
        });
    });
});

可能有更好的方法,但这对我来说很有效。