You have to calculate the distance to each color, and pick the smallest.

There are a few ways to do this. A simple method would be to calculate the distance would be:

`sqrt((r-r1)^2+(g-g1)^2+(b-b1)^2)`

A better method might be to incorporate the weighted values to calculate a distance, for instance the values used when converting RGB->YUV:

`Y = 0.299 * R + 0.587 * G + 0.114 * B`

in that case you would use

`sqrt(((r - r1) * .299)^2 + ((g - g1) * .587)^2 + ((b - b1) * .114)^2)`

Of course, since you don't need the exact distances, just a comparison, you can and probably should just skip the square root, making the last calculation:

`((r - r1) * .299)^2 + ((g - g1) * .587)^2 + ((b - b1) * .114)^2`

Thanks for this, im going to edit the OP and put the function I made.

Random thought: Strictly speaking you don't need to take the square root and can just find the smallest square if performance is a concern.

@mootinator Why do we need to square the values at all? Why not just shortest distance?

@mootinator Are we squaring to eliminate negative values? Does anyone know if the absolute value function is faster than squaring? Or simply converting to a string and stripping the negative then converting back to a number, or maybe just multiplying itself by negative 1 if it's negative?

@Albert Renshaw We're squaring to find the euclidean distance between two points. We're skipping taking the square root of the distance because that step doesn't affect the sort order of the distances.

## php - RGB to closest predefined color - Stack Overflow

php function colors gd

The RGB colour-space is simply a cube. In 24-bit colour each side has a length of 256, allowing values from 0 to 255. In order to find the closest colour in within this cube, you need a distance function. The simplest and most intuitive is the Euclidean distance: if you have colour (r1, g1, b1) and another colour (r2, g2, b2) the distance would be sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2).

The challenge for you is then to find the best match across all the values in your predefined array. I suggest that you start simply by iterating over all your values and check the distance for each in turn. Note that for this purpose you do not need to perform the sqrt, simply comparing on the sum of the squares would be sufficient, and would have the benefit of being all based in integer maths. My PHP isn't great, but roughly you would do:

```function dist(\$col1,\$col2) {
\$delta_r = \$col1 - \$col2;
\$delta_g = \$col1 - \$col2;
\$delta_b = \$col1 - \$col2;
return \$delta_r * \$delta_r + \$delta_g * \$delta_g + \$delta_b * \$delta_b;
}

\$closest=\$colors;
\$mindist=dist(\$rgb,\$colors);
\$ncolors=sizeof(\$colors);
for(\$i = 1; \$i < \$ncolors; ++\$i)
{
\$currdist = dist(\$rgb,\$colors[\$i]);
if(\$currdist<\$mindist) {
\$mindist=\$currdist;
\$closest=\$colors[\$i];
}
}```

There are more complicated distance functions (for instance, taking better account of psychovisual interpretation of colour differences (look into Delta E) but I suspect this is more than you need.

It's not necessarily a cube, even if it's commonly done so. It's primarily a vector space, and could as well be a paralleloid.

@user502515: It could be, but it's unlikely. All the RGB colour spaces I've encountered (most obviously sRGB) tend to be bounded in the range 0 to 1 or 0 to 255. Other colour spaces, such as CIE Lab, do indeed have different bounds, but they are not RGB.

@beldaz why are we squaring the distance as well? Why not just take the sum of the distance of each color?

Is it to eliminate negative values? Are there quicker ways of doing this?

@Albert the sum of distances would be like walking around a square rather than walking directly across it: the distances are different (FWIW your approach is sometimes referred to as a Manhattan Distance).

## php - RGB to closest predefined color - Stack Overflow

php function colors gd

You need to map the distance of each item to the reference point first.

Then you sort the map and then you can tell which has the lowest (or highest if you reverse the search) distance:

```\$ref = array(49.648881, -103.575312);

\$items = array(
'0' => array('item1','otheritem1details....','55.645645','-42.5323'),
'1' => array('item1','otheritem1details....','100.645645','-402.5323')
);

\$distances = array_map(function(\$item) use(\$ref) {
\$a = array_slice(\$item, -2);
return distance(\$a, \$ref);
}, \$items);

asort(\$distances);

echo 'Closest item is: ', var_dump(\$items[key(\$distances)]);```
```Closest item is: array(4) {
=>
string(5) "item1"
=>
string(21) "otheritem1details...."
=>
string(9) "55.645645"
=>
string(8) "-42.5323"
}```

Take care you have the right order of lat and long.

The distance function (only the header slightly changed and units have been dropped):

```function distance(\$a, \$b)
{
list(\$lat1, \$lon1) = \$a;
list(\$lat2, \$lon2) = \$b;

\$theta = \$lon1 - \$lon2;
\$dist = acos(\$dist);
\$miles = \$dist * 60 * 1.1515;
return \$miles;
}```

## php - Find closest longitude and latitude in array? - Stack Overflow

php latitude-longitude

You need to map the distance of each item to the reference point first.

Then you sort the map and then you can tell which has the lowest (or highest if you reverse the search) distance:

```\$ref = array(49.648881, -103.575312);

\$items = array(
'0' => array('item1','otheritem1details....','55.645645','-42.5323'),
'1' => array('item1','otheritem1details....','100.645645','-402.5323')
);

\$distances = array_map(function(\$item) use(\$ref) {
\$a = array_slice(\$item, -2);
return distance(\$a, \$ref);
}, \$items);

asort(\$distances);

echo 'Closest item is: ', var_dump(\$items[key(\$distances)]);```
```Closest item is: array(4) {
=>
string(5) "item1"
=>
string(21) "otheritem1details...."
=>
string(9) "55.645645"
=>
string(8) "-42.5323"
}```

Take care you have the right order of lat and long.

The distance function (only the header slightly changed and units have been dropped):

```function distance(\$a, \$b)
{
list(\$lat1, \$lon1) = \$a;
list(\$lat2, \$lon2) = \$b;

\$theta = \$lon1 - \$lon2;
\$dist = acos(\$dist);
\$miles = \$dist * 60 * 1.1515;
return \$miles;
}```

## php - Find closest longitude and latitude in array? - Stack Overflow

php latitude-longitude

I think what you're trying to achieve could be done better using the Haversine formula in your SQL. Google has a tutorial on how to get the nearest locations in a MySQL database but the general idea is this SQL:

```SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) )
* sin( radians( lat ) ) ) ) AS distance
FROM markers
HAVING distance < 25
ORDER BY distance LIMIT 0 , 20;```

Then all the work you need to do is done on the database, so you don't have to pull all the businesses into your PHP script before you even check the distance.

Didn't know that formula, seems pretty useful. Thanks for sharing!

Very simple, and you can do it all in SQL!

To search by kilometers instead of miles, replace 3959 with 6371

which one is lat and long from 37 and -122 thanks.

and also one last thing can you please tell us if this work fine for thousand records. Thanks

## php - How to efficiently find the closest locations nearby a given loc...

php mysql

Option 1: Do the calculation on the database by switching to a database that supports GeoIP.

Option 2: Do the calculation on the database: you're using MySQL, so the following stored procedure should help

```CREATE FUNCTION distance (latA double, lonA double, latB double, LonB double)
RETURNS double DETERMINISTIC
BEGIN
SET @deltaLat = @RlatA - @RlatB;
SET @deltaLon = @RlonA - @RlonB;
SET @d = SIN(@deltaLat/2) * SIN(@deltaLat/2) +
COS(@RlatA) * COS(@RlatB) * SIN(@deltaLon/2)*SIN(@deltaLon/2);
RETURN 2 * ASIN(SQRT(@d)) * 6371.01;
END//```

If you have an index on latitude and longitude in your database, you can reduce the number of calculations that need to be calculated by working out an initial bounding box in PHP (\$minLat, \$maxLat, \$minLong and \$maxLong), and limiting the rows to a subset of your entries based on that (WHERE latitude BETWEEN \$minLat AND \$maxLat AND longitude BETWEEN \$minLong AND \$maxLong). Then MySQL only needs to execute the distance calculation for that subset of rows.

FURTHER EDIT (as an explanation for the previous edit)

If you're simply using the SQL statement provided by Jonathon (or a stored procedure to calculate the distance) then SQL still has to look through every record in your database, and to calculate the distance for every record in your database before it can decide whether to return that row or discard it.

Because the calculation is relatively slow to execute, it would be better if you could reduce the set of rows that need to be calculated, eliminating rows that will clearly fall outside of the required distance, so that we're only executing the expensive calculation for a smaller number of rows.

If you consider that what you're doing is basically drawing a circle on a map, centred on your initial point, and with a radius of distance; then the formula simply identifies which rows fall within that circle... but it still has to checking every single row.

Using a bounding box is like drawing a square on the map first with the left, right, top and bottom edges at the appropriate distance from our centre point. Our circle will then be drawn within that box, with the Northmost, Eastmost, Southmost and Westmost points on the circle touching the borders of the box. Some rows will fall outside that box, so SQL doesn't even bother trying to calculate the distance for those rows. It only calculates the distance for those rows that fall within the bounding box to see if they fall within the circle as well.

Within PHP, we can use a very simple calculation that works out the minimum and maximum latitude and longitude based on our distance, then set those values in the WHERE clause of your SQL statement. This is effectively our box, and anything that falls outside of that is automatically discarded without any need to actually calculate its distance.

There's a good explanation of this (with PHP code) on the Movable Type website that should be essential reading for anybody planning to do any GeoPositioning work in PHP.

Thank you very much, I have two questions. 1 - whats a stored procedure? how would i implement that, and then use it? 2 - is this any more efficient or better than Jonathon's answer?

A "stored procedure" is basically a user-defined block of code stored within the database server itself. You can read about MySQL stored procedures at dev.mysql.com/doc/refman/5.1/en/stored-routines.html It basically does the same as Jonathon's code, but instead of all the math within your select statement, you simply reference the new function distance() in your select (passing in the appropriate arguments) as you might do with any of the MySQL built-in functions

Note, the 6371.01 is the radius multiplier in kilometers, change it to 3958 if you want the value in miles

ah right i understand, thats a really good idea thanks. :) I'll look into stored procedures. I really don't understand your edit! ha, I'm not sure whether that's because I don't understand how indexes work or because I just can't get my head around the concept. Could you shed a bit more light on it at all? Sorry to be thick, and if you don't have the time then don't worry at all. :)

## php - How to efficiently find the closest locations nearby a given loc...

php mysql

By using the wordwrap function. It splits the texts in multiple lines such that the maximum width is the one you specified, breaking at word boundaries. After splitting, you simply take the first line:

`substr(\$string, 0, strpos(wordwrap(\$string, \$your_desired_width), "\n"));`

One thing this oneliner doesn't handle is the case when the text itself is shorter than the desired width. To handle this edge-case, one should do something like:

```if (strlen(\$string) > \$your_desired_width)
{
\$string = wordwrap(\$string, \$your_desired_width);
\$string = substr(\$string, 0, strpos(\$string, "\n"));
}```

The above solution has the problem of prematurely cutting the text if it contains a newline before the actual cutpoint. Here a version which solves this problem:

```function tokenTruncate(\$string, \$your_desired_width) {
\$parts = preg_split('/([\s\n\r]+)/', \$string, null, PREG_SPLIT_DELIM_CAPTURE);
\$parts_count = count(\$parts);

\$length = 0;
\$last_part = 0;
for (; \$last_part < \$parts_count; ++\$last_part) {
\$length += strlen(\$parts[\$last_part]);
if (\$length > \$your_desired_width) { break; }
}

return implode(array_slice(\$parts, 0, \$last_part));
}```

Also, here is the PHPUnit testclass used to test the implementation:

```class TokenTruncateTest extends PHPUnit_Framework_TestCase {
public function testBasic() {
\$this->assertEquals("1 3 5 7 9 ",
tokenTruncate("1 3 5 7 9 11 14", 10));
}

public function testEmptyString() {
\$this->assertEquals("",
tokenTruncate("", 10));
}

public function testShortString() {
\$this->assertEquals("1 3",
tokenTruncate("1 3", 10));
}

public function testStringTooLong() {
\$this->assertEquals("",
tokenTruncate("toooooooooooolooooong", 10));
}

public function testContainingNewline() {
\$this->assertEquals("1 3\n5 7 9 ",
tokenTruncate("1 3\n5 7 9 11 14", 10));
}
}```

Special UTF8 characters like '' are not handled. Add 'u' at the end of the REGEX to handle it:

`\$parts = preg_split('/([\s\n\r]+)/u', \$string, null, PREG_SPLIT_DELIM_CAPTURE);`

This seems like it would prematurely cut the text if there is a \n before the desired width.

@KendallHopkins: true, there is indeed an issue. I updated the answer with an alternative implementation which solves the given issue.

Would this example work for a string that contains html tags like a paragraph tags?

This is a very cool solution. Don't Have any use for it right now but might down the line not that I know about it.

Why not adding: if(strlen(\$string) <= \$your_desired_width) return \$string; as first statement?

## How to Truncate a string in PHP to the word closest to a certain numbe...

php string function
`iconv("utf-8","ascii//TRANSLIT",\$input);`

Why does this solution return "o for on my machine and on the examples in the php reference it returns oe?

This bombs with a value of false and gives me a notice that illegal characters were encountered...

## utf 8 - PHP: Replace umlauts with closest 7-bit ASCII equivalent in an...

php utf-8 diacritics strtr
`iconv("utf-8","ascii//TRANSLIT",\$input);`

Why does this solution return "o for on my machine and on the examples in the php reference it returns oe?

This bombs with a value of false and gives me a notice that illegal characters were encountered...

## utf 8 - PHP: Replace umlauts with closest 7-bit ASCII equivalent in an...

php utf-8 diacritics strtr

Since this question is displayed in the top ten of goolge search results, here is a more complex function I wrote some years ago, which produced better results than the existing PHP functions.

```/*
* Die Funktion gibt den Array-Schlssel der Farbe (\$palette),
* die am ehesten der Farbe \$givenColor entspricht.
*
* Returns the index of the palette-color which is most similar
* to \$givenColor.
*
* \$givenColor und die Eintrge in \$palette knnen entweder
* Strings im Format (#)rrggbb
* (z. B. "ff0000", "4da4f3" oder auch "#b5d7f3")
* oder Arrays mit je einem Wert fr Rot, Grn und Blau
* (z. B. \$givenColor = array( 0xff, 0x00, 0x00 ) )
* sein.
*
* \$givenColor and the colors in \$palette should be either
* formatted as (#)rrggbb
* (e. g. "ff0000", "4da4f3" or "#b5d7f3")
* or arrays with values for red, green and blue
* (e. g. \$givenColor = array( 0xff, 0x00, 0x00 ) )
*
* Referenzen/References:
* function rgb2lab
*   - http://www.f4.fhtw-berlin.de/~barthel/ImageJ/ColorInspector//HTMLHilfe/farbraumJava.htm
*   - http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
*   - http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
*
* function deltaE
*   - http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CMC.html
*/
function getNearestColor( \$givenColor,
\$palette = array('blue' => '0000ff','red' => 'ff0000','green' => '00ff00','yellow' => 'ffff00','black' => '000000','white' => 'ffffff','orange' => 'ff8800','purple' => 'ff00ff', 'teal' => '00ffff')
)
{
if(!function_exists('rgb2lab'))
{
function rgb2lab(\$rgb) {
\$eps = 216/24389; \$k = 24389/27;
// reference white D50
\$xr = 0.964221; \$yr = 1.0; \$zr = 0.825211;
// reference white D65
#\$xr = 0.95047; \$yr = 1.0; \$zr = 1.08883;

// RGB to XYZ
\$rgb = \$rgb/255; //R 0..1
\$rgb = \$rgb/255; //G 0..1
\$rgb = \$rgb/255; //B 0..1

// assuming sRGB (D65)
\$rgb = (\$rgb <= 0.04045)?(\$rgb/12.92):pow((\$rgb+0.055)/1.055,2.4);
\$rgb = (\$rgb <= 0.04045)?(\$rgb/12.92):pow((\$rgb+0.055)/1.055,2.4);
\$rgb = (\$rgb <= 0.04045)?(\$rgb/12.92):pow((\$rgb+0.055)/1.055,2.4);

// sRGB D50
\$x =  0.4360747*\$rgb + 0.3850649*\$rgb + 0.1430804*\$rgb;
\$y =  0.2225045*\$rgb + 0.7168786*\$rgb + 0.0606169*\$rgb;
\$z =  0.0139322*\$rgb + 0.0971045*\$rgb + 0.7141733*\$rgb;
// sRGB D65
/*\$x =  0.412453*\$rgb + 0.357580*\$rgb + 0.180423*\$rgb;
\$y =  0.212671*\$rgb + 0.715160*\$rgb + 0.072169*\$rgb;
\$z =  0.019334*\$rgb + 0.119193*\$rgb + 0.950227*\$rgb;*/

// XYZ to Lab
\$xr = \$x/\$xr; \$yr = \$y/\$yr; \$zr = \$z/\$zr;

\$fx = (\$xr > \$eps)?pow(\$xr, 1/3):(\$fx = (\$k * \$xr + 16) / 116); \$fy = (\$yr > \$eps)?pow(\$yr, 1/3):(\$fy = (\$k * \$yr + 16) / 116); \$fz = (\$zr > \$eps)?pow(\$zr, 1/3):(\$fz = (\$k * \$zr + 16) / 116);

\$lab = array();
\$lab[] = round(( 116 * \$fy ) - 16); \$lab[] = round(500*(\$fx-\$fy)); \$lab[] = round(200*(\$fy-\$fz));
return \$lab;
} // function rgb2lab
}

if(!function_exists('deltaE'))
{
function deltaE(\$lab1, \$lab2)
{
// CMC 1:1
\$l = 1; \$c = 1;

\$c1 = sqrt(\$lab1*\$lab1+\$lab1*\$lab1); \$c2 = sqrt(\$lab2*\$lab2+\$lab2*\$lab2);

\$h1 = (((180000000/M_PI) * atan2(\$lab1,\$lab1) + 360000000) % 360000000)/1000000;

\$t = (164 <= \$h1 AND \$h1 <= 345)?(0.56 + abs(0.2 * cos(\$h1+168))):(0.36 + abs(0.4 * cos(\$h1+35)));
\$f = sqrt(pow(\$c1,4)/(pow(\$c1,4) + 1900));

\$sl = (\$lab1 < 16)?(0.511):((0.040975*\$lab1)/(1 + 0.01765*\$lab1));
\$sc = (0.0638 * \$c1)/(1 + 0.0131 * \$c1) + 0.638;
\$sh = \$sc * (\$f * \$t + 1 -\$f);

return sqrt( pow((\$lab1-\$lab2)/(\$l * \$sl),2) + pow((\$c1-\$c2)/(\$c * \$sc),2) + pow(sqrt((\$lab1-\$lab2)*(\$lab1-\$lab2) + (\$lab1-\$lab2)*(\$lab1-\$lab2) + (\$c1-\$c2)*(\$c1-\$c2))/\$sh,2) );
} // function deltaE
}

if(!function_exists('colorDistance'))
{
function colorDistance(\$lab1,\$lab2)
{
return sqrt((\$lab1-\$lab2)*(\$lab1-\$lab2)+(\$lab1-\$lab2)*(\$lab1-\$lab2)+(\$lab1-\$lab2)*(\$lab1-\$lab2));
}
}

if(!function_exists('str2rgb'))
{
function str2rgb(\$str)
{
\$str = preg_replace('~[^0-9a-f]~','',\$str);
\$rgb = str_split(\$str,2);
for(\$i=0;\$i<3;\$i++)
\$rgb[\$i] = intval(\$rgb[\$i],16);

return \$rgb;
} // function str2rgb
}

// split into RGB, if not already done
\$givenColorRGB = is_array(\$givenColor)?\$givenColor:str2rgb(\$givenColor);
\$min = 0xffff;
\$return = NULL;

foreach(\$palette as \$key => \$color)
{
// split into RGB
\$color = is_array(\$color)?\$color:str2rgb(\$color);
// deltaE
#if(\$min >= (\$deltaE = deltaE(rgb2lab(\$color),rgb2lab(\$givenColorRGB))))
// euclidean distance
if(\$min >= (\$deltaE = colorDistance(rgb2lab(\$color),rgb2lab(\$givenColorRGB))))
{
\$min = \$deltaE;
\$return = \$key;
}
}

return \$return;
}```

for me this is the only proper answer!

Be aware that meanwhile there are replacements for the Delta E algorithm I used in the above code. Nevertheless, if I were to implement a new color distance function today, I would use the DIN99c or DIN99d color spaces since they are easier and faster to calculate than CIE94 or CIEDE2000 while serving a similar quality.

Some explanation is in order. What does this do? Why is it better?

This function uses a color space in which the distances between the colors are similar to the human color perception. This allows for a certain color to get the best matching color from a given palette. But as I wrote: Today I would use an implementation of DIN99 to achieve this. The above function was written over 10 years ago.

## php - RGB to closest predefined color - Stack Overflow

php function colors gd

This will return the first 200 characters of words:

`preg_replace('/\s+?(\S+)?\$/', '', substr(\$string, 0, 201));`

This actually works better than the accepted solution :)

Almost. It seems like it removes the last word of the sentence for me no matter what.

works great but i found the same error as ReX357. When there is more than 1 word, it deletes the last one.

Just wrap it in a check to make sure the string is longer than what you are testing for (same as the accepted answer) if (strlen(\$string) > \$your_desired_width) { preg_replace(...); }

## How to Truncate a string in PHP to the word closest to a certain numbe...

php string function

## This will match as many instances as you have:

`Track number:(?:.(?!Track number:))*subtitles`

This will return the following (as many regions there are between "Track number:" and "subtitles"

## php - get closest match in regex - Stack Overflow

php regex

A little trick that doesn't require setting locales or having huge translation tables:

```function Unaccent(\$string)
{
if (strpos(\$string = htmlentities(\$string, ENT_QUOTES, 'UTF-8'), '&') !== false)
{
\$string = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '\$1', \$string), ENT_QUOTES, 'UTF-8');
}

return \$string;
}```

The only requirement for it to work properly is to save your files in UTF-8 (as you should already).

did not work with (Lithuanian)

## utf 8 - PHP: Replace umlauts with closest 7-bit ASCII equivalent in an...

php utf-8 diacritics strtr

A little trick that doesn't require setting locales or having huge translation tables:

```function Unaccent(\$string)
{
if (strpos(\$string = htmlentities(\$string, ENT_QUOTES, 'UTF-8'), '&') !== false)
{
\$string = html_entity_decode(preg_replace('~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '\$1', \$string), ENT_QUOTES, 'UTF-8');
}

return \$string;
}```

The only requirement for it to work properly is to save your files in UTF-8 (as you should already).

did not work with (Lithuanian)

## utf 8 - PHP: Replace umlauts with closest 7-bit ASCII equivalent in an...

php utf-8 diacritics strtr

there are no more virtualFields in cake 3 but you still can create an alias for your calculated field

As suggested by @ndm you'd better bind \$latitude and \$longitude to prevent SQL injections

```\$distanceField = '(3959 * acos (cos ( radians(:latitude) )
* cos( radians( Sightings.latitude ) )
* sin( radians( Sightings.latitude ) )))';```
```\$sightings = \$this->Sightings->find()
->select([
'distance' => \$distanceField
])
->having(['distance < ' => \$distance])
->bind(':latitude', \$latitude, 'float')
->bind(':longitude', \$longitude, 'float')
->contain(['Photos', 'Tags']);```

Please make sure to either explicitly cast or quote \$latitude and \$longitude in this example, or to use bindings, as otherwise this is a possible SQL injection vulnerability!

This is really close to what I need, it's selecting the correct rows, but it only seems to contain the distance value, is there a way to hydrate the entities as "Normal"?

You Can select all the fields you need of course. The manuale explains how to select all the fields of the model

`->autoFields(true)`

## php - CakePHP query closest latitude longitude from database - Stack O...

php mysql cakephp location cakephp-3.0

To improve the speed of your query you could first limit the set of results that you'll do calculations for using something like the sub-select below (note that I also used a different method for calculating the distance - it works for me, ymmv). In my tests, using the where clause with a tolerance of 1 was over 100 times faster than the query without it.

```...
\$tol = 1; // limits the search to lat/long within 1 from the given values
\$query_args = array(\$lat,\$long,\$lat-\$tol,\$lat+\$tol,\$long-\$tol,\$long+\$tol);
\$query = "
SELECT *,latitude, longitude,
SQRT( POW( 69.1 * ( latitude - %s) , 2 )
+ POW( 69.1 * ( %s - longitude )
* COS( latitude / 57.3 ) , 2 ) )
AS distance FROM zipcodes
WHERE latitude > %d AND latitude < %d
AND longitude > %d AND longitude < %d
ORDER BY distance ASC limit 10
";
...```

## php - Find closest 10 cities with MySQL using latitude and longitude? ...

php mysql geocoding latitude-longitude

Rather using the law of cosines for distance, you can use flat earth approximation. The flat earth equations reduce the number of trig functions in the calculation. The lat, lon is the difference between your reference point and the test point.

This formula would not be accurate for long distance navigation (thousands of miles) but for this particular problem, you aren't really interested in accurate distance, but who is the closest point to me. This is a simpler formulation that should give you that.

```x = lon * cos(lat)   // lat/lon are in radians!
y = lat
distance = R * sqrt( x + y )  // R is radius of the earth;
// typical value is 6371 km```
```function distanceMeters(\$lat1, \$lon1, \$lat2, \$lon2) {
\$x = deg2rad( \$lon1 - \$lon2 ) * cos( deg2rad( \$lat1 ) );
\$y = deg2rad( \$lat1 - \$lat2 );
\$dist = 6371000.0 * sqrt( \$x*\$x + \$y*\$y );

return \$dist;
}```

If you're not concerned with the actual distance (i.e. just sorting), you can also drop R * from the last step as it's a constant multiplication for all entries

## php - Find closest longitude and latitude in array? - Stack Overflow

php latitude-longitude

Rather using the law of cosines for distance, you can use flat earth approximation. The flat earth equations reduce the number of trig functions in the calculation. The lat, lon is the difference between your reference point and the test point.

This formula would not be accurate for long distance navigation (thousands of miles) but for this particular problem, you aren't really interested in accurate distance, but who is the closest point to me. This is a simpler formulation that should give you that.

```x = lon * cos(lat)   // lat/lon are in radians!
y = lat
distance = R * sqrt( x + y )  // R is radius of the earth;
// typical value is 6371 km```
```function distanceMeters(\$lat1, \$lon1, \$lat2, \$lon2) {
\$x = deg2rad( \$lon1 - \$lon2 ) * cos( deg2rad( \$lat1 ) );
\$y = deg2rad( \$lat1 - \$lat2 );
\$dist = 6371000.0 * sqrt( \$x*\$x + \$y*\$y );

return \$dist;
}```

If you're not concerned with the actual distance (i.e. just sorting), you can also drop R * from the last step as it's a constant multiplication for all entries

## php - Find closest longitude and latitude in array? - Stack Overflow

php latitude-longitude
`Tricky solution,(for  testing purpose i have added a sample string just in the middle to show this solution is working fine.)`
```\$string='"
|+ EBML version: 1
|+ EBML maximum ID length: 4
|+ EBML maximum size length: 8
|+ Doc type: matroska
|+ Doc type version: 2
|+ Doc type read version: 2
+ Segment, size 627752082
|+ Seek head (subentries will be skipped)
|+ EbmlVoid (size: 4044)
|+ Segment information
| + Timecode scale: 1000000
| + Muxing application: libebml v1.0.0 + libmatroska v1.0.0
| + Writing application: mkvmerge v4.1.1 (\'Bouncin\' Back\') built on Jul  3 2010 22:54:08
| + Duration: 7279.440s (02:01:19.440)
| + Date: Sat Sep 18 15:52:16 2010 UTC
| + Segment UID: 0x83 0x63 0x0c 0xd7 0x2c 0xb9 0x73 0xb5 0xab 0x7f 0xd0 0xa4 0x3d 0x1c 0xf9 0xf6
|+ Segment tracks
| + A track
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
|  + Track UID: 1383154402
|  + Track type: video
|  + Lacing flag: 0
|  + MinCache: 1
|  + Codec ID: V_MPEG4/ISO/AVC
|  + CodecPrivate, length 45 (h.264 profile: Main @L3.1)
|  + Default duration: 40.000ms (25.000 frames/fields per second for a video track)
|  + Video track
|   + Pixel width: 1280
|   + Pixel height: 696
|   + Display width: 1280
|   + Display height: 696
| + A track
|  + Track number: 2 (track ID for mkvmerge & mkvextract: 1)
|  + Track UID: 3159569538
|  + Track type: audio
|  + Codec ID: A_AAC
|  + CodecPrivate, length 2
|  + Default duration: 21.333ms (46.875 frames/fields per second for a video track)
|  + Audio track
|   + Sampling frequency: 48000
|   + Channels: 2
| + A track
|  + Track number: 3 (track ID for mkvmerge & mkvextract: 2)
|  + Track UID: 3633586111
|  + Track type: subtitles
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
| + A track
|  + Track number: 4 (track ID for mkvmerge & mkvextract: 3)
|  + Track UID: 1098098602
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: dut
| + A track
|  + Track number: 5 (track ID for mkvmerge & mkvextract: 4)
|  + Track UID: 2228128442
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: fre
| + A track
|  + Track number: 6 (track ID for mkvmerge & mkvextract: 5)
|  + Track UID: 1507679374
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: ita
| + A track
|  + Track number: 7 (track ID for mkvmerge & mkvextract: 6)
|  + Track UID: 3667538853
|  + Track type: subtitles
|  + Default flag: 0
|  + Lacing flag: 0
|  + Codec ID: S_TEXT/UTF8
|  + Language: swe
|+ EbmlVoid (size: 1239)
|+ Cluster
';
\$result=null;
\$matched=false;
for(\$x=0;\$x<substr_count(\$string, "|");\$x++)
{
preg_match_all("/Track number(?:.*?[\|]){".\$x."}/s", \$string,\$matches);
foreach(\$matches as \$match)
{
if(preg_match_all("/Track number.*?subtitles/s", \$match,\$matches))
{
\$result[]=\$matches;
\$matched=true;
}
}
if(\$matched==true)
{
break;
}
}
print_r(\$result);```

@hmedia1 I dont understand friend what you are trying to say.... are you trying to say somethinig about mickmackusa ?

@SahilGulati we get problem in multi-subtitle (multi-match) case, please check regex101.com/r/Z6DLrr/1 and regex101.com/r/Z6DLrr/2 the first one just grep the last match, the second one works fine for all matches except the first match

@SahilGulati the second solution will return only one result too

## php - get closest match in regex - Stack Overflow

php regex
`\$WidgetText = substr(\$string, 0, strrpos(substr(\$string, 0, 200), ' '));`

And there you have it a reliable method of truncating any string to the nearest whole word, while staying under the maximum string length.

I've tried the other examples above and they did not produce the desired results.

If the given string's length is less than the maximum length, this would cut off everything until the last space. To avoid this, wrap this inside an if statement: if (strlen(\$str) > 200) { ... }

Simple and probably much faster than other solutions.

One issue with this is it returns an empty string if the string doesn't contain a space.

## How to Truncate a string in PHP to the word closest to a certain numbe...

php string function