Advertisement

06.25.2008 at 09:02AM PDT, ID: 23515080
[x]
Attachment Details
[x]
The Solution Rating System

With so many solutions, how can you tell which solutions are most likely to help you and which ones are not? To provide you with a tool to use, we rate our solutions based on various elements that most accurately determine if a solution is a quality solution. To explain what factors affect the solution rating, here are the elements we take into consideration when formulating our solution rating.

  • The Grade of the Solution
  • The Zone Rank of the Expert Providing the Solution
  • The Number of Author and Expert Comments
  • The Number of Experts Contributing
  • The Feedback of the Community

Your Input Matters
Because of the way the system is set up, the most important variable in this equation is you. As a member of Experts Exchange, you are able to cast your vote on the quality of the solutions in regard to how complete, accurate, helpful and easy to understand each solution is. When you provide your feedback, each rating is adjusted accordingly. So, if you see a solution that has a poor rating that you think is a good solution, let us know by rating it. As you do, the rating will be adjusted and will become more accurate for other members of our site.

If you have any suggestions that you would like to make for our rating system, please ask a question in the Suggestions Zone of Community Support.

Thank you!

9.2

Zip code proximity search using zipfinder.cfc  - need to show distance for each zip code

Asked by skodama2 in Cold Fusion Markup Language, ColdFusion Application Server

Tags:

Hi,

I'm working on a zip code proximity search using zipfinder.cfc that was written by Robert Capili.  The proximity search is working great, but I need to show the distance from the origin zip to the zipcodes in the returned array.  I'm sure it can be done - but not sure to how to go about it.

The query qSquareSearch in zipfinder.cfc includes distance from original zip as dist.  I've pasted the major part of the cfc below:

