Solve conflicts
This commit is contained in:
@@ -1,108 +0,0 @@
|
|||||||
--Text array, country array --
|
|
||||||
--- Function ---
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_admin_country_v1(names text[], country text[])
|
|
||||||
RETURNS SETOF geocode_admin_country_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin_country_v1%rowtype;
|
|
||||||
nans TEXT[];
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
SELECT array_agg(p) INTO nans FROM (SELECT unnest(names) p, unnest(country) c) g WHERE c IS NULL;
|
|
||||||
|
|
||||||
IF 0 < array_length(nans, 1) THEN
|
|
||||||
SELECT array_agg(p), array_agg(c) INTO names, country FROM (SELECT unnest(names) p, unnest(country) c) g WHERE c IS NOT NULL;
|
|
||||||
FOR ret IN SELECT g.q, NULL as c, g.geom, g.success FROM (SELECT (geocode_admin1_polygons(nans)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
|
|
||||||
FOR ret IN WITH
|
|
||||||
p AS (SELECT r.p, r.q, c, (SELECT iso3 FROM country_decoder WHERE lower(regexp_replace(r.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(names)),'.',' ')) p, unnest(names) q, unnest(country) c) r)
|
|
||||||
SELECT
|
|
||||||
q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, c, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_province_polygons
|
|
||||||
WHERE p.p = ANY (synonyms)
|
|
||||||
AND iso3 = p.i
|
|
||||||
-- To calculate frequency, I simply counted the number of users
|
|
||||||
-- we had signed up in each country. Countries with more users,
|
|
||||||
-- we favor higher in the geocoder :)
|
|
||||||
ORDER BY frequency DESC LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM p) n
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql';
|
|
||||||
|
|
||||||
--Text array --
|
|
||||||
|
|
||||||
|
|
||||||
--- Function ---
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_admin_country_v1(name text[])
|
|
||||||
RETURNS SETOF geocode_admin_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_province_polygons
|
|
||||||
WHERE d.c = ANY (synonyms)
|
|
||||||
ORDER BY frequency DESC LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql';
|
|
||||||
|
|
||||||
--Text array, country text--
|
|
||||||
|
|
||||||
|
|
||||||
--- Function ---
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_admin_country_v1(name text[], inputcountry text)
|
|
||||||
RETURNS SETOF geocode_admin_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
FOR ret IN WITH
|
|
||||||
p AS (SELECT r.c, r.q, (SELECT iso3 FROM country_decoder WHERE lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) r)
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_province_polygons
|
|
||||||
WHERE p.c = ANY (synonyms)
|
|
||||||
AND iso3 = p.i
|
|
||||||
-- To calculate frequency, I simply counted the number of users
|
|
||||||
-- we had signed up in each country. Countries with more users,
|
|
||||||
-- we favor higher in the geocoder :)
|
|
||||||
ORDER BY frequency DESC LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM p) n
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql';
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
CREATE OR REPLACE FUNCTION geocode_ip(ip text[])
|
|
||||||
RETURNS SETOF geocode_ip_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_ip_v1%rowtype;
|
|
||||||
n TEXT;
|
|
||||||
new_ips INET[];
|
|
||||||
old_ips TEXT[];
|
|
||||||
BEGIN
|
|
||||||
FOR n IN SELECT unnest(ip) LOOP
|
|
||||||
BEGIN
|
|
||||||
IF family(n::inet)=6 THEN
|
|
||||||
new_ips := array_append(new_ips, n::inet);
|
|
||||||
old_ips := array_append(old_ips, n);
|
|
||||||
ELSE
|
|
||||||
new_ips := array_append(new_ips, ('::ffff:'||n)::inet);
|
|
||||||
old_ips := array_append(old_ips, n);
|
|
||||||
END IF;
|
|
||||||
EXCEPTION WHEN OTHERS THEN
|
|
||||||
SELECT n AS q, NULL as geom, FALSE as success INTO ret;
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
FOR ret IN WITH ips AS (SELECT unnest(old_ips) s, unnest(new_ips) net),
|
|
||||||
matches AS (SELECT s, (SELECT the_geom FROM ip_address_locations WHERE network_start_ip <= ips.net ORDER BY network_start_ip DESC LIMIT 1) geom FROM ips)
|
|
||||||
SELECT s, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM matches
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
@@ -1,324 +0,0 @@
|
|||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[])
|
|
||||||
RETURNS SETOF geocode_namedplace_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN WITH best AS (SELECT s AS q, (SELECT the_geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) ORDER BY population DESC LIMIT 1) AS geom FROM (SELECT unnest(places) as s) p),
|
|
||||||
next AS (SELECT p.s AS q, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM (SELECT unnest(places) as s) p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL))
|
|
||||||
SELECT q, geom, TRUE AS success FROM best WHERE geom IS NOT NULL
|
|
||||||
UNION ALL
|
|
||||||
SELECT q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text, inputcountry text)
|
|
||||||
RETURNS SETOF geocode_admin1_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin1_country_v1%rowtype;
|
|
||||||
has_country BOOLEAN;
|
|
||||||
has_admin1s BOOLEAN;
|
|
||||||
admin1s_a TEXT[];
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
has_country := TRUE;
|
|
||||||
has_admin1s := TRUE;
|
|
||||||
|
|
||||||
IF inputcountry IS NULL THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
ELSIF inputcountry = '' THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF admin1s IS NULL THEN
|
|
||||||
has_admin1s := FALSE;
|
|
||||||
ELSIF admin1s = '' THEN
|
|
||||||
has_admin1s := FALSE;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- no country value
|
|
||||||
IF has_country IS FALSE THEN
|
|
||||||
-- no country no admin1 value
|
|
||||||
IF has_admin1s IS FALSE THEN
|
|
||||||
FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(places)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
-- no country, has admin1 value
|
|
||||||
ELSE
|
|
||||||
FOR ret IN
|
|
||||||
SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM (
|
|
||||||
SELECT (
|
|
||||||
geocode_namedplace(
|
|
||||||
places,
|
|
||||||
(SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r),
|
|
||||||
NULL
|
|
||||||
)
|
|
||||||
).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
-- has country value
|
|
||||||
ELSE
|
|
||||||
-- has country, no admin1 value
|
|
||||||
IF has_admin1s IS FALSE THEN
|
|
||||||
FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(places, inputcountry)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
-- has country, has admin1 value
|
|
||||||
ELSE
|
|
||||||
FOR ret IN
|
|
||||||
SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM (
|
|
||||||
SELECT (
|
|
||||||
geocode_namedplace(
|
|
||||||
places,
|
|
||||||
(SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r),
|
|
||||||
inputcountry
|
|
||||||
)
|
|
||||||
).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text[], inputcountry text)
|
|
||||||
RETURNS SETOF geocode_admin1_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin1_country_v1%rowtype;
|
|
||||||
nans TEXT[];
|
|
||||||
isoTwo TEXT := NULL;
|
|
||||||
has_country BOOLEAN;
|
|
||||||
BEGIN
|
|
||||||
has_country := TRUE;
|
|
||||||
-- find the iso2 code for the input country string, else NULL
|
|
||||||
IF inputcountry IS NULL THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
ELSIF inputcountry = '' THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
END IF;
|
|
||||||
IF has_country THEN
|
|
||||||
SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- find all cases where admin1 is NULL
|
|
||||||
SELECT array_agg(p) INTO nans FROM (SELECT unnest(places) p, unnest(admin1s) c) g WHERE c IS NULL;
|
|
||||||
|
|
||||||
IF 0 < array_length(nans, 1) THEN
|
|
||||||
SELECT array_agg(p), array_agg(c) INTO places, admin1s FROM (SELECT unnest(places) p, unnest(admin1s) c) g WHERE c IS NOT NULL;
|
|
||||||
IF has_country THEN
|
|
||||||
-- geocode our named place without admin1 but with our iso2
|
|
||||||
FOR ret IN SELECT g.q, null AS a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans, inputcountry)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
ELSE
|
|
||||||
-- geocode our named place without admin1 and without iso2
|
|
||||||
FOR ret IN SELECT g.q, NULL as a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- find all cases where admin1 is and empty string
|
|
||||||
SELECT array_agg(p) INTO nans FROM (SELECT unnest(places) p, unnest(admin1s) c) g WHERE c='';
|
|
||||||
|
|
||||||
IF 0 < array_length(nans, 1) THEN
|
|
||||||
SELECT array_agg(p), array_agg(c) INTO places, admin1s FROM (SELECT unnest(places) p, unnest(admin1s) c) g WHERE c!='';
|
|
||||||
IF has_country THEN
|
|
||||||
-- geocode our named place without admin1 but with our iso2
|
|
||||||
FOR ret IN
|
|
||||||
SELECT g.q, '' AS a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans, inputcountry)).*) g
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
ELSE
|
|
||||||
-- geocode our named place without admin1 and without iso2
|
|
||||||
FOR ret IN
|
|
||||||
SELECT g.q, '' AS a1, inputcountry as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans)).*) g
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- geocode all the cases where admin1 is available
|
|
||||||
IF has_country THEN
|
|
||||||
FOR ret IN WITH
|
|
||||||
-- return c=iso2 and search without country
|
|
||||||
p AS (
|
|
||||||
SELECT r.s, r.a1, (SELECT admin1 FROM admin1_decoder WHERE lower(r.a1) = ANY (synonyms) AND admin1_decoder.iso2 = isoTwo LIMIT 1) i FROM (SELECT unnest(places) AS s, unnest(admin1s)::text AS a1) r),
|
|
||||||
best AS (SELECT p.s AS q, p.a1 as a1, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.admin1 = p.i ORDER BY population DESC LIMIT 1) AS geom FROM p),
|
|
||||||
next AS (SELECT p.s AS q, p.a1 AS a1, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND ga.admin1 = p.i AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL))
|
|
||||||
SELECT q, a1, inputcountry as c, geom, TRUE AS success FROM best WHERE geom IS NOT NULL
|
|
||||||
UNION ALL
|
|
||||||
SELECT q, a1, inputcountry as c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
ELSE
|
|
||||||
-- return c=NULL and search without country
|
|
||||||
FOR ret IN WITH
|
|
||||||
p AS (
|
|
||||||
SELECT r.s, r.a1, (SELECT admin1 FROM admin1_decoder WHERE lower(r.a1) = ANY (synonyms) LIMIT 1) i FROM (SELECT unnest(places) AS s, unnest(admin1s)::text AS a1) r WHERE a1 IS NOT NULL and a1 != ''),
|
|
||||||
best AS (SELECT p.s AS q, p.a1 as a1, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.admin1 = p.i ORDER BY population DESC LIMIT 1) AS geom FROM p),
|
|
||||||
next AS (SELECT p.s AS q, p.a1 AS a1, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND ga.admin1 = p.i AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL))
|
|
||||||
SELECT q, a1, inputcountry as c, geom, TRUE AS success FROM best WHERE geom IS NOT NULL
|
|
||||||
UNION ALL
|
|
||||||
SELECT q, a1, inputcountry as c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text[], inputcountry text[])
|
|
||||||
RETURNS SETOF geocode_admin1_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin1_country_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
IF admin1s IS NULL THEN
|
|
||||||
FOR ret IN SELECT g.q as q, NULL as a1, g.c as c, g.geom as geom, g.success as success FROM (SELECT (geocode_namedplace(places, inputcountry)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
ELSE
|
|
||||||
FOR ret IN WITH clean AS (SELECT array_agg(p) p, array_agg(a) a, c FROM (SELECT p, a, c FROM (SELECT unnest(places) p, unnest(admin1s) a, unnest(inputcountry) c) z GROUP BY p, a, c) y GROUP BY c)
|
|
||||||
SELECT (geocode_namedplace(p, a, c)).* FROM clean LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], country text[])
|
|
||||||
RETURNS SETOF geocode_namedplace_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_country_v1%rowtype;
|
|
||||||
nans TEXT[];
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
SELECT array_agg(p) INTO nans FROM (SELECT unnest(places) p, unnest(country) c) g WHERE c IS NULL;
|
|
||||||
|
|
||||||
IF 0 < array_length(nans, 1) THEN
|
|
||||||
SELECT array_agg(p), array_agg(c) INTO places, country FROM (SELECT unnest(places) p, unnest(country) c) g WHERE c IS NOT NULL;
|
|
||||||
FOR ret IN SELECT g.q, NULL as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT array_agg(p) INTO nans FROM (SELECT unnest(places) p, unnest(country) c) g WHERE c='';
|
|
||||||
IF 0 < array_length(nans, 1) THEN
|
|
||||||
SELECT array_agg(p), array_agg(c) INTO places, country FROM (SELECT unnest(places) p, unnest(country) c) g WHERE c!='';
|
|
||||||
FOR ret IN SELECT g.q, '' as c, g.geom, g.success FROM (SELECT (geocode_namedplace(nans)).*) g LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
FOR ret IN WITH
|
|
||||||
p AS (SELECT r.s, r.c, (SELECT iso2 FROM country_decoder WHERE lower(regexp_replace(r.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms)) i FROM (SELECT unnest(places) AS s, unnest(country)::text AS c) r),
|
|
||||||
best AS (SELECT p.s AS q, p.c AS c, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.iso2 = p.i ORDER BY population DESC LIMIT 1) AS geom FROM p),
|
|
||||||
next AS (SELECT p.s AS q, p.c AS c, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND gp.iso2 = p.i AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM p WHERE p.s NOT IN (SELECT q FROM best WHERE c = p.c AND geom IS NOT NULL))
|
|
||||||
SELECT q, c, geom, TRUE AS success FROM best WHERE geom IS NOT NULL
|
|
||||||
UNION ALL
|
|
||||||
SELECT q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], inputcountry text)
|
|
||||||
RETURNS SETOF geocode_admin_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_admin_country_v1%rowtype;
|
|
||||||
isoTwo TEXT := NULL;
|
|
||||||
has_country BOOLEAN;
|
|
||||||
BEGIN
|
|
||||||
has_country := TRUE;
|
|
||||||
-- find the iso2 code for the input country string, else NULL
|
|
||||||
IF inputcountry IS NULL THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
ELSIF inputcountry = '' THEN
|
|
||||||
has_country := FALSE;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF has_country THEN
|
|
||||||
SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1;
|
|
||||||
FOR ret IN WITH
|
|
||||||
best AS (SELECT p.s AS q, (SELECT gp.the_geom AS geom FROM global_cities_points_limited gp WHERE gp.lowername = lower(p.s) AND gp.iso2 = isoTwo ORDER BY population DESC LIMIT 1) AS geom FROM (SELECT unnest(places) AS s) p),
|
|
||||||
next AS (SELECT p.s AS q, (SELECT gp.the_geom FROM global_cities_points_limited gp, global_cities_alternates_limited ga WHERE lower(p.s) = ga.lowername AND gp.iso2 = isoTwo AND ga.geoname_id = gp.geoname_id ORDER BY preferred DESC LIMIT 1) geom FROM (SELECT unnest(places) AS s) p WHERE p.s NOT IN (SELECT q FROM best WHERE geom IS NOT NULL))
|
|
||||||
SELECT q, inputcountry c, geom, TRUE AS success FROM best WHERE geom IS NOT NULL
|
|
||||||
UNION ALL
|
|
||||||
SELECT q, inputcountry c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
-- no country included, or iso interpretation found
|
|
||||||
ELSE
|
|
||||||
FOR ret IN
|
|
||||||
SELECT g.q as q, inputcountry as c, g.geom as geom, g.success as success FROM (SELECT (geocode_namedplace(places)).*) g
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
|
|
||||||
-- geocode_namedplace_country --
|
|
||||||
CREATE OR REPLACE FUNCTION public.geocode_namedplace_country(places text[], country text[])
|
|
||||||
RETURNS SETOF geocode_namedplace_country_v1
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
IMMUTABLE SECURITY DEFINER
|
|
||||||
AS $function$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_country_v1%rowtype;
|
|
||||||
iso TEXT[];
|
|
||||||
i INT;
|
|
||||||
fails INT[];
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
SELECT array_agg((SELECT iso2 FROM country_decoder WHERE lower(regexp_replace(r.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms))) i FROM (SELECT unnest(country)::text AS c) r INTO iso;
|
|
||||||
|
|
||||||
FOR i IN 1 .. array_upper(places, 1) LOOP
|
|
||||||
|
|
||||||
SELECT q, c, (SELECT gp.the_geom AS geom FROM global_cities_points gp WHERE gp.lowername = lower(x.q) AND gp.iso2 = x.i ORDER BY population DESC LIMIT 1), TRUE as success FROM (SELECT unnest(places) q, unnest(iso) i, unnest(country) c) x INTO ret;
|
|
||||||
IF ret.geom IS NOT NULL THEN
|
|
||||||
RETURN NEXT ret;
|
|
||||||
ELSE
|
|
||||||
fails := array_append(fails, i);
|
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$function$
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
-- Functions for points --
|
|
||||||
|
|
||||||
-- codes array, country text
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountry text)
|
|
||||||
RETURNS SETOF geocode_namedplace_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_points
|
|
||||||
WHERE postal_code = upper(d.q)
|
|
||||||
AND iso3 = (
|
|
||||||
SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1
|
|
||||||
)
|
|
||||||
LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
-- codes array, countries array
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountries text[])
|
|
||||||
RETURNS SETOF geocode_place_country_iso_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_place_country_iso_v1%rowtype;
|
|
||||||
geo GEOMETRY;
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, c, iso3, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, c, (SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(d.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1) iso3, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_points
|
|
||||||
WHERE postal_code = upper(d.q)
|
|
||||||
AND iso3 = (
|
|
||||||
SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(d.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1
|
|
||||||
)
|
|
||||||
LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q, unnest(inputcountries) c) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
IF ret.geom IS NULL AND ret.iso3 = 'GBR' THEN
|
|
||||||
geo := geocode_greatbritain_outward(ret.q);
|
|
||||||
IF geo IS NOT NULL THEN
|
|
||||||
ret.geom := geo;
|
|
||||||
ret.success := TRUE;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
-- codes array text
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[])
|
|
||||||
RETURNS SETOF geocode_namedplace_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_points
|
|
||||||
WHERE postal_code = upper(d.q)
|
|
||||||
LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
-- codes array integers, countries array
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_points(code integer[], inputcountries text[])
|
|
||||||
RETURNS SETOF geocode_postalint_country_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_postalint_country_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, c, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_points
|
|
||||||
WHERE postal_code_num = d.q
|
|
||||||
AND iso3 = (
|
|
||||||
SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(d.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1
|
|
||||||
)
|
|
||||||
LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q, unnest(inputcountries) c) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
|
|
||||||
-- Functions for polygons --
|
|
||||||
-- Usage
|
|
||||||
--SELECT (geocode_postalcode_polygons(Array['10013','G9H','03782'], Array['USA', 'Canada', 'US'])).*
|
|
||||||
-- codes array, countries array
|
|
||||||
|
|
||||||
CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) RETURNS SETOF geocode_namedplace_country_v1
|
|
||||||
LANGUAGE plpgsql SECURITY DEFINER
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_country_v1%rowtype;
|
|
||||||
adm text[];
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
SELECT INTO adm array_agg((SELECT adm0_a3 FROM admin0_synonyms WHERE name_ = lower(regexp_replace(b.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text LIMIT 1)) FROM (SELECT UNNEST(inputcountries) c) b;
|
|
||||||
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, c, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_polygons
|
|
||||||
WHERE postal_code = CASE WHEN a = 'CAN' THEN substring(upper(d.q) from 1 for 3) ELSE upper(d.q) END
|
|
||||||
AND iso3 = a
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q, unnest(inputcountries) c, unnest(adm) a) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
-- codes array integers, countries array
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code integer[], inputcountries text[])
|
|
||||||
RETURNS SETOF geocode_postalint_country_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_postalint_country_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, c, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_polygons
|
|
||||||
WHERE postal_code_num = d.q
|
|
||||||
AND iso3 = (
|
|
||||||
SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(d.c, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1
|
|
||||||
)
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q, unnest(inputcountries) c) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
-- codes array text
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code text[])
|
|
||||||
RETURNS SETOF geocode_namedplace_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_polygons
|
|
||||||
WHERE postal_code = upper(d.q)
|
|
||||||
LIMIT 1
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
-- codes array text, countries text
|
|
||||||
CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code text[], inputcountry text)
|
|
||||||
RETURNS SETOF geocode_namedplace_v1 AS $$
|
|
||||||
DECLARE
|
|
||||||
ret geocode_namedplace_v1%rowtype;
|
|
||||||
BEGIN
|
|
||||||
FOR ret IN
|
|
||||||
SELECT
|
|
||||||
q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
q, (
|
|
||||||
SELECT the_geom
|
|
||||||
FROM global_postal_code_polygons
|
|
||||||
WHERE postal_code = upper(d.q)
|
|
||||||
AND iso3 = (
|
|
||||||
SELECT iso3 FROM country_decoder WHERE
|
|
||||||
lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1
|
|
||||||
)
|
|
||||||
) geom
|
|
||||||
FROM (SELECT unnest(code) q) d
|
|
||||||
) v
|
|
||||||
LOOP
|
|
||||||
RETURN NEXT ret;
|
|
||||||
END LOOP;
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user