移动地图时,在谷歌地图中更新Ajax Json数组中的标记

问题描述 投票:-1回答:2

我希望我的Google地图在移动地图时更新标记 - 使用bounds_changed或idle - 通过提交新的Ajax,删除现有标记并放置新集合。

到目前为止,我有以下两个脚本: - 第一个从JSON数组中读取标题,纬度和经度,并正确地将标记放在地图中。但是我无法正确添加bounds_changed代码。 - 第二个脚本包含一个bounds_changed触发器,它将一组新标记加载到div中,但我不知道如何输入该数组作为标记的数据(并更新它们)。

如果你可以帮我修复这两个脚本中的任何一个,这样我就可以使两个东西都能正常工作 - 从脚本1中读取JSON数组中的标记,并在脚本2中移动map时更新数组 - 我将非常感激。

我已经尝试了很多变化,并阅读了所有关于问题的问题而没有运气。完全卡住了!

脚本1 - 从JSON数组中获取标记:

<script>
jQuery(function($) {
    // Asynchronously Load the map API
    var script = document.createElement('script');
    script.src = "https://maps.googleapis.com/maps/api/js?key=SECRET&sensor=false&callback=initialize";
    document.body.appendChild(script);
});

function initialize() {
    var map;
    var bounds = new google.maps.LatLngBounds();
    var mapOptions = {
        mapTypeId: 'roadmap'
    };
    ne_lng = -70.18087440625004;
    sw_lng = -92.10958534375004;
    ne_lat = 44.078852008513245;
    sw_lat = 28.9109895909681;

    // Display a map on the page
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    map.setTilt(45);
    var latlngData = 0;

        // Info Window Content
        var infoWindowContent = [
            ['<div class="info_content">' +
            '<h3>London Eye</h3>' +
            '<p>The London Eye is a giant Ferris wheel situated on the banks of the River Thames. The entire structure is 135 metres (443 ft) tall and the wheel has a diameter of 120 metres (394 ft).</p>' + '</div>'],
            ['<div class="info_content">' +
            '<h3>Palace of Westminster</h3>' +
            '<p>The Palace of Westminster is the meeting place of the House of Commons and the House of Lords, the two houses of the Parliament of the United Kingdom. Commonly known as the Houses of Parliament after its tenants.</p>' +
            '</div>']
        ];

        // Display multiple markers on a map, same info for everyone, just an example
        var infoWindow = new google.maps.InfoWindow(), marker, i;

        // Loop through our array of markers & place each one on the map, fetching avg_gps_latitude,   avg_gps_longitude from latlngData, received from ajax call ( but it dodn't work)
        loadLocations().done(function (latlngData) {


            for (i = 0; i < latlngData.length; i++) {
                var position = new google.maps.LatLng(latlngData[i].latitude, latlngData[i].longitude);
                bounds.extend(position);
                marker = new google.maps.Marker({
                    position: position,
                    map: map,
                    title: latlngData[i].ssid
                });

                // Allow each marker to have an info window
                google.maps.event.addListener(marker, 'click', (function (marker, i) {
                    return function () {
                        infoWindow.setContent(infoWindowContent[0][0]);
                        infoWindow.open(map, marker);
                    }
                })(marker, i));

                // Automatically center the map fitting all markers on the screen
                map.fitBounds(bounds);
            }

          });


        // Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
        var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function (event) {
            this.setZoom(6);
            google.maps.event.removeListener(boundsListener);
        });
    }


    function loadLocations()
    {
        return $.ajax({
              type:'POST',
              url: 'includes/newjson.php',
              dataType: 'json',
              data:{
                a: ne_lat,
                b: ne_lng,
                c: sw_lat,
                d: sw_lng
      },
      async: true,
      //cache: false,
      success: function(result){
          console.log("successx");
          console.log(result);
          var jsonStr = JSON.stringify(result);
          $('#results').html(jsonStr);
          // $('#results').html(result);
           // initialize();
          },
        error: function (xhr, ajaxOptions, thrownError) {
          alert(xhr.status);
          alert(thrownError);
        }
  });
  }

  //  google.maps.event.addDomListener(window, 'load', initialize);


