如何使用 google 地图 API 制作一个在特定半径范围内搜索项目的表单?
How to make a form which searches an item around a specific radius using google maps API?
我正在制作一个 website,我想在 google 地图上围绕当前位置或某个人工地址画一个圆圈。
用户可以选择是否要围绕当前位置或他们将提供的某个随机地址做圆。 (用户可以选择将手动地址放入当前位置,如下图所示)
现在我们还需要确保圆的半径是特定的(距当前位置0-20/70km),用户需要也决定那个。 (当前位置下方的线将决定用户可以在这里和那里移动的半径0-70km)
例如:用户想要创建一个从当前位置到 30KM 的圆圈,或者用户想要创建一个从某个随机地址到 20KM 的圆圈。
我用来制作搜索半径搜索栏的HTML代码是:
<div class="input-searchradius">
<input class="form-control search_radius mb-4" type="text" placeholder="search radius">
</div>
问题陈述:
(1) 我想知道我需要进行哪些更改 或需要添加哪些代码 以便搜索项目围绕一个特定的半径。我想,我需要整合代码 Google Maps circle 但我不确定我该怎么做。
(2) 在 website 上点击搜索半径后,以下 options/screen 将出现在底部:
让我们试着给你一些第一步,我不会编写整个应用程序的代码,而是给你一些指导方针来解决你遇到的小问题:
在地图中添加圆圈
嗯,为此你有很多不同的输入选项,但最重要的部分是 addCircle 函数:
function addCircle(center){
circle = new google.maps.Circle({
map: map, //The existing map
center: center,
radius: 200, //This will be modified afterwards
zindex: 100
});
}
中心可以来自 click 例如:
// Area is wherever you want to attach the click, either a polygon, a map...
google.maps.event.addListener(area, "click", function(event) {
addCircle(event.latLng);
});
或通过获取某个地址的位置(This is documented as well),或任何方法(拖放圆圈,拖动标记 blablabla)
添加动态半径
好吧,如果我们知道 the radius of the Circle is given in meters,那么就很容易为 addCircle 函数提供正确的半径。例如,20 公里 -> 20 000 米。所以你只需要在调用 addCircle 时能够访问半径(它可以是一个参数,一个全局变量......你的选择)。
绘图部分已经完成,现在让我们在圆圈内搜索。
只获取圆圈内的标记
这里有一个先决条件,要有你地图上的所有标记。您可能有一系列从数据库中获得的地点,或者您可能 get the markers from Google Maps API(例如地点搜索)。
之后你将不得不计算这些标记和你给定的中心之间的距离,并检查距离是否小于你的半径(使用 computeDistanceBetween 很容易),所以你会知道哪些标记对你有效。
const markers = [//array of my valid markers with position];
markers.filter( (marker) =>
google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), center.getPosition()) < radius; // Filter the markers which distance is bigger than radius;
剩下的工作应该很简单,place the markers in the map 并根据这些信息做任何您想做的事。
额外内容
作为进一步的帮助,有一对 examples/answers 可能对您有用:
Full Google Map API example,非常简单的分步指南。
Radius search using places,关于如何进行半径搜索的一个很好的答案。
Example of radius search,喜欢的话打开F12调试代码,其实很容易跟上
编辑**:我没有意识到其中 2 个 link 在评论中也指出了。
我建议使用工作线程进行搜索,以通过在后台进行搜索来释放 UI 线程。如果用户移动圆圈或 expands/contracts 它也很有用,因为可以放弃之前的 search/render 匹配标记,
importScripts("Tier3Toolbox.js");
var currVintage = 0;
var inBounds = false;
var facFilter = [];
var imageProlog = "<div style='height:5em; width:5em; display:inline-block;vertical-align:middle;'>" +
"<img style='height:100%; width: 100%; max-height:100%; max-width:100%' src='";
var imageEpilog = "' ></div>";
var facilityTable, lineBreak;
self.addEventListener('message', function(e)
{
var data = e.data;
switch (data.cmd) {
case 'init':
initThread(data.load);
break;
case 'initFilter':
for (var i=0; i<data.filterTable.length; i++) {
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'filter':
facFilter = [];
for (var i=0; i<data.filterTable.length; i++) {
if (data.filterTable[i].facSelected)
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'search':
var searchVintage = ++currVintage;
var tableSearch = new searcher(searchVintage, data);
break;
case 'reset':
reset();
self.postMessage({'reset': true});
break;
case 'stop':
self.postMessage({'success' : true});
self.close();
break;
default:
self.postMessage({'success' : false, 'msg' : data.msg});
};
}, false);
function initThread(msg)
{
facilityTable = JSON.parse(msg);
reset();
self.postMessage({'success' : true,
'cnt' : facilityTable.length
});
}
function reset()
{
for (var i=0; i<facilityTable.length; i++) {
facilityTable[i].visible=false
}
currVintage = 0;
}
function searcher(searchVintage, msg)
{
var myVintage = searchVintage;
var facIndex = -1;
var msg = msg;
var checkLoop = function()
{
if (myVintage != currVintage)
return;
if (++facIndex == facilityTable.length)
return;
inBounds = geoFencer.call(this, msg);
if (inBounds) {
var facMatch = 0;
var bubbleHTML = "";
for (var i=0; i<facilityTable[facIndex].facilities.length; i++){
var currFac = facilityTable[facIndex].facilities[i];
if (facFilter[currFac.locTypeId] != undefined) {
if (facMatch != 0) {
lineBreak = (facMatch / 3);
if (lineBreak == lineBreak.toFixed(0)) {
bubbleHTML += "<br />";
}
}
facMatch++;
bubbleHTML += imageProlog + facFilter[currFac.locTypeId].icon + imageEpilog;
}
}
if (facMatch == 0) {
inBounds = false;
}
}
if (inBounds != facilityTable[facIndex].visible) {
self.postMessage({'match' : inBounds,
'facIndex' : facIndex,
'scopeVintage': msg.scopeVintage,
'bubbleHTML' : bubbleHTML,
'success' : true
});
facilityTable[facIndex].visible = inBounds;
}
setTimeout(checkLoop,0);
}
var circleCheck = function(msg)
{
var diff = Tier3Toolbox.calculateDistance(
msg.centerLat,
msg.centerLng,
facilityTable[facIndex].searchLat,
facilityTable[facIndex].searchLng);
if (msg.radius > diff)
return true;
return false;
}
var rectangleCheck = function(msg)
{
if (facilityTable[facIndex].searchLat > msg.SWLat &&
facilityTable[facIndex].searchLat < msg.NELat &&
facilityTable[facIndex].searchLng > msg.SWLng &&
facilityTable[facIndex].searchLng < msg.NELng)
return true;
return false;
}
var GEOFENCER = [circleCheck,rectangleCheck];
var geoFencer = GEOFENCER[msg.checker];
setTimeout(checkLoop,0);
return this;
}
提到的"Toolbox"函数是:-
function Tier3Toolbox()
{
return this;
}
Tier3Toolbox.EARTH_RADIUS = 6378137; /* Equitorial Radius instead of 6371000 */
Tier3Toolbox.toRad =
function (num) {
return num * Math.PI / 180;
};
Tier3Toolbox.calculateDistance =
function(lat1, lon1, lat2, lon2){
var dLat = this.toRad(lat2 - lat1);
var dLon = this.toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) *
Math.cos(this.toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var distance = this.EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return distance;
}
Tier3Toolbox.prototype.callAJAX =
function(url, method, callback, serverArgs)
{
var callback = callback;
var xmlhttp;
var target = url;
var args = (serverArgs != undefined) ? serverArgs : "";
var postArgs = "";
var callbackArgs = new Array();
for (i = 4; i < arguments.length; i++) {
callbackArgs[i - 3] = arguments[i];
}
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
callbackArgs[0] = xmlhttp;
if (method.toUpperCase() == "GET") {
target = target + "?" + args;
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
callback.apply(this, callbackArgs)
} else {
throw new Error("Error making Ajax call to " + target + " Status = " + xmlhttp.status);
}
}
};
xmlhttp.open(method, url, true);
if (method.toUpperCase() == "POST") {
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
postArgs = args;
}
xmlhttp.send(postArgs);
}
Tier3Toolbox.reportError =
function(error)
{
var header = error.header || "Error";
var message = error.message || "";
var topWindow=window.top.document.open();
topWindow.write("<!DOCTYPE html><html><body style='height: 100%;'><hr><h1>" + header + "</h1><hr>");
topWindow.write("<h2>Please contact Server Support for assistance.</h2><br />");
topWindow.write('<p style="color:red">' + message + "</p></body></html>");
topWindow.close();
return;
}
在您的主线中,您需要添加如下侦听器:-
google.maps.event.addDomListener(radarCircle, 'center_changed', reScope);
google.maps.event.addDomListener(radarCircle, 'radius_changed', reScope);
google.maps.event.addDomListener(radarRectangle, 'bounds_changed', reScope);
function createFacilityMarkers(xmlhttp){
facFinder = new Worker("facfinder.js");
facFinder.addEventListener('message', workerInit, false);
facFinder.postMessage({'cmd' : 'init', 'load' : xmlhttp.responseText});
}
function reScope() {
var searchReq = {'cmd':'search', 'scopeVintage':scopeVintage};
if (radarShape.getCenter) {
searchReq.checker = 0;
var currCenter = radarCircle.getCenter();
searchReq.centerLat = currCenter.lat();
searchReq.centerLng = currCenter.lng();
searchReq.radius = radarCircle.getRadius();
} else {
searchReq.checker = 1;
searchReq.SWLat = radarShape.getBounds().getSouthWest().lat();
searchReq.SWLng = radarShape.getBounds().getSouthWest().lng();
searchReq.NELat = radarShape.getBounds().getNorthEast().lat();
searchReq.NELng = radarShape.getBounds().getNorthEast().lng();
}
facFinder.postMessage(searchReq);
}
HTH
干杯理查德
这里遵循@SirPeople 的建议是解决您的核心问题陈述的完整代码,即从用户那里获取位置输入、更新地图并在其周围设置动态半径。
这里是JSFiddlelinkhttps://jsfiddle.net/innamhunzai/63vcthp7/3/
JS:
var circle;
var map;
function initMap() {
var centerCoordinates = new google.maps.LatLng(37.6, -95.665);
map = new google.maps.Map(document.getElementById('map'), {
center: centerCoordinates,
zoom: 4
});
var card = document.getElementById('pac-card');
var input = document.getElementById('pac-input');
var infowindowContent = document.getElementById('infowindow-content');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
infowindow.setContent(infowindowContent);
var marker = new google.maps.Marker({
map: map
});
circle = new google.maps.Circle({
map: map,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
});
autocomplete.addListener('place_changed', function() {
document.getElementById("location-error").style.display = 'none';
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
document.getElementById("location-error").style.display = 'inline-block';
document.getElementById("location-error").innerHTML = "Cannot Locate '" + input.value + "' on map";
return;
}
map.fitBounds(place.geometry.viewport);
marker.setPosition(place.geometry.location);
circle.setCenter(place.geometry.location);
marker.setVisible(true);
circle.setVisible(true);
infowindowContent.children['place-icon'].src = place.icon;
infowindowContent.children['place-name'].textContent = place.name;
infowindowContent.children['place-address'].textContent = input.value;
infowindow.open(map, marker);
});
}
function updateRadius() {
circle.setRadius(document.getElementById('radius').value * 1609.34);
map.fitBounds(circle.getBounds());
}
**CSS:**
#map {
height: 400px;
}
**HTML**
<html>
<link href="style.css" rel="stylesheet" type="text/css">
<body>
<div class="pac-card" id="pac-card">
<div>
<div id="label">
Location search
</div>
</div>
<div id="pac-container">
<input id="pac-input" type="text" placeholder="Enter a location">
<div id="location-error"></div>
</div>
<div>
<input type="range" id="radius" name="radius" min="0" max="100" onchange="updateRadius()">
</div>
</div>
<div id="map"></div>
<div id="infowindow-content">
<img src="" width="16" height="16" id="place-icon">
<span id="place-name" class="title"></span><br>
<span id="place-address"></span>
</div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initMap"
async defer></script>
</body>
</html>
我正在制作一个 website,我想在 google 地图上围绕当前位置或某个人工地址画一个圆圈。
用户可以选择是否要围绕当前位置或他们将提供的某个随机地址做圆。 (用户可以选择将手动地址放入当前位置,如下图所示)
现在我们还需要确保圆的半径是特定的(距当前位置0-20/70km),用户需要也决定那个。 (当前位置下方的线将决定用户可以在这里和那里移动的半径0-70km)
例如:用户想要创建一个从当前位置到 30KM 的圆圈,或者用户想要创建一个从某个随机地址到 20KM 的圆圈。
我用来制作搜索半径搜索栏的HTML代码是:
<div class="input-searchradius">
<input class="form-control search_radius mb-4" type="text" placeholder="search radius">
</div>
问题陈述:
(1) 我想知道我需要进行哪些更改 或需要添加哪些代码 以便搜索项目围绕一个特定的半径。我想,我需要整合代码 Google Maps circle 但我不确定我该怎么做。
(2) 在 website 上点击搜索半径后,以下 options/screen 将出现在底部:
让我们试着给你一些第一步,我不会编写整个应用程序的代码,而是给你一些指导方针来解决你遇到的小问题:
在地图中添加圆圈
嗯,为此你有很多不同的输入选项,但最重要的部分是 addCircle 函数:
function addCircle(center){
circle = new google.maps.Circle({
map: map, //The existing map
center: center,
radius: 200, //This will be modified afterwards
zindex: 100
});
}
中心可以来自 click 例如:
// Area is wherever you want to attach the click, either a polygon, a map...
google.maps.event.addListener(area, "click", function(event) {
addCircle(event.latLng);
});
或通过获取某个地址的位置(This is documented as well),或任何方法(拖放圆圈,拖动标记 blablabla)
添加动态半径
好吧,如果我们知道 the radius of the Circle is given in meters,那么就很容易为 addCircle 函数提供正确的半径。例如,20 公里 -> 20 000 米。所以你只需要在调用 addCircle 时能够访问半径(它可以是一个参数,一个全局变量......你的选择)。
绘图部分已经完成,现在让我们在圆圈内搜索。
只获取圆圈内的标记
这里有一个先决条件,要有你地图上的所有标记。您可能有一系列从数据库中获得的地点,或者您可能 get the markers from Google Maps API(例如地点搜索)。
之后你将不得不计算这些标记和你给定的中心之间的距离,并检查距离是否小于你的半径(使用 computeDistanceBetween 很容易),所以你会知道哪些标记对你有效。
const markers = [//array of my valid markers with position];
markers.filter( (marker) =>
google.maps.geometry.spherical.computeDistanceBetween(marker.getPosition(), center.getPosition()) < radius; // Filter the markers which distance is bigger than radius;
剩下的工作应该很简单,place the markers in the map 并根据这些信息做任何您想做的事。
额外内容
作为进一步的帮助,有一对 examples/answers 可能对您有用:
Full Google Map API example,非常简单的分步指南。
Radius search using places,关于如何进行半径搜索的一个很好的答案。
Example of radius search,喜欢的话打开F12调试代码,其实很容易跟上
编辑**:我没有意识到其中 2 个 link 在评论中也指出了。
我建议使用工作线程进行搜索,以通过在后台进行搜索来释放 UI 线程。如果用户移动圆圈或 expands/contracts 它也很有用,因为可以放弃之前的 search/render 匹配标记,
importScripts("Tier3Toolbox.js");
var currVintage = 0;
var inBounds = false;
var facFilter = [];
var imageProlog = "<div style='height:5em; width:5em; display:inline-block;vertical-align:middle;'>" +
"<img style='height:100%; width: 100%; max-height:100%; max-width:100%' src='";
var imageEpilog = "' ></div>";
var facilityTable, lineBreak;
self.addEventListener('message', function(e)
{
var data = e.data;
switch (data.cmd) {
case 'init':
initThread(data.load);
break;
case 'initFilter':
for (var i=0; i<data.filterTable.length; i++) {
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'filter':
facFilter = [];
for (var i=0; i<data.filterTable.length; i++) {
if (data.filterTable[i].facSelected)
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'search':
var searchVintage = ++currVintage;
var tableSearch = new searcher(searchVintage, data);
break;
case 'reset':
reset();
self.postMessage({'reset': true});
break;
case 'stop':
self.postMessage({'success' : true});
self.close();
break;
default:
self.postMessage({'success' : false, 'msg' : data.msg});
};
}, false);
function initThread(msg)
{
facilityTable = JSON.parse(msg);
reset();
self.postMessage({'success' : true,
'cnt' : facilityTable.length
});
}
function reset()
{
for (var i=0; i<facilityTable.length; i++) {
facilityTable[i].visible=false
}
currVintage = 0;
}
function searcher(searchVintage, msg)
{
var myVintage = searchVintage;
var facIndex = -1;
var msg = msg;
var checkLoop = function()
{
if (myVintage != currVintage)
return;
if (++facIndex == facilityTable.length)
return;
inBounds = geoFencer.call(this, msg);
if (inBounds) {
var facMatch = 0;
var bubbleHTML = "";
for (var i=0; i<facilityTable[facIndex].facilities.length; i++){
var currFac = facilityTable[facIndex].facilities[i];
if (facFilter[currFac.locTypeId] != undefined) {
if (facMatch != 0) {
lineBreak = (facMatch / 3);
if (lineBreak == lineBreak.toFixed(0)) {
bubbleHTML += "<br />";
}
}
facMatch++;
bubbleHTML += imageProlog + facFilter[currFac.locTypeId].icon + imageEpilog;
}
}
if (facMatch == 0) {
inBounds = false;
}
}
if (inBounds != facilityTable[facIndex].visible) {
self.postMessage({'match' : inBounds,
'facIndex' : facIndex,
'scopeVintage': msg.scopeVintage,
'bubbleHTML' : bubbleHTML,
'success' : true
});
facilityTable[facIndex].visible = inBounds;
}
setTimeout(checkLoop,0);
}
var circleCheck = function(msg)
{
var diff = Tier3Toolbox.calculateDistance(
msg.centerLat,
msg.centerLng,
facilityTable[facIndex].searchLat,
facilityTable[facIndex].searchLng);
if (msg.radius > diff)
return true;
return false;
}
var rectangleCheck = function(msg)
{
if (facilityTable[facIndex].searchLat > msg.SWLat &&
facilityTable[facIndex].searchLat < msg.NELat &&
facilityTable[facIndex].searchLng > msg.SWLng &&
facilityTable[facIndex].searchLng < msg.NELng)
return true;
return false;
}
var GEOFENCER = [circleCheck,rectangleCheck];
var geoFencer = GEOFENCER[msg.checker];
setTimeout(checkLoop,0);
return this;
}
提到的"Toolbox"函数是:-
function Tier3Toolbox()
{
return this;
}
Tier3Toolbox.EARTH_RADIUS = 6378137; /* Equitorial Radius instead of 6371000 */
Tier3Toolbox.toRad =
function (num) {
return num * Math.PI / 180;
};
Tier3Toolbox.calculateDistance =
function(lat1, lon1, lat2, lon2){
var dLat = this.toRad(lat2 - lat1);
var dLon = this.toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) *
Math.cos(this.toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var distance = this.EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return distance;
}
Tier3Toolbox.prototype.callAJAX =
function(url, method, callback, serverArgs)
{
var callback = callback;
var xmlhttp;
var target = url;
var args = (serverArgs != undefined) ? serverArgs : "";
var postArgs = "";
var callbackArgs = new Array();
for (i = 4; i < arguments.length; i++) {
callbackArgs[i - 3] = arguments[i];
}
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
callbackArgs[0] = xmlhttp;
if (method.toUpperCase() == "GET") {
target = target + "?" + args;
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
callback.apply(this, callbackArgs)
} else {
throw new Error("Error making Ajax call to " + target + " Status = " + xmlhttp.status);
}
}
};
xmlhttp.open(method, url, true);
if (method.toUpperCase() == "POST") {
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
postArgs = args;
}
xmlhttp.send(postArgs);
}
Tier3Toolbox.reportError =
function(error)
{
var header = error.header || "Error";
var message = error.message || "";
var topWindow=window.top.document.open();
topWindow.write("<!DOCTYPE html><html><body style='height: 100%;'><hr><h1>" + header + "</h1><hr>");
topWindow.write("<h2>Please contact Server Support for assistance.</h2><br />");
topWindow.write('<p style="color:red">' + message + "</p></body></html>");
topWindow.close();
return;
}
在您的主线中,您需要添加如下侦听器:-
google.maps.event.addDomListener(radarCircle, 'center_changed', reScope);
google.maps.event.addDomListener(radarCircle, 'radius_changed', reScope);
google.maps.event.addDomListener(radarRectangle, 'bounds_changed', reScope);
function createFacilityMarkers(xmlhttp){
facFinder = new Worker("facfinder.js");
facFinder.addEventListener('message', workerInit, false);
facFinder.postMessage({'cmd' : 'init', 'load' : xmlhttp.responseText});
}
function reScope() {
var searchReq = {'cmd':'search', 'scopeVintage':scopeVintage};
if (radarShape.getCenter) {
searchReq.checker = 0;
var currCenter = radarCircle.getCenter();
searchReq.centerLat = currCenter.lat();
searchReq.centerLng = currCenter.lng();
searchReq.radius = radarCircle.getRadius();
} else {
searchReq.checker = 1;
searchReq.SWLat = radarShape.getBounds().getSouthWest().lat();
searchReq.SWLng = radarShape.getBounds().getSouthWest().lng();
searchReq.NELat = radarShape.getBounds().getNorthEast().lat();
searchReq.NELng = radarShape.getBounds().getNorthEast().lng();
}
facFinder.postMessage(searchReq);
}
HTH
干杯理查德
这里遵循@SirPeople 的建议是解决您的核心问题陈述的完整代码,即从用户那里获取位置输入、更新地图并在其周围设置动态半径。
这里是JSFiddlelinkhttps://jsfiddle.net/innamhunzai/63vcthp7/3/
JS:
var circle;
var map;
function initMap() {
var centerCoordinates = new google.maps.LatLng(37.6, -95.665);
map = new google.maps.Map(document.getElementById('map'), {
center: centerCoordinates,
zoom: 4
});
var card = document.getElementById('pac-card');
var input = document.getElementById('pac-input');
var infowindowContent = document.getElementById('infowindow-content');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
infowindow.setContent(infowindowContent);
var marker = new google.maps.Marker({
map: map
});
circle = new google.maps.Circle({
map: map,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
});
autocomplete.addListener('place_changed', function() {
document.getElementById("location-error").style.display = 'none';
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
document.getElementById("location-error").style.display = 'inline-block';
document.getElementById("location-error").innerHTML = "Cannot Locate '" + input.value + "' on map";
return;
}
map.fitBounds(place.geometry.viewport);
marker.setPosition(place.geometry.location);
circle.setCenter(place.geometry.location);
marker.setVisible(true);
circle.setVisible(true);
infowindowContent.children['place-icon'].src = place.icon;
infowindowContent.children['place-name'].textContent = place.name;
infowindowContent.children['place-address'].textContent = input.value;
infowindow.open(map, marker);
});
}
function updateRadius() {
circle.setRadius(document.getElementById('radius').value * 1609.34);
map.fitBounds(circle.getBounds());
}
**CSS:**
#map {
height: 400px;
}
**HTML**
<html>
<link href="style.css" rel="stylesheet" type="text/css">
<body>
<div class="pac-card" id="pac-card">
<div>
<div id="label">
Location search
</div>
</div>
<div id="pac-container">
<input id="pac-input" type="text" placeholder="Enter a location">
<div id="location-error"></div>
</div>
<div>
<input type="range" id="radius" name="radius" min="0" max="100" onchange="updateRadius()">
</div>
</div>
<div id="map"></div>
<div id="infowindow-content">
<img src="" width="16" height="16" id="place-icon">
<span id="place-name" class="title"></span><br>
<span id="place-address"></span>
</div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initMap"
async defer></script>
</body>
</html>