From 352916d2475266bbc9c18122e56a5a5be6f8fee4 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 15:39:25 +0100 Subject: [PATCH 01/11] Cleans country inputs and fixes some trailing spaces --- geocoder/admin1/sql/geocoder.sql | 38 ++++++++++------------ geocoder/extension/sql/0.0.1/20_admin1.sql | 22 ++++++------- geocoder/setup/admin1/response-types.sql | 16 +++++++-- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/geocoder/admin1/sql/geocoder.sql b/geocoder/admin1/sql/geocoder.sql index c6ff759..0f1e5dd 100644 --- a/geocoder/admin1/sql/geocoder.sql +++ b/geocoder/admin1/sql/geocoder.sql @@ -1,11 +1,9 @@ --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 +DECLARE ret geocode_admin_country_v1%rowtype; nans TEXT[]; BEGIN @@ -21,19 +19,19 @@ DECLARE END IF; - FOR ret IN WITH - p AS (SELECT r.p, r.q, c, (SELECT iso3 FROM country_decoder WHERE lower(r.c) = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(names)),'.',' ')) p, unnest(names) q, unnest(country) c) r) + 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 + SELECT the_geom FROM global_province_polygons - WHERE p.p = ANY (synonyms) + 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 had signed up in each country. Countries with more users, -- we favor higher in the geocoder :) ORDER BY frequency DESC LIMIT 1 ) geom @@ -51,23 +49,23 @@ $$ LANGUAGE 'plpgsql'; --- Function --- CREATE OR REPLACE FUNCTION geocode_admin_country_v1(name text[]) RETURNS SETOF geocode_admin_v1 AS $$ -DECLARE +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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_province_polygons - WHERE d.c = ANY (synonyms) + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -80,23 +78,23 @@ $$ LANGUAGE 'plpgsql'; --- Function --- CREATE OR REPLACE FUNCTION geocode_admin_country_v1(name text[], inputcountry text) RETURNS SETOF geocode_admin_v1 AS $$ - DECLARE + 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(inputcountry) = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) r) + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_province_polygons - WHERE p.c = ANY (synonyms) + 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 had signed up in each country. Countries with more users, -- we favor higher in the geocoder :) ORDER BY frequency DESC LIMIT 1 ) geom diff --git a/geocoder/extension/sql/0.0.1/20_admin1.sql b/geocoder/extension/sql/0.0.1/20_admin1.sql index 8d4310a..756ae0e 100644 --- a/geocoder/extension/sql/0.0.1/20_admin1.sql +++ b/geocoder/extension/sql/0.0.1/20_admin1.sql @@ -13,9 +13,9 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[]) RETURNS SETOF ge FROM ( SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_province_polygons - WHERE d.c = ANY (synonyms) + WHERE d.c = ANY (synonyms) ORDER BY frequency DESC LIMIT 1 ) geom FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) d @@ -31,23 +31,23 @@ $$; CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[], inputcountry text) RETURNS SETOF geocode_admin_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_admin_v1%rowtype; BEGIN - FOR ret IN WITH + FOR ret IN WITH p AS (SELECT r.c, r.q, (SELECT iso3 FROM country_decoder WHERE lower(inputcountry) = 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 + SELECT the_geom FROM global_province_polygons - WHERE p.c = ANY (synonyms) + 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 had signed up in each country. Countries with more users, -- we favor higher in the geocoder :) ORDER BY frequency DESC LIMIT 1 ) geom @@ -63,7 +63,7 @@ $$; CREATE OR REPLACE FUNCTION geocode_admin1_polygons(names text[], country text[]) RETURNS SETOF geocode_admin_country_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_admin_country_v1%rowtype; nans TEXT[]; BEGIN @@ -86,12 +86,12 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(names text[], country text[]) FROM ( SELECT q, c, ( - SELECT the_geom + SELECT the_geom FROM global_province_polygons - WHERE p.p = ANY (synonyms) + 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 had signed up in each country. Countries with more users, -- we favor higher in the geocoder :) ORDER BY frequency DESC LIMIT 1 ) geom diff --git a/geocoder/setup/admin1/response-types.sql b/geocoder/setup/admin1/response-types.sql index acc7abc..a3484ff 100644 --- a/geocoder/setup/admin1/response-types.sql +++ b/geocoder/setup/admin1/response-types.sql @@ -1,3 +1,15 @@ -- Response types for admin1 geocoder -CREATE TYPE geocode_admin_v1 AS (q TEXT, geom GEOMETRY, success BOOLEAN); -CREATE TYPE geocode_admin_country_v1 AS (q TEXT, c TEXT, geom GEOMETRY, success BOOLEAN); + +CREATE TYPE geocode_admin_v1 AS ( + q text, + geom geometry, + success boolean +); + + +CREATE TYPE geocode_admin_country_v1 AS ( + q text, + c text, + geom geometry, + success boolean +); From 4be28d4b9ba02fa57fc94c97c26360831a3817d6 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 15:41:42 +0100 Subject: [PATCH 02/11] Adds country cleaning in extension --- geocoder/extension/sql/0.0.1/20_admin1.sql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/geocoder/extension/sql/0.0.1/20_admin1.sql b/geocoder/extension/sql/0.0.1/20_admin1.sql index 756ae0e..bf994be 100644 --- a/geocoder/extension/sql/0.0.1/20_admin1.sql +++ b/geocoder/extension/sql/0.0.1/20_admin1.sql @@ -4,14 +4,14 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[]) RETURNS SETOF geocode_admin_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, ( SELECT the_geom FROM global_province_polygons @@ -20,7 +20,7 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[]) RETURNS SETOF ge ) geom FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -36,11 +36,11 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[], inputcountry tex BEGIN FOR ret IN WITH - p AS (SELECT r.c, r.q, (SELECT iso3 FROM country_decoder WHERE lower(inputcountry) = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(name)),'.',' ')) c, unnest(name) q) r) + 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 + SELECT q, ( SELECT the_geom FROM global_province_polygons @@ -79,12 +79,12 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(names text[], country text[]) END IF; - FOR ret IN WITH - p AS (SELECT r.p, r.q, c, (SELECT iso3 FROM country_decoder WHERE lower(r.c) = ANY (synonyms)) i FROM (SELECT trim(replace(lower(unnest(names)),'.',' ')) p, unnest(names) q, unnest(country) c) r) + 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 + SELECT q, c, ( SELECT the_geom FROM global_province_polygons From 7661b28e5214aff4bebe6f21a2a03788bd4c11b8 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 15:53:06 +0100 Subject: [PATCH 03/11] Cleans countries in extensions --- .../extension/sql/0.0.1/40_namedplaces.sql | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/geocoder/extension/sql/0.0.1/40_namedplaces.sql b/geocoder/extension/sql/0.0.1/40_namedplaces.sql index 4cd1620..b1a68cd 100644 --- a/geocoder/extension/sql/0.0.1/40_namedplaces.sql +++ b/geocoder/extension/sql/0.0.1/40_namedplaces.sql @@ -5,7 +5,7 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], country text[]) RETURNS SETOF geocode_namedplace_country_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_namedplace_country_v1%rowtype; nans TEXT[]; BEGIN @@ -27,13 +27,13 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], country text[]) RET END LOOP; END IF; - FOR ret IN WITH - p AS (SELECT r.s, r.c, (SELECT iso2 FROM country_decoder WHERE lower(r.c) = ANY (synonyms)) i FROM (SELECT unnest(places) AS s, unnest(country)::text AS c) r), + 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 + SELECT q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next LOOP RETURN NEXT ret; END LOOP; @@ -45,7 +45,7 @@ $$; CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], inputcountry text) RETURNS SETOF geocode_admin_country_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_admin_country_v1%rowtype; isoTwo TEXT := NULL; has_country BOOLEAN; @@ -59,8 +59,8 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], inputcountry text) END IF; IF has_country THEN - SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(inputcountry) = ANY (synonyms) LIMIT 1; - FOR ret IN WITH + 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 @@ -70,11 +70,11 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], inputcountry text) RETURN NEXT ret; END LOOP; -- no country included, or iso interpretation found - ELSE - FOR ret IN + 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; + RETURN NEXT ret; END LOOP; END IF; RETURN; @@ -85,7 +85,7 @@ $$; CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text, inputcountry text) RETURNS SETOF geocode_admin1_country_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_admin1_country_v1%rowtype; has_country BOOLEAN; has_admin1s BOOLEAN; @@ -115,12 +115,12 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text, input RETURN NEXT ret; END LOOP; -- no country, has admin1 value - ELSE - FOR ret IN + ELSE + FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM ( SELECT ( geocode_namedplace( - places, + places, (SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r), NULL ) @@ -136,12 +136,12 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text, input RETURN NEXT ret; END LOOP; -- has country, has admin1 value - ELSE - FOR ret IN + ELSE + FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM ( SELECT ( geocode_namedplace( - places, + places, (SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r), inputcountry ) @@ -158,7 +158,7 @@ $$; CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inputcountry text) RETURNS SETOF geocode_admin1_country_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_admin1_country_v1%rowtype; nans TEXT[]; isoTwo TEXT := NULL; @@ -172,7 +172,7 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inp has_country := FALSE; END IF; IF has_country THEN - SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(inputcountry) = ANY (synonyms) LIMIT 1; + 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 @@ -200,15 +200,15 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inp 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 + 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 + 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; @@ -217,8 +217,8 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inp -- geocode all the cases where admin1 is available IF has_country THEN - FOR ret IN WITH - -- return c=iso2 and search without country + 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), @@ -230,15 +230,15 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inp RETURN NEXT ret; END LOOP; ELSE - -- return c=NULL and search without country - FOR ret IN WITH + -- 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 + 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; @@ -252,14 +252,14 @@ $$; CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inputcountry text[]) RETURNS SETOF geocode_admin1_country_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + 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 + 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; @@ -273,14 +273,14 @@ $$; CREATE OR REPLACE FUNCTION geocode_namedplace(places text[]) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next LOOP RETURN NEXT ret; END LOOP; From b7562ff6f220dd9b8e5e7ca2f6e8a35c7f8b1d83 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 15:53:17 +0100 Subject: [PATCH 04/11] Cleans countries --- .../namedplace/sql/geocode_namedplace.sql | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/geocoder/namedplace/sql/geocode_namedplace.sql b/geocoder/namedplace/sql/geocode_namedplace.sql index 80ba76d..e2f81eb 100644 --- a/geocoder/namedplace/sql/geocode_namedplace.sql +++ b/geocoder/namedplace/sql/geocode_namedplace.sql @@ -3,14 +3,14 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[]) LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + 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 + SELECT q, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next LOOP RETURN NEXT ret; END LOOP; @@ -24,7 +24,7 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + DECLARE ret geocode_admin1_country_v1%rowtype; has_country BOOLEAN; has_admin1s BOOLEAN; @@ -54,12 +54,12 @@ AS $function$ RETURN NEXT ret; END LOOP; -- no country, has admin1 value - ELSE - FOR ret IN + ELSE + FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM ( SELECT ( geocode_namedplace( - places, + places, (SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r), NULL ) @@ -75,12 +75,12 @@ AS $function$ RETURN NEXT ret; END LOOP; -- has country, has admin1 value - ELSE - FOR ret IN + ELSE + FOR ret IN SELECT g.q, admin1s AS a1, inputcountry as c, g.geom, g.success FROM ( SELECT ( geocode_namedplace( - places, + places, (SELECT array_agg(a) FROM (SELECT admin1s a FROM GENERATE_SERIES(1, Array_Length(places, 1)) s) r), inputcountry ) @@ -99,7 +99,7 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + DECLARE ret geocode_admin1_country_v1%rowtype; nans TEXT[]; isoTwo TEXT := NULL; @@ -113,7 +113,7 @@ AS $function$ has_country := FALSE; END IF; IF has_country THEN - SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(inputcountry) = ANY (synonyms) LIMIT 1; + 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 @@ -141,15 +141,15 @@ AS $function$ 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 + 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 + 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; @@ -158,28 +158,28 @@ AS $function$ -- geocode all the cases where admin1 is available IF has_country THEN - FOR ret IN WITH - -- return c=iso2 and search without country + 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 + 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 + -- 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 + 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; @@ -194,14 +194,14 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], admin1s text LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + 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 + 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; @@ -217,7 +217,7 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], country text LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + DECLARE ret geocode_namedplace_country_v1%rowtype; nans TEXT[]; BEGIN @@ -239,13 +239,13 @@ AS $function$ END LOOP; END IF; - FOR ret IN WITH - p AS (SELECT r.s, r.c, (SELECT iso2 FROM country_decoder WHERE lower(r.c) = ANY (synonyms)) i FROM (SELECT unnest(places) AS s, unnest(country)::text AS c) r), + 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 + SELECT q, c, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM next LOOP RETURN NEXT ret; END LOOP; @@ -259,7 +259,7 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace(places text[], inputcountry LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ - DECLARE + DECLARE ret geocode_admin_country_v1%rowtype; isoTwo TEXT := NULL; has_country BOOLEAN; @@ -273,22 +273,22 @@ AS $function$ END IF; IF has_country THEN - SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(inputcountry) = ANY (synonyms) LIMIT 1; - FOR ret IN WITH + 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 + 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 + 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; + RETURN NEXT ret; END LOOP; END IF; RETURN; @@ -301,14 +301,14 @@ CREATE OR REPLACE FUNCTION public.geocode_namedplace_country(places text[], coun LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER AS $function$ -DECLARE +DECLARE ret geocode_namedplace_country_v1%rowtype; iso TEXT[]; - i INT; + i INT; fails INT[]; BEGIN - SELECT array_agg((SELECT iso2 FROM country_decoder WHERE lower(r.c) = ANY (synonyms))) i FROM (SELECT unnest(country)::text AS c) r INTO iso; + 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 From 65dab2196a266067e60dd4f516614173f9d1539b Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 16:04:02 +0100 Subject: [PATCH 05/11] Cleans countries in postal codes --- geocoder/postal-codes/sql/geocoder.sql | 68 +++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/geocoder/postal-codes/sql/geocoder.sql b/geocoder/postal-codes/sql/geocoder.sql index c812634..f91da2a 100644 --- a/geocoder/postal-codes/sql/geocoder.sql +++ b/geocoder/postal-codes/sql/geocoder.sql @@ -4,27 +4,27 @@ CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountry text) RETURNS SETOF geocode_namedplace_v1 AS $$ - DECLARE + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_points WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(inputcountry) = ANY (synonyms) LIMIT 1 + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -35,7 +35,7 @@ $$ LANGUAGE 'plpgsql' SECURITY DEFINER; CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RETURNS SETOF geocode_place_country_iso_v1 AS $$ - DECLARE + DECLARE ret geocode_place_country_iso_v1%rowtype; geo GEOMETRY; BEGIN @@ -44,7 +44,7 @@ CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountries SELECT q, c, iso3, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM ( - SELECT + SELECT q, c, (SELECT iso3 FROM country_decoder WHERE lower(d.c) = ANY (synonyms) LIMIT 1) iso3, ( SELECT the_geom @@ -52,13 +52,13 @@ CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountries WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(d.c) = ANY (synonyms) LIMIT 1 + 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 + LOOP IF ret.geom IS NULL AND ret.iso3 = 'GBR' THEN geo := geocode_greatbritain_outward(ret.q); IF geo IS NOT NULL THEN @@ -76,23 +76,23 @@ $$ LANGUAGE 'plpgsql' SECURITY DEFINER; CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[]) RETURNS SETOF geocode_namedplace_v1 AS $$ - DECLARE + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_points - WHERE postal_code = upper(d.q) + WHERE postal_code = upper(d.q) LIMIT 1 ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -103,27 +103,27 @@ $$ LANGUAGE 'plpgsql' SECURITY DEFINER; CREATE OR REPLACE FUNCTION geocode_postalcode_points(code integer[], inputcountries text[]) RETURNS SETOF geocode_postalint_country_v1 AS $$ - DECLARE + 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 + 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(d.c) = ANY (synonyms) LIMIT 1 + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -139,18 +139,18 @@ $$ LANGUAGE 'plpgsql' SECURITY DEFINER; CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) RETURNS SETOF geocode_namedplace_country_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, c, ( SELECT the_geom FROM global_postal_code_polygons @@ -159,7 +159,7 @@ CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) ) geom FROM (SELECT unnest(code) q, unnest(inputcountries) c, unnest(adm) a) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -170,7 +170,7 @@ $$; -- codes array integers, countries array CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code integer[], inputcountries text[]) RETURNS SETOF geocode_postalint_country_v1 AS $$ - DECLARE + DECLARE ret geocode_postalint_country_v1%rowtype; BEGIN FOR ret IN @@ -184,12 +184,12 @@ BEGIN WHERE postal_code_num = d.q AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(d.c) = ANY (synonyms) LIMIT 1 + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -199,7 +199,7 @@ $$ LANGUAGE 'plpgsql' SECURITY DEFINER; -- codes array text CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code text[]) RETURNS SETOF geocode_namedplace_v1 AS $$ - DECLARE + DECLARE ret geocode_namedplace_v1%rowtype; BEGIN FOR ret IN @@ -208,14 +208,14 @@ CREATE OR REPLACE FUNCTION geocode_postalcode_polygons(code text[]) FROM ( SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_polygons - WHERE postal_code = upper(d.q) + WHERE postal_code = upper(d.q) LIMIT 1 ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -225,26 +225,26 @@ $$ 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 + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_polygons WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(inputcountry) = ANY (synonyms) LIMIT 1 + lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1 ) ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; From 21a893f6acd9f4f9da29fc0aaf365852e3aebbf4 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 16:06:13 +0100 Subject: [PATCH 06/11] Cleans countries in postal codes for extension --- .../extension/sql/0.0.1/50_postalcodes.sql | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/geocoder/extension/sql/0.0.1/50_postalcodes.sql b/geocoder/extension/sql/0.0.1/50_postalcodes.sql index 9dd264f..9ab6e1a 100644 --- a/geocoder/extension/sql/0.0.1/50_postalcodes.sql +++ b/geocoder/extension/sql/0.0.1/50_postalcodes.sql @@ -5,18 +5,18 @@ CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) RETURNS SETOF geocode_namedplace_country_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, c, ( SELECT the_geom FROM global_postal_code_polygons @@ -25,7 +25,7 @@ CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) ) geom FROM (SELECT unnest(code) q, unnest(inputcountries) c, unnest(adm) a) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -38,26 +38,26 @@ $$; CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountry text) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_polygons WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(inputcountry) = ANY (synonyms) LIMIT 1 + lower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text = ANY (synonyms) LIMIT 1 ) ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -69,23 +69,23 @@ $$; CREATE FUNCTION geocode_postalcode_polygons(code text[]) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_polygons - WHERE postal_code = upper(d.q) + WHERE postal_code = upper(d.q) LIMIT 1 ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -98,27 +98,27 @@ $$; CREATE FUNCTION geocode_postalcode_points(code text[], inputcountry text) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_points WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(inputcountry) = ANY (synonyms) LIMIT 1 + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -130,27 +130,27 @@ $$; CREATE FUNCTION geocode_postalcode_points(code integer[], inputcountries text[]) RETURNS SETOF geocode_postalint_country_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + 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 + 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(d.c) = ANY (synonyms) LIMIT 1 + 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 + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -162,23 +162,23 @@ $$; CREATE FUNCTION geocode_postalcode_points(code text[]) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + DECLARElower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text 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 + SELECT q, ( - SELECT the_geom + SELECT the_geom FROM global_postal_code_points - WHERE postal_code = upper(d.q) + WHERE postal_code = upper(d.q) LIMIT 1 ) geom FROM (SELECT unnest(code) q) d ) v - LOOP + LOOP RETURN NEXT ret; END LOOP; RETURN; @@ -190,7 +190,7 @@ $$; CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RETURNS SETOF geocode_place_country_iso_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + DECLARE ret geocode_place_country_iso_v1%rowtype; geo GEOMETRY; BEGIN @@ -199,7 +199,7 @@ CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RE SELECT q, c, iso3, geom, CASE WHEN geom IS NULL THEN FALSE ELSE TRUE END AS success FROM ( - SELECT + SELECT q, c, (SELECT iso3 FROM country_decoder WHERE lower(d.c) = ANY (synonyms) LIMIT 1) iso3, ( SELECT the_geom @@ -207,13 +207,13 @@ CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RE WHERE postal_code = upper(d.q) AND iso3 = ( SELECT iso3 FROM country_decoder WHERE - lower(d.c) = ANY (synonyms) LIMIT 1 + 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 + LOOP IF ret.geom IS NULL AND ret.iso3 = 'GBR' THEN geo := geocode_greatbritain_outward(ret.q); IF geo IS NOT NULL THEN @@ -239,7 +239,7 @@ CREATE FUNCTION geocode_greatbritain_outward(code text) RETURNS geometry geom := NULL; IF array_length(string_to_array(code,' '),1) = 2 THEN code := split_part(code, ' ', 1) || ' ' || rpad(substring(split_part(code, ' ', 2), 1, 1), 3, '#'); - SELECT the_geom INTO geom FROM global_postal_code_points WHERE + SELECT the_geom INTO geom FROM global_postal_code_points WHERE postal_code = code AND iso3 = 'GBR' LIMIT 1; @@ -252,15 +252,15 @@ $$; CREATE FUNCTION admin0_available_services(name text[]) RETURNS SETOF available_services_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARE + DECLARE ret available_services_v1%rowtype; BEGIN RETURN QUERY - SELECT d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons FROM + SELECT d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons FROM ( - SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x FROM + SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x FROM ( SELECT unnest(name) q - ) + ) g) d LEFT OUTER JOIN admin0_synonyms s ON name_ = d.x LEFT OUTER JOIN available_services n ON s.adm0_a3 = n.adm0_a3 GROUP BY d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons; END $$; From ec0d06446d6a0f3157684cfda8a7bec6ef265656 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 16:11:50 +0100 Subject: [PATCH 07/11] Fixes typo --- geocoder/extension/sql/0.0.1/50_postalcodes.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geocoder/extension/sql/0.0.1/50_postalcodes.sql b/geocoder/extension/sql/0.0.1/50_postalcodes.sql index 9ab6e1a..12a7aa6 100644 --- a/geocoder/extension/sql/0.0.1/50_postalcodes.sql +++ b/geocoder/extension/sql/0.0.1/50_postalcodes.sql @@ -162,7 +162,7 @@ $$; CREATE FUNCTION geocode_postalcode_points(code text[]) RETURNS SETOF geocode_namedplace_v1 LANGUAGE plpgsql SECURITY DEFINER AS $$ - DECLARElower(regexp_replace(inputcountry, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text + DECLARE ret geocode_namedplace_v1%rowtype; BEGIN FOR ret IN From 49eb8213eb79e51e93441ba811d4a8506e5a4977 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Mon, 30 Nov 2015 17:03:06 +0100 Subject: [PATCH 08/11] Adds missing normalization in postal codes --- geocoder/extension/sql/0.0.1/50_postalcodes.sql | 2 +- geocoder/postal-codes/sql/geocoder.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/geocoder/extension/sql/0.0.1/50_postalcodes.sql b/geocoder/extension/sql/0.0.1/50_postalcodes.sql index 12a7aa6..719a5a2 100644 --- a/geocoder/extension/sql/0.0.1/50_postalcodes.sql +++ b/geocoder/extension/sql/0.0.1/50_postalcodes.sql @@ -201,7 +201,7 @@ CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RE FROM ( SELECT q, c, (SELECT iso3 FROM country_decoder WHERE - lower(d.c) = ANY (synonyms) LIMIT 1) iso3, ( + 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) diff --git a/geocoder/postal-codes/sql/geocoder.sql b/geocoder/postal-codes/sql/geocoder.sql index f91da2a..af7be61 100644 --- a/geocoder/postal-codes/sql/geocoder.sql +++ b/geocoder/postal-codes/sql/geocoder.sql @@ -46,7 +46,7 @@ CREATE OR REPLACE FUNCTION geocode_postalcode_points(code text[], inputcountries FROM ( SELECT q, c, (SELECT iso3 FROM country_decoder WHERE - lower(d.c) = ANY (synonyms) LIMIT 1) iso3, ( + 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) From 3e8f635404b4491e78656fb8a940d5bc6c4c8b89 Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Tue, 1 Dec 2015 14:11:44 +0100 Subject: [PATCH 09/11] Encapsulate cleaning function and restructure --- ...{10_admin0_test.out => 20_admin0_test.out} | 0 ...{20_admin1_test.out => 30_admin1_test.out} | 0 ...{30_ipaddr_test.out => 40_ipaddr_test.out} | 0 ...laces_test.out => 50_namedplaces_test.out} | 0 ...alcode_test.out => 60_postalcode_test.out} | 0 .../extension/sql/0.0.1/10_aux_functions.sql | 8 + .../0.0.1/{10_admin0.sql => 20_admin0.sql} | 6 +- ...table.sql => 25_country_decoder_table.sql} | 0 .../0.0.1/{20_admin1.sql => 30_admin1.sql} | 4 +- .../0.0.1/{30_ipaddr.sql => 40_ipaddr.sql} | 0 ...{40_namedplaces.sql => 50_namedplaces.sql} | 10 +- ...{50_postalcodes.sql => 60_postalcodes.sql} | 14 +- ...{10_admin0_test.sql => 20_admin0_test.sql} | 0 ...{20_admin1_test.sql => 30_admin1_test.sql} | 0 ...{30_ipaddr_test.sql => 40_ipaddr_test.sql} | 0 ...laces_test.sql => 50_namedplaces_test.sql} | 0 ...alcode_test.sql => 60_postalcode_test.sql} | 0 geocoder/postal-codes/extension/.gitignore | 3 - geocoder/postal-codes/extension/Makefile | 8 - geocoder/postal-codes/extension/README.md | 36 -- .../cdb_geocoder_postalcode--0.0.1.sql | 523 ------------------ .../extension/cdb_geocoder_postalcode.control | 6 - .../expected/cdb_geocoder_postalcode_test.out | 108 ---- .../sql/cdb_geocoder_postalcode_test.sql | 67 --- 24 files changed, 25 insertions(+), 768 deletions(-) rename geocoder/extension/expected/{10_admin0_test.out => 20_admin0_test.out} (100%) rename geocoder/extension/expected/{20_admin1_test.out => 30_admin1_test.out} (100%) rename geocoder/extension/expected/{30_ipaddr_test.out => 40_ipaddr_test.out} (100%) rename geocoder/extension/expected/{40_namedplaces_test.out => 50_namedplaces_test.out} (100%) rename geocoder/extension/expected/{50_postalcode_test.out => 60_postalcode_test.out} (100%) create mode 100644 geocoder/extension/sql/0.0.1/10_aux_functions.sql rename geocoder/extension/sql/0.0.1/{10_admin0.sql => 20_admin0.sql} (96%) rename geocoder/extension/sql/0.0.1/{15_country_decoder_table.sql => 25_country_decoder_table.sql} (100%) rename geocoder/extension/sql/0.0.1/{20_admin1.sql => 30_admin1.sql} (94%) rename geocoder/extension/sql/0.0.1/{30_ipaddr.sql => 40_ipaddr.sql} (100%) rename geocoder/extension/sql/0.0.1/{40_namedplaces.sql => 50_namedplaces.sql} (97%) rename geocoder/extension/sql/0.0.1/{50_postalcodes.sql => 60_postalcodes.sql} (93%) rename geocoder/extension/sql/{10_admin0_test.sql => 20_admin0_test.sql} (100%) rename geocoder/extension/sql/{20_admin1_test.sql => 30_admin1_test.sql} (100%) rename geocoder/extension/sql/{30_ipaddr_test.sql => 40_ipaddr_test.sql} (100%) rename geocoder/extension/sql/{40_namedplaces_test.sql => 50_namedplaces_test.sql} (100%) rename geocoder/extension/sql/{50_postalcode_test.sql => 60_postalcode_test.sql} (100%) delete mode 100644 geocoder/postal-codes/extension/.gitignore delete mode 100644 geocoder/postal-codes/extension/Makefile delete mode 100644 geocoder/postal-codes/extension/README.md delete mode 100644 geocoder/postal-codes/extension/cdb_geocoder_postalcode--0.0.1.sql delete mode 100644 geocoder/postal-codes/extension/cdb_geocoder_postalcode.control delete mode 100644 geocoder/postal-codes/extension/expected/cdb_geocoder_postalcode_test.out delete mode 100644 geocoder/postal-codes/extension/sql/cdb_geocoder_postalcode_test.sql diff --git a/geocoder/extension/expected/10_admin0_test.out b/geocoder/extension/expected/20_admin0_test.out similarity index 100% rename from geocoder/extension/expected/10_admin0_test.out rename to geocoder/extension/expected/20_admin0_test.out diff --git a/geocoder/extension/expected/20_admin1_test.out b/geocoder/extension/expected/30_admin1_test.out similarity index 100% rename from geocoder/extension/expected/20_admin1_test.out rename to geocoder/extension/expected/30_admin1_test.out diff --git a/geocoder/extension/expected/30_ipaddr_test.out b/geocoder/extension/expected/40_ipaddr_test.out similarity index 100% rename from geocoder/extension/expected/30_ipaddr_test.out rename to geocoder/extension/expected/40_ipaddr_test.out diff --git a/geocoder/extension/expected/40_namedplaces_test.out b/geocoder/extension/expected/50_namedplaces_test.out similarity index 100% rename from geocoder/extension/expected/40_namedplaces_test.out rename to geocoder/extension/expected/50_namedplaces_test.out diff --git a/geocoder/extension/expected/50_postalcode_test.out b/geocoder/extension/expected/60_postalcode_test.out similarity index 100% rename from geocoder/extension/expected/50_postalcode_test.out rename to geocoder/extension/expected/60_postalcode_test.out diff --git a/geocoder/extension/sql/0.0.1/10_aux_functions.sql b/geocoder/extension/sql/0.0.1/10_aux_functions.sql new file mode 100644 index 0000000..210923f --- /dev/null +++ b/geocoder/extension/sql/0.0.1/10_aux_functions.sql @@ -0,0 +1,8 @@ +-- Cleaning function +CREATE OR REPLACE FUNCTION geocode_clean_name(name text) RETURNS text + LANGUAGE plpgsql + AS $$ + BEGIN + RETURN regexp_replace(name, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'); + END +$$; diff --git a/geocoder/extension/sql/0.0.1/10_admin0.sql b/geocoder/extension/sql/0.0.1/20_admin0.sql similarity index 96% rename from geocoder/extension/sql/0.0.1/10_admin0.sql rename to geocoder/extension/sql/0.0.1/20_admin0.sql index 216d37e..64e7dc2 100644 --- a/geocoder/extension/sql/0.0.1/10_admin0.sql +++ b/geocoder/extension/sql/0.0.1/20_admin0.sql @@ -9,7 +9,7 @@ CREATE OR REPLACE FUNCTION geocode_admin0_polygons(name text[]) -- FOR ret IN RETURN QUERY SELECT d.q, n.the_geom as geom, CASE WHEN s.adm0_a3 IS NULL then FALSE ELSE TRUE END AS success - FROM (SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x + FROM (SELECT q, lower(geocode_clean_name(q))::text x FROM (SELECT unnest(name) q) g) d LEFT OUTER JOIN admin0_synonyms s ON name_ = d.x LEFT OUTER JOIN ne_admin0_v3 n ON s.adm0_a3 = n.adm0_a3 GROUP BY d.q, n.the_geom, s.adm0_a3; @@ -24,7 +24,7 @@ CREATE OR REPLACE FUNCTION admin0_synonym_lookup(name text[]) ret synonym_lookup_v1%rowtype; BEGIN RETURN QUERY SELECT d.q, s.adm0_a3 - FROM (SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x + FROM (SELECT q, lower(geocode_clean_name(q))::text x FROM (SELECT unnest(name) q) g) d LEFT OUTER JOIN admin0_synonyms s ON name_ = d.x GROUP BY d.q, s.adm0_a3; END @@ -74,7 +74,7 @@ CREATE INDEX idx_admin0_synonyms_rank ON admin0_synonyms USING btree (rank); -- create trigger function. used in both admin0 and admin1 synonym tables CREATE OR REPLACE FUNCTION alpha_numeric_identifiers() RETURNS trigger AS $alpha_numeric_identifiers$ BEGIN - NEW.name_ := lower(regexp_replace(NEW.name, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g')); + NEW.name_ := lower(geocode_clean_name(NEW.name)); RETURN NEW; END; $alpha_numeric_identifiers$ LANGUAGE plpgsql; diff --git a/geocoder/extension/sql/0.0.1/15_country_decoder_table.sql b/geocoder/extension/sql/0.0.1/25_country_decoder_table.sql similarity index 100% rename from geocoder/extension/sql/0.0.1/15_country_decoder_table.sql rename to geocoder/extension/sql/0.0.1/25_country_decoder_table.sql diff --git a/geocoder/extension/sql/0.0.1/20_admin1.sql b/geocoder/extension/sql/0.0.1/30_admin1.sql similarity index 94% rename from geocoder/extension/sql/0.0.1/20_admin1.sql rename to geocoder/extension/sql/0.0.1/30_admin1.sql index bf994be..26b435d 100644 --- a/geocoder/extension/sql/0.0.1/20_admin1.sql +++ b/geocoder/extension/sql/0.0.1/30_admin1.sql @@ -36,7 +36,7 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(name text[], inputcountry tex 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) + p AS (SELECT r.c, r.q, (SELECT iso3 FROM country_decoder WHERE lower(geocode_clean_name(inputcountry))::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 ( @@ -80,7 +80,7 @@ CREATE OR REPLACE FUNCTION geocode_admin1_polygons(names text[], country text[]) 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) + p AS (SELECT r.p, r.q, c, (SELECT iso3 FROM country_decoder WHERE lower(geocode_clean_name(r.c))::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 ( diff --git a/geocoder/extension/sql/0.0.1/30_ipaddr.sql b/geocoder/extension/sql/0.0.1/40_ipaddr.sql similarity index 100% rename from geocoder/extension/sql/0.0.1/30_ipaddr.sql rename to geocoder/extension/sql/0.0.1/40_ipaddr.sql diff --git a/geocoder/extension/sql/0.0.1/40_namedplaces.sql b/geocoder/extension/sql/0.0.1/50_namedplaces.sql similarity index 97% rename from geocoder/extension/sql/0.0.1/40_namedplaces.sql rename to geocoder/extension/sql/0.0.1/50_namedplaces.sql index b1a68cd..893d257 100644 --- a/geocoder/extension/sql/0.0.1/40_namedplaces.sql +++ b/geocoder/extension/sql/0.0.1/50_namedplaces.sql @@ -28,7 +28,7 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], country text[]) RET 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), + p AS (SELECT r.s, r.c, (SELECT iso2 FROM country_decoder WHERE lower(geocode_clean_name(r.c))::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 @@ -59,20 +59,20 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], inputcountry text) 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; + SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(geocode_clean_name(inputcountry))::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 + 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 + 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; @@ -172,7 +172,7 @@ CREATE OR REPLACE FUNCTION geocode_namedplace(places text[], admin1s text[], inp 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; + SELECT iso2 INTO isoTwo FROM country_decoder WHERE lower(geocode_clean_name(inputcountry))::text = ANY (synonyms) LIMIT 1; END IF; -- find all cases where admin1 is NULL diff --git a/geocoder/extension/sql/0.0.1/50_postalcodes.sql b/geocoder/extension/sql/0.0.1/60_postalcodes.sql similarity index 93% rename from geocoder/extension/sql/0.0.1/50_postalcodes.sql rename to geocoder/extension/sql/0.0.1/60_postalcodes.sql index 719a5a2..b429482 100644 --- a/geocoder/extension/sql/0.0.1/50_postalcodes.sql +++ b/geocoder/extension/sql/0.0.1/60_postalcodes.sql @@ -10,7 +10,7 @@ CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountries text[]) 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; + SELECT INTO adm array_agg((SELECT adm0_a3 FROM admin0_synonyms WHERE name_ = lower(geocode_clean_name(b.c))::text LIMIT 1)) FROM (SELECT UNNEST(inputcountries) c) b; FOR ret IN SELECT @@ -52,7 +52,7 @@ CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountry text) RETU 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 + lower(geocode_clean_name(inputcountry))::text = ANY (synonyms) LIMIT 1 ) ) geom FROM (SELECT unnest(code) q) d @@ -112,7 +112,7 @@ CREATE FUNCTION geocode_postalcode_points(code text[], inputcountry text) RETURN 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 + lower(geocode_clean_name(inputcountry))::text = ANY (synonyms) LIMIT 1 ) LIMIT 1 ) geom @@ -144,7 +144,7 @@ CREATE FUNCTION geocode_postalcode_points(code integer[], inputcountries text[]) 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 + lower(geocode_clean_name(d.c))::text = ANY (synonyms) LIMIT 1 ) LIMIT 1 ) geom @@ -201,13 +201,13 @@ CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RE 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, ( + lower(geocode_clean_name(d.c))::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 + lower(geocode_clean_name(d.c))::text = ANY (synonyms) LIMIT 1 ) LIMIT 1 ) geom @@ -257,7 +257,7 @@ CREATE FUNCTION admin0_available_services(name text[]) RETURNS SETOF available_s BEGIN RETURN QUERY SELECT d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons FROM ( - SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x FROM + SELECT q, lower(geocode_clean_name(q))::text x FROM ( SELECT unnest(name) q ) diff --git a/geocoder/extension/sql/10_admin0_test.sql b/geocoder/extension/sql/20_admin0_test.sql similarity index 100% rename from geocoder/extension/sql/10_admin0_test.sql rename to geocoder/extension/sql/20_admin0_test.sql diff --git a/geocoder/extension/sql/20_admin1_test.sql b/geocoder/extension/sql/30_admin1_test.sql similarity index 100% rename from geocoder/extension/sql/20_admin1_test.sql rename to geocoder/extension/sql/30_admin1_test.sql diff --git a/geocoder/extension/sql/30_ipaddr_test.sql b/geocoder/extension/sql/40_ipaddr_test.sql similarity index 100% rename from geocoder/extension/sql/30_ipaddr_test.sql rename to geocoder/extension/sql/40_ipaddr_test.sql diff --git a/geocoder/extension/sql/40_namedplaces_test.sql b/geocoder/extension/sql/50_namedplaces_test.sql similarity index 100% rename from geocoder/extension/sql/40_namedplaces_test.sql rename to geocoder/extension/sql/50_namedplaces_test.sql diff --git a/geocoder/extension/sql/50_postalcode_test.sql b/geocoder/extension/sql/60_postalcode_test.sql similarity index 100% rename from geocoder/extension/sql/50_postalcode_test.sql rename to geocoder/extension/sql/60_postalcode_test.sql diff --git a/geocoder/postal-codes/extension/.gitignore b/geocoder/postal-codes/extension/.gitignore deleted file mode 100644 index e710f0e..0000000 --- a/geocoder/postal-codes/extension/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -results/ -regression.diffs -regression.out diff --git a/geocoder/postal-codes/extension/Makefile b/geocoder/postal-codes/extension/Makefile deleted file mode 100644 index dcff338..0000000 --- a/geocoder/postal-codes/extension/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -EXTENSION = cdb_geocoder_postalcode -DATA = cdb_geocoder_postalcode--0.0.1.sql -REGRESS = cdb_geocoder_postalcode_test - -# postgres build stuff -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) diff --git a/geocoder/postal-codes/extension/README.md b/geocoder/postal-codes/extension/README.md deleted file mode 100644 index b2afd35..0000000 --- a/geocoder/postal-codes/extension/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# CartoDB postal code geocoder extension -Postgres extension for the CartoDB postal code geocoder. It is meant to contain the functions and related objects needed to geocode by postal codes. It is not meant to contain the actual data used to geocode them. - -## Dependencies -This extension is thought to be used on top of CartoDB platform. Therefore a cartodb user is required to install the extension onto it. - -The following is a non-comprehensive list of dependencies: - -- Postgres 9.3+ -- Postgis extension -- Schema triggers extension -- CartoDB extension - -## Installation into the db cluster -This requires root privileges -``` -sudo make all install -``` - -## Execute tests -``` -PGUSER=postgres make installcheck -``` - -## Install onto a user's database -``` -psql -U development_cartodb_user_fe3b850a-01c0-48f9-8a26-a82f09e9b53f cartodb_dev_user_fe3b850a-01c0-48f9-8a26-a82f09e9b53f_db -``` - -and then: - -```sql -CREATE EXTENSION cdb_geocoder_postalcode; -``` - -The extension creation in the user's db does not require special privileges. It can be even created from the sql api. diff --git a/geocoder/postal-codes/extension/cdb_geocoder_postalcode--0.0.1.sql b/geocoder/postal-codes/extension/cdb_geocoder_postalcode--0.0.1.sql deleted file mode 100644 index 8845075..0000000 --- a/geocoder/postal-codes/extension/cdb_geocoder_postalcode--0.0.1.sql +++ /dev/null @@ -1,523 +0,0 @@ --- Complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION cdb_geocoder_postalcode" to load this file. \quit - --- Response types for admin0 geocoder -CREATE TYPE geocode_namedplace_v1 AS (q TEXT, geom GEOMETRY, success BOOLEAN); -CREATE TYPE geocode_postalint_country_v1 AS (q TEXT, c TEXT, geom GEOMETRY, success BOOLEAN); -CREATE TYPE geocode_namedplace_country_v1 AS (q TEXT, c TEXT, geom GEOMETRY, success BOOLEAN); -CREATE TYPE available_services_v1 AS (q text, adm0_a3 text, postal_code_points boolean, postal_code_polygons boolean); -CREATE TYPE geocode_place_country_iso_v1 AS (q text, c text, iso3 text, geom geometry, success boolean); - --- Public API functions -- ---- Geocoding function --- --- TODO: deal with permissions - -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 -$$; - - --- TODO: The next function works with an incorrect table - -CREATE FUNCTION geocode_postalcode_polygons(code text[], inputcountry text) RETURNS SETOF geocode_namedplace_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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(inputcountry) = ANY (synonyms) LIMIT 1 - ) - ) geom - FROM (SELECT unnest(code) q) d - ) v - LOOP - RETURN NEXT ret; - END LOOP; - RETURN; -END -$$; - --- TODO: The next function works with an incorrect table - -CREATE FUNCTION geocode_postalcode_polygons(code text[]) RETURNS SETOF geocode_namedplace_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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 -$$; - ------- POINTS ------ - - -CREATE FUNCTION geocode_postalcode_points(code text[], inputcountry text) RETURNS SETOF geocode_namedplace_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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(inputcountry) = ANY (synonyms) LIMIT 1 - ) - LIMIT 1 - ) geom - FROM (SELECT unnest(code) q) d - ) v - LOOP - RETURN NEXT ret; - END LOOP; - RETURN; -END -$$; - - - -CREATE FUNCTION geocode_postalcode_points(code integer[], inputcountries text[]) RETURNS SETOF geocode_postalint_country_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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(d.c) = 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 -$$; - - - -CREATE FUNCTION geocode_postalcode_points(code text[]) RETURNS SETOF geocode_namedplace_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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 -$$; - - - -CREATE FUNCTION geocode_postalcode_points(code text[], inputcountries text[]) RETURNS SETOF geocode_place_country_iso_v1 - LANGUAGE plpgsql SECURITY DEFINER - 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(d.c) = 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(d.c) = 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 -$$; - - - -CREATE FUNCTION geocode_greatbritain_outward(code text) RETURNS geometry - LANGUAGE plpgsql - AS $$ - DECLARE - geom GEOMETRY; - BEGIN - code := trim(code); - geom := NULL; - IF array_length(string_to_array(code,' '),1) = 2 THEN - code := split_part(code, ' ', 1) || ' ' || rpad(substring(split_part(code, ' ', 2), 1, 1), 3, '#'); - SELECT the_geom INTO geom FROM global_postal_code_points WHERE - postal_code = code - AND iso3 = 'GBR' - LIMIT 1; - END IF; - RETURN geom; -END -$$; - - -CREATE FUNCTION admin0_available_services(name text[]) RETURNS SETOF available_services_v1 - LANGUAGE plpgsql SECURITY DEFINER - AS $$ - DECLARE - ret available_services_v1%rowtype; - BEGIN RETURN QUERY - SELECT d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons FROM - ( - SELECT q, lower(regexp_replace(q, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g'))::text x FROM - ( - SELECT unnest(name) q - ) - g) d LEFT OUTER JOIN admin0_synonyms s ON name_ = d.x LEFT OUTER JOIN available_services n ON s.adm0_a3 = n.adm0_a3 GROUP BY d.q, n.adm0_a3, n.postal_code_points, n.postal_code_polygons; -END -$$; --------------------------------------------------------------------------------- - --- Support tables - -CREATE TABLE global_postal_code_polygons ( - the_geom geometry(Geometry,4326), - zcta5ce10 text, - geoid10 text, - mtfcc10 text, - cartodb_id integer NOT NULL, - created_at timestamp with time zone DEFAULT now() NOT NULL, - updated_at timestamp with time zone DEFAULT now() NOT NULL, - the_geom_webmercator geometry(Geometry,3857), - iso3 text, - postal_code text, - postal_code_num integer -); - - -CREATE SEQUENCE global_postal_code_polygons_cartodb_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; -ALTER SEQUENCE global_postal_code_polygons_cartodb_id_seq OWNED BY global_postal_code_polygons.cartodb_id; -ALTER TABLE ONLY global_postal_code_polygons ALTER COLUMN cartodb_id SET DEFAULT nextval('global_postal_code_polygons_cartodb_id_seq'::regclass); - - -ALTER TABLE ONLY global_postal_code_polygons - ADD CONSTRAINT global_postal_code_polygons_cartodb_id_key UNIQUE (cartodb_id); -ALTER TABLE ONLY global_postal_code_polygons - ADD CONSTRAINT global_postal_code_polygons_pkey PRIMARY KEY (cartodb_id); - - -CREATE INDEX global_postal_code_polygons_the_geom_idx ON global_postal_code_polygons USING gist (the_geom); -CREATE INDEX global_postal_code_polygons_the_geom_webmercator_idx ON global_postal_code_polygons USING gist (the_geom_webmercator); -CREATE INDEX global_postal_code_polygons_postal_code_idx ON global_postal_code_polygons USING btree (postal_code); -CREATE INDEX global_postal_code_polygons_iso3_idx ON global_postal_code_polygons USING btree (iso3); -CREATE INDEX global_global_postal_code_polygons_postal_code_num_idx ON global_postal_code_polygons USING btree (postal_code_num); - - -CREATE TRIGGER track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON global_postal_code_polygons FOR EACH STATEMENT EXECUTE PROCEDURE cartodb.cdb_tablemetadata_trigger(); -CREATE TRIGGER update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON global_postal_code_polygons FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_the_geom_webmercator(); -CREATE TRIGGER update_updated_at_trigger BEFORE UPDATE ON global_postal_code_polygons FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_updated_at(); - - -CREATE TABLE global_postal_code_points ( - iso2 text, - postal_code text, - place_name text, - admin_name1 text, - admin_code1 text, - admin_name2 text, - admin_code2 text, - admin_name3 text, - admin_code3 text, - accuracy text, - the_geom geometry(Geometry,4326), - cartodb_id integer NOT NULL, - created_at timestamp with time zone DEFAULT now() NOT NULL, - updated_at timestamp with time zone DEFAULT now() NOT NULL, - the_geom_webmercator geometry(Geometry,3857), - iso3 text, - frompoly boolean, - postal_code_num integer, - datasource text -); - - -CREATE SEQUENCE global_postal_code_points_cartodb_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; -ALTER SEQUENCE global_postal_code_points_cartodb_id_seq OWNED BY global_postal_code_points.cartodb_id; -ALTER TABLE ONLY global_postal_code_points ALTER COLUMN cartodb_id SET DEFAULT nextval('global_postal_code_points_cartodb_id_seq'::regclass); - - -ALTER TABLE ONLY global_postal_code_points - ADD CONSTRAINT global_postal_code_points_cartodb_id_key UNIQUE (cartodb_id); -ALTER TABLE ONLY global_postal_code_points - ADD CONSTRAINT global_postal_code_points_pkey PRIMARY KEY (cartodb_id); - - -CREATE INDEX global_postal_code_points_the_geom_idx ON global_postal_code_points USING gist (the_geom); -CREATE INDEX global_postal_code_points_the_geom_webmercator_idx ON global_postal_code_points USING gist (the_geom_webmercator); -CREATE INDEX global_postal_code_points_postal_code_idx ON global_postal_code_points USING btree (postal_code); -CREATE INDEX global_postal_code_points_iso3_idx ON global_postal_code_points USING btree (iso3); -CREATE INDEX global_postal_code_points_postal_code_num_idx ON global_postal_code_points USING btree (postal_code_num); - - -CREATE TRIGGER track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON global_postal_code_points FOR EACH STATEMENT EXECUTE PROCEDURE cartodb.cdb_tablemetadata_trigger(); -CREATE TRIGGER update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON global_postal_code_points FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_the_geom_webmercator(); -CREATE TRIGGER update_updated_at_trigger BEFORE UPDATE ON global_postal_code_points FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_updated_at(); - - - -CREATE TABLE available_services ( - adm0_a3 text, - admin0 boolean, - cartodb_id integer NOT NULL, - created_at timestamp with time zone DEFAULT now() NOT NULL, - updated_at timestamp with time zone DEFAULT now() NOT NULL, - the_geom geometry(Geometry,4326), - the_geom_webmercator geometry(Geometry,3857), - postal_code_points boolean, - postal_code_polygons boolean -); - -CREATE SEQUENCE available_services_cartodb_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE available_services_cartodb_id_seq OWNED BY available_services.cartodb_id; -ALTER TABLE ONLY available_services ALTER COLUMN cartodb_id SET DEFAULT nextval('available_services_cartodb_id_seq'::regclass); - - -ALTER TABLE ONLY available_services - ADD CONSTRAINT available_services_cartodb_id_key UNIQUE (cartodb_id); -ALTER TABLE ONLY available_services - ADD CONSTRAINT available_services_pkey PRIMARY KEY (cartodb_id); - - - -CREATE INDEX available_services_the_geom_idx ON available_services USING gist (the_geom); -CREATE INDEX available_services_the_geom_webmercator_idx ON available_services USING gist (the_geom_webmercator); - - -CREATE TRIGGER track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON available_services FOR EACH STATEMENT EXECUTE PROCEDURE cartodb.cdb_tablemetadata_trigger(); -CREATE TRIGGER update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON available_services FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_the_geom_webmercator(); -CREATE TRIGGER update_updated_at_trigger BEFORE UPDATE ON available_services FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_updated_at(); - - - -CREATE TABLE country_decoder ( - name text, - nativename text, - tld text, - iso2 text, - ccn3 text, - iso3 text, - currency text, - callingcode text, - capital text, - altspellings text, - relevance text, - region text, - subregion text, - language text, - languagescodes text, - translations text, - population text, - latlng text, - demonym text, - borders text, - the_geom geometry(Geometry,4326), - cartodb_id integer NOT NULL, - created_at timestamp with time zone DEFAULT now() NOT NULL, - updated_at timestamp with time zone DEFAULT now() NOT NULL, - the_geom_webmercator geometry(Geometry,3857), - synbu text[], - synonyms text[], - users double precision -); - - -CREATE SEQUENCE country_decoder_cartodb_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -ALTER SEQUENCE available_services_cartodb_id_seq OWNED BY country_decoder.cartodb_id; -ALTER TABLE ONLY country_decoder ALTER COLUMN cartodb_id SET DEFAULT nextval('country_decoder_cartodb_id_seq'::regclass); - - -ALTER TABLE ONLY country_decoder - ADD CONSTRAINT country_decoder_cartodb_id_key UNIQUE (cartodb_id); -ALTER TABLE ONLY country_decoder - ADD CONSTRAINT country_decoder_pkey PRIMARY KEY (cartodb_id); - - - -CREATE INDEX country_decoder_the_geom_idx ON country_decoder USING gist (the_geom); -CREATE INDEX country_decoder_the_geom_webmercator_idx ON country_decoder USING gist (the_geom_webmercator); - - -CREATE TRIGGER track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON country_decoder FOR EACH STATEMENT EXECUTE PROCEDURE cartodb.cdb_tablemetadata_trigger(); -CREATE TRIGGER update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON country_decoder FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_the_geom_webmercator(); -CREATE TRIGGER update_updated_at_trigger BEFORE UPDATE ON country_decoder FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_updated_at(); - - -CREATE TABLE admin0_synonyms ( - name text, - rank double precision, - created_at timestamp with time zone DEFAULT now() NOT NULL, - updated_at timestamp with time zone DEFAULT now() NOT NULL, - the_geom geometry(Geometry,4326), - the_geom_webmercator geometry(Geometry,3857), - cartodb_id integer NOT NULL, - adm0_a3 text, - name_ text -); - -CREATE SEQUENCE admin0_synonyms_cartodb_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; -ALTER SEQUENCE admin0_synonyms_cartodb_id_seq OWNED BY admin0_synonyms.cartodb_id; -ALTER TABLE ONLY admin0_synonyms ALTER COLUMN cartodb_id SET DEFAULT nextval('admin0_synonyms_cartodb_id_seq'::regclass); - - -ALTER TABLE ONLY admin0_synonyms - ADD CONSTRAINT admin0_synonyms_cartodb_id_key UNIQUE (cartodb_id); -ALTER TABLE ONLY admin0_synonyms - ADD CONSTRAINT admin0_synonyms_pkey PRIMARY KEY (cartodb_id); - - -CREATE INDEX admin0_synonyms_the_geom_idx ON admin0_synonyms USING gist (the_geom); -CREATE INDEX admin0_synonyms_the_geom_webmercator_idx ON admin0_synonyms USING gist (the_geom_webmercator); -CREATE INDEX idx_admin0_synonyms_nam ON admin0_synonyms USING btree (name); -CREATE INDEX idx_admin0_synonyms_name ON admin0_synonyms USING btree (lower(regexp_replace(name, '\W+'::text, ''::text))); -CREATE INDEX idx_admin0_synonyms_name_ ON admin0_synonyms USING btree (name_); -CREATE INDEX idx_admin0_synonyms_name_patt ON admin0_synonyms USING btree (name_ text_pattern_ops); -CREATE INDEX idx_admin0_synonyms_name_rank ON admin0_synonyms USING btree (name_, rank); -CREATE INDEX idx_admin0_synonyms_rank ON admin0_synonyms USING btree (rank); - --- create trigger function. used in both admin0 and admin1 synonym tables -CREATE OR REPLACE FUNCTION alpha_numeric_identifiers() RETURNS trigger AS $alpha_numeric_identifiers$ - BEGIN - NEW.name_ := lower(regexp_replace(NEW.name, '[^a-zA-Z\u00C0-\u00ff]+', '', 'g')); - RETURN NEW; - END; -$alpha_numeric_identifiers$ LANGUAGE plpgsql; - -CREATE TRIGGER admin0_synonyms_name_update BEFORE INSERT OR UPDATE OF name ON admin0_synonyms FOR EACH ROW EXECUTE PROCEDURE alpha_numeric_identifiers(); -CREATE TRIGGER track_updates AFTER INSERT OR DELETE OR UPDATE OR TRUNCATE ON admin0_synonyms FOR EACH STATEMENT EXECUTE PROCEDURE cartodb.cdb_tablemetadata_trigger(); -CREATE TRIGGER update_the_geom_webmercator_trigger BEFORE INSERT OR UPDATE OF the_geom ON admin0_synonyms FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_the_geom_webmercator(); -CREATE TRIGGER update_updated_at_trigger BEFORE UPDATE ON admin0_synonyms FOR EACH ROW EXECUTE PROCEDURE cartodb._cdb_update_updated_at(); diff --git a/geocoder/postal-codes/extension/cdb_geocoder_postalcode.control b/geocoder/postal-codes/extension/cdb_geocoder_postalcode.control deleted file mode 100644 index 70f249c..0000000 --- a/geocoder/postal-codes/extension/cdb_geocoder_postalcode.control +++ /dev/null @@ -1,6 +0,0 @@ -# cdb geocoder postalcode extension -comment = 'CartoDB postalcode internal geocoder' -default_version = '0.0.1' -relocatable = true -requires = cartodb -superuser = false diff --git a/geocoder/postal-codes/extension/expected/cdb_geocoder_postalcode_test.out b/geocoder/postal-codes/extension/expected/cdb_geocoder_postalcode_test.out deleted file mode 100644 index 83ddaec..0000000 --- a/geocoder/postal-codes/extension/expected/cdb_geocoder_postalcode_test.out +++ /dev/null @@ -1,108 +0,0 @@ -CREATE EXTENSION postgis; -CREATE EXTENSION schema_triggers; -CREATE EXTENSION plpythonu; -CREATE EXTENSION cartodb; -CREATE EXTENSION cdb_geocoder_postalcode; -SELECT (geocode_postalcode_polygons(Array['03204'], Array['Spain'])).*; - q | c | geom | success --------+-------+------+--------- - 03204 | Spain | | f -(1 row) - -SELECT (geocode_postalcode_polygons(Array['03204'], 'ESP')).*; - q | geom | success --------+------+--------- - 03204 | | f -(1 row) - -SELECT (geocode_postalcode_polygons(Array['03204'])).*; - q | geom | success --------+------+--------- - 03204 | | f -(1 row) - -SELECT (geocode_postalcode_points(Array['03204'], 'Spain')).*; - q | geom | success --------+------+--------- - 03204 | | f -(1 row) - -SELECT (geocode_postalcode_points('{03204}', 'Spain')).*; - q | geom | success --------+------+--------- - 03204 | | f -(1 row) - -SELECT (geocode_postalcode_points(Array['03204'])).*; - q | geom | success --------+------+--------- - 03204 | | f -(1 row) - -SELECT (geocode_postalcode_points(Array['03204'], Array['Spain'])).*; - q | c | iso3 | geom | success --------+-------+------+------+--------- - 03204 | Spain | | | f -(1 row) - -SELECT geocode_greatbritain_outward('YO1 721'); - geocode_greatbritain_outward ------------------------------- - -(1 row) - -SELECT (admin0_available_services(Array['Spain'])).*; - q | adm0_a3 | postal_code_points | postal_code_polygons --------+---------+--------------------+---------------------- - Spain | | | -(1 row) - --- Mock the varnish invalidation function -CREATE OR REPLACE FUNCTION public.cdb_invalidate_varnish(table_name text) RETURNS void AS $$ -BEGIN - RETURN; -END -$$ -LANGUAGE plpgsql; --- Insert mock source data -INSERT INTO global_postal_code_points (the_geom, iso3, postal_code, postal_code_num) VALUES ( - '0101000020E61000000000000000E040408036B47414764840', - 'ESP', - '03204', - 3204 -); -INSERT INTO global_postal_code_polygons (the_geom, iso3, postal_code, postal_code_num) VALUES ( - '0106000020E610000001000000010300000001000000040000000000000000E000C01F383D7839B740400000000000E000C0AA3C0EDE220F3B4000000000004812404FB7FCCD04893D400000000000E000C01F383D7839B74040', - 'ESP', - '03204', - 3204 -); -INSERT INTO country_decoder (iso3, synonyms) VALUES ( - 'ESP', - Array['spain', 'Spain', 'ESP'] -); -INSERT INTO available_services (adm0_a3, admin0, postal_code_points, postal_code_polygons) VALUES ( - 'ESP', - 't', - 't', - 't' -); -INSERT INTO admin0_synonyms (adm0_a3, name, name_, rank) VALUES ( - 'ESP', - 'Spain', - 'spain', - 3 -); -INSERT INTO admin0_synonyms (adm0_a3, name, name_, rank) VALUES ( - 'ESP', - 'ESP', - 'esp', - 4 -); --- Check that the geocoding function is callable, should return success = true -SELECT (geocode_postalcode_polygons(Array['03204'], Array['Spain'])).geom; - geom --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 0106000020E610000001000000010300000001000000040000000000000000E000C01F383D7839B740400000000000E000C0AA3C0EDE220F3B4000000000004812404FB7FCCD04893D400000000000E000C01F383D7839B74040 -(1 row) - diff --git a/geocoder/postal-codes/extension/sql/cdb_geocoder_postalcode_test.sql b/geocoder/postal-codes/extension/sql/cdb_geocoder_postalcode_test.sql deleted file mode 100644 index fe4f884..0000000 --- a/geocoder/postal-codes/extension/sql/cdb_geocoder_postalcode_test.sql +++ /dev/null @@ -1,67 +0,0 @@ -CREATE EXTENSION postgis; -CREATE EXTENSION schema_triggers; -CREATE EXTENSION plpythonu; -CREATE EXTENSION cartodb; -CREATE EXTENSION cdb_geocoder_postalcode; - -SELECT (geocode_postalcode_polygons(Array['03204'], Array['Spain'])).*; -SELECT (geocode_postalcode_polygons(Array['03204'], 'ESP')).*; -SELECT (geocode_postalcode_polygons(Array['03204'])).*; -SELECT (geocode_postalcode_points(Array['03204'], 'Spain')).*; -SELECT (geocode_postalcode_points('{03204}', 'Spain')).*; -SELECT (geocode_postalcode_points(Array['03204'])).*; -SELECT (geocode_postalcode_points(Array['03204'], Array['Spain'])).*; -SELECT geocode_greatbritain_outward('YO1 721'); -SELECT (admin0_available_services(Array['Spain'])).*; --- Mock the varnish invalidation function -CREATE OR REPLACE FUNCTION public.cdb_invalidate_varnish(table_name text) RETURNS void AS $$ -BEGIN - RETURN; -END -$$ -LANGUAGE plpgsql; - --- Insert mock source data -INSERT INTO global_postal_code_points (the_geom, iso3, postal_code, postal_code_num) VALUES ( - '0101000020E61000000000000000E040408036B47414764840', - 'ESP', - '03204', - 3204 -); - -INSERT INTO global_postal_code_polygons (the_geom, iso3, postal_code, postal_code_num) VALUES ( - '0106000020E610000001000000010300000001000000040000000000000000E000C01F383D7839B740400000000000E000C0AA3C0EDE220F3B4000000000004812404FB7FCCD04893D400000000000E000C01F383D7839B74040', - 'ESP', - '03204', - 3204 -); - -INSERT INTO country_decoder (iso3, synonyms) VALUES ( - 'ESP', - Array['spain', 'Spain', 'ESP'] -); - -INSERT INTO available_services (adm0_a3, admin0, postal_code_points, postal_code_polygons) VALUES ( - 'ESP', - 't', - 't', - 't' -); - -INSERT INTO admin0_synonyms (adm0_a3, name, name_, rank) VALUES ( - 'ESP', - 'Spain', - 'spain', - 3 -); - -INSERT INTO admin0_synonyms (adm0_a3, name, name_, rank) VALUES ( - 'ESP', - 'ESP', - 'esp', - 4 -); - --- Check that the geocoding function is callable, should return success = true -SELECT (geocode_postalcode_polygons(Array['03204'], Array['Spain'])).geom; - From db88a54ff030f61bef1bec6375cd301b293c018f Mon Sep 17 00:00:00 2001 From: Carla Iriberri Date: Tue, 1 Dec 2015 15:14:11 +0100 Subject: [PATCH 10/11] Solve conflicts --- geocoder/admin1/sql/geocoder.sql | 108 ------ geocoder/ip-addresses/sql/geocoder.sql | 31 -- .../namedplace/sql/geocode_namedplace.sql | 324 ------------------ geocoder/postal-codes/sql/geocoder.sql | 253 -------------- 4 files changed, 716 deletions(-) delete mode 100644 geocoder/admin1/sql/geocoder.sql delete mode 100644 geocoder/ip-addresses/sql/geocoder.sql delete mode 100644 geocoder/namedplace/sql/geocode_namedplace.sql delete mode 100644 geocoder/postal-codes/sql/geocoder.sql diff --git a/geocoder/admin1/sql/geocoder.sql b/geocoder/admin1/sql/geocoder.sql deleted file mode 100644 index 0f1e5dd..0000000 --- a/geocoder/admin1/sql/geocoder.sql +++ /dev/null @@ -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'; - diff --git a/geocoder/ip-addresses/sql/geocoder.sql b/geocoder/ip-addresses/sql/geocoder.sql deleted file mode 100644 index 3935cb5..0000000 --- a/geocoder/ip-addresses/sql/geocoder.sql +++ /dev/null @@ -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; \ No newline at end of file diff --git a/geocoder/namedplace/sql/geocode_namedplace.sql b/geocoder/namedplace/sql/geocode_namedplace.sql deleted file mode 100644 index e2f81eb..0000000 --- a/geocoder/namedplace/sql/geocode_namedplace.sql +++ /dev/null @@ -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$ diff --git a/geocoder/postal-codes/sql/geocoder.sql b/geocoder/postal-codes/sql/geocoder.sql deleted file mode 100644 index af7be61..0000000 --- a/geocoder/postal-codes/sql/geocoder.sql +++ /dev/null @@ -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; - From c3924fb41d8bba76d759b8108e6dd4d1c2c871c1 Mon Sep 17 00:00:00 2001 From: Carla Date: Tue, 1 Dec 2015 15:19:16 +0100 Subject: [PATCH 11/11] Update response-types.sql --- geocoder/setup/admin1/response-types.sql | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/geocoder/setup/admin1/response-types.sql b/geocoder/setup/admin1/response-types.sql index a3484ff..acc7abc 100644 --- a/geocoder/setup/admin1/response-types.sql +++ b/geocoder/setup/admin1/response-types.sql @@ -1,15 +1,3 @@ -- Response types for admin1 geocoder - -CREATE TYPE geocode_admin_v1 AS ( - q text, - geom geometry, - success boolean -); - - -CREATE TYPE geocode_admin_country_v1 AS ( - q text, - c text, - geom geometry, - success boolean -); +CREATE TYPE geocode_admin_v1 AS (q TEXT, geom GEOMETRY, success BOOLEAN); +CREATE TYPE geocode_admin_country_v1 AS (q TEXT, c TEXT, geom GEOMETRY, success BOOLEAN);