diff options
author | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-03-20 14:33:29 +0000 |
---|---|---|
committer | Matthew Somerville <matthew-github@dracos.co.uk> | 2018-04-03 09:34:47 +0100 |
commit | 8b932d2b0ef36579a3b2b5fb9702f03d9e73559a (patch) | |
tree | 76a03b19ac1153708c7441ac8a5d12ab1fedd6c7 | |
parent | 1ddef8a4fc90aa283ec2a24b1a5e332eea7e1069 (diff) |
[FixaMinGata] Update geocoding.
- Removes the FixaMinGata Geocode module
- Surround bounds coordinates with quotes
- Return a different bounding box for Öckerö and other places
- Specifies specific GPS coordinates for certain OpenStreetMap relations
- Removes a comment
-rw-r--r-- | perllib/FixMyStreet/Cobrand/FixaMinGata.pm | 70 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/FixaMinGata.pm | 176 | ||||
-rw-r--r-- | perllib/FixMyStreet/Geocode/OSM.pm | 1 |
3 files changed, 63 insertions, 184 deletions
diff --git a/perllib/FixMyStreet/Cobrand/FixaMinGata.pm b/perllib/FixMyStreet/Cobrand/FixaMinGata.pm index 59c64d455..e84e4cf55 100644 --- a/perllib/FixMyStreet/Cobrand/FixaMinGata.pm +++ b/perllib/FixMyStreet/Cobrand/FixaMinGata.pm @@ -3,10 +3,10 @@ use base 'FixMyStreet::Cobrand::Default'; use strict; use warnings; +use utf8; use Carp; use mySociety::MaPit; -use FixMyStreet::Geocode::FixaMinGata; use DateTime; sub country { @@ -23,10 +23,66 @@ sub enter_postcode_text { # Is also adding language parameter sub disambiguate_location { - return { + my $self = shift; + my $string = shift; + + my $out = { + %{ $self->SUPER::disambiguate_location() }, lang => 'sv', - country => 'se', # Is this the right format? /Rikard + country => 'se', }; + + $string = lc($string); + + if ($string eq 'lysekil') { + # Lysekil + $out->{bounds} = [ '58.4772', '11.3983', '58.1989', '11.5755' ]; + } elsif ($string eq 'tjörn') { + # Tjörn + $out->{bounds} = [ '58.0746', '11.4429', '57.9280', '11.7815' ]; + } elsif ($string eq 'varmdö') { + # Varmdö + $out->{bounds} = [ '59.4437', '18.3513', '59.1907', '18.7688' ]; + } elsif ($string eq 'öckerö') { + # Öckerö + $out->{bounds} = [ '57.7985', '11.5792', '57.6265', '11.7108' ]; + } + + return $out; +} + +sub geocoder_munge_results { + my ($self, $result) = @_; + + if ($result->{osm_id} == 1076755) { # Hammarö, Hammarö, Värmlands län, Svealand, Sweden + $result->{lat} = 59.3090; + $result->{lon} = 13.5297; + } + + if ($result->{osm_id} == 398625) { # Haninge, Landskapet Södermanland, Stockholms län, Svealand, Sweden + $result->{lat} = 59.1069; + $result->{lon} = 18.2085; + } + + if ($result->{osm_id} == 5831132) { # Nordmaling District, Nordmaling, Ångermanland, Västerbottens län, Norrland, 91433, Sweden + $result->{lat} = 63.5690; + $result->{lon} = 19.5028; + } + + if ($result->{osm_id} == 935430) { # Sotenäs, Västra Götalands län, Götaland, Sweden + $result->{lat} = 58.4219; + $result->{lon} = 11.3345; + } + + if ($result->{osm_id} == 935640) { # Tanum, Västra Götalands län, Götaland, Sweden + $result->{lat} = 58.7226; + $result->{lon} = 11.3242; + } + + if ($result->{osm_id} == 289344) { # Älvkarleby, Landskapet Uppland, Uppsala län, Svealand, Sweden + $result->{lat} = 60.5849; + $result->{lon} = 17.4545; + } } sub area_types { @@ -37,11 +93,9 @@ sub area_types { sub geocode_postcode { my ( $self, $s ) = @_; - # Most people write Swedish postcodes like this: - #+ XXX XX, so let's remove the space - # Is this the right place to do this? //Rikard - # This is the right place! // Jonas - $s =~ s/\ //g; # Rikard, remove space in postcode + # Most people write Swedish postcodes like this: + # XXX XX, so let's remove the space + $s =~ s/\ //g; if ($s =~ /^\d{5}$/) { my $location = mySociety::MaPit::call('postcode', $s); if ($location->{error}) { diff --git a/perllib/FixMyStreet/Geocode/FixaMinGata.pm b/perllib/FixMyStreet/Geocode/FixaMinGata.pm deleted file mode 100644 index 3ad98b148..000000000 --- a/perllib/FixMyStreet/Geocode/FixaMinGata.pm +++ /dev/null @@ -1,176 +0,0 @@ -# FixMyStreet:Geocode::FixaMinGata -# OpenStreetmap forward and reverse geocoding for FixMyStreet. -# -# Copyright (c) 2011 Petter Reinholdtsen. Some rights reserved. -# Email: pere@hungry.com - -# This module is a slightly derived version of OSM.pm. - -# As of January 2014, the FixaMinGata developers are considering to make further -# changes related to OSM, so it's probably best to keep this module separate -# from the OSM module for now. - -package FixMyStreet::Geocode::FixaMinGata; - -use warnings; -use strict; - -use LWP::Simple; -use Memcached; -use XML::Simple; -use Utils; - -my $osmapibase = "http://www.openstreetmap.org/api/"; -my $nominatimbase = "http://nominatim.openstreetmap.org/"; - -# string STRING CONTEXT -# Looks up on Nominatim, 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 $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, - format => 'json', - addressdetails => 1, - limit => 20, - #'accept-language' => '', - email => 'info' . chr(64) . 'morus.se', - ); - # $query_params{viewbox} = $params->{bounds}[1] . ',' . $params->{bounds}[2] . ',' . $params->{bounds}[3] . ',' . $params->{bounds}[0] - # if $params->{bounds}; - $query_params{countrycodes} = $params->{country} - if $params->{country}; - $url .= join('&', map { "$_=$query_params{$_}" } keys %query_params); - - my $js = FixMyStreet::Geocode::cache('osm', $url); - if (!$js) { - return { error => _('Sorry, we could not find that location.') }; - } - - my ( %locations, $error, @valid_locations, $latitude, $longitude ); - foreach (@$js) { - next if $_->{class} eq "boundary"; - my @s = split(/,/, $_->{display_name}); - my $address = join(",", @s[0,1,2]); - $locations{$address} = [$_->{lat}, $_->{lon}]; - } - - foreach my $key (keys %locations) { - ( $latitude, $longitude ) = - map { Utils::truncate_coordinate($_) } - ($locations{$key}[0], $locations{$key}[1]); - push (@$error, { - address => $key, - latitude => $latitude, - longitude => $longitude - }); - push (@valid_locations, $_); - } - - return { latitude => $latitude, longitude => $longitude } if scalar @valid_locations == 1; - return { error => $error }; -} - -sub reverse_geocode { - my ($latitude, $longitude, $zoom) = @_; - my $url = - "${nominatimbase}reverse?format=xml&zoom=$zoom&lat=$latitude&lon=$longitude"; - my $key = "OSM:reverse_geocode:$url"; - my $result = Memcached::get($key); - unless ($result) { - my $j = LWP::Simple::get($url); - if ($j) { - Memcached::set($key, $j, 3600); - my $ref = XMLin($j); - return $ref; - } else { - print STDERR "No reply from $url\n"; - } - return undef; - } - return XMLin($result); -} - -sub _osmxml_to_hash { - my ($xml, $type) = @_; - my $ref = XMLin($xml); - my %tags; - if ('ARRAY' eq ref $ref->{$type}->{tag}) { - map { $tags{$_->{'k'}} = $_->{'v'} } @{$ref->{$type}->{tag}}; - return \%tags; - } else { - return undef; - } -} - -sub get_object_tags { - my ($type, $id) = @_; - my $url = "${osmapibase}0.6/$type/$id"; - my $key = "OSM:get_object_tags:$url"; - my $result = Memcached::get($key); - unless ($result) { - my $j = LWP::Simple::get($url); - if ($j) { - Memcached::set($key, $j, 3600); - return _osmxml_to_hash($j, $type); - } else { - print STDERR "No reply from $url\n"; - } - return undef; - } - return _osmxml_to_hash($result, $type); -} - -# A better alternative might be -# http://www.geonames.org/maps/osm-reverse-geocoder.html#findNearbyStreetsOSM -sub get_nearest_road_tags { - my ( $cobrand, $latitude, $longitude ) = @_; - my $inforef = reverse_geocode($latitude, $longitude, 16); - if (exists $inforef->{result}->{osm_type} - && 'way' eq $inforef->{result}->{osm_type}) { - my $osmtags = get_object_tags('way', - $inforef->{result}->{osm_id}); - unless ( exists $osmtags->{operator} ) { - $osmtags->{operatorguess} = $cobrand->guess_road_operator( $osmtags ); - } - return $osmtags; - } - return undef; -} - -sub closest_road_text { - my ( $cobrand, $latitude, $longitude ) = @_; - my $str = ''; - my $osmtags = get_nearest_road_tags( $cobrand, $latitude, $longitude ); - if ($osmtags) { - my ($name, $ref) = ('',''); - $name = $osmtags->{name} if exists $osmtags->{name}; - $ref = " ($osmtags->{ref})" if exists $osmtags->{ref}; - if ($name || $ref) { - $str .= _('The following information about the nearest road might be inaccurate or irrelevant, if the problem is close to several roads or close to a road without a name registered in OpenStreetMap.') . "\n\n"; - $str .= sprintf(_("Nearest named road to the pin placed on the map (automatically generated using OpenStreetMap): %s%s"), - $name, $ref) . "\n\n"; - - if (my $operator = $osmtags->{operator}) { - $str .= sprintf(_("Road operator for this named road (from OpenStreetMap): %s"), - $operator) . "\n\n"; - } elsif ($operator = $osmtags->{operatorguess}) { - $str .= sprintf(_("Road operator for this named road (derived from road reference number and type): %s"), - $operator) . "\n\n"; - } - } - } - return $str; -} - -1; - diff --git a/perllib/FixMyStreet/Geocode/OSM.pm b/perllib/FixMyStreet/Geocode/OSM.pm index 4878df997..d237f453b 100644 --- a/perllib/FixMyStreet/Geocode/OSM.pm +++ b/perllib/FixMyStreet/Geocode/OSM.pm @@ -52,6 +52,7 @@ sub string { my ( $error, @valid_locations, $latitude, $longitude ); foreach (@$js) { + $c->cobrand->call_hook(geocoder_munge_results => $_); ( $latitude, $longitude ) = map { Utils::truncate_coordinate($_) } ( $_->{lat}, $_->{lon} ); |