【问题标题】:Google Maps API Javascript, get longitude latitude from form input on pageGoogle Maps API Javascript,从页面上的表单输入中获取经度纬度
【发布时间】:2020-07-12 04:54:40
【问题描述】:

我正在尝试创建一个单页地图生成器,他们可以在其中输入地址和邮政编码。

这部分有效

Geolocation API 然后进行反向查找以获取经度和纬度,并将其填充到 2 个隐藏的输入字段以供以后使用。

这部分不起作用

然后,我需要使用 Maps 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。

在 timeout 函数中移动所有内容会引发未定义 initMap 的 promise 错误。

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>

【问题讨论】:

    标签: javascript google-maps google-maps-api-3 google-maps-api-2


    【解决方案1】:

    有几个问题。

    1. 我收到 JavaScript 错误:InvalidValueError: setCenter: not a LatLng or LatLngLiteral with finite coordinates: in property lat: NaN is not an accepted value,因为在您的 API 中包含:

    您有callback=initMap,但您不希望它在 API 加载时运行,您希望它在用户单击“查找地址”后运行。删除:

    <script src="https://maps.googleapis.com/maps/api/js?key=REMOVED_FOR_PRIVACY" async defer></script>
    
    1. 当我单击“查找地址”时出现 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 Geocoder,并添加错误检查:
    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")
    });
    

    proof of concept fiddle

    代码 sn-p:

    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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 2017-10-04
      相关资源
      最近更新 更多