Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google maps Google Places API商店定位器-单击搜索结果标题以显示信息窗口_Google Maps_Google Maps Api 3_Google Places Api_Geojson_Infowindow - Fatal编程技术网

Google maps Google Places API商店定位器-单击搜索结果标题以显示信息窗口

Google maps Google Places API商店定位器-单击搜索结果标题以显示信息窗口,google-maps,google-maps-api-3,google-places-api,geojson,infowindow,Google Maps,Google Maps Api 3,Google Places Api,Geojson,Infowindow,我的地图功能正常,直到我通过邮政编码搜索最近的商店位置,并尝试在生成的面板中单击结果的标题,以显示相应标题的信息窗口 换句话说,我希望能够单击搜索结果标题,当您单击时,它会在与标题关联的地图标记上打开信息窗口 单击地图标记以显示信息窗口工作正常。在搜索后生成的结果列表中单击搜索结果,则不会 我正在使用geoJSON加载位置 function initMap() { // Create the map. const map = new google.maps.Map(

我的地图功能正常,直到我通过邮政编码搜索最近的商店位置,并尝试在生成的面板中单击结果的标题,以显示相应标题的信息窗口

换句话说,我希望能够单击搜索结果标题,当您单击时,它会在与标题关联的地图标记上打开信息窗口

单击地图标记以显示信息窗口工作正常。在搜索后生成的结果列表中单击搜索结果,则不会

我正在使用geoJSON加载位置

   function initMap() {
    // Create the map.
        const map = new google.maps.Map(document.getElementById('map'), {
            zoom: 7,
            center: { lat: 32.434521, lng: -86.333977 },
            styles: mapStyle,
        });

        // Load the stores GeoJSON onto the map.
        map.data.loadGeoJson('My geojson file', {idPropertyName: 'storeid'});

        // Define the custom marker icons, using the store's "category".
        map.data.setStyle((feature) => {
        return {
        icon: {
            url: 'my marker icon',
            scaledSize: new google.maps.Size(64, 64),
        },
        };
    });


        const apiKey = 'my key';
        const infoWindow = new google.maps.InfoWindow();

        // Show the information for a store when its marker is clicked.
        map.data.addListener('click', (event) => {
        const name = event.feature.getProperty('name');
        const address = event.feature.getProperty('address');
        const phone = event.feature.getProperty('phone');
        const position = event.feature.getGeometry().get(); 
        const content = `
            <h5>${name}</h5><p>${address}</p><p>${phone}</p>
        `;

        infoWindow.setContent(content);
        infoWindow.setPosition(position);
        infoWindow.setOptions({pixelOffset: new google.maps.Size(0, -30)});
        infoWindow.open(map);
        });

    // SEARCH BAR

    // Build and add the search bar
    const card = document.createElement('div');
    const titleBar = document.createElement('div');
    const title = document.createElement('div');
    const container = document.createElement('div');
    const magnify = document.createElement('div');
    const input = document.createElement('input');
    const options = {
        types: ['(regions)'],
        componentRestrictions: {country: 'us'},
    };

    card.setAttribute('id', 'pac-card');
    title.setAttribute('id', 'title');
    title.textContent = 'Find the nearest location';
    titleBar.appendChild(title);
    container.setAttribute('id', 'pac-container');
    magnify.setAttribute('id', 'magnify');
    input.setAttribute('id', 'pac-input');
    input.setAttribute('type', 'text');
    input.setAttribute('placeholder', 'ZIP CODE');
    container.appendChild(input);
    let parent = document.getElementById('map-hero');
    parent.appendChild(card);
    card.appendChild(titleBar);
    card.appendChild(container);
    let magnifyParent = document.getElementById('pac-container');
    magnifyParent.appendChild(magnify);
    // map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);


    // Make the search bar into a Places Autocomplete search bar and select
    // which detail fields should be returned about the place that
    // the user selects from the suggestions.
    const autocomplete = new google.maps.places.Autocomplete(input, options);

    autocomplete.setFields(
        ['address_components', 'geometry', 'name']);

    // END SEARCH BAR

    // Press Enter to Search Zip Code

    var pac_input = document.getElementById('pac-input');

    (function pacSelectFirst(input) {
        // store the original event binding function
        var _addEventListener = (input.addEventListener) ? input.addEventListener : input.attachEvent;

        function addEventListenerWrapper(type, listener) {
            // Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected,
            // and then trigger the original listener.
            if (type == "keydown") {
            var orig_listener = listener;
            listener = function(event) {
            var suggestion_selected = $(".pac-item-selected").length > 0;
            if (event.which == 13 && !suggestion_selected) {
            var simulated_downarrow = $.Event("keydown", {
                keyCode: 40,
                which: 40
            });
                orig_listener.apply(input, [simulated_downarrow]);
                }
                orig_listener.apply(input, [event]);
                };
            }
            _addEventListener.apply(input, [type, listener]);
        }
        input.addEventListener = addEventListenerWrapper;
        input.attachEvent = addEventListenerWrapper;

        var autoComplete = new google.maps.places.Autocomplete(input);
        autoComplete.setTypes(['regions'])
        // autoComplete.unbindAll();

    })(pac_input);
    //End Press Enter to Search Zip Code

    //Click magnifying glass to search

    document.getElementById('magnify').onclick = function () {
        var input = document.getElementById('pac-input');

        function no_op() {}

        google.maps.event.trigger(input, 'focus', {});
        google.maps.event.trigger(input, 'keydown', {
          keyCode: 40, // arrow down
          stopPropagation: no_op, // No-op function in order to prevent error
          preventDefault: no_op,
        });  
        google.maps.event.trigger(input, 'keydown', { keyCode: 13 });  // enter
        google.maps.event.trigger(this, 'focus', {});
      };
    //End Click magnifying glass to search

    // Set the origin point when the user selects an address
    const originMarker = new google.maps.Marker({map: map});
    originMarker.setVisible(false);
    let originLocation = map.getCenter();

    autocomplete.addListener('place_changed', async () => {
        originMarker.setVisible(false);
        originLocation = map.getCenter();
        const place = autocomplete.getPlace();

        if (!place.geometry) {
        // User entered the name of a Place that was not suggested and
        // pressed the Enter key, or the Place Details request failed.
        window.alert('No address available for input: \'' + place.name + '\'');
        return;
        }

        // Recenter the map to the selected address
        originLocation = place.geometry.location;
        map.setCenter(originLocation);
        map.setZoom(9);
        console.log(place);

        originMarker.setPosition(originLocation);
        originMarker.setVisible(true);

        // Use the selected address as the origin to calculate distances
        // to each of the store locations
        const rankedStores = await calculateDistances(map.data, originLocation);
        showStoresList(map.data, rankedStores);

        return;
    });

    }


    // Calculate Distance

    async function calculateDistances(data, origin) {
    const stores = [];
    const destinations = [];

    // Build parallel arrays for the store IDs and destinations
    data.forEach((store) => {
        const storeNum = store.getProperty('storeid');
        const storeLoc = store.getGeometry().get();

        stores.push(storeNum);
        destinations.push(storeLoc);
    });

    // Retrieve the distances of each store from the origin
    // The returned list will be in the same order as the destinations list
    const service = new google.maps.DistanceMatrixService();
    const getDistanceMatrix =
        (service, parameters) => new Promise((resolve, reject) => {
        service.getDistanceMatrix(parameters, (response, status) => {
            if (status != google.maps.DistanceMatrixStatus.OK) {
            reject(response);
            } else {
            const distances = [];
            const results = response.rows[0].elements;
            for (let j = 0; j < results.length; j++) {
                const element = results[j];
                const distanceText = element.distance.text;
                const distanceVal = element.distance.value;
                const distanceObject = {
                storeid: stores[j],
                distanceText: distanceText,
                distanceVal: distanceVal,
                };
                distances.push(distanceObject);
            }

            resolve(distances);
            }
        });
        });

    const distancesList = await getDistanceMatrix(service, {
        origins: [origin],
        destinations: destinations,
        travelMode: 'DRIVING',
        unitSystem: google.maps.UnitSystem.IMPERIAL,
    });

    distancesList.sort((first, second) => {
        return first.distanceVal - second.distanceVal;
    });

    return distancesList;
    }

    // End Calculate Distance

    //Show Closest Location List
    function showStoresList(data, stores) {
    if (stores.length == 0) {
        console.log('empty stores');
        return;
    }

    let panel = document.createElement('div');
    // If the panel already exists, use it. Else, create it and add to the page.
    if (document.getElementById('panel')) {
        panel = document.getElementById('panel');
        // If panel is already open, close it
        if (panel.classList.contains('open')) {
        panel.classList.remove('open');
        }
    } else {
        panel.setAttribute('id', 'panel');
        let parent = document.getElementById('map');
        parent.appendChild(panel);
    //  const body = document.body;
    //  body.insertBefore(panel, body.childNodes[0]);
    }


    // Clear the previous details
    while (panel.lastChild) {
        panel.removeChild(panel.lastChild);
    }

    stores.forEach((store) => {
        // Add store details with text formatting
        const name = document.createElement('p');
        name.setAttribute('id', 'locationName');
        name.classList.add('place');
        const currentStore = data.getFeatureById(store.storeid);
        name.textContent = currentStore.getProperty('name');
        panel.appendChild(name);
        const distanceText = document.createElement('p');
        distanceText.classList.add('distanceText');
        distanceText.textContent = store.distanceText;
        panel.appendChild(distanceText);

    });

    // Open the panel
    panel.classList.add('open');

    return;
    }

    //End Show Closest Location List
HTML

搜索后通过JS创建的带有标题和距离的生成面板。这些是我希望能够单击以显示信息窗口的标题(同时仍然能够单击标记以显示信息窗口)

单击侧边栏,您就拥有打开信息窗口所需的所有数据

单击标记时执行相同的操作:

function openInfoWindowOnMarker(feature) {
   console.log(feature);
   const name = feature.getProperty('name');
   const address = feature.getProperty('address');
   const phone = feature.getProperty('phone');
   const position = feature.getGeometry().get();
   const content = `<h5>${name}</h5><p>${address}</p><p>${phone}</p>`;

   infoWindow.setContent(content);
   infoWindow.setPosition(position);
   infoWindow.setOptions({
     pixelOffset: new google.maps.Size(0, -30)
   });
   infoWindow.open(map);
 }

 infoWindow = new google.maps.InfoWindow();
 // Show the information for a store when its marker is clicked.
 map.data.addListener('click', (event) => {
   openInfoWindowOnMarker(event.feature)
 });
需要进行一些其他更改,以使代码可以使用
映射
信息窗口

代码片段:

var信息窗口;
var映射;
函数initMap(){
//创建地图。
map=new google.maps.map(document.getElementById('map'){
缩放:7,
中心:{
纬度:32.434521,
液化天然气:-86.333977
},
//样式:mapStyle,
});
//将存储的GeoJSON加载到地图上。
addGeoJson(geoJsonData{
idPropertyName:“存储ID”
});
//使用商店的“类别”定义自定义标记图标。
map.data.setStyle((功能)=>{
返回{
图标:{
网址:'https://staging.ymcamontgomery.org/wp-content/uploads/2020/02/map-marker-1.svg',
scaledSize:新的google.maps.Size(64,64),
},
};
});
const apiKey='Aizasyckoudz5y7hmm0yrccqocvlwzdm6m8s5qk';
infoWindow=new google.maps.infoWindow();
//单击某个存储的标记时显示该存储的信息。
map.data.addListener('单击',(事件)=>{
openInfoWindowOnMarker(event.feature)
});
//搜索栏
//构建并添加搜索栏
const card=document.createElement('div');
const titleBar=document.createElement('div');
const title=document.createElement('div');
const container=document.createElement('div');
const放大=document.createElement('div');
常量输入=document.createElement('input');
常量选项={
类型:['(区域)],
组件限制:{
国家:“美国”
},
};
setAttribute('id','pac card');
title.setAttribute('id','title');
title.textContent='查找最近的位置';
标题栏。附属物(标题);
setAttribute('id','pac container');
setAttribute('id','magnize');
setAttribute('id','pac input');
input.setAttribute('type','text');
setAttribute('占位符','邮政编码');
setAttribute('value','Montgomery');
container.appendChild(输入);
让parent=document.getElementById('map-hero');
父母、子女(卡片);
卡片。附属物(标题栏);
卡片.附件(容器);
让magnificparent=document.getElementById('pac-container');
放大父对象。追加子对象(放大);
//map.controls[google.maps.ControlPosition.TOP\u RIGHT].push(卡片);
//将搜索栏设置为位置自动完成搜索栏,然后选择
//应返回哪些有关所选位置的详细信息字段
//用户从建议中进行选择。
const autocomplete=new google.maps.places.autocomplete(输入,选项);
自动完成设置字段(
['address_components'、'geometry'、'name']);
//结束搜索栏
//按Enter键搜索邮政编码
var pac_input=document.getElementById('pac-input');
(功能pacSelectFirst(输入){
//存储原始事件绑定函数
var _addEventListener=(input.addEventListener)?input.addEventListener:input.attachEvent;
函数addEventListenerWrapper(类型,侦听器){
//当未选择pac建议时,在点击“返回”时模拟按下“向下箭头”键,
//然后触发原始侦听器。
如果(类型==“键控键控”){
var orig_listener=监听器;
侦听器=函数(事件){
所选var suggestion_=$(“.pac项已选定”)。长度>0;
如果(选择event.which==13&&!建议){
var模拟_向下箭头=$.Event(“向下键”{
密码:40,
哪个:40
});
orig_listener.apply(输入,[simulated_downarrow]);
}
orig_listener.apply(输入,[event]);
};
}
_apply(输入,[type,listener]);
}
input.addEventListener=addEventListenerWrapper;
input.attachEvent=addEventListenerWrapper;
var autoComplete=new google.maps.places.autoComplete(输入);
autoComplete.setTypes(['regions'])
//自动完成。取消绑定();
})(pac_输入);
//结束按Enter键搜索邮政编码
//单击放大镜进行搜索
document.getElementById('放大').onclick=function(){
var input=document.getElementById('pac-input');
函数no_op(){}
google.maps.event.trigger(输入'focus',{});
google.maps.event.trigger(输入'keydown'{
键码:40,//向下箭头
stopPropagation:no_op,//为了防止错误,没有op函数
预防默认值:无操作,
});
google.maps.event.trigger(输入'keydown'{
密码:13
});//输入
google.maps.event.trigger(这个'focus',{});
};
//结束单击放大镜进行搜索
//设置用户选择地址时的原点
const originMarker=new google.maps.Marker({
地图:地图
});
originMarker.setVisible(假);
让originLocation=map.getCenter();
autocomplete.addListener('place\u changed',异步(
<div id="map-hero" class="map-hero">
        <h1 class="white center">GET STARTED BY ENTERING YOUR ZIP CODE</h1>
        <h4 class="white center">You can also zoom and drag to find a location nearest you</h4>
    </div>
    <div class="center-info-bar">
        <div id="map"></div>
        <script src="my script source"></script>
        <script async defer src="https://maps.googleapis.com/maps/api/js?key=MY API KEY &libraries=places&callback=initMap"></script>
    </div>
  #map {
            height: 400px;
            width: 100%; 
        }
        .map-hero{
            background-image: url('my url');
            background-size: cover;
            background-position: center;
            min-height: 355px;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        .center-info-bar{
            margin-bottom: 0;
        }
        .sidebar{
            display: none;
        }
        .content{
            width: 100%;
        }
        .gm-style-iw-c{
            padding: 25px;
            width: 300px;
        }
        .gm-style-iw-d{
            height: auto;
        }
        .map-loc-name{
            font-size: 15px;
            font-weight: bold;
            width: 100%;
            margin-bottom: 15px;
        } 
        #pac-card {
            background-color: #fff;
            border-radius: 2px 0 0 2px;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
            box-sizing: border-box;
            font-family: Roboto;
            margin: 10px 10px 0 0;
            -moz-box-sizing: border-box;
            outline: none;
            // custom
            max-width: 300px;
            background: transparent;
            box-shadow: none;
            margin: 0 auto;
          }

          #pac-container {
            padding-top: 12px;
            padding-bottom: 12px;
            margin-right: 12px;
            display: flex;
            align-items: center;
          }

          #pac-input {
            text-overflow: ellipsis;
            // custom
            width: 100%;
            padding: 15px;
            border: 3px solid #C11589;
            border-radius: 10px 0 0 10px;
            background: transparent;
            color: #fff; 
            font-size: 18px;
            font-weight: bold;
            font-family: 'Cachet-Bold', Verdana, sans-serif;
          }

          #pac-input::placeholder{
              color: #fff;
              font-family: 'Cachet-Bold', Verdana, sans-serif;
              font-weight: bold;
              font-size: 18px;
          }

          input:focus{
            box-shadow: none;
        }
          #magnify{
              width: 50px;
              height: 58px;
              border-radius: 0 10px 10px 0;
              background-color: #C11589;
              background-image: url('my url');
              background-size: 80%;
              background-position: center;
              background-repeat: no-repeat;
          }

          #magnify:hover{
              cursor: pointer;
          }

          #title {
            color: #fff;
            background-color: #acbcc9;
            font-size: 18px;
            font-weight: 400;
            padding: 6px 12px;
            // custom
            display: none;
          }

          .hidden {
            display: none;
          }

          /* Styling for an info pane that slides out from the left. 
           * Hidden by default. */
          #panel {
            height: 100%;
            width: null;
            background-color: white;
            position: absolute;
            z-index: 1;
            overflow-x: hidden;
            transition: all .2s ease-out;
          }

          .open {
            width: 250px;
          }

          .place {
            font-family: 'open sans', arial, sans-serif;
            font-size: 1.2em;
            font-weight: 500;
            margin-block-end: 0px;
            padding-left: 18px;
            padding-right: 18px;
          }

          .distanceText {
            color: silver;
            font-family: 'open sans', arial, sans-serif;
            font-size: 1em;
            font-weight: 400;
            margin-block-start: 0.25em;
            padding-left: 18px;
            padding-right: 18px;
          }
