javascript - 按州过滤标记并结合地点自动完成功能 - Google Maps JavaScript API

标签 javascript jquery google-maps google-maps-api-3 google-places-api

我正在使用Google Maps Places Library从事类似于以下内容的工作:http://codepen.io/maudulus/pen/oxNXod 。正如您所看到的,当您加载页面时,可以使用 State select 过滤许多标记。您还可以使用搜索框查找与您搜索位置的一个标准差以内的标记。

但是,我正在尝试将这两个功能结合起来(例如,有人搜索某个位置,然后按州过滤结果)。我不确定为什么这目前不起作用...我的猜测是它可能是双重添加点,因为它似乎确实想要过滤位置(当您更改 时,您可以看到它们闪烁选择)。

位置代码

var map;
var originalStores = [];
var markersArr = [];
var geocoder = new google.maps.Geocoder();

var typingTimer; //timer identifier
var doneTypingInterval = 1000; //time in ms, 5 second for example
var $location = $('#location');

$location.on('keyup', function(e) {
  clearTimeout(typingTimer);
  typingTimer = setTimeout(queryLocation, doneTypingInterval);
});

$location.on('keydown', function() {
  clearTimeout(typingTimer);
});

function queryLocation(urlParamLocation) {
  var queryingLocation = (urlParamLocation) ? urlParamLocation : $('#location').val();
  getLatLong(queryingLocation, function(discoveredLatLng) {
    replotMap(discoveredLatLng);
  });
}

function getLatLong(address, cb) {
  var tempCurrentPosition = {
    latitude: "",
    longitude: ""
  };
  geocoder.geocode({
    'address': address
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      tempCurrentPosition.latitude = results[0].geometry.location.lat();
      tempCurrentPosition.longitude = results[0].geometry.location.lng();
      cb(tempCurrentPosition);
    }
  });
}

function replotMap(locationValue) {
  if (locationValue) {
    $.each(originalStores, function(index, thisLocale) {
      thisLocale.distance = getDistanceFromLatLon(locationValue.latitude, locationValue.longitude, thisLocale.latitude, thisLocale.longitude);
    });
    var sdCompliant = withinOneSD(originalStores, standardDeviation(originalStores));
    addMapMarkers(sdCompliant);
  }
}

function initialize() {
  var input = document.getElementById('location');
  var autocomplete = new google.maps.places.Autocomplete(input);
}

initialize();

function initializeMap() {
  var myLatlng = new google.maps.LatLng(39.768408, -86.157975);
  var mapOptions = {
    zoom: 7,
    center: myLatlng,
    scrollwheel: false,
    navigationControl: false,
    mapTypeControl: false,
    scaleControl: false,
    draggable: true,
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);
  plotAllMarkers();
}

initializeMap();

function plotAllMarkers() {
  removeExtraneousMarkers();
  $.each($('#locations-ul li'), function(index, store) {
    var thisStoreObj = {};
    thisStoreObj.Address = $(store).attr('address');
    thisStoreObj.latitude = $(store).attr('data-latitude');
    thisStoreObj.longitude = $(store).attr('data-longitude');
    thisStoreObj.Store = $(store).attr('data-store');
    thisStoreObj.distance = "";
    originalStores.push(thisStoreObj);
  });
  originalStores = originalStores.sort(compare);
  $.each(originalStores, function(index, thisStore) {
    if (thisStore.Store) {
      plotTableRow(thisStore);
    }
  });
  addMapMarkers(originalStores);
}

function addMapMarkers(arr, allArr) {
  removeExtraneousMarkers();
  deleteMarkers();
  var bounds = new google.maps.LatLngBounds();
  $.each(arr, function(index, thisLocation) {
    plotTableRow(thisLocation);
    var currentState = findState(thisLocation.Address);

    var currLatlng = new google.maps.LatLng(thisLocation.latitude, thisLocation.longitude);
    var marker = new google.maps.Marker({
      position: currLatlng,
      map: map,
      title: thisLocation.Store,
      state: currentState
    });

    markersArr.push(marker);
  });
  for (var i = 0; i < markersArr.length; i++) {
    bounds.extend(markersArr[i].getPosition());
  }
  map.fitBounds(bounds);

  adjustPlottedMarkersToBounds(markersArr);
}

function filterByState(stateMarkerArr) {
  $('#state-select').on('change', function() {
    var stateCode = $(this).val();
    $('.locations-table .locations-div').hide();
    $.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
      var addressText = $(thisLocation).find('h4').text();
      if (addressText.indexOf(stateCode) > -1) {
        $(thisLocation).show();
      }
    });
    clearMarkers();
    $.each(stateMarkerArr, function(index, thisStateMarker) {
      if (thisStateMarker.state == stateCode) {
        thisStateMarker.setMap(map);
      }
    });
  });
}

function adjustPlottedMarkersToBounds(allArr) {
  google.maps.event.addListener(map, 'bounds_changed', function() {
    removeExtraneousMarkers();
    var markersArrStateFilter = [];
    for (var i = 0; i < allArr.length; i++) {
      if (map.getBounds().contains(allArr[i].getPosition())) {
        // markers[i] in visible bounds
        markersArrStateFilter.push(allArr[i]);
        allArr[i].setMap(map);
        $.each(originalStores, function(index, thisStore) {
          if (thisStore.Store == allArr[i].title) {
            plotTableRow(thisStore, "filtered-location");
          }
        });
      } else {
        // markers[i] is not in visible bounds
        allArr[i].setMap(null);
      }
    }
    filterByState(markersArrStateFilter);
  });
};

