
Note: This is currently broken and outdated.
The location search api is not ready for location 3.



This file describes the public API for the CivicSpace location system as defined by
 in the library implemented by "location.inc" and its supporting files.

For a example of this API's usage, consult "location.module"


FUNCTION SPECIFICATIONS DESCRIBED IN THIS FILE:
----------------------------------------------
  location_nearby_postalcodes_bylocation(): A function that searches for postal codes within a specified search-radius
                  for a specified location.

  location_nearby_postalcodes_bylatlon(): A function that searches for postal codes within a specified search-radius for
                  a specified latitude and longitude.

  location_get_postalcode_data(): A function that takes a (postalcode,country) pair an returns lat/lon, city, province.  This
                  function is meant to replace location_latlon_rough(); see below.

  location_latlon_rough(): A function that returns the latitude and longitude of the specified postal-code/country pair.
                  This latitude and longitude will be of the approximate center of the postal-code's area.  This function
                  will soon be removed from the API as it has been replaced by the more comprehensive
                  location_get_postalcode_data() described above. [TO BE DEPRECATED]

  location_latlon_exact(): A function that returns the latitude and longitude of the given full location.  Typically implemented
                  on top of a web-service. [TO BE IMPLEMENTED]

  location_map_link(): A function that returns, based on the site configuration, either NULL or 1 or more deep-links to mapping
                   web sites for the parameter location array.

  location_driving_directions_link(): A function that returns, given 2 locationes, a deep-link to Yahoo! Maps or some other site
                  that provides driving directions.  The site chosen depends on the implementation at the country-level.

  location_form(): A function that generates a form for collecting locative information.  Depending on the parameters,
                  it can collect just the postal code and country or a full location or whatever fields are specified
                  in its parameters.

  location_proximity_form(): A function that generates a form for collecting proximity search parameters.

  location_valid(): A function for validating locationes. [TO BE SPECIFIED]

  theme_location(): A function that takes in an location and themes it.  (e.g., $output .= theme('location', $location)).

  location_distance_between(): A function that, given a pair of lat/lon pairs, returns the distance between them.

  location_form2api(): A function that, given an location submitted via a form generated by location_form, converts the
                      submitted location into a form to be used by the rest of the API.

  location_api2form(): A function that, given an location in the standard array format (see "IMPORTANT NOTES" below)
                      returns an location in a format that can be passed to location_form in order to render the
                      form with the appropriate prefilled values.


"[TO BE SPECIFIED]"   => Function spec has not been completed and may possibly be eliminated from spec.
"[TO BE IMPLEMENTED]" => Function spec exists but is to be implemented in a future release.
"[TO BE DEPRECATED]"  => This function will soon be removed from the API.
----------------------------------------------



IMPORTANT NOTES:
----------------
Formats
---
In the following API, a 'location' is merely an associative array with the following keys:
  'street'      => A string for the street portion of an location
  'additional'  => A string for the additional street portion of an location
  'province'    => An upper-case, standard postal abbreviation of a state/province/territory
  'postal_code' => A string or integer for the postal code
  'country'     => The lower-case of the ISO 3166 two-letter alpha code (e.g., 'us' for U.S., 'ca' for Canada).

For locations that are passed to location_form() for the $prefilled_values parameter, the same format applies
except that the 'province' field is the concatenation of the country code, '-', and the province abbreviation.
For example, 'CA' is the value for California for all purposes, but when passing this in a location for prefilled
values, it should be 'us-CA'.  There are two functions to help convert back and forth between these formats:
location_form2api() and location_api2form().  These are described further below.

Delegation
---
With the exception of location_form() and location_proximity_form(), the calls to functions listed here are, in the end,
dispatched to country-specific location libraries which are implemented in country-specific '.inc' files.  For example,
location_latlon_rough(), when given a U.S. location, really returns a result that is determined by call to
"location_latlon_rough_us()" which is implemented in the file "location.us.inc".

Current Implementation
---
Currently, the only country supported is the United States.  For the future, however, there will be documentation for how to
implement a country-specific include file that can be plugged into the system to support these calls for new countries.  This
scheme will revolve around method signatures for a handful of simple-to-write functions.






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_nearby_postalcodes_bylocation($location, $distance, $distance_unit = 'km');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes an location and a distance and returns an array of all postal-codes (from all countries that are supported)
within the specified distance of the specified location.