function openInfoWindowOnMarker(feature) {
   console.log(feature);
   const name = feature.getProperty('name');
   const address = feature.getProperty('address');
   const phone = feature.getProperty('phone');
   const position = feature.getGeometry().get();
   const content = `<h5>${name}</h5><p>${address}</p><p>${phone}</p>`;

   infoWindow.setContent(content);
   infoWindow.setPosition(position);
   infoWindow.setOptions({
     pixelOffset: new google.maps.Size(0, -30)
   });
   infoWindow.open(map);
 }

 infoWindow = new google.maps.InfoWindow();
 // Show the information for a store when its marker is clicked.
 map.data.addListener('click', (event) => {
   openInfoWindowOnMarker(event.feature)
 });
 stores.forEach((store) => {
   console.log(store);
   // Add store details with text formatting
   const name = document.createElement('p');
   name.setAttribute('id', 'locationName');
   name.classList.add('place');
   const currentStore = data.getFeatureById(store.storeid);
   name.addEventListener('click', (function(currentStore) {
     return function() {
     openInfoWindowOnMarker(currentStore);
   }})(currentStore));
   name.textContent = currentStore.getProperty('name');
   panel.appendChild(name);
   const distanceText = document.createElement('p');
   distanceText.classList.add('distanceText');
   distanceText.textContent = store.distanceText;
   panel.appendChild(distanceText);
 });