简体   繁体   中英

Find nearest markers for place selected Google Maps API?

I need to highlight all the nearest markers for the place i enter in my textbox. I am uploading the markers through my KML. But the issue is that

i am able to highlight the area but the markers dont get highlighted

. Please find the code that i have tried.

   <!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>test123</title>
    <link href="https://developers.google.com/maps/documentation/javascript/examples/default.css" rel="stylesheet">
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
<script type="text/javascript" src="http://geoxml3.googlecode.com/svn/branches/polys/geoxml3.js"></script>
<script type="text/javascript">

        var side_bar_html = ""; 
        var marker_lat;
        var marker_lng;
        var kml;
        // arrays to hold copies of the markers and html used by the side_bar 
        // because the function closure trick doesnt work there 
        var gmarkers = []; 

       // global "map" variable
        var map = null;
        var circle = null;
        var geocoder = new google.maps.Geocoder();
        function initialize() {
            var center = new google.maps.LatLng(28.019440, -17.382813); //set map center
            var mapOptions = {
                zoom: 3, //set default zoom level
                center: center,
                mapTypeId: google.maps.MapTypeId.ROADMAP //set default map type(ROADMAP,SATELLITE,HYBRID,TERRAIN)
            };

            map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); //***ORIGINAL***
            var mcOptions = {gridSize: 50, maxZoom: 15};

            var markerclusterer = new MarkerClusterer(map, [], mcOptions);
            var infoWindow = new google.maps.InfoWindow({maxWidth: 800});

            var myParser = new geoXML3.parser({//*** ORIGINAL: only {map: map});
                map: map, singleInfoWindow: true,
                createMarker: function(placemark) {
                    //Constructing marker for each Placemark node, and then add it to the markclustere
            var point = placemark.latlng;
                    // var point = new google.maps.LatLng(placemark.point.lat, placemark.point.lng);
                    var marker = new google.maps.Marker({position: point});

                    google.maps.event.addListener(marker, "click", function() {
                        marker_lat = marker.getPosition().lat();
                        marker_lng = marker.getPosition().lng();
                        infoWindow.close();
                        infoWindow.setOptions({maxWidth: 800});
                        var content = "<strong>" + placemark.name + "</strong><br>" + placemark.description;
                        infoWindow.setContent(content);
                        infoWindow.open(map, marker);
                    });
                    markerclusterer.addMarker(marker);
                }
            });
            //kml=myParser.parse('atlanta.kml');
            myParser.parse('atlanta.kml');
        }

        function makeSidebar() {
               side_bar_html = "";
               for (var i=0; i < gmarkers.length; i++){
                 if (map.getBounds().contains(gmarkers[i].getPosition())) {
                   // add a line to the side_bar html
                   side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
                 }
               }
               // put the assembled side_bar_html contents into the side_bar div
               document.getElementById("side_bar").innerHTML = side_bar_html;
            }



        function codeAddress() {
            var address = document.getElementById('address').value;
            var radius = parseInt(document.getElementById('radius').value, 10)*1000;
            geocoder.geocode( { 'address': address}, function(results, status) {
              if (status == google.maps.GeocoderStatus.OK) {
                side_bar_html = "";
               // map.setCenter(results[0].geometry.location);
                var searchCenter = results[0].geometry.location;
                alert(kml);
                getNearest(kml,marker_lat,marker_lng);
                /*
                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
                */
                if (circle) circle.setMap(null);
                circle = new google.maps.Circle({center:searchCenter,
                                                 radius: radius,
                                                 fillOpacity: 0.35,
                                                 fillColor: "#FF0000",
                                                 map: map});
                var bounds = new google.maps.LatLngBounds();
                var foundMarkers = 0;
                for (var i=0; i<gmarkers.length;i++) {
                  if (google.maps.geometry.spherical.computeDistanceBetween(gmarkers[i].getPosition(),searchCenter) < radius) {
                    bounds.extend(gmarkers[i].getPosition())
                    gmarkers[i].setMap(map);
                    // add a line to the side_bar html
                    side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
                    foundMarkers++;
                  } else {
                    gmarkers[i].setMap(null);
                  }
                }
                // put the assembled side_bar_html contents into the side_bar div
                //document.getElementById("side_bar").innerHTML = side_bar_html;
                if (foundMarkers > 0) {
                  map.fitBounds(bounds);
            } else {
                  map.fitBounds(circle.getBounds());
                }
                // makeSidebar();
                google.maps.event.addListenerOnce(map, 'bounds_changed', makeSidebar);

              } else {
                alert('Geocode was not successful for the following reason: ' + status);
              }
            });
          }

        var infowindow = new google.maps.InfoWindow(
                  { 
                    size: new google.maps.Size(150,50)
                  });

     // A function to create the marker and set up the event window function 
        function createMarker(latlng, name, html) {
            var contentString = html;
            var marker = new google.maps.Marker({
                position: latlng,
                // map: map,
                title: name,
                //name: name,
                zIndex: Math.round(latlng.lat()*-100000)<<5
                });

            google.maps.event.addListener(marker, 'click', function() {
                infowindow.setContent(contentString); 
                infowindow.open(map,marker);
                });
            // save the info we need to use later for the side_bar
            gmarkers.push(marker);
            // add a line to the side_bar html
            side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
        }

        function getNearest(kml, lat, lng) {
            var result = [];
            //we can easily skip document/placemark/point
            var coords = kml.getElementsByTagName('coordinates');
            for (var i=0;i<coords.length;i++) {
                var points = coords[i].textContent.split(',');
                if ((Math.abs(points[0]-lat)<0.1) && (Math.abs(points[1]-lng)<0.1)) {
                    result.push(new google.maps.LatLng(points[0], points[1]));
                }
            }
            return result;
        }



        google.maps.event.addDomListener(window, 'load', initialize);
    </script>