function removeExtraneousMarkers() {
  $('.locations-div').remove()
  $('#state-select').val('').change();
}

// Sets the map on all markers in the array.
function setMapOnAll(map) {
  for (var i = 0; i < markersArr.length; i++) {
    markersArr[i].setMap(map);
  }
}

// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
  setMapOnAll(null);
}

function deleteMarkers() {
  clearMarkers();
  markersArr = [];
}

function findState(subStr) {
  if (subStr.indexOf('OH') > -1) {
    return 'OH';
  } else if (subStr.indexOf('IL') > -1) {
    return 'IL';
  } else if (subStr.indexOf('MO') > -1) {
    return 'MO';
  } else if (subStr.indexOf('MI') > -1) {
    return 'MI';
  } else if (subStr.indexOf('IN') > -1) {
    return 'IN';
  }
}

function plotTableRow(thisStore, addedClass) {
  $('.locations-table').append('<div class="columns small-12 medium-6 locations-div ' + addedClass + '"><div class="row"><div class="columns small-3"><img src="https://cdn1.iconfinder.com/data/icons/mirrored-twins-icon-set-hollow/512/PixelKit_point_marker_icon.png"></div><div class="columns small-9"><h3>Marker</h3><h4>' + thisStore.Address + '</h4></div></div></div>');
};

附录代码:

function compare(a, b) {
  if (a.distance < b.distance)
    return -1;
  if (a.distance > b.distance)
    return 1;
  return 0;
}

function getDistanceFromLatLon(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2 - lat1); // deg2rad below
  var dLon = deg2rad(lon2 - lon1);
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c; // Distance in km
  return getMiles(d);
}

function deg2rad(deg) {
  return deg * (Math.PI / 180)
}
//converts to miles
function getMiles(i) {
  return i * 0.621371192;
}

function withinOneSD(arr, sd) {
  var tempArr = [];
  var arrMax = Math.max.apply(Math, numArr);
  var arrMin = Math.min.apply(Math, numArr);
  $.each(arr, function(index, currValue) {
    if (currValue.distance <= (arrMin + sd)) {
      tempArr.push(currValue);
    }
  });
  return tempArr;
}
var numArr;

function standardDeviation(values) {
  numArr = [];
  $.each(values, function(index, currentValue) {
    numArr.push(currentValue.distance);
  })
  var avg = average(numArr);

  var squareDiffs = numArr.map(function(value) {
    var diff = value - avg;
    var sqrDiff = diff * diff;
    return sqrDiff;
  });

  var avgSquareDiff = average(squareDiffs);

  var stdDev = Math.sqrt(avgSquareDiff);
  return stdDev;
}

function average(data) {
  var sum = data.reduce(function(sum, value) {
    return sum + value;
  }, 0);

  var avg = sum / data.length;
  return avg;
}

在这里查看:http://codepen.io/maudulus/pen/oxNXod

最佳答案

一个问题是此代码仅显示标记,如果标记与状态不匹配则不会隐藏它们,看起来 clearMarkers 没有按照您的想法进行操作:

function filterByState(stateMarkerArr) {
  $('#state-select').on('change', function() {
    var stateCode = $(this).val();
    $('.locations-table .locations-div').hide();
    $.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
      var addressText = $(thisLocation).find('h4').text();
      if (addressText.indexOf(stateCode) > -1) {
        $(thisLocation).show();
      }
    });
    clearMarkers();
    $.each(stateMarkerArr, function(index, thisStateMarker) {
      if (thisStateMarker.state == stateCode) {
        thisStateMarker.setMap(map);
      } 
    });
  });
}

if (thisStateMarker.state == stateCode) {

添加 else
function filterByState(stateMarkerArr) {
  $('#state-select').on('change', function() {
    var stateCode = $(this).val();
    $('.locations-table .locations-div').hide();
    $.each($('.locations-table .locations-div.filtered-location'), function(index, thisLocation) {
      var addressText = $(thisLocation).find('h4').text();
      if (addressText.indexOf(stateCode) > -1) {
        $(thisLocation).show();
      }
    });
    clearMarkers();
    $.each(stateMarkerArr, function(index, thisStateMarker) {
      if (thisStateMarker.state == stateCode) {
        thisStateMarker.setMap(map);
      } else {
        thisStateMarker.setMap(null);
      }
    });
  });
}

关于javascript - 按州过滤标记并结合地点自动完成功能 - Google Maps JavaScript API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35660222/

相关文章:

jquery - 使用 jQuery 删除逗号后的所有字符

objective-c - 如何在 Objective c 中沿坐标平滑移动 GMSMarker

javascript - 如何修复谷歌地图上的标记并移动 map ?

Javascript View HTML 切换

javascript - angularjs想要的打印布局不正确

javascript - jQuery SlideDown 和 Border - 奇怪的跳转

javascript - 如何使用jquery直接打印<i>标签

javascript - select2 正确显示粗体文本,但在键入时,粗体变成了 html 标签

javascript - jquery hover 只适用于点击事件?

javascript - 谷歌地图 - 如何获得以米为单位的两点之间的距离?