</script>

脚本2 - 在移动地图但未传递到Google地图标记时,使用JSON数组更新#result中的数组(原始数组在脚本中作为PHP变量输入):

    <script type="text/javascript">
jQuery(function($) {
    // Asynchronously Load the map API
    var script = document.createElement('script');
    script.src = "https://maps.googleapis.com/maps/api/js?key=SECRET&sensor=false&callback=initialize";
    document.body.appendChild(script);
});

function initialize() {
    var map;
    var bounds = new google.maps.LatLngBounds();
    var mapOptions = {
        mapTypeId: 'roadmap'
    };

    // Display a map on the page
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    map.setTilt(45);

    google.maps.event.addListener(map, 'bounds_changed', function(){
        // alert(this.getBounds());
    ne_lng = map.getBounds().getNorthEast().lng();
    sw_lng = map.getBounds().getSouthWest().lng();
    ne_lat = map.getBounds().getNorthEast().lat();
    sw_lat = map.getBounds().getSouthWest().lat();
    console.log(ne_lng);
    console.log(sw_lng);
    console.log(ne_lat);
    console.log(sw_lat);

    $.ajax({
        type:'POST',
        url: 'includes/mapQuery.php',
        data:{
          a: ne_lat,
          b: ne_lng,
          c: sw_lat,
          d: sw_lng
},
async: true,
cache: false,
        success: function(result){
            console.log("success");
            $('#results').html(result);
            // newmarkers = result;
            // console.log(newmarkers);
        } // End of success function of ajax form
    }); // End of ajax call

    });

    // Multiple Markers
    var markers =
    <?php
        echo str_replace('"', "'", json_encode($maparray, JSON_NUMERIC_CHECK));
    ?>
    ;

    // Info Window Content
    var infoWindowContent = [
        ['<div class="info_content">' +
        '<h3>London Eye</h3>' +
        '<p>The London Eye is a giant Ferris wheel situated on the banks of the River Thames. The entire structure is 135 metres (443 ft) tall and the wheel has a diameter of 120 metres (394 ft).</p>' +        '</div>'],
        ['<div class="info_content">' +
        '<h3>Palace of Westminster</h3>' +
        '<p>The Palace of Westminster is the meeting place of the House of Commons and the House of Lords, the two houses of the Parliament of the United Kingdom. Commonly known as the Houses of Parliament after its tenants.</p>' +
        '</div>']
    ];

    // Display multiple markers on a map
    var infoWindow = new google.maps.InfoWindow(), marker, i;

    // Loop through our array of markers & place each one on the map
    for( i = 0; i < markers.length; i++ ) {
        var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
        bounds.extend(position);
        var iconBase = 'img/icons/';
        marker = new google.maps.Marker({
            position: position,
            map: map,
            icon: iconBase + 'student-icon.png',
            title: markers[i][0]
        });

        // Allow each marker to have an info window
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
                infoWindow.setContent(infoWindowContent[i][0]);
                infoWindow.open(map, marker);
            }
        })(marker, i));

        // Automatically center the map fitting all markers on the screen
        map.fitBounds(bounds);
    }

    // Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
    var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
        this.setZoom(6);
        google.maps.event.removeListener(boundsListener);
    });



}</script>
javascript json ajax google-maps google-maps-api-3
2个回答
0
投票
    If I understand correctly, there are two thing you want to achieve here. 

    1. when initialize the map, get json from server and add makers on it.
    2. when bounds changes, get json and redraws all the maps.

    You are very close, I would suggest you to reorganize your code.

    1. you need a global array of marks, so you can remove makers from map for redrawing.

    ```
    // set globals
    var makers = []
    // clear markers
    function clearMaker (markers) {
      markers.map(m => {m.setmap(null)})
    }
    ```

    2. seperate drawMarkers function
    ```
    // drawMarkers
    function drawMarkers(markerJson, markers, map, infowindow) {
      clearMarkers(markers);
      // your draw marker code
    }
    ```

    3. Your loadLocation

    ```
    /*search location based on geoparams
    geoparam: {
                 a: ne_lat,
                 b: ne_lng,
                 c: sw_lat,
                 d: sw_lng
    }
    */

    function loadLocations(geoparam)
    {
            return $.ajax({
                  type:'POST',
                  url: 'includes/newjson.php',
                  dataType: 'json',
                  data: geoparam
            })
      }
    ```
