Google Maps: Resetting Markers with Coordinates

2020-05-09 17:12发布

问题:

I'm working on a Google Maps API program that provides a nearbySearch function based on longitude and latitude, and user given locations. It works almost exactly as intended, but there's one final part that I've been having a lot of trouble with, and that's resetting the markers. Here's a screenshot of the code when initially ran, the search works as intended, you can see the results to the right, and there's a section showing user locations (orange markers) and the number of users tied to these locations:

But when the user enters a latitude and longitude, the map will update, but nothing else will.

Something that I thought may help, and seems like it could've been close was setting an if else statement for the initMap function, and having an onclick function from the submit button change it to false, thus changing the starting lat & lng with the user lat & lng:

function initMap() {
// Create the map.
if (true)
var SHU = {
lat: lat,
lng: lng
}
else {
  var SHU = {
  lat: newLatlat,
  lng: newLng
}};

But messing with the onclick function of submit just ended up ruining other aspects of the code, so I come asking for help. Here's the code, and it should run without issue, but you may need an API key of your own.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Base Mapper</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1">

<style id="compiled-css" type="text/css">
#map {
height: 100%;
}

html,
body {
height: 100%;
margin: 0;
padding-top: 10px;
padding-left: 10px;
padding-right: 10px;
background-color: #ffd1b2
}

#right-panel {
font-family: 'Roboto', 'sans-serif';
line-height: 30px;
padding-left: 10px;
}

#right-panel select,
#right-panel input {
font-size: 15px;
}

#right-panel select {
width: 100%;
}

#right-panel i {
font-size: 12px;
}

#right-panel {
font-family: Arial, Helvetica, sans-serif;
position: absolute;
right: 5px;
top: 60%;
margin-top: -395px;
height: 650px;
width: 200px;
padding: 10px;
padding-left: 10px;
z-index: 10;
border: 1px solid #999;
background: #fff;
}

h2 {
font-size: 23px;
margin: 0 0 5px 0;
}

ul {
list-style-type: none;
padding: 0;
margin: 0;
height: 580px;
width: 200px;
overflow-y: scroll;
}

li {
background-color: #ffc965;
padding: 5px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

li:nth-child(odd) {
background-color: #fff065;
}

#more {
width: 100%;
margin: 5px 0 0 0;
}

input[type=text],
select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
background-color: #ffefe5
}