</head>


<body>

   <table border="1"> 
      <tr> 
        <td> 
    <div id="map-canvas" style="height:600px; width:600px"></div>
        </td> 
        <td valign="top" > 
         <!--   <div id="side_bar" style="width:300px;height:450px; text-decoration: underline; color: #4444ff; overflow:auto;"></div> --> 
        </td> 
      </tr> 
    </table> 
  <div>
      <input id="address" type="textbox" value="Atlanta">
      <input type="button" value="Geocode" onclick="codeAddress()"><br>
      <input id="radius" type="textbox" value="50"> kilometers
    </div> 
</body>
</html>

Below is my KML

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
    <Document>
        <name>Untitled layer</name>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Marta Station</name>
            <Point>
                <coordinates>-84.38641000000001,33.750331,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Arts Center Station</name>
            <Point>
                <coordinates>-84.38712499999997,33.789283,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Ashby Station</name>
            <Point>
                <coordinates>-84.41755599999999,33.756289,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>avondale marta station</name>
            <Point>
                <coordinates>-84.28206699999998,33.775099,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Bankhead Station</name>
            <Point>
                <coordinates>-84.428677,33.77206,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Brookhaven Station</name>
            <Point>
                <coordinates>-84.33914700000003,33.86025,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Buckhead Station</name>
            <Point>
                <coordinates>-84.36729600000001,33.847874,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Chamblee Station</name>
            <Point>
                <coordinates>-84.305949,33.887911,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Civic Center Station</name>
            <Point>
                <coordinates>-84.38750399999998,33.766245,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>College Park Station</name>
            <Point>
                <coordinates>-84.44701600000002,33.651381,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Decatur Station</name>
            <Point>
                <coordinates>-84.29690699999998,33.77444,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Dome-GWCC-Philips Arena-CNN Station</name>
            <Point>
                <coordinates>-84.39775900000001,33.75633,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Doraville Station</name>
            <Point>
                <coordinates>-84.28089299999999,33.902966,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Dunwoody MARTA Station</name>
            <Point>
                <coordinates>-84.34497499999998,33.920753,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>East Lake Station</name>
            <Point>
                <coordinates>-84.312611,33.765062,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Marta East Point</name>
            <Point>
                <coordinates>-84.44032099999998,33.678097,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Edgewood-Candler Park South Parking Lot</name>
            <Point>
                <coordinates>-84.33961999999997,33.761972,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Forsyth St @ 5 Points Marta</name>
            <Point>
                <coordinates>-84.39219100000003,33.75423,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Garnett Station</name>
            <Point>
                <coordinates>-84.395513,33.748938,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Georgia State Station</name>
            <Point>
                <coordinates>-84.385404,33.749866,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Hamilton E Holmes Station</name>
            <Point>
                <coordinates>-84.46804099999997,33.754627,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Indian Creek Station</name>
            <Point>
                <coordinates>-84.22925499999997,33.769212,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Inman Park-Reynoldstown Station</name>
            <Point>
                <coordinates>-84.35262,33.757317,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Kensington Station</name>
            <Point>
                <coordinates>-84.25223599999998,33.772472,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>King Memorial Station</name>
            <Point>
                <coordinates>-84.37588099999999,33.749978,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Lakewood-ft McPherson Station</name>
            <Point>
                <coordinates>-84.42930000000001,33.700629,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Lenox Station</name>
            <Point>
                <coordinates>-84.35785399999997,33.845137,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Lindbergh Center Station</name>
            <Point>
                <coordinates>-84.36922600000003,33.823608,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Medical Center Station</name>
            <Point>
                <coordinates>-84.35127,33.911593,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Midtown Station</name>
            <Point>
                <coordinates>-84.38665700000001,33.780737,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>North Avenue Station</name>
            <Point>
                <coordinates>-84.38707399999998,33.771935,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>North Springs Station</name>
            <Point>
                <coordinates>-84.357235,33.945416,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Oakland City Station</name>
            <Point>
                <coordinates>-84.42527899999999,33.71726400000001,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Peachtree Center Station</name>
            <Point>
                <coordinates>-84.387564,33.759532,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Sandy Springs Transit Station</name>
            <Point>
                <coordinates>-84.35135200000002,33.932104,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>Vine City Station</name>
            <Point>
                <coordinates>-84.40434800000003,33.756612,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>West End Station</name>
            <Point>
                <coordinates>-84.41296699999998,33.73584,0.0</coordinates>
            </Point>
        </Placemark>
        <Placemark>
            <styleUrl>#icon-503-FF8277</styleUrl>
            <name>West Lake Station</name>
            <Point>
                <coordinates>-84.446503,33.75347,0.0</coordinates>
            </Point>
        </Placemark>
        <Style id='icon-503-FF8277'>
            <IconStyle>
                <color>ff7782FF</color>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
                </Icon>
            </IconStyle>
        </Style>
    </Document>