@param $location
  An associative array where
    'street'       => the street location
    'additional'   => extra street location or building name or hall or something like that.
    'city'         => a city name
    'province'     => province code as defined by the country specific include file
    'country'      => lower-cased two-letter ISO 3166 code (REQUIRED)
    'postal_code'  => the postal_code

@param $distance
  The number portion of the distance; it is forced to an integer ceiling

@param $distance_unit
  The unit of distance being used for the distance being submitted.
  Valid arguments for $distance_unit are 'mile' and 'km'.  If something other than one of
  these unit types is submitted for this argument, it is forced to 'km'.

@return
  An array where
    -> the keys are a postive integer ranking of the search result's closeness to the parameter $postal_code
       with 1 being assigned to the nearest postal code
    -> the values are an associative array where
         'postal_code'   => A postal code that fell within the search-radius given by $distance and $distance_unit.
         'country'       => The two-letter ISO code for the home-country of this particular postal_code search result.
         'city'          => The city to which this postal code belongs.
         'province'      => The province to which this postal code belongs.
         'lon'           => The longitude coordinate of the approximate center of the area covered by 'postal_code'
         'lat'           => The latitude coordinate of the approximate center of the area covered by 'postal_code'
         'distance'      => The number of 'km's or 'mile's that are between the approximate center of the area of
                            the $postal_code parameter and that of the 'postal_code' in this subarray
         'distance_unit' => The unit of distance specified by 'scalar'






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_nearby_postalcodes_bylatlon($lon, $lat, $distance, $distance_unit = 'km');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes a latitude, longitude, and a distance, and returns all postal_codes within

@param $lon
  A floating point of the longitude coordinate of the search point

@param $lat
  A floating point of the latitude coordinate of the search point

@param $distance
  The number portion of the distance; it is forced to an integer ceiling

@param $distance_unit
  The unit of distance being used for the distance being submitted.
  Valid arguments for $distance_unit are 'mile' and 'km'.  If something other than one of
  these unit types is submitted for this argument, it is forced to 'km'.

@return
  An array where
    -> the keys are a contatenation of the country's ISO code and the postal code.  For example, if
       one of the search results is for postal code "94803" in the United States, the key is then "us94803"
    -> the values are an associative array where
         'postal_code'   => A postal code that fell within the search-radius given by $distance and $distance_unit.
         'country'       => The two-letter ISO code for the home-country of this particular postal_code search result.
         'lon'           => The longitude coordinate of the approximate center of the area covered by 'postal_code'
         'lat'           => The latitude coordinate of the approximate center of the area covered by 'postal_code'
         'distance'      => The number of 'km's or 'mile's that are between the approximate center of the area of the
                            $postal_code parameter and that of the 'postal_code' in this array
         'distance_unit' => The unit of distance specified by 'distance'


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_get_postalcode_data($location = array());                                            +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes a location and uses the combination of postal code and country to return an array that gives the
city, province, and lat/lon dat for that postal code.

@param $location
  An associative array $location where
    'street'       => the street portion of the location
    'additional' => additional street portion of the location
    'province'     => the province, state, or territory
    'country'      => lower-cased two-letter ISO code (REQUIRED)
    'postal_code'  => international postal code (REQUIRED)

@return
  NULL if data cannot be found.
  Otherwise, an associative array where
    'lat' => is a floating point of the latitude coordinate of this location
    'lon' => is a floating point of the longitude coordinate of this location
    'city' => is a string for the city this postalcode is in (or the most recognized city at the given postal)
    'province' => the province of the given postal code.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_latlon_rough($location = array());                                                   +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Takes an location and returns a "rough" latitude/longitude pair based on the postal code
data available for the given country.

@param $location
  An associative array $location where
    'street'       => the street portion of the location
    'additional' => additional street portion of the location
    'province'     => the province, state, or territory
    'country'      => lower-cased two-letter ISO code (REQUIRED)
    'postal_code'  => international postal code (REQUIRED)