.container {
border-radius: 5px;
background-color: #ffd1b2
padding: 80px;
width: 80%
}
button {
width: 100%;
background-color: #8f20b6;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}

button:hover {
background-color: #cba00d;
}
table {
width: 100%;
background-color: #8f20b6;
color: white;
padding: 25px 0px;
margin: 8px 0;
border: none;
cursor: pointer;
}

</style>
</head>
<body>
<div class="container">
<form id="mapCenterForm" action="" onsubmit="return false;">
<label for="latitude">lat</label>
<input type="text" id="lat" name="latitude" placeholder="0.000000">

<label for="longitude">lng</label>
<input type="text" id="lng" name="longitude" placeholder="0.000000">
<br>
<button onclick="change_center(); return false">
Submit
</button>
</form>
<div id="map" style="height: 500px"></div>

</div>
<div id="right-panel">
<h2>Locations</h2>
<div id="number_results"></div>
<ul id="places"></ul>
<button id="more">More Results</button>
</div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIza...&callback=initMap" async defer></script>

<script type="text/javascript">


var blue_icon = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
var orange_icon = 'http://maps.google.com/mapfiles/ms/icons/orange-dot.png';
var map;
var lat = 41.18076;
var lng = -73.20537;
var userLoc = 0;
var userCount = 0;
var stopper = 1;

function initMap() {
// Create the map.
if (true)
var SHU = {
lat: lat,
lng: lng
}
else {
  var SHU = {
  lat: newLatlat,
  lng: newLng
}};
map = new google.maps.Map(document.getElementById('map'), {
center: SHU,
zoom: 13
});

google.maps.event.addListener(map, 'click', function(e) {
document.getElementById('lat').value = e.latLng.lat();
document.getElementById('lng').value = e.latLng.lng();
})

// Create the places service.
var service = new google.maps.places.PlacesService(map);
var getNextPage = null;
var moreButton = document.getElementById('more');
moreButton.onclick = function() {
moreButton.disabled = true;
if (getNextPage) getNextPage();
};

service.nearbySearch({
location: SHU,
radius: 4000,
keyword: "(library) OR (hospital)"
},

function(results, status, pagination) {
if (status !== 'OK') return;

createMarkers(results);
moreButton.disabled = !pagination.hasNextPage;
getNextPage = pagination.hasNextPage && function() {
pagination.nextPage();
};
});
}

function createMarkers(places) {
  var harry = new google.maps.Marker({
      position: {lat: 41.18076, lng: -73.20537},
      map: map,
      icon: orange_icon,
      title: 'Harry & Martha Richardson'
    })
      if (((lat>40.78076&&lat<41.58076)||(lng>-73.60537&&lng<-72.80537))&&(stopper==1))
      { userLoc = userLoc+1
        userCount = userCount+2 };
  var Maria = new google.maps.Marker({
      position: {lat: 41.14055, lng: -73.26827},
      map: map,
      icon: orange_icon,
      title: 'Maria Blane'
    })
      if (((lat>40.74055&&lat<41.54055)||(lng>-74.00537&&lng<-73.20537))&&(stopper==1))
      { userLoc = userLoc+1
        userCount = userCount+1};
  var Kent = new google.maps.Marker({
      position: {lat: 41.19613, lng: -73.21837},
      map: map,
      icon: orange_icon,
      title: 'Kent, Pedro, Natasha'
    })
      if (((lat>40.79613&&lat<41.59613)||(lng>-73.61837&&lng<-72.81837))&&(stopper==1))
        { userLoc = userLoc+1
          userCount = userCount+3 };
  var DummyVar1 = new google.maps.Marker({
      position: {lat: 38.897957, lng: -77.036560},
      map: map,
      icon: orange_icon,
      title: 'Dummy Name'
    })
      if (((lat>38.497957&&lat<39.297957)||(lng>-77.43656&&lng<-76.63656))&&(stopper==1))
        { userLoc = userLoc+1
          userCount = userCount+100 };
  var DummyVar2 = new google.maps.Marker({
      position: {lat: 36.056595, lng: -112.125092},
      map: map,
      icon: orange_icon,
      title: 'Dummier Name'
    })
      if ((lat>35.656595&&lat<36.456595)||(lng>-112.525092&&lng<-111.725092))
        { userLoc = userLoc+1
          userCount = userCount+100
          };
    { stopper = 0 };
var bounds = new google.maps.LatLngBounds();
var placesList = document.getElementById('places');

for (var i = 0, place; place = places[i]; i++) {
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};

var marker = new google.maps.Marker({
map: map,
icon: blue_icon,
title: place.name,
position: place.geometry.location
});

var li = document.createElement('li');
li.textContent = place.name;
placesList.appendChild(li);
document.getElementById('number_results').innerHTML = placesList.children.length + " returned";
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
document.getElementById("val").innerHTML = "Based on your latitude of " + lat + " and longitude of " + lng +
", the total places found is: " + (document.getElementById('places').children.length) + ". User locations: " + userLoc + ". Total users: " + userCount + ".";
}
function change_center() {
var newLat = parseFloat(document.getElementById("lat").value);
var newLng = parseFloat(document.getElementById("lng").value);

map.setCenter({
lat: newLat,
lng: newLng
});
return false;
}

</script>

<script>
// tell the embed parent frame the height of the content
if (window.parent && window.parent.parent){
window.parent.parent.postMessage(["resultsFrame", {
height: document.body.getBoundingClientRect().height,
slug: "r96szuhx"
}], "*")
}

// always overwrite window.name, in case users try to set it manually
window.name = "result"
</script>

<table>
<tr>
<th id="val"></th>
</tr>
</table>
</body>
</html>

回答1:

You need to re-run the query when the map center changes. I would suggest putting that query into a function you can call both places (and tracking the markers so you can remove them when you start a new query):

function nearbySearch() {
  document.getElementById('places').innerHTML = "";
  for (var i=0; i<markers.length;i++) {
    markers[i].setMap(null);
  }
  markers = [];
  // Create the places service.
  var service = new google.maps.places.PlacesService(map);
  var getNextPage = null;
  var moreButton = document.getElementById('more');
  moreButton.onclick = function() {
    moreButton.disabled = true;
    if (getNextPage) getNextPage();
  };

  service.nearbySearch({
    location: map.getCenter(),
    radius: 4000,
    keyword: "(library) OR (hospital)"
  },

  function(results, status, pagination) {
    if (status !== 'OK') return;

    createMarkers(results);
    moreButton.disabled = !pagination.hasNextPage;
    getNextPage = pagination.hasNextPage && function() {
      pagination.nextPage();
    };
  });
}

working code snippet:

#map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding-top: 10px;
  padding-left: 10px;
  padding-right: 10px;
  background-color: #ffd1b2
}

