Google Maps SearchBox不在边界内搜索

时间:2018-01-24 20:20:43

标签: google-maps-api-3

我在让谷歌的搜索框服务正常运行时遇到问题。

我所拥有的是一张绘有多边形的地图。我想使用搜索框和/或自动填充服务仅返回此多边形边界内指定类型的业务(例如餐馆,快餐店,仓库等)。

我可以使用附近服务根据类型或关键字返回结果。我也可以通过搜索框返回餐馆的结果;但是,如果我更新搜索以寻找其他商家,例如仓库,地图会缩小并显示全世界的仓库

这是一个工作小提琴的例子:

<html>
<head>
    <meta charset="utf-8">
    <title>Transition Center Online</title>
    <meta name="description" content="">
    <meta name="title" content="">
    <meta name="author" content="WWRF">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <style>
        #map {
            height: 600px;
            width: 100%;
        }
        #description {
            font-family: Roboto;
            font-size: 15px;
            font-weight: 300;
        }

        #infowindow-content .title {
            font-weight: bold;
        }

        #infowindow-content {
            display: none;
        }

        #map #infowindow-content {
            display: inline;
        }

        .pac-card {
            margin: 10px 10px 0 0;
            border-radius: 2px 0 0 2px;
            box-sizing: border-box;
            -moz-box-sizing: border-box;
            outline: none;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
            background-color: #fff;
            font-family: Roboto;
        }

        #pac-container {
            padding-bottom: 12px;
            margin-right: 12px;
        }

        .pac-controls {
            display: inline-block;
            padding: 5px 11px;
        }

        .pac-controls label {
            font-family: Roboto;
            font-size: 13px;
            font-weight: 300;
        }

        #pac-input {
            background-color: #fff;
            font-family: Roboto;
            font-size: 15px;
            font-weight: 300;
            margin-left: 12px;
            padding: 0 11px 0 13px;
            text-overflow: ellipsis;
            width: 400px;
        }

        #pac-input:focus {
            border-color: #4d90fe;
        }

        #title {
            color: #fff;
            background-color: #4d90fe;
            font-size: 25px;
            font-weight: 500;
            padding: 6px 12px;
        }
        #target {
            width: 345px;
        }
    </style>
