How to calculate latitude and longitude based on distance in laravel - laravel

This is my function
public function getRshow(){
$lats = $tenl[0]->latitude;
$longs = $tlog[0]->longitude;
$distance =$par_dis[0]->partner_distance;
$project = "SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(( $lats - latitude) * pi()/180 / 2), 2) +COS( $lats * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( $longs - longitude) * pi()/180 / 2), 2) ))) as distance
FROM `abserve_renterpost` having distance <= $distance order by distance";
$la=DB::SELECT($project);
$lara=array();
foreach ($project as $key => $v) {
$lara[]=(get_object_vars($v));
}
}
My query is working good if I run only the query, but if I converted my query for value and array format it's not working, error is displayed as below.
(SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' - latitude) * pi()/180 / 2), 2) +COS( 27.7 * pi()/180) * COS(latitude * ' at line 1 (SQL: SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(( 27.7 - latitude) * pi()/180 / 2), 2) +COS( 27.7 * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( 74.12399600000003
- longitude) * pi()/180 / 2), 2) ))) as distance
FROM `abserve_renterpost` having distance <= 200 order by distance))

I noticed $lats was 27.7 which is odd.
try this
$lats = $tenl[0]->latitude;
$longs = $tlog[0]->longitude;
$distance =$par_dis[0]->partner_distance;
$project = <<<SQL
SELECT * , (3956 * 2 * ASIN(
SQRT(
POWER(SIN(($lats - `latitude`) * pi() / 180 / 2), 2)
+ COS($lats * pi() / 180)
* COS(`latitude` * pi() / 180)
* POWER(SIN(($longs - `longitude`) * pi() / 180 / 2), 2)
))
) as 'distance'
FROM `abserve_renterpost`
WHERE distance <= $distance
ORDER BY distance;
SQL;
$la=DB::select($project);
$lara=array();
foreach ($project as $key => $v) {
$lara[]=(get_object_vars($v));
}

Related

How to avoid errors in trigonometry functions in Oracle?

I have a curson in my stored procedure
SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
FROM example_table_1 a,
(SELECT pnradius AS radius,
111.045 AS distance_unit,
57.2957795 AS rad2deg,
0.01745329251994 AS deg2rad
FROM dual) geo,
example_table me
WHERE a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit) AND
pnlatitude + (geo.radius / geo.distance_unit)
AND a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude)))) AND
pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND geo.distance_unit * rad2deg *
(acos(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)))) < pnradius
AND a.parent_id = me.answer
AND a.parent_table = 'example_table'
pnlatitude and pnlongiture are paramenters of procedure.
In most cases this cursor works great. But sometimes in some areas in Russia this cursor cause this error:
I understand what is going on here, but I can't track where does it happen. I can adjust deg2rad value and it helps, but then this error will appear with other coordinates.
Is it possible to reduce the value of trigonometry function paramentr to 1 when it is more than 1?
Use the LEAST function to ensure you don't pass an argument greater than 1 to ACOS:
SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
FROM example_table_1 a,
(SELECT pnradius AS radius,
111.045 AS distance_unit,
57.2957795 AS rad2deg,
0.01745329251994 AS deg2rad
FROM dual) geo,
example_table me
WHERE a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit)
AND pnlatitude + (geo.radius / geo.distance_unit)
AND a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
AND geo.distance_unit * rad2deg *
(acos(LEAST(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)), 1))) < pnradius
AND a.parent_id = me.answer
AND a.parent_table = 'example_table'
This is the same as your original with a LEAST(big-long-calc, 1) added inside the ACOS call. Hopefully I counted the parentheses right - if not, adjust as necessary. :-)
Best of luck.

Laravel subquery whereIn

I have a problem with a query.
I want to make a subquery but it does not return results.
Here is my code :
$distance_representations = Representation::select('id')
->where(DB::raw('round(6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude)))::numeric, 1) < 50'))
->limit(10)
->get();
$representations = Representation::select('id', 'city', DB::raw('round(6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude)))::numeric, 1) < 50'))
->whereIn('id', $distance_representations)
->get();
return view('search', array('representations' => $representations));
PostgreSQL equivalent :
select id, city, round((6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude))))::numeric, 1) as distance
from representations
where id in (
select id
from representations
where round((6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude))))::numeric, 1) < 50
limit 10
)
Thank you
perhaps you can try this
$distance_representations = Representation::find('id')
->where(DB::raw('round(6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude)))::numeric, 1) < 50'))
->limit(10)
->get();
$representations = Representation::all()
->where(DB::raw('round(6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude)))::numeric, 1) < 50'))
->whereIn('id', $distance_representations.id)
->get();
hope this will help you.
I don't see why you need the sub-query? Unless I'm missing something, you should be able to select your data using a single query.
$representations = Representation::selectRaw('id, city, round(6371 * acos(cos(radians(45.0)) * cos(radians(latitude)) * cos(radians(longitude) - radians(2.7)) + sin(radians(45.0)) * sin(radians(latitude)))::numeric, 1) < 50 AS distance')
->where('distance', '<', 50)
->limit(10)
->get();
I found the solution. I can not do better. Thank you.
This solution WORKS !
$representations_with_distance = Representation::select('id', 'city', DB::raw('round(6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))::numeric, 1) as distance'));
$representation = DB::table(DB::raw("({$representations_with_distance->toSql()}) as rd"))
->where('distance', '<', '?')
->orderBy('distance')
->offset(0)
->limit(10)
->setBindings([$latitude, $longitude, $latitude, $radius])
->get();
return view('search', array('representations' => $representation));

Escape values in multiples DB raw select in Laravel 4

In my query I have something like:
->select('User.id', 'city', 'lat', 'lng', 'comment', 'Comments.created_at', 'disponibility',
DB::raw("User.*, (count(Comments.user_id)) as note_count"),
DB::raw("User.*, (3956 * 2 * ASIN(SQRT( POWER(SIN((:lat - lat) * pi()/180 / 2), 2) +COS(:lat * pi()/180) * COS(lat * pi()/180) * POWER(SIN((:lng - lng) * pi()/180 / 2), 2) ))/0.621371192) as distance"),
["lat" => $lat, "lng" => $lng]
)
For a reason, it give me error that I don't know why
strtolower() expects parameter 1 to be string, array given
Anyone can help me please?
Much appreciated
The problem here is probably that you put your binding not as 2nd argument for DB::raw but as argument for select method.
Just try instead of above code:
->select('User.id', 'city', 'lat', 'lng', 'comment', 'Comments.created_at', 'disponibility',
DB::raw("User.*, (count(Comments.user_id)) as note_count"),
DB::raw("User.*, (3956 * 2 * ASIN(SQRT( POWER(SIN((:lat - lat) * pi()/180 / 2), 2) +COS(:lat * pi()/180) * COS(lat * pi()/180) * POWER(SIN((:lng - lng) * pi()/180 / 2), 2) ))/0.621371192) as distance", ["lat" => $lat, "lng" => $lng])
)

Square with diagonal in Pascal

I have written an application which will write square with diagonal (from left side) - output:
+ * * * *
* + * * *
* * + * *
* * * + *
* * * * +
Code for first application:
PROGRAM cycle4;
USES CRT;
VAR a,r,s:INTEGER;
BEGIN
CLRSCR;
WRITE (‘Enter the number of lines :‘) ;
READLN(a);
FOR r:= 1 TO a DO
BEGIN
FOR s:=1 TO a DO
IF r = s THEN WRITE(‘+‘)
ELSE WRITE(‘*‘) ;
WRITELN;
END;
READLN;
END.
And now I have to create an application which will write square with diagonal (from right side) - output:
* * * * +
* * * + *
* * + * *
* + * * *
+ * * * *
But I don't know how can I write it. Can you help me?
Thanks :)
The line of code which defines the position of + sign is that:
IF r = s THEN WRITE(‘+‘)
and this is the only line you need to change:
IF r + s = a + 1 THEN WRITE(‘+‘)
I think this should work, check with Pascal compiler, haven't used it for about 10 years :)

yii query not caching when using createCommand

I have the following query being logged in mysql which is not being cached.
SELECT
*,
round(priceperkm * IFNULL(KMPlanned, projects.KM),
4) AS NEWVALUE,
round(PRICE * IFNULL(KMPlanned, projects.KM),
2) AS TotalPriceForItem,
SUM(((abs(FSP - LSP) + 1) * SI) / 1000) AS KM_Completed,
round(SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE,
2) AS TotalPrice,
if(round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, projects.KM)) * 100,
2)>100,100,round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, projects.KM)) * 100,
2)) AS TotalPercent
FROM
hdb.projects
join
biditems ON projects.id = biditems.project_id
join
lookupprocess ON biditems.ITEMID = lookupprocess.biditems_id
left join
jobsprocesscomplete ON lookupprocess.ID = lookupprocess_id
left join
detailsseismic ON jobsprocesscomplete.JOBNO = detailsseismic.JOBNO
where
projects.PROJID = '1407075'
and lookupprocess.ID = 16299
The Yii code is as follows.
$dependancy = new CDbCacheDependency("select last_modified_date from projects where PROJID = $projid");
$countJobs = Jobs::model()->cache(CACHE_TIMEOUT,$dependancy)->count(array("condition"=>"PROJID=$projid"));
foreach ($processstages as $k=>$v) {
$sql = "SELECT
*,
round(priceperkm * IFNULL(KMPlanned, projects.KM),
4) AS NEWVALUE,
round(PRICE * IFNULL(KMPlanned, projects.KM),
2) AS TotalPriceForItem,
SUM(((abs(FSP - LSP) + 1) * SI) / 1000) AS KM_Completed,
round(SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE,
2) AS TotalPrice,
if(round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, projects.KM)) * 100,
2)>100,100,round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, projects.KM)) * 100,
2)) AS TotalPercent
FROM
hdb.projects
join
biditems ON projects.id = biditems.project_id
join
lookupprocess ON biditems.ITEMID = lookupprocess.biditems_id
left join
jobsprocesscomplete ON lookupprocess.ID = lookupprocess_id
left join
details".$type['type']." ON jobsprocesscomplete.JOBNO = details".$type['type'].".JOBNO
where
projects.PROJID = :pid
and lookupprocess.ID = :lid
";
$command = Yii::app()->db->cache(CACHE_TIMEOUT,$dependancy)->createCommand($sql); // need to set memecahce to 50m to cache this query
//Yii::log("select last_modified_date from projects where PROJID = $projid",CLogger::LEVEL_INFO, __METHOD__);
$command->bindValue(":lid",$k,PDO::PARAM_INT);
$command->bindValue(":pid",$projid,PDO::PARAM_INT);
Yii::log((memory_get_peak_usage(true))/1024/1024 . "MB",CLogger::LEVEL_INFO, __METHOD__);
$query = $command->query();
}
I cannot seem to figure out why it is not caching these results as the last_modified_date is not changing. i have set max item cache to 32m and memcache memory to 512.
I have rewrote my query to as below which gets cached but the createCommand way it does not
$criteria=new CDbCriteria;
$criteria->select = '
round(priceperkm * IFNULL(KMPlanned, t.KM),
4) AS NEWVALUE,
round(PRICE * IFNULL(KMPlanned, t.KM),
2) AS TotalPriceForItem,
SUM(((abs(FSP - LSP) + 1) * SI) / 1000) AS KM_Completed,
round(SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE,
2) AS TotalPrice,
if(round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, t.KM)) * 100,
2)>100,100,round((SUM(((abs(FSP - LSP) + 1) * SI) / 1000) * PRICE) / (PRICE * IFNULL(KMPlanned, t.KM)) * 100,
2)) AS TotalPercent';
$criteria->join = 'join biditems ON t.id = biditems.project_id ';
$criteria->join .= 'join lookupprocess ON biditems.ITEMID = lookupprocess.biditems_id ';
$criteria->join .= 'left join jobsprocesscomplete ON lookupprocess.ID = lookupprocess_id ';
$criteria->join .= 'left join details'.$type['type'].' ON jobsprocesscomplete.JOBNO = details'.$type['type'].'.JOBNO ';
$criteria->compare('t.PROJID',$projid);
$criteria->compare('lookupprocess.ID',$k);
Projects::model()->cache(CACHE_TIMEOUT,$dependancy)->findAll($criteria);
Try to put the following:
$result = Yii::app()->db->cache(self::CACHE_TIMEOUT,$dependancy)
->createCommand($sql)
->bindValue(":lid",$k,PDO::PARAM_INT);
->bindValue(":pid",$projid,PDO::PARAM_INT)
->findAll();
I assumed that CACHE_TIMEOUT was a constant in this class, but if it is defined in another class, then you need to adapt this part

Resources