在Fusion Tables Map List View中添加“在地图上查看”链接

时间:2013-09-18 09:07:12

标签: google-maps-api-3 google-fusion-tables

我正在Derek Eder使用精彩的Fusion Tables地图模板。我按照here的指示激活了结果列表。

我想在每个列表上都有一个“查看地图”链接,这样当我点击链接时,页面会向上滚动到地图并打开该特定列表的信息窗口。您可以在geo places主题上看到一个示例。

以下是我的代码

HTML

<!DOCTYPE html>
<html lang='en'>
  <head>

    <link rel="stylesheet" href="bootstrap.spacelab.min.css"/>
    <link rel="stylesheet" href="bootstrap-responsive.min.css"/>
    <link rel="stylesheet" href="custom.css"/>
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->


  </head>
  <body>
    <div class='navbar'>
      <div class='navbar-inner'>
        <div class='container'>
          <a class='brand' href='/'>Worldwide Stores</a>
        </div>
      </div>
    </div>
    <div class='container-fluid'>
      <div class='row-fluid'>
        <div class='span4'>


          <div class='well'>
            <h4>
              Address <small>(<a id='find_me' href='#'>find me</a>)</small>
            </h4>
            <input class='input-block-level' id='search_address' placeholder='Enter an address or an intersection' type='text' />
            <label>
              show companies within
              <select class='input-small' id='search_radius'>
                <option value='400'>2 blocks</option>
                <option value='805'>1/2 mile</option>
                <option value='1610'>1 mile</option>
                <option value='3220'>2 miles</option>
                <option value='8050'>5 miles</option>
                <option value='16100'>10 miles</option>
                <option value='40250'>25 miles</option>
                <option value='80500'>50 miles</option>
                <option value='161000'>100 miles</option>
                <option value='402500'>250 miles</option>
                <option value='805000'>500 miles</option>
                <option value='1610000'>1000 miles</option>
              </select>

            </label>


                    <h5> Refine Your Search By:</h5>
                        <label>
                            <select id='select_type'>
                             <option value=''>All Categories</option>
                             <option value='Hotels'>Hotels</option>
                             <option value='Restaurants'>Restaurants</option>
                             <option value='Shopping Malls'>Shopping Malls</option>
                             <option value='Travel Agents'>Travel Agents</option>
                            </select>
                            </label>

                            <label>
                            <select disabled id='select_type1'>
                            <option value=''>Select Two</option>
                            <option value='male'>Male</option>
                            <option value='female'>Female</option>
                            </select>
                            </label>

                            <label>
                            <select disabled id='select_type2'>
                            <option value=''>Select Three</option>
                            <option value='Advanced Materials/Prd'>Advanced Materials/Prd</option>
                            <option value='Advertising Agencies'>Advertising Agencies</option>
                            <option value='Advertising Sales'>Advertising Sales</option>
                            <option value='Advertising Services'>Advertising Services</option>
                         </select>
                         </label>




          <input class='btn btn-primary' id='search' type='button' value='Search' />
            <button class='btn' id='reset'>Reset</button>

            </div>





          <p class='alert alert-info lead' id='result_count'></p>


    </p>  </p>
    </p>  </p>
    </p>  </p>


        </div>


        <div class='span8'>
          <div id='map_canvas'></div>
          <div class='well'>
            <div id='results_list'></div>
          </div>
        </div>

      </div>
    </div>

    <script type="text/javascript" src="source/jquery.js"></script>
    <script type="text/javascript" src="source/bootstrap.js"></script>
    <script type="text/javascript" src="source/jquery.address.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;libraries=places"></script>
    <script type="text/javascript" src="source/jquery.geocomplete.min.js"></script>
    <script type="text/javascript" src="maps_lib.js"></script>
    <script type='text/javascript'>
      //<![CDATA[
        $(window).resize(function () {
          var h = $(window).height(),
            offsetTop = 90; // Calculate the top offset

          $('#map_canvas').css('height', (h - offsetTop));
        }).resize();

        $(function() {
          MapsLib.initialize();
          $("#search_address").geocomplete();

          $(':checkbox').click(function(){
            MapsLib.doSearch();
          });

          $(':radio').click(function(){
            MapsLib.doSearch();
          });

          $('#search_radius').change(function(){
            MapsLib.doSearch();
          });

          $('#select_type').change(function(){
            MapsLib.doSearch();
          });
           $('#select_type1').change(function(){
            MapsLib.doSearch();
          });
            $('#select_type2').change(function(){
            MapsLib.doSearch();
          });

          $('#search').click(function(){
            MapsLib.doSearch();
          });

          $('#find_me').click(function(){
            MapsLib.findMe(); 
            return false;
          });

          $('#reset').click(function(){
            $.address.parameter('address','');
            MapsLib.initialize(); 
            return false;
          });

          $(":text").keydown(function(e){
              var key =  e.keyCode ? e.keyCode : e.which;
              if(key == 13) {
                  $('#search').click();
                  return false;
              }
          });
        });
      //]]>
    </script>
  </body>
