0

ユーザーが単一のマーカーから特定の距離内にいるかどうかを判断することに成功しました。次にやりたいことは、ユーザーが配列に保存されている複数の場所の近くにいるかどうかをスクリプトでチェックすることです。はいの場合、スクリプトでそれぞれの場所に固有のイベントをトリガーしたいと考えています。

これが私のコードです:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true"></script>
<script>
    var map, GeoMarker;

  function initialize() {
    var mapOptions = {
        panControl: false,
        mapTypeControl: false,
        streetViewControl: false,
        overviewMapControl: false,
        disableDoubleClickZoom: false,  
      scrollwheel: false,
      zoom: 17,
      center: new google.maps.LatLng(99.000, 10.000),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

// Markers

var locations = [
  ['1', 49.463344,11.079942, 6],
  ['2', 49.462309,11.078335, 4],
  ['3', 49.463466,11.084214, 5],
  ['4', 49.46348,11.076061, 3],
  ['5', 49.464345,11.07885, 2],
  ['6', 49.461095,11.079601, 1]
];

var infowindow = new google.maps.InfoWindow();

var mark1, i;

for (i = 0; i < locations.length; i++) {  
  mark1 = new google.maps.Marker({
    position: new google.maps.LatLng(locations[i][1], locations[i][2]),
    map: map
  });
google.maps.event.addListener(mark1, 'click', (function(mark1, i) {
    return function() {
      infowindow.setContent(locations[i][0]);
      infowindow.open(map, mark1);
    }
  })(mark1, i));
}

GeoMarker = new GeolocationMarker();

var IsWithinRadius = false;
var RadiusInMeters = 10;
var LocationOfInterest = new google.maps.LatLng(49.463344,11.079942); // Needs to be a variable!

google.maps.event.addListener(GeoMarker, 'position_changed', function() {map.setCenter(this.getPosition());

var UserPosition = this.getPosition();

var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {IsWithinRadius = false;}

var IsCurrentPositionInRadius = 
Math.abs(google.maps.geometry.spherical.computeDistanceBetween(UserPosition, LocationOfInterest)) <= RadiusInMeters; // Radius reached?
var JustEnteredRadius = !IsWithinRadius && IsCurrentPositionInRadius; // Radius reached!
IsWithinRadius = IsCurrentPositionInRadius;

if(JustEnteredRadius) {
// Trigger Event
}
}
});

GeoMarker.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>

ご覧のとおり、ユーザーが特定の座標から半径 10 メートル以内にいるかどうかを確認するスクリプトがあります。配列内のすべての場所をチェックするようにするには、スクリプトをどのように変更する必要がありますか?

大変助かります!

4

1 に答える 1

0

マーカーを作成するときは、それらを配列に格納するか、各位置をそのマーカーに変換して、位置データをマーカー自体に格納します。次に、その配列をループし、ユーザーからの各マーカーの距離を確認して保存し、一時的に使用するために各マーカーを新しい配列に配置する関数が必要です。次に、その新しい配列内のマーカーをユーザーからの距離で並べ替え、ユーザーからの最大距離を超えるマーカーをその配列から削除します。この配列を取得すると、その中に何か残っている場合、最初の項目が最も近いマーカーであることがわかります。現在処理しているマーカーに基づいて、発生させたい「イベント」を決定します。

たとえば、マウスに追従するマーカーを使用して GeolocationMarker のインスタンスをシミュレートするデモを次に示します。この例では、radiusInMeters は 100 メートルに設定されており、デモをより簡単に実行できるようになっています。また、デモは、ユーザーがまだ「訪問」していないマーカーに対してのみ作用することに注意してください。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Markers Treasure Hunt</title>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry&sensor=false"></script>
</head>
<body>
<div id="map_canvas" style="width:500px; height:400px; margin:0 auto;"></div>
<div id="UserCoordinates" style="text-align:center;">Mouse over the map and go close to the markers</div>
<script>

function initialize() {
    var i, marker, GeoMarker,
        gm = google.maps,
        mapOptions = {
            panControl: false,
            mapTypeControl: false,
            streetViewControl: false,
            overviewMapControl: false,
            disableDoubleClickZoom: false,
            scrollwheel: false,
            zoom: 17,
            center: new google.maps.LatLng(49.452, 11.077),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        },
        map = new gm.Map(document.getElementById('map_canvas'), mapOptions),
        locations = [
            ['Treasure 1', 49.463344, 11.079942, 6],
            ['Treasure 2', 49.462309, 11.078335, 4],
            ['Treasure 3', 49.463466, 11.084214, 5],
            ['Treasure 4', 49.46348, 11.076061, 3],
            ['Treasure 5', 49.464345, 11.07885, 2],
            ['Treasure 6', 49.461095, 11.079601, 1]
        ],
        infowindow = new gm.InfoWindow(),
        markersVisited = 0,
        bounds = new gm.LatLngBounds(),
        GeoMarker = new gm.Marker({
            position: new gm.LatLng(100, 0),
            icon: 'http://maps.google.com/mapfiles/kml/pal3/icon20.png'
    });
    gm.event.addListener(map, 'mousemove', function (evt) {
        GeoMarker.setPosition(evt.latLng);
    });
    for (i = 0; i < locations.length; i++) {
        latLng = new gm.LatLng(locations[i][1], locations[i][2]);
        bounds.extend(latLng);
        marker = new gm.Marker({
            position: latLng,
            map: map,
            icon: 'http://google.com/mapfiles/kml/paddle/'+ (i + 1) +'-lv.png',
            index: i,
            title: locations[i][0],
            data: locations[i][3],
            visited: false
        });
        gm.event.addListener(marker, 'click', function () {
            infowindow.setContent(this.title);
            infowindow.open(map, this);
        });
        locations[i] = marker;
    }
    map.fitBounds(bounds);
    function getClosestMarkers(userPosition, maxDistance) {
        var i, marker, mPos,
            len = locations.length,
            arr = [];
         //assign distanceFromUser for all markers
        for (i = 0; i < len; i++) {
            marker = locations[i];
            mPos = marker.getPosition();
            marker.distanceFromUser = gm.geometry.spherical.computeDistanceBetween(userPosition, mPos);
             //ignoring markers which have been 'visited' already, if they
             //have not yet been 'visited', store them in arr
            if (!marker.visited) {
                arr.push(marker);
            }
        }
         //arrange items in arr by distanceFromUser, closest to furthest
        arr.sort(function (m1, m2) {
            var a = m1.distanceFromUser,
                b = m2.distanceFromUser;
            if (a == b) {
                return 0;
            }
            return (a > b) ? 1 : -1;
        });
         //remove all markers from arr which are greater than maxDistance away from userPosition
        for (i = arr.length - 1; i >= 0; i--) {
            marker = arr[i];
            if (marker.distanceFromUser > maxDistance) {
                arr.pop();
            }
        }
        return arr;
    }
    gm.event.addListener(
        GeoMarker,
        'position_changed',
        function () {
            var marker, closestMarkers,
                radiusInMeters = 100,
                userPosition = this.getPosition(),
                displayElement = document.getElementById('UserCoordinates');
            if (userPosition === null) {
                return;
            }
            //only use the below line with your actual GeoMarker instance of GeolocationMarker
            //map.setCenter(userPosition);
            closestMarkers = getClosestMarkers(userPosition, radiusInMeters);
            if (markersVisited == locations.length) {
                displayElement.innerHTML = 'All markers already found';
            } else if (closestMarkers.length) {
                //here is where you would determine what event to trigger,
                //based upon which marker closestMarkers[0] is
                //location.replace("puzzle.php");
                marker = closestMarkers[0];
                displayElement.innerHTML = marker.title;
                displayElement.innerHTML += ', marker.data = '+ marker.data +', marker.index = '+ marker.index;
                marker.visited = true;
                markersVisited++;
            }
        }
    );
    GeoMarker.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);

</script>
</body>
</html>

フィドルの例: http://jsfiddle.net/uXpGD/

そこに mousemove の代わりに GeolocationMarker を組み込む方法を理解していただければ幸いです。基本的には、GeolocationMarker スクリプトを追加し、マップ上の mousemove のイベント リスナーを削除し、ここで使用されているマーカーの代わりに GeolocationMarker を作成し、マップのコメントを解除するだけです。 position_changed イベント ハンドラで setCenter(userPosition) を呼び出します。ああ、radiusInMeters を 10 に戻します。

于 2013-11-03T10:33:17.267 に答える