</head>
<body>

        <div class="container">
            <p>TODO: Add Google JavaScript Map with walkroute outline.</p>
            <p>TODO: List walking times</p>
            <p>TODO: List common walk routes and businesses</p>

            <!--  where the map will live  -->
            <input id="pac-input" class="controls" type="text" placeholder="Search Box">
            <div id="map"></div>
        </div>

    <script>
        // This example requires the Places library. Include the libraries=places
        // parameter when you first load the API. For example:
        // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">

        var map;

        var infowindow;

        function initMap() {
            var wwrf = {
                lat: 37.682319,
                lng: -97.333311
            };

            map = new google.maps.Map(document.getElementById('map'), {
                center: wwrf,
                zoom: 14
            });

            var squareCoords = [
                {lat: 37.697465, lng: -97.341629},
                {lat: 37.697636, lng: -97.317306},
                {lat: 37.671759, lng: -97.317142},
                {lat: 37.673308, lng: -97.352833},
                {lat: 37.693239, lng: -97.352852}
            ];

            // Construct the walkroute polygon.
            var walkRoute = new google.maps.Polygon({
                paths: squareCoords,
                strokeColor: '#008000',
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: '#008000',
                fillOpacity: 0.1
            });
            walkRoute.setMap(map);

            infowindow = new google.maps.InfoWindow();
            var service = new google.maps.places.PlacesService(map);
            service.nearbySearch({
                location: wwrf,
                radius: 1600,
                type: ['establishment'],
                //keyword: ['restaurant']
            }, callback);

            var walkRouteBounds = new google.maps.LatLngBounds(
              new google.maps.LatLng(37.673308, -97.352833),
              new google.maps.LatLng(37.697636, -97.317306),
            );

            var options = {
                bounds: walkRouteBounds,
                strictBounds: true
            };

            // Create the search box and link it to the UI element.
            var input = document.getElementById('pac-input');

            var searchBox = new google.maps.places.SearchBox(input, options);
            map.controls[google.maps.ControlPosition.TOP_CENTER].push(input);

            var markers = [];
            // Listen for the event fired when the user selects a prediction and retrieve
            // more details for that place.
            searchBox.addListener('places_changed', function() {
                var places = searchBox.getPlaces();
                searchBox.setBounds(walkRouteBounds);
                if (places.length == 0) {
                  return;
                }

                // Clear out the old markers.
                markers.forEach(function(marker) {
                  marker.setMap(null);
                });
                markers = [];

                // For each place, get the icon, name and location.
                var bounds = new google.maps.LatLngBounds(
                  new google.maps.LatLng(37.673308, -97.352833),
                  new google.maps.LatLng(37.697636, -97.317306),
                );
                places.forEach(function(place) {
                  if (!place.geometry) {
                    console.log("Returned place contains no geometry");
                    return;
                  }
                  var icon = {
                    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)
                  };

                  // Create a marker for each place.
                  markers.push(new google.maps.Marker({
                    map: map,
                    //icon: icon,
                    title: place.name,
                    position: place.geometry.location
                  }));

                  if (place.geometry.viewport) {
                    // Only geocodes have viewport.
                    bounds.union(place.geometry.viewport);
                  } else {
                    bounds.extend(place.geometry.location);
                  }
                });
                map.fitBounds(bounds);
            });

        }

        function callback(results, status) {
          if (status === google.maps.places.PlacesServiceStatus.OK) {
            for (var i = 0; i < results.length; i++) {
              createMarker(results[i]);
            }
          }
        }

        function createMarker(place) {
          var placeLoc = place.geometry.location;
          var marker = new google.maps.Marker({
            map: map,
            position: place.geometry.location
          });

          google.maps.event.addListener(marker, 'click', function() {
            infowindow.setContent('<strong>' + place.name + '</strong><br/>' + place.formatted_address);
            infowindow.open(map, this);
          });
        }

</script>

    <script src="https://maps.googleapis.com/maps/api/js?key=your_api&libraries=places&callback=initMap" async defer></script>

</body>

GoogleMap searchbox fiddle

编辑好的,所以我能够使用下拉框找到解决方案,虽然这不太理想,因为我必须对我的关键字进行硬编码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Walkroute Dropdown</title>
    <meta name="description" content="">
    <meta name="title" content="">
    <meta name="author" content="WWRF">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <style>
        #map {
            height: 600px;
            width: 100%;
        }
        #description {
            font-family: Roboto;
            font-size: 15px;
            font-weight: 300;
        }

        #infowindow-content .title {
            font-weight: bold;
        }

        #infowindow-content {
            display: none;
        }

        #map #infowindow-content {
            display: inline;
        }

        .pac-card {
            margin: 10px 10px 0 0;
            border-radius: 2px 0 0 2px;
            box-sizing: border-box;
            -moz-box-sizing: border-box;
            outline: none;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
            background-color: #fff;
            font-family: Roboto;
        }

        #pac-container {
            padding-bottom: 12px;
            margin-right: 12px;
        }

        .pac-controls {
            display: inline-block;
            padding: 5px 11px;
        }

        .pac-controls label {
            font-family: Roboto;
            font-size: 13px;
            font-weight: 300;
        }

        #pac-input {
            background-color: #fff;
            font-family: Roboto;
            font-size: 15px;
            font-weight: 300;
            margin-left: 12px;
            padding: 0 11px 0 13px;
            text-overflow: ellipsis;
            width: 400px;
        }

        #pac-input:focus {
            border-color: #4d90fe;
        }

        #title {
            color: #fff;
            background-color: #4d90fe;
            font-size: 25px;
            font-weight: 500;
            padding: 6px 12px;
        }
        #target {
            width: 345px;
        }
    </style>