</html>

maps_lib.js

/*!
 * Searchable Map Template with Google Fusion Tables
 * http://derekeder.com/searchable_map_template/
 *
 * Copyright 2012, Derek Eder
 * Licensed under the MIT license.
 * https://github.com/derekeder/FusionTable-Map-Template/wiki/License
 *
 * Date: 12/10/2012
 *
 */

var MapsLib = MapsLib || {};
var MapsLib = {

  //Setup section - put your Fusion Table details here
  //Using the v1 Fusion Tables API. See https://developers.google.com/fusiontables/docs/v1/migration_guide for more info

  //the encrypted Table ID of your Fusion Table (found under File => About)
  //NOTE: numeric IDs will be deprecated soon
  fusionTableId:      "1f8rnajgS2iSVwwBR1NwXwImUuFB7VCpOg1-IfCs",

  //*New Fusion Tables Requirement* API key. found at https://code.google.com/apis/console/
  //*Important* this key is for demonstration purposes. please register your own.
  googleApiKey:       "API KEY",

  //name of the location column in your Fusion Table.
  //NOTE: if your location column name has spaces in it, surround it with single quotes
  //example: locationColumn:     "'my location'",
  locationColumn:     "Address",

  map_centroid:       new google.maps.LatLng(17,15), //center that your map defaults to
  locationScope:      "",      //geographical area appended to all address searches
  recordName:         "Store",       //for showing number of results
  recordNamePlural:   "Stores",

  searchRadius:       805,            //in meters ~ 1/2 mile
  defaultZoom:        2,             //zoom level when map is loaded (bigger is more zoomed in)
  addrMarkerImage: 'http://derekeder.com/images/icons/blue-pushpin.png',
  currentPinpoint: null,

  initialize: function() {
    $( "#result_count" ).html("");

    geocoder = new google.maps.Geocoder();
    var myOptions = {
      zoom: MapsLib.defaultZoom,
      center: MapsLib.map_centroid,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($("#map_canvas")[0],myOptions);

    // maintains map centerpoint for responsive design
    google.maps.event.addDomListener(map, 'idle', function() {
        MapsLib.calculateCenter();
    });

    google.maps.event.addDomListener(window, 'resize', function() {
        map.setCenter(MapsLib.map_centroid);
    });

    MapsLib.searchrecords = null;

    //reset filters
    $("#search_address").val(MapsLib.convertToPlainString($.address.parameter('address')));
    var loadRadius = MapsLib.convertToPlainString($.address.parameter('radius'));
    if (loadRadius != "") $("#search_radius").val(loadRadius);
    else $("#search_radius").val(MapsLib.searchRadius);
    $(":checkbox").attr("checked", "checked");
    $("#result_count").hide();

    //-----custom initializers-------



    //run the default search
    MapsLib.doSearch();
  },

  doSearch: function(location) {
    MapsLib.clearSearch();
    var address = $("#search_address").val();
    MapsLib.searchRadius = $("#search_radius").val();

    var whereClause = MapsLib.locationColumn + " not equal to ''";

    //-----custom filters-------

   if ( $("#select_type").val() != "") {
      whereClause += " AND 'Category' = '" + $("#select_type").val() + "'";
      }

    if ( $("#select_type1").val() != "") {
      whereClause += " AND 'sex' = '" + $("#select_type1").val() + "'";
      }


    if ( $("#select_type2").val() != "") {
      whereClause += " AND 'Subindustry' = '" + $("#select_type2").val() + "'";
      }



    //-------end of custom filters--------

    if (address != "") {
      if (address.toLowerCase().indexOf(MapsLib.locationScope) == -1)
        address = address + " " + MapsLib.locationScope;

      geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          MapsLib.currentPinpoint = results[0].geometry.location;

          $.address.parameter('address', encodeURIComponent(address));
          $.address.parameter('radius', encodeURIComponent(MapsLib.searchRadius));
          map.setCenter(MapsLib.currentPinpoint);
          map.setZoom(14);

          if (MapsLib.searchRadius == "400")
            map.setZoom(16);
          else if (MapsLib.searchRadius == "805")
            map.setZoom(15);
          else if (MapsLib.searchRadius == "1610")
            map.setZoom(14);
          else if (MapsLib.searchRadius == "3220")
            map.setZoom(13);
          else if (MapsLib.searchRadius == "8050")
            map.setZoom(12);
          else if (MapsLib.searchRadius == "16100")
            map.setZoom(11);
          else if (MapsLib.searchRadius == "40250")
            map.setZoom(09);
          else if (MapsLib.searchRadius == "80500")
            map.setZoom(08);
          else if (MapsLib.searchRadius == "161000")
            map.setZoom(07);
          else if (MapsLib.searchRadius == "402500")
            map.setZoom(06);
          else if (MapsLib.searchRadius == "805000")
            map.setZoom(05);
          else if (MapsLib.searchRadius == "1610000")
            map.setZoom(04);
          else
            map.setZoom(14);


          MapsLib.addrMarker = new google.maps.Marker({
            position: MapsLib.currentPinpoint,
            map: map,
            icon: MapsLib.addrMarkerImage,
            animation: google.maps.Animation.DROP,
            title:address
          });

          whereClause += " AND ST_INTERSECTS(" + MapsLib.locationColumn + ", CIRCLE(LATLNG" + MapsLib.currentPinpoint.toString() + "," + MapsLib.searchRadius + "))";

          MapsLib.drawSearchRadiusCircle(MapsLib.currentPinpoint);
          MapsLib.submitSearch(whereClause, map, MapsLib.currentPinpoint);
        }
        else {
          alert("We could not find your address: " + status);
        }
      });
    }
    else { //search without geocoding callback
      MapsLib.submitSearch(whereClause, map);
    }
  },

  submitSearch: function(whereClause, map, location) {
    //get using all filters
    //NOTE: styleId and templateId are recently added attributes to load custom marker styles and info windows
    //you can find your Ids inside the link generated by the 'Publish' option in Fusion Tables
    //for more details, see https://developers.google.com/fusiontables/docs/v1/using#WorkingStyles

    MapsLib.searchrecords = new google.maps.FusionTablesLayer({
      query: {
        from:   MapsLib.fusionTableId,
        select: MapsLib.locationColumn,
        where:  whereClause
      },
      styleId: 2,
      templateId: 2
    });
    MapsLib.searchrecords.setMap(map);
    MapsLib.getCount(whereClause);
    MapsLib.getList(whereClause);
  },

  clearSearch: function() {
    if (MapsLib.searchrecords != null)
      MapsLib.searchrecords.setMap(null);
    if (MapsLib.addrMarker != null)
      MapsLib.addrMarker.setMap(null);
    if (MapsLib.searchRadiusCircle != null)
      MapsLib.searchRadiusCircle.setMap(null);
  },

  findMe: function() {
    // Try W3C Geolocation (Preferred)
    var foundLocation;

    if(navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        foundLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
        MapsLib.addrFromLatLng(foundLocation);
      }, null);
    }
    else {
      alert("Sorry, we could not find your location.");
    }
  },

  addrFromLatLng: function(latLngPoint) {
    geocoder.geocode({'latLng': latLngPoint}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if (results[1]) {
          $('#search_address').val(results[1].formatted_address);
          $('.hint').focus();
          MapsLib.doSearch();
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  },

  drawSearchRadiusCircle: function(point) {
      var circleOptions = {
        strokeColor: "#4b58a6",
        strokeOpacity: 0.3,
        strokeWeight: 1,
        fillColor: "#4b58a6",
        fillOpacity: 0.05,
        map: map,
        center: point,
        clickable: false,
        zIndex: -1,
        radius: parseInt(MapsLib.searchRadius)
      };
      MapsLib.searchRadiusCircle = new google.maps.Circle(circleOptions);
  },

  query: function(selectColumns, whereClause, callback) {
    var queryStr = [];
    queryStr.push("SELECT " + selectColumns);
    queryStr.push(" FROM " + MapsLib.fusionTableId);
    queryStr.push(" WHERE " + whereClause);

    var sql = encodeURIComponent(queryStr.join(" "));
    $.ajax({url: "https://www.googleapis.com/fusiontables/v1/query?sql="+sql+"&callback="+callback+"&key="+MapsLib.googleApiKey, dataType: "jsonp"});
  },

  handleError: function(json) {
    if (json["error"] != undefined) {
      var error = json["error"]["errors"]
      console.log("Error in Fusion Table call!");
      for (var row in error) {
        console.log(" Domain: " + error[row]["domain"]);
        console.log(" Reason: " + error[row]["reason"]);
        console.log(" Message: " + error[row]["message"]);
      }
    }
  },

  getCount: function(whereClause) {
    var selectColumns = "Count()";
    MapsLib.query(selectColumns, whereClause,"MapsLib.displaySearchCount");
  },

  displaySearchCount: function(json) {
    MapsLib.handleError(json);
    var numRows = 0;
    if (json["rows"] != null)
      numRows = json["rows"][0];

    var name = MapsLib.recordNamePlural;
    if (numRows == 1)
    name = MapsLib.recordName;
    $( "#result_count" ).fadeOut(function() {
        $( "#result_count" ).html(MapsLib.addCommas(numRows) + " " + name + " found");
      });
    $( "#result_count" ).fadeIn();
  },

getList: function(whereClause) {
  var selectColumns = "StoreName, Address, Contact, Website";
  MapsLib.query(selectColumns, whereClause, "MapsLib.displayList");
},

displayList: function(json) {
  MapsLib.handleError(json);
  var data = json["rows"];
  var template = "";

  var results = $("#results_list");
  results.hide().empty(); //hide the existing list and empty it out first

  if (data == null) {
    //clear results list
    results.append("<li><span class='lead'>No results found</span></li>");
  }
  else {
    for (var row in data) {
      template = "\
        <div class='row-fluid item-list'>\
          <div class='span12'>\
            <span class='lead'>" + data[row][0] + "\</span>\
            <br />\
            " + data[row][4] + "\
            <br />\
            " + data[row][5] + "\
            <br />\
            <a href='" + data[row][6] + "'>\
                <span>" + data[row][7] + "\</span>\
            </a>\
            <br />\
            <a onClick=''>\
                <span style='color: red;'>See on Map</span>\
            </a>\
          </div>\
        </div>"
      results.append(template);
    }
  }
  results.fadeIn();
},

  addCommas: function(nStr) {
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
  },

  // maintains map centerpoint for responsive design
  calculateCenter: function() {
    center = map.getCenter();
  },

  //converts a slug or query string in to readable text
  convertToPlainString: function(text) {
    if (text == undefined) return '';
    return decodeURIComponent(text);
  }

  //-----custom functions-------
  // NOTE: if you add custom functions, make sure to append each one with a comma, except for the last one.
  // This also applies to the convertToPlainString function above

  //-----end of custom functions-------
}

enter image description here

2 个答案:

答案 0 :(得分:0)

它并不像看起来那么容易。

FusionTableLayer上的功能(例如标记)的位置在您真正点击之前无法使用(此点击无法模拟)。

您无法通过查询获取该功能的LatLng,因为您已在FusionTable中存储了地址而非LatLng。

尽管API知道LatLng的地址,但无法访问它们。

所以你唯一能做的就是:

  1. 获取行的地址
  2. 使用google.maps.Geocoder对此地址进行地理编码
  3. 在地理编码器返回的LatLng中打开自定义InfoWindow(由行的属性填充的内容)。

答案 1 :(得分:0)

我宁愿在Dr.Molle的答案中添加评论,但是由于Stack Overflow的点数系统,我必须添加一个答案,即使我认为这不会真正有用,因为我不能非常具体。我假设那是因为我的目标是让我回答问题,而不只是谈论答案;)

Dr.Molle走在正确的轨道上,但是每次点击都会调用地理编码器不仅非常缓慢,而且每个IP每天只会收到很多地理编码器请求。所以:

创建具有唯一标识符的列。向标记添加一个侦听器,以便在单击时,它将在表中查询该ID。当结果进来时,使用返回的数据创建一个InfoWindow(对不起,没有帮助)。

这是一个完全符合您要求的样本: https://developers.google.com/fusiontables/docs/samples/change_infowindow_content