@return
  NULL if data cannont be found.
  Otherwise, an associative array where
    'lat' => is a floating point of the latitude coordinate of this location
    'lon' => is a floating point of the longitude coordinate of this location





++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_latlon_exact($location = array());                                                     +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Currently, this is not a priority until there is an implementable use for exact longitude,
latitude coordinates for an location.  The idea is that this call will eventually retrieve
information through a web-service.  Whereas location_latlon_rough() returns an approximate
lat/lon pair based strictly on the postal code where this lat/lon pair is pulled from a
database table, this function is intended to send the entire location to a web-service and
to retrieve exact lat/lon coordinates.

@param $location
  An array where
    -> the key values are 'street', 'additional', 'province', 'country', 'postal_code'
    -> the values are:
        'street'         => the string representing the street location (REQUIRED)
        'additional'     => the string representing the additional street location portion in the location form
        'city'           => the city name (REQUIRED)
        'province'       => the province code defined in the country-specific include file
        'country'        => the lower-case of the two-letter ISO code (REQUIRED)
        'postal_code'    => the postal-code (REQUIRED)

@return
  NULL if the delegated-to function that does the actual look-up does not exist.
  If the appropriate function exists, then this function returns an associative array where
     'lon' => A floating point number for the longitude coordinate of the parameter location
     'lat' => A floating point number for the latitude coordinate of the parameter location






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_map_link($location = array(), $link_text = 'See map');                                 +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Get deep-links to a mapping services such as Yahoo! Maps or MapQuest (actual providers depend on configuration
of location module) given a location.  The call is delegated based on the 'country' value in the $location parameter.

@param $location
  An associative array where
     'street'       => A string representing the street location
     'additional'   => A string for any additional portion of the street location
     'city'         => A string for the city name
     'province'     => The standard postal abbreviation for the province
     'country'      => The two-letter ISO code for the country of the location (REQUIRED)
     'postal_code'  => The international postal code for the location

@return
  NULL if there are not mapping providers configured for the country or if no links could be generated.
  A string of the form "See map: Yahoo! Maps, MapQuest" where Yahoo! Maps and Mapquest are links to the
  given location and can be replaced with other options (e.g., Google) available in the location module settings.
  The idea is to encode the appropriate parameters as HTTP GET variables to the URL.





++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_driving_directions_link($locationA = array(), $locationB = array(), $link_text = 'Get directions');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Takes two locationes and tries to return a deep-link to driving directions.

Parameters:
@param $locationA
  An associative array that represents an location where
     'street'       => the street portions of the location
     'additional'   => additional street portion of the location
     'city'         => the city name
     'province'     => the province, state, or territory
     'country'      => lower-cased two-letter ISO code (REQUIRED)
     'postal_code'  => the postal code

@param $locationB
  An associative array that represents an location in the same way that
  parameter $locationA does.

@param $link_text
  The text of the HTML link that is to be generated.

@return
  A deep-link to driving directions on Yahoo! or some other mapping service, if enough fields are filled in the parameters.
  A deep-link to a form for driving directions with information pre-filled if not enough, but some fields are filled in the parameters.
  The empty string if no information is provided (or if so little information is provided that there is no function to which to delegate
  the call.

  We dispatch the call to a country-specific function.  The country-specific function, in this case,
  will be the one reflected by the country parameter of the first function.  We require that
  both locationes supplied have a country field at the minimum.

  The country-specific functions will ultimately decide, with the parameters given, whether to
  to link to a form for driving directions is provided, where this form will be
  pre-populated with whatever values were available or whether to link directly to the driving
  directions themselves if enough fields are filled for each location.






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_form($fields = array(), $prefilled_values = array(), $required_fields = array(), $description = '', $form_name = 'location', $function = NULL);
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Generates a Drupal HTML form for collecting locationes.

@param $fields
  An array of values where each value is one of 'street', 'city', 'province', 'postal_code', or 'country'.
  The presence of values in this array determines which fields will be served in the location form generated
  by a call to this function.  If this array is empty, all fields are generated.

@param $prefilled_values
  An associative array where
    -> Each key is one of the location fields: 'street', 'additional', 'city', 'province', 'postal_code', 'country'
    -> Each value is a prefilled value for the given field.                                       ..... ))