</head>
<body>

        <div class="container">

            <select name="mapchange" onchange="updateMap(this.options[this.selectedIndex].value)">
                <option value="restaurants">Restaurants</option>
                <option value="warehouses">Warehouses</option>
                <option value="temp services">Temp Services</option>
            </select>
            <!--  where the map will live  -->
            <div id="map"></div>
        </div>

    <script>
        // This example requires the Places library. Include the libraries=places
        // parameter when you first load the API. For example:
        // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">

        var map;

        var infowindow;

        var wwrf = {
                lat: 37.682319,
                lng: -97.333311
            };



        function initMap() {

            map = new google.maps.Map(document.getElementById('map'), {
                center: wwrf,
                zoom: 14
            });

            var squareCoords = [
                {lat: 37.697465, lng: -97.341629},
                {lat: 37.697636, lng: -97.317306},
                {lat: 37.671759, lng: -97.317142},
                {lat: 37.673308, lng: -97.352833},
                {lat: 37.693239, lng: -97.352852}
            ];

            // Construct the walkroute polygon.
            var walkRoute = new google.maps.Polygon({
                paths: squareCoords,
                strokeColor: '#008000',
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: '#008000',
                fillOpacity: 0.1
            });
            walkRoute.setMap(map);

            infowindow = new google.maps.InfoWindow();
            /*var service = new google.maps.places.PlacesService(map);
            service.nearbySearch({
                location: wwrf,
                radius: 1600,
                type: ['establishment'],
                keyword: ['restaurant']
            }, callback);*/

        }
        var markers = [];

        function callback(results, status) {
          if (status === google.maps.places.PlacesServiceStatus.OK) {
            for (var i = 0; i < results.length; i++) {
                createMarker(results[i]);
            }
          }
        }

        function createMarker(place) {
            var placeLoc = place.geometry.location;

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

            // Create a marker for each place.
            markers.push(marker);

            google.maps.event.addListener(marker, 'click', function() {
                infowindow.setContent('<strong>' + place.name + '</strong><br/>' + place.formatted_address);
                infowindow.open(map, this);
            });
        }

        function updateMap(selectControl)   {

            // Clear out the old markers.
            markers.forEach(function(marker) {
                marker.setMap(null);
            });
            markers = [];

            var keyword = selectControl;
            var service = new google.maps.places.PlacesService(map);
            service.nearbySearch({
                location: wwrf,
                radius: 1600,
                type: ['establishment'],
                keyword: keyword
            }, callback);
        }

        function clearMarkers() {
            for (var i = 0; i < markersArray.length; i++ ) {
                markersArray[i].setMap(null);
            }
            markersArray.length = 0;
        }

</script>

    <script src="https://maps.googleapis.com/maps/api/js?key=your_api&libraries=places&callback=initMap" async defer></script>

</body>
</html>

这里是小提琴的链接:Walkroute dropdown

2 个答案:

答案 0 :(得分:0)

好的,我一直在寻找这个问题,这里有一个我认为可能的解决方案:

所以在回调函数的For循环中,我可以在创建一个要求的标记之前建议(使用IF并且我认为有一个名为contains的方法返回一个布尔值)如果     place.geometry.location位于您的边界内,因此如果该位置不在您的边界内,则您不会创建该标记,因此地图不会缩小。

另一种解决方案是在自动完成搜索后强制缩放到某个值。

我希望你能找到解决问题的方法。

答案 1 :(得分:0)

我可以看到您尝试使用strictBounds: true选项初始化SearchBox,但不幸的是,SearchBox当前不支持严格边界过滤器。如果你可以切换到自动完成,它确实支持严格的边界,你可以初始化自动完成,如

var options = {
    bounds: walkRouteBounds,
    strictBounds: true,
    types: ['establishment']
};

var input = document.getElementById('pac-input');
var autocomplete = new google.maps.places.Autocomplete(input, options);

关于SearchBox的严格范围,Google问题跟踪器中有一项功能请求:

https://issuetracker.google.com/issues/67982212

随意添加功能请求,以添加您的投票并订阅通知。