From: Sarah Hoffmann Date: Thu, 13 Apr 2017 20:12:19 +0000 (+0200) Subject: Merge pull request #700 from lonvia/structured-address-info X-Git-Tag: v3.0.0~42 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/1e30e578e0b8e51d64a9409086cb8b1a1d43643b?hp=8138729aea652acd1c9148df9d9318cbfb9c4da2 Merge pull request #700 from lonvia/structured-address-info Move address information into hstore column --- diff --git a/lib/Geocode.php b/lib/Geocode.php index 971eb85d..ec8eb348 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -423,7 +423,7 @@ class Geocode $sSQL .= " rank_address,"; $sSQL .= " min(place_id) AS place_id, "; $sSQL .= " min(parent_place_id) AS parent_place_id, "; - $sSQL .= " calculated_country_code AS country_code, "; + $sSQL .= " country_code, "; $sSQL .= " get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) AS langaddress,"; $sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) AS placename,"; $sSQL .= " get_name_by_language(name, ARRAY['ref']) AS ref,"; @@ -466,7 +466,7 @@ class Geocode $sSQL .= " admin_level, "; $sSQL .= " rank_search, "; $sSQL .= " rank_address, "; - $sSQL .= " calculated_country_code, "; + $sSQL .= " country_code, "; $sSQL .= " importance, "; if (!$this->bDeDupe) $sSQL .= "place_id,"; $sSQL .= " langaddress, "; @@ -551,7 +551,7 @@ class Geocode $sSQL .= " 30 AS rank_address, "; $sSQL .= " min(place_id) as place_id, "; $sSQL .= " min(parent_place_id) AS parent_place_id, "; - $sSQL .= " calculated_country_code AS country_code, "; + $sSQL .= " country_code, "; $sSQL .= " get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) AS langaddress, "; $sSQL .= " null AS placename, "; $sSQL .= " null AS ref, "; @@ -576,7 +576,7 @@ class Geocode $sSQL .= " SELECT "; $sSQL .= " osm_id, "; $sSQL .= " place_id, "; - $sSQL .= " calculated_country_code, "; + $sSQL .= " country_code, "; $sSQL .= " CASE "; // interpolate the housenumbers here $sSQL .= " WHEN startnumber != endnumber "; $sSQL .= " THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) "; @@ -595,7 +595,7 @@ class Geocode $sSQL .= " osm_id, "; $sSQL .= " place_id, "; $sSQL .= " housenumber_for_place, "; - $sSQL .= " calculated_country_code "; //is this group by really needed?, place_id + housenumber (in combination) are unique + $sSQL .= " country_code "; //is this group by really needed?, place_id + housenumber (in combination) are unique if (!$this->bDeDupe) $sSQL .= ", place_id "; if (CONST_Use_Aux_Location_data) { @@ -1239,8 +1239,8 @@ class Geocode if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber']) { // Just looking for a country by code - look it up if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) { - $sSQL = "SELECT place_id FROM placex WHERE calculated_country_code='".$aSearch['sCountryCode']."' AND rank_search = 4"; - if ($sCountryCodesSQL) $sSQL .= " AND calculated_country_code in ($sCountryCodesSQL)"; + $sSQL = "SELECT place_id FROM placex WHERE country_code='".$aSearch['sCountryCode']."' AND rank_search = 4"; + if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)"; if ($bBoundingBoxSearch) $sSQL .= " AND _st_intersects($this->sViewboxSmallSQL, geometry)"; $sSQL .= " ORDER BY st_area(geometry) DESC LIMIT 1"; @@ -1258,7 +1258,7 @@ class Geocode $sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct"; if ($sCountryCodesSQL) $sSQL .= " JOIN placex USING (place_id)"; $sSQL .= " WHERE st_contains($this->sViewboxSmallSQL, ct.centroid)"; - if ($sCountryCodesSQL) $sSQL .= " AND calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)"; if (sizeof($this->aExcludePlaceIDs)) { $sSQL .= " AND place_id not in (".join(',', $this->aExcludePlaceIDs).")"; } @@ -1275,7 +1275,7 @@ class Geocode $sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct"; if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)"; $sSQL .= " WHERE ST_Contains($this->sViewboxLargeSQL, ct.centroid)"; - if ($sCountryCodesSQL) $sSQL .= " AND calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)"; if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC"; $sSQL .= " LIMIT $this->iLimit"; if (CONST_Debug) var_dump($sSQL); @@ -1288,7 +1288,7 @@ class Geocode $sSQL .= " AND type='".$aSearch['sType']."'"; $sSQL .= " AND ST_Contains($this->sViewboxSmallSQL, geometry) "; $sSQL .= " AND linked_place_id is null"; - if ($sCountryCodesSQL) $sSQL .= " AND calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)"; if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, centroid) ASC"; $sSQL .= " LIMIT $this->iLimit"; if (CONST_Debug) var_dump($sSQL); @@ -1534,7 +1534,7 @@ class Geocode $sSQL .= " AND class='".$aSearch['sClass']."' "; $sSQL .= " AND type='".$aSearch['sType']."'"; $sSQL .= " AND linked_place_id is null"; - if ($sCountryCodesSQL) $sSQL .= " AND calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)"; $sSQL .= " ORDER BY rank_search ASC "; $sSQL .= " LIMIT $this->iLimit"; if (CONST_Debug) var_dump($sSQL); @@ -1604,7 +1604,7 @@ class Geocode if (sizeof($this->aExcludePlaceIDs)) { $sSQL .= " and l.place_id not in (".join(',', $this->aExcludePlaceIDs).")"; } - if ($sCountryCodesSQL) $sSQL .= " and lp.calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " and lp.country_code in ($sCountryCodesSQL)"; if ($sOrderBySQL) $sSQL .= "order by ".$sOrderBySQL." asc"; if ($this->iOffset) $sSQL .= " offset $this->iOffset"; $sSQL .= " limit $this->iLimit"; @@ -1631,7 +1631,7 @@ class Geocode if (sizeof($this->aExcludePlaceIDs)) { $sSQL .= " AND l.place_id not in (".join(',', $this->aExcludePlaceIDs).")"; } - if ($sCountryCodesSQL) $sSQL .= " AND l.calculated_country_code in ($sCountryCodesSQL)"; + if ($sCountryCodesSQL) $sSQL .= " AND l.country_code in ($sCountryCodesSQL)"; if ($sOrderBy) $sSQL .= "ORDER BY ".$OrderBysSQL." ASC"; if ($this->iOffset) $sSQL .= " OFFSET $this->iOffset"; $sSQL .= " limit $this->iLimit"; diff --git a/lib/PlaceLookup.php b/lib/PlaceLookup.php index eff66fd1..40d003fa 100644 --- a/lib/PlaceLookup.php +++ b/lib/PlaceLookup.php @@ -103,9 +103,9 @@ class PlaceLookup $bIsInterpolation = $sType == 'interpolation'; if ($bIsTiger) { - $sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, null as street, null as isin, postcode,"; + $sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, postcode,"; $sSQL .= " 'us' as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,"; - $sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, "; + $sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as country_code, "; $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,"; $sSQL .= " null as placename,"; $sSQL .= " null as ref,"; @@ -119,9 +119,9 @@ class PlaceLookup $sSQL .= " END as housenumber"; $sSQL .= " from location_property_tiger where place_id = ".$iPlaceID.") as blub1) as blub2"; } elseif ($bIsInterpolation) { - $sSQL = "select place_id, partition, 'W' as osm_type, osm_id, 'place' as class, 'house' as type, null admin_level, housenumber, null as street, null as isin, postcode,"; - $sSQL .= " calculated_country_code as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,"; - $sSQL .= " (0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, calculated_country_code, "; + $sSQL = "select place_id, partition, 'W' as osm_type, osm_id, 'place' as class, 'house' as type, null admin_level, housenumber, postcode,"; + $sSQL .= " country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,"; + $sSQL .= " (0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, country_code, "; $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,"; $sSQL .= " null as placename,"; $sSQL .= " null as ref,"; @@ -139,9 +139,9 @@ class PlaceLookup // and not interpolated } else { $sSQL = "select placex.place_id, partition, osm_type, osm_id, class,"; - $sSQL .= " type, admin_level, housenumber, street, isin, postcode, country_code,"; + $sSQL .= " type, admin_level, housenumber, postcode, country_code,"; $sSQL .= " parent_place_id, linked_place_id, rank_address, rank_search, "; - $sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, calculated_country_code, "; + $sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, country_code, "; $sSQL .= " get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress,"; $sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) as placename,"; $sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,"; diff --git a/lib/ReverseGeocode.php b/lib/ReverseGeocode.php index d4e13875..1de0893c 100644 --- a/lib/ReverseGeocode.php +++ b/lib/ReverseGeocode.php @@ -118,7 +118,7 @@ class ReverseGeocode $iMaxRank = 26; } - $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code'; + $sSQL = 'select place_id,parent_place_id,rank_search,country_code'; $sSQL .= ' FROM placex'; $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')'; $sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank; @@ -135,7 +135,7 @@ class ReverseGeocode ); $iPlaceID = $aPlace['place_id']; $iParentPlaceID = $aPlace['parent_place_id']; - $bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us'); + $bIsInUnitedStates = ($aPlace['country_code'] == 'us'); } // If a house was found make sure there isn't an interpolation line diff --git a/osm2pgsql b/osm2pgsql index 45b5ce62..00841fc1 160000 --- a/osm2pgsql +++ b/osm2pgsql @@ -1 +1 @@ -Subproject commit 45b5ce62f0b31bd4e8ffcb854e7cd0bba88f3496 +Subproject commit 00841fc1b884b3b29fa3e661f7ac884464a81b26 diff --git a/sql/functions.sql b/sql/functions.sql index 1db32d1d..f4be01e2 100644 --- a/sql/functions.sql +++ b/sql/functions.sql @@ -598,13 +598,14 @@ BEGIN IF addr_street is null and addr_place is null THEN select nodes from planet_osm_ways where id = wayid INTO waynodes; - FOR location IN SELECT placex.street, placex.addr_place from placex + FOR location IN SELECT placex.address from placex where osm_type = 'N' and osm_id = ANY(waynodes) - and (placex.street is not null or placex.addr_place is not null) + and placex.address is not null + and (placex.address ? 'street' or placex.address ? 'place') and indexed_status < 100 limit 1 LOOP - addr_street = location.street; - addr_place = location.addr_place; + addr_street = location.address->'street'; + addr_place = location.address->'place'; END LOOP; END IF; @@ -654,16 +655,16 @@ BEGIN NEW.indexed_date := now(); IF NEW.indexed_status IS NULL THEN - IF NEW.interpolationtype NOT IN ('odd', 'even', 'all') THEN - -- other interpolation types than odd/even/all (e.g. numeric ones) are not supported - RETURN NULL; + IF NEW.address is NULL OR NOT NEW.address ? 'interpolation' + OR NEW.address->'interpolation' NOT IN ('odd', 'even', 'all') THEN + -- other interpolation types than odd/even/all (e.g. numeric ones) are not supported + RETURN NULL; END IF; NEW.indexed_status := 1; --STATUS_NEW + NEW.country_code := lower(get_country_code(NEW.linegeo)); - NEW.calculated_country_code := lower(get_country_code(NEW.linegeo)); - - NEW.partition := get_partition(NEW.calculated_country_code); + NEW.partition := get_partition(NEW.country_code); NEW.geometry_sector := geometry_sector(NEW.partition, NEW.linegeo); END IF; @@ -690,14 +691,14 @@ BEGIN NEW.place_id := nextval('seq_place'); NEW.indexed_status := 1; --STATUS_NEW - NEW.calculated_country_code := lower(get_country_code(NEW.geometry)); + NEW.country_code := lower(get_country_code(NEW.geometry)); - NEW.partition := get_partition(NEW.calculated_country_code); + NEW.partition := get_partition(NEW.country_code); NEW.geometry_sector := geometry_sector(NEW.partition, NEW.geometry); -- copy 'name' to or from the default language (if there is a default language) IF NEW.name is not null AND array_upper(akeys(NEW.name),1) > 1 THEN - default_language := get_country_language_code(NEW.calculated_country_code); + default_language := get_country_language_code(NEW.country_code); IF default_language IS NOT NULL THEN IF NEW.name ? 'name' AND NOT NEW.name ? ('name:'||default_language) THEN NEW.name := NEW.name || hstore(('name:'||default_language), (NEW.name -> 'name')); @@ -707,14 +708,6 @@ BEGIN END IF; END IF; - IF NEW.admin_level > 15 THEN - NEW.admin_level := 15; - END IF; - - IF NEW.housenumber IS NOT NULL THEN - i := getorcreate_housenumber_id(make_standard_name(NEW.housenumber)); - END IF; - IF NEW.osm_type = 'X' THEN -- E'X'ternal records should already be in the right format so do nothing ELSE @@ -724,14 +717,15 @@ BEGIN -- By doing in postgres we have the country available to us - currently only used for postcode IF NEW.class in ('place','boundary') AND NEW.type in ('postcode','postal_code') THEN - IF NEW.postcode IS NULL THEN + IF NEW.address IS NULL OR NOT NEW.address ? 'postcode' THEN -- most likely just a part of a multipolygon postcode boundary, throw it away RETURN NULL; END IF; + NEW.postcode := NEW.address->'postcode'; NEW.name := hstore('ref', NEW.postcode); - IF NEW.calculated_country_code = 'gb' THEN + IF NEW.country_code = 'gb' THEN IF NEW.postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9][A-Z][A-Z])$' THEN NEW.rank_search := 25; @@ -744,14 +738,14 @@ BEGIN NEW.rank_address := 5; END IF; - ELSEIF NEW.calculated_country_code = 'sg' THEN + ELSEIF NEW.country_code = 'sg' THEN IF NEW.postcode ~ '^([0-9]{6})$' THEN NEW.rank_search := 25; NEW.rank_address := 11; END IF; - ELSEIF NEW.calculated_country_code = 'de' THEN + ELSEIF NEW.country_code = 'de' THEN IF NEW.postcode ~ '^([0-9]{5})$' THEN NEW.rank_search := 21; @@ -781,11 +775,11 @@ BEGIN IF NEW.type in ('continent') THEN NEW.rank_search := 2; NEW.rank_address := NEW.rank_search; - NEW.calculated_country_code := NULL; + NEW.country_code := NULL; ELSEIF NEW.type in ('sea') THEN NEW.rank_search := 2; NEW.rank_address := 0; - NEW.calculated_country_code := NULL; + NEW.country_code := NULL; ELSEIF NEW.type in ('country') THEN NEW.rank_search := 4; NEW.rank_address := NEW.rank_search; @@ -896,7 +890,7 @@ BEGIN -- a country code make no sense below rank 4 (country) IF NEW.rank_search < 4 THEN - NEW.calculated_country_code := NULL; + NEW.country_code := NULL; END IF; -- Block import below rank 22 @@ -917,9 +911,9 @@ BEGIN -- work around bug in postgis, this may have been fixed in 2.0.0 (see http://trac.osgeo.org/postgis/ticket/547) update placex set indexed_status = 2 where (st_covers(NEW.geometry, placex.geometry) OR ST_Intersects(NEW.geometry, placex.geometry)) - AND rank_search > NEW.rank_search and indexed_status = 0 and ST_geometrytype(placex.geometry) = 'ST_Point' and (rank_search < 28 or name is not null or (NEW.rank_search >= 16 and addr_place is not null)); + AND rank_search > NEW.rank_search and indexed_status = 0 and ST_geometrytype(placex.geometry) = 'ST_Point' and (rank_search < 28 or name is not null or (NEW.rank_search >= 16 and address ? 'place')); update placex set indexed_status = 2 where (st_covers(NEW.geometry, placex.geometry) OR ST_Intersects(NEW.geometry, placex.geometry)) - AND rank_search > NEW.rank_search and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (NEW.rank_search >= 16 and addr_place is not null)); + AND rank_search > NEW.rank_search and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (NEW.rank_search >= 16 and address ? 'place')); END IF; ELSE -- mark nearby items for re-indexing, where 'nearby' depends on the features rank_search and is a complete guess :( @@ -951,7 +945,7 @@ BEGIN update location_property_osmline set indexed_status = 2 where indexed_status = 0 and ST_DWithin(location_property_osmline.linegeo, NEW.geometry, diameter); ELSEIF NEW.rank_search >= 16 THEN -- up to rank 16, street-less addresses may need reparenting - update placex set indexed_status = 2 where indexed_status = 0 and rank_search > NEW.rank_search and ST_DWithin(placex.geometry, NEW.geometry, diameter) and (rank_search < 28 or name is not null or addr_place is not null); + update placex set indexed_status = 2 where indexed_status = 0 and rank_search > NEW.rank_search and ST_DWithin(placex.geometry, NEW.geometry, diameter) and (rank_search < 28 or name is not null or address ? 'place'); ELSE -- for all other places the search terms may change as well update placex set indexed_status = 2 where indexed_status = 0 and rank_search > NEW.rank_search and ST_DWithin(placex.geometry, NEW.geometry, diameter) and (rank_search < 28 or name is not null); @@ -991,9 +985,8 @@ DECLARE linegeo GEOMETRY; splitline GEOMETRY; sectiongeo GEOMETRY; - street TEXT; - addr_place TEXT; postcode TEXT; + seg_postcode TEXT; BEGIN -- deferred delete IF OLD.indexed_status = 100 THEN @@ -1005,99 +998,97 @@ BEGIN RETURN NEW; END IF; - -- do the reparenting: (finally here, because ALL places in placex, - -- that are needed for reparenting, need to be up to date) - -- (the osm interpolationline in location_property_osmline was marked for - -- reparenting in placex_insert/placex_delete with index_status = 1 or 2 (1 inset, 2 delete) - -- => index.c: sets index_status back to 0 - -- => triggers this function) + NEW.interpolationtype = NEW.address->'interpolation'; + place_centroid := ST_PointOnSurface(NEW.linegeo); - -- marking descendants for reparenting is not needed, because there are - -- actually no descendants for interpolation lines - NEW.parent_place_id = get_interpolation_parent(NEW.osm_id, NEW.street, NEW.addr_place, + NEW.parent_place_id = get_interpolation_parent(NEW.osm_id, NEW.address->'street', + NEW.address->'place', NEW.partition, place_centroid, NEW.linegeo); - -- if we are just updating then our work is done - IF OLD.indexed_status != 1 THEN - return NEW; - END IF; - - -- otherwise split the line as necessary - select nodes from planet_osm_ways where id = NEW.osm_id INTO waynodes; - IF array_upper(waynodes, 1) IS NULL THEN - RETURN NEW; + IF NEW.address is not NULL and NEW.address ? 'postcode' THEN + NEW.postcode = NEW.address->'postcode'; END IF; - linegeo := NEW.linegeo; - startnumber := NULL; - street := NEW.street; - addr_place := NEW.addr_place; - postcode := NEW.postcode; - - FOR nodeidpos in 1..array_upper(waynodes, 1) LOOP - - select * from place where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT - and housenumber is not NULL limit 1 INTO nextnode; - --RAISE NOTICE 'Nextnode.place_id: %s', nextnode.place_id; - IF nextnode.osm_id IS NOT NULL THEN - --RAISE NOTICE 'place_id is not null'; - IF nodeidpos > 1 and nodeidpos < array_upper(waynodes, 1) THEN - -- Make sure that the point is actually on the line. That might - -- be a bit paranoid but ensures that the algorithm still works - -- should osm2pgsql attempt to repair geometries. - splitline := split_line_on_node(linegeo, nextnode.geometry); - sectiongeo := ST_GeometryN(splitline, 1); - linegeo := ST_GeometryN(splitline, 2); - ELSE - sectiongeo = linegeo; + -- if the line was newly inserted, split the line as necessary + IF OLD.indexed_status = 1 THEN + select nodes from planet_osm_ways where id = NEW.osm_id INTO waynodes; + + IF array_upper(waynodes, 1) IS NULL THEN + RETURN NEW; END IF; - endnumber := substring(nextnode.housenumber,'[0-9]+')::integer; - IF startnumber IS NOT NULL AND endnumber IS NOT NULL - AND startnumber != endnumber - AND ST_GeometryType(sectiongeo) = 'ST_LineString' THEN + linegeo := NEW.linegeo; + startnumber := NULL; + postcode := NEW.postcode; + + FOR nodeidpos in 1..array_upper(waynodes, 1) LOOP + + select osm_id, address, geometry + from place where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT + and address is not NULL and address ? 'housenumber' limit 1 INTO nextnode; + --RAISE NOTICE 'Nextnode.place_id: %s', nextnode.place_id; + IF nextnode.osm_id IS NOT NULL THEN + --RAISE NOTICE 'place_id is not null'; + IF nodeidpos > 1 and nodeidpos < array_upper(waynodes, 1) THEN + -- Make sure that the point is actually on the line. That might + -- be a bit paranoid but ensures that the algorithm still works + -- should osm2pgsql attempt to repair geometries. + splitline := split_line_on_node(linegeo, nextnode.geometry); + sectiongeo := ST_GeometryN(splitline, 1); + linegeo := ST_GeometryN(splitline, 2); + ELSE + sectiongeo = linegeo; + END IF; + endnumber := substring(nextnode.address->'housenumber','[0-9]+')::integer; - IF (startnumber > endnumber) THEN - housenum := endnumber; - endnumber := startnumber; - startnumber := housenum; - sectiongeo := ST_Reverse(sectiongeo); - END IF; + IF startnumber IS NOT NULL AND endnumber IS NOT NULL + AND startnumber != endnumber + AND ST_GeometryType(sectiongeo) = 'ST_LineString' THEN - IF NEW.startnumber IS NULL THEN - NEW.startnumber := startnumber; - NEW.endnumber := endnumber; - NEW.linegeo := sectiongeo; - NEW.street := coalesce(street, prevnode.street, nextnode.street); - NEW.addr_place := coalesce(addr_place, prevnode.addr_place, nextnode.addr_place); - NEW.postcode := coalesce(postcode, prevnode.postcode, nextnode.postcode); - ELSE - insert into location_property_osmline - (linegeo, partition, osm_id, parent_place_id, - startnumber, endnumber, interpolationtype, - street, addr_place, postcode, calculated_country_code, - geometry_sector, indexed_status) - values (sectiongeo, NEW.partition, NEW.osm_id, NEW.parent_place_id, - startnumber, endnumber, NEW.interpolationtype, - coalesce(street, prevnode.street, nextnode.street), - coalesce(addr_place, prevnode.addr_place, nextnode.addr_place), - coalesce(postcode, prevnode.postcode, nextnode.postcode), - NEW.calculated_country_code, NEW.geometry_sector, 0); - END IF; - END IF; + IF (startnumber > endnumber) THEN + housenum := endnumber; + endnumber := startnumber; + startnumber := housenum; + sectiongeo := ST_Reverse(sectiongeo); + END IF; - -- early break if we are out of line string, - -- might happen when a line string loops back on itself - IF ST_GeometryType(linegeo) != 'ST_LineString' THEN - RETURN NEW; - END IF; + seg_postcode := coalesce(postcode, + prevnode.address->'postcode', + nextnode.address->'postcode'); + + IF NEW.startnumber IS NULL THEN + NEW.startnumber := startnumber; + NEW.endnumber := endnumber; + NEW.linegeo := sectiongeo; + NEW.postcode := seg_postcode; + ELSE + insert into location_property_osmline + (linegeo, partition, osm_id, parent_place_id, + startnumber, endnumber, interpolationtype, + address, postcode, country_code, + geometry_sector, indexed_status) + values (sectiongeo, NEW.partition, NEW.osm_id, NEW.parent_place_id, + startnumber, endnumber, NEW.interpolationtype, + NEW.address, seg_postcode, + NEW.country_code, NEW.geometry_sector, 0); + END IF; + END IF; - startnumber := substring(nextnode.housenumber,'[0-9]+')::integer; - prevnode := nextnode; - END IF; - END LOOP; + -- early break if we are out of line string, + -- might happen when a line string loops back on itself + IF ST_GeometryType(linegeo) != 'ST_LineString' THEN + RETURN NEW; + END IF; + startnumber := substring(nextnode.address->'housenumber','[0-9]+')::integer; + prevnode := nextnode; + END IF; + END LOOP; + END IF; + + -- marking descendants for reparenting is not needed, because there are + -- actually no descendants for interpolation lines RETURN NEW; END; $$ @@ -1131,7 +1122,10 @@ DECLARE address_street_word_id INTEGER; address_street_word_ids INTEGER[]; parent_place_id_rank BIGINT; - + + addr_street TEXT; + addr_place TEXT; + isin TEXT[]; isin_tokens INT[]; @@ -1160,11 +1154,6 @@ BEGIN RETURN NEW; END IF; - -- ignore interpolated addresses - IF NEW.class = 'place' and NEW.type = 'address' THEN - RETURN NEW; - END IF; - --DEBUG: RAISE WARNING 'placex_update % %',NEW.osm_type,NEW.osm_id; --RAISE WARNING '%',NEW.place_id; @@ -1189,31 +1178,52 @@ BEGIN RETURN NEW; END IF; + IF NEW.address is not NULL THEN + IF NEW.address ? 'conscriptionnumber' THEN + i := getorcreate_housenumber_id(make_standard_name(NEW.address->'conscriptionnumber')); + IF NEW.address ? 'streetnumber' THEN + i := getorcreate_housenumber_id(make_standard_name(NEW.address->'streetnumber')); + NEW.housenumber := (NEW.address->'conscriptionnumber') || '/' || (NEW.address->'streetnumber'); + ELSE + NEW.housenumber := NEW.address->'conscriptionnumber'; + END IF; + ELSEIF NEW.address ? 'streetnumber' THEN + NEW.housenumber := NEW.address->'streetnumber'; + i := getorcreate_housenumber_id(make_standard_name(NEW.address->'streetnumber')); + ELSEIF NEW.address ? 'housenumber' THEN + NEW.housenumber := NEW.address->'housenumber'; + i := getorcreate_housenumber_id(make_standard_name(NEW.housenumber)); + END IF; + + addr_street = NEW.address->'street'; + addr_place = NEW.address->'place'; + + NEW.postcode = NEW.address->'postcode'; + END IF; + -- Speed up searches - just use the centroid of the feature -- cheaper but less acurate place_centroid := ST_PointOnSurface(NEW.geometry); NEW.centroid := null; -- recalculate country and partition - IF NEW.rank_search = 4 THEN + IF NEW.rank_search = 4 AND NEW.address is not NULL AND NEW.address ? 'country' THEN -- for countries, believe the mapped country code, -- so that we remain in the right partition if the boundaries -- suddenly expand. + NEW.country_code := lower(NEW.address->'country'); NEW.partition := get_partition(lower(NEW.country_code)); IF NEW.partition = 0 THEN - NEW.calculated_country_code := lower(get_country_code(place_centroid)); - NEW.partition := get_partition(NEW.calculated_country_code); - ELSE - NEW.calculated_country_code := lower(NEW.country_code); + NEW.country_code := lower(get_country_code(place_centroid)); + NEW.partition := get_partition(NEW.country_code); END IF; ELSE - IF NEW.rank_search > 4 THEN - --NEW.calculated_country_code := lower(get_country_code(NEW.geometry, NEW.country_code)); - NEW.calculated_country_code := lower(get_country_code(place_centroid)); + IF NEW.rank_search >= 4 THEN + NEW.country_code := lower(get_country_code(place_centroid)); ELSE - NEW.calculated_country_code := NULL; + NEW.country_code := NULL; END IF; - NEW.partition := get_partition(NEW.calculated_country_code); + NEW.partition := get_partition(NEW.country_code); END IF; -- waterway ways are linked when they are part of a relation and have the same class/type @@ -1244,7 +1254,7 @@ BEGIN -- Thought this wasn't needed but when we add new languages to the country_name table -- we need to update the existing names IF NEW.name is not null AND array_upper(akeys(NEW.name),1) > 1 THEN - default_language := get_country_language_code(NEW.calculated_country_code); + default_language := get_country_language_code(NEW.country_code); IF default_language IS NOT NULL THEN IF NEW.name ? 'name' AND NOT NEW.name ? ('name:'||default_language) THEN NEW.name := NEW.name || hstore(('name:'||default_language), (NEW.name -> 'name')); @@ -1263,7 +1273,7 @@ BEGIN END LOOP; NEW.importance := null; - select language||':'||title,importance from get_wikipedia_match(NEW.extratags, NEW.calculated_country_code) INTO NEW.wikipedia,NEW.importance; + select language||':'||title,importance from get_wikipedia_match(NEW.extratags, NEW.country_code) INTO NEW.wikipedia,NEW.importance; IF NEW.importance IS NULL THEN select language||':'||title,importance from wikipedia_article where osm_type = NEW.osm_type and osm_id = NEW.osm_id order by importance desc limit 1 INTO NEW.wikipedia,NEW.importance; END IF; @@ -1283,16 +1293,17 @@ BEGIN -- if we have a POI and there is no address information, -- see if we can get it from a surrounding building - IF NEW.osm_type = 'N' AND NEW.street IS NULL AND NEW.addr_place IS NULL + IF NEW.osm_type = 'N' AND addr_street IS NULL AND addr_place IS NULL AND NEW.housenumber IS NULL THEN FOR location IN select * from placex where ST_Covers(geometry, place_centroid) - and (housenumber is not null or street is not null or addr_place is not null) + and address is not null + and (address ? 'housenumber' or address ? 'street' or address ? 'place') and rank_search > 28 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') limit 1 LOOP - NEW.housenumber := location.housenumber; - NEW.street := location.street; - NEW.addr_place := location.addr_place; + NEW.housenumber := location.address->'housenumber'; + addr_street := location.address->'street'; + addr_place := location.address->'place'; END LOOP; END IF; @@ -1317,8 +1328,8 @@ BEGIN -- Note that addr:street links can only be indexed once the street itself is indexed - IF NEW.parent_place_id IS NULL AND NEW.street IS NOT NULL THEN - address_street_word_ids := get_name_ids(make_standard_name(NEW.street)); + IF NEW.parent_place_id IS NULL AND addr_street IS NOT NULL THEN + address_street_word_ids := get_name_ids(make_standard_name(addr_street)); IF address_street_word_ids IS NOT NULL THEN FOR location IN SELECT * from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP NEW.parent_place_id := location.place_id; @@ -1326,8 +1337,8 @@ BEGIN END IF; END IF; - IF NEW.parent_place_id IS NULL AND NEW.addr_place IS NOT NULL THEN - address_street_word_ids := get_name_ids(make_standard_name(NEW.addr_place)); + IF NEW.parent_place_id IS NULL AND addr_place IS NOT NULL THEN + address_street_word_ids := get_name_ids(make_standard_name(addr_place)); IF address_street_word_ids IS NOT NULL THEN FOR location IN SELECT * from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP NEW.parent_place_id := location.place_id; @@ -1349,7 +1360,7 @@ BEGIN -- Is this node part of a way? IF NEW.parent_place_id IS NULL AND NEW.osm_type = 'N' THEN - FOR location IN select p.place_id, p.osm_id, p.parent_place_id, p.rank_search, p.street, p.addr_place from placex p, planet_osm_ways w + FOR location IN select p.place_id, p.osm_id, p.parent_place_id, p.rank_search, p.address from placex p, planet_osm_ways w where p.osm_type = 'W' and p.rank_search >= 26 and p.geometry && NEW.geometry and w.id = p.osm_id and NEW.osm_id = any(w.nodes) LOOP @@ -1360,8 +1371,8 @@ BEGIN END IF; -- If the way mentions a street or place address, try that for parenting. - IF NEW.parent_place_id IS NULL AND location.street IS NOT NULL THEN - address_street_word_ids := get_name_ids(make_standard_name(location.street)); + IF NEW.parent_place_id IS NULL AND location.address ? 'street' THEN + address_street_word_ids := get_name_ids(make_standard_name(location.address->'street')); IF address_street_word_ids IS NOT NULL THEN FOR linkedplacex IN SELECT place_id from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP NEW.parent_place_id := linkedplacex.place_id; @@ -1369,8 +1380,8 @@ BEGIN END IF; END IF; - IF NEW.parent_place_id IS NULL AND location.addr_place IS NOT NULL THEN - address_street_word_ids := get_name_ids(make_standard_name(location.addr_place)); + IF NEW.parent_place_id IS NULL AND location.address ? 'place' THEN + address_street_word_ids := get_name_ids(make_standard_name(location.address->'place')); IF address_street_word_ids IS NOT NULL THEN FOR linkedplacex IN SELECT place_id from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) LOOP NEW.parent_place_id := linkedplacex.place_id; @@ -1415,9 +1426,9 @@ BEGIN -- Get the details of the parent road select * from search_name where place_id = NEW.parent_place_id INTO location; - NEW.calculated_country_code := location.country_code; + NEW.country_code := location.country_code; - -- Merge the postcode into the parent's address if necessary XXXX + -- Merge the postcode into the parent's address if necessary IF NEW.postcode IS NOT NULL THEN isin_tokens := '{}'::int[]; address_street_word_id := getorcreate_word_id(make_standard_name(NEW.postcode)); @@ -1452,10 +1463,10 @@ BEGIN -- Just be happy with inheriting from parent road only IF NEW.rank_search <= 25 and NEW.rank_address > 0 THEN - result := add_location(NEW.place_id, NEW.calculated_country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, NEW.geometry); + result := add_location(NEW.place_id, NEW.country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, NEW.geometry); END IF; - result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); + result := insertSearchName(NEW.partition, NEW.place_id, NEW.country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); return NEW; END IF; @@ -1585,7 +1596,7 @@ BEGIN -- from the linked place. Make sure a name tag for the default language exists in -- this case. IF NEW.name is not null AND array_upper(akeys(NEW.name),1) > 1 THEN - default_language := get_country_language_code(NEW.calculated_country_code); + default_language := get_country_language_code(NEW.country_code); IF default_language IS NOT NULL THEN IF NEW.name ? 'name' AND NOT NEW.name ? ('name:'||default_language) THEN NEW.name := NEW.name || hstore(('name:'||default_language), (NEW.name -> 'name')); @@ -1598,7 +1609,7 @@ BEGIN -- Did we gain a wikipedia tag in the process? then we need to recalculate our importance IF NEW.importance is null THEN - select language||':'||title,importance from get_wikipedia_match(NEW.extratags, NEW.calculated_country_code) INTO NEW.wikipedia,NEW.importance; + select language||':'||title,importance from get_wikipedia_match(NEW.extratags, NEW.country_code) INTO NEW.wikipedia,NEW.importance; END IF; -- Still null? how about looking it up by the node id IF NEW.importance IS NULL THEN @@ -1618,8 +1629,8 @@ BEGIN -- convert isin to array of tokenids isin_tokens := '{}'::int[]; - IF NEW.isin IS NOT NULL THEN - isin := regexp_split_to_array(NEW.isin, E'[;,]'); + IF NEW.address IS NOT NULL THEN + isin := avals(NEW.address); IF array_upper(isin, 1) IS NOT NULL THEN FOR i IN 1..array_upper(isin, 1) LOOP address_street_word_id := get_name_id(make_standard_name(isin[i])); @@ -1657,7 +1668,7 @@ BEGIN -- %NOTIGERDATA% IF 0 THEN -- for the USA we have an additional address table. Merge in zip codes from there too - IF NEW.rank_search = 26 AND NEW.calculated_country_code = 'us' THEN + IF NEW.rank_search = 26 AND NEW.country_code = 'us' THEN FOR location IN SELECT distinct postcode from location_property_tiger where parent_place_id = NEW.place_id LOOP address_street_word_id := get_name_id(make_standard_name(location.postcode)); nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); @@ -1801,14 +1812,14 @@ BEGIN IF NEW.name IS NOT NULL THEN IF NEW.rank_search <= 25 and NEW.rank_address > 0 THEN - result := add_location(NEW.place_id, NEW.calculated_country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, NEW.geometry); + result := add_location(NEW.place_id, NEW.country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, NEW.geometry); END IF; IF NEW.rank_search between 26 and 27 and NEW.class = 'highway' THEN - result := insertLocationRoad(NEW.partition, NEW.place_id, NEW.calculated_country_code, NEW.geometry); + result := insertLocationRoad(NEW.partition, NEW.place_id, NEW.country_code, NEW.geometry); END IF; - result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); + result := insertSearchName(NEW.partition, NEW.place_id, NEW.country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); END IF; @@ -1937,7 +1948,8 @@ BEGIN --DEBUG: RAISE WARNING 'place_insert: % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,st_area(NEW.geometry); -- filter wrong tupels IF ST_IsEmpty(NEW.geometry) OR NOT ST_IsValid(NEW.geometry) OR ST_X(ST_Centroid(NEW.geometry))::text in ('NaN','Infinity','-Infinity') OR ST_Y(ST_Centroid(NEW.geometry))::text in ('NaN','Infinity','-Infinity') THEN - INSERT INTO import_polygon_error values (NEW.osm_type, NEW.osm_id, NEW.class, NEW.type, NEW.name, NEW.country_code, + INSERT INTO import_polygon_error values (NEW.osm_type, NEW.osm_id, NEW.class, NEW.type, + NEW.name, NEW.address->'country', now(), ST_IsValidReason(NEW.geometry), null, NEW.geometry); -- RAISE WARNING 'Invalid Geometry: % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type; RETURN null; @@ -1970,34 +1982,22 @@ BEGIN where w.id = NEW.osm_id and p.osm_type = 'N' and p.osm_id = any(w.nodes); - INSERT INTO location_property_osmline - (osm_id, interpolationtype, street, - addr_place, postcode, calculated_country_code, linegeo) - VALUES (NEW.osm_id, NEW.housenumber, NEW.street, - NEW.addr_place, NEW.postcode, NEW.country_code, NEW.geometry); + INSERT INTO location_property_osmline (osm_id, address, linegeo) + VALUES (NEW.osm_id, NEW.address, NEW.geometry); IF existing.osm_type IS NULL THEN return NEW; END IF; - IF coalesce(existing.housenumber, '') != coalesce(NEW.housenumber, '') - OR coalesce(existing.street, '') != coalesce(NEW.street, '') - OR coalesce(existing.addr_place, '') != coalesce(NEW.addr_place, '') - OR coalesce(existing.isin, '') != coalesce(NEW.isin, '') - OR coalesce(existing.postcode, '') != coalesce(NEW.postcode, '') - OR coalesce(existing.country_code, '') != coalesce(NEW.country_code, '') + IF coalesce(existing.address, ''::hstore) != coalesce(NEW.address, ''::hstore) + OR (coalesce(existing.extratags, ''::hstore) != coalesce(NEW.extratags, ''::hstore)) OR existing.geometry::text != NEW.geometry::text THEN update place set name = NEW.name, - housenumber = NEW.housenumber, - street = NEW.street, - addr_place = NEW.addr_place, - isin = NEW.isin, - postcode = NEW.postcode, - country_code = NEW.country_code, + address = NEW.address, extratags = NEW.extratags, admin_level = NEW.admin_level, geometry = NEW.geometry @@ -2009,8 +2009,9 @@ BEGIN ELSE -- insert to placex -- Patch in additional country names - IF NEW.admin_level = 2 AND NEW.type = 'administrative' AND NEW.country_code is not null THEN - SELECT name FROM country_name WHERE country_code = lower(NEW.country_code) INTO existing; + IF NEW.admin_level = 2 AND NEW.type = 'administrative' + AND NEW.address is not NULL AND NEW.address ? 'country' THEN + SELECT name FROM country_name WHERE country_code = lower(NEW.address->'country') INTO existing; IF existing.name IS NOT NULL THEN NEW.name = existing.name || NEW.name; END IF; @@ -2068,56 +2069,16 @@ BEGIN END IF; -- No - process it as a new insertion (hopefully of low rank or it will be slow) - insert into placex (osm_type, osm_id, class, type, name, admin_level, housenumber, - street, addr_place, isin, postcode, country_code, extratags, geometry) - values (NEW.osm_type - ,NEW.osm_id - ,NEW.class - ,NEW.type - ,NEW.name - ,NEW.admin_level - ,NEW.housenumber - ,NEW.street - ,NEW.addr_place - ,NEW.isin - ,NEW.postcode - ,NEW.country_code - ,NEW.extratags - ,NEW.geometry - ); + insert into placex (osm_type, osm_id, class, type, name, + admin_level, address, extratags, geometry) + values (NEW.osm_type, NEW.osm_id, NEW.class, NEW.type, NEW.name, + NEW.admin_level, NEW.address, NEW.extratags, NEW.geometry); --DEBUG: RAISE WARNING 'insert done % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,NEW.name; RETURN NEW; END IF; - -- Various ways to do the update - - -- Debug, what's changed? - IF FALSE THEN - IF coalesce(existing.name::text, '') != coalesce(NEW.name::text, '') THEN - RAISE WARNING 'update details, name: % % % %',NEW.osm_type,NEW.osm_id,existing.name::text,NEW.name::text; - END IF; - IF coalesce(existing.housenumber, '') != coalesce(NEW.housenumber, '') THEN - RAISE WARNING 'update details, housenumber: % % % %',NEW.osm_type,NEW.osm_id,existing.housenumber,NEW.housenumber; - END IF; - IF coalesce(existing.street, '') != coalesce(NEW.street, '') THEN - RAISE WARNING 'update details, street: % % % %',NEW.osm_type,NEW.osm_id,existing.street,NEW.street; - END IF; - IF coalesce(existing.addr_place, '') != coalesce(NEW.addr_place, '') THEN - RAISE WARNING 'update details, street: % % % %',NEW.osm_type,NEW.osm_id,existing.addr_place,NEW.addr_place; - END IF; - IF coalesce(existing.isin, '') != coalesce(NEW.isin, '') THEN - RAISE WARNING 'update details, isin: % % % %',NEW.osm_type,NEW.osm_id,existing.isin,NEW.isin; - END IF; - IF coalesce(existing.postcode, '') != coalesce(NEW.postcode, '') THEN - RAISE WARNING 'update details, postcode: % % % %',NEW.osm_type,NEW.osm_id,existing.postcode,NEW.postcode; - END IF; - IF coalesce(existing.country_code, '') != coalesce(NEW.country_code, '') THEN - RAISE WARNING 'update details, country_code: % % % %',NEW.osm_type,NEW.osm_id,existing.country_code,NEW.country_code; - END IF; - END IF; - -- Special case for polygon shape changes because they tend to be large and we can be a bit clever about how we handle them IF existing.geometry::text != NEW.geometry::text AND ST_GeometryType(existing.geometry) in ('ST_Polygon','ST_MultiPolygon') @@ -2148,55 +2109,40 @@ BEGIN IF coalesce(existing.name::text, '') != coalesce(NEW.name::text, '') OR coalesce(existing.extratags::text, '') != coalesce(NEW.extratags::text, '') - OR coalesce(existing.housenumber, '') != coalesce(NEW.housenumber, '') - OR coalesce(existing.street, '') != coalesce(NEW.street, '') - OR coalesce(existing.addr_place, '') != coalesce(NEW.addr_place, '') - OR coalesce(existing.isin, '') != coalesce(NEW.isin, '') - OR coalesce(existing.postcode, '') != coalesce(NEW.postcode, '') - OR coalesce(existing.country_code, '') != coalesce(NEW.country_code, '') + OR coalesce(existing.address, ''::hstore) != coalesce(NEW.address, ''::hstore) OR coalesce(existing.admin_level, 15) != coalesce(NEW.admin_level, 15) OR existing.geometry::text != NEW.geometry::text THEN update place set name = NEW.name, - housenumber = NEW.housenumber, - street = NEW.street, - addr_place = NEW.addr_place, - isin = NEW.isin, - postcode = NEW.postcode, - country_code = NEW.country_code, + address = NEW.address, extratags = NEW.extratags, admin_level = NEW.admin_level, geometry = NEW.geometry where osm_type = NEW.osm_type and osm_id = NEW.osm_id and class = NEW.class and type = NEW.type; - + IF NEW.class in ('place','boundary') AND NEW.type in ('postcode','postal_code') THEN - IF NEW.postcode IS NULL THEN + IF NEW.address is NULL OR NOT NEW.address ? 'postcode' THEN -- postcode was deleted, no longer retain in placex DELETE FROM placex where place_id = existingplacex.place_id; RETURN NULL; END IF; - NEW.name := hstore('ref', NEW.postcode); + NEW.name := hstore('ref', NEW.address->'postcode'); END IF; - + update placex set name = NEW.name, - housenumber = NEW.housenumber, - street = NEW.street, - addr_place = NEW.addr_place, - isin = NEW.isin, - postcode = NEW.postcode, - country_code = NEW.country_code, + address = NEW.address, parent_place_id = null, extratags = NEW.extratags, - admin_level = CASE WHEN NEW.admin_level > 15 THEN 15 ELSE NEW.admin_level END, - indexed_status = 2, + admin_level = NEW.admin_level, + indexed_status = 2, geometry = NEW.geometry where place_id = existingplacex.place_id; - + -- if a node(=>house), which is part of a interpolation line, changes (e.g. the street attribute) => mark this line for reparenting -- (already here, because interpolation lines are reindexed before nodes, so in the second call it would be too late) IF NEW.osm_type='N' and NEW.class='place' and NEW.type='house' THEN @@ -2339,7 +2285,7 @@ DECLARE hadcountry BOOLEAN; BEGIN -- first query osmline (interpolation lines) - select parent_place_id, calculated_country_code, 30, postcode, null, 'place', 'house' from location_property_osmline + select parent_place_id, country_code, 30, postcode, null, 'place', 'house' from location_property_osmline WHERE place_id = in_place_id AND in_housenumber>=startnumber AND in_housenumber <= endnumber INTO for_place_id,searchcountrycode, searchrankaddress, searchpostcode, searchhousename, searchclass, searchtype; IF for_place_id IS NOT NULL THEN @@ -2367,13 +2313,13 @@ BEGIN -- %NOAUXDATA% END IF; IF for_place_id IS NULL THEN - select parent_place_id, calculated_country_code, housenumber, rank_search, postcode, name, class, type from placex + select parent_place_id, country_code, housenumber, rank_search, postcode, name, class, type from placex WHERE place_id = in_place_id and rank_search > 27 INTO for_place_id, searchcountrycode, searchhousenumber, searchrankaddress, searchpostcode, searchhousename, searchclass, searchtype; END IF; IF for_place_id IS NULL THEN - select coalesce(linked_place_id, place_id), calculated_country_code, + select coalesce(linked_place_id, place_id), country_code, housenumber, rank_search, postcode, null from placex where place_id = in_place_id INTO for_place_id, searchcountrycode, searchhousenumber, searchrankaddress, searchpostcode, searchhousename; @@ -2388,13 +2334,13 @@ BEGIN CASE WHEN class = 'place' and type = 'postcode' THEN hstore('name', postcode) ELSE name END as name, class, type, admin_level, true as fromarea, true as isaddress, CASE WHEN rank_address = 0 THEN 100 WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address, - 0 as distance, calculated_country_code, postcode + 0 as distance, country_code, postcode from placex where place_id = for_place_id LOOP --RAISE WARNING '%',location; - IF searchcountrycode IS NULL AND location.calculated_country_code IS NOT NULL THEN - searchcountrycode := location.calculated_country_code; + IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN + searchcountrycode := location.country_code; END IF; IF searchpostcode IS NOT NULL and location.type = 'postcode' THEN location.isaddress := FALSE; @@ -2426,17 +2372,17 @@ BEGIN CASE WHEN extratags ? 'place' THEN extratags->'place' ELSE type END as type, admin_level, fromarea, isaddress, CASE WHEN address_place_id = for_place_id AND rank_address = 0 THEN 100 WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address, - distance,calculated_country_code,postcode + distance,country_code,postcode from place_addressline join placex on (address_place_id = placex.place_id) where place_addressline.place_id = for_place_id and (cached_rank_address > 0 AND cached_rank_address < searchrankaddress) and address_place_id != for_place_id - and (placex.calculated_country_code IS NULL OR searchcountrycode IS NULL OR placex.calculated_country_code = searchcountrycode) + and (placex.country_code IS NULL OR searchcountrycode IS NULL OR placex.country_code = searchcountrycode) order by rank_address desc,isaddress desc,fromarea desc,distance asc,rank_search desc LOOP --RAISE WARNING '%',location; - IF searchcountrycode IS NULL AND location.calculated_country_code IS NOT NULL THEN - searchcountrycode := location.calculated_country_code; + IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN + searchcountrycode := location.country_code; END IF; IF searchpostcode IS NOT NULL and location.type = 'postcode' THEN location.isaddress := FALSE; @@ -2497,31 +2443,6 @@ $$ LANGUAGE plpgsql; -CREATE OR REPLACE FUNCTION update_place(search_place_id BIGINT) RETURNS BOOLEAN - AS $$ -DECLARE - numfeatures integer; -BEGIN - update placex set - name = place.name, - housenumber = place.housenumber, - street = place.street, - addr_place = place.addr_place, - isin = place.isin, - postcode = place.postcode, - country_code = place.country_code, - parent_place_id = null - from place - where placex.place_id = search_place_id - and place.osm_type = placex.osm_type and place.osm_id = placex.osm_id - and place.class = placex.class and place.type = placex.type; - update placex set indexed_status = 2 where place_id = search_place_id; - update placex set indexed_status = 0 where place_id = search_place_id; - return true; -END; -$$ -LANGUAGE plpgsql; - CREATE OR REPLACE FUNCTION get_searchrank_label(rank INTEGER) RETURNS TEXT AS $$ DECLARE @@ -2641,7 +2562,7 @@ BEGIN IF out_parent_place_id IS NULL THEN FOR location IN SELECT place_id FROM getNearestRoadFeature(out_partition, place_centroid) LOOP out_parent_place_id := location.place_id; - END LOOP; + END LOOP; END IF; out_postcode := in_postcode; @@ -2908,9 +2829,9 @@ BEGIN IF ST_GeometryType(placegeom) in ('ST_Polygon','ST_MultiPolygon') THEN FOR geom IN select split_geometry(placegeom) FROM placex WHERE place_id = placeid LOOP update placex set indexed_status = 2 where (st_covers(geom, placex.geometry) OR ST_Intersects(geom, placex.geometry)) - AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) = 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and addr_place is not null)); + AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) = 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and address > 'place')); update placex set indexed_status = 2 where (st_covers(geom, placex.geometry) OR ST_Intersects(geom, placex.geometry)) - AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and addr_place is not null)); + AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and address ? 'place')); END LOOP; ELSE diameter := 0; @@ -2935,7 +2856,7 @@ BEGIN update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter); ELSEIF rank >= 16 THEN -- up to rank 16, street-less addresses may need reparenting - update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter) and (rank_search < 28 or name is not null or addr_place is not null); + update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter) and (rank_search < 28 or name is not null or address ? 'place'); ELSE -- for all other places the search terms may change as well update placex set indexed_status = 2 where indexed_status = 0 and rank_search > rank and ST_DWithin(placex.geometry, placegeom, diameter) and (rank_search < 28 or name is not null); diff --git a/sql/tables.sql b/sql/tables.sql index f228081f..8be7c39e 100644 --- a/sql/tables.sql +++ b/sql/tables.sql @@ -94,10 +94,9 @@ CREATE TABLE location_property_osmline ( startnumber INTEGER, endnumber INTEGER, interpolationtype TEXT, - street TEXT, - addr_place TEXT, + address HSTORE, postcode TEXT, - calculated_country_code VARCHAR(2), + country_code VARCHAR(2), geometry_sector INTEGER, indexed_status INTEGER, indexed_date TIMESTAMP){ts:search-data}; @@ -144,7 +143,9 @@ CREATE TABLE placex ( indexed_date TIMESTAMP, wikipedia TEXT, -- calculated wikipedia article name (language:title) geometry_sector INTEGER, - calculated_country_code varchar(2) + country_code varchar(2), + housenumber TEXT, + postcode TEXT ) {ts:search-data}; SELECT AddGeometryColumn('placex', 'centroid', 4326, 'GEOMETRY', 2); CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id) {ts:search-index}; diff --git a/test/bdd/db/import/interpolation.feature b/test/bdd/db/import/interpolation.feature index 7dfc6b23..d7ac9a4f 100644 --- a/test/bdd/db/import/interpolation.feature +++ b/test/bdd/db/import/interpolation.feature @@ -7,6 +7,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | 1 1 | | N2 | place | house | 6 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001 | And the ways | id | nodes | @@ -21,6 +23,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | 1 1 | | N2 | place | house | 6 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1.001, 1 1 | And the ways | id | nodes | @@ -35,6 +39,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 1 | 1 1 | | N2 | place | house | 11 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | odd | 1 1, 1 1.001 | And the ways | id | nodes | @@ -49,6 +55,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 1 | 1 1 | | N2 | place | house | 3 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | all | 1 1, 1 1.001 | And the ways | id | nodes | @@ -63,6 +71,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | 1 1 | | N2 | place | house | 10 | 1.001 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001 | And the ways | id | nodes | @@ -77,6 +87,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | 1 1 | | N2 | place | house | 10 | 1.001 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001 | And the ways | id | nodes | @@ -92,6 +104,8 @@ Feature: Import of address interpolations | N1 | place | house | 2 | 1 1 | | N2 | place | house | 14 | 1.001 1.001 | | N3 | place | house | 10 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001 | And the ways | id | nodes | @@ -109,6 +123,8 @@ Feature: Import of address interpolations | N2 | place | house | 14 | 1.001 1.001 | | N3 | place | house | 10 | 1 1.001 | | N4 | place | house | 18 | 1.001 1.002 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001, 1.001 1.002 | And the ways | id | nodes | @@ -126,6 +142,8 @@ Feature: Import of address interpolations | N1 | place | house | 2 | 1 1 | | N2 | place | house | 14 | 1.001 1.001 | | N3 | place | house | 10 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1.001 1.001, 1 1.001, 1 1 | And the ways | id | nodes | @@ -142,6 +160,8 @@ Feature: Import of address interpolations | N1 | place | house | 2 | 1 1 | | N2 | place | house | 8 | 1.001 1.001 | | N3 | place | house | 7 | 1 1.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001 | And the ways | id | nodes | @@ -158,6 +178,8 @@ Feature: Import of address interpolations | N1 | place | house | 2 | 0 0 | | N2 | place | house | 6 | 0 0.001 | | N3 | place | house | 10 | 0 0.002 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 0 0, 0 0.001, 0 0.002, 0 0.001 | And the ways | id | nodes | @@ -174,6 +196,8 @@ Feature: Import of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | 0 0 | | N2 | place | house | 6 | 0 0.001 | + And the places + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | 0 0, 0 0.001, 0 0.002, 0 0.001 | And the ways | id | nodes | @@ -192,7 +216,7 @@ Feature: Import of address interpolations | N3 | place | house | 12 | :n-middle-w | | N4 | place | house | 16 | :n-middle-e | And the places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W10 | place | houses | even | | :w-middle | | W11 | place | houses | even | Cloud Street | :w-middle | And the places @@ -238,9 +262,9 @@ Feature: Import of address interpolations | N3 | place | house | 12 | Cloud Street | :n-middle-w | | N4 | place | house | 16 | Cloud Street | :n-middle-e | And the places - | osm | class | type | housenr | geometry | - | W10 | place | houses | even | :w-middle | - | W11 | place | houses | even | :w-middle | + | osm | class | type | addr+interpolation | geometry | + | W10 | place | houses | even | :w-middle | + | W11 | place | houses | even | :w-middle | And the places | osm | class | type | name | geometry | | W2 | highway | tertiary | Sun Way | :w-north | @@ -277,7 +301,9 @@ Feature: Import of address interpolations | N1 | place | house | 10 | 144.9632341 -37.76163 | | N2 | place | house | 6 | 144.9630541 -37.7628174 | | N3 | shop | supermarket | 2 | 144.9629794 -37.7630755 | - | W1 | place | houses | even | 144.9632341 -37.76163,144.9630541 -37.7628172,144.9629794 -37.7630755 | + And the places + | osm | class | type | addr+interpolation | geometry | + | W1 | place | houses | even | 144.9632341 -37.76163,144.9630541 -37.7628172,144.9629794 -37.7630755 | And the ways | id | nodes | | 1 | 1,2,3 | @@ -288,19 +314,23 @@ Feature: Import of address interpolations | 6 | 10 | 144.9630541 -37.7628174, 144.9632341 -37.76163 | Scenario: Place with missing address information - Given the places - | osm | class | type | housenr | geometry | - | N1 | place | house | 23 | 0.0001 0.0001 | - | N2 | amenity | school | | 0.0001 0.0002 | - | N3 | place | house | 29 | 0.0001 0.0004 | - | W1 | place | houses | odd | 0.0001 0.0001,0.0001 0.0002,0.0001 0.0004 | + Given the grid + | 1 | | 2 | | | 3 | + And the places + | osm | class | type | housenr | + | N1 | place | house | 23 | + | N2 | amenity | school | | + | N3 | place | house | 29 | + And the places + | osm | class | type | addr+interpolation | geometry | + | W1 | place | houses | odd | 1,2,3 | And the ways | id | nodes | | 1 | 1,2,3 | When importing Then W1 expands to interpolation | start | end | geometry | - | 23 | 29 | 0.0001 0.0001, 0.0001 0.0002, 0.0001 0.0004 | + | 23 | 29 | 1,2,3 | Scenario: Ways without node entries are ignored Given the places diff --git a/test/bdd/db/import/naming.feature b/test/bdd/db/import/naming.feature index d2339376..f3019e2a 100644 --- a/test/bdd/db/import/naming.feature +++ b/test/bdd/db/import/naming.feature @@ -8,8 +8,8 @@ Feature: Import and search of names | N1 | place | locality | german | country:de | When importing Then placex contains - | object | calculated_country_code | name+name | - | N1 | de | german | + | object | country_code | name+name | + | N1 | de | german | Scenario: Copying name tag to default language if it does not exist Given the places @@ -17,8 +17,8 @@ Feature: Import and search of names | N1 | place | locality | german | finnish | country:de | When importing Then placex contains - | object | calculated_country_code | name | name+name:fi | name+name:de | - | N1 | de | german | finnish | german | + | object | country_code | name | name+name:fi | name+name:de | + | N1 | de | german | finnish | german | Scenario: Copying default language name tag to name if it does not exist Given the places @@ -26,8 +26,8 @@ Feature: Import and search of names | N1 | place | locality | german | finnish | country:de | When importing Then placex contains - | object | calculated_country_code | name | name+name:fi | name+name:de | - | N1 | de | german | finnish | german | + | object | country_code | name | name+name:fi | name+name:de | + | N1 | de | german | finnish | german | Scenario: Do not overwrite default language with name tag Given the places @@ -35,5 +35,5 @@ Feature: Import and search of names | N1 | place | locality | german | finnish | local | country:de | When importing Then placex contains - | object | calculated_country_code | name | name+name:fi | name+name:de | - | N1 | de | german | finnish | local | + | object | country_code | name | name+name:fi | name+name:de | + | N1 | de | german | finnish | local | diff --git a/test/bdd/db/import/parenting.feature b/test/bdd/db/import/parenting.feature index 2650f6f0..401a58f1 100644 --- a/test/bdd/db/import/parenting.feature +++ b/test/bdd/db/import/parenting.feature @@ -325,11 +325,11 @@ Feature: Parenting of objects | W3 | highway | residential | foo | :w-NS | When importing Then placex contains - | object | parent_place_id | street | addr_place | housenumber | - | W1 | W3 | foo | nowhere | 3 | - | N1 | W3 | foo | nowhere | 3 | - | N2 | W3 | foo | nowhere | 3 | - | N3 | W3 | foo | nowhere | 3 | + | object | parent_place_id | housenumber | + | W1 | W3 | 3 | + | N1 | W3 | 3 | + | N2 | W3 | 3 | + | N3 | W3 | 3 | Scenario: POIs don't inherit from streets Given the scene building-on-street-corner @@ -344,8 +344,8 @@ Feature: Parenting of objects | W3 | highway | residential | foo | :w-NS | When importing Then placex contains - | object | parent_place_id | street | addr_place | housenumber | - | N1 | W3 | None | None | None | + | object | parent_place_id | housenumber | + | N1 | W3 | None | Scenario: POIs with own address do not inherit building address Given the scene building-on-street-corner @@ -370,11 +370,11 @@ Feature: Parenting of objects | W3 | highway | residential | foo | :w-NS | When importing Then placex contains - | object | parent_place_id | street | addr_place | housenumber | - | W1 | N4 | None | theplace | 3 | - | N1 | W2 | bar | None | None | - | N2 | W3 | None | None | 4 | - | N3 | W2 | None | nowhere | None | + | object | parent_place_id | housenumber | + | W1 | N4 | 3 | + | N1 | W2 | None | + | N2 | W3 | 4 | + | N3 | W2 | None | Scenario: POIs parent a road if they are attached to it Given the scene points-on-roads diff --git a/test/bdd/db/import/placex.feature b/test/bdd/db/import/placex.feature index 7cbedaa3..f124e482 100644 --- a/test/bdd/db/import/placex.feature +++ b/test/bdd/db/import/placex.feature @@ -8,8 +8,8 @@ Feature: Import into placex | N1 | highway | primary | country:us | When importing Then placex contains - | object | country_code | calculated_country_code | - | N1 | None | us | + | object | addr+country | country_code | + | N1 | - | us | Scenario: Location overwrites country code tag Given the named places @@ -17,8 +17,8 @@ Feature: Import into placex | N1 | highway | primary | de | country:us | When importing Then placex contains - | object | country_code | calculated_country_code | - | N1 | de | us | + | object | addr+country | country_code | + | N1 | de | us | Scenario: Country code tag overwrites location for countries Given the named places @@ -26,8 +26,8 @@ Feature: Import into placex | R1 | boundary | administrative | 2 | de | (-100 40, -101 40, -101 41, -100 41, -100 40) | When importing Then placex contains - | object | country_code | calculated_country_code | - | R1 | de | de | + | object | addr+country | country_code | + | R1 | de | de | Scenario: Illegal country code tag for countries is ignored Given the named places @@ -35,8 +35,8 @@ Feature: Import into placex | R1 | boundary | administrative | 2 | xx | (-100 40, -101 40, -101 41, -100 41, -100 40) | When importing Then placex contains - | object | country_code | calculated_country_code | - | R1 | xx | us | + | object | addr+country | country_code | + | R1 | xx | us | Scenario: admin level is copied over Given the named places @@ -47,24 +47,6 @@ Feature: Import into placex | object | admin_level | | N1 | 3 | - Scenario: admin level is default 15 - Given the named places - | osm | class | type | - | N1 | amenity | prison | - When importing - Then placex contains - | object | admin_level | - | N1 | 15 | - - Scenario: admin level is never larger than 15 - Given the named places - | osm | class | type | admin | - | N1 | amenity | prison | 16 | - When importing - Then placex contains - | object | admin_level | - | N1 | 15 | - Scenario: postcode node without postcode is dropped Given the places | osm | class | type | name+ref | @@ -87,10 +69,10 @@ Feature: Import into placex | N3 | place | postcode | Y45 | country:gb | When importing Then placex contains - | object | postcode | calculated_country_code | rank_search | rank_address | - | N1 | E45 2CD | gb | 25 | 5 | - | N2 | E45 2 | gb | 23 | 5 | - | N3 | Y45 | gb | 21 | 5 | + | object | postcode | country_code | rank_search | rank_address | + | N1 | E45 2CD | gb | 25 | 5 | + | N2 | E45 2 | gb | 23 | 5 | + | N3 | Y45 | gb | 21 | 5 | Scenario: wrongly formatted GB postcodes are down-ranked Given the places @@ -100,10 +82,10 @@ Feature: Import into placex | N3 | place | postcode | y45 | country:gb | When importing Then placex contains - | object | calculated_country_code | rank_search | rank_address | - | N1 | gb | 30 | 30 | - | N2 | gb | 30 | 30 | - | N3 | gb | 30 | 30 | + | object | country_code | rank_search | rank_address | + | N1 | gb | 30 | 30 | + | N2 | gb | 30 | 30 | + | N3 | gb | 30 | 30 | Scenario: search and address rank for DE postcodes correctly assigned Given the places @@ -114,11 +96,11 @@ Feature: Import into placex | N4 | place | postcode | 564276 | country:de | When importing Then placex contains - | object | calculated_country_code | rank_search | rank_address | - | N1 | de | 21 | 11 | - | N2 | de | 30 | 30 | - | N3 | de | 30 | 30 | - | N4 | de | 30 | 30 | + | object | country_code | rank_search | rank_address | + | N1 | de | 21 | 11 | + | N2 | de | 30 | 30 | + | N3 | de | 30 | 30 | + | N4 | de | 30 | 30 | Scenario: search and address rank for other postcodes are correctly assigned Given the places @@ -134,16 +116,16 @@ Feature: Import into placex | N9 | place | postcode | A1:bc10 | country:ca | When importing Then placex contains - | object | calculated_country_code | rank_search | rank_address | - | N1 | ca | 21 | 11 | - | N2 | ca | 21 | 11 | - | N3 | ca | 21 | 11 | - | N4 | ca | 21 | 11 | - | N5 | ca | 21 | 11 | - | N6 | ca | 21 | 11 | - | N7 | ca | 25 | 11 | - | N8 | ca | 25 | 11 | - | N9 | ca | 25 | 11 | + | object | country_code | rank_search | rank_address | + | N1 | ca | 21 | 11 | + | N2 | ca | 21 | 11 | + | N3 | ca | 21 | 11 | + | N4 | ca | 21 | 11 | + | N5 | ca | 21 | 11 | + | N6 | ca | 21 | 11 | + | N7 | ca | 25 | 11 | + | N8 | ca | 25 | 11 | + | N9 | ca | 25 | 11 | Scenario: search and address ranks for places are correctly assigned Given the named places diff --git a/test/bdd/db/update/interpolation.feature b/test/bdd/db/update/interpolation.feature index 0eaa97fd..f7f7dddb 100644 --- a/test/bdd/db/update/interpolation.feature +++ b/test/bdd/db/update/interpolation.feature @@ -17,7 +17,9 @@ Feature: Update of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | - | W10 | place | houses | even | :w-middle | + And updating places + | osm | class | type | addr+interpolation | geometry | + | W10 | place | houses | even | :w-middle | Then placex contains | object | parent_place_id | | N1 | W2 | @@ -32,6 +34,8 @@ Feature: Update of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | + And the places + | osm | class | type | addr+interpolation | geometry | | W10 | place | houses | even | :w-middle | And the places | osm | class | type | name | geometry | @@ -49,7 +53,7 @@ Feature: Update of address interpolations | parent_place_id | start | end | | W2 | 2 | 6 | When updating places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W10 | place | houses | even | Cloud Street | :w-middle | Then placex contains | object | parent_place_id | @@ -65,6 +69,8 @@ Feature: Update of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | + And the places + | osm | class | type | addr+interpolation | geometry | | W10 | place | houses | even | :w-middle | And the places | osm | class | type | name | geometry | @@ -99,6 +105,8 @@ Feature: Update of address interpolations | osm | class | type | housenr | geometry | | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | + And the places + | osm | class | type | addr+interpolation | geometry | | W10 | place | houses | even | :w-middle | And the places | osm | class | type | name | geometry | @@ -129,7 +137,7 @@ Feature: Update of address interpolations | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | And the places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W10 | place | houses | even | Cloud Street| :w-middle | And the places | osm | class | type | name | geometry | @@ -163,7 +171,7 @@ Feature: Update of address interpolations | N1 | place | house | 2 | :n-middle-w | | N2 | place | house | 6 | :n-middle-e | And the places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W10 | place | houses | even | Cloud Street| :w-middle | And the places | osm | class | type | name | geometry | @@ -209,7 +217,7 @@ Feature: Update of address interpolations | N1 | place | house | 2 | :n-north-w | | N2 | place | house | 6 | :n-north-e | And updating places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W1 | place | houses | even | Cloud Street| :w-north | Then placex has no entry for W1 And W1 expands to interpolation @@ -229,7 +237,7 @@ Feature: Update of address interpolations | id | nodes | | 1 | 1,100,101,102,2 | And the places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W1 | place | houses | even | Cloud Street| :w-north | When importing Then placex has no entry for W1 @@ -252,7 +260,7 @@ Feature: Update of address interpolations | id | nodes | | 1 | 1,100,101,102,2 | And the places - | osm | class | type | housenr | geometry | + | osm | class | type | addr+interpolation | geometry | | W1 | place | houses | even | :w-north | When importing Then W1 expands to no interpolation @@ -261,7 +269,7 @@ Feature: Update of address interpolations | N1 | place | house | 2 | :n-north-w | | N2 | place | house | 6 | :n-north-e | And updating places - | osm | class | type | housenr | street | geometry | + | osm | class | type | addr+interpolation | street | geometry | | W1 | place | houses | even | Cloud Street| :w-north | Then W1 expands to interpolation | parent_place_id | start | end | @@ -279,7 +287,7 @@ Feature: Update of address interpolations | id | nodes | | 2 | 3,4,5 | And the places - | osm | class | type | housenr | geometry | + | osm | class | type | addr+interpolation | geometry | | W2 | place | houses | even | 3,4,5 | And the places | osm | class | type | housenr | @@ -309,7 +317,7 @@ Feature: Update of address interpolations | id | nodes | | 2 | 3,4,5 | And the places - | osm | class | type | housenr | geometry | + | osm | class | type | addr+interpolation | geometry | | W2 | place | houses | even | 3,4,5 | And the places | osm | class | type | housenr | @@ -338,7 +346,7 @@ Feature: Update of address interpolations | id | nodes | | 2 | 3,4 | And the places - | osm | class | type | housenr | geometry | + | osm | class | type | addr+interpolation | geometry | | W2 | place | houses | even | 3,4 | And the places | osm | class | type | housenr | diff --git a/test/bdd/environment.py b/test/bdd/environment.py index 58494deb..aca7929d 100644 --- a/test/bdd/environment.py +++ b/test/bdd/environment.py @@ -4,6 +4,7 @@ import os import psycopg2 import psycopg2.extras import subprocess +import tempfile from nose.tools import * # for assert functions from sys import version_info as python_version @@ -88,17 +89,20 @@ class NominatimEnvironment(object): conn.commit() conn.close() - # execute osm2pgsql on an empty file to get the right tables - osm2pgsql = os.path.join(self.build_dir, 'osm2pgsql', 'osm2pgsql') - proc = subprocess.Popen([osm2pgsql, '-lsc', '-r', 'xml', - '-O', 'gazetteer', '-d', self.template_db, '-'], - cwd=self.build_dir, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - [outstr, errstr] = proc.communicate(input=b'') - logger.debug("running osm2pgsql for template: %s\n%s\n%s" % (osm2pgsql, outstr, errstr)) - self.run_setup_script('create-functions', 'create-tables', - 'create-partition-tables', 'create-partition-functions', - 'load-data', 'create-search-indices') + # execute osm2pgsql import on an empty file to get the right tables + with tempfile.NamedTemporaryFile(dir='/tmp', suffix='.xml') as fd: + fd.write(b'') + fd.flush() + self.run_setup_script('import-data', + 'ignore-errors', + 'create-functions', + 'create-tables', + 'create-partition-tables', + 'create-partition-functions', + 'load-data', + 'create-search-indices', + osm_file=fd.name, + osm2pgsql_cache='200') def setup_api_db(self, context): self.write_nominatim_config(self.api_test_db) diff --git a/test/bdd/osm2pgsql/import/tags.feature b/test/bdd/osm2pgsql/import/tags.feature index d81b6c72..7db8d629 100644 --- a/test/bdd/osm2pgsql/import/tags.feature +++ b/test/bdd/osm2pgsql/import/tags.feature @@ -102,8 +102,8 @@ Feature: Tag evaluation n1 T=,name=real """ Then place contains - | object | name | - | N1 | 'name' : 'real' | + | object | class | type | name | + | N1 | | | 'name' : 'real' | Examples: | key | value | @@ -300,7 +300,7 @@ Feature: Tag evaluation n11 T= """ Then place contains - | object | class | type | postcode | + | object | class | type | addr+postcode | | N10 | highway | secondary | | | N11 | place | postcode | | And place has no entry for N10:place @@ -320,9 +320,9 @@ Feature: Tag evaluation n20 Tamenity=hospital,addr:place=Foo%20%Town """ Then place contains - | object | class | type | street | addr_place | - | N10 | amenity | hospital | Foo St | None | - | N20 | amenity | hospital | - | Foo Town | + | object | class | type | addr+street | addr+place | + | N10 | amenity | hospital | Foo St | - | + | N20 | amenity | hospital | - | Foo Town | Scenario Outline: Import of country @@ -331,16 +331,16 @@ Feature: Tag evaluation n10 Tplace=village,= """ Then place contains - | object | class | type | country_code | + | object | class | type | addr+country | | N10 | place | village | | Examples: - | key | value | - | country_code | us | - | ISO3166-1 | XX | - | is_in:country_code | __ | - | addr:country | .. | - | addr:country_code | cv | + | key | value | + | country_code | us | + | ISO3166-1 | XX | + | is_in:country_code | __ | + | addr:country | .. | + | addr:country_code | cv | Scenario Outline: Ignore country codes with wrong length When loading osm data @@ -348,7 +348,7 @@ Feature: Tag evaluation n10 Tplace=village,country_code= """ Then place contains - | object | class | type | country_code | + | object | class | type | addr+country | | N10 | place | village | - | Examples: @@ -368,24 +368,11 @@ Feature: Tag evaluation n13 Tbuilding=yes,addr:conscriptionnumber=3,addr:streetnumber=111 """ Then place contains - | object | class | type | housenumber | - | N10 | building | yes | 4b | - | N11 | building | yes | 003 | - | N12 | building | yes | 2345 | - | N13 | building | yes | 3/111 | - - Scenario: Import of address interpolations - When loading osm data - """ - n10 Taddr:interpolation=odd - n11 Taddr:housenumber=10,addr:interpolation=odd - n12 Taddr:interpolation=odd,addr:housenumber=23 - """ - Then place contains - | object | class | type | housenumber | - | N10 | place | houses | odd | - | N11 | place | houses | odd | - | N12 | place | houses | odd | + | object | class | type | address | + | N10 | building | yes | 'housenumber' : '4b' | + | N11 | building | yes | 'conscriptionnumber' : '003' | + | N12 | building | yes | 'streetnumber' : '2345' | + | N13 | building | yes | 'conscriptionnumber' : '3', 'streetnumber' : '111' | Scenario: Shorten tiger:county tags When loading osm data @@ -395,26 +382,26 @@ Feature: Tag evaluation n12 Tplace=village,tiger:county=Feebourgh """ Then place contains - | object | class | type | isin | + | object | class | type | addr+tiger:county | | N10 | place | village | Feebourgh county | - | N11 | place | village | Alabama,Feebourgh county | + | N11 | place | village | Feebourgh county | | N12 | place | village | Feebourgh county | Scenario Outline: Import of address tags When loading osm data """ - n10 Tplace=village,= + n10 Tplace=village,addr:= + n11 Tplace=village,is_in:= """ Then place contains - | object | class | type | isin | - | N10 | place | village | | + | object | class | type | address | + | N10 | place | village | '' : '' | Examples: - | key | value | - | is_in:country | Xanadu | - | addr:suburb | hinein | - | addr:city | Sydney | - | addr:state | Jura | + | key | value | + | suburb | hinein | + | city | Sydney | + | state | Jura | Scenario: Import of isin tags with space When loading osm data @@ -423,9 +410,9 @@ Feature: Tag evaluation n11 Tplace=village,addr:county=le%20%havre """ Then place contains - | object | class | type | isin | - | N10 | place | village | Stockholm, Sweden | - | N11 | place | village | le havre | + | object | class | type | address | + | N10 | place | village | 'is_in' : 'Stockholm, Sweden' | + | N11 | place | village | 'county' : 'le havre' | Scenario: Import of admin level When loading osm data @@ -438,8 +425,8 @@ Feature: Tag evaluation Then place contains | object | class | type | admin_level | | N10 | amenity | hospital | 3 | - | N11 | amenity | hospital | 100 | - | N12 | amenity | hospital | 100 | + | N11 | amenity | hospital | 15 | + | N12 | amenity | hospital | 15 | | N13 | amenity | hospital | 3 | Scenario Outline: Import of extra tags @@ -550,5 +537,5 @@ Feature: Tag evaluation n290393920 Taddr:city=Perpignan,addr:country=FR,addr:housenumber=43\,addr:postcode=66000,addr:street=Rue%20%Pierre%20%Constant%20%d`Ivry,source=cadastre-dgi-fr%20%source%20%:%20%Direction%20%Générale%20%des%20%Impôts%20%-%20%Cadastre%20%;%20%mise%20%à%20%jour%20%:2008 """ Then place contains - | object | class | type | housenumber | - | N290393920 | place | house| 43\ | + | object | class | type | address | + | N290393920 | place | house| 'city' : 'Perpignan', 'country' : 'FR', 'housenumber' : '43\\', 'postcode' : '66000', 'street' : 'Rue Pierre Constant d`Ivry' | diff --git a/test/bdd/osm2pgsql/update/relation.feature b/test/bdd/osm2pgsql/update/relation.feature index 0eccd3e6..83ce9129 100644 --- a/test/bdd/osm2pgsql/update/relation.feature +++ b/test/bdd/osm2pgsql/update/relation.feature @@ -137,7 +137,7 @@ Feature: Update of relations by osm2pgsql r1 Ttype=boundary,boundary=administrative,name=Foo,country_code=XX,admin_level=2 Mw1@ """ Then place contains - | object | country_code | name | + | object | addr+country | name | | R1 | XX | 'name' : 'Foo' | Scenario: Country boundary names are extended when country_code known @@ -154,6 +154,6 @@ Feature: Update of relations by osm2pgsql r1 Ttype=boundary,boundary=administrative,name=Foo,country_code=ch,admin_level=2 Mw1@ """ Then place contains - | object | country_code | name+name:de | name+name | + | object | addr+country | name+name:de | name+name | | R1 | ch | Schweiz | Foo | diff --git a/test/bdd/steps/db_ops.py b/test/bdd/steps/db_ops.py index df1d1688..30c216a5 100644 --- a/test/bdd/steps/db_ops.py +++ b/test/bdd/steps/db_ops.py @@ -8,7 +8,7 @@ import psycopg2.extras class PlaceColumn: def __init__(self, context, force_name): - self.columns = { 'admin_level' : 100} + self.columns = { 'admin_level' : 15} self.force_name = force_name self.context = context self.geometry = None @@ -20,9 +20,10 @@ class PlaceColumn: self.add_hstore('name', key[5:], value) elif key.startswith('extra+'): self.add_hstore('extratags', key[6:], value) + elif key.startswith('addr+'): + self.add_hstore('address', key[5:], value) else: - assert_in(key, ('class', 'type', 'street', 'addr_place', - 'isin', 'postcode')) + assert_in(key, ('class', 'type')) self.columns[key] = None if value == '' else value def set_key_name(self, value): @@ -39,10 +40,24 @@ class PlaceColumn: self.columns['admin_level'] = int(value) def set_key_housenr(self, value): - self.columns['housenumber'] = None if value == '' else value + if value: + self.add_hstore('address', 'housenumber', value) + + def set_key_postcode(self, value): + if value: + self.add_hstore('address', 'postcode', value) + + def set_key_street(self, value): + if value: + self.add_hstore('address', 'street', value) + + def set_key_addr_place(self, value): + if value: + self.add_hstore('address', 'place', value) def set_key_country(self, value): - self.columns['country_code'] = None if value == '' else value + if value: + self.add_hstore('address', 'country', value) def set_key_geometry(self, value): self.geometry = self.context.osm.parse_geometry(value, self.context.scene) @@ -74,6 +89,47 @@ class PlaceColumn: self.geometry) cursor.execute(query, list(self.columns.values())) +class LazyFmt(object): + + def __init__(self, fmtstr, *args): + self.fmt = fmtstr + self.args = args + + def __str__(self): + return self.fmt % self.args + +class PlaceObjName(object): + + def __init__(self, placeid, conn): + self.pid = placeid + self.conn = conn + + def __str__(self): + if self.pid is None: + return "" + + cur = self.conn.cursor() + cur.execute("""SELECT osm_type, osm_id, class + FROM placex WHERE place_id = %s""", + (self.pid, )) + eq_(1, cur.rowcount, "No entry found for place id %s" % self.pid) + + return "%s%s:%s" % cur.fetchone() + +def compare_place_id(expected, result, column, context): + if expected == '0': + eq_(0, result, + LazyFmt("Bad place id in column %s. Expected: 0, got: %s.", + column, PlaceObjName(result, context.db))) + elif expected == '-': + assert_is_none(result, + LazyFmt("bad place id in column %s: %s.", + column, PlaceObjName(result, context.db))) + else: + eq_(NominatimID(expected).get_place_id(context.db.cursor()), result, + LazyFmt("Bad place id in column %s. Expected: %s, got: %s.", + column, expected, PlaceObjName(result, context.db))) + class NominatimID: """ Splits a unique identifier for places into its components. As place_ids cannot be used for testing, we use a unique @@ -223,15 +279,11 @@ def import_and_index_data_from_place_table(context): cur = context.db.cursor() cur.execute( """insert into placex (osm_type, osm_id, class, type, name, admin_level, - housenumber, street, addr_place, isin, postcode, country_code, extratags, - geometry) + address, extratags, geometry) select * from place where not (class='place' and type='houses' and osm_type='W')""") cur.execute( - """insert into location_property_osmline - (osm_id, interpolationtype, street, addr_place, - postcode, calculated_country_code, linegeo) - SELECT osm_id, housenumber, street, addr_place, - postcode, country_code, geometry from place + """insert into location_property_osmline (osm_id, address, linegeo) + SELECT osm_id, address, geometry from place WHERE class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'""") context.db.commit() @@ -302,14 +354,16 @@ def check_placex_contents(context, exact): eq_(res['name'][name], row[h]) elif h.startswith('extratags+'): eq_(res['extratags'][h[10:]], row[h]) - elif h in ('linked_place_id', 'parent_place_id'): - if row[h] == '0': - eq_(0, res[h]) - elif row[h] == '-': - assert_is_none(res[h]) + elif h.startswith('addr+'): + if row[h] == '-': + if res['address'] is not None: + assert_not_in(h[5:], res['address']) else: - eq_(NominatimID(row[h]).get_place_id(context.db.cursor()), - res[h]) + assert_in(h[5:], res['address'], "column " + h) + assert_equals(res['address'][h[5:]], row[h], + "column %s" % h) + elif h in ('linked_place_id', 'parent_place_id'): + compare_place_id(row[h], res[h], h, context) else: assert_db_column(res, h, row[h], context) @@ -338,7 +392,7 @@ def check_placex_contents(context, exact): expected_content.add((res['osm_type'], res['osm_id'], res['class'])) for h in row.headings: msg = "%s: %s" % (row['object'], h) - if h in ('name', 'extratags'): + if h in ('name', 'extratags', 'address'): if row[h] == '-': assert_is_none(res[h], msg) else: @@ -348,14 +402,14 @@ def check_placex_contents(context, exact): assert_equals(res['name'][h[5:]], row[h], msg) elif h.startswith('extratags+'): assert_equals(res['extratags'][h[10:]], row[h], msg) - elif h in ('linked_place_id', 'parent_place_id'): - if row[h] == '0': - assert_equals(0, res[h], msg) - elif row[h] == '-': - assert_is_none(res[h], msg) + elif h.startswith('addr+'): + if row[h] == '-': + if res['address'] is not None: + assert_not_in(h[5:], res['address']) else: - assert_equals(NominatimID(row[h]).get_place_id(context.db.cursor()), - res[h], msg) + assert_equals(res['address'][h[5:]], row[h], msg) + elif h in ('linked_place_id', 'parent_place_id'): + compare_place_id(row[h], res[h], h, context) else: assert_db_column(res, h, row[h], context) @@ -384,7 +438,8 @@ def check_search_name_contents(context): FROM word, (SELECT unnest(%s) as term) t WHERE word_token = make_standard_name(t.term)""", (terms,)) - ok_(subcur.rowcount >= len(terms)) + ok_(subcur.rowcount >= len(terms), + "No word entry found for " + row[h]) for wid in subcur: assert_in(wid[0], res[h], "Missing term for %s/%s: %s" % (pid, h, wid[1])) @@ -446,13 +501,7 @@ def check_location_property_osmline(context, oid, neg): if h in ('start', 'end'): continue elif h == 'parent_place_id': - if row[h] == '0': - eq_(0, res[h]) - elif row[h] == '-': - assert_is_none(res[h]) - else: - eq_(NominatimID(row[h]).get_place_id(context.db.cursor()), - res[h]) + compare_place_id(row[h], res[h], h, context) else: assert_db_column(res, h, row[h], context) diff --git a/test/bdd/steps/osm_data.py b/test/bdd/steps/osm_data.py index d0d8d892..f56a106a 100644 --- a/test/bdd/steps/osm_data.py +++ b/test/bdd/steps/osm_data.py @@ -79,14 +79,10 @@ def update_from_osm_file(context): cur = context.db.cursor() cur.execute("""insert into placex (osm_type, osm_id, class, type, name, - admin_level, housenumber, street, addr_place, isin, postcode, - country_code, extratags, geometry) select * from place""") + admin_level, address, extratags, geometry) select * from place""") cur.execute( - """insert into location_property_osmline - (osm_id, interpolationtype, street, addr_place, - postcode, calculated_country_code, linegeo) - SELECT osm_id, housenumber, street, addr_place, - postcode, country_code, geometry from place + """insert into location_property_osmline (osm_id, address, linegeo) + SELECT osm_id, address, geometry from place WHERE class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'""") context.db.commit() diff --git a/utils/setup.php b/utils/setup.php index 87c1dd07..0814794f 100755 --- a/utils/setup.php +++ b/utils/setup.php @@ -186,7 +186,7 @@ if ($aCMDResult['import-data'] || $aCMDResult['all']) { passthruCheckReturn($osm2pgsql); $oDB =& getDB(); - if (!chksql($oDB->getRow('select * from place limit 1'))) { + if (!$aCMDResult['ignore-errors'] && !chksql($oDB->getRow('select * from place limit 1'))) { fail('No Data'); } } @@ -365,8 +365,8 @@ if ($aCMDResult['load-data'] || $aCMDResult['all']) { for ($i = 0; $i < $iLoadThreads; $i++) { $aDBInstances[$i] =& getDB(true); $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, '; - $sSQL .= 'housenumber, street, addr_place, isin, postcode, country_code, extratags, '; - $sSQL .= 'geometry) select * from place where osm_id % '.$iLoadThreads.' = '.$i; + $sSQL .= ' address, extratags, geometry) '; + $sSQL .= 'select * from place where osm_id % '.$iLoadThreads.' = '.$i; $sSQL .= " and not (class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString')"; if ($aCMDResult['verbose']) echo "$sSQL\n"; if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection)); @@ -374,10 +374,8 @@ if ($aCMDResult['load-data'] || $aCMDResult['all']) { // last thread for interpolation lines $aDBInstances[$iLoadThreads] =& getDB(true); $sSQL = 'insert into location_property_osmline'; - $sSQL .= ' (osm_id, interpolationtype, street, addr_place,'; - $sSQL .= ' postcode, calculated_country_code, linegeo)'; - $sSQL .= ' SELECT osm_id, housenumber, street, addr_place,'; - $sSQL .= ' postcode, country_code, geometry from place where '; + $sSQL .= ' (osm_id, address, linegeo)'; + $sSQL .= ' SELECT osm_id, address, geometry from place where '; $sSQL .= "class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'"; if ($aCMDResult['verbose']) echo "$sSQL\n"; if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection)); @@ -474,16 +472,16 @@ if ($aCMDResult['calculate-postcodes'] || $aCMDResult['all']) { $bDidSomething = true; $oDB =& getDB(); if (!pg_query($oDB->connection, 'DELETE from placex where osm_type=\'P\'')) fail(pg_last_error($oDB->connection)); - $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) "; - $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,calculated_country_code,"; - $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from (select calculated_country_code,postcode,"; + $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,country_code,geometry) "; + $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,country_code,"; + $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from (select country_code,postcode,"; $sSQL .= "avg(st_x(st_centroid(geometry))) as x,avg(st_y(st_centroid(geometry))) as y "; - $sSQL .= "from placex where postcode is not null group by calculated_country_code,postcode) as x "; + $sSQL .= "from placex where postcode is not null group by country_code,postcode) as x "; $sSQL .= "where ST_Point(x,y) is not null"; if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection)); if (CONST_Use_Extra_US_Postcodes) { - $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) "; + $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,country_code,geometry) "; $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,'us',"; $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from us_postcode"; if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection)); diff --git a/website/deletable.php b/website/deletable.php index 531bdadb..95000032 100755 --- a/website/deletable.php +++ b/website/deletable.php @@ -10,7 +10,7 @@ $sOutputFormat = 'html'; $oDB =& getDB(); -$sSQL = "select placex.place_id, calculated_country_code as country_code,"; +$sSQL = "select placex.place_id, country_code,"; $sSQL .= " name->'name' as name, i.* from placex, import_polygon_delete i"; $sSQL .= " where placex.osm_id = i.osm_id and placex.osm_type = i.osm_type"; $sSQL .= " and placex.class = i.class and placex.type = i.type"; diff --git a/website/details.php b/website/details.php index 0025a8ba..7f0a951f 100755 --- a/website/details.php +++ b/website/details.php @@ -83,7 +83,7 @@ $hLog = logStart($oDB, 'details', $_SERVER['QUERY_STRING'], $aLangPrefOrder); // Get the details for this point $sSQL = "SELECT place_id, osm_type, osm_id, class, type, name, admin_level,"; -$sSQL .= " housenumber, street, isin, postcode, calculated_country_code AS country_code,"; +$sSQL .= " housenumber, postcode, country_code,"; $sSQL .= " importance, wikipedia,"; $sSQL .= " to_char(indexed_date, 'YYYY-MM-DD HH24:MI') AS indexed_date,"; $sSQL .= " parent_place_id, ";