Il s'agit d'une solution rapide qui trouve la station météorologique NOAA la plus proche pour 21 221 villes dans DBpedia (v2014).
#standardSQL
CREATE TEMPORARY FUNCTION distance(lat1 FLOAT64, lon1 FLOAT64, lat2 FLOAT64, lon2 FLOAT64)
RETURNS FLOAT64
LANGUAGE js AS """
var p = 0.017453292519943295; // Math.PI/180
var c = Math.cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
""";
SELECT *
FROM (
SELECT city, country_label, distance, name weather_station, country,
RANK() OVER(PARTITION BY city ORDER BY distance DESC) rank
FROM (
SELECT city, a.country_label, distance(a.lat,a.lon,b.lat,b.lon) distance, b.name, b.country
FROM (
SELECT rdf_schema_label city, country_label, country,
CAST(REGEXP_EXTRACT(point, r'(-?\d*\.\d*)') as FLOAT64) lat,
CAST(REGEXP_EXTRACT(point, r' (-?\d*\.\d*)') as FLOAT64) lon
FROM `fh-bigquery.dbpedia2014temp.City`
WHERE point!='NULL'
) a
JOIN (
SELECT name, country, usaf, wban, lat, lon
FROM `bigquery-public-data.noaa_gsod.stations`
WHERE lat != 0.0 AND lon !=0.0
) b
ON CAST(a.lat as INT64)=CAST(b.lat as INT64)
AND CAST(a.lon as INT64)=CAST(b.lon as INT64)
)
)
WHERE rank=1
Avertissements:
- Il utilise la formule de distance de https://stackoverflow.com/a/22476600/132438
- Optimise en limitant JOIN que par la recherche de stations dans la même INT (LAT), INT (LON) que la ville. Il est possible d'améliorer cela, mais je vais laisser cela pour une autre question.