Google Maps SearchBox不在边界内搜索 [英] Google Maps SearchBox not searching in bounds

查看:88
本文介绍了Google Maps SearchBox不在边界内搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在让Google的搜索框服务无法正常运行方面遇到问题.

I'm having problems getting google's searchbox service to run properly for me.

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

What I have is a map with a polygon drawn on it. I would like to use the searchbox and/or autocomplete service to return ONLY business of the specified type (e.g. restaurants, fast food, warehouses, etc.) that are within this polygons boundaries.

我可以使用邻近服务根据类型或关键字返回结果.我还可以在搜索框中返回餐厅的搜索结果;但是,如果我更新搜索以查找其他业务(例如仓库),则地图会缩小并显示世界各地的仓库..

I can use the nearby service to return results based on type or keyword. I can also get the searchbox to return results for restaurants; however, if I update the search to look for other businesses, such as warehouses, the map zooms out and shows warehouses all over the world.

这是一个有用的小提琴示例:

Here is a working fiddle example:

<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搜索框小提琴

好,所以我可以使用下拉框提出一个解决方案,尽管它不是理想的选择,因为我必须对关键字进行硬编码.

Alright so I have been able to come up with a solution using a dropdown box, although it is not ideal because I have to hard code my keywords.

<!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下拉

推荐答案

我可以看到您尝试使用strictBounds: true选项初始化SearchBox,但是不幸的是,SearchBox当前不支持严格边界过滤器.如果您可以切换到自动完成功能,则表示确实支持严格限制,您可以像这样初始化自动完成功能

I can see that you try to initialize the SearchBox with strictBounds: true option, but unfortunately, the SearchBox doesn't support strict bounds filter at current moment. If you can switch to the Autocomplete, it is indeed supports strict bounds and you can initialize the autocomplete like

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问题跟踪器中有一个功能请求:

Regarding the strict bounds for SearchBox, there is a feature request in Google issue tracker:

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

随时为功能请求加注星标,以添加您的投票并订阅通知.

Feel free to star the feature request to add your vote and subscribe to notifications.

这篇关于Google Maps SearchBox不在边界内搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