0
votes

I want to build a tool which allows me to search and locate my database (longitude and latitude users ), within a certain radius. i already have a googlemaps API key.

Is there a ready made tool or API ?. Any tips or suggestions?

here is my laravel code, so far i have fetched my db users as markers in map.

  #map {
    height: 50%;
  }

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

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




<script>
    key=YOUR_API_KEY&libraries=places">

let users = ; console.log(users);

function initMap() { var myLatLng = {lat: 53.2193133, lng: 6.5669632};

      var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 11,
        center: myLatLng
      });

      var markers = [];
      for (let i of users) {
        markers.push(
          new google.maps.Marker({
            position: {lat: parseFloat(i.latitude), lng: parseFloat(i.longitude)},
            map: map,
            title: i

            //hier wil ik eigelijk nog de naam van de gebruiker die vertoont wordt als je op de marker klikt. 
        }));


      }

      // var marker = new google.maps.Marker({
      //   position: myLatLng,
      //   map: map,
      //   title: 'Hello World!'
      // });
      // var marker2 = new google.maps.Marker({
      //   position: {lat: 53.2183133, lng: 6.5669632},
      //   map: map,
      //   title: 'Hello World!'
      // });


      // var myLatlng = new google.maps.LatLng(53.2193133,6.5669632);

      // var mapOptions = {
      //   zoom: 4,
      //   center: myLatlng
      // }
      // // var map = new google.maps.Map(document.getElementById("map"), mapOptions);

      // // var marker = new google.maps.Marker({
      // //   position: myLatlng,
      // //   title:"Hello World!"
      // });

}

// i was thinking to try something like this function to put in my controller

public function zoek(Request $request){

        $lat=$request ->lat;
        $lng=$request ->lng;

        $users=User::whereBetween('lat', [lat-0.05, lat+0.05])   ??

1
Not hard to find spatial radius formulas for whatever database you are usingcharlietfl
What is the desired technology that you want to use to calculate the radius? This is not asked. What where your efforts, where did you fail?michaeak

1 Answers

0
votes

I use a worker thread so as not to block the main-thread and make it interruptble to terminate a current search if a new set of search criteria is available.

In the mainline something like: -

function createFacilityMarkers(xmlhttp){
    facFinder = new Worker("facfinder.js");
    facFinder.addEventListener('message', workerInit, false);

    facFinder.postMessage({'cmd' : 'init', 'load' : xmlhttp.responseText});

facfinder.js looks like: -

importScripts("Tier3Toolbox.js");

var currVintage = 0;
var inBounds = false;
var facFilter = [];
var imageProlog = "<div style='height:5em; width:5em; display:inline-block;vertical-align:middle;'>" +
                  "<img style='height:100%; width: 100%; max-height:100%; max-width:100%' src='";
var imageEpilog = "' ></div>";
var facilityTable, lineBreak;

self.addEventListener('message', function(e) 
{
  var data = e.data;
  switch (data.cmd) {
    case 'init':
      initThread(data.load);
      break;
    case 'initFilter':
      for (var i=0; i<data.filterTable.length; i++) {
        facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
      }
      break;
    case 'filter':
      facFilter = [];
      for (var i=0; i<data.filterTable.length; i++) {
        if (data.filterTable[i].facSelected)
          facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
      }
      break;
    case 'search':
      var searchVintage = ++currVintage;
      var tableSearch = new searcher(searchVintage, data);
      break;
    case 'reset':
      reset();
      self.postMessage({'reset': true});
      break;
    case 'stop':
      self.postMessage({'success' : true});
      self.close(); 
      break;
    default:
      self.postMessage({'success' : false, 'msg' : data.msg});
  };
}, false);

function initThread(msg) 
{
    facilityTable = JSON.parse(msg);
    reset();

    self.postMessage({'success' : true, 
                      'cnt'     : facilityTable.length
                    });     
}   

function reset() 
{
    for (var i=0; i<facilityTable.length; i++) {
        facilityTable[i].visible=false
    }
    currVintage = 0;
}   

function searcher(searchVintage, msg)
{
    var myVintage = searchVintage;
    var facIndex  = -1;
    var msg       = msg;

    var checkLoop = function()
    {
        if (myVintage != currVintage)
            return;

        if (++facIndex == facilityTable.length)
            return;

        inBounds = geoFencer.call(this, msg);

        if (inBounds) {
            var facMatch = 0;
            var bubbleHTML = "";
            for (var i=0; i<facilityTable[facIndex].facilities.length; i++){
                var currFac = facilityTable[facIndex].facilities[i];
                if (facFilter[currFac.locTypeId] != undefined) {
                    if (facMatch != 0) {
                        lineBreak = (facMatch / 3);
                        if (lineBreak == lineBreak.toFixed(0)) {
                            bubbleHTML += "<br />";
                        }
                    }
                    facMatch++;
                    bubbleHTML += imageProlog + facFilter[currFac.locTypeId].icon + imageEpilog;

                }
            }
            if (facMatch == 0) {
                inBounds = false;
            }
        }

        if (inBounds != facilityTable[facIndex].visible) {
            self.postMessage({'match'       : inBounds,
                              'facIndex'    : facIndex,
                              'scopeVintage': msg.scopeVintage,
                              'bubbleHTML'  : bubbleHTML,
                              'success'     : true
                            }); 
            facilityTable[facIndex].visible = inBounds;
        }

        setTimeout(checkLoop,0);
    }

    var circleCheck = function(msg) 
    {
        var diff = Tier3Toolbox.calculateDistance(
                        msg.centerLat,
                        msg.centerLng,
                        facilityTable[facIndex].searchLat,
                        facilityTable[facIndex].searchLng);

        if (msg.radius > diff)
            return true;        

        return false;
    }

    var rectangleCheck = function(msg) 
    {
        if (facilityTable[facIndex].searchLat > msg.SWLat &&
            facilityTable[facIndex].searchLat < msg.NELat &&
            facilityTable[facIndex].searchLng > msg.SWLng &&
            facilityTable[facIndex].searchLng < msg.NELng)
            return true;        

        return false;
    }

    var GEOFENCER = [circleCheck,rectangleCheck];
    var geoFencer = GEOFENCER[msg.checker];

    setTimeout(checkLoop,0);
    return this;
}

And the calculateDistance function is: -

    Tier3Toolbox.calculateDistance =
    function(lat1, lon1, lat2, lon2){
        var dLat = this.toRad(lat2 - lat1);
        var dLon = this.toRad(lon2 - lon1);
        var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) * 
                Math.cos(this.toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
        var distance = this.EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return distance;
    }