Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
607 views
in Technique[技术] by (71.8m points)

google maps api 3 - Calculate Marker In Circle

Base on this http://jsfiddle.net/kaiser/wzcst/light/ example, but the marker in circle is not accurate, when the marker is outside circle and near to circle it is consider inside the circle which is not wanted.

Is there any other idea?

code snippet (from linked fiddle):

window.onload = function init() {
  var
    contentCenter = '<span class="infowin">Center Marker (draggable)</span>',
    contentA = '<span class="infowin">Marker A (draggable)</span>',
    contentB = '<span class="infowin">Marker B (draggable)</span>';
  var
    latLngCenter = new google.maps.LatLng(37.081476, -94.510574),
    latLngCMarker = new google.maps.LatLng(37.0814, -94.5105),
    latLngA = new google.maps.LatLng(37.2, -94.1),
    latLngB = new google.maps.LatLng(38, -93),
    map = new google.maps.Map(document.getElementById('map'), {
      zoom: 7,
      center: latLngCenter,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      mapTypeControl: false
    }),
    markerCenter = new google.maps.Marker({
      position: latLngCMarker,
      title: 'Location',
      map: map,
      draggable: true
    }),
    infoCenter = new google.maps.InfoWindow({
      content: contentCenter
    }),
    markerA = new google.maps.Marker({
      position: latLngA,
      title: 'Location',
      map: map,
      draggable: true
    }),
    infoA = new google.maps.InfoWindow({
      content: contentA
    }),
    markerB = new google.maps.Marker({
      position: latLngB,
      title: 'Location',
      map: map,
      draggable: true
    }),
    infoB = new google.maps.InfoWindow({
      content: contentB
    })
    // exemplary setup: 
    // Assumes that your map is signed to the var "map"
    // Also assumes that your marker is named "marker"
    ,
    circle = new google.maps.Circle({
      map: map,
      clickable: false,
      // metres
      radius: 100000,
      fillColor: '#fff',
      fillOpacity: .6,
      strokeColor: '#313131',
      strokeOpacity: .4,
      strokeWeight: .8
    });
  // attach circle to marker
  circle.bindTo('center', markerCenter, 'position');

  var
  // get the Bounds of the circle
    bounds = circle.getBounds()
    // Note spans
    ,
    noteA = jQuery('.bool#a'),
    noteB = jQuery('.bool#b');

  noteA.text(bounds.contains(latLngA));
  noteB.text(bounds.contains(latLngB));

  // get some latLng object and Question if it's contained in the circle:
  google.maps.event.addListener(markerCenter, 'dragend', function() {
    latLngCenter = new google.maps.LatLng(markerCenter.position.lat(), markerCenter.position.lng());
    bounds = circle.getBounds();
    noteA.text(bounds.contains(latLngA));
    noteB.text(bounds.contains(latLngB));
  });

  google.maps.event.addListener(markerA, 'dragend', function() {
    latLngA = new google.maps.LatLng(markerA.position.lat(), markerA.position.lng());
    noteA.text(bounds.contains(latLngA));
  });

  google.maps.event.addListener(markerB, 'dragend', function() {
    latLngB = new google.maps.LatLng(markerB.position.lat(), markerB.position.lng());
    noteB.text(bounds.contains(latLngB));
  });

  google.maps.event.addListener(markerCenter, 'click', function() {
    infoCenter.open(map, markerCenter);
  });

  google.maps.event.addListener(markerA, 'click', function() {
    infoA.open(map, markerA);
  });

  google.maps.event.addListener(markerB, 'click', function() {
    infoB.open(map, markerB);
  });

  google.maps.event.addListener(markerCenter, 'drag', function() {
    infoCenter.close();
    noteA.html("draggin&hellip;");
    noteB.html("draggin&hellip;");
  });

  google.maps.event.addListener(markerA, 'drag', function() {
    infoA.close();
    noteA.html("draggin&hellip;");
  });

  google.maps.event.addListener(markerB, 'drag', function() {
    infoB.close();
    noteB.html("draggin&hellip;");
  });
};
body {
  margin: 0;
  padding: 0
}
html,
body,
#map {
  height: 100%;
  font-family: Arial, sans-serif;
  font-size: .9em;
  color: #fff;
}
#note {
  text-align: center;
  padding: .3em;
  10px;
  background: #009ee0;
}
.bool {
  font-style: italic;
  color: #313131;
}
.info {
  display: inline-block;
  width: 40%;
  text-align: center;
}
.infowin {
  color: #313131;
}
#title,
.bool {
  font-weight: bold;
}
<script src="http://maps.googleapis.com/maps/api/js"></script>
<div id="note"><span id="title">&raquo;Inside the circle?&laquo;</span>
  <hr /><span class="info">Marker <strong>A</strong>: <span id="a" class="bool"></span></span>&larr;&diams;&rarr; <span class="info">Marker <strong>B</strong>: <span id="b" class="bool"></span></span>