@param $required_fields
  An array of values that are required.  Each string can be one of 'street', 'city', 'postal_code', 'province', or 'country'.
  The presence of values in this array determines which fields will be marked as 'required'.  Validation (i.e., making sure
  a required value is actually filled in is the responsibility of the caller)

@param $description
  A text description of specifically what location is being collected by the form to be served.

@param $form_name
  An additional parameter to help prevent HTML input name collisions.  If the caller is using this
  function to generate more than 1 location form on a page, then the generated name for each HTML input's
  "name" attribute will go by the value supplied for $form_name.  This parameter is defaulted to 'location'
  For example, if $form_name == 'xyz' and there is a 'street' field in the form to be served,
  the "name" attribute for the HTML <input> will be "edit[xyz][street]"

@param $function
  A string that tells location_form() which location API function will be using the location submitted via the
  generated form.  For example, if $function == 'latlon_rough', then the returned location_form (if it includes
  a country field) will only generate a list of countries in the HTML select for which function location_latlon_rough()
  is supported.  To figure out which countries these are, we check to see which of the configured countries have existing
  functions to support the call.  In this case, we would check to see if there existed a function called "location_latlon_rough_us()"
  before listing the United States in the HTML SELECT for the generated location form.  $function is defaulted to NULL.
  If $function is NULL, the HTML SELECT that is generated will list all countries.

@return
  An location form based on the parameters specified.  If the $fields array is empty, then the
  function returns a form in which all possible fields are served as optional form items.


EXAMPLES:

   -> The following call returns a form that only contains fields for a postal_code and country where
      the postal_code is required:
           ---
           $form = location_form(array('postal_code', 'country'), array(), array('postal_code', 'country'), 'Permanent location')
           ---
      The form returned by this call is generated with calls to Drupal's 'form_' functions:

           $form  = form_textfield('Postal Code', 'location][postal_code', '', 64, 64, NULL, NULL, TRUE);
      -------------------------------------------------------------------------------------------------
   -> The following call returns a form that contains fields for a street, province, and postal_code,
      but the street, city, and province fields are optional while postal_code is required:
           ---
           $form = location_form(array('street', 'city', 'province', 'postal_code'), array(), array('postal_code'));
           ---
   -> The form returned by this call is generated with the following calls to Drupal's 'form_' functions:

           $form  = form_textfield('Street', 'location][street', '', 64, 64);
           $form .= form_textfield('Additional', 'location][additional', '', 64, 64);
           // The 'Additional' field is always and only generated when 'street' is specified as one of the fields.
           // The 'Additional' field is always optional whether or not 'Street' is required.
           $form .= form_textfield('City', 'location][city', '', 64, 64);
           $form .= _location_province_select_options(); // defined below
           $form .= form_textfield('Postal Code', 'location][postal_code', '', 64, 64, NULL, NULL, TRUE);
       ------------------------------------------------------------------------------------------------
   For the following examples, assume we have the following two locationes:
      (1) $locationA = ('street' => '2010 Broadway St', 'city' => 'Redwood City', 'province' => 'CA', 'postal_code' => '94063', 'country' => 'us');
      (2) $locationB = ('street' => '2010 Broadway St', 'city' => 'Redwood City', 'province' => 'us-CA', 'postal_code' => '94063', 'country' => 'us');
    -> The following calls return the exact same form that contains fields for a street, province, postal_code, where prefilled
       values are submitted to the form.

           $form = location_form(array('street', 'city', 'province', 'postal_code', 'country'), $locationB, array('street', 'city', 'province', 'postal_code',  country'), '', 'home_location');

           $form = location_form(array('street', 'city', 'province', 'postal_code', 'country'), location_api2form($locationA), array('street', 'city', 'province', 'postal_code', 'country'), '', 'home_location');

    -> The form returned by these call is ultimately generated with the following calls to Drupal's 'form_' functions:

           $form  = textfield('Street', 'home_location][street', '2010 Broadway St.', 64, 64, NULL, NULL, TRUE);
           $form .= textfield('Additional', 'home_location][additional', 'Attn: Ankur Rishi', 64, 64, NULL, NULL, TRUE);
           $form .= textfield('City', 'home_location][city', 'Redwood City', 64, 64, NULL, NULL, TRUE);
           $form .= _location_province_select_options(TRUE, 'us-CA', 'home_location');
           $form .= textfield('Postal Code', 'home_location][postal_code', '94063', 64, 64, NULL, NULL, TRUE);
           $form .= _location_country_select_options(TRUE, 'us', 'home_location');

       Note that in both cases, the first and third argument can take the same array since all the fields are being required.






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_proximity_form($location_form = '', $label = '', $description = '', $prefilled_values = array(), $form_name = 'location');
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
This function generates a form for doing proximity searches within a certain distance
of a specified point.

Depending on the context within which this function is called, the search-point can either
be user-supplied via the location form that is passed (if one is available) or done within
a search-point extracted from a contact table or some other location source specified by
the programmer calling this function.

@param $location_form
  An optional location form, preferably generated by location_form().  If the script processing this
  form also needs a user-supplied location, this parameter is used to specify a form for collecting the
  search-point about which this search is being done.  If the caller does not supply a form, it is
  assumed that the caller already has a search point in mind and that this will be made clear in
  the $description parameter.

@param $label
  The label you want to apply to the form group that is returned (passed as $legend param to form_group()).

@param $description
  A text description of what is being searched for (e.g., 'Find all upcoming events near you.')

@param $prefilled_values
  An associative array for prefilled values for the proximity search parameters, where
    'distance' => is the prefilled int value to be selected for the distance scalar
    'distance_unit' => is 'km' or 'mile'

@param $form_name
  An additional parameter to help prevent HTML input name collisions.  If the caller is using this
  function to generate more than 1 location proximity form on a page, then the generated name for
  each HTML input's "name" attribute will be $form_name.  Allowing the caller to pass $form_name allows
  the caller the flexibility of using more than one location proximity search form on one page.

@return
  An HTML form (generated by Drupal form functions) that lets users specify proximity search parameters that include distance,
  the unit of distance, and a search-point if the optional $location_form parameter is passed.  If one is not passed,
  the caller of this function will be assumed to already have one.






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function theme_location($location = array());                                                            +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Generates HTML for the passed location.

@param $location
  An associative array where
     'street'       => A string representing the street location
     'additional'   => A string for any additional portion of the street location
     'city'         => A string for the city name
     'province'     => The standard postal abbreviation for the province
     'country'      => The two-letter ISO code for the country of the location (REQUIRED)
     'postal_code'  => The international postal code for the location

@return
  An HTML string with special tags for locationes.





++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_distance_between($latlonA = array(), $latlonB = array(), $distance_unit = 'km');      +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Given two points in lat/lon form, returns the distance between them.

@param $latlonA
  An associative array where
     'lon' => is a floating point of the longitude coordinate for the point given by latlonA
     'lat' => is a floating point of the latitude coordinate for the point given by latlonB

@param $latlonB
     Another point formatted like $latlonB

@param $distance_unit
     A string that is either 'km' or 'mile'.
     If neither 'km' or 'mile' is passed, the parameter is forced to 'km'

@return
   NULL if sense can't be made of the parameters.
   An associative array where
     'scalar' => Is the distance between the two lat/lon parameter points
     'distance_unit' => Is the unit of distance being represented by 'scalar'.
                        This will be 'km' unless 'mile' is passed for the $distance_unit param





++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_form2api($location = array());                                                         +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@param $location
  An associative array that has been submitted by an HTML form generated by location_form().

@return
  An associative array in which the submitted values are modified to pass to the location API
  as the $location parameter (excepting location_form()).

  This means changing the province field to remove the country code and dash.
  For example: California is served by the key 'us-CA' in the location form and this is what is passed when it is
               submitted through a form generated by location_form().

               This is changed to 'CA' in the returned array.






++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function location_api2form($location = array());                                                         +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Inverse of location_form2api()

@param $location
  An associative array that can be passed as the $location parameter to the location API.

@return
  An associative array with the same values modified so that the array can be passed as the
  $prefilled_values parameter to location_api2form()

  Meant to take the standard location array format used by the public API (minus the form generating functions) and convert them
  into values that can be used by location_form() to fill in the prefilled values.

