Lamplight API examples - geographic organisation search

Any data shown on this page is fictious - this is an example!

The example

Search for organisations near:

The code

As in all these examples, we're using the php Lamplight_Client class, which makes constructing requests a bit easier. First, set up the client

    $client = new Lamplight_Client('', array(
        'key'     => LAMPLIGHT_APIKEY,
        'lampid'  => LAMPLIGHT_ID,
        'project' => LAMPLIGHT_PROJECT
    ));   
    

This gives us an Http Client with the authentication parameters set (we use an include to define the LAMPLIGHT_APIKEY, LAMPLIGHT_ID and LAMPLIGHT_PROJECT constants). We don't need to pass a uri because the Lamplight_Client does it for us.

Next, tell it what we want to fetch, and make the request. Firstly, we want some organisations - those that are 'service users' in Lamplight. We'll use the (new in version 2.1) near method to specify where we want to centre our search, and how far to look - in this case, 100,000m (100km). As well as postcodes, you can also search by latitude/longitude or northing/easting - pass them in to the to the same near method. At the server, Lamplight tries to work out what it is: it will check for a valid UK postcode first, then look for a comma, and then look for a decimal point to decide if it's lat/long or northing/easting.

  // Set up the client to fetch all orgs
  $client->fetchOrgs("user")
         ->fetchSome();

  if ($_GET['postcode']) {
      $client->near($_GET['postcode'], 100000);
  }

    

And once that's all set, we can make the request:

    
    $orgResponse = $client->request();

    

The Zend_Http_Response returned (see Zend Framework API docs has some useful methods: we use isError() and getStatus() to check we've got something back with a 200 response, and then getBody() to retrieve the json encoded data. It's then a simple step to decode it and iterate over the data returned to write out some data.

This time, we pass the json returned straight through to some javascript that displays the map. If you run a geographic search like this, Lamplight will return some extra data in the meta data, giving you the latitude/longitude of your search term. So if you search near a postcode, it's telling you the lat/long of that postcode.

This is really handy for centering the map. The javascript below is what's running the map on this page: the comments will walk you through it. We like to use YAHOO User Interface, which may be unfamiliar but shouldn't be too distracting here. The other thing to note is that we need to include the Google Maps and YAHOO user interface seed javascript files: these are loaded in the head of the page:


    <script type="text/javascript" charset="utf-8" 
      src="http://yui.yahooapis.com/3.7.3/build/yui/yui-min.js"></script>
    <script type="text/javascript"
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_GOES_HERE&sensor=ARE_YOU_USING_A_LOCATION_SENSOR">
    </script>

    

We add some divs in the html to hold the map and info pane:

  <div style="clear:both;">
    <div id="orgmap_holder" style="width:60%; height:300px; float:left;"></div>
    <div id="mapinfo" style="width: 35%; height:300px; margin-left: 62%;"></div>
  </div>
   

And then this javascript appears after that. It creates a Google map, centred on our search term. It then goes through the Lamplight data, adding a marker for each organisation found. And for each marker, it also adds an event listener so that if you click on the marker it will display some information in the right-hand pane.


    // This is the main YUI loader: we tell it what modules we'll want to use
    // and the loader loads them for us, before calling the callback function 
    // that builds the map.  Don't worry too much about this if you're not sure
    // what it's all about.
    YUI().use("json", "node", "array", "escape", function (Y) {

        var searchData,
            map,
            mapOptions,
            infoPanel;


        // get our data from Lamplight:
        searchData = Y.JSON.parse('<?php echo addslashes($jsonOrgs); ?>');
        

        // This sets up the map initially.
        // The Lamplight API returns some meta data that includes the lat/lng
        // of the point we searched for (even if that's a postcode)
        // so we can centre the map on that point
        mapOptions = {
            center: new google.maps.LatLng(
                searchData.meta.geosearchCentre.lat, 
                searchData.meta.geosearchCentre.lng
            ),
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(Y.one("#orgmap_holder").getDOMNode(), mapOptions);


        // The node we'll put some text info in if they click
        infoPanel = Y.one("#mapinfo");

        // Add some markers.  We go through the data we have from the server
        // and for each organisation, add a marker.
        // We'll also set it up so that when you click on a marker
        // you get some information in the right-hand panel next to the map
        Y.Array.each(searchData.data, function (org) {

            // create the marker.
            // The item in the array (org) has properties lat and lng, and name 
            // (amongst others)
            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(org.lat, org.lng),
                map: map,
                title: org.name
            });


            // now listen for the click on it:
            google.maps.event.addListener(marker, "click", function() {
                var esc = Y.Escape.html;
                infoPanel.setHTML("<h2>" + esc(org.name) + "</h2>" +
                    "<p>" + esc(org.address_line_1 + ", " + org.postcode) + "</p>" +
                    (org.Services_offered ? "<p><b>Services: </b>" + 
                    esc(org.Services_offered.join(", ")) + "</p>" : "") + 
                    (org.web !== "" ? "<p><a href=" + esc(org.web) +
                    " target="_blank">" + esc(org.web) + "</a></p>" : "")
                );
            });
        });
      
      });

    

There's some obvious improvements we could make here: We could set the zoom level so we see markers if they exist. We could set up the geographic search as a json service on our server, and with map pans make new AJAX requests and update the markers as we go.