[NUUG fiksgatami] Idé til å identifisere veieier med OpenStreetmap
Petter Reinholdtsen
pere at hungry.com
Thu Apr 14 09:30:07 CEST 2011
[Petter Reinholdtsen]
> Alternativt kan vi sende til begge, men legge inn informasjon i
> eposten om hva vi har gjettet oss frem til av operatør for veien.
Jeg har videreforedlet perlkoden og patchet inn i bin/send-reports.
Vedlagt er et utkast til patch som gir følgende snutt i
eksempelrapportene på fiksgatami-dev.nuug.no:
Dear Vennesla,
A user of FixMyStreet has submitted the following report of a
local problem that they believe might require your attention.
To view a map of the precise location of this issue, or to
provide an update on the problem, please visit the following
link:
http://fiksgatami-dev.nuug.no/report/57
This web page also contains a photo of the problem, provided by
the user.
----------
Name: =D8rjan V=F8llestad
Email: orjanv (at) gmail.com
Category: Dumpet skrot
Subject: Ute omr=E5det
Details: Cccccccccccc
Latitude: 58.265957
Longitude: 7.975955
Nearest named road to the pin placed on the map (automatically
generated using OpenStreetmap): Sentrumsvegen (FV66)
Guessed road operator: Statens Vegvesen
Ser dette greit ut? Hvis dere synes dette ser greit ut, er neste steg
å sjekke med Matthew hva han synes.
Det nest nederste avsnittet kommer kun hvis Nominatim-søket returnerer
en vei, og det nederste avsnittet kommer kun med hvis koen tror
Statens vegvesen er operatør for veien.
Patchen bør fortsatt justeres. F.eks. tror jeg de OSM-relaterte
funksjonene bør flyttes til perllib/FixMyStreet/Map/OSM.pm i stedet
for å ligge direkte i send-reports.
Jeg tror en slik tilnærming kombinert med at vi sender både til
kommunen og vegvesenet vil gjøre det enklere for mottaker å gjette om
det er en sak de skal ha eller ikke, synliggjøre at bedre datagrunnlag
vil gjøre oss mer treffsikker, samt gjøre at kommunene og vegvesenet
blir mer motivert til å komme med korreksjoner rundt veieierskap og
navn når de ser at de i neste omgang får bedre meldinger når vi
korrigerer OSM basert på tilbakemeldingene.
Vennlig hilsen,
--
Petter Reinholdtsen
-------------- next part --------------
diff --git a/bin/send-reports b/bin/send-reports
index 8e6d2d1..e1e8290 100755
--- a/bin/send-reports
+++ b/bin/send-reports
@@ -46,6 +46,12 @@ BEGIN {
);
}
+use XML::Simple;
+use LWP::Simple;
+use Data::Dumper;
+my $nominatimbase = "http://nominatim.openstreetmap.org/";
+my $osmbase = "http://www.openstreetmap.org/api/";
+
# Set up site, language etc.
my ($verbose, $nomail) = CronFns::options();
my $base_url = mySociety::Config::get('BASE_URL');
@@ -110,9 +116,8 @@ foreach my $row (@$unsent) {
$h{easting_northing} #
= "Easting: $h{easting}\n\n" #
. "Northing: $h{northing}\n\n";
-
- $h{closest_address} = find_closest($row, $h{latitude}, $h{longitude});
}
+ $h{closest_address} = find_closest($row, $h{latitude}, $h{longitude});
$h{closest_address_machine} = $h{closest_address};
my (@to, @recips, $template, $areas_info);
@@ -274,6 +279,72 @@ if ($verbose) {
}
}
+sub lookupNominatim {
+ my ($latitude, $longitude) = @_;
+ my $url =
+ "${nominatimbase}reverse?format=xml&zoom=16&lat=$latitude&lon=$longitude";
+ my $j = LWP::Simple::get($url);
+ if ($j) {
+ my $ref = XMLin($j);
+# print STDERR "URL: $url\n";
+# print STDERR Dumper($ref);
+ return $ref;
+ } else {
+ print STDERR "No reply from $url\n";
+ }
+ return undef;
+}
+sub getOSMWayTags {
+ my $wayid = shift;
+ my $url = "${osmbase}0.6/way/$wayid";
+# print STDERR "URL: $url\n";
+ my $j = LWP::Simple::get($url);
+ if ($j) {
+ my $ref = XMLin($j);
+# print STDERR Dumper($ref);
+ my %tags;
+ map { $tags{$_->{'k'}} = $_->{'v'} } @{$ref->{way}->{tag}};
+ return \%tags;
+ } else {
+ print STDERR "No reply from $url\n";
+ }
+ return undef;
+}
+
+sub guessRoadOperator {
+ my $inforef = shift;
+ my $highway = $inforef->{highway} || "unknown";
+ my $ref = $inforef->{ref} || "unknown";
+
+ my $operator;
+
+ if ($highway eq "trunk"
+ || $highway eq "primary"
+ || $ref =~ m/E \d+/
+ || $ref =~ m/Fv\d+/i
+ ) {
+ $operator = "Statens Vegvesen";
+ }
+# print STDERR "Guessing operator $operator\n" if defined $operator;
+ return $operator;
+}
+
+sub getNearestRoadTags {
+ my ($latitude, $longitude) = @_;
+ my $inforef = lookupNominatim($latitude, $longitude);
+ if ('way' eq $inforef->{result}->{osm_type}) {
+
+ my $osmtags = getOSMWayTags($inforef->{result}->{osm_id});
+# print STDERR Dumper $osmtags;
+ unless (exists $osmtags->{operator}) {
+ $osmtags->{operatorguess} = guessRoadOperator($osmtags);
+ delete $osmtags->{operator};
+ }
+ return $osmtags;
+ }
+ return undef;
+}
+
sub _get_district_for_contact {
my ( $lat, $lon ) = @_;
my $district =
@@ -353,24 +424,55 @@ sub find_closest {
return '' unless $row->{used_map};
# Get nearest road-type thing from Bing
- my $url = "http://dev.virtualearth.net/REST/v1/Locations/$latitude,$longitude?c=en-GB&key=" . mySociety::Config::get('BING_MAPS_API_KEY');
+ my $bingkey;
+ try {
+ $bingkey = mySociety::Config::get('BING_MAPS_API_KEY');
+ } otherwise {
+ my $e = shift;
+ # Ignoring missing BING key, it is optional.
+ };
+ if ($bingkey) {
+ my $url = "http://dev.virtualearth.net/REST/v1/Locations/$latitude,$longitude?c=en-GB&key=$bingkey";
my $j = LWP::Simple::get($url);
if ($j) {
$j = JSON->new->utf8->allow_nonref->decode($j);
if ($j->{resourceSets}[0]{resources}[0]{name}) {
- $str .= "Nearest road to the pin placed on the map (automatically generated by Bing Maps): $j->{resourceSets}[0]{resources}[0]{name}\n\n";
+ $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s\n\n"),
+ $j->{resourceSets}[0]{resources}[0]{name});
+ }
}
}
# Get nearest postcode from Matthew's random gazetteer (put in MaPit? Or elsewhere?)
- $url = "http://gazetteer.dracos.vm.bytemark.co.uk/point/$latitude,$longitude.json";
- $j = LWP::Simple::get($url);
+ if ( mySociety::Config::get('COUNTRY') eq 'GB' ) {
+ my $url = "http://gazetteer.dracos.vm.bytemark.co.uk/point/$latitude,$longitude.json";
+ my $j = LWP::Simple::get($url);
if ($j) {
$j = JSON->new->utf8->allow_nonref->decode($j);
if ($j->{postcode}) {
- $str .= "Nearest postcode to the pin placed on the map (automatically generated): $j->{postcode}[0] ($j->{postcode}[1]m away)\n\n";
+ $str .= sprintf(_("Nearest postcode to the pin placed on the map (automatically generated): %s (%sm away)\n\n"),
+ $j->{postcode}[0], $j->{postcode}[1]);
+ }
+ }
}
+ if ( mySociety::Config::get('COUNTRY') eq 'NO' ) {
+ my $osmtags = getNearestRoadTags($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 .= sprintf(_("Nearest named road to the pin placed on the map (automatically generated using OpenStreetmap): %s%s\n\n"),
+ $name, $ref);
}
+ my $operator = $osmtags->{operator} || $osmtags->{operatorguess};
+ if ($operator) {
+ $str .= sprintf(_("Guessed road operator: %s\n\n"),
+ $operator);
+ }
+ }
+ }
+
return $str;
}
More information about the fiksgatami
mailing list