</kml>

I cannot decrypt your code with my eyes :) Dont know exactly where and when things is suppose to happend. But, I saved your KML as a file, kml.kml, to mimick how ever you receives it :

$.ajax({
    url: 'kml.kml',
    success : function(kml) {
        console.log(getNearest(kml, -84.44, 33.65));
    }
});

The function getNearest parses the KML and returns an array of google.maps.LatLng 's which represent the nearest points (nearer than 0.1) based on the values of lat and lng , the center.

function getNearest(kml, lat, lng) {
    var result = [];
    //we can easily skip document/placemark/point
    var coords = kml.getElementsByTagName('coordinates');
    for (var i=0;i<coords.length;i++) {
        var points = coords[i].textContent.split(',');
        if ((Math.abs(points[0]-lat)<0.1) && (Math.abs(points[1]-lng)<0.1)) {
            result.push(new google.maps.LatLng(points[0], points[1]));
        }
    }
    return result;
}

In the case above, using the KML in the question, it returns an array of 8 latLngs you now can use as a base for plotting "hgihlighted" markers.

在此处输入图片说明

Here is my function that calculates distance between two points in kms:

unction distance(lat1, lng1, lat2, lng2) {
        var radlat1 = Math.PI * lat1 / 180;
        var radlat2 = Math.PI * lat2 / 180;
        var radlon1 = Math.PI * lng1 / 180;
        var radlon2 = Math.PI * lng2 / 180;
        var theta = lng1 - lng2;
        var radtheta = Math.PI * theta / 180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist);
        dist = dist * 180 / Math.PI;
        dist = dist * 60 * 1.1515;

        //Get in in kilometers
        dist = dist * 1.609344;

        return dist;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM