Yii 1.1: geocoder

A standardized interface for GeoCoding APIs
5 followers

This extension allows you to use a standard interface for GeoCoding APIs. As well as to auto generate a Yahoo or Google map of the GeoCoded location.

Currently supported APIs are Google, GeoCoder.us, and Yahoo.

Resources

Documentation

Requirements

  • Yii 1.0.10 or above

Installation

  • Extract the release file under protected/extensions

Usage

Register for an API Key
Google key: http://code.google.com/apis/maps/signup.html
Yahoo key: http://developer.yahoo.com/maps/rest/V1/geocode.html

See the following code examples:

Standalone

Yii::import('application.extensions.geocoder.GeoCoder');
$geocode = new GeoCoder;
$geocode->init();
$geocode->setApiKey('<your API key>'); // As of 1.0.2
$geocode->setDriver('<your driver>'); // 'google' or 'yahoo'
$result = $geocode->query('Las Vegas, NV 89103');

Application Component

'components' => array(
  ...
    'geocoder' => array(
       'class' => 'application.extensions.geocoder.GeoCoder',
       'api_key' => '<your API key>',
       'api_driver' => '<your driver>', // 'google' or 'yahoo'
     ),
  ...
)
 
$result = Yii::app()->geocoder->query('Las Vegas, NV 89103');

Rendering Maps

Summary
The map rendering is handled by the GeoCode_Result class. It uses its own render functions to generate the maps. It also requires javascript to be enabled.

Map Types
The map types that are rendered need to be passed to the view. These are constants as defined by the map supplier. Only include the constant name, do NOT include namespaces, etc.

Caveats
It is possible to change the map provider that is used for rendering a specific GeoCode_Result by passing an optional 3rd parameter to the renderMap function with the name of the provider. However, because some map APIs (eg. Yahoo) require an API key to validate access, these maps can only be rendered from a Result derived from their respective driver.

Because this is using v3 of the Google Maps API, it does not require an API key to access the javascript. Therefore, a google map can be rendered from any Result object. The same can not be said for the other map providers.

Usage
Create an empty div in your HTML with the id of "map_canvas", then use the following code:

Yahoo Map Example

// $result is a GeoCode_Result object from a Yahoo Driver
$result->renderMap('map_canvas', array(
    'mapType' => 'YAHOO_MAP_REG'
));

Google Map Example

// $result is a GeoCode_Result object from a Google Driver
$result->renderMap('map_canvas', array(
    'mapTypeId' => 'ROADMAP',
    'zoom' => 13
));

Note: Some browsers will not render the contents of the canvas and the maps will appear to be hidden. To fix this, add a new CSS entry to main.css that will force the browser to give the canvas a width and height.

#map_canvas {
    width: 500px;
    height: 300px;
}

Multiple Points on the same map

As of version 1.0.4 it is now possible to render multiple points to the same map. This can be accomplished in two ways: 1) by rendering multiple results to the same container, 2) by manually specifying the lat/lon where the marker is to be placed.

Example

// $result is an array of GeoCode_Result objects from a Google Driver
$result[0]->renderMap('map_canvas', array(
    'mapTypeId' => 'ROADMAP',
    'zoom' => 13
));
 
// Render the second result to the same map
// Any options passed to the function will be ignored
//  since this canvas has already been initialized
$result[1]->renderMap('map_canvas');
 
// Render a point manually to that same canvas
// Arguments are in this order because if no canvas is
//  specified, it defaults to using the last one created
$result[0]->renderPoint($my_lat, $my_lon, 'map_canvas');

Change Log

November 12, 2009

  • Initial release.

November 12, 2009 (version 1.0.1)

  • libraries/drivers/Yahoo.php
    1. Adding support for properly handling warning messages
    2. Changed how the cleaned_query is calculated to make it more smart

November 13, 2009 (version 1.0.2)

  • Added functionality to generate a map of the GeoCoded location
  • Fixed Bug #482262

November 17, 2009 (version 1.0.3)

December 2, 2009 (version 1.0.4)

  • Added ability to render many results to the same map using renderMap
  • Added ability to manually add markers to a map using renderPoint

Total 3 comments

#1030 report it
Hitman911 at 2010/01/05 11:29am
google driver

when i use the GeoCoder extension with the google driver on the accordion effect of the pogostick extension it crach the browser I think that there is a style coflict

#1113 report it
mageta at 2009/12/05 07:30pm
A good and useful extension for yii

This is a good extension. It does what it should.

But maybe some suggestions: I have never used the google api before. It was quite annoying to figure out what constants are valid and where they are documented. Maybe you could point your users to it (in your documentation: http://code.google.com/intl/de/apis/maps/documentation/v3/reference.html#MapOptions).

I also added some "nice to have" things into the code. First I added a event in the point-view to center my map on a click of the marker:

google.maps.event.addListener(marker, 'click', function() {
    gmap.panTo(point);
});
You have all these information alrdy inside the view and I found it quite useful ;)

I also added a options-variable to the renderPointer-function (maybe not everyone wants the pointer to be clickable or whatever).

Also a good addition might be the ability to add a InfoWindow into the map. I just copied the renderPoint-function into a new one (the option-array must contain a content-field, which is used for the window):

public function renderWindow($lat, $lon, $container_id, $description=null, $options=array())
{
    // Validate the container
    if (!isset(self::$_map_containers[$container_id]))
        throw new GeoCode_Exception("Unknown map container '{$container_id}'");
    // Get our type
    $type = self::$_map_containers[$container_id];
    // Render the view
    $point_script = $this->render("{$type}/window", array(
        'latitude' => ($lat === null) ? $this->latitude : $lat,
        'longitude' => ($lon === null) ? $this->longitude : $lon,
        'options' => $options
    ), true);
    // Register the javascript
    Yii::app()->clientScript->registerScript("{$type}_point_js".(self::$_point_count++), $point_script, CClientScript::POS_READY);
}
and the view (I found it quite dirty to use "gmap" and "marker" as predefined elements, but you did the same in the point-view (only gmap in there ;) ) and I don't wanted it more complicated just for me ^^):
var point = new google.maps.LatLng(<?php echo $latitude; ?>, <?php echo $longitude; ?>);
var infoWindow = new google.maps.InfoWindow({
<?php
foreach ($options as $key => $value)
{
    echo "\t".$key.': '.$value.",\n";
}
?>
    position: point,
});
google.maps.event.addListener(marker, 'click', function() {
    infoWindow.open(gmap);
});

maybe you or someone else find these things also useful.

#1159 report it
jerry2801 at 2009/11/20 09:11am
Great!

Thanks for share! is so good!

Leave a comment

Please to leave your comment.

Create extension
  • Yii Version: 1.1
  • License: Other Open Source License
  • Developed by: killermonk
  • Category: Others
  • Votes: +3 / -1
  • Downloaded: 1,753 times
  • Created on: Nov 12, 2009
  • Last updated: Dec 23, 2009