
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.
-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
-
MamtaCan 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?Reply
-
admininfo@webeasystep.comsorry , 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 thanksReply
-
-
Gemaits 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 thisReply
-
admininfo@webeasystep.comYes, 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 worksReply
-
-
ayushHI...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..Reply
-
noorulbasarsir same yahe website mujay php awer javascript may chahye kia ho jaye gy ya ap help kar daingay?Reply
-
admininfo@webeasystep.comsorry ,but i don't understand your languageReply
-
-
waqarClosest provide function not working properly. when i click to the button it does not perform any action.Reply
-
admininfo@webeasystep.comyes,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 positionReply
-
-
praveenkumarjamiHow to change the service provider location from static to dynamic... I want to use this code for vehicle tracking or device tracking...Reply
-
admininfo@webeasystep.comcreate 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 channelReply
-
-
waqari 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.Reply
-
admininfo@webeasystep.comhi waqr, try to inspect to show what happens in the console like what i did in the video tutorialsReply
-
-
AhsamHi,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..Reply
-
admininfo@webeasystep.comit is an option and for sure it is not always accurate solution,and you can use Google Maps Geolocation API as alternativeReply
-
-
Abdur Rozaqi 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 :DReply
-
admininfo@webeasystep.comyou will find all tables here https://bitbucket.org/webeasystep/qr_code_generate_codeigniter/src/54064d146b5ea4597a30f75d25f7942cd89b3d41/application/tables/?at=masterReply
-
-
mahmod nasserhey 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 ??Reply
-
admininfo@webeasystep.comHi Mohamed , You are welcome , But Sorry i am no understanding what did you mean ,please explain in details thanksReply
-
-
abhishek shuklaFailed 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 ?Reply
-
ThunderThis 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!Reply
-
Anamicanice tutorialReply
-
Leandrothis 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..?Reply
-
Pandyhow 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_onceReply
-
fathurhai 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 ?Reply
-
sangeethaHI sir, I need a another filter that is two types of filters in this tutorial.can pls help me in this.Reply
-
Jagruti MetaliyaHello 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.Reply
-
saadou belbedjالسلام عليكم اولا شكرا على مجهوداتك الجبارة ..اخي العزيز عند الضغط على الرابط لرفع الملف وعند رفعه من الرابط المباشر تجد انه الملفات الموجودة في الرار ليست نفسها المةجودة في شرحك في التوتوريال ارجو الرد وشكراReply