Google Maps API Javascript, получить широту долготы от ввода формы на странице - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь создать 1-страничный генератор карт, в котором они вводят свой адрес и почтовый индекс.

Эта часть работает

Затем Geolocation API выполняет обратный поиск получить долготу и широту и заполнить ее 2 скрытыми полями ввода для последующего использования.

Эта часть не работает

Затем мне нужно использовать API Карт, чтобы получить значения долготы и широты из скрытых входных данных и сгенерировать карту, однако, переменные приходят в NULL, потому что они установлены внутри функции, которая активируется при нажатии.

Мне нужно иметь возможность запускать код генератора карт после того, как значение было установлено, или передавать набор значений через сначала из заданного числа, а затем по нажатию кнопки перезапустите код, используя скрытые значения.

<script>
var apiKey='REMOVED FOR PRIVACY';
var longitude, latitude, map;

jQuery(document).ready(function( $ ) {
    $('#find-address').click(function () {
        var address = $('#address').val();
        var postcode = $('#postcode').val();
        var addressClean = address.replace(/\s+/g, '+');
        var postcodeClean = postcode.replace(/\s+/g, '+');
        var apiCall = 'https://maps.googleapis.com/maps/api/geocode/json?address='+addressClean+',+'+postcodeClean+'&key='+apiKey+'';

        $.getJSON(apiCall,function (data, textStatus) {
            longitude = data.results[0].geometry.location.lng;
            latitude = data.results[0].geometry.location.lat;
            document.getElementById("long").value = longitude;
            document.getElementById("lat").value = latitude;
        });

        setTimeout(function(){
            longitude = $("input#long").val();
            latitude = $("input#lat").val();

            if(longitude && latitude){
                longitude = parseFloat(longitude);
                latitude = parseFloat(latitude);

                initMap(longitude,latitude);
            }
        }, 1000);
    });
});

function initMap(longitude,latitude) {
    var myLatlng = new google.maps.LatLng(latitude,longitude);

    var mapOptions = {
      zoom: 12,
      center: myLatlng
    }

    var map = new google.maps.Map(document.getElementById("map-embed-div"), mapOptions);

    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        draggable: true,
        title: "Where's your garden?"
    });
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=REMOVED_FOR_PRIVACY&callback=initMap" async defer></script>

Я пытался вызвать функцию внутри функции setTimeout и передать значения в обратном вызове функции. однако это возвращает NULL.

Перемещение всего внутри функции тайм-аута приводит к ошибке обещания, так как initMap не определен.

HTML Форма

<form action="/instant-quote-test/#wpcf7-f3686-p3924-o1" method="post" class="wpcf7-form mailchimp-ext-0.5.14" novalidate="novalidate">
    <div style="display: none;">
        <input type="hidden" name="_wpcf7" value="3686" /><br />
        <input type="hidden" name="_wpcf7_version" value="5.1.7" /><br />
        <input type="hidden" name="_wpcf7_locale" value="en_GB" /><br />
        <input type="hidden" name="_wpcf7_unit_tag" value="wpcf7-f3686-p3924-o1" /><br />
        <input type="hidden" name="_wpcf7_container_post" value="3924" />
    </div>

    <p><span class="wpcf7-form-control-wrap your-fname"><input type="hidden" name="your-fname" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span><span class="wpcf7-form-control-wrap your-email"><input type="hidden" name="your-email" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span><span class="wpcf7-form-control-wrap your-phone"><input type="hidden" name="your-phone" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span></p>


    <input type="text" name="street-address" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" id="address" aria-required="true" aria-invalid="false" placeholder="Street Address" />

    <input type="text" name="post-code" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" id="postcode" aria-required="true" aria-invalid="false" placeholder="Post Code" />

    <input type="hidden" id="lat" value=""><input type="hidden" id="long" value="">
    <input type="hidden" name="addressField1" value=""><input type="hidden" name="postcodeField" value="">
    <a href="#" id="find-address" title="Find Address" class="button">Find Address</a>

    <div id="map-embed">
        <div id="map-embed-div" style="height:400px;width:100%;"></div>
    </div>

    <div id="after-map-quote">
        <input type="submit" value="Get My Lawn Care Quote" class="wpcf7-form-control wpcf7-submit quote-send" />
    </div>
</form>

1 Ответ

0 голосов
/ 01 апреля 2020

Существует несколько проблем.

  1. Я получаю ошибку JavaScript: InvalidValueError: setCenter: not a LatLng or LatLngLiteral with finite coordinates: in property lat: NaN is not an accepted value, поскольку в вашем API есть:

you иметь callback=initMap, но вы не хотите, чтобы он запускался при загрузке API, вы хотите, чтобы он запускался после того, как пользователь нажмет «Найти адрес». Удалить это:

<script src="https://maps.googleapis.com/maps/api/js?key=REMOVED_FOR_PRIVACY" async defer></script>
Я получаю ошибку JavaScript: Uncaught TypeError: Cannot read property 'geometry' of undefined, когда нажимаю «Найти адрес», потому что проверка ошибок отсутствует. Если я проверяю текстовый статус (по крайней мере, с помощью тестового ключа Google), он говорит мне: "API keys with referer restrictions cannot be used with this API.", status: "REQUEST_DENIED". Если я использую неограниченный ключ для запроса к геокодеру, я получаю карту с маркером (по крайней мере, для действительного адреса). Я бы предложил использовать геокодер Google JavaScript API v3 и добавить проверку ошибок:
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
  address: addressClean + "," + postcodeClean
}, function(results, status) {
  console.log(status);
  if (status == 'OK') {

    console.log(results);
    longitude = results[0].geometry.location.lng();
    latitude = results[0].geometry.location.lat();
    document.getElementById("long").value = longitude;
    document.getElementById("lat").value = latitude;
    // geocoder is asynchronous, do this in the callback function
    longitude = $("input#long").val();
    latitude = $("input#lat").val();

    if (longitude && latitude) {
      longitude = parseFloat(longitude);
      latitude = parseFloat(latitude);

      initMap(longitude, latitude);
    }
  } else alert("geocode failed")
});

подтверждение концепции скрипта

screenshot of resulting map

фрагмент кода:

var apiKey = 'AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk';
var longitude, latitude, map;

jQuery(document).ready(function($) {
  $('#find-address').click(function() {
    var address = $('#address').val();
    var postcode = $('#postcode').val();
    var addressClean = address.replace(/\s+/g, '+');
    var postcodeClean = postcode.replace(/\s+/g, '+');
    var apiCall = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + addressClean + ',+' + postcodeClean + '&key=' + apiKey + '';

    //$.getJSON(apiCall,function (data, textStatus) {
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({
      address: addressClean + "," + postcodeClean
    }, function(results, status) {
      console.log(status);
      if (status == 'OK') {

        console.log(results);
        longitude = results[0].geometry.location.lng();
        latitude = results[0].geometry.location.lat();
        document.getElementById("long").value = longitude;
        document.getElementById("lat").value = latitude;
        // geocoder is asynchronous, do this in the callback function
        longitude = $("input#long").val();
        latitude = $("input#lat").val();

        if (longitude && latitude) {
          longitude = parseFloat(longitude);
          latitude = parseFloat(latitude);

          initMap(longitude, latitude);
        }
      } else alert("geocode failed")
    });
  });

  function initMap(longitude, latitude) {
    var myLatlng = new google.maps.LatLng(latitude, longitude);

    var mapOptions = {
      zoom: 12,
      center: myLatlng
    }

    var map = new google.maps.Map(document.getElementById("map-embed-div"), mapOptions);

    var marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      draggable: true,
      title: "Where's your garden?"
    });
  };
})
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="/instant-quote-test/#wpcf7-f3686-p3924-o1" method="post" class="wpcf7-form mailchimp-ext-0.5.14" novalidate="novalidate">
  <div style="display: none;">
    <input type="hidden" name="_wpcf7" value="3686" /><br />
    <input type="hidden" name="_wpcf7_version" value="5.1.7" /><br />
    <input type="hidden" name="_wpcf7_locale" value="en_GB" /><br />
    <input type="hidden" name="_wpcf7_unit_tag" value="wpcf7-f3686-p3924-o1" /><br />
    <input type="hidden" name="_wpcf7_container_post" value="3924" />
  </div>

  <p><span class="wpcf7-form-control-wrap your-fname"><input type="hidden" name="your-fname" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span><span class="wpcf7-form-control-wrap your-email"><input type="hidden" name="your-email" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span>
    <span
      class="wpcf7-form-control-wrap your-phone"><input type="hidden" name="your-phone" value="" size="40" class="wpcf7-form-control wpcf7dtx-dynamictext wpcf7-dynamichidden" aria-invalid="false" /></span>
  </p>


  <input type="text" name="street-address" value="77 Mass Ave" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" id="address" aria-required="true" aria-invalid="false" placeholder="Street Address" />

  <input type="text" name="post-code" value="02139" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" id="postcode" aria-required="true" aria-invalid="false" placeholder="Post Code" />

  <input type="hidden" id="lat" value=""><input type="hidden" id="long" value="">
  <input type="hidden" name="addressField1" value=""><input type="hidden" name="postcodeField">
  <a href="#" id="find-address" title="Find Address" class="button">Find Address</a>

  <div id="map-embed">
    <div id="map-embed-div" style="height:400px;width:100%;"></div>
  </div>

  <div id="after-map-quote">
    <input type="submit" value="Get My Lawn Care Quote" class="wpcf7-form-control wpcf7-submit quote-send" />
  </div>
</form>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" async defer></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...