Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

find locations near zip code

Posted on 2006-07-20
6
338 Views
Last Modified: 2008-02-26
Hi,

We have an intranet application that looks up our retail locations based on the customers zip code (so we can direct them to the nearest store). It's actually an MS SQL stored procedure.

We want to port this to a MySQL/PHP application. Here is the stored procedure that determines the nearest locations:

------------------------------------------------------
CREATE Procedure sp_RetailerDistance

      (
            @pLAT float,
            @pLNG float
      )


As
SELECT TOP 20
    ARX_RetailerLocatorList.CustomerNumber,
    ARX_RetailerLocatorList.ShipToCode,
    ARX_RetailerLocatorList.CustomerName,
    ARX_RetailerLocatorList.AddressLine1,
    ARX_RetailerLocatorList.City,
    ARX_RetailerLocatorList.State,
    ARX_RetailerLocatorList.ZipCode,
    ARX_RetailerLocatorList.PhoneNumber,
    ZipLocation.LAT,
    ZipLocation.LNG,
    STR(3959 * acos(sin(LAT/57.3)*sin(@pLAT/57.3) + cos(LAT/57.3) * cos(@pLAT/57.3) * cos(@pLNG/57.3 - LNG/57.3)),7,1) As Distance
FROM
    dbo.ARX_RetailerLocatorList
    INNER JOIN
    dbo.ZipLocation
    ON
    LEFT(dbo.ARX_RetailerLocatorList.ZipCode, 5) = dbo.ZipLocation.ZIP_CODE
ORDER BY
    Distance ASC

return
GO
----------------------------------------------------

I guess @pLAT and @pLNG are passed in as parameters? IF so, then I should figure out how those values are determined first... Basically I would like suggestions or a solution on how to port this to mysql. Maybe there's already a solution out there that does something similar. I would rather not do it as a stored procedure (and would prefer a php-based solution), but whatever works is good for me...

Thanks!
0
Comment
Question by:MaritimeSource
  • 2
  • 2
  • 2
6 Comments
 

Author Comment

by:MaritimeSource
ID: 17149051
I've determined there's a "ziplocation" table that has the following columns:

zip, city, state, lng, lat

So the script first gets the lng and lat based on the zip provided. Then it passes those to the stored procedure.
0
 
LVL 9

Expert Comment

by:Rob_Jeffrey
ID: 17149153
The stored procedure does take the Latitude and Logitude from the other table as parameters.
You can write this as a PHP function relatively easily.  The first part would be to get the data into an equivilantly structured MySQL tables.

The newest versions of MySQL server allow for stored procedures as well so this could be ported directly into the MySQL server as a stored procedure.
0
 

Author Comment

by:MaritimeSource
ID: 17149181
Right, but stored procedure syntax is different amongst various db's right? This is MS SQL SERVER:

STR(3959 * acos(sin(LAT/57.3)*sin(@pLAT/57.3) + cos(LAT/57.3) * cos(@pLAT/57.3) * cos(@pLNG/57.3 - LNG/57.3)),7,1) As Distance

Would that work directly in MYSQL?
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 9

Assisted Solution

by:Rob_Jeffrey
Rob_Jeffrey earned 100 total points
ID: 17149267
MySQL does have mathematical functions for COS, aCOS, and SIN so it should work with minimal changes.
The function may need some tweaking if there is a sign order difference - but it doesn't look like it.
These functions have been available since at lease MySQL 4.0.3.
0
 
LVL 6

Accepted Solution

by:
SysTurn earned 400 total points
ID: 17152451
The calcualtions you do will have invalid results according to the calculations shown here: http://mathforum.org/library/drmath/view/51711.html

The stored procedure shold be rewritten like this:

STORED PROCEDURE:
==================

CREATE Procedure sp_RetailerDistance

     (
          @pLAT float,
          @pLNG float
     )


As
SELECT TOP 20
    ARX_RetailerLocatorList.CustomerNumber,
    ARX_RetailerLocatorList.ShipToCode,
    ARX_RetailerLocatorList.CustomerName,
    ARX_RetailerLocatorList.AddressLine1,
    ARX_RetailerLocatorList.City,
    ARX_RetailerLocatorList.State,
    ARX_RetailerLocatorList.ZipCode,
    ARX_RetailerLocatorList.PhoneNumber,
    ZipLocation.LAT,
    ZipLocation.LNG,
    CASE
        WHEN (LAT = @pLAT AND LNG = @pLNG) THEN 0
        WHEN ((SIN(LAT / 57.29577951) * SIN(@pLAT / 57.29577951)) + (COS(LAT / 57.29577951) * COS(@pLAT / 57.29577951) * COS((LNG / 57.29577951) - (@pLNG /57.29577951))) > 1) THEN STR(3963.1 * ACOS(1), 7, 1)
        ELSE STR(3963.1 * ACOS(SIN(LAT / 57.29577951) * SIN(@pLAT / 57.29577951)) + (COS(LAT / 57.29577951) * COS(@pLAT / 57.29577951) * COS((LNG / 57.29577951) - (@pLNG /57.29577951))), 7, 1)
    END AS Distance
FROM
    dbo.ARX_RetailerLocatorList
    INNER JOIN
    dbo.ZipLocation
    ON
    LEFT(dbo.ARX_RetailerLocatorList.ZipCode, 5) = dbo.ZipLocation.ZIP_CODE
ORDER BY
    Distance ASC

return
GO



And the PHP function can be something like this:

function RetailerDistance($pLAT, $pLNG)
{
    $SQL = 'SELECT
                ARX_RetailerLocatorList.CustomerNumber,
                ARX_RetailerLocatorList.ShipToCode,
                ARX_RetailerLocatorList.CustomerName,
                ARX_RetailerLocatorList.AddressLine1,
                ARX_RetailerLocatorList.City,
                ARX_RetailerLocatorList.State,
                ARX_RetailerLocatorList.ZipCode,
                ARX_RetailerLocatorList.PhoneNumber,
                ZipLocation.LAT,
                ZipLocation.LNG,
                CASE
                    WHEN (LAT = ' . $pLAT . ' AND LNG = ' . $pLNG . ') THEN 0
                    WHEN ((SIN(LAT / 57.29577951) * SIN(' . $pLAT . ' / 57.29577951)) + (COS(LAT / 57.29577951) * COS(' . $pLAT . ' / 57.29577951) * COS((LNG / 57.29577951) - (' . $pLNG . ' /57.29577951))) > 1) THEN TRUNCATE(3963.1 * ACOS(1), 1)
                    ELSE TRUNCATE(3963.1 * ACOS(SIN(LAT / 57.29577951) * SIN(' . $pLAT . ' / 57.29577951)) + (COS(LAT / 57.29577951) * COS(' . $pLAT . ' / 57.29577951) * COS((LNG / 57.29577951) - (' . $pLNG . ' /57.29577951))), 1)
                END AS Distance
            FROM
                ARX_RetailerLocatorList
                INNER JOIN
                ZipLocation
                ON (LEFT(ARX_RetailerLocatorList.ZipCode, 5) = ZipLocation.ZIP_CODE)
            ORDER BY
                Distance ASC
            LIMIT 0, 20';
               
    //
    // EXECUTE THE SQL AND RETURN ITS RESULT
    //
}

If you still want to work with the same calculations you use, It will be easy for you now to edit the SQL query.


Kind Regards
Bakr
0
 
LVL 6

Expert Comment

by:SysTurn
ID: 17154467
Thanks for the A ;) Glad to hear that your problem has been solved.

Kind Regards
Bakr
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question