Last week I talked about location based searches. I covered how to find the nearest point in a database of locations to a given longitude and latitude. In this article, I take a look at performing a map based search by obtaining a longitude and latitude from a point on a map.
Squaring The Sphere
On the face of it, map based searches should be simple. Just as location based searches should be. But for the same reasons, they are not. A map is a two dimensional projection of a three dimensional sphere. While a map is a rectangle, what it represents in not.
If mapping a relatively small area, it would be convenient to state the coordinates of two opposing corners and measure how far along the X and Y axis a user has clicked to get longitude and latitude. But for most mapping systems, it is necessary to cover a large area.
In the example I gave last week, I needed to work with a county sized map. This was too large an area for the quick and dirty method above.
Performing a Map Based Search
I had a static map, I knew its physical width and height in pixels. I also needed to find the longitude and latitude of each of the four corners of the map. It should be noted, the longitude of the northwest corner was not the same as the longitude for the southwest corner. The same was equally true of the longitude and latitude of each of the corners.
Here comes the technical bit, as before the example is in PHP. The following, sanitised, variables are required to calculate the longitude and latitude of a point on the map:
- $iMapWidth: The width of the map image in pixels.
- $iMapHeight: The height of the map image in pixels.
- $iNEE: The longitude of the northeast corner of the map.
- $iNWE: The longitude of the northwest corner of the map.
- $iSEE: The longitude of the southeast corner of the map.
- $SWE: The longitude of the southwest corner of the map.
- $iNEN: The latitude of the northeast corner of the map.
- $NWN: The latitude of the northwest corner of the map.
- $iSEN: The latitude of the southeast corner of the map.
- $iSWN: The latitude of the of the southwest corner of the map.
- $iMapX: The X coordinate the user clicked on (in pixels).
- $iMapY: The Y coordinate the user clicked on (in pixels).
Calculated Values for Map Based Search
First the longitude and latitude of each corner should be used to create a width and height (in longitude and latitude terms) for the top, bottom, left and right edges of the map.
$iNorthWidth = ($iNEE - $iNWE); $iSouthWidth = ($iSEE - $iSWE); $iWestHeight = ($iNWN - $iSWN); $iEastHeight = ($iNEN - $iSEN);
Next, the user’s click coordinates should be translated to map coordinates. The X coordinate remains the same but the Y coordinate needs to be inverted. The reason for this is compass and map coordinates start in the bottom left, but image coordinates start in the top left:
$iX = $iMapX; $iY = $iMapHeight - 1 - $iMapY;
Finally all these values can be used to calculate an approximate longitude and latitude:
$lon = round(((((((($iNorthWidth - $iSouthWidth) / $iMapHeight) * $iY) + $iSouthWidth) / $iMapWidth) * $iX) + (((($iNWE - $iSWE) / $iMapHeight) * $iY) + $iNWE)) * 100000) / 100000; $lat = round(((((((($iEastHeight - $iWestHeight) / $iMapWidth) * $iX) + $iWestHeight) / $iMapHeight) * $iY) + (((($iSEN - $iSWN) / $iMapWidth) * $iX) + $iSEN)) * 100000) / 100000;
At first glance, it might seem counter intuitive that the height and Y coordinates are being used to calculate the longitude. The same applies to the latitude calculation. However, these are needed to find the average coordinates for a given point.
To complete a map based search, the new longitude and latitude are ready to be used with the method described in my previous article. Take a look at location based searches for more details.
SAMWare UK creates bespoke solutions and websites. Contact us to arrange a chat to discuss your needs and for a free no obligation quote.