I am looking for an algorithm (php would be most ideal) that can, given two sets of coordinates (start and end), calculate the geographical coordinates along that path at given intervals (say every mile). Note that I am not looking for something like Bresenham's algorithm - I want the exact coordinates along the path.
You need to find the latitude/longitude of a point at a given distance along a great circle passing through your start- and end-point. You'll find the formulae worked out here, which you should be able to adapt to your use case.
Related
I have distance matrix as two-dimensional array, like this:
So, I need to find clusters, of elements with its help. I can do it, using hierarchic clusterization, like k-means. I have found such example here PHP K-Means
How can I convert my two-dimensional array into array of points, listed in this example?
$points = [
[80,55],[86,59],[19,85],[41,47],[57,58],
[76,22],[94,60],[13,93],[90,48],[52,54],
[62,46],[88,44],[85,24],[63,14],[51,40],
[75,31],[86,62],[81,95],[47,22],[43,95],
[71,19],[17,65],[69,21],[59,60],[59,12],
[15,22],[49,93],[56,35],[18,20],[39,59],
[50,15],[81,36],[67,62],[32,15],[75,65],
[10,47],[75,18],[13,45],[30,62],[95,79],
[64,11],[92,14],[94,49],[39,13],[60,68],
[62,10],[74,44],[37,42],[97,60],[47,73],
];
First: a nitpick: k-Means is not a hierarchical clustering algorithm, see https://www.quora.com/What-is-the-difference-between-k-means-and-hierarchical-clustering for details o the difference.
Second: you don't want to convert a distance matrix back to the points it originated from as you take a step back. Sadly the k-Means implementation you linked only has an API that allows you to enter raw coordinates and assumes Euclidean distance, therefore you have some possibilities, depending on your requirements:
Where do you get the distance matrix from? If it is possible, get the raw coordinates (and make sure the distance measure is euclidean distance) and use the library you linked.
Override the Point class in the library you linked: specifically the getDistanceWith method to return values from your matrix
If you only need to calculate the cluster once, use python and sklearn. This library does exactly what you want. Especially: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.cluster.hierarchy.linkage.html
Write your own code: clustering is quite an easy topic and therefore it is a nice coding exercise.
Let me explain the project a bit. We have a huge list of stores with addresses. Each one of theses addresses in the database have a geo location.
Now my question is: when a user fills in his address and postal code etc., we have his location and his geo location, is it possible to find the closest store in google maps based on the location of the user. If not through geo location then maybe based on postal code?
I have looked in to google maps api but didn't find something jet to do this.
Important is that it searches in the stores we have added to google maps.
I rather not use google maps but only the: http://maps.googleapis.com/maps/api/geocode/json?
And if it's possible then we can leave google maps out of it but just searched the database based on geo location that would be even better.
The only question then is how do you do the matching based on geo location or something else? You just check witch one is smaller or bigger or is there more to it then comparing the two?
It would be really nice if somebody could give me a good lead on how to do this.
first of all use a map and ask the user to set his approximate location, get that values,
with this code get the distance to each store:
google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
from https://developers.google.com/maps/documentation/javascript/reference?hl=en-US#spherical
now choose the shorter and output it
but I'd rather ask him to input the City and get the distance through Wolfram api request
$city=customer_city;
$north=store_north; //coordinate_l
$west=store_west; //coordinate_L
$wolfram_query="http://api.wolframalpha.com/v2/query?appid=".$appid."&input=distance%20from%20".$city."%20to%20".$north."N%20".$west."W%20in%20km&format=image,plaintext";
and get the distance from the xml answer leaving google maps out
an other option using zipcodes is to calculate the spherical distance from two coordinates with this php function inside a while loop going through all the lat and long of the sores:
function calcDist($lat_A, $long_A, $lat_store[i], $long_store[i]) {
$distance = sin(deg2rad($lat_A))
* sin(deg2rad($lat_B))
+ cos(deg2rad($lat_A))
* cos(deg2rad($lat_B))
* cos(deg2rad($long_A - $long_B));
$distance = (rad2deg(acos($distance))) * 69.09;
return $distance;
}
distance is in miles, if you want the distance in km use this
function miles2kms($miles) {
$ratio = 1.609344;
$kms = $miles * $ratio;
return $kms;
}
and you can retrieve the lat and long of the zip code using this database:
http://sourceforge.net/projects/zips/files/#files
or this
http://postcodedb.sourceforge.net/dumpCSV.php
to improve the result of the distance you should use Haversine or Vincenty calculations... which are a little more complex..
... but what we like of the net is that someone has surely done this before we did, and of course shared his efforts!
http://www.phpclasses.org/package/6480-PHP-Calculate-the-distance-between-Earth-two-points.html
this is a class that implements haversine distance! this might be better... if you want to use Vincenty try this: Implementing Vincenty's Formula in PHP , try which one gives you the best results, even if the most accurate will always be wolfram, mathematicians worked on that, so that works pretty well ;)
When you say "Geo location", what specific information do you have about the location? I've done something similar using co-ordinates (lat and long) of an entity, and a large collection of co-ordinates of nearby places of interest. Because lat and long (in decimal) are just...decimals, then it's one equation to calculate which point is closest to the other by finding the smallest difference between both the lat and long values.
This gets much more complex if you want to consider the travel time between the points, for example, but for simple applications, comparing the co-ordinates should be adequate.
I have a 2D array with various entries at different positions. However some positions have same value (say 5). I need to find the nearest block with value 5 from any other positioned element.!
Image is in this link :)
This is the image to understand the problem better
In this pic above. We can use the concept of Digital Image Processing to find the m-distance between each blocks. But if the problem space is too big ( suppose an array of 100X100 or 200X200) then the solution in this way will be time taking.
In way to solution I found out these links.
Wikipedia Link for Nearest Neighbour
Apart from this how to map this whole thing in programming...?
You can try any PL/SQL code for this, then you can get the nearest point from there.
The simplest (maybe not most efficient) way is if you use the Wikipedia method #1 which is as follows:
Loop though all the coordinate pairs, finding the distance between them. Formula: sqrt((x2-x1)^2+(y2-y1)^2)
Keep track of which pair are closest to the point you are testing, and the closest distance.
After each calculation, test if the distance is shorter; if so, then overwrite the distance and closest-pair variables.
I can expand this if you like.
A client wants a page on their website where the user can search for a stockist of their product range. What they want is the ability to enter a UK PostCode and for a list of their stockists to appear in closest order.
Is there a way to utilise Google Maps to determine the closest supplier?
I have a PHP MySQL database with ALL the suppliers Postcodes and details and I'll have the postcode of the user to use as well.
I think you'll need the Ordnance Survey CodePoint data to map your postcodes to a longitude and latitude. Codepoint is available as a commercial product, or there's also Codepoint Open
Once you have the latitude and longitude, then you can use standard algorithms such as Haversine or Vincenty to calculate distances between the points
EDIT
Structure of the CodePoint Open CSV files can be found here. Note that location is held as Northings and Esatings rather than Longitude and Latitude, so it will need converting. There's a number of articles about this on the web, e.g.
http://www.deepbluesky.com/blog/-/converting-os-coodinates-into-longitude-latitude_7/
http://mediakey.dk/~cc/convert-northing-and-easting-utm-to-longitude-and-latitude/
but you need to be aware that OS Northings/Eastings are based on the Airy 1830 ellipsoid rather than the WGS84 model used by Google maps (and most GSM systems). Failing to allow for this difference can put you out by anything between 70-120m between Cornwall and East Anglia.
You can also find PHP functions to do this conversion at the Movable Type site (essential reading for any PHP developer, working with GeoData. I'd recommend adding a couple off columns to your stockist database for longitude and latitude, and a one-off script to update all existing data using the Codepoint data, then modify your insert/update routines for stockists to keep this information up-to-date.
Using PHP, another solution for this conversion is PHPCoord by Jonathan Stott
For higher performance in your database query, do a lookup of lat/long against a "bounding box" before calculating distances. I've explained how to do this in response to a similar query.
I think you'll need a little more data than that. I'd suggest that you need to store the latitude and longitude of every UK postcode alongside the postcode itself. I think this data is available from the Royal Mail for a cost and I remember reading somewhere that it was going to be available in the public domain too. Have a user enter their postcode, look up their latitude and longitude in the db and then use that to perform another query that calculates the closest supplier to them, perhaps within a certain number of miles. You could perhaps create a stores procedure to do all of this on the db. This post seems to have some details on how to do this.
If you want it to be fast then pre-compute the distances between postcodes within a certain radius of each other - see the following:
Calculate distance between zip codes and users
This should work fine in your case unless you think a user would be willing to travel more than 100 miles to purchase a product ??
Instead of Google Maps, this open postcode geocoding API may be of use to you. As others have mentioned, once you have lat long for both points you can use standard algos to find distances. A previous question contains some info on how to do this directly in SQL.
You may find this website helpful: SQL/CSV Postcode Database
I've previously used this to lookup long/lat from a postcode "outcode".
There's also a php script (which I've not tested) which calculates distance between two postcodes.
Google maps has a function that lets you retreive the distance between two points: getDistance(), of the GDirections class.
Now, this is Javascript, so it'll only be able to calculate once the page has loaded.
My search form however, has the ability to indicate what's the maximum distance you want between yourself and another person and based on that, a list of search results has to be provided.
Since I can't use this function in PHP, is there another way for me to calculate the distance between 2 points on the earth? By giving up the street, postal code and city name, just like what Google maps needs.
This page has a list of google maps parameters for use in http connection. By specifying the output paramter you can choose to give back kml files or similar and can be used in any lanuage that can make http connections.
Looks like you want to calculate a Great Circle Distance
Formulas have been discussed here on stackoverflow before.
A point on earth is defined by it's latitude and longitude. If you want to calculate the distance between 2 points on earth by giving up the street, postal code and city name, you will need geo-referene data.
This data is available for free on the internet, but the accuracy and availability differ greatly from region to region. (USA data is of good quality, data for Kenia for example will be harder to come by)
So to answer your question:
Yes, there are other ways to calculate what you want. But they require more work/are more complex than just querying the google API.
You might want tot read: Creating a Store Locator with PHP, MySQL & Google Maps
Hope this points you into the right direction.
You can use kml file. It's xml-formatted file that you can recieve by link like http://maps.google.com/maps?f=d&hl=en&saddr=<src latitude>,<src longitude>&daddr=<dist latitude>,<dist longitude>&ie=UTF8&0&om=0&output=kml
in recieved file you can parse and summate distances from