Tutorials

Article Content:Codeigniter google maps geolocation integration

Codeigniter google maps geolocation integration

Codeigniter google maps geolocation integration.

Hi my friends, in the last week I have an awesome task I liked to share, the client asked me to build a reservation service form which using google map service to find the closest providers to client location by detecting his location and search in the database by latitude and longtuide ,it was in this scenario:

1- User opens the form, once he did, Geolocation API will detect his location, send latitude and longitude to Google map and set it to hidden inputs.

2- Then Google map displays his location with information window with the sentence (Your Location Is Here), after this draw a circle around your location with 30 kilometers.

3- Under Google map, there's a (show positions) button related to a RelatedLocationAjax() function by onclick() event, when the user clicks the button the Ajax function will be fired to call a closest_locations() function in the controller.

4- closest_locations () function will call get_closest_locations() function in the model which has a query to select all providers by ServiceId and about 30 kilometers distance around current latitude and longitude to the user.

5- closest_locations() will take all results as array and Output to JSON array.

6- In the view, you will take the ajax result from RelatedLocationAjax() function and pass to add_markers(result) function which responsible to push all providers to the map as markers with their information

7-After drawing all markers you will see the count of providers around your location displays above the map, as example (10 Providers Available), and the map will reset position again to fit to your location with all markers to sure that all markers displayed on the map.

What Will You Learn In This Tutorial?
-Find Your Location with Geolocation API 
-Integrate Geolocation with Google Map To Display Your Location On Google Map 
-Store get coordinates from google maps in database MySQL Nearest Locations to Your Location With Mysql 
-Display locations dynamically with google markers 
-Draw circle around all markers
-Use info window dynamically to display users information 
-Pick up latitude and longitude from markers and geolocation to input form or ajax request 
-Integrate all these features with codeigniter

This is the theory side, let’s do it practically my friends to describe it step by step as we always do.

1- Create Database Schema :

Import Services Table and Providers to Your database "demo"

--
-- Table structure for table `ci_providers`
--

CREATE TABLE `ci_providers` (
  `user_id` int(11) NOT NULL,
  `fullname` varchar(40) NOT NULL,
  `lat` float(10,6) NOT NULL,
  `lng` float(10,6) NOT NULL,
  `email` varchar(254) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `ci_providers`
--

INSERT INTO `ci_providers` (`user_id`, `fullname`, `lat`, `lng`, `email`) VALUES
(1, 'ahmed', 29.956051, 30.913300, 'webeasystep@gmail.com'),
(2, 'fakhr', 29.957001, 30.914499, 'info@webeasystep.com');

--
-- Table structure for table `ci_services`
--

CREATE TABLE `ci_services` (
  `ServiceId` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `ServiceName` varchar(50) DEFAULT NULL,
  `ServiceDesc` varchar(255) DEFAULT NULL,
  `CreatedAt` int(11) NOT NULL,
  `Order` int(11) NOT NULL,
  `Status` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Services Table';

--
-- Dumping data for table `ci_services`
--

INSERT INTO `ci_services` (`ServiceId`, `user_id`, `ServiceName`, `ServiceDesc`, `CreatedAt`, `Order`, `Status`) VALUES
(1, 1, 'Service Name', 'Service Describtion', 1488098862, 1, 1),
(2, 2, 'Service Name', 'Service Describtion', 1488098862, 1, 1);

2- Create Services.php Controller with three functions 

book_service() function to load the book_service view and index to auto redirect when open the services controller

  // this function will redirect to book service page
    function index()
    {
        $this->book_service();
    }


 // this function to load service book page
    function book_service()
    {

        $this->view('content/book_service');

    }
closest_locations() function to receive ajax request and return closest providers as json output , we use foreach loop to change result by adding link in the info window (optionally)

    // this function receive ajax request and return closest providers
    function closest_locations(){

        $location =json_decode( preg_replace('/\\\"/',"\"",$_POST['data']));
        $lan=$location->longitude;
        $lat=$location->latitude;
        $ServiceId=$location->ServiceId;
        $base = base_url();
        $providers= $this->services_model->get_closest_locations($lan,$lat,$ServiceId);
        $indexed_providers = array_map('array_values', $providers);
        // this loop will change retrieved results to add links in the info window for the provider
        $x = 0;
        foreach($indexed_providers as $arrays => &$array){
            foreach($array as $key => &$value){
                if($key === 1){
                    $pieces = explode(",", $value);
                    $value = "$pieces[1]<a href='$base$pieces[0]'>More..</a>";
                }

                $x++;
            }
        }
        echo json_encode($indexed_providers,JSON_UNESCAPED_UNICODE);

    }

Data returned as json will be like this :

  var locations = [
     ["Ahmed Fakhr","Do this service 1 <a href=''>more</a>",  "29.957051,30.914529", "http://maps.google.com/mapfiles/ms/icons/blue.png"],
     ["Ali", "Do this service 1 <a href=''>more</a>", "29.956051,30.913529", "http://maps.google.com/mapfiles/ms/icons/green.png"],
     ["Mahmoud","Do this service 1 <a href=''>more</a>","29.955051,30.912529", "http://maps.google.com/mapfiles/ms/icons/red.png"],
     ];

3- Create Services_model.php Controller with one function

This function will select the only closeset providers in 30 kilometers distance  around current latitude and longitude by using Haversine Formula , and filter results by service type

class Services_model extends CI_Model
{

    // get closest providers
    // around 30 kilo meters from your location
    // by using latitude , longtuide and service id //
    function get_closest_locations($lng,$lat,$ServiceId){
        $results= $this->db->query("SELECT fullname,CONCAT(ci_providers.user_id,',',ServiceDesc) AS dscr,CONCAT(lat,',', lng) as pos,'http://maps.google.com/mapfiles/ms/icons/green.png' AS icon,
    ( 6371 * acos( cos( radians({$lat}) ) * cos( radians( `lat` ) ) * cos( radians( `lng` ) - radians({$lng}) ) + sin( radians({$lat}) ) * sin( radians( `lat` ) ) ) ) AS distance
    FROM ci_providers
    INNER JOIN ci_services  ON ci_services.user_id = ci_providers.user_id
    AND ci_services.ServiceId = $ServiceId
    HAVING distance <= 30
    ORDER BY distance ASC
      ")->result_array();
        return $results;
    }
}

4- Create book_service.php in views directory

First, add the form that collect servce id , available providers counter , display map, and fill the hidden inputs for current latitude and longtuide

 you will also notice  click event related to show closest providers button

                <form id="ServiceRequest" action="<?= current_url() ?>" method='post'>

                    <!-- dropdown service id  !-->
                    <div class="form-group">
                        <label class="control-label">ServiceType:</label>
                        <select name="Service_type" class="form-control" id="ServiceId">
                            <option>--all--</option>
                            <option value="1" selected>Service One</option>
                            <option value="2">Service Two</option>
                        </select>
                    </div>

                    <div class="form-group">
                        <!-- provider_counter service id  !-->
                        <label for="provider_counter" class="control-label">Closest Providers :</label>
                        <div class="text-lg-center alert-danger"id="info"></div>
                        <!-- display map  !-->
                        <div id="map" style="height: 600px; width:800px;"></div>
                        <!-- current latituide and longtuide  !-->
                        <input id="lat" type="hidden" value="" />
                        <input id="lng" type="hidden" value="" />
                        <button type="button" onclick="RelatedLocationAjax();">show_closest_providers</button>
                    </div>

                    <div id='submit_button'>
                        <input class="btn btn-success" type="submit" name="submit" value="add comment"/>
                    </div>
                </form>

The second part of this file is the most important part which do all the process in javascript to google map api 3 and with ajax requests, i describe all code with comments, so i recommended to read all comments to understand what we do here , i made i readable as much possible

<script>

    var lat = document.getElementById("lat"); // this will select the input with id = lat 
    var lng = document.getElementById("lng"); // this will select the input with id = lng   
    var info = document.getElementById("info"); // this will select the current div  with id = info 
    var ServiceId = document.getElementById("ServiceId"); // this will select the input with id = ServiceId 
    var locations = [];
    var km = 30; // this kilometers used to specify circle wide when use drawcircle function
    var Crcl ; // circle variable
    var map; // map variable
    var mapOptions = {
        zoom: 11,
        center: {lat:24.774265, lng:46.738586}
    }; // map options
    var markers = []; // markers array ,we will fill it dynamically
    var infoWindow = new google.maps.InfoWindow(); // information window ,we will use for our location and for markers
    // this will initiate when load the page and have all
    function initialize() {
        // set the map to the div with id = map and set the mapOptions as defualt
        map = new google.maps.Map(document.getElementById('map'),
            mapOptions);

        var infoWindow = new google.maps.InfoWindow({map: map});

        // get current location with HTML5 geolocation API.
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                var pos = {
                    lat: position.coords.latitude,
                    lng: position.coords.longitude
                };
                lat.value  =  position.coords.latitude ;
                lng.value  =  position.coords.longitude;
                info.nodeValue =  position.coords.longitude;
                // set the current posation to the map and create info window with (Here Is Your Location) sentense
                infoWindow.setPosition(pos);
                infoWindow.setContent('Here Is Your Location.');
                // set this info window in the center of the map 
                map.setCenter(pos);
                // draw circle on the map with parameters
                DrowCircle(mapOptions, map, pos, km);

            }, function() {
                // if user block the geolocatoon API and denied detect his location
                handleLocationError(true, infoWindow, map.getCenter());
            });
        } else {
            // Browser doesn't support Geolocation
            handleLocationError(false, infoWindow, map.getCenter());

        }
    }
    // to handle user denied
    function handleLocationError(browserHasGeolocation, infoWindow, pos) {
        infoWindow.setPosition(pos);
        infoWindow.setContent(browserHasGeolocation ?
            'Error: User Has Denied Location Detection.' :
            'Error: Your browser doesn\'t support geolocation.');
    }

    // to draw circle around 30 kilometers to current location
    function DrowCircle(mapOptions, map, pos, km ) {
        var populationOptions = {
            strokeColor: '#FF0000',
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: '#FF0000',
            fillOpacity: 0.35,
            map: map,
            center: pos,
            radius: Math.sqrt(km*500) * 100
        };
        // Add the circle for this city to the map.
        this.Crcl = new google.maps.Circle(populationOptions);
    }
    // this function to get providers with ajax request
    function RelatedLocationAjax() {
        $.ajax({
            type: "POST",
            url: "<?= base_url() ?>services/closest_locations",
            dataType: "json",
            data:"data="+ '{ "latitude":"'+ lat.value+'", "longitude": "'+lng.value+'", "ServiceId": "'+ServiceId.value+'" }',
            success:function(data) {
                // when request is successed add markers with results
                add_markers(data);
            }
        });
    }
    // this function to will draw markers with data returned from the ajax request
    function add_markers(data){
        var marker, i;
        var bounds = new google.maps.LatLngBounds();
        var infowindow = new google.maps.InfoWindow();
        // display how many closest providers avialable 
        document.getElementById('info').innerHTML = " Available:" + data.length + " Providers<br>";

        for (i = 0; i < data.length; i++) {
            var coordStr = data[i][2];
            var coords = coordStr.split(",");
            var pt = new google.maps.LatLng(parseFloat(coords[0]), parseFloat(coords[1]));
            bounds.extend(pt);
            marker = new google.maps.Marker({
                position: pt,
                map: map,
                icon: data[i][3],
                address: data[i][1],
                title: data[i][0],
                html: data[i][0] + "<br>" + data[i][1]
            });
            markers.push(marker);
            google.maps.event.addListener(marker, 'click', (function (marker, i) {
                return function () {
                    infowindow.setContent(marker.html);
                    infowindow.open(map, marker);
                }
            })
            (marker, i));

        }
        // this is important part , because we tell the map to put all markers inside the circle,
        // so all results will display and centered
        map.fitBounds(this.Crcl.getBounds());
    }

    google.maps.event.addDomListener(window, 'load', initialize);

</script>
<script async defer
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDNyLsAhFt4hIZKeNJYC244jPPayM0GhrY&callback=initialize">
</script>

The Finall result will be Like his

Download Link



  • Mamta
    Can you please upload a live demo also on this page so that we could run the code and see the result for once before start learning from this tutorial?
    April 7, 2017
    Reply
    • admin
      info@webeasystep.com
      sorry , but this is not available for this tutorial,you can download full example and follow every step in the video and the code will run thanks
      April 9, 2017
      Reply
  • Gema
    its very nice, but i want to enquire, when i click show closest provider, it dont want to show up, please sir can you help me about this
    May 4, 2017
    Reply
    • admin
      info@webeasystep.com
      Yes, this is true because you should update the table by nearest latitudes and longitudes to your current location; I tested it in the video after adding some nearest latitudes and longitudes to my current location, so to fix this 1- Get your current latitude and longitude 2- Add some nearest latitudes and longitudes in the table 3- Test again, and it will works
      May 4, 2017
      Reply
  • ayush
    HI...i imported all the tables in my demo database as well as extracted the zip file from the downloading link.But in the extracted link thsre is no folder of codeigniter-nearest-markers-map.Thus when i type URL llocalhost/codeigniter-nearest-markers-map/# error is coming...please send me the remaining file..
    July 22, 2017
    Reply
  • noorulbasar
    sir same yahe website mujay php awer javascript may chahye kia ho jaye gy ya ap help kar daingay?
    August 17, 2017
    Reply
    • admin
      info@webeasystep.com
      sorry ,but i don't understand your language
      August 18, 2017
      Reply
  • waqar
    Closest provide function not working properly. when i click to the button it does not perform any action.
    August 23, 2017
    Reply
    • admin
      info@webeasystep.com
      yes,because you should change the latitude and the longitude from the table to your current lat and long,this is because the function calculate 30 kilometer from this position
      September 9, 2017
      Reply
  • praveenkumarjami
    How to change the service provider location from static to dynamic... I want to use this code for vehicle tracking or device tracking...
    September 7, 2017
    Reply
    • admin
      info@webeasystep.com
      create another function for provider registration,when the user choose his location from the map you will detect his latitude and longitude,then set them with JavaScript to hidden input and save them into user details table,thats it, i recommended to see the part 2 for the tutorial from my YouTube channel
      September 9, 2017
      Reply
  • waqar
    i have change the value of lattitude and longitude in the table with my nearest lat and lon , it still doesn't work sir.when i click on show closest provider it doesn't perform any action with no error.
    September 20, 2017
    Reply
    • admin
      info@webeasystep.com
      hi waqr, try to inspect to show what happens in the console like what i did in the video tutorials
      September 20, 2017
      Reply
      • waqar
        waqar538shabbir@yahoo.com
        how do we add marker instead of info window.setpos(pos)?
        September 22, 2017
        Reply
        • admin
          info@webeasystep.com
          follow the video steps and you will see how to add markers dynamically
          September 24, 2017
          Reply
  • Ahsam
    Hi,Thank You Your material has been graeat source of support for me but i want to ask you that html5 navigator that you have used in your code to pick my current location is making a big diffrence of my current location it is not exact how can make it better..
    September 25, 2017
    Reply
    • admin
      info@webeasystep.com
      it is an option and for sure it is not always accurate solution,and you can use Google Maps Geolocation API as alternative
      September 26, 2017
      Reply
  • Abdur Rozaq
    i have download the source code & create the database. but it say Table 'demo.ci_sessions' doesn't exist . can you tell me how to fix that ? thanks :D
    October 11, 2017
    Reply
    • admin
      info@webeasystep.com
      you will find all tables here https://bitbucket.org/webeasystep/qr_code_generate_codeigniter/src/54064d146b5ea4597a30f75d25f7942cd89b3d41/application/tables/?at=master
      October 15, 2017
      Reply
  • mahmod nasser
    hey bro, i'm mahmod thank you very much for this explaine , i have one question i can do this only on set of (lat, long) as json/html ?? pure html and javascript ??
    December 27, 2017
    Reply
    • admin
      info@webeasystep.com
      Hi Mohamed , You are welcome , But Sorry i am no understanding what did you mean ,please explain in details thanks
      December 28, 2017
      Reply
  • abhishek shukla
    Failed to load resource: the server responded with a status of 404 (Not Found) starter-template.css Failed to load resource: the server responded with a status of 404 (Not Found) bootstrap.min.js Failed to load resource: the server responded with a status of 404 (Not Found) ie10-viewport-bug-workaround.js Failed to load resource: the server responded with a status of 404 (Not Found) (index):98 Uncaught ReferenceError: google is not defined at (index):98 bootstrap.min.js Failed to load resource: the server responded with a status of 404 (Not Found) ie10-viewport-bug-workaround.js Failed to load resource: the server responded with a status of 404 (Not Found) 6/codeigniter-nearest-markers-map/services/closest_locations Failed to load resource: the server responded with a status of 404 (Not Found) bootstrap.min.css Failed to load resource: the server responded with a status of 404 (Not Found) starter-template.css Failed to load resource: the server responded with a status of 404 (Not Found) sir i m having trouble to to track nearset lcation ?
    March 30, 2018
    Reply
  • Thunder
    This is an increidble tutorial& video! I have been trying to create a script that simply connects to a mysql table containing rows of businesses with address fields that contain the information my Google API Geocoder URL can submit to return the latitude & longitude. The script would read the table records, return the lat & long values, UPDATE the table records placing values into the lat & long fields, then move to the next record, submit it to Google API, handle errors, then move to next record until ended. I see elements of your script that are usable but I have not figured out the Update mysql table conditional logic to take the returned data from Google and just SET the lat & long fields before moving to the next record. Have you ever made a script that does this simpler operation? Thank you for your kind reply!
    July 20, 2018
    Reply
  • Anamica
    nice tutorial
    October 23, 2018
    Reply
  • Leandro
    this error appears ........ An error has occurred. This page has not loaded Google Maps correctly. Discover the technical details of the problem in the JavaScript console. how can I solve that..?
    November 5, 2018
    Reply
  • Pandy
    how to fix it? --- Severity: 8192 Message: __autoload() is deprecated, use spl_autoload_register() instead Filename: config/config.php Line Number: 355 Backtrace: File: C:\xampp\htdocs\codeigniter-nearest-markers-map\index.php Line: 293 Function: require_once
    December 11, 2018
    Reply
  • fathur
    hai admin , when i clik show closed provider it doesn't to show the place i want . i was change the lattitude and longitude on the table same with my location but it same doesnt work . can you help me to fix it ?
    May 28, 2019
    Reply
  • sangeetha
    HI sir, I need a another filter that is two types of filters in this tutorial.can pls help me in this.
    September 1, 2019
    Reply
  • Jagruti Metaliya
    Hello Sir, Thank you for the tutorial it will work fine with my code, But I have one confusion , what 6371 ?? I have read the Haversine formula but didn't understand. can you please help me.. Thank you in advance.
    October 9, 2019
    Reply
  • saadou belbedj
    السلام عليكم اولا شكرا على مجهوداتك الجبارة ..اخي العزيز عند الضغط على الرابط لرفع الملف وعند رفعه من الرابط المباشر تجد انه الملفات الموجودة في الرار ليست نفسها المةجودة في شرحك في التوتوريال ارجو الرد وشكرا
    May 28, 2020
    Reply

Leave a Reply

Your email address will not be published.


Notify me of followup comments via e-mail.
You can also Subscribe without commenting.