#right-panel {
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

#right-panel select,
#right-panel input {
  font-size: 15px;
}

#right-panel select {
  width: 100%;
}

#right-panel i {
  font-size: 12px;
}

#right-panel {
  font-family: Arial, Helvetica, sans-serif;
  position: absolute;
  right: 5px;
  top: 60%;
  margin-top: -395px;
  height: 650px;
  width: 200px;
  padding: 10px;
  padding-left: 10px;
  z-index: 10;
  border: 1px solid #999;
  background: #fff;
}

h2 {
  font-size: 23px;
  margin: 0 0 5px 0;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  height: 580px;
  width: 200px;
  overflow-y: scroll;
}

li {
  background-color: #ffc965;
  padding: 5px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

li:nth-child(odd) {
  background-color: #fff065;
}

#more {
  width: 100%;
  margin: 5px 0 0 0;
}

input[type=text],
select {
  width: 100%;
  padding: 12px 20px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  background-color: #ffefe5
}

.container {
  border-radius: 5px;
  background-color: #ffd1b2 padding: 80px;
  width: 80%
}

button {
  width: 100%;
  background-color: #8f20b6;
  color: white;
  padding: 14px 20px;
  margin: 8px 0;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #cba00d;
}

table {
  width: 100%;
  background-color: #8f20b6;
  color: white;
  padding: 25px 0px;
  margin: 8px 0;
  border: none;
  cursor: pointer;
}
<div class="container">
  <form id="mapCenterForm" action="" onsubmit="return false;">
    <label for="latitude">lat</label>
    <input type="text" id="lat" name="latitude" placeholder="0.000000">

    <label for="longitude">lng</label>
    <input type="text" id="lng" name="longitude" placeholder="0.000000">
    <br>
    <button onclick="change_center(); return false">
Submit
</button>
  </form>
  <div id="map" style="height: 500px"></div>

</div>
<div id="right-panel">
  <h2>Locations</h2>
  <div id="number_results"></div>
  <ul id="places"></ul>
  <button id="more">More Results</button>
</div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>

