7 use Geo::EZLocate::Interfaces::Authentication::Authentication;
8 use Geo::EZLocate::Interfaces::Geocoding::Geocoding;
12 Geo::EZLocate - TomTom EZLocate geocoding service interface
20 our $VERSION = '0.01';
22 our $timeout = 10; # in minutes
28 my $geo = Geo::EZLocate->new();
29 my $result = $geo->login('myusername', 'mypassword');
35 =head2 login USERNAME PASSWORD
37 Authenticates and caches a login token. Returns the result code, which
38 is zero on success and nonzero on failure.
42 # shorthand class names
44 my $Interfaces = 'Geo::EZLocate::Interfaces';
45 my $Auth = $Interfaces.'::Authentication::Authentication';
46 my $EZClient = $Interfaces.'::EZClient::EZClient';
47 my $Geocoding = $Interfaces.'::Geocoding::Geocoding';
51 # mimic the official API
54 return bless { username => $username, password => $password, @_ },
61 if ( $self->{identity} and (time - $self->{authtime}) < $timeout ) {
62 return; # no need to reauth
65 my ($username, $password) = @_;
67 $self->{username} = $username;
68 $self->{password} = $password;
73 for (split(//, $self->{password})) {
74 $key = ($key << 4) + ord($_);
75 my $bits = $key & 0xf0000000;
77 $key = ($key ^ $bits);
79 $key = $key & 0x3fffffff;
81 my $client = $self->{'auth'} ||= $Auth->new;
82 my $r_requestChallenge = $client->requestChallenge({
83 userName => $self->{username},
84 minutesValid => $timeout,
86 my $eid = $r_requestChallenge->get_encryptedID;
88 # XOR $eid with key, multiply it by the magic number, XOR it back
89 my $ans = $eid ^ $key;
90 $ans = ($ans * 39371) % 0x3fffffff;
93 my $r_answerChallenge = $client->answerChallenge({
94 originalChallenge => $eid,
95 encryptedResponse => $ans,
98 my $id = $r_answerChallenge->get_credential;
100 $self->{identity} = $id;
101 $self->{authtime} = time;
103 return $r_answerChallenge->get_resultCode;
106 =head2 findAddress ADDRESS, CITY, STATE, ZIP, [OPTION => VALUE] ...
108 Validate the specified address. The only OPTION that matters currently
109 is 'country', which can be set to "CA" to search for addresses in Canada.
116 # again, imitate the positional parameters in the official SDK
117 $params{Addr} = shift;
118 $params{City} = shift;
119 $params{State} = shift;
120 $params{ZIP} = shift;
123 my $client = $self->{geocoding} ||= $Geocoding->new;
125 die "authentication failed" unless $self->{identity};
127 my $service = 'USA_Geo_004';
128 if ( lc($opt{'country'} || '') eq 'ca' ) {
129 $service = 'CAN_Geo_001';
132 nv => [ map { +{ name => $_, value => $params{$_} } } keys %params ]
134 my $r_findAddress = $client->findAddress({
135 'service' => $service,
136 'identity' => $self->{identity},
140 my $nvs = $r_findAddress->get_result->get_mAttributes->get_nv;
143 foreach my $nv (@$nvs) {
144 $match->{$nv->get_name} = '' . $nv->get_value; #force stringification
152 Mark Wells, C<< <mark at freeside.biz> >>
156 Much of the API is unsupported. The Geo::EZLocate::Interfaces::*
157 packages have autogenerated wrappers for all of the API methods, and
158 they work, but I haven't documented or tested most of them.
160 This module shouldn't even be necessary, but the EZLocate SDK has a
161 restrictive license which makes it impractical for open-source
162 development. This is a shame, because their geocoding service is
167 You can find documentation for this module with the perldoc command.
169 perldoc Geo::EZLocate
171 This library is not supported by TomTom.
173 =head1 LICENSE AND COPYRIGHT
175 Copyright 2012 Mark Wells.
177 This program is free software; you can redistribute it and/or modify it
178 under the terms of either: the GNU General Public License as published
179 by the Free Software Foundation; or the Artistic License.
181 See http://dev.perl.org/licenses/ for more information.
186 1; # End of Geo::EZLocate