The key area of zipfinder.cfc:
<cfcomponent>      
      <cffunction name="zipToLL" access="public">
            <!---
                  This is a helper function.  Given a zip code, it will look up the
                  relevant lats and longs (and their corresponding values in radians)
                  and then pass back a structure containing this information --->
                  
            <cfargument name="zip" type="string" required="true">
            
            <!--- gets a new coordinate pair --->
            <cfset cp = getNewCoordinate()>      
            
            <cfquery name="qGetLL" datasource="#application.dsn#">
            select latitude,longitude,rlatitude,rlongitude from zip
            where zip = <cfqueryparam value="#zip#" cfsqltype="CF_SQL_CHAR">
            </cfquery>
            
            <cfif qGetLL.recordcount gt 0>
                  <cfset cp.latitude            = qGetLL.latitude>
                  <cfset cp.longitude            = qGetLL.longitude>
                  <cfset cp.rlatitude       = qGetLL.rlatitude>
                  <cfset cp.rlongitude       = qGetLL.rlongitude>
            </cfif>
            
            <cfreturn cp>
    </cffunction>

      <!--- +++++++++++++++++++++++++++++++++++++++++++++ --->            
      
      <cffunction name="getNewCoordinate" access="public">
            <!---
                  Basically, this is a constructor that gives us a blank coordinate pair.
             --->
             
            <cfset retVal                         = structNew()>
            <cfset retVal.latitude            = 0>
            <cfset retVal.longitude            = 0>
            <cfset retVal.rlatitude            = 0>
            <cfset retVal.rlongitude      = 0>
            <cfreturn retVal>            
    </cffunction>
      
      
      <!--- +++++++++++++++++++++++++++++++++++++++++++++ --->            
      
      <cffunction name="squareSearch" access="public">      
            <!---
                  This function performs a proximity search by building out a rectangle
                  from a given set of coordinates, and then returning matching items that
                  fall within that area.  It is not the most accurate way to search, but
                  for smaller distances, it is okay.  It is also very fast.
            --->
            <cfargument name="radius"       type="numeric"       required="true">
            <cfargument name="zip"             type="string"       required="true">
        <cfargument name="type"     type="numeric"  required="true">
            
            <cfset radius             = arguments.radius>
            <cfset zip                  = arguments.zip>            
            <cfset z1                  = zipToLL(zip)>
            
            <cfset lat_miles      = application.latitudeMiles>      <!--- You can change this if you need more precision --->
            <cfset lon_miles      = abs(lat_miles * cos(z1.latitude * application.piDivRad))>
            <cfset lat_degrees      = radius / lat_miles>
            <cfset lon_degrees      = radius / lon_miles>
            
            <!--- This is where we calculate the bounds of the search rectangle --->
            <cfset lat1                  = z1.latitude - lat_degrees>
            <cfset lat2                  = z1.latitude + lat_degrees>
            <cfset lon1                  = z1.longitude - lon_degrees>
            <cfset lon2                  = z1.longitude + lon_degrees>
            
            
            <!---
                  To perform the search, we're going to use trigonometry.  Remember the equation, x^2 + y^2 = z^2,
                  aka the Pythazizzle Thizzle? If you look closely, you can see that we are using that in order
                  to calculate the distance (dist) in the query below.
                  
                  This is good, because it is a fast calculation.  But, it is bad because it is calculating the
                  distance as if it were a line.  If the world were flat, this would be perfect.  But, since it isn't,
                  this will start to show errors the larger the radius gets.
                  
                  Still, for your applications, the errors might be small enough to justify the BLAZING SPEED.
             --->
            <cfquery name="qSquareSearch" datasource="#application.dsn#">
            select       zip, state, city,
                  SQRT(
                              SQUARE(#lat_miles# * (latitude - (#z1.latitude#)))
                              +
                              square(#lon_miles# * (longitude - (#z1.longitude#)))
                        ) as dist
            from       zip
            where
                  latitude between #lat1# AND #lat2#
                  AND
                  longitude between #lon1# AND #lon2#
                  
            order by dist asc
            </cfquery>
            
            <!---
                  This is just a quick filter query that will remove some of the zips that get erroneously
                  included in the result set.  This helps to offset the errors that this method introduces,
                  but only just a little.
             --->
            <cfquery name="qRefine" dbtype="query">
            select * from qSquareSearch where dist < <cfqueryparam value="#radius#" cfsqltype="CF_SQL_INTEGER">
        </cfquery>
            
            <cfreturn qRefine>      
    </cffunction>

On the results page, zipSearch.cfm, the cfc is invoked:

<cfinvoke component="zipfinder" method="squareSearch" radius="#FORM.miles#"
zip="#FORM.zip#" type="#FORM.type#" returnvariable="results"></cfinvoke>

I then look up my customers with a query using the returned zip codes in the radius:

    <cfquery name="hospital" datasource="#application.dsn#">
        select *
        from vwServiceLookup
        where zip IN (#ListQualify(ValueList(results.zip),"'")#) AND svcType = 1
        order by memberLevel DESC, custName ASC
      </cfquery>

I output the query, and it shows the basics from the database.  However, I need to show the distance from the current row's zipcode to the zipcode in #FORM.zip#.  Assuming I can use the returned value dist from the cfc, but not sure how to do it.  Trying to avoid re-querying as much as I can.

Thanks in advance!
Todd
Start Free Trial
 
Loading Advertisement...
 
[+][-]06.25.2008 at 10:45AM PDT, ID: 21868120

View this solution now by starting your 7-day free trial. Setting up your free trial is quick, easy, and secure. We will return you to this solution, unlocked, when you're done.

 

About this solution

Zones: Cold Fusion Markup Language, ColdFusion Application Server
Tags: Coldfusion
Sign Up Now!
Solution Provided By: SBennett
Participating Experts: 2
Solution Grade: A
 
 
[+][-]06.26.2008 at 08:28PM PDT, ID: 21880801

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:01AM PDT, ID: 21885121

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:05AM PDT, ID: 21885163

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:20AM PDT, ID: 21885317

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:24AM PDT, ID: 21885356

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:32AM PDT, ID: 21885434

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:44AM PDT, ID: 21885562

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:46AM PDT, ID: 21885582

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]06.27.2008 at 09:49AM PDT, ID: 21885614

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
 
Loading Advertisement...
20080716-EE-VQP-32 / EE_QW_2_20070628