</div>
<div id="map">test</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A google.maps.LatLngBounds is a rectangle. You need a polygon "contains" function. For a circle this can be reduced to testing whether the point is less than the radius away from the center.

Example

code snippet:

window.onload = function init() {
  var
    contentCenter = '<span class="infowin">Center Marker (draggable)</span>',
    contentA = '<span class="infowin">Marker A (draggable)</span>',
    contentB = '<span class="infowin">Marker B (draggable)</span>';
  var
    latLngCenter = new google.maps.LatLng(37.081476, -94.510574),
    latLngCMarker = new google.maps.LatLng(37.0814, -94.5105),
    latLngA = new google.maps.LatLng(37.2, -94.1),
    latLngB = new google.maps.LatLng(38, -93),
    map = new google.maps.Map(document.getElementById('map'), {
      zoom: 7,
      center: latLngCenter,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      mapTypeControl: false
    }),
    markerCenter = new google.maps.Marker({
      position: latLngCMarker,
      title: 'Center of Circle',
      map: map,
      draggable: true
    }),
    infoCenter = new google.maps.InfoWindow({
      content: contentCenter
    }),
    markerA = new google.maps.Marker({
      position: latLngA,
      title: 'A',
      map: map,
      label: "A",
      draggable: true
    }),
    infoA = new google.maps.InfoWindow({
      content: contentA
    }),
    markerB = new google.maps.Marker({
      position: latLngB,
      title: 'B',
      map: map,
      label: "B",
      draggable: true
    }),
    infoB = new google.maps.InfoWindow({
      content: contentB
    })
    // exemplary setup: 
    // Assumes that your map is signed to the var "map"
    // Also assumes that your marker is named "marker"
    ,
    circle = new google.maps.Circle({
      map: map,
      clickable: false,
      // metres
      radius: 100000,
      fillColor: '#fff',
      fillOpacity: .6,
      strokeColor: '#313131',
      strokeOpacity: .4,
      strokeWeight: .8
    });
  // attach circle to marker
  circle.bindTo('center', markerCenter, 'position');

  var
  // get the Bounds of the circle
    bounds = circle.getBounds()
    // Note spans
    ,
    noteA = jQuery('.bool#a'),
    noteB = jQuery('.bool#b');

  noteA.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerA.getPosition(), markerCenter.getPosition())));
  noteB.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerB.getPosition(), markerCenter.getPosition())));

  // get some latLng object and Question if it's contained in the circle:
  google.maps.event.addListener(markerCenter, 'dragend', function() {
    latLngCenter = markerCenter.position;
    noteA.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerA.getPosition(), markerCenter.getPosition())));
    noteB.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerB.getPosition(), markerCenter.getPosition())));
  });

  google.maps.event.addListener(markerA, 'dragend', function() {
    latLngA = markerA.position;
    noteA.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerA.getPosition(), markerCenter.getPosition())));
  });

  google.maps.event.addListener(markerB, 'dragend', function() {
    latLngB = markerB.position;
    noteB.text((100000 > google.maps.geometry.spherical.computeDistanceBetween(markerB.getPosition(), markerCenter.getPosition())));
  });

  google.maps.event.addListener(markerCenter, 'click', function() {
    infoCenter.open(map, markerCenter);
  });

  google.maps.event.addListener(markerA, 'click', function() {
    infoA.open(map, markerA);
  });

  google.maps.event.addListener(markerB, 'click', function() {
    infoB.open(map, markerB);
  });

  google.maps.event.addListener(markerCenter, 'drag', function() {
    infoCenter.close();
    noteA.html("draggin&hellip;");
    noteB.html("draggin&hellip;");
  });

  google.maps.event.addListener(markerA, 'drag', function() {
    infoA.close();
    noteA.html("draggin&hellip;");
  });

  google.maps.event.addListener(markerB, 'drag', function() {
    infoB.close();
    noteB.html("draggin&hellip;");
  });
};
body {
  margin: 0;
  padding: 0
}
html,
body,
#map {
  height: 100%;
  font-family: Arial, sans-serif;
  font-size: .9em;
  color: #fff;
}
#note {
  text-align: center;
  padding: .3em;
  10px;
  background: #009ee0;
}
.bool {
  font-style: italic;
  color: #313131;
}
.info {
  display: inline-block;
  width: 40%;
  text-align: center;
}
.infowin {
  color: #313131;
}
#title,
.bool {
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="note"><span id="title">&raquo;Inside the circle?&laquo;</span>
  <hr /><span class="info">Marker <strong>A</strong>: <span id="a" class="bool"></span></span>&larr;&diams;&rarr; <span class="info">Marker <strong>B</strong>: <span id="b" class="bool"></span></span>
</div>
<div id="map">test</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...