diff options
author | Matthew Somerville <matthew@mysociety.org> | 2012-12-04 16:10:44 +0000 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2012-12-04 16:10:44 +0000 |
commit | 93e01b6bf2017f308b85301016f16d7e3619b314 (patch) | |
tree | 931c9168347b4fe5e33374cf3de31604b40061a5 /perllib/FixMyStreet/Geocode | |
parent | 429f5b61f56519914dd38c0e62d0709d4d380dee (diff) |
Add Zurich geocoder (and allow geocoder choice to be picked in config).
Diffstat (limited to 'perllib/FixMyStreet/Geocode')
-rw-r--r-- | perllib/FixMyStreet/Geocode/Bing.pm | 9 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/Google.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/OSM.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/Zurich.pm | 90 |
4 files changed, 110 insertions, 3 deletions
diff --git a/perllib/FixMyStreet/Geocode/Bing.pm b/perllib/FixMyStreet/Geocode/Bing.pm index 18e6b56ce..85eef3d0f 100644 --- a/perllib/FixMyStreet/Geocode/Bing.pm +++ b/perllib/FixMyStreet/Geocode/Bing.pm @@ -15,14 +15,21 @@ use File::Path (); use LWP::Simple; use Digest::MD5 qw(md5_hex); +use mySociety::Locale; + # string STRING CONTEXT # Looks up on Bing Maps API, and caches, a user-inputted location. # Returns array of (LAT, LON, ERROR), where ERROR is either undef, a string, or # an array of matches if there are more than one. The information in the query # may be used to disambiguate the location in cobranded versions of the site. sub string { - my ( $s, $c, $params ) = @_; + my ( $s, $c ) = @_; + + my $params = $c->cobrand->disambiguate_location($s); + + $s = FixMyStreet::Geocode::escape($s); $s .= '+' . $params->{town} if $params->{town} and $s !~ /$params->{town}/i; + my $url = "http://dev.virtualearth.net/REST/v1/Locations?q=$s"; $url .= '&userMapView=' . join(',', @{$params->{bounds}}) if $params->{bounds}; diff --git a/perllib/FixMyStreet/Geocode/Google.pm b/perllib/FixMyStreet/Geocode/Google.pm index db3a8ae91..fd65b89b1 100644 --- a/perllib/FixMyStreet/Geocode/Google.pm +++ b/perllib/FixMyStreet/Geocode/Google.pm @@ -14,6 +14,7 @@ use File::Slurp; use File::Path (); use LWP::Simple; use Digest::MD5 qw(md5_hex); +use mySociety::Locale; # string STRING CONTEXT # Looks up on Google Maps API, and caches, a user-inputted location. @@ -21,7 +22,11 @@ use Digest::MD5 qw(md5_hex); # an array of matches if there are more than one. The information in the query # may be used to disambiguate the location in cobranded versions of the site. sub string { - my ( $s, $c, $params ) = @_; + my ( $s, $c ) = @_; + + my $params = $c->cobrand->disambiguate_location($s); + + $s = FixMyStreet::Geocode::escape($s); my $url = 'http://maps.google.com/maps/geo?q=' . $s; $url .= '&ll=' . $params->{centre} if $params->{centre}; diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm index d96338c16..fd14b0acc 100644 --- a/perllib/FixMyStreet/Geocode/OSM.pm +++ b/perllib/FixMyStreet/Geocode/OSM.pm @@ -29,8 +29,13 @@ my $nominatimbase = "http://nominatim.openstreetmap.org/"; # an array of matches if there are more than one. The information in the query # may be used to disambiguate the location in cobranded versions of the site. sub string { - my ( $s, $c, $params ) = @_; + my ( $s, $c ) = @_; + + my $params = $c->cobrand->disambiguate_location($s); + + $s = FixMyStreet::Geocode::escape($s); $s .= '+' . $params->{town} if $params->{town} and $s !~ /$params->{town}/i; + my $url = "${nominatimbase}search?"; my %query_params = ( q => $s, diff --git a/perllib/FixMyStreet/Geocode/Zurich.pm b/perllib/FixMyStreet/Geocode/Zurich.pm new file mode 100644 index 000000000..9cffc7a32 --- /dev/null +++ b/perllib/FixMyStreet/Geocode/Zurich.pm @@ -0,0 +1,90 @@ +#!/usr/bin/perl +# +# FixMyStreet::Geocode::Zurich +# Geocoding with Zurich web service. +# +# Thanks to http://msdn.microsoft.com/en-us/library/ms995764.aspx +# and http://noisemore.wordpress.com/2009/03/19/perl-soaplite-wsse-web-services-security-soapheader/ +# for SOAP::Lite pointers +# +# Copyright (c) 2012 UK Citizens Online Democracy. All rights reserved. +# Email: matthew@mysociety.org; WWW: http://www.mysociety.org/ + +package FixMyStreet::Geocode::Zurich; + +use strict; +use Geo::Coordinates::CH1903; +use SOAP::Lite; +use mySociety::Locale; + +my ($soap, $method, $security); + +sub setup_soap { + return if $soap; + + # Variables for the SOAP web service + my $geocoder = FixMyStreet->config('GEOCODER'); + my $url = $geocoder->{url}; + my $username = $geocoder->{username}; + my $password = $geocoder->{password}; + my $attr = 'http://ch/geoz/fixmyzuerich/service'; + my $action = "$attr/IFixMyZuerich/"; + + # Set up the SOAP handler + $security = SOAP::Header->name("Security")->attr({ + 'mustUnderstand' => 'true', + 'xmlns' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' + })->value( + \SOAP::Header->name( + "UsernameToken" => \SOAP::Header->value( + SOAP::Header->name('Username', $username), + SOAP::Header->name('Password', $password) + ) + ) + ); + $soap = SOAP::Lite->on_action( sub { $action . $_[1]; } )->proxy($url); + $method = SOAP::Data->name('getLocation')->attr({ xmlns => $attr }); +} + +# string STRING CONTEXT +# Looks up on Zurich web service a user-inputted location. +# Returns array of (LAT, LON, ERROR), where ERROR is either undef, a string, or +# an array of matches if there are more than one. The information in the query +# may be used to disambiguate the location in cobranded versions of the site. +sub string { + my ( $s, $c ) = @_; + + setup_soap(); + + my $search = SOAP::Data->name('search' => $s)->type(''); + my $count = SOAP::Data->name('count' => 10)->type(''); + my $result = $soap->call($method, $security, $search, $count); + $result = $result->result; + + if (!$result || !$result->{Location}) { + return { error => _('Sorry, we could not parse that location. Please try again.') }; + } + + my $results = $result->{Location}; + $results = [ $results ] unless ref $results eq 'ARRAY'; + + my ( $error, @valid_locations, $latitude, $longitude ); + foreach (@$results) { + ($latitude, $longitude) = Geo::Coordinates::CH1903::to_latlon($_->{easting}, $_->{northing}); + mySociety::Locale::in_gb_locale { + push (@$error, { + address => $_->{text}, + latitude => sprintf('%0.6f', $latitude), + longitude => sprintf('%0.6f', $longitude) + }); + }; + push (@valid_locations, $_); + last if lc($_->{text}) eq lc($s); + } + + return { latitude => $latitude, longitude => $longitude } if scalar @valid_locations == 1; + return { error => $error }; +} + +1; + |