The Google Map is the best example of displaying a near by location using the latitude and the longitude. Locations are basically a set of latitude and longitude. It means we can find the distance between two coordinates. That is the source and the destination latitude, longitude. So basically in this post, I will be showing you a demo for listing the shops. Then, I will be displaying you the shops near by location in Laravel 6. This demo will be a good example of finding the nearest location as per the current location. In my previous post, I have shown you to implement Google Autocomplete Address in Laravel 6. So, let’s start by creating a new project.
Prerequisites
Before creating a new project in Laravel 6, your system configuration must follow the below criteria. Your system must be ready with these tools.
- PHP version >=7.3.9
- MySQL (version > 5)
- Apache/Nginx Server
- VS Code Editor
When you are ready with the above configuration let’s create a new project.
Laravel 6 Project For Finding Near By Location
You will have to create a new project in Laravel 6. So that we can implement the functionality for finding the shops near by selected location. In this project, first of all, we will insert some shops in a specific location. That means for every location we’ll pick the latitude and the longitude of the location.
composer create-project --prefer-dist laravel/laravel distance-project
So, just wait for creating the project. Once, the project has been created, let’s move to the next step.
How to Upload Files and Images in Laravel 6 with Validation
Create and Configure the Database
We’ll require a database for all the operations. Actually, we are going to save some shops/stores in the database. The shops will have the latitude and longitude. Then we’ll retrieve the created stores/shops near by location.
Open MySQL or phpMyAdmin and just create a database with the below command.
create database laravel6_nearby_location;
Once, the database has been created, let’s configure the database with the Laravel project.
Configure Database in Laravel 6
Open the .env file of the Laravel 6 project. Now, just replace the below details with your database details there.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel6_nearby_location
DB_USERNAME=root
DB_PASSWORD=root
RESTful APIs in Laravel 6 with Passport Authentication
Create Model and Migration
For finding the shop or store near by location by latitude and longitude, we’ll have to create the record first. So, for creating the record into the database, we will have to create the Model and a migration file. So, just open the terminal and create a Model with the migration file.
php artisan make:model Shop --migration
The above command will create a Model with the name Shop. Also, a migration file will be created inside the database/migrations.
Add Fields in Migration File
When the migration file has been created, let’s add some fields that will be creating the table structure.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateShopsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('shops', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string("shop_name");
$table->text("description");
$table->string("address");
$table->string("latitude");
$table->string("longitude");
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('shops');
}
}
Once you have added the fields in the migration file, let’s migrate all into the database.
How to Integrate Laravel 6 Application with Firebase
Migrate Table into Database
For migrating the tables, we need to hit the below command in the terminal.
php artisan migrate
The entered command will generate the specified tables inside the database.
Add Fillable Data into Model
In Laravel eloquent, we need to specify the fillable data in the model. The fillable data mainly defines the fields inside the table that will gonna manage by the Model. Hence, we have a model named Store. So, in the Store.php just add the below codes.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Shop extends Model
{
// -------- [ Mass Assignment ] ---------
protected $fillable = ["shop_name", "description", "address", "latitude", "longitude", "image"];
}
How to Implement Datatable Column Filter in Laravel 6
Create Controller
For this project, we’ll create a controller. In this controller, we will save the shop details into the database. Using Laravel eloquent. Further, we’ll implement the functionality to list the created shops near by location as per the current latitude and longitude. So, let’s do step by step.
php artisan make:controller ShopController.php
Once, you have created the controller, let’s put the below code there.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Shop;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
class ShopController extends Controller
{
public function index(Request $request) {
$latitude = "28.418715";
$longitude = "77.0478997";
$shops = DB::table("shops");
$shops = $shops->select("*", DB::raw("6371 * acos(cos(radians(" . $latitude . "))
* cos(radians(latitude)) * cos(radians(longitude) - radians(" . $longitude . "))
+ sin(radians(" .$latitude. ")) * sin(radians(latitude))) AS distance"));
$shops = $shops->having('distance', '<', 20);
$shops = $shops->orderBy('distance', 'asc');
$shops = $shops->get();
return view('shop-listing', compact("shops"));
}
// ------------ load shop view ---------------
public function create() {
return view('create-shop');
}
// ----------------- save shop detail ----------------------
public function store(Request $request) {
$request->validate([
"shop_name" => "required",
"location" => "required",
"filename" => "required|mimes:jpeg,png,jpg,bmp|max:2048"
]);
if($file = $request->file('file')) {
$image_name = time().'.'.$file->getClientOriginalExtension();
$target_path = public_path('/uploads/');
if($file->move($target_path, $image_name)) {
$dataArray = array (
"shop_name" => $request->shop_name,
"address" => $request->location,
"description" => $request->description,
"latitude" => $request->latitude,
"longitude" => $request->longitude,
"image" => ""
);
$shop = Shop::create($dataArray);
if(!is_null($shop)) {
return back()->with("success", "Shop details saved successfully");
}
}
}
}
}
In the above controller functions, I have created the functionality to save the shop from the view (front end) and in the next function, I have implemented the query for displaying the shops near by location according to distance.
Laravel 6 Custom Login and Registration with Session
In the next step, we will create views.
Create Views
In Laravel, you can find the views inside the resources folder. So, here we’ll create two views for this project.
- create-shop.blade.php
- shop-listing.blade.php
The first blade file is just for creating the shop. In this blade file, we’ll be creating a form and some input fields. The input fields will be based on the number of fields that you have been created inside the database table.
So, just add the below snippet in the create-shop.blade.php file.
<!doctype html>
<html lang="en">
<head>
<title>Find Near By Location : Example Programming Fields</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
<form action="{{ url('store-shop') }}" method="post" enctype="multipart/form-data ">
{{ csrf_field() }}
<div class="row">
<div class="col-xl-6 m-auto">
<div class="card shadow">
<div class="card-header bg-primary">
<h5 class="card-title text-white mt-2"> Create Shop With Latitude and Longitude </h5>
</div>
<div class="card-body">
{{-- print success message --}}
@if(Session::has('success'))
<div class="alert alert-success">
{{ Session::get('success') }}
@php
Session::forget('success');
@endphp
</div>
@endif
<div class="form-group">
<label for="shop_name"> Shop Name <span class="text-danger"> * </span> </label>
<input type="text" name="shop_name" class="form-control" id="shop_name" placeholder="Shop Name" value="{{ old('shop_name') }}">
{!! $errors->first('shop_name', '<small class="text-danger">:message </small>') !!}
</div>
<div class="form-group">
<label for="description"> Description </label>
<input type="text" name="description" class="form-control" id="description" placeholder="Description" value="{{ old('description') }}">
</div>
<div class="form-group">
<label for="description"> Location </label>
<input type="text" name="location" class="form-control" id="location" placeholder="Select Location" value="{{ old('location') }}">
<input type="hidden" name="latitude" class="form-control" id="latitude" value="{{ old('latitude') }}">
<input type="hidden" name="longitude" class="form-control" id="longitude" value={{ old('longitude') }}>
{!! $errors->first('location', '<small class="text-danger">:message </small>') !!}
</div>
<div class="form-group">
<label for="file"> Image </label>
<input type="file" name="filename" id="filename" class="form-control">
{!! $errors->first('file', '<small class="text-danger">:message </small>') !!}
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success"> Save </button>
</div>
</div>
</div>
</div>
</form>
</div>
{{-- javascript code --}}
<script src="https://maps.google.com/maps/api/js?key=YOUR_KEY&libraries=places&callback=initAutocomplete" type="text/javascript"></script>
<script>
$(document).ready(function() {
$("#lat_area").addClass("d-none");
$("#long_area").addClass("d-none");
});
</script>
<script>
google.maps.event.addDomListener(window, 'load', initialize);
function initialize() {
var options = {
componentRestrictions: {country: "IN"}
};
var input = document.getElementById('location');
var autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
$('#latitude').val(place.geometry['location'].lat());
$('#longitude').val(place.geometry['location'].lng());
// --------- show lat and long ---------------
$("#lat_area").removeClass("d-none");
$("#long_area").removeClass("d-none");
});
}
</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Drag and Drop File Upload in Laravel 6 Using Dropzone js
Add the below code inside the shop-listing.blade.php file. In this blade file, I have listed out the shops as per the latitude and the longitude.
<!doctype html>
<html lang="en">
<head>
<title>Shop Listing Based on Current Location - Programming Fields </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
</head>
<body>
<div class="container mt-5">
<h3 class="text-center"> Shop Near By Location </h3>
<div class="row mt-4">
@foreach($shops as $shop)
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-12 col-12 m-auto">
<div class="card shadow p-3">
<div class="card-image border" style="height:228px;">
<img src="{{ url('/uploads/'.$shop->image) }}" class="img-fluid" style="height: 100%; width:100%;"/>
</div>
<h5 class="card-title float-left pt-2"> {{ $shop->shop_name }} <small class="text-right float-right">{{round($shop->distance, 2) . " KM "}}</small></h5>
<p> {{ $shop->address }} </p>
</div>
</div>
@endforeach
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Laravel 6 Login and Registration with Authentication
Add Routes
In the next step, add the below routes in the routes/web.php file.
Route::get('shop', 'ShopController@index');
Route::get('shop-create', 'ShopController@create');
Route::post('store-shop', 'ShopController@store');
Now, save and run your application.
http://localhost:8000/shop-create
The above URL will open the form for creating the shop details. So, just fill out the details and create the shop.
After creating the shop, it will prompt you the success message.
So, here, I have created some shops. You can check into the database table also.
How to Send Email in Laravel 6 Via Gmail Using SMTP
Now, to see the result just enter the below route URL.
http://localhost:8000/shop
Here, the result is in front of you. You can see the created shops are displaying according to the near by distance from the current location latitude and longitude.
Laravel 6 REST API For ToDo Application with Passport Auth
Conclusion
This post is just a demonstration of finding shops near by location. You can extend this demo for your real projects as per the requirement. Basically, I am trying to put you the demo that you can implement these kinds of projects into your real world. You can find the current location using JavaScript. So, that it will detect the location and will provide you the latitude and longitude of the current location. So, I hope you will love the above post. If you feel any doubt about this post then let me know through the comment. I will try to resolve your query.
rizki says
Sir, how to get current location on gmap laravel.. Thanks
Elangamani says
i’m getting this error,
Column not found: 1054 Unknown column ‘distance’ in ‘order clause’. how to fix this, can you please explain?
Umesh Rana says
You will have to write the proper query like this –
select("*", DB::raw("6371 * acos(cos(radians(" . $latitude . ")) * cos(radians(latitude)) * cos(radians(longitude) - radians(" . $longitude . "))
+ sin(radians(" .$latitude. ")) * sin(radians(latitude))) AS distance")) having('distance', '<', 20) orderBy('distance', 'asc');
In this query, the distance will be calculated automatically on the basis of the Latitude and the Longitude. It doesn't need to define the distance anywhere.
chirag says
i’m getting this error,
Column not found: 1054 Unknown column ‘distance’ in ‘order clause’. how to fix this, can you please explain?
this is my code
$latitude = “28.418715”;
$longitude = “77.0478997”;
$location = DB::table(“check_ins”)
->select(“*”, DB::raw(“6371 * acos(cos(radians(” . $latitude . “))
* cos(radians(latitude)) * cos(radians(longitude) – radians(” . $longitude . “))
+ sin(radians(” . $latitude . “)) * sin(radians(latitude))) AS distance”))
->having(‘distance’, ‘orderBy(‘distance’, ‘asc’)
->get();
Umesh Rana says
Your query is not correct. Please follow the above solution. I have specified the query.