Solved

find locations near zip code

Posted on 2006-07-20
6
330 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

911 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now