<script type="text/javascript">
  var blue_icon = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
  var orange_icon = 'http://maps.google.com/mapfiles/ms/icons/orange-dot.png';
  var map;
  var lat = 41.18076;
  var lng = -73.20537;
  var userLoc = 0;
  var userCount = 0;
  var stopper = 1;
  var markers = [];

  function initMap() {
    // Create the map.
    var SHU = {
      lat: lat,
      lng: lng
    }
    map = new google.maps.Map(document.getElementById('map'), {
      center: SHU,
      zoom: 13
    });

    google.maps.event.addListener(map, 'click', function(e) {
      document.getElementById('lat').value = e.latLng.lat();
      document.getElementById('lng').value = e.latLng.lng();
    })

    nearbySearch();
  }

  function createMarkers(places) {
    var harry = new google.maps.Marker({
      position: {
        lat: 41.18076,
        lng: -73.20537
      },
      map: map,
      icon: orange_icon,
      title: 'Harry & Martha Richardson'
    })
    if (((lat > 40.78076 && lat < 41.58076) || (lng > -73.60537 && lng < -72.80537)) && (stopper == 1)) {
      userLoc = userLoc + 1
      userCount = userCount + 2
    };
    var Maria = new google.maps.Marker({
      position: {
        lat: 41.14055,
        lng: -73.26827
      },
      map: map,
      icon: orange_icon,
      title: 'Maria Blane'
    })
    if (((lat > 40.74055 && lat < 41.54055) || (lng > -74.00537 && lng < -73.20537)) && (stopper == 1)) {
      userLoc = userLoc + 1
      userCount = userCount + 1
    };
    var Kent = new google.maps.Marker({
      position: {
        lat: 41.19613,
        lng: -73.21837
      },
      map: map,
      icon: orange_icon,
      title: 'Kent, Pedro, Natasha'
    })
    if (((lat > 40.79613 && lat < 41.59613) || (lng > -73.61837 && lng < -72.81837)) && (stopper == 1)) {
      userLoc = userLoc + 1
      userCount = userCount + 3
    };
    var DummyVar1 = new google.maps.Marker({
      position: {
        lat: 38.897957,
        lng: -77.036560
      },
      map: map,
      icon: orange_icon,
      title: 'Dummy Name'
    })
    if (((lat > 38.497957 && lat < 39.297957) || (lng > -77.43656 && lng < -76.63656)) && (stopper == 1)) {
      userLoc = userLoc + 1
      userCount = userCount + 100
    };
    var DummyVar2 = new google.maps.Marker({
      position: {
        lat: 36.056595,
        lng: -112.125092
      },
      map: map,
      icon: orange_icon,
      title: 'Dummier Name'
    })
    if ((lat > 35.656595 && lat < 36.456595) || (lng > -112.525092 && lng < -111.725092)) {
      userLoc = userLoc + 1
      userCount = userCount + 100
    }; {
      stopper = 0
    };
    var bounds = new google.maps.LatLngBounds();
    var placesList = document.getElementById('places');

    for (var i = 0, place; place = places[i]; i++) {
      var image = {
        url: place.icon,
        size: new google.maps.Size(71, 71),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(17, 34),
        scaledSize: new google.maps.Size(25, 25)
      };

      var marker = new google.maps.Marker({
        map: map,
        icon: blue_icon,
        title: place.name,
        position: place.geometry.location
      });
      markers.push(marker);

      var li = document.createElement('li');
      li.textContent = place.name;
      placesList.appendChild(li);
      document.getElementById('number_results').innerHTML = placesList.children.length + " returned";
      bounds.extend(place.geometry.location);
    }
    map.fitBounds(bounds);
    document.getElementById("val").innerHTML = "Based on your latitude of " + lat + " and longitude of " + lng +
      ", the total places found is: " + (document.getElementById('places').children.length) + ". User locations: " + userLoc + ". Total users: " + userCount + ".";
  }

  function change_center() {
    var newLat = parseFloat(document.getElementById("lat").value);
    var newLng = parseFloat(document.getElementById("lng").value);

    map.setCenter({
      lat: newLat,
      lng: newLng
    });
    nearbySearch();
    return false;
  }

  function nearbySearch() {
    document.getElementById('places').innerHTML = "";
    for (var i=0; i<markers.length;i++) {
      markers[i].setMap(null);
    }
    markers = [];
    // Create the places service.
    var service = new google.maps.places.PlacesService(map);
    var getNextPage = null;
    var moreButton = document.getElementById('more');
    moreButton.onclick = function() {
      moreButton.disabled = true;
      if (getNextPage) getNextPage();
    };

    service.nearbySearch({
        location: map.getCenter(),
        radius: 4000,
        keyword: "(library) OR (hospital)"
      },

      function(results, status, pagination) {
        if (status !== 'OK') return;

        createMarkers(results);
        moreButton.disabled = !pagination.hasNextPage;
        getNextPage = pagination.hasNextPage && function() {
          pagination.nextPage();
        };
      });
  }
</script>

<table>
  <tr>
    <th id="val"></th>
  </tr>
</table>