Neil K
Neil K

Reputation: 1328

Display map markers inside area

I have a large number of locations stored in a database which I want to display on a Google map when they inside a specified area. I have most of the functionality I want working, with a route searchable between two places and all the map markers in the database showing on the map.

The part I am unsure of is how to display only the markers which are inside the boxpolys created by RouteBoxer. I am pulling in the locations from a static JSON file for testing purposes.

 var map = null;
 var boxpolys = null;
 var directions = null;
 var routeBoxer = null;
 var distance = null; // km

 function initialize() {

   var mapOptions = {
     center: new google.maps.LatLng(54.604008, -5.930415),
     mapTypeId: google.maps.MapTypeId.ROADMAP,
     zoom: 8
   };

   var input = document.getElementById('from');
   var autocomplete = new google.maps.places.Autocomplete(input);
   var input2 = document.getElementById('to');
   var autocomplete2 = new google.maps.places.Autocomplete(input2);


   map = new google.maps.Map(document.getElementById("map"), mapOptions);
   routeBoxer = new RouteBoxer();

   directionService = new google.maps.DirectionsService();
   directionsRenderer = new google.maps.DirectionsRenderer({
     map: map
   });

 }

 function mapmarkers() {

   $.getJSON('empdata.json', function(data) {
     var json = data;
     for (var i = 0; i < json.length; i++) {
       var obj = json[i];

       var marker = new google.maps.Marker({
         position: new google.maps.LatLng(obj.latitude, obj.longitude),
         map: map,
         title: obj.siteName
       });
       marker.addListener('click', function() {
         infowindow.open(map, marker);
       });


     }
   });
 }



 function route() {
   // Clear any previous route boxes from the map
   clearBoxes();

   // Convert the distance to box around the route from miles to km
   distance = parseFloat(document.getElementById("distance").value) * 1.609344;


   var request = {
     origin: document.getElementById("from").value,
     destination: document.getElementById("to").value,
     travelMode: google.maps.DirectionsTravelMode.DRIVING
   }

   // Make the directions request
   directionService.route(request, function(result, status) {
     if (status == google.maps.DirectionsStatus.OK) {
       directionsRenderer.setDirections(result);

       // Box around the overview path of the first route
       var path = result.routes[0].overview_path;
       var boxes = routeBoxer.box(path, distance);
       drawBoxes(boxes);
     } else {
       alert("Directions query failed: " + status);
     }
   });
   mapmarkers();
 }

 // Draw the array of boxes as polylines on the map
 function drawBoxes(boxes) {
   boxpolys = new Array(boxes.length);
   for (var i = 0; i < boxes.length; i++) {
     boxpolys[i] = new google.maps.Rectangle({
       bounds: boxes[i],
       fillOpacity: 0,
       strokeOpacity: 1.0,
       strokeColor: '#000000',
       strokeWeight: 1,
       map: map
     });
   }
 }

 // Clear boxes currently on the map
 function clearBoxes() {
   if (boxpolys != null) {
     for (var i = 0; i < boxpolys.length; i++) {
       boxpolys[i].setMap(null);
     }
   }
   boxpolys = null;
 }
* {
  box-sizing: border-box;
}
body {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  font: 16px"Source Sans", helvetica, arial, sans-serif;
  font-weight: 400;
}
#map {
  height: calc(100vh - 80px);
  width: 100vw;
  position: absolute;
  bottom: 0;
}
<html>

<head>
  <script src="http://maps.google.com/maps/api/js?key=AIzaSyBHiqPzkP8tv-Pwji2wsI6-WM5W6-O0Y78&libraries=places" type="text/javascript"></script>
  <script src="http://dev.bigpixelcreative.com/maptest/js/routeboxer.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>

<body onload="initialize();">
  <div id="floating-panel">
    <b>Start: </b>
    <input id="from" type="text" size="50">
    <b>End: </b>
    <input id="to" type="text" size="50">
    <b>Radius: </b>
    <input id="distance" type="text" size="10">
    <button id="sbmtButton" onclick="route()">Search</button>

  </div>
  <div id="map"></div>
</body>

</html>

Upvotes: 2

Views: 1655

Answers (2)

Rodrigo Esquivel
Rodrigo Esquivel

Reputation: 68

The first solution that comes out of the box is to make an iteration between boxpolys and your markers, then ask if the marker is in the location. If is, then put it on the map.

function   containsinrectangle(boxpolys){
    for (var i = 0; i < json.length; i++) {
        var obj = json[i];
            for (var a = 0; i < boxpolys.length; i++) {
            // Ask if the position exist in the rectangles
           //  take note I am using the rectangle class's methods
                if(boxpolys[a].getBounds().contains(new google.maps.LatLng(obj.latitude,obj.longitude))){
                    //do your routine to create the marker
                }      
            }


    }

}

Now this solution is way all exponential, so you have to take to additional measures in order to make this to function more efficiently. If you are using a Geographic Database, I suggest bring only the markers that are in the bounds of the visible zone of the map for example so then the numbers of iterations decrease.

As an additional note, yes you can ask to the rectangle class a contain method, The rectangle class does not have it by itself but if you ask for the getBounds() method it will return an object, the LatLngBounds that do. I tested myself, but also you take a look at the links below for more documentation:

google maps api : determine if point is inside shape

and in the API DOC: https://developers.google.com/maps/documentation/javascript/reference?hl=en&csw=1#Rectangle

Because the Getbounds method return a LatLngBounds object take a look a this additional link.

https://developers.google.com/maps/documentation/javascript/reference?hl=en&csw=1#LatLngBounds

Upvotes: 2

sunny kashyap
sunny kashyap

Reputation: 2293

Istead of rectangle class you should use polgyn class. Then you can determine about a location that it exists in that location or not with containsLocation() function

Do it Like this

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Polygon arrays</title>
    <style>


html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
  #map {
    height: 100%;
  }
</style>


</head>
  <body>
    <div id="map"></div>
    <script>
      // This example requires the Geometry library. Include the libraries=geometry
      // parameter when you first load the API. For example:
      // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

  function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: 24.886, lng: -70.269},
      zoom: 5,
    });

    var triangleCoords = [
      {lat: 25.774, lng: -80.19},
      {lat: 18.466, lng: -66.118},
      {lat: 32.321, lng: -64.757}
    ];

    var bermudaTriangle = new google.maps.Polygon({paths: triangleCoords});

    google.maps.event.addListener(map, 'click', function(e) {
      var resultColor =
          google.maps.geometry.poly.containsLocation(e.latLng, bermudaTriangle) ?
          'red' :
          'green';

      new google.maps.Marker({
        position: e.latLng,
        map: map,
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          fillColor: resultColor,
          fillOpacity: .2,
          strokeColor: 'white',
          strokeWeight: .5,
          scale: 10
        }
      });
    });
  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry&callback=initMap"
     async defer></script>

for more information see this link

Upvotes: 0

Related Questions