mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-03-12 05:44:06 +00:00
Merge pull request #2597 from lonvia/reorganise-interpolations
Reorganise interpolation code
This commit is contained in:
2
.github/workflows/ci-tests.yml
vendored
2
.github/workflows/ci-tests.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
|||||||
ubuntu: [18, 20]
|
ubuntu: [18, 20]
|
||||||
include:
|
include:
|
||||||
- ubuntu: 18
|
- ubuntu: 18
|
||||||
postgresql: 9.5
|
postgresql: 9.6
|
||||||
postgis: 2.5
|
postgis: 2.5
|
||||||
pytest: pytest
|
pytest: pytest
|
||||||
php: 7.2
|
php: 7.2
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ When running the import you may get a version mismatch:
|
|||||||
|
|
||||||
pg_config seems to use bad includes sometimes when multiple versions
|
pg_config seems to use bad includes sometimes when multiple versions
|
||||||
of PostgreSQL are available in the system. Make sure you remove the
|
of PostgreSQL are available in the system. Make sure you remove the
|
||||||
server development libraries (`postgresql-server-dev-9.5` on Ubuntu)
|
server development libraries (`postgresql-server-dev-13` on Ubuntu)
|
||||||
and recompile (`cmake .. && make`).
|
and recompile (`cmake .. && make`).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ For compiling:
|
|||||||
|
|
||||||
For running Nominatim:
|
For running Nominatim:
|
||||||
|
|
||||||
* [PostgreSQL](https://www.postgresql.org) (9.5+ will work, 11+ strongly recommended)
|
* [PostgreSQL](https://www.postgresql.org) (9.6+ will work, 11+ strongly recommended)
|
||||||
* [PostGIS](https://postgis.net) (2.2+ will work, 3.0+ strongly recommended)
|
* [PostGIS](https://postgis.net) (2.2+ will work, 3.0+ strongly recommended)
|
||||||
* [Python 3](https://www.python.org/) (3.6+)
|
* [Python 3](https://www.python.org/) (3.6+)
|
||||||
* [Psycopg2](https://www.psycopg.org) (2.7+)
|
* [Psycopg2](https://www.psycopg.org) (2.7+)
|
||||||
|
|||||||
@@ -348,7 +348,9 @@ class PlaceLookup
|
|||||||
$sSQL .= ' null::text AS extra_place ';
|
$sSQL .= ' null::text AS extra_place ';
|
||||||
$sSQL .= ' FROM (';
|
$sSQL .= ' FROM (';
|
||||||
$sSQL .= ' SELECT place_id, '; // interpolate the Tiger housenumbers here
|
$sSQL .= ' SELECT place_id, '; // interpolate the Tiger housenumbers here
|
||||||
$sSQL .= ' ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) AS centroid, ';
|
$sSQL .= ' CASE WHEN startnumber != endnumber';
|
||||||
|
$sSQL .= ' THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float)';
|
||||||
|
$sSQL .= ' ELSE ST_LineInterpolatePoint(linegeo, 0.5) END AS centroid, ';
|
||||||
$sSQL .= ' parent_place_id, ';
|
$sSQL .= ' parent_place_id, ';
|
||||||
$sSQL .= ' housenumber_for_place';
|
$sSQL .= ' housenumber_for_place';
|
||||||
$sSQL .= ' FROM (';
|
$sSQL .= ' FROM (';
|
||||||
@@ -405,7 +407,7 @@ class PlaceLookup
|
|||||||
$sSQL .= ' CASE '; // interpolate the housenumbers here
|
$sSQL .= ' CASE '; // interpolate the housenumbers here
|
||||||
$sSQL .= ' WHEN startnumber != endnumber ';
|
$sSQL .= ' WHEN startnumber != endnumber ';
|
||||||
$sSQL .= ' THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) ';
|
$sSQL .= ' THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) ';
|
||||||
$sSQL .= ' ELSE ST_LineInterpolatePoint(linegeo, 0.5) ';
|
$sSQL .= ' ELSE linegeo ';
|
||||||
$sSQL .= ' END as centroid, ';
|
$sSQL .= ' END as centroid, ';
|
||||||
$sSQL .= ' parent_place_id, ';
|
$sSQL .= ' parent_place_id, ';
|
||||||
$sSQL .= ' housenumber_for_place ';
|
$sSQL .= ' housenumber_for_place ';
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ class ReverseGeocode
|
|||||||
{
|
{
|
||||||
Debug::newFunction('lookupInterpolation');
|
Debug::newFunction('lookupInterpolation');
|
||||||
$sSQL = 'SELECT place_id, parent_place_id, 30 as rank_search,';
|
$sSQL = 'SELECT place_id, parent_place_id, 30 as rank_search,';
|
||||||
$sSQL .= ' ST_LineLocatePoint(linegeo,'.$sPointSQL.') as fraction,';
|
$sSQL .= ' (endnumber - startnumber) * ST_LineLocatePoint(linegeo,'.$sPointSQL.') as fhnr,';
|
||||||
$sSQL .= ' startnumber, endnumber, interpolationtype,';
|
$sSQL .= ' startnumber, endnumber, step,';
|
||||||
$sSQL .= ' ST_Distance(linegeo,'.$sPointSQL.') as distance';
|
$sSQL .= ' ST_Distance(linegeo,'.$sPointSQL.') as distance';
|
||||||
$sSQL .= ' FROM location_property_osmline';
|
$sSQL .= ' FROM location_property_osmline';
|
||||||
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';
|
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';
|
||||||
@@ -327,9 +327,9 @@ class ReverseGeocode
|
|||||||
&& $this->iMaxRank >= 28
|
&& $this->iMaxRank >= 28
|
||||||
) {
|
) {
|
||||||
$sSQL = 'SELECT place_id,parent_place_id,30 as rank_search,';
|
$sSQL = 'SELECT place_id,parent_place_id,30 as rank_search,';
|
||||||
$sSQL .= 'ST_LineLocatePoint(linegeo,'.$sPointSQL.') as fraction,';
|
$sSQL .= ' (endnumber - startnumber) * ST_LineLocatePoint(linegeo,'.$sPointSQL.') as fhnr,';
|
||||||
$sSQL .= 'ST_distance('.$sPointSQL.', linegeo) as distance,';
|
$sSQL .= ' startnumber, endnumber, step,';
|
||||||
$sSQL .= 'startnumber,endnumber,interpolationtype';
|
$sSQL .= ' ST_Distance('.$sPointSQL.', linegeo) as distance';
|
||||||
$sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$oResult->iId;
|
$sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$oResult->iId;
|
||||||
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, 0.001)';
|
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, 0.001)';
|
||||||
$sSQL .= ' ORDER BY distance ASC limit 1';
|
$sSQL .= ' ORDER BY distance ASC limit 1';
|
||||||
@@ -341,7 +341,11 @@ class ReverseGeocode
|
|||||||
if ($aPlaceTiger) {
|
if ($aPlaceTiger) {
|
||||||
$aPlace = $aPlaceTiger;
|
$aPlace = $aPlaceTiger;
|
||||||
$oResult = new Result($aPlaceTiger['place_id'], Result::TABLE_TIGER);
|
$oResult = new Result($aPlaceTiger['place_id'], Result::TABLE_TIGER);
|
||||||
$oResult->iHouseNumber = closestHouseNumber($aPlaceTiger);
|
$iRndNum = max(0, round($aPlaceTiger['fhnr'] / $aPlaceTiger['step']) * $aPlaceTiger['step']);
|
||||||
|
$oResult->iHouseNumber = $aPlaceTiger['startnumber'] + $iRndNum;
|
||||||
|
if ($oResult->iHouseNumber > $aPlaceTiger['endnumber']) {
|
||||||
|
$oResult->iHouseNumber = $aPlaceTiger['endnumber'];
|
||||||
|
}
|
||||||
$iRankAddress = 30;
|
$iRankAddress = 30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,7 +367,11 @@ class ReverseGeocode
|
|||||||
|
|
||||||
if ($aHouse) {
|
if ($aHouse) {
|
||||||
$oResult = new Result($aHouse['place_id'], Result::TABLE_OSMLINE);
|
$oResult = new Result($aHouse['place_id'], Result::TABLE_OSMLINE);
|
||||||
$oResult->iHouseNumber = closestHouseNumber($aHouse);
|
$iRndNum = max(0, round($aHouse['fhnr'] / $aHouse['step']) * $aHouse['step']);
|
||||||
|
$oResult->iHouseNumber = $aHouse['startnumber'] + $iRndNum;
|
||||||
|
if ($oResult->iHouseNumber > $aHouse['endnumber']) {
|
||||||
|
$oResult->iHouseNumber = $aHouse['endnumber'];
|
||||||
|
}
|
||||||
$aPlace = $aHouse;
|
$aPlace = $aHouse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -769,18 +769,9 @@ class SearchDescription
|
|||||||
// if nothing found, search in the interpolation line table
|
// if nothing found, search in the interpolation line table
|
||||||
$sSQL = 'SELECT distinct place_id FROM location_property_osmline';
|
$sSQL = 'SELECT distinct place_id FROM location_property_osmline';
|
||||||
$sSQL .= ' WHERE startnumber is not NULL';
|
$sSQL .= ' WHERE startnumber is not NULL';
|
||||||
$sSQL .= ' AND parent_place_id in ('.$sRoadPlaceIDs.') AND (';
|
$sSQL .= ' and parent_place_id in ('.$sRoadPlaceIDs.')';
|
||||||
if ($iHousenumber % 2 == 0) {
|
$sSQL .= ' and ('.$iHousenumber.' - startnumber) % step = 0';
|
||||||
// If housenumber is even, look for housenumber in streets
|
$sSQL .= ' and '.$iHousenumber.' between startnumber and endnumber';
|
||||||
// with interpolationtype even or all.
|
|
||||||
$sSQL .= "interpolationtype='even'";
|
|
||||||
} else {
|
|
||||||
// Else look for housenumber with interpolationtype odd or all.
|
|
||||||
$sSQL .= "interpolationtype='odd'";
|
|
||||||
}
|
|
||||||
$sSQL .= " or interpolationtype='all') and ";
|
|
||||||
$sSQL .= $iHousenumber.'>=startnumber and ';
|
|
||||||
$sSQL .= $iHousenumber.'<=endnumber';
|
|
||||||
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
|
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
@@ -795,15 +786,9 @@ class SearchDescription
|
|||||||
// If nothing found then search in Tiger data (location_property_tiger)
|
// If nothing found then search in Tiger data (location_property_tiger)
|
||||||
if (CONST_Use_US_Tiger_Data && $sRoadPlaceIDs && $bIsIntHouseNumber && empty($aResults)) {
|
if (CONST_Use_US_Tiger_Data && $sRoadPlaceIDs && $bIsIntHouseNumber && empty($aResults)) {
|
||||||
$sSQL = 'SELECT place_id FROM location_property_tiger';
|
$sSQL = 'SELECT place_id FROM location_property_tiger';
|
||||||
$sSQL .= ' WHERE parent_place_id in ('.$sRoadPlaceIDs.') and (';
|
$sSQL .= ' WHERE parent_place_id in ('.$sRoadPlaceIDs.')';
|
||||||
if ($iHousenumber % 2 == 0) {
|
$sSQL .= ' and ('.$iHousenumber.' - startnumber) % step = 0';
|
||||||
$sSQL .= "interpolationtype='even'";
|
$sSQL .= ' and '.$iHousenumber.' between startnumber and endnumber';
|
||||||
} else {
|
|
||||||
$sSQL .= "interpolationtype='odd'";
|
|
||||||
}
|
|
||||||
$sSQL .= " or interpolationtype='all') and ";
|
|
||||||
$sSQL .= $iHousenumber.'>=startnumber and ';
|
|
||||||
$sSQL .= $iHousenumber.'<=endnumber';
|
|
||||||
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
|
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
|
||||||
|
|
||||||
Debug::printSQL($sSQL);
|
Debug::printSQL($sSQL);
|
||||||
|
|||||||
@@ -206,26 +206,6 @@ function parseLatLon($sQuery)
|
|||||||
return array($sFound, $fQueryLat, $fQueryLon);
|
return array($sFound, $fQueryLat, $fQueryLon);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closestHouseNumber($aRow)
|
|
||||||
{
|
|
||||||
$fHouse = $aRow['startnumber']
|
|
||||||
+ ($aRow['endnumber'] - $aRow['startnumber']) * $aRow['fraction'];
|
|
||||||
|
|
||||||
switch ($aRow['interpolationtype']) {
|
|
||||||
case 'odd':
|
|
||||||
$iHn = (int)($fHouse/2) * 2 + 1;
|
|
||||||
break;
|
|
||||||
case 'even':
|
|
||||||
$iHn = (int)(round($fHouse/2)) * 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$iHn = (int)(round($fHouse));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function_exists('array_key_last')) {
|
if (!function_exists('array_key_last')) {
|
||||||
function array_key_last(array $array)
|
function array_key_last(array $array)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,17 +7,6 @@
|
|||||||
|
|
||||||
-- Functions for address interpolation objects in location_property_osmline.
|
-- Functions for address interpolation objects in location_property_osmline.
|
||||||
|
|
||||||
-- Splits the line at the given point and returns the two parts
|
|
||||||
-- in a multilinestring.
|
|
||||||
CREATE OR REPLACE FUNCTION split_line_on_node(line GEOMETRY, point GEOMETRY)
|
|
||||||
RETURNS GEOMETRY
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
RETURN ST_Split(ST_Snap(line, point, 0.0005), point);
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION get_interpolation_address(in_address HSTORE, wayid BIGINT)
|
CREATE OR REPLACE FUNCTION get_interpolation_address(in_address HSTORE, wayid BIGINT)
|
||||||
RETURNS HSTORE
|
RETURNS HSTORE
|
||||||
@@ -64,9 +53,13 @@ BEGIN
|
|||||||
IF parent_place_id is null THEN
|
IF parent_place_id is null THEN
|
||||||
FOR location IN SELECT place_id FROM placex
|
FOR location IN SELECT place_id FROM placex
|
||||||
WHERE ST_DWithin(geom, placex.geometry, 0.001) and placex.rank_search = 26
|
WHERE ST_DWithin(geom, placex.geometry, 0.001) and placex.rank_search = 26
|
||||||
ORDER BY (ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,0))+
|
ORDER BY CASE WHEN ST_GeometryType(geom) = 'ST_Line' THEN
|
||||||
|
(ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,0))+
|
||||||
ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,0.5))+
|
ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,0.5))+
|
||||||
ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,1))) ASC limit 1
|
ST_distance(placex.geometry, ST_LineInterpolatePoint(geom,1)))
|
||||||
|
ELSE ST_distance(placex.geometry, geom) END
|
||||||
|
ASC
|
||||||
|
LIMIT 1
|
||||||
LOOP
|
LOOP
|
||||||
parent_place_id := location.place_id;
|
parent_place_id := location.place_id;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
@@ -82,24 +75,38 @@ $$
|
|||||||
LANGUAGE plpgsql STABLE;
|
LANGUAGE plpgsql STABLE;
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION osmline_reinsert(node_id BIGINT, geom GEOMETRY)
|
CREATE OR REPLACE FUNCTION reinsert_interpolation(way_id BIGINT, addr HSTORE,
|
||||||
RETURNS BOOLEAN
|
geom GEOMETRY)
|
||||||
|
RETURNS INT
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
existingline RECORD;
|
existing BIGINT[];
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT w.id FROM planet_osm_ways w, location_property_osmline p
|
-- Get the existing entry from the interpolation table.
|
||||||
WHERE p.linegeo && geom and p.osm_id = w.id and p.indexed_status = 0
|
SELECT array_agg(place_id) INTO existing
|
||||||
and node_id = any(w.nodes) INTO existingline;
|
FROM location_property_osmline WHERE osm_id = way_id;
|
||||||
|
|
||||||
IF existingline.id is not NULL THEN
|
IF existing IS NULL or array_length(existing, 1) = 0 THEN
|
||||||
DELETE FROM location_property_osmline WHERE osm_id = existingline.id;
|
INSERT INTO location_property_osmline (osm_id, address, linegeo)
|
||||||
INSERT INTO location_property_osmline (osm_id, address, linegeo)
|
VALUES (way_id, addr, geom);
|
||||||
SELECT osm_id, address, geometry FROM place
|
ELSE
|
||||||
WHERE osm_type = 'W' and osm_id = existingline.id;
|
-- Update the interpolation table:
|
||||||
END IF;
|
-- The first entry gets the original data, all other entries
|
||||||
|
-- are removed and will be recreated on indexing.
|
||||||
|
-- (An interpolation can be split up, if it has more than 2 address nodes)
|
||||||
|
UPDATE location_property_osmline
|
||||||
|
SET address = addr,
|
||||||
|
linegeo = geom,
|
||||||
|
startnumber = null,
|
||||||
|
indexed_status = 1
|
||||||
|
WHERE place_id = existing[1];
|
||||||
|
IF array_length(existing, 1) > 1 THEN
|
||||||
|
DELETE FROM location_property_osmline
|
||||||
|
WHERE place_id = any(existing[2:]);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
RETURN true;
|
RETURN 1;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql;
|
LANGUAGE plpgsql;
|
||||||
@@ -114,8 +121,10 @@ BEGIN
|
|||||||
|
|
||||||
IF NEW.indexed_status IS NULL THEN
|
IF NEW.indexed_status IS NULL THEN
|
||||||
IF NEW.address is NULL OR NOT NEW.address ? 'interpolation'
|
IF NEW.address is NULL OR NOT NEW.address ? 'interpolation'
|
||||||
OR NEW.address->'interpolation' NOT IN ('odd', 'even', 'all') THEN
|
OR NOT (NEW.address->'interpolation' in ('odd', 'even', 'all')
|
||||||
-- other interpolation types than odd/even/all (e.g. numeric ones) are not supported
|
or NEW.address->'interpolation' similar to '[1-9]')
|
||||||
|
THEN
|
||||||
|
-- alphabetic interpolation is not supported
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
@@ -136,18 +145,20 @@ CREATE OR REPLACE FUNCTION osmline_update()
|
|||||||
RETURNS TRIGGER
|
RETURNS TRIGGER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
place_centroid GEOMETRY;
|
|
||||||
waynodes BIGINT[];
|
waynodes BIGINT[];
|
||||||
prevnode RECORD;
|
prevnode RECORD;
|
||||||
nextnode RECORD;
|
nextnode RECORD;
|
||||||
startnumber INTEGER;
|
startnumber INTEGER;
|
||||||
endnumber INTEGER;
|
endnumber INTEGER;
|
||||||
housenum INTEGER;
|
newstart INTEGER;
|
||||||
|
newend INTEGER;
|
||||||
|
moddiff SMALLINT;
|
||||||
linegeo GEOMETRY;
|
linegeo GEOMETRY;
|
||||||
splitline GEOMETRY;
|
splitline GEOMETRY;
|
||||||
sectiongeo GEOMETRY;
|
sectiongeo GEOMETRY;
|
||||||
interpol_postcode TEXT;
|
interpol_postcode TEXT;
|
||||||
postcode TEXT;
|
postcode TEXT;
|
||||||
|
stepmod SMALLINT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- deferred delete
|
-- deferred delete
|
||||||
IF OLD.indexed_status = 100 THEN
|
IF OLD.indexed_status = 100 THEN
|
||||||
@@ -159,107 +170,139 @@ BEGIN
|
|||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
NEW.interpolationtype = NEW.address->'interpolation';
|
NEW.parent_place_id := get_interpolation_parent(NEW.token_info, NEW.partition,
|
||||||
|
ST_PointOnSurface(NEW.linegeo),
|
||||||
place_centroid := ST_PointOnSurface(NEW.linegeo);
|
NEW.linegeo);
|
||||||
NEW.parent_place_id = get_interpolation_parent(NEW.token_info, NEW.partition,
|
|
||||||
place_centroid, NEW.linegeo);
|
|
||||||
|
|
||||||
interpol_postcode := token_normalized_postcode(NEW.address->'postcode');
|
interpol_postcode := token_normalized_postcode(NEW.address->'postcode');
|
||||||
|
|
||||||
NEW.token_info := token_strip_info(NEW.token_info);
|
NEW.token_info := token_strip_info(NEW.token_info);
|
||||||
IF NEW.address ? '_inherited' THEN
|
IF NEW.address ? '_inherited' THEN
|
||||||
NEW.address := hstore('interpolation', NEW.interpolationtype);
|
NEW.address := hstore('interpolation', NEW.address->'interpolation');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- if the line was newly inserted, split the line as necessary
|
-- If the line was newly inserted, split the line as necessary.
|
||||||
IF OLD.indexed_status = 1 THEN
|
IF OLD.indexed_status = 1 THEN
|
||||||
select nodes from planet_osm_ways where id = NEW.osm_id INTO waynodes;
|
IF NEW.address->'interpolation' in ('odd', 'even') THEN
|
||||||
|
NEW.step := 2;
|
||||||
|
stepmod := CASE WHEN NEW.address->'interpolation' = 'odd' THEN 1 ELSE 0 END;
|
||||||
|
ELSE
|
||||||
|
NEW.step := CASE WHEN NEW.address->'interpolation' = 'all'
|
||||||
|
THEN 1
|
||||||
|
ELSE (NEW.address->'interpolation')::SMALLINT END;
|
||||||
|
stepmod := NULL;
|
||||||
|
END IF;
|
||||||
|
|
||||||
IF array_upper(waynodes, 1) IS NULL THEN
|
SELECT nodes INTO waynodes
|
||||||
RETURN NEW;
|
FROM planet_osm_ways WHERE id = NEW.osm_id;
|
||||||
|
|
||||||
|
IF array_upper(waynodes, 1) IS NULL THEN
|
||||||
|
RETURN NEW;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
linegeo := null;
|
||||||
|
SELECT null::integer as hnr INTO prevnode;
|
||||||
|
|
||||||
|
-- Go through all nodes on the interpolation line that have a housenumber.
|
||||||
|
FOR nextnode IN
|
||||||
|
SELECT DISTINCT ON (nodeidpos)
|
||||||
|
osm_id, address, geometry,
|
||||||
|
substring(address->'housenumber','[0-9]+')::integer as hnr
|
||||||
|
FROM placex, generate_series(1, array_upper(waynodes, 1)) nodeidpos
|
||||||
|
WHERE osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT
|
||||||
|
and address is not NULL and address ? 'housenumber'
|
||||||
|
ORDER BY nodeidpos
|
||||||
|
LOOP
|
||||||
|
RAISE WARNING 'processing point % (%)', nextnode.hnr, ST_AsText(nextnode.geometry);
|
||||||
|
IF linegeo is null THEN
|
||||||
|
linegeo := NEW.linegeo;
|
||||||
|
ELSE
|
||||||
|
splitline := ST_Split(ST_Snap(linegeo, nextnode.geometry, 0.0005), nextnode.geometry);
|
||||||
|
sectiongeo := ST_GeometryN(splitline, 1);
|
||||||
|
linegeo := ST_GeometryN(splitline, 2);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
linegeo := NEW.linegeo;
|
IF prevnode.hnr is not null
|
||||||
startnumber := NULL;
|
-- Check if there are housenumbers to interpolate between the
|
||||||
|
-- regularly mapped housenumbers.
|
||||||
FOR nodeidpos in 1..array_upper(waynodes, 1) LOOP
|
-- (Conveniently also fails if one of the house numbers is not a number.)
|
||||||
|
and abs(prevnode.hnr - nextnode.hnr) > NEW.step
|
||||||
select osm_id, address, geometry
|
THEN
|
||||||
from place where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT
|
IF prevnode.hnr < nextnode.hnr THEN
|
||||||
and address is not NULL and address ? 'housenumber' limit 1 INTO nextnode;
|
startnumber := prevnode.hnr;
|
||||||
--RAISE NOTICE 'Nextnode.place_id: %s', nextnode.place_id;
|
endnumber := nextnode.hnr;
|
||||||
IF nextnode.osm_id IS NOT NULL THEN
|
ELSE
|
||||||
--RAISE NOTICE 'place_id is not null';
|
startnumber := nextnode.hnr;
|
||||||
IF nodeidpos > 1 and nodeidpos < array_upper(waynodes, 1) THEN
|
endnumber := prevnode.hnr;
|
||||||
-- Make sure that the point is actually on the line. That might
|
sectiongeo := ST_Reverse(sectiongeo);
|
||||||
-- 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 IS NOT NULL AND endnumber IS NOT NULL
|
|
||||||
AND startnumber != endnumber
|
|
||||||
AND ST_GeometryType(sectiongeo) = 'ST_LineString' THEN
|
|
||||||
|
|
||||||
IF (startnumber > endnumber) THEN
|
|
||||||
housenum := endnumber;
|
|
||||||
endnumber := startnumber;
|
|
||||||
startnumber := housenum;
|
|
||||||
sectiongeo := ST_Reverse(sectiongeo);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- determine postcode
|
|
||||||
postcode := coalesce(interpol_postcode,
|
|
||||||
token_normalized_postcode(prevnode.address->'postcode'),
|
|
||||||
token_normalized_postcode(nextnode.address->'postcode'),
|
|
||||||
postcode);
|
|
||||||
|
|
||||||
IF postcode is NULL THEN
|
|
||||||
SELECT token_normalized_postcode(placex.postcode)
|
|
||||||
FROM placex WHERE place_id = NEW.parent_place_id INTO postcode;
|
|
||||||
END IF;
|
|
||||||
IF postcode is NULL THEN
|
|
||||||
postcode := get_nearest_postcode(NEW.country_code, nextnode.geometry);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF NEW.startnumber IS NULL THEN
|
|
||||||
NEW.startnumber := startnumber;
|
|
||||||
NEW.endnumber := endnumber;
|
|
||||||
NEW.linegeo := sectiongeo;
|
|
||||||
NEW.postcode := 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, postcode,
|
|
||||||
NEW.country_code, NEW.geometry_sector, 0);
|
|
||||||
END IF;
|
|
||||||
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;
|
|
||||||
|
|
||||||
startnumber := substring(nextnode.address->'housenumber','[0-9]+')::integer;
|
|
||||||
prevnode := nextnode;
|
|
||||||
END IF;
|
END IF;
|
||||||
END LOOP;
|
|
||||||
|
-- Adjust the interpolation, so that only inner housenumbers
|
||||||
|
-- are taken into account.
|
||||||
|
IF stepmod is null THEN
|
||||||
|
newstart := startnumber + NEW.step;
|
||||||
|
ELSE
|
||||||
|
newstart := startnumber + 1;
|
||||||
|
moddiff := newstart % NEW.step - stepmod;
|
||||||
|
IF moddiff < 0 THEN
|
||||||
|
newstart := newstart + (NEW.step + moddiff);
|
||||||
|
ELSE
|
||||||
|
newstart := newstart + moddiff;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
newend := newstart + ((endnumber - 1 - newstart) / NEW.step) * NEW.step;
|
||||||
|
|
||||||
|
-- If newstart and newend are the same, then this returns a point.
|
||||||
|
sectiongeo := ST_LineSubstring(sectiongeo,
|
||||||
|
(newstart - startnumber)::float / (endnumber - startnumber)::float,
|
||||||
|
(newend - startnumber)::float / (endnumber - startnumber)::float);
|
||||||
|
startnumber := newstart;
|
||||||
|
endnumber := newend;
|
||||||
|
|
||||||
|
-- determine postcode
|
||||||
|
postcode := coalesce(interpol_postcode,
|
||||||
|
token_normalized_postcode(prevnode.address->'postcode'),
|
||||||
|
token_normalized_postcode(nextnode.address->'postcode'),
|
||||||
|
postcode);
|
||||||
|
IF postcode is NULL THEN
|
||||||
|
SELECT token_normalized_postcode(placex.postcode)
|
||||||
|
FROM placex WHERE place_id = NEW.parent_place_id INTO postcode;
|
||||||
|
END IF;
|
||||||
|
IF postcode is NULL THEN
|
||||||
|
postcode := get_nearest_postcode(NEW.country_code, nextnode.geometry);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Add the interpolation. If this is the first segment, just modify
|
||||||
|
-- the interpolation to be inserted, otherwise add an additional one
|
||||||
|
-- (marking it indexed already).
|
||||||
|
IF NEW.startnumber IS NULL THEN
|
||||||
|
NEW.startnumber := startnumber;
|
||||||
|
NEW.endnumber := endnumber;
|
||||||
|
NEW.linegeo := sectiongeo;
|
||||||
|
NEW.postcode := postcode;
|
||||||
|
ELSE
|
||||||
|
INSERT INTO location_property_osmline
|
||||||
|
(linegeo, partition, osm_id, parent_place_id,
|
||||||
|
startnumber, endnumber, step,
|
||||||
|
address, postcode, country_code,
|
||||||
|
geometry_sector, indexed_status)
|
||||||
|
VALUES (sectiongeo, NEW.partition, NEW.osm_id, NEW.parent_place_id,
|
||||||
|
startnumber, endnumber, NEW.step,
|
||||||
|
NEW.address, postcode,
|
||||||
|
NEW.country_code, NEW.geometry_sector, 0);
|
||||||
|
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;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
prevnode := nextnode;
|
||||||
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- marking descendants for reparenting is not needed, because there are
|
|
||||||
-- actually no descendants for interpolation lines
|
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ DECLARE
|
|||||||
country RECORD;
|
country RECORD;
|
||||||
existing RECORD;
|
existing RECORD;
|
||||||
existingplacex RECORD;
|
existingplacex RECORD;
|
||||||
existingline RECORD;
|
existingline BIGINT[];
|
||||||
result BOOLEAN;
|
interpol RECORD;
|
||||||
BEGIN
|
BEGIN
|
||||||
{% if debug %}
|
{% if debug %}
|
||||||
RAISE WARNING 'place_insert: % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,st_area(NEW.geometry);
|
RAISE WARNING 'place_insert: % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,st_area(NEW.geometry);
|
||||||
@@ -57,19 +57,7 @@ BEGIN
|
|||||||
IF NEW.class='place' and NEW.type='houses'
|
IF NEW.class='place' and NEW.type='houses'
|
||||||
and NEW.osm_type='W' and ST_GeometryType(NEW.geometry) = 'ST_LineString'
|
and NEW.osm_type='W' and ST_GeometryType(NEW.geometry) = 'ST_LineString'
|
||||||
THEN
|
THEN
|
||||||
-- Get the existing entry from the interpolation table.
|
PERFORM reinsert_interpolation(NEW.osm_id, NEW.address, NEW.geometry);
|
||||||
SELECT * INTO existingline
|
|
||||||
FROM location_property_osmline WHERE osm_id = NEW.osm_id;
|
|
||||||
|
|
||||||
-- Update the interpolation table:
|
|
||||||
-- delete all old interpolation lines with same osm_id
|
|
||||||
-- and insert the new one(s) (they can be split up, if they have > 2 nodes)
|
|
||||||
IF existingline.osm_id IS NOT NULL THEN
|
|
||||||
DELETE FROM location_property_osmline where osm_id = NEW.osm_id;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
INSERT INTO location_property_osmline (osm_id, address, linegeo)
|
|
||||||
VALUES (NEW.osm_id, NEW.address, NEW.geometry);
|
|
||||||
|
|
||||||
-- Now invalidate all address nodes on the line.
|
-- Now invalidate all address nodes on the line.
|
||||||
-- They get their parent from the interpolation.
|
-- They get their parent from the interpolation.
|
||||||
@@ -156,6 +144,28 @@ BEGIN
|
|||||||
RETURN null;
|
RETURN null;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
-- If an address node is part of a interpolation line and changes or is
|
||||||
|
-- newly inserted (happens when the node already existed but now gets address
|
||||||
|
-- information), then mark the interpolation 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 coalesce(existing.address, ''::hstore) != coalesce(NEW.address, ''::hstore)
|
||||||
|
THEN
|
||||||
|
FOR interpol IN
|
||||||
|
SELECT DISTINCT osm_id, address, geometry FROM place, planet_osm_ways w
|
||||||
|
WHERE NEW.geometry && place.geometry
|
||||||
|
and place.osm_type = 'W'
|
||||||
|
and exists (SELECT * FROM location_property_osmline
|
||||||
|
WHERE osm_id = place.osm_id
|
||||||
|
and indexed_status in (0, 2))
|
||||||
|
and w.id = place.osm_id and NEW.osm_id = any (w.nodes)
|
||||||
|
LOOP
|
||||||
|
PERFORM reinsert_interpolation(interpol.osm_id, interpol.address,
|
||||||
|
interpol.geometry);
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Get the existing placex entry.
|
-- Get the existing placex entry.
|
||||||
SELECT * INTO existingplacex
|
SELECT * INTO existingplacex
|
||||||
FROM placex
|
FROM placex
|
||||||
@@ -278,16 +288,6 @@ BEGIN
|
|||||||
geometry = NEW.geometry
|
geometry = NEW.geometry
|
||||||
WHERE place_id = existingplacex.place_id;
|
WHERE place_id = existingplacex.place_id;
|
||||||
|
|
||||||
-- If an address node which is part of a interpolation line changes
|
|
||||||
-- 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 coalesce(existing.address, ''::hstore) != coalesce(NEW.address, ''::hstore)
|
|
||||||
THEN
|
|
||||||
result:= osmline_reinsert(NEW.osm_id, NEW.geometry);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Invalidate linked places: they potentially get a new name and addresses.
|
-- Invalidate linked places: they potentially get a new name and addresses.
|
||||||
IF existingplacex.linked_place_id is not NULL THEN
|
IF existingplacex.linked_place_id is not NULL THEN
|
||||||
UPDATE placex x
|
UPDATE placex x
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ DECLARE
|
|||||||
BEGIN
|
BEGIN
|
||||||
-- For POI nodes, check if the address should be derived from a surrounding
|
-- For POI nodes, check if the address should be derived from a surrounding
|
||||||
-- building.
|
-- building.
|
||||||
IF p.rank_search < 30 OR p.osm_type != 'N' OR p.address is not null THEN
|
IF p.rank_search < 30 OR p.osm_type != 'N' THEN
|
||||||
result.address := p.address;
|
result.address := p.address;
|
||||||
ELSE
|
ELSEIF p.address is null THEN
|
||||||
-- The additional && condition works around the misguided query
|
-- The additional && condition works around the misguided query
|
||||||
-- planner of postgis 3.0.
|
-- planner of postgis 3.0.
|
||||||
SELECT placex.address || hstore('_inherited', '') INTO result.address
|
SELECT placex.address || hstore('_inherited', '') INTO result.address
|
||||||
@@ -42,6 +42,20 @@ BEGIN
|
|||||||
and (placex.address ? 'housenumber' or placex.address ? 'street' or placex.address ? 'place')
|
and (placex.address ? 'housenumber' or placex.address ? 'street' or placex.address ? 'place')
|
||||||
and rank_search = 30 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon')
|
and rank_search = 30 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon')
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
ELSE
|
||||||
|
result.address := p.address;
|
||||||
|
-- See if we can inherit addtional address tags from an interpolation.
|
||||||
|
-- These will become permanent.
|
||||||
|
FOR location IN
|
||||||
|
SELECT (address - 'interpolation'::text - 'housenumber'::text) as address
|
||||||
|
FROM place, planet_osm_ways w
|
||||||
|
WHERE place.osm_type = 'W' and place.address ? 'interpolation'
|
||||||
|
and place.geometry && p.geometry
|
||||||
|
and place.osm_id = w.id
|
||||||
|
and p.osm_id = any(w.nodes)
|
||||||
|
LOOP
|
||||||
|
result.address := location.address || result.address;
|
||||||
|
END LOOP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
result.address := result.address - '_unlisted_place'::TEXT;
|
result.address := result.address - '_unlisted_place'::TEXT;
|
||||||
@@ -131,18 +145,6 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF parent_place_id is null and poi_osm_type = 'N' THEN
|
IF parent_place_id is null and poi_osm_type = 'N' THEN
|
||||||
-- Is this node part of an interpolation?
|
|
||||||
FOR location IN
|
|
||||||
SELECT q.parent_place_id
|
|
||||||
FROM location_property_osmline q, planet_osm_ways x
|
|
||||||
WHERE q.linegeo && bbox and x.id = q.osm_id
|
|
||||||
and poi_osm_id = any(x.nodes)
|
|
||||||
LIMIT 1
|
|
||||||
LOOP
|
|
||||||
{% if debug %}RAISE WARNING 'Get parent from interpolation: %', location.parent_place_id;{% endif %}
|
|
||||||
RETURN location.parent_place_id;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
FOR location IN
|
FOR location IN
|
||||||
SELECT p.place_id, p.osm_id, p.rank_search, p.address,
|
SELECT p.place_id, p.osm_id, p.rank_search, p.address,
|
||||||
coalesce(p.centroid, ST_Centroid(p.geometry)) as centroid
|
coalesce(p.centroid, ST_Centroid(p.geometry)) as centroid
|
||||||
@@ -626,10 +628,7 @@ BEGIN
|
|||||||
{% if not disable_diff_updates %}
|
{% if not disable_diff_updates %}
|
||||||
-- The following is not needed until doing diff updates, and slows the main index process down
|
-- The following is not needed until doing diff updates, and slows the main index process down
|
||||||
|
|
||||||
IF NEW.osm_type = 'N' and NEW.rank_search > 28 THEN
|
IF NEW.rank_address > 0 THEN
|
||||||
-- might be part of an interpolation
|
|
||||||
result := osmline_reinsert(NEW.osm_id, NEW.geometry);
|
|
||||||
ELSEIF NEW.rank_address > 0 THEN
|
|
||||||
IF (ST_GeometryType(NEW.geometry) in ('ST_Polygon','ST_MultiPolygon') AND ST_IsValid(NEW.geometry)) THEN
|
IF (ST_GeometryType(NEW.geometry) in ('ST_Polygon','ST_MultiPolygon') AND ST_IsValid(NEW.geometry)) THEN
|
||||||
-- Performance: We just can't handle re-indexing for country level changes
|
-- Performance: We just can't handle re-indexing for country level changes
|
||||||
IF st_area(NEW.geometry) < 1 THEN
|
IF st_area(NEW.geometry) < 1 THEN
|
||||||
@@ -656,7 +655,7 @@ BEGIN
|
|||||||
-- roads may cause reparenting for >27 rank places
|
-- roads may cause reparenting for >27 rank places
|
||||||
update placex set indexed_status = 2 where indexed_status = 0 and rank_search > NEW.rank_search and ST_DWithin(placex.geometry, NEW.geometry, diameter);
|
update placex set indexed_status = 2 where indexed_status = 0 and rank_search > NEW.rank_search and ST_DWithin(placex.geometry, NEW.geometry, diameter);
|
||||||
-- reparenting also for OSM Interpolation Lines (and for Tiger?)
|
-- reparenting also for OSM Interpolation Lines (and for Tiger?)
|
||||||
update location_property_osmline set indexed_status = 2 where indexed_status = 0 and ST_DWithin(location_property_osmline.linegeo, NEW.geometry, diameter);
|
update location_property_osmline set indexed_status = 2 where indexed_status = 0 and startnumber is not null and ST_DWithin(location_property_osmline.linegeo, NEW.geometry, diameter);
|
||||||
ELSEIF NEW.rank_search >= 16 THEN
|
ELSEIF NEW.rank_search >= 16 THEN
|
||||||
-- up to rank 16, street-less addresses may need reparenting
|
-- 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 address ? 'place');
|
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');
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ CREATE INDEX IF NOT EXISTS idx_placex_geometry_reverse_lookupPolygon
|
|||||||
AND name is not null AND indexed_status = 0 AND linked_place_id is null;
|
AND name is not null AND indexed_status = 0 AND linked_place_id is null;
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_osmline_parent_place_id
|
CREATE INDEX IF NOT EXISTS idx_osmline_parent_place_id
|
||||||
ON location_property_osmline USING BTREE (parent_place_id) {{db.tablespace.search_index}};
|
ON location_property_osmline USING BTREE (parent_place_id) {{db.tablespace.search_index}}
|
||||||
|
WHERE parent_place_id is not null;
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id
|
CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id
|
||||||
ON location_property_osmline USING BTREE (osm_id) {{db.tablespace.search_index}};
|
ON location_property_osmline USING BTREE (osm_id) {{db.tablespace.search_index}};
|
||||||
@@ -48,6 +49,10 @@ CREATE INDEX IF NOT EXISTS idx_postcode_postcode
|
|||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_place_osm_unique
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_place_osm_unique
|
||||||
ON place USING btree(osm_id, osm_type, class, type) {{db.tablespace.address_index}};
|
ON place USING btree(osm_id, osm_type, class, type) {{db.tablespace.address_index}};
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_place_interpolations
|
||||||
|
ON place USING gist(geometry) {{db.tablespace.address_index}}
|
||||||
|
WHERE osm_type = 'W' and address ? 'interpolation';
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
-- Indices only needed for search.
|
-- Indices only needed for search.
|
||||||
@@ -62,8 +67,12 @@ CREATE INDEX IF NOT EXISTS idx_postcode_postcode
|
|||||||
|
|
||||||
{% if postgres.has_index_non_key_column %}
|
{% if postgres.has_index_non_key_column %}
|
||||||
CREATE INDEX IF NOT EXISTS idx_placex_housenumber
|
CREATE INDEX IF NOT EXISTS idx_placex_housenumber
|
||||||
ON placex USING btree (parent_place_id) INCLUDE (housenumber) WHERE housenumber is not null;
|
ON placex USING btree (parent_place_id) {{db.tablespace.search_index}}
|
||||||
|
INCLUDE (housenumber)
|
||||||
|
WHERE housenumber is not null;
|
||||||
CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id_with_hnr
|
CREATE INDEX IF NOT EXISTS idx_osmline_parent_osm_id_with_hnr
|
||||||
ON location_property_osmline USING btree(parent_place_id) INCLUDE (startnumber, endnumber);
|
ON location_property_osmline USING btree(parent_place_id) {{db.tablespace.search_index}}
|
||||||
|
INCLUDE (startnumber, endnumber)
|
||||||
|
WHERE startnumber is not null;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ CREATE TABLE location_property_tiger (
|
|||||||
parent_place_id BIGINT,
|
parent_place_id BIGINT,
|
||||||
startnumber INTEGER,
|
startnumber INTEGER,
|
||||||
endnumber INTEGER,
|
endnumber INTEGER,
|
||||||
|
step SMALLINT,
|
||||||
partition SMALLINT,
|
partition SMALLINT,
|
||||||
linegeo GEOMETRY,
|
linegeo GEOMETRY,
|
||||||
interpolationtype TEXT,
|
|
||||||
postcode TEXT);
|
postcode TEXT);
|
||||||
GRANT SELECT ON location_property_tiger TO "{{config.DATABASE_WEBUSER}}";
|
GRANT SELECT ON location_property_tiger TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
@@ -95,10 +95,10 @@ CREATE TABLE location_property_osmline (
|
|||||||
indexed_date TIMESTAMP,
|
indexed_date TIMESTAMP,
|
||||||
startnumber INTEGER,
|
startnumber INTEGER,
|
||||||
endnumber INTEGER,
|
endnumber INTEGER,
|
||||||
|
step SMALLINT,
|
||||||
partition SMALLINT,
|
partition SMALLINT,
|
||||||
indexed_status SMALLINT,
|
indexed_status SMALLINT,
|
||||||
linegeo GEOMETRY,
|
linegeo GEOMETRY,
|
||||||
interpolationtype TEXT,
|
|
||||||
address HSTORE,
|
address HSTORE,
|
||||||
token_info JSONB, -- custom column for tokenizer use only
|
token_info JSONB, -- custom column for tokenizer use only
|
||||||
postcode TEXT,
|
postcode TEXT,
|
||||||
@@ -106,7 +106,8 @@ CREATE TABLE location_property_osmline (
|
|||||||
){{db.tablespace.search_data}};
|
){{db.tablespace.search_data}};
|
||||||
CREATE UNIQUE INDEX idx_osmline_place_id ON location_property_osmline USING BTREE (place_id) {{db.tablespace.search_index}};
|
CREATE UNIQUE INDEX idx_osmline_place_id ON location_property_osmline USING BTREE (place_id) {{db.tablespace.search_index}};
|
||||||
CREATE INDEX idx_osmline_geometry_sector ON location_property_osmline USING BTREE (geometry_sector) {{db.tablespace.address_index}};
|
CREATE INDEX idx_osmline_geometry_sector ON location_property_osmline USING BTREE (geometry_sector) {{db.tablespace.address_index}};
|
||||||
CREATE INDEX idx_osmline_linegeo ON location_property_osmline USING GIST (linegeo) {{db.tablespace.search_index}};
|
CREATE INDEX idx_osmline_linegeo ON location_property_osmline USING GIST (linegeo) {{db.tablespace.search_index}}
|
||||||
|
WHERE startnumber is not null;
|
||||||
GRANT SELECT ON location_property_osmline TO "{{config.DATABASE_WEBUSER}}";
|
GRANT SELECT ON location_property_osmline TO "{{config.DATABASE_WEBUSER}}";
|
||||||
|
|
||||||
drop table IF EXISTS search_name;
|
drop table IF EXISTS search_name;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
CREATE INDEX IF NOT EXISTS idx_location_property_tiger_parent_place_id_imp
|
CREATE INDEX IF NOT EXISTS idx_location_property_tiger_parent_place_id_imp
|
||||||
ON location_property_tiger_import (parent_place_id)
|
ON location_property_tiger_import (parent_place_id)
|
||||||
{% if postgres.has_index_non_key_column %}
|
{% if postgres.has_index_non_key_column %}
|
||||||
INCLUDE (startnumber, endnumber)
|
INCLUDE (startnumber, endnumber, step)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{db.tablespace.aux_index}};
|
{{db.tablespace.aux_index}};
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_location_property_tiger_place_id_imp
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_location_property_tiger_place_id_imp
|
||||||
|
|||||||
@@ -5,7 +5,15 @@
|
|||||||
-- Copyright (C) 2022 by the Nominatim developer community.
|
-- Copyright (C) 2022 by the Nominatim developer community.
|
||||||
-- For a full list of authors see the git log.
|
-- For a full list of authors see the git log.
|
||||||
DROP TABLE IF EXISTS location_property_tiger_import;
|
DROP TABLE IF EXISTS location_property_tiger_import;
|
||||||
CREATE TABLE location_property_tiger_import (linegeo GEOMETRY, place_id BIGINT, partition INTEGER, parent_place_id BIGINT, startnumber INTEGER, endnumber INTEGER, interpolationtype TEXT, postcode TEXT);
|
CREATE TABLE location_property_tiger_import (
|
||||||
|
linegeo GEOMETRY,
|
||||||
|
place_id BIGINT,
|
||||||
|
partition INTEGER,
|
||||||
|
parent_place_id BIGINT,
|
||||||
|
startnumber INTEGER,
|
||||||
|
endnumber INTEGER,
|
||||||
|
step SMALLINT,
|
||||||
|
postcode TEXT);
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tiger_line_import(linegeo GEOMETRY, in_startnumber INTEGER,
|
CREATE OR REPLACE FUNCTION tiger_line_import(linegeo GEOMETRY, in_startnumber INTEGER,
|
||||||
in_endnumber INTEGER, interpolationtype TEXT,
|
in_endnumber INTEGER, interpolationtype TEXT,
|
||||||
@@ -24,11 +32,12 @@ DECLARE
|
|||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
IF in_endnumber > in_startnumber THEN
|
IF in_endnumber > in_startnumber THEN
|
||||||
startnumber = in_startnumber;
|
startnumber := in_startnumber;
|
||||||
endnumber = in_endnumber;
|
endnumber := in_endnumber;
|
||||||
ELSE
|
ELSE
|
||||||
startnumber = in_endnumber;
|
startnumber := in_endnumber;
|
||||||
endnumber = in_startnumber;
|
endnumber := in_startnumber;
|
||||||
|
linegeo := ST_Reverse(linegeo);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF startnumber < 0 THEN
|
IF startnumber < 0 THEN
|
||||||
@@ -50,8 +59,10 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Filter out really broken tiger data
|
-- Filter out really broken tiger data
|
||||||
IF numberrange > 0 AND (numberrange::float/stepsize::float > 500)
|
IF numberrange > 0
|
||||||
AND ST_length(linegeo)/(numberrange::float/stepsize::float) < 0.000001 THEN
|
and numberrange::float/stepsize::float > 500
|
||||||
|
and ST_length(linegeo)/(numberrange::float/stepsize::float) < 0.000001
|
||||||
|
THEN
|
||||||
RAISE WARNING 'Road too short for number range % to % (%)',startnumber,endnumber,
|
RAISE WARNING 'Road too short for number range % to % (%)',startnumber,endnumber,
|
||||||
ST_length(linegeo)/(numberrange::float/stepsize::float);
|
ST_length(linegeo)/(numberrange::float/stepsize::float);
|
||||||
RETURN 0;
|
RETURN 0;
|
||||||
@@ -74,8 +85,12 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
--insert street(line) into import table
|
--insert street(line) into import table
|
||||||
insert into location_property_tiger_import (linegeo, place_id, partition, parent_place_id, startnumber, endnumber, interpolationtype, postcode)
|
insert into location_property_tiger_import (linegeo, place_id, partition,
|
||||||
values (linegeo, nextval('seq_place'), out_partition, out_parent_place_id, startnumber, endnumber, interpolationtype, in_postcode);
|
parent_place_id, startnumber, endnumber,
|
||||||
|
step, postcode)
|
||||||
|
values (linegeo, nextval('seq_place'), out_partition,
|
||||||
|
out_parent_place_id, startnumber, endnumber,
|
||||||
|
stepsize, in_postcode);
|
||||||
|
|
||||||
RETURN 1;
|
RETURN 1;
|
||||||
END;
|
END;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# just use the pgxs makefile
|
# just use the pgxs makefile
|
||||||
|
|
||||||
foreach(suffix ${PostgreSQL_ADDITIONAL_VERSIONS} "13" "12" "11" "10" "9.6" "9.5" "9.4" "9.3")
|
foreach(suffix ${PostgreSQL_ADDITIONAL_VERSIONS} "14" "13" "12" "11" "10" "9.6")
|
||||||
list(APPEND PG_CONFIG_HINTS
|
list(APPEND PG_CONFIG_HINTS
|
||||||
"/usr/pgsql-${suffix}/bin")
|
"/usr/pgsql-${suffix}/bin")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -216,3 +216,58 @@ def create_tiger_housenumber_index(conn, **_):
|
|||||||
ON location_property_tiger
|
ON location_property_tiger
|
||||||
USING btree(parent_place_id)
|
USING btree(parent_place_id)
|
||||||
INCLUDE (startnumber, endnumber) """)
|
INCLUDE (startnumber, endnumber) """)
|
||||||
|
|
||||||
|
|
||||||
|
@_migration(4, 0, 99, 1)
|
||||||
|
def create_interpolation_index_on_place(conn, **_):
|
||||||
|
""" Create idx_place_interpolations for lookup of interpolation lines
|
||||||
|
on updates.
|
||||||
|
"""
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute("""CREATE INDEX IF NOT EXISTS idx_place_interpolations
|
||||||
|
ON place USING gist(geometry)
|
||||||
|
WHERE osm_type = 'W' and address ? 'interpolation'""")
|
||||||
|
|
||||||
|
|
||||||
|
@_migration(4, 0, 99, 2)
|
||||||
|
def add_step_column_for_interpolation(conn, **_):
|
||||||
|
""" Add a new column 'step' to the interpolations table.
|
||||||
|
|
||||||
|
Also convers the data into the stricter format which requires that
|
||||||
|
startnumbers comply with the odd/even requirements.
|
||||||
|
"""
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
# Mark invalid all interpolations with no intermediate numbers.
|
||||||
|
cur.execute("""UPDATE location_property_osmline SET startnumber = null
|
||||||
|
WHERE endnumber - startnumber <= 1 """)
|
||||||
|
# Align the start numbers where odd/even does not match.
|
||||||
|
cur.execute("""UPDATE location_property_osmline
|
||||||
|
SET startnumber = startnumber + 1,
|
||||||
|
linegeo = ST_LineSubString(linegeo,
|
||||||
|
1.0 / (endnumber - startnumber)::float,
|
||||||
|
1)
|
||||||
|
WHERE (interpolationtype = 'odd' and startnumber % 2 = 0)
|
||||||
|
or (interpolationtype = 'even' and startnumber % 2 = 1)
|
||||||
|
""")
|
||||||
|
# Mark invalid odd/even interpolations with no intermediate numbers.
|
||||||
|
cur.execute("""UPDATE location_property_osmline SET startnumber = null
|
||||||
|
WHERE interpolationtype in ('odd', 'even')
|
||||||
|
and endnumber - startnumber = 2""")
|
||||||
|
# Finally add the new column and populate it.
|
||||||
|
cur.execute("ALTER TABLE location_property_osmline ADD COLUMN step SMALLINT")
|
||||||
|
cur.execute("""UPDATE location_property_osmline
|
||||||
|
SET step = CASE WHEN interpolationtype = 'all'
|
||||||
|
THEN 1 ELSE 2 END
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
@_migration(4, 0, 99, 3)
|
||||||
|
def add_step_column_for_tiger(conn, **_):
|
||||||
|
""" Add a new column 'step' to the tiger data table.
|
||||||
|
"""
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute("ALTER TABLE location_property_tiger ADD COLUMN step SMALLINT")
|
||||||
|
cur.execute("""UPDATE location_property_tiger
|
||||||
|
SET step = CASE WHEN interpolationtype = 'all'
|
||||||
|
THEN 1 ELSE 2 END
|
||||||
|
""")
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ Version information for Nominatim.
|
|||||||
# to 99 to make sure that the migration is applied when updating from a
|
# to 99 to make sure that the migration is applied when updating from a
|
||||||
# patch release to the next minor version. Patch releases usually shouldn't
|
# patch release to the next minor version. Patch releases usually shouldn't
|
||||||
# have migrations in them. When they are needed, then make sure that the
|
# have migrations in them. When they are needed, then make sure that the
|
||||||
# migration can reapplied and set the migration version to the appropriate
|
# migration can be reapplied and set the migration version to the appropriate
|
||||||
# patch level when cherry-picking the commit with the migration.
|
# patch level when cherry-picking the commit with the migration.
|
||||||
#
|
#
|
||||||
# Released versions always have a database patch level of 0.
|
# Released versions always have a database patch level of 0.
|
||||||
NOMINATIM_VERSION = (4, 0, 99, 1)
|
NOMINATIM_VERSION = (4, 0, 99, 4)
|
||||||
|
|
||||||
POSTGRESQL_REQUIRED_VERSION = (9, 5)
|
POSTGRESQL_REQUIRED_VERSION = (9, 5)
|
||||||
POSTGIS_REQUIRED_VERSION = (2, 2)
|
POSTGIS_REQUIRED_VERSION = (2, 2)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Feature: Reverse geocoding
|
|||||||
| way | place | house |
|
| way | place | house |
|
||||||
And result addresses contain
|
And result addresses contain
|
||||||
| house_number | road | postcode | country_code |
|
| house_number | road | postcode | country_code |
|
||||||
| 697 | Upper Kingston Road | 36067 | us |
|
| 707 | Upper Kingston Road | 36067 | us |
|
||||||
|
|
||||||
@Tiger
|
@Tiger
|
||||||
Scenario: No TIGER house number for zoom < 18
|
Scenario: No TIGER house number for zoom < 18
|
||||||
|
|||||||
@@ -16,23 +16,23 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 6 | 1 1, 1 1.001 |
|
| 4 | 4 | 1 1.0005 |
|
||||||
|
|
||||||
Scenario: Backwards even two point interpolation line
|
Scenario: Backwards even two point interpolation line
|
||||||
Given the places
|
Given the places
|
||||||
| osm | class | type | housenr | geometry |
|
| osm | class | type | housenr | geometry |
|
||||||
| N1 | place | house | 2 | 1 1 |
|
| N1 | place | house | 2 | 1 1 |
|
||||||
| N2 | place | house | 6 | 1 1.001 |
|
| N2 | place | house | 8 | 1 1.003 |
|
||||||
And the places
|
And the places
|
||||||
| osm | class | type | addr+interpolation | geometry |
|
| osm | class | type | addr+interpolation | geometry |
|
||||||
| W1 | place | houses | even | 1 1.001, 1 1 |
|
| W1 | place | houses | even | 1 1.003, 1 1 |
|
||||||
And the ways
|
And the ways
|
||||||
| id | nodes |
|
| id | nodes |
|
||||||
| 1 | 2,1 |
|
| 1 | 2,1 |
|
||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 6 | 1 1, 1 1.001 |
|
| 4 | 6 | 1 1.001, 1 1.002 |
|
||||||
|
|
||||||
Scenario: Simple odd two point interpolation
|
Scenario: Simple odd two point interpolation
|
||||||
Given the places
|
Given the places
|
||||||
@@ -48,23 +48,23 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 1 | 11 | 1 1, 1 1.001 |
|
| 3 | 9 | 1 1.0002, 1 1.0008 |
|
||||||
|
|
||||||
Scenario: Simple all two point interpolation
|
Scenario: Simple all two point interpolation
|
||||||
Given the places
|
Given the places
|
||||||
| osm | class | type | housenr | geometry |
|
| osm | class | type | housenr | geometry |
|
||||||
| N1 | place | house | 1 | 1 1 |
|
| N1 | place | house | 1 | 1 1 |
|
||||||
| N2 | place | house | 3 | 1 1.001 |
|
| N2 | place | house | 4 | 1 1.003 |
|
||||||
And the places
|
And the places
|
||||||
| osm | class | type | addr+interpolation | geometry |
|
| osm | class | type | addr+interpolation | geometry |
|
||||||
| W1 | place | houses | all | 1 1, 1 1.001 |
|
| W1 | place | houses | all | 1 1, 1 1.003 |
|
||||||
And the ways
|
And the ways
|
||||||
| id | nodes |
|
| id | nodes |
|
||||||
| 1 | 1,2 |
|
| 1 | 1,2 |
|
||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 1 | 3 | 1 1, 1 1.001 |
|
| 2 | 3 | 1 1.001, 1 1.002 |
|
||||||
|
|
||||||
Scenario: Even two point interpolation line with intermediate empty node
|
Scenario: Even two point interpolation line with intermediate empty node
|
||||||
Given the places
|
Given the places
|
||||||
@@ -80,7 +80,7 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 10 | 1 1, 1 1.001, 1.001 1.001 |
|
| 4 | 8 | 1 1.0005, 1 1.001, 1.0005 1.001 |
|
||||||
|
|
||||||
Scenario: Even two point interpolation line with intermediate duplicated empty node
|
Scenario: Even two point interpolation line with intermediate duplicated empty node
|
||||||
Given the places
|
Given the places
|
||||||
@@ -96,7 +96,7 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 10 | 1 1, 1 1.001, 1.001 1.001 |
|
| 4 | 8 | 1 1.0005, 1 1.001, 1.0005 1.001 |
|
||||||
|
|
||||||
Scenario: Simple even three point interpolation line
|
Scenario: Simple even three point interpolation line
|
||||||
Given the places
|
Given the places
|
||||||
@@ -113,8 +113,8 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 10 | 1 1, 1 1.001 |
|
| 4 | 8 | 1 1.00025, 1 1.00075 |
|
||||||
| 10 | 14 | 1 1.001, 1.001 1.001 |
|
| 12 | 12 | 1.0005 1.001 |
|
||||||
|
|
||||||
Scenario: Simple even four point interpolation line
|
Scenario: Simple even four point interpolation line
|
||||||
Given the places
|
Given the places
|
||||||
@@ -132,9 +132,9 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 10 | 1 1, 1 1.001 |
|
| 4 | 8 | 1 1.00025, 1 1.00075 |
|
||||||
| 10 | 14 | 1 1.001, 1.001 1.001 |
|
| 12 | 12 | 1.0005 1.001 |
|
||||||
| 14 | 18 | 1.001 1.001, 1.001 1.002 |
|
| 16 | 16 | 1.001 1.0015 |
|
||||||
|
|
||||||
Scenario: Reverse simple even three point interpolation line
|
Scenario: Reverse simple even three point interpolation line
|
||||||
Given the places
|
Given the places
|
||||||
@@ -151,8 +151,8 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 10 | 1 1, 1 1.001 |
|
| 4 | 8 | 1 1.00025, 1 1.00075 |
|
||||||
| 10 | 14 | 1 1.001, 1.001 1.001 |
|
| 12 | 12 | 1.0005 1.001 |
|
||||||
|
|
||||||
Scenario: Even three point interpolation line with odd center point
|
Scenario: Even three point interpolation line with odd center point
|
||||||
Given the places
|
Given the places
|
||||||
@@ -169,8 +169,7 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 7 | 1 1, 1 1.001 |
|
| 4 | 6 | 1 1.0004, 1 1.0008 |
|
||||||
| 7 | 8 | 1 1.001, 1.001 1.001 |
|
|
||||||
|
|
||||||
Scenario: Interpolation line with self-intersecting way
|
Scenario: Interpolation line with self-intersecting way
|
||||||
Given the places
|
Given the places
|
||||||
@@ -187,9 +186,9 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 6 | 0 0, 0 0.001 |
|
| 4 | 4 | 0 0.0005 |
|
||||||
| 6 | 10 | 0 0.001, 0 0.002 |
|
| 8 | 8 | 0 0.0015 |
|
||||||
| 6 | 10 | 0 0.001, 0 0.002 |
|
| 8 | 8 | 0 0.0015 |
|
||||||
|
|
||||||
Scenario: Interpolation line with self-intersecting way II
|
Scenario: Interpolation line with self-intersecting way II
|
||||||
Given the places
|
Given the places
|
||||||
@@ -205,7 +204,7 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 6 | 0 0, 0 0.001 |
|
| 4 | 4 | 0 0.0005 |
|
||||||
|
|
||||||
Scenario: addr:street on interpolation way
|
Scenario: addr:street on interpolation way
|
||||||
Given the scene parallel-road
|
Given the scene parallel-road
|
||||||
@@ -236,10 +235,10 @@ Feature: Import of address interpolations
|
|||||||
| N4 | W3 |
|
| N4 | W3 |
|
||||||
Then W10 expands to interpolation
|
Then W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
Then W11 expands to interpolation
|
Then W11 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 12 | 16 |
|
| W3 | 14 | 14 |
|
||||||
When sending search query "16 Cloud Street"
|
When sending search query "16 Cloud Street"
|
||||||
Then results contain
|
Then results contain
|
||||||
| ID | osm_type | osm_id |
|
| ID | osm_type | osm_id |
|
||||||
@@ -278,10 +277,10 @@ Feature: Import of address interpolations
|
|||||||
| N4 | W3 |
|
| N4 | W3 |
|
||||||
Then W10 expands to interpolation
|
Then W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
Then W11 expands to interpolation
|
Then W11 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 12 | 16 |
|
| W3 | 14 | 14 |
|
||||||
When sending search query "16 Cloud Street"
|
When sending search query "16 Cloud Street"
|
||||||
Then results contain
|
Then results contain
|
||||||
| ID | osm_type | osm_id |
|
| ID | osm_type | osm_id |
|
||||||
@@ -306,8 +305,8 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 2 | 6 | 144.9629794 -37.7630755, 144.9630541 -37.7628174 |
|
| 4 | 4 | 144.963016 -37.762946 |
|
||||||
| 6 | 10 | 144.9630541 -37.7628174, 144.9632341 -37.76163 |
|
| 8 | 8 | 144.963144 -37.7622237 |
|
||||||
|
|
||||||
Scenario: Place with missing address information
|
Scenario: Place with missing address information
|
||||||
Given the grid
|
Given the grid
|
||||||
@@ -326,7 +325,7 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 23 | 29 | 1,2,3 |
|
| 25 | 27 | 0.000016 0,0.00002 0,0.000033 0 |
|
||||||
|
|
||||||
Scenario: Ways without node entries are ignored
|
Scenario: Ways without node entries are ignored
|
||||||
Given the places
|
Given the places
|
||||||
@@ -348,7 +347,7 @@ Feature: Import of address interpolations
|
|||||||
Given the places
|
Given the places
|
||||||
| osm | class | type | housenr | geometry |
|
| osm | class | type | housenr | geometry |
|
||||||
| N1 | place | house | 0 | 1 1 |
|
| N1 | place | house | 0 | 1 1 |
|
||||||
| N2 | place | house | 2 | 1 1.001 |
|
| N2 | place | house | 10 | 1 1.001 |
|
||||||
And the places
|
And the places
|
||||||
| osm | class | type | addr+interpolation | geometry |
|
| osm | class | type | addr+interpolation | geometry |
|
||||||
| W1 | place | houses | even | 1 1, 1 1.001 |
|
| W1 | place | houses | even | 1 1, 1 1.001 |
|
||||||
@@ -358,9 +357,8 @@ Feature: Import of address interpolations
|
|||||||
When importing
|
When importing
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| start | end | geometry |
|
| start | end | geometry |
|
||||||
| 0 | 2 | 1 1, 1 1.001 |
|
| 2 | 8 | 1 1.0002, 1 1.0008 |
|
||||||
When sending jsonv2 reverse coordinates 1,1
|
When sending jsonv2 reverse coordinates 1,1
|
||||||
Then results contain
|
Then results contain
|
||||||
| ID | osm_type | osm_id | type | display_name |
|
| ID | osm_type | osm_id | type | display_name |
|
||||||
| 0 | way | 1 | house | 0 |
|
| 0 | node | 1 | house | 0 |
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: addr:street added to interpolation
|
Scenario: addr:street added to interpolation
|
||||||
Given the scene parallel-road
|
Given the scene parallel-road
|
||||||
@@ -51,7 +51,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | addr+interpolation | street | geometry |
|
| osm | class | type | addr+interpolation | street | geometry |
|
||||||
| W10 | place | houses | even | Cloud Street | :w-middle |
|
| W10 | place | houses | even | Cloud Street | :w-middle |
|
||||||
@@ -61,7 +61,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W3 |
|
| N2 | W3 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 2 | 6 |
|
| W3 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: addr:street added to housenumbers
|
Scenario: addr:street added to housenumbers
|
||||||
Given the scene parallel-road
|
Given the scene parallel-road
|
||||||
@@ -86,7 +86,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | street | housenr | geometry |
|
| osm | class | type | street | housenr | geometry |
|
||||||
| N1 | place | house | Cloud Street| 2 | :n-middle-w |
|
| N1 | place | house | Cloud Street| 2 | :n-middle-w |
|
||||||
@@ -97,7 +97,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W3 |
|
| N2 | W3 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 2 | 6 |
|
| W3 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: interpolation tag removed
|
Scenario: interpolation tag removed
|
||||||
Given the scene parallel-road
|
Given the scene parallel-road
|
||||||
@@ -122,7 +122,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
When marking for delete W10
|
When marking for delete W10
|
||||||
Then W10 expands to no interpolation
|
Then W10 expands to no interpolation
|
||||||
And placex contains
|
And placex contains
|
||||||
@@ -152,7 +152,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | name | geometry |
|
| osm | class | type | name | geometry |
|
||||||
| W3 | highway | unclassified | Cloud Street | :w-south |
|
| W3 | highway | unclassified | Cloud Street | :w-south |
|
||||||
@@ -162,7 +162,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W3 |
|
| N2 | W3 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 2 | 6 |
|
| W3 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: referenced road deleted
|
Scenario: referenced road deleted
|
||||||
Given the scene parallel-road
|
Given the scene parallel-road
|
||||||
@@ -187,7 +187,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W3 |
|
| N2 | W3 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W3 | 2 | 6 |
|
| W3 | 4 | 4 |
|
||||||
When marking for delete W3
|
When marking for delete W3
|
||||||
Then placex contains
|
Then placex contains
|
||||||
| object | parent_place_id |
|
| object | parent_place_id |
|
||||||
@@ -195,7 +195,7 @@ Feature: Update of address interpolations
|
|||||||
| N2 | W2 |
|
| N2 | W2 |
|
||||||
And W10 expands to interpolation
|
And W10 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: building becomes interpolation
|
Scenario: building becomes interpolation
|
||||||
Given the scene building-with-parallel-streets
|
Given the scene building-with-parallel-streets
|
||||||
@@ -222,7 +222,7 @@ Feature: Update of address interpolations
|
|||||||
Then placex has no entry for W1
|
Then placex has no entry for W1
|
||||||
And W1 expands to interpolation
|
And W1 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: interpolation becomes building
|
Scenario: interpolation becomes building
|
||||||
Given the scene building-with-parallel-streets
|
Given the scene building-with-parallel-streets
|
||||||
@@ -243,7 +243,7 @@ Feature: Update of address interpolations
|
|||||||
Then placex has no entry for W1
|
Then placex has no entry for W1
|
||||||
And W1 expands to interpolation
|
And W1 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | housenr | geometry |
|
| osm | class | type | housenr | geometry |
|
||||||
| W1 | place | house | 3 | :w-building |
|
| W1 | place | house | 3 | :w-building |
|
||||||
@@ -273,7 +273,7 @@ Feature: Update of address interpolations
|
|||||||
| W1 | place | houses | even | Cloud Street| :w-north |
|
| W1 | place | houses | even | Cloud Street| :w-north |
|
||||||
Then W1 expands to interpolation
|
Then W1 expands to interpolation
|
||||||
| parent_place_id | start | end |
|
| parent_place_id | start | end |
|
||||||
| W2 | 2 | 6 |
|
| W2 | 4 | 4 |
|
||||||
|
|
||||||
Scenario: housenumber added in middle of interpolation
|
Scenario: housenumber added in middle of interpolation
|
||||||
Given the grid
|
Given the grid
|
||||||
@@ -294,15 +294,15 @@ Feature: Update of address interpolations
|
|||||||
| N5 | place | house | 10 |
|
| N5 | place | house | 10 |
|
||||||
When importing
|
When importing
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 10 | 3,4,5 |
|
| W1 | 4 | 8 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | housenr |
|
| osm | class | type | housenr |
|
||||||
| N4 | place | house | 6 |
|
| N4 | place | house | 6 |
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 6 | 3,4 |
|
| W1 | 4 | 4 |
|
||||||
| W1 | 6 | 10 | 4,5 |
|
| W1 | 8 | 8 |
|
||||||
|
|
||||||
@Fail
|
@Fail
|
||||||
Scenario: housenumber removed in middle of interpolation
|
Scenario: housenumber removed in middle of interpolation
|
||||||
@@ -325,13 +325,13 @@ Feature: Update of address interpolations
|
|||||||
| N5 | place | house | 10 |
|
| N5 | place | house | 10 |
|
||||||
When importing
|
When importing
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 6 | 3,4 |
|
| W1 | 4 | 4 |
|
||||||
| W1 | 6 | 10 | 4,5 |
|
| W1 | 8 | 8 |
|
||||||
When marking for delete N4
|
When marking for delete N4
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 10 | 3,4,5 |
|
| W1 | 4 | 8 |
|
||||||
|
|
||||||
Scenario: Change the start housenumber
|
Scenario: Change the start housenumber
|
||||||
Given the grid
|
Given the grid
|
||||||
@@ -352,12 +352,12 @@ Feature: Update of address interpolations
|
|||||||
| N4 | place | house | 6 |
|
| N4 | place | house | 6 |
|
||||||
When importing
|
When importing
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 6 | 3,4 |
|
| W1 | 4 | 4 |
|
||||||
When updating places
|
When updating places
|
||||||
| osm | class | type | housenr |
|
| osm | class | type | housenr |
|
||||||
| N4 | place | house | 8 |
|
| N4 | place | house | 8 |
|
||||||
Then W2 expands to interpolation
|
Then W2 expands to interpolation
|
||||||
| parent_place_id | start | end | geometry |
|
| parent_place_id | start | end |
|
||||||
| W1 | 2 | 8 | 3,4 |
|
| W1 | 4 | 6 |
|
||||||
|
|
||||||
|
|||||||
@@ -91,33 +91,4 @@ class LibTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertEquals($sQuery, $aRes[0]);
|
$this->assertEquals($sQuery, $aRes[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function closestHouseNumberEvenOddOther($startnumber, $endnumber, $fraction, $aExpected)
|
|
||||||
{
|
|
||||||
foreach (array('even', 'odd', 'other') as $itype) {
|
|
||||||
$this->assertEquals(
|
|
||||||
$aExpected[$itype],
|
|
||||||
closestHouseNumber(array(
|
|
||||||
'startnumber' => $startnumber,
|
|
||||||
'endnumber' => $endnumber,
|
|
||||||
'fraction' => $fraction,
|
|
||||||
'interpolationtype' => $itype
|
|
||||||
)),
|
|
||||||
"$startnumber => $endnumber, $fraction, $itype"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testClosestHouseNumber()
|
|
||||||
{
|
|
||||||
$this->closestHouseNumberEvenOddOther(50, 100, 0.5, array('even' => 76, 'odd' => 75, 'other' => 75));
|
|
||||||
// upper bound
|
|
||||||
$this->closestHouseNumberEvenOddOther(50, 100, 1.5, array('even' => 100, 'odd' => 100, 'other' => 100));
|
|
||||||
// lower bound
|
|
||||||
$this->closestHouseNumberEvenOddOther(50, 100, -0.5, array('even' => 50, 'odd' => 50, 'other' => 50));
|
|
||||||
// fraction 0
|
|
||||||
$this->closestHouseNumberEvenOddOther(50, 100, 0, array('even' => 50, 'odd' => 51, 'other' => 50));
|
|
||||||
// start == end
|
|
||||||
$this->closestHouseNumberEvenOddOther(50, 50, 0.5, array('even' => 50, 'odd' => 50, 'other' => 50));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user