【问题标题】:Google Maps API: Create a store locatorGoogle Maps API:创建商店定位器
【发布时间】:2009-08-28 21:24:53
【问题描述】:

今天我正在尝试使用谷歌地图的 api 制作商店定位器。 商店定位器的设置如下: 两个区域,一个带有包含给定区域内所有商​​店的地图(以中心点的可选半径测量),另一个区域包含地图上所有商店的列表,它们的信息,当然还有指向他们的网站。当人们点击商店列表中的商店名称时,它会以地图中的商店为中心,并在商店标记上方打开一个信息窗口。

我有一个 javascript 变量,我煞费苦心地从 php 脚本中分配了一些 json 数据(从数据库中动态选择这些数据)

locations = [{"siteurl":"http:\/\/localhost.localdomain\/5","address":"260 Test St","city":"Brooklyn","state":"New York","zip_code":"11206"},{"siteurl":"http:\/\/localhost.localdomain\/4","address":"3709 Testing St.","city":"Austin","state":"Texas","zip_code":"78705"}]; 

现在,我知道我需要运行 5 个不同的函数,下面列出了它们的明显用途:

  1. geocoder.getLocations :曾经 转换地址数据(来自 json 对象)转化为经纬度 数据对象
  2. addElementToList: 用于添加地址信息到 商店列表,并绑定 centerOnStore onclick 函数
  3. centerOnStore在列表区域点击店铺列表项时,该功能中心位于地图区域被点击的店铺。此功能还会在以商店为中心的上方打开一个信息窗口。
  4. placeMarker 在地图上放置标记的函数,在地理编码器返回 latitudeLongitude 对象时调用
  5. eventListener 这以某种方式与单击列表项有关,它进一步将地图集中在相关商店上

好吧,我不喜欢它会出现。我刚刚学习 javascript 闭包,我认为这些可能是必要的,但我不太了解它们。我需要想办法让所有这些功能进入正常工作状态,来回传递信息,并创建一个商店定位器

.


这是我到目前为止所得到的,但其中有一些非常错误的地方。

    var map = null;
    var geocoder = null;
    var locations = null;
    var center_on = null;
    var zoom_level = null;
    var markerList = [];

    function initialize()
    {
            if(GBrowserIsCompatible())
            {
                    // Assign vars
                    map = new GMap2(document.getElementById("map_canvas"));
                    geocoder = new GClientGeocoder();
                    locations = <?php echo(json_encode($my_vars['locations'])); ?>;
                    center_on = "<?php echo($my_vars['center_on']); ?>";
                    zoom_level = <?php echo($my_vars['zoom_level']); ?>;
                    var currentLocation = 0;

                    geocoder.getLatLng(center_on, function(myPoint)
                    {
                            map.setCenter(myPoint, zoom_level);
                    });
                    map.setUIToDefault();


                    var list = document.getElementById('center_list');

                    for(var i = 0; i < locations.length; i++)
                    {
                            var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
                            geocoder.getLocations(address, addAddressToMap);
                    }

            }




            function addAddressToMap(response) {

                    if (!response || response.Status.code != 200) {
                            currentLocation++;
                    } else {
                    var place = response.Placemark[0];
                    var point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
                    marker = new GMarker(point);
                    GEvent.addListener(marker, 'click', function(){
                            this.openInfoWindowHtml("<strong>" + place.address + "</strong><br /><a href='" + locations[currentLocation]['siteurl'] + "'>" + locations[currentLocation]['siteurl'] + "</a>");
                    });
                    map.setCenter(point, 13);
                    markerList.push(marker);
                    map.addOverlay(marker);
                    li = document.createElement('li');

                    li.innerHTML = "<strong>" + place.address + "</strong>";
                    li.setAttribute('onclick', 'center_on_center(' + place.Point.coordinates[1] + ',' + place.Point.coordinates[0] + ')');
                    li.setAttribute('id', 'center_');
                    li.style.fontSize = '1.4em';
                    document.getElementById('center_list').appendChild(li);
                    // alert(currentLocation) here says 0,0,0,0
                    currentLocation++;
                    // alert(currentLocation) here says 1,2,3,4
                    }
            }
    }

我为代码墙感到抱歉。我不能再想了。我不知道这会如此困难。完全不知道。

如果我在增加它之前在行中警告 currentLocation,它总是 0。但是如果我在增加它之后在行中警告它,它是 '1,2,3,4' 等等。这与我所知道的一切背道而驰关于计算机。

【问题讨论】:

  • 有点不相关,但是一旦获得地理编码,您就应该真正将它们存储在数据库中,因为这应该会加快您的应用程序的速度。
  • 为此,我必须在 wordpress MU 管理员中添加一个钩子以运行 javascript 异步 xml 请求,并确保在用户提交表单之前完成该请求。
  • 您最好使用 HTTP 地理编码器将位置存储在数据库中。 code.google.com/apis/maps/documentation/geocoding/index.html

标签: javascript api google-maps closures


【解决方案1】:

暂时忘记关闭。一旦你得到一个工作的应用程序,你就可以深入研究这些。我认为您此时的目标应该是获得能够实现您想要的东西。

对我来说,您似乎唯一缺少的就是callback function 的想法。例如,addElementToList 将作为回调参数传递给geocoder.getLocaitons。它的工作方式是当 getLocations() 完成时,它调用 addElementToList 并将 getLocations() 的结果作为参数提供给 addElementToList。然后 addElementToList 的代码会将您的商店位置作为标记添加到地图中,并使用商店的名称或地址或其他任何内容将新元素添加到您的 html 列表中。

查看这篇博文,了解使用回调的简单示例:Introducing Google's Geocoding Service。

最后一部分,以特定商店为中心,可以(如您所建议的)使用事件侦听器完成。您可以为标记的点击设置监听器,也可以为您的列表上的点击设置监听器。添加标记时,you can also add an event listener on it。如果您可以为地图上的所有标记设置一个侦听器,那就太好了,但我对 google 的 API 不够熟悉,不知道这是否可行。

【讨论】:

    【解决方案2】:

    这些信息的来源是什么? placeMarker 当然不会响铃。 Google Maps API 参考(包含示例!)可在http://code.google.com/apis/maps/documentation/reference.html

    获取

    【讨论】:

    • 一些功能是我自己假设的设计,placeMarker 只是一种更简单的说法function placeMarker(response) { if (!response || response.Status.code != 200) { } else { place = response.Placemark[0]; point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]); marker = new GMarker(point); map.addOverlay(marker); }
    【解决方案3】:

    根据您对@Rushyo 的回答的评论——您似乎对 Javascript 和 Google Maps API 足够了解来构建这些函数。我对你在寻找什么感到有点困惑。

    不过,我建议您首先将纬度/经度坐标添加到您的数据库中。您不必在每次加载地图时都对地址进行地理编码。

    更新:针对您在下面的评论,这里是您引用的代码 - 以及地理编码器调用的 addAddressToMap() 函数。它为每个地址创建一个标记并将其添加到数组markerList。然后您可以稍后访问该数组中的标记,因为我们在 addAddressToMap() 函数的范围之外对其进行了初始化。

    for(var i = 0; i < locations.length; i++) { 
        var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
        geocoder.getLocations(address, addAddressToMap); 
    }
    
    var markerList = new array();
    
    function addAddressToMap(response) {
        if (!response || response.Status.code != 200) {
            alert("\"" + address + "\" not found");
      } else {
          place = response.Placemark[0];
          point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
          marker = new GMarker(point);
          markerList.push(marker);
          map.addOverlay(marker);
      }
    }
    

    更新 2:响应您在上述问题中发布的代码,由于地理编码器的异步特性,您可能会在 currentLocation 中获得随机数。请记住,您的 getLocations() 函数将在收到任何响应之前发送对数组中每个位置的请求。

    【讨论】:

    • 我想我只是希望能有一个蓝图来填充细节。我可以或多或少地创建功能,但我无法让它们相互协作。我知道这些是我见过的所有商店定位器中通常包含的功能,但我只是不知道它们是如何相互关联的。我不知道如何在 javascript 函数之间来回传递数据,它不像在 php 中那样工作,这是我更熟悉的语言。
    • 基本上,我只是碰到了我的认知壁垒,我想不出我的出路。当然,该功能是在几天前到期的。
    • 例如`for(var i = 0; i
    • 那么有什么方法可以取回地理编码器的 latLng 并将其用于不同的函数,而该函数不是地理编码器的回调?我需要在地址 infoWindow 中插入商店的 url,但是无法将日期传递给地理编码器的回调函数
    【解决方案4】:

    我正在创建一个新答案,因为我的另一个答案越来越混乱。

    为了获得正确的关闭,您需要创建一个单独的函数来发出地理编码器请求。以下代码将允许您将所需的 infoWindow 文本分配给每个标记。

    for(var i = 0; i < locations.length; i++) {
        var address = locations[i]['address'] + ', ' + locations[i]['city'] + ' ' + locations[i]['state'] + ', ' + locations[i]['zip_code'];
        var text = locations[i]['address']; // or whatever you want the text to be
        getLocation(address, text);
    }
    

    ...

    function getLocation(address, text) {
        geocoder.getLocations(address, function(response) {
            var place = response.Placemark[0];
            var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
            marker = new GMarker(point);
            marker.bindInfoWindowHtml(text); // note that if you want to use GEvent.addListener() instead - you'll need to create another function to get proper closure
            map.addOverlay(marker);
        });
    }
    

    有关 Google 地图中关闭的更多信息,请参阅以下问题:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      相关资源
      最近更新 更多