I want to calculate distance between two latitude and longitude sets.
My problem
I have 2500+ zip codes in a table and I have 10000+ shops, Every shops and zip codes have their lat, lng.
Every shop has their delivery distance in KMS.
I want to save all zip codes of a shop which falls within their delivery distance in a table named shop_delivery_zips. I can't use maps at the time on placing order, because shop might not want to deliver at every zips which falls in their delivery distance range.
So, first time i want to insert the data in shop_delivery_zips table by checking their delivery distance.
My solution
First, I thought that i will write a code which will go to every zips codes and calculate distance between shop lat, lng and zip lat,lng and will save data in shop_delivery_zips table, but if i do that, then i have to call the google apis for every time and if i do for all our data, then i have to make 2500*10000 google api calls, which google don't allow in one day, so I can't go with those option.
So, i want to know that is there any way by which i calculate the distance between two lat,lng set. May be by the calculation google use to calculate the same. Please suggest me that solution or any other solution if you know.
Please let me know, if anything is not clear.
I know of this solution to calculate as needed (taken from https://github.com/shafiqpab/distance-between-two-addresses-google-maps-api-php/blob/master/index.php):
//Calculate distance from latitude and longitude
$theta = $longitudeFrom - $longitudeTo;
$dist = sin(deg2rad($latitudeFrom)) * sin(deg2rad($latitudeTo)) +
cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo)) *
cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.8515;
$unit = strtoupper($unit);
// for units in KM
$kilometers = round($miles * 1.609344, PHP_ROUND_HALF_UP).' km';
Is that what you are looking for?
While #tbedner has the correct solution mathematically, you do not want to perform this calculation against every location in the list, as the math is very non-trivial.
First you define a simple bounding box, eg:
lat BETWEEN $min_lat AND $max_lat
AND
lng BETWEEN $min_lng AND $max_lng
Which is very simple and can easily leverage indexes, and then you do the complicated math on the much smaller subset of locations that fall inside the box to find the ones that are within the radius you want.
Related
I'm interested in making a site which will store several locations and needs to be able to find them based on a user's query. Similar to how sites like Yelp, Zomato, Zillow, etc. function. My preferred tech stack is PHP/MySQL.
That said, I have a few related questions. Given a database of locations with their associate latitude/longitude coordinates...
How are they able to query their database of locations and return the ones within X distance of a specific city or ZIP code?
Furthermore, how can they query their database for locations that, instead of being within proximity, are within very specific city or state limits? Where do they get their boundary data from and how do you determine if a coordinate falls within that boundary in an efficient manner?
Lastly, I notice that some of the sites have city-specific links on their site. I would have expected city data to be pulled from remote mapping APIs, but they often associate images and other content with those cities. Do these sites store the names of all cities in their own database? Where do they get their list?
This will help with your first point.
I use this query to search properties in my database by distance from a starting point. The starting point is the longitude and latitude, $coordX and $coordY. I get these from doing a geocode lookup on the Google Maps API:
SELECT properties.*,
(
( ACOS(SIN(".$coordX." * PI() / 180) *
SIN(coordX * PI() / 180) + COS(".$coordX." * PI() / 180) *
COS(coordX * PI() / 180) * COS((".$coordY." - coordY) *
PI() / 180)) * 180 / PI()) * 60 * 1.1515
)
AS distance
FROM properties
order by distance
In my table I store the coordinates of the coordinates of individual properties in the coordX and coordY columns.
Here's MySQL function that will take two latitude/longitude pairs, and give you the distance in degrees between the two points.
It uses the Haversine formula to calculate the distance. Since the Earth is not a perfect sphere, there is some error near the
poles and the equator.
To convert to miles, multiply by 3961.
To convert to kilometers, multiply by 6373.
To convert to meters, multiply by 6373000.
To convert to feet, multiply by (3961 * 5280) 20914080.
DELIMITER $$
CREATE FUNCTION haversine(
lat1 FLOAT, lon1 FLOAT,
lat2 FLOAT, lon2 FLOAT
) RETURNS float
NO SQL
DETERMINISTIC
COMMENT 'Returns the distance in degrees on the Earth between two known points of latitude and longitude. To get miles, multiply by 3961, and km by 6373'
BEGIN
RETURN DEGREES(ACOS(
COS(RADIANS(lat1)) *
COS(RADIANS(lat2)) *
COS(RADIANS(lon2) - RADIANS(lon1)) +
SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
));
END;
DELIMITER ;
Add columns to your address table for latitude and longitude with a type of FLOAT(10,6).
Write a php script to do the lookup of the lat/long when the record is saved.
Then you can do a select against the table to get a list of addresses with distances. You can even sort
the results by distance, or limit the result to a certain radius from the reference location.
SELECT
`street`,
`city`,
`state`,
`zip`,
(haversine($ref_location_lat,$ref_location_long,`lat`,`long) * 3961) as `distance`
FROM `address_table`
WHERE (haversine($ref_location_lat,$ref_location_long,`lat`,`long) * 3961) < 300 // Example for limiting returned records to a raduis of 300 miles.
ORDER BY haversine($ref_location_lat,$ref_location_long,`lat`,`long) DESC; // Don't need actual distance for sorting, just relative distance.
I would like to calculate distance between 2 points of latitude and longitude in PHP (NOT IN ANDROID)**i have read about **Haversine Formula and Spherical Law of Cosines for calculate distance between two points but my main motive is get best location difference between 2 points in Meters.
For Example Two devices place at next to each other and that android devices is sending location to server,So we need to take that location of each device and calculate minimum distance between these 2 device in meter.Result from Server after calculation should be like in 2-3 meters when device is placed next to each others
So what are the possible ways to calculate minimum distance between two device in meters when device next to each other on server side
Note : I need to calculate distance which i got in kms or miles which is big difference when device is next to each other. Haversine Formula and Spherical Law of Cosines is i found best way to calculate but i need to do more in these formulas to get minimum difference between 2 device.Not on Android Device. This question is not related to This Question
I have used the Haversine formula in PHP to calculate distance in kms between two geocoordinates:
// Haversine formula
function geoDistance($lon1, $lat1, $lon2, $lat2) {
$R = 6371; // Radius of the earth in km
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
$a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = $R * $c; // Distance in km
return $d;
}
I guess, having enough precision in lon and lat would yield a result that multiplied by 1,000 migth be useful as a measure of distance in meters, right?
According to https://gis.stackexchange.com/questions/8650/measuring-accuracy-of-latitude-and-longitude the fifth decimal place is worth up to 1.1 m: it distinguish trees from each other.
I have a customer that requires that a user can add his/her zip code, then an administrator can select users in specific area range
for example:
user - zip code
1 - 24533
2 - 56924
3 - 35993
4 - 13435
admin's zip code is 39824
He needs to select people in area range of 5 kilometers by zipcode.
How can this happen using php or any other solutions?
Very simple
You just need the latitude and longitude of the zipcodes against which zipcode you want to get the zipcodes. If you not have longitude and latotude get it from google it is free. you can easily get latitude and longitude by zipcode.
For example you want to get the zipcodes round 100 mile of 'H8t'
i have a table of zipcodes having latitude and longitude info.
First i write a query to my table to get latitude and longitude
SELECT * FROM Tbl_Master_ZIPCodes WHERE ZIPcode ='H8T'
after getting latitude and longitude i write a query below to get all zipcodes in the range of 100 miles of 'H8T'
SELECT distinct zipcode,
3963 * (ACOS((SIN(45.456700/57.2958) * SIN(latitude/57.2958)) + (COS(45.456700/57.2958) * COS(latitude/57.2958) * COS(longitude/57.2958 - -73.712000/57.2958)))) AS distance
FROM Tbl_Master_ZIPCodes
WHERE 3963 * (ACOS((SIN(45.456700/57.2958) * SIN(latitude/57.2958)) + (COS(45.456700/57.2958) * COS(latitude/57.2958) * COS(longitude/57.2958 - -73.712000/57.2958)))) <= 100 Order by Distance
php/mysql zip code proximity search
But, personally, I like the zip code range and distance calculation solution for you. If you had lat and long I would suggestion another but this seems to be similar to what you need.
http://www.micahcarrick.com/php-zip-code-range-and-distance-calculation.html
If you are receiving address with the zip code, then you can query the Google geocode Api to get the geocode of these addresses.
Once you have these geocodes, calculating distance can be done using code sample from this site
I have a php script and a database of geolocations.
At the moment my users can enter their postcode, using Yahaa I get their geo location.
Now that I have their geolocation I want to write a script that loads their local businesses in order of distance. I'm guessing to do this I need to load records from the database that have the most similar coordinates to the users current geolocation. I tried this code:
$sql = "SELECT * FROM dirlistings WHERE ABS(latitude - $lat) AND ABS(longitude - $long)";
However it just displays the results in normal order.
Have I missed anything?
I think you want an ORDER clause in there somewhere.
But what you really want is the Haversine formula: MySQL Great Circle Distance (Haversine formula)
It's more complicated than you think.
This is a great article that helped me a lot. Although its written in javascript, you easily change it to php.
http://www.movable-type.co.uk/scripts/latlong.html
Note that circle distance isn't going to be precise enough if you're talking about large distances (thousands of miles, for example), as the earth's surface isn't flat. If you need a better formula for geo-distance calculation, you can use something like this:
$dlat = ((double)$lat) / 57.29577951;
$dlon = ((double)$lon) / 57.29577951;
$sql = "SELECT *
FROM dirlistings
WHERE 3963.0 * acos(sin(latitude / 57.29577951) * sin($dlat) + cos(latitude / 57.29577951) * cos($dlat) * cos($dlon - longitude / 57.29577951)) < MAX_DIST
ORDER BY acos(sin(latitude / 57.29577951) * sin($dlat) + cos(latitude / 57.29577951) * cos($dlat) * cos($dlon - longitude / 57.29577951))
";
The distances here are in miles - make sure to specify correct max distance - and this formula will give very close results for distances of even ten thousand miles. Note though that such computation is quite time- and power-intensive and if you are not dealing with large distances (i.e. nothing more than a couple hundred miles), then you should use a quicker approximation.
You've missed quite a few things. In order to do what you're trying to do, you need to compute (using the Pythagorean theorem) the distance between two points, and then order by that distance.
You can calculate distance ( (lat - $lat)^2 + (lon - $lon)^2 )^0.5 via:
SQRT(
POW(latitude - ' . $lat . ',2)
+
POW(longitude - ' . $lon . ',2)
) AS distance
Then it's as simple as:
ORDER BY distance ASC
Try ORDER BY latitude, longitude at the end. That should do it or approximately do it.
I have a table which has complete route co-ordinates (lat/lon). The data is of every 0.5 meters. I want to calculate distance between every two points and put the result in distance column of mysql table:
Lat lon Distance
12.9994 77.66645 0
12.9874 77.76888 0.5
12.8977 77.88404 1.0
12.7899 11.87999 1.5
I have written a function in php to calculate like GetDist($lat1,$lon1,$lat2,$lon2), but the issue is every time $lat1,$lon1,$lat2,$lon2 has to be fetched from mysql and after coming out of the function $lat1 should be updated with $lat2 and $lon1 should be updated with $lon2 and $lat2/$lon2 should acquire new data from Mysql.
Can anyone help me on how to I do this?
Thanks
For calculating the distance of your dataset given one point, you can look at Fastest Way to Find Distance Between Two Lat/Long Points.
Then you can calculate the distance "between every two points" in a loop, taking each row's lat and lng parameter as query.