简体   繁体   English

Google Maps API:创建商店定位器

[英]Google Maps API: Create a store locator

Today I am trying to make a store locator using google maps' api. 今天我正在尝试使用谷歌地图'api制作商店定位器。 The store locator is to be set up like so: two areas, one with a map containing all the stores in a given area (measured in a selectable radius from a center point), and one area with a list of all the stores on the map, their information, and of course a link to their website. 商店定位器的设置方式如下:两个区域,一个带有包含给定区域中所有商店的地图(以中心点的可选半径测量),另一个区域包含所有商店的列表。地图,他们的信息,当然还有他们网站的链接。 When a person clicks on the name of the store on the store list, it centers upon the store in the map, and opens an infoWindow above the store marker. 当用户点击商店列表中商店的名称时,它会以地图中的商店为中心,并在商店标记上方打开infoWindow。

I have a javascript variable to which I have taken pains to assign some json data from a php script (which is selecting this data on the fly from a database) 我有一个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"}]; 

Now, I know there are 5 different functions I need to run, listed below with their apparent use: 现在,我知道我需要运行5种不同的功能,下面列出了它们的明显用途:

  1. geocoder.getLocations : Used to convert address data (from the json object) into latitude and longitude data object geocoder.getLocations :用于将地址数据(来自json对象)转换为纬度和经度数据对象
  2. addElementToList : Used to add address information to the list of stores, and bind the centerOnStore function to onclick addElementToList :用于将地址信息添加到商店列表,并将centerOnStore函数绑定到onclick
  3. centerOnStore when a store list item is clicked in the list area, this function center's upon the store that has been clicked on in the map area. centerOnStore在列表区域中单击商店列表项时,此功能中心位于已在地图区域中单击的商店中。 This function also opens an infoWindow above the centered upon store. 此函数还会在以商店为中心的上方打开一个infoWindow。
  4. placeMarker the function to place a marker on the map, called once the geocoder returns latitudeLongitude objects placeMarker用于在地图上放置标记的功能,一旦地理编码器返回latitudeLongitude对象,就会调用该功能
  5. eventListener this is tied up somehow in the clicking of a list item and it's further centering the map upon the store in question eventListener在点击列表项时以某种方式绑定了它,并且它进一步将地图置于相关商店的中心位置

Well, i am out of my league it would appear. 好吧,我出现在联盟之外。 I am just now learning about javascript closures, and I think these may be necessary, but I can't quite understand them. 我刚刚学习javascript闭包,我认为这些可能是必要的,但我不太了解它们。 I need to figure out some way to get all these functions into a working order, passing information back and forth to each other, and create a store locator 我需要找出一些方法将所有这些函数放入工作顺序,相互传递信息,并创建商店定位器

.


Here is what I've got so far, but there is something very wrong with it. 这是我到目前为止所得到的,但它有一些非常错误。

    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
                    }
            }
    }

I am sorry for the wall of code. 我很抱歉代码墙。 I can't think anymore. 我再也想不到了。 I had no idea this would be so difficult. 我不知道这会如此困难。 No idea at all. 根本不知道。

if I alert currentLocation in the line before I increment it, it's always 0. but If I alert it in the line after I increment it, it's '1,2,3,4' etc. This goes against everything I know about computers. 如果我在增加它之前提醒行中的currentLocation,它总是为0.但如果我在增加它之后在行中提醒它,它是'1,2,3,4'等等。这违背了我对计算机的所有了解。

Forget about closures for a moment. 暂时忘掉关闭。 You can dive into those once you get a working app. 一旦你得到一个有用的应用程序,你可以深入研究这些 I think you're goal at this point to should be to just get something that accomplishes what you want. 我认为你在这一点上的目标应该是获得能够实现你想要的东西。

To me, it seems like the only piece you're missing is the idea of a callback function . 对我来说,似乎唯一缺少的是回调函数的想法。 For instance, addElementToList would be passed as the callback argument to geocoder.getLocaitons . 例如,addElementToList将作为回调参数传递给geocoder.getLocaitons The way it works is that when getLocations() finishes, it calls addElementToList and supplies the result from getLocations() as an argument to addElementToList. 它的工作方式是当getLocations()完成时,它调用addElementToList并将getLocations()的结果作为addElementToList的参数提供。 The code for addElementToList will then add your store location to the map as a marker and add a new element to your html list with the store's name or address or whatever. 然后,addElementToList的代码将您的商店位置作为标记添加到地图中,并使用商店的名称或地址或其他内容将新元素添加到您的html列表中。

Take a look at this blog post for a simple example using a callback: Introducing Google's Geocoding Service . 请查看此博客文章,了解使用回调的简单示例: 介绍Google的地理编码服务

The last part, centering on a specific store, can be done (as you suggested) with event listeners. 最后一部分,以特定商店为中心,可以使用事件监听器(如您所建议的那样)完成。 You can set up a listener for clicks on the markers and also for clicks on your list. 您可以为标记点击以及列表中的点击设置监听器。 When you add a marker, you can also add an event listener on it . 添加标记时, 还可以在其上添加事件侦听器 It'd be nice if you could set one listener for all markers on the map but I'm not familiar enough with google's API to know if this is possible. 如果您可以为地图上的所有标记设置一个监听器,那就太好了,但我对谷歌的API不太熟悉,知道这是否可行。

What is your source for that information? 您获取该信息的来源是什么? placeMarker certainly doesn't ring a bell. placeMarker肯定不响铃。 The Google Maps API reference (complete with examples!) is available at http://code.google.com/apis/maps/documentation/reference.html Google Maps API参考(包含示例!)可在http://code.google.com/apis/maps/documentation/reference.html上找到。

Based on your comment to @Rushyo's answer- it seems like you know enough about Javascript and the Google Maps API to construct those functions. 根据您对@Rushyo的回答的评论 - 您似乎对Javascript和Google Maps API有足够的了解来构建这些功能。 I'm a little confused as to what you're looking for. 我对你要找的东西有点困惑。

I would suggest however, that you add lat/lon coordinates to your database in the first place. 不过,我建议您首先在数据库中添加lat / lon坐标。 You shouldn't have to geocode the addresses every time the map is loaded. 每次加载地图时,您都不必对地址进行地理编码。

Update: In response to your comment below, here is the code you referenced - along with the addAddressToMap() function called by the Geocoder. 更新:在回复下面的评论时,这里是您引用的代码 - 以及Geocoder调用的addAddressToMap()函数。 It creates a marker for each address and adds it to the array markerList . 它为每个地址创建一个标记,并将其添加到数组markerList You can then access the markers in that array later, since we initialized it outside the scope of the addAddressToMap() function. 然后,您可以在以后访问该数组中的标记,因为我们在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);
  }
}

Update 2: In response to the code you posted in your question above, you're probably getting random numbers in currentLocation because of the asynchronous nature of the Geocoder. 更新2:为了回应您在上述问题中发布的代码,由于Geocoder的异步特性,您可能会在currentLocation获取随机数。 Remember that your getLocations() function will send requests for every location in the array before it gets any responses back. 请记住, getLocations()函数会在收到任何响应之前为数组中的每个位置发送请求。

I'm creating a new answer, since my other answer is getting messy. 我正在创建一个新的答案,因为我的另一个答案是变得混乱。

In order to get proper closure, you'll need to create a separate function to make the geocoder request. 为了获得正确的闭包,您需要创建一个单独的函数来生成地理编码器请求。 The following code will allow you to assign the desired infoWindow text to each marker. 以下代码将允许您为每个标记分配所需的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);
    });
}

For more info on closure in Google maps, see these questions: 有关Google地图中关闭的更多信息,请参阅以下问题:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM