aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/Geocode
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/Geocode')
-rw-r--r--perllib/FixMyStreet/Geocode/Bexley.pm71
-rw-r--r--perllib/FixMyStreet/Geocode/Bing.pm9
-rw-r--r--perllib/FixMyStreet/Geocode/Google.pm3
-rw-r--r--perllib/FixMyStreet/Geocode/OSM.pm15
-rw-r--r--perllib/FixMyStreet/Geocode/Zurich.pm33
5 files changed, 122 insertions, 9 deletions
diff --git a/perllib/FixMyStreet/Geocode/Bexley.pm b/perllib/FixMyStreet/Geocode/Bexley.pm
new file mode 100644
index 000000000..8a1a886bb
--- /dev/null
+++ b/perllib/FixMyStreet/Geocode/Bexley.pm
@@ -0,0 +1,71 @@
+package FixMyStreet::Geocode::Bexley;
+use parent 'FixMyStreet::Geocode::OSM';
+
+use warnings;
+use strict;
+
+use URI::Escape;
+
+my $base = 'http://tilma.mysociety.org/mapserver/bexley?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=Streets&outputFormat=geojson&Filter=%3CFilter%3E%3CPropertyIsLike%20wildcard=%27*%27%20singleChar=%27.%27%20escape=%27!%27%3E%3CPropertyName%3EADDRESS%3C/PropertyName%3E%3CLiteral%3E{{str}}%3C/Literal%3E%3C/PropertyIsLike%3E%3C/Filter%3E';
+
+# Data is ALL CAPS
+sub recase {
+ my $word = shift;
+ return $word if $word =~ /FP/;
+ return lc $word if $word =~ /^(AND|TO)$/;
+ return ucfirst lc $word;
+}
+
+sub string {
+ my ($cls, $s, $c) = @_;
+
+ my $osm = $cls->SUPER::string($s, $c);
+ my $js = query_layer($s);
+ return $osm unless $js && @{$js->{features}};
+
+ $c->stash->{geocoder_url} = $s;
+
+ my ( $error, @valid_locations, $latitude, $longitude, $address );
+ foreach (sort { $a->{properties}{ADDRESS} cmp $b->{properties}{ADDRESS} } @{$js->{features}}) {
+ my @lines = @{$_->{geometry}{coordinates}};
+ @lines = ([ @lines ]) if $_->{geometry}{type} eq 'LineString';
+ my @points = map { @$_ } @lines;
+ my $mid = int @points/2;
+ my $e = $points[$mid][0];
+ my $n = $points[$mid][1];
+ ( $latitude, $longitude ) = Utils::convert_en_to_latlon_truncated( $e, $n );
+ $address = sprintf("%s, %s", $_->{properties}{ADDRESS}, $_->{properties}{TOWN});
+ $address =~ s/([\w']+)/recase($1)/ge;
+ push @$error, {
+ address => $address,
+ latitude => $latitude,
+ longitude => $longitude
+ };
+ push (@valid_locations, $_);
+ }
+
+ if ($osm->{latitude}) { # one result from OSM
+ push @$error, {
+ address => $osm->{address},
+ latitude => $osm->{latitude},
+ longitude => $osm->{longitude},
+ };
+ return { error => $error };
+ }
+
+ if (ref $osm->{error} eq 'ARRAY') {
+ push @$error, @{$osm->{error}};
+ return { error => $error };
+ }
+
+ return { latitude => $latitude, longitude => $longitude, address => $address }
+ if scalar @valid_locations == 1;
+ return { error => $error };
+}
+
+sub query_layer {
+ my $s = uc shift;
+ $s = URI::Escape::uri_escape_utf8("*$s*");
+ (my $url = $base) =~ s/\{\{str\}\}/$s/;
+ return FixMyStreet::Geocode::cache('bexley', $url);
+}
diff --git a/perllib/FixMyStreet/Geocode/Bing.pm b/perllib/FixMyStreet/Geocode/Bing.pm
index 9e425441a..1d39d911f 100644
--- a/perllib/FixMyStreet/Geocode/Bing.pm
+++ b/perllib/FixMyStreet/Geocode/Bing.pm
@@ -11,13 +11,19 @@ use strict;
use FixMyStreet::Geocode;
use Utils;
+sub setup {
+ my $cls = shift;
+ return 1 if FixMyStreet->config('BING_MAPS_API_KEY');
+ return 0;
+}
+
# 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 ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
@@ -32,6 +38,7 @@ sub string {
$url .= '&userLocation=' . $params->{centre} if $params->{centre};
$url .= '&c=' . $params->{bing_culture} if $params->{bing_culture};
+ $c->stash->{geocoder_url} = $url;
my $js = FixMyStreet::Geocode::cache('bing', $url, 'key=' . FixMyStreet->config('BING_MAPS_API_KEY'));
if (!$js) {
return { error => _('Sorry, we could not parse that location. Please try again.') };
diff --git a/perllib/FixMyStreet/Geocode/Google.pm b/perllib/FixMyStreet/Geocode/Google.pm
index ad1881541..ffbad96ba 100644
--- a/perllib/FixMyStreet/Geocode/Google.pm
+++ b/perllib/FixMyStreet/Geocode/Google.pm
@@ -16,7 +16,7 @@ use URI::Escape;
# 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 ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
@@ -49,6 +49,7 @@ sub string {
$url .= '&components=' . $components if $components;
+ $c->stash->{geocoder_url} = $url;
my $args = 'key=' . FixMyStreet->config('GOOGLE_MAPS_API_KEY');
my $js = FixMyStreet::Geocode::cache('google', $url, $args, qr/"status"\s*:\s*"(OVER_QUERY_LIMIT|REQUEST_DENIED|INVALID_REQUEST|UNKNOWN_ERROR)"/);
if (!$js) {
diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm
index 0d296f299..20e653cf6 100644
--- a/perllib/FixMyStreet/Geocode/OSM.pm
+++ b/perllib/FixMyStreet/Geocode/OSM.pm
@@ -14,8 +14,8 @@ use Memcached;
use XML::Simple;
use Utils;
-my $osmapibase = "http://www.openstreetmap.org/api/";
-my $nominatimbase = "http://nominatim.openstreetmap.org/";
+my $osmapibase = "https://www.openstreetmap.org/api/";
+my $nominatimbase = "https://nominatim.openstreetmap.org/";
# string STRING CONTEXT
# Looks up on Nominatim, and caches, a user-inputted location.
@@ -23,7 +23,7 @@ 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 ) = @_;
+ my ( $cls, $s, $c ) = @_;
my $params = $c->cobrand->disambiguate_location($s);
# Allow cobrand to fixup the user input
@@ -47,19 +47,22 @@ sub string {
if $params->{country};
$url .= join('&', map { "$_=$query_params{$_}" } sort keys %query_params);
+ $c->stash->{geocoder_url} = $url;
my $js = FixMyStreet::Geocode::cache('osm', $url);
if (!$js) {
return { error => _('Sorry, we could not find that location.') };
}
- my ( $error, @valid_locations, $latitude, $longitude );
+ my ( $error, @valid_locations, $latitude, $longitude, $address );
foreach (@$js) {
$c->cobrand->call_hook(geocoder_munge_results => $_);
+ next unless $_->{display_name};
( $latitude, $longitude ) =
map { Utils::truncate_coordinate($_) }
( $_->{lat}, $_->{lon} );
+ $address = $_->{display_name};
push (@$error, {
- address => $_->{display_name},
+ address => $address,
icon => $_->{icon},
latitude => $latitude,
longitude => $longitude
@@ -67,7 +70,7 @@ sub string {
push (@valid_locations, $_);
}
- return { latitude => $latitude, longitude => $longitude } if scalar @valid_locations == 1;
+ return { latitude => $latitude, longitude => $longitude, address => $address } if scalar @valid_locations == 1;
return { error => $error };
}
diff --git a/perllib/FixMyStreet/Geocode/Zurich.pm b/perllib/FixMyStreet/Geocode/Zurich.pm
index c7bd9e9d9..b0c0b528e 100644
--- a/perllib/FixMyStreet/Geocode/Zurich.pm
+++ b/perllib/FixMyStreet/Geocode/Zurich.pm
@@ -24,6 +24,8 @@ sub setup_soap {
# Variables for the SOAP web service
my $geocoder = FixMyStreet->config('GEOCODER');
+ return unless ref $geocoder eq 'HASH';
+
my $url = $geocoder->{url};
my $username = $geocoder->{username};
my $password = $geocoder->{password};
@@ -49,6 +51,34 @@ sub setup_soap {
$method = SOAP::Data->name('getLocation95')->attr({ xmlns => $attr });
}
+sub admin_district {
+ my ($e, $n) = @_;
+
+ setup_soap();
+ return unless $soap;
+
+ my $attr = 'http://ch/geoz/fixmyzuerich/service';
+ my $bo = 'http://ch/geoz/fixmyzuerich/bo';
+ my $method = SOAP::Data->name('getInfoByLocation')->attr({ xmlns => $attr });
+ my $location = SOAP::Data->name(
+ 'location' => \SOAP::Data->value(
+ SOAP::Data->name('bo:easting', $e),
+ SOAP::Data->name('bo:northing', $n),
+ )
+ )->attr({ 'xmlns:bo' => $bo });
+ my $search = SOAP::Data->value($location);
+ my $result;
+ eval {
+ $result = $soap->call($method, $security, $search);
+ };
+ if ($@) {
+ warn $@ if FixMyStreet->config('STAGING_SITE');
+ return 'The geocoder appears to be down.';
+ }
+ $result = $result->result;
+ return $result;
+}
+
# 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
@@ -60,13 +90,14 @@ sub setup_soap {
# versions of the site.
sub string {
- my ( $s, $c ) = @_;
+ my ( $cls, $s, $c ) = @_;
setup_soap();
my $cache_dir = path(FixMyStreet->config('GEO_CACHE'), 'zurich')->absolute(FixMyStreet->path_to());
my $cache_file = $cache_dir->child(md5_hex($s));
my $result;
+ $c->stash->{geocoder_url} = $s;
if (-s $cache_file && -M $cache_file <= 7 && !FixMyStreet->config('STAGING_SITE')) {
$result = retrieve($cache_file);
} else {