You can call loadLocation functions when initilize and bounds_changed and it returns a promise.

```
loadLocation(geoparams).then((data) => {
  drawMarkers(data, markers, map, inforwindow);
}).catch(err => { console.log(error)});
```

0
投票

这是适合我的解决方案。结果可以看出here

JSON数据来自这个php文件,只要移动地图就会更新:

include("conn.php");
$ne_lat = $_POST['a'];
$ne_lon = $_POST['b'];
$sw_lat = $_POST['c'];
$sw_lon = $_POST['d'];

$result = mysqli_query($con,"SELECT schoolname, latitude, longitude, total_students, act_composite_25, schoolid, (sat_critread_25+sat_math_25) as sat, (100 * admissions_total/applicants_total) as admrate, degree_bachelor, degree_masters, url, city, usstate, tuition_outstate, tuition_instate FROM usschools WHERE
(CASE WHEN $ne_lat < $sw_lat
        THEN latitude BETWEEN $ne_lat AND $sw_lat
        ELSE latitude BETWEEN $sw_lat AND $ne_lat
END)
AND
(CASE WHEN $ne_lon < $sw_lon
        THEN longitude BETWEEN $ne_lon AND $sw_lon
        ELSE longitude BETWEEN $sw_lon AND $ne_lon
END) and degree_bachelor = 1 order by act_composite_25 desc limit 20");
  if (!$result) {
    printf("Error: %s\n", mysqli_error($con));
    exit();
}

while ($row = $result->fetch_assoc()) {
  $data[] = $row;
  }

并生成地图并更新标记如下:

    <script>
    jQuery(function($) {
        // Asynchronously Load the map API
        var script = document.createElement('script');
        script.src = "https://maps.googleapis.com/maps/api/js?key=MYKEY&sensor=false&callback=initialize";
        document.body.appendChild(script);
    });

        ne_lng = -70.18087440625004;
        sw_lng = -92.10958534375004;
        ne_lat = 44.078852008513245;
        sw_lat = 28.9109895909681;

        function initialize() {
          var markers;
          var map;
          var markers1 = [];


            var bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(46.35960484925907, -81.34113061749997),
    new google.maps.LatLng(39.41643540717689, -70.37677514874997)
);
            var mapOptions = {
                mapTypeId: 'roadmap'
            };

        // Display a map on the page
        map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
        map.setTilt(45);
        var latlngData = 0;


        var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function (event) {
            this.setZoom(6);
            google.maps.event.removeListener(boundsListener);
        });
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);

// would be great if a margin could be added to prevent schools on edges from loading without marker
google.maps.event.addListener(map, 'idle', function() {
    ne_lng = map.getBounds().getNorthEast().lng()-0.01;
    sw_lng = map.getBounds().getSouthWest().lng()+0.01;
    ne_lat = map.getBounds().getNorthEast().lat()-0.01;
    sw_lat = map.getBounds().getSouthWest().lat()+0.01;
    console.log(ne_lng);
    console.log(sw_lng);
    console.log(ne_lat);
    console.log(sw_lat);

      function loadLocations()
        {
          $("#results").empty();
            return $.ajax({
                  type:'POST',
                  url: 'includes/newjson.php',
                  dataType: 'json',
                  data:{
                    a: ne_lat,
                    b: ne_lng,
                    c: sw_lat,
                    d: sw_lng
          },
          async: true,
          success: function(result){
              console.log("ajax");
              console.log(result);

              var len = result.length;
            for(var i=0; i<len; i++){
                var id = result[i].schoolid;
                var name = result[i].schoolname;
                var students = (result[i].total_students).toLocaleString();
                var act = result[i].act_composite_25;
                var sat = result[i].sat;
                var acceptancerate = (result[i].admrate).toFixed(1);
                var degree_bachelor = result[i].degree_bachelor;
                var degree_masters = result[i].degree_masters;
                var url = result[i].url;
                var city = result[i].city;
                var usstate = result[i].usstate;
                var tuition_outstate = (result[i].tuition_outstate).toLocaleString();
                var tuition_instate = (result[i].tuition_instate).toLocaleString();
                var tr_str = "<div class='resultBox'>" +
                    "<div class='resultImg'><span class='helper'></span><object data='img/schools/logo" + id + ".png' type='image/png' class='resultLogo'><img src='img/schools/logo.png' class='resultLogo'></object></div>" +
                    "<div class='resultColumn1'><div class='resultName'>" + name + "</div>" +
                    "<div class='resultBachelor" + degree_bachelor + "'></div>" +
                    "<div class='resultMasters" + degree_masters + "'></div>" +
                    "<div class='resultAddress'>" + city + ", " + usstate + "</div>" +
                    "<div class='resultStudents'>Students: " + students + "</div>" +
                    "<div class='resultTuition'>Tuition: $" + tuition_outstate + "/$" + tuition_instate + "</div></div>" +
                    "<div class='resultColumn2'><div class='resultAct'><div class='testLabel'><img src='img/act.png' class='tests'></div><div class='testScore act'>" + act + "</div></div>" +
                    "<div class='resultSat'><div class='testLabel'><img src='img/sat.png' class='tests'></div><div class='testScore sat'>" + sat + "</div></div><div class='testLegend'>Required score</div>" +
                    "<div class='resultAcceptRate'><div class='acceptBar' style='height:"+acceptancerate+"%'></div><div class='acceptLabel' style='bottom:"+acceptancerate+"%'>" + acceptancerate + "%</div></div><div class='acceptLegend'>Accepted</div></div>" +
                    "<div class='resultColumn3'><div class='resultSaveSchool'><a href='saveSchool?id=" + id + "' target='_new' class='btn btn-result btn-save'>Save</a></div>" +
                    "<div class='resultMore'><a href='https://" + url + "' target='_new' class='btn btn-result btn-school-url'>Website</a></div></div>" +
                    "</div>";

                $("#results").append(tr_str);
            }
              },
            error: function (xhr, ajaxOptions, thrownError) {
              alert(xhr.status);
              alert(thrownError);
            }
      });
      }

                  // Loop through our array of markers & place each one on the map, fetching avg_gps_latitude,   avg_gps_longitude from latlngData, received from ajax call ( but it dodn't work)
                  loadLocations().done(function (latlngData) {

                    for (i = 0; i < markers1.length; i++) {
                            markers1[i].setMap(null);
                            }
                            markers1 = [];
                            markers = [];
                            markers = loadLocations();

                      for (i = 0; i < latlngData.length; i++) {
                        //var infoWindow = new google.maps.InfoWindow(), marker;
                        var letter = String.fromCharCode("A".charCodeAt(0) + i - 1);
                        var infoWindow = new google.maps.InfoWindow(), marker, i;
                              var infoWindowContent = '<div class="info_content">' +
                              '<p class="infoWindowName">'+' '+latlngData[i].schoolname+'</p></div>';
                          var tooltip = '';
                          var position = new google.maps.LatLng(latlngData[i].latitude, latlngData[i].longitude);
                          bounds.extend(position);
                          var iconBase = 'img/icons/';
                          var labeltext = latlngData[i].schoolname;
                          marker = new google.maps.Marker({
                              position: position,
                              map: map,
                              label: {
                                color: '#111',
                                text: labeltext,
                                fontSize: '12px'
                          },
                              icon: iconBase + 'marker_black.png'
                              //title: tooltip
                          });
                          markers1.push(marker);

                          // Allow each marker to have an info window
                          google.maps.event.addListener(marker, 'click', (function (marker, infoWindowContent) {
                              return function () {
                                  infoWindow.setContent(infoWindowContent);
                                  infoWindow.open(map, marker);
                              }
                          })(marker, infoWindowContent));
                          // Automatically center the map fitting all markers on the screen
                          //map.fitBounds(bounds);
                      }
                      console.log("loadLocations");
                    });
});
}
</script>
© www.soinside.com 2019 - 2024. All rights reserved.