From: Sarah Hoffmann Date: Fri, 4 May 2018 20:04:56 +0000 (+0200) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Tag: deploy~334 X-Git-Url: https://git.openstreetmap.org/nominatim.git/commitdiff_plain/275f3b26560a44099dff762776277812ef0f122f?hp=c684d0a545646646d581365f3f18d285f1314033 Merge remote-tracking branch 'upstream/master' --- diff --git a/lib/DebugHtml.php b/lib/DebugHtml.php index ce2b8361..0f5af241 100644 --- a/lib/DebugHtml.php +++ b/lib/DebugHtml.php @@ -39,73 +39,75 @@ class Debug public static function printDebugTable($sHeading, $aVar) { echo ''.$sHeading.":\n"; - echo ''; + echo "
\n"; if (!empty($aVar)) { - echo ''; + echo " \n"; $aKeys = array(); $aInfo = reset($aVar); if (!is_array($aInfo)) { $aInfo = $aInfo->debugInfo(); } foreach ($aInfo as $sKey => $mVal) { - echo ''; + echo ' '."\n"; $aKeys[] = $sKey; } - echo ''; + echo " \n"; foreach ($aVar as $oRow) { $aInfo = $oRow; if (!is_array($oRow)) { $aInfo = $oRow->debugInfo(); } - echo ''; + echo " \n"; foreach ($aKeys as $sKey) { - echo ''; + echo ''."\n"; } - echo ''; + echo " \n"; } } - echo '
'.$sKey.''.$sKey.'
';
+                    echo '    
';
                     if (isset($aInfo[$sKey])) {
                         Debug::outputVar($aInfo[$sKey], '');
                     }
-                    echo '
'; + echo "\n"; } public static function printGroupTable($sHeading, $aVar) { echo ''.$sHeading.":\n"; - echo ''; + echo "
\n"; if (!empty($aVar)) { - echo ''; + echo " \n"; + echo ' '."\n"; $aKeys = array(); - $aInfo = reset(reset($aVar)); + $aInfo = reset($aVar)[0]; if (!is_array($aInfo)) { $aInfo = $aInfo->debugInfo(); } foreach ($aInfo as $sKey => $mVal) { - echo ''; + echo ' '."\n"; $aKeys[] = $sKey; } - echo ''; + echo " \n"; foreach ($aVar as $sGrpKey => $aGroup) { foreach ($aGroup as $oRow) { $aInfo = $oRow; if (!is_array($oRow)) { $aInfo = $oRow->debugInfo(); } - echo ''; + echo " \n"; + echo ' '."\n"; foreach ($aKeys as $sKey) { - echo ''; + echo ''."\n"; } - echo ''; + echo " \n"; } } } - echo '
Group
Group'.$sKey.''.$sKey.'
'.$sGrpKey.'
'.$sGrpKey.'
';
+                        echo '    
';
                         if (!empty($aInfo[$sKey])) {
                             Debug::outputVar($aInfo[$sKey], '');
                         }
-                        echo '
'; + echo "\n"; } public static function printSQL($sSQL) @@ -128,9 +130,9 @@ class Debug $sPre = "\n".$sPreNL; } } elseif (is_array($mVar) && isset($mVar['__debug_format'])) { - if (!empty($mVar[data])) { + if (!empty($mVar['data'])) { $sPre = ''; - foreach ($mVar[data] as $mValue) { + foreach ($mVar['data'] as $mValue) { echo $sPre; Debug::outputSimpleVar($mValue); $sPre = ', '; diff --git a/sql/functions.sql b/sql/functions.sql index 305365d1..c9797a5c 100644 --- a/sql/functions.sql +++ b/sql/functions.sql @@ -1311,8 +1311,8 @@ BEGIN i := getorcreate_housenumber_id(make_standard_name(NEW.housenumber)); END IF; - addr_street = NEW.address->'street'; - addr_place = NEW.address->'place'; + addr_street := NEW.address->'street'; + addr_place := NEW.address->'place'; IF NEW.address ? 'postcode' and NEW.address->'postcode' not similar to '%(,|;)%' THEN i := getorcreate_postcode_id(NEW.address->'postcode'); @@ -1419,7 +1419,7 @@ BEGIN -- see if we can get it from a surrounding building 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) + FOR location IN select address from placex where ST_Covers(geometry, place_centroid) 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') @@ -1456,9 +1456,7 @@ BEGIN 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; - END LOOP; + SELECT place_id from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) INTO NEW.parent_place_id; END IF; END IF; --DEBUG: RAISE WARNING 'Checked for addr:street (%)', NEW.parent_place_id; @@ -1466,88 +1464,80 @@ BEGIN 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; - END LOOP; + SELECT place_id from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) INTO NEW.parent_place_id; END IF; END IF; --DEBUG: RAISE WARNING 'Checked for addr:place (%)', NEW.parent_place_id; -- Is this node part of an interpolation? IF NEW.parent_place_id IS NULL AND NEW.osm_type = 'N' THEN - FOR location IN - SELECT q.parent_place_id FROM location_property_osmline q, planet_osm_ways x - WHERE q.linegeo && NEW.geometry and x.id = q.osm_id and NEW.osm_id = any(x.nodes) - LIMIT 1 - LOOP - NEW.parent_place_id := location.parent_place_id; - END LOOP; + SELECT q.parent_place_id FROM location_property_osmline q, planet_osm_ways x + WHERE q.linegeo && NEW.geometry and x.id = q.osm_id and NEW.osm_id = any(x.nodes) + LIMIT 1 INTO NEW.parent_place_id; END IF; --DEBUG: RAISE WARNING 'Checked for interpolation (%)', NEW.parent_place_id; -- 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.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) + FOR location IN + SELECT p.place_id, p.osm_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 --DEBUG: RAISE WARNING 'Node is part of way % ', location.osm_id; -- Way IS a road then we are on it - that must be our road - IF location.rank_search < 28 AND NEW.parent_place_id IS NULL THEN + IF location.rank_search < 28 THEN --RAISE WARNING 'node in way that is a street %',location; NEW.parent_place_id := location.place_id; + EXIT; END IF; --DEBUG: RAISE WARNING 'Checked if way is street (%)', NEW.parent_place_id; -- If the way mentions a street or place address, try that for parenting. - 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; - END LOOP; + IF location.address is not null THEN + IF 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 + SELECT place_id from getNearestNamedRoadFeature(NEW.partition, place_centroid, address_street_word_ids) INTO NEW.parent_place_id; + EXIT WHEN NEW.parent_place_id is not NULL; + END IF; END IF; - END IF; - --DEBUG: RAISE WARNING 'Checked for addr:street in way (%)', NEW.parent_place_id; + --DEBUG: RAISE WARNING 'Checked for addr:street in way (%)', NEW.parent_place_id; - 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; - END LOOP; + IF 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 + SELECT place_id from getNearestNamedPlaceFeature(NEW.partition, place_centroid, address_street_word_ids) INTO NEW.parent_place_id; + EXIT WHEN NEW.parent_place_id is not NULL; + END IF; END IF; - END IF; --DEBUG: RAISE WARNING 'Checked for addr:place in way (%)', NEW.parent_place_id; + END IF; -- Is the WAY part of a relation - IF NEW.parent_place_id IS NULL THEN - FOR relation IN select * from planet_osm_rels where parts @> ARRAY[location.osm_id] and members @> ARRAY['w'||location.osm_id] - LOOP - -- At the moment we only process one type of relation - associatedStreet - IF relation.tags @> ARRAY['associatedStreet'] AND array_upper(relation.members, 1) IS NOT NULL THEN - FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP - IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN - --RAISE WARNING 'node in way that is in a relation %',relation; - SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint - and rank_search = 26 and name is not null INTO NEW.parent_place_id; - END IF; - END LOOP; + FOR relation IN select * from planet_osm_rels where parts @> ARRAY[location.osm_id] and members @> ARRAY['w'||location.osm_id] + LOOP + -- At the moment we only process one type of relation - associatedStreet + IF relation.tags @> ARRAY['associatedStreet'] AND array_upper(relation.members, 1) IS NOT NULL THEN + FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP + IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN +--RAISE WARNING 'node in way that is in a relation %',relation; + SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint + and rank_search = 26 and name is not null INTO NEW.parent_place_id; END IF; END LOOP; - END IF; + END IF; + END LOOP; + EXIT WHEN NEW.parent_place_id is not null; --DEBUG: RAISE WARNING 'Checked for street relation in way (%)', NEW.parent_place_id; END LOOP; - END IF; -- Still nothing, just use the nearest road IF NEW.parent_place_id IS NULL THEN - FOR location IN SELECT place_id FROM getNearestRoadFeature(NEW.partition, place_centroid) LOOP - NEW.parent_place_id := location.place_id; - END LOOP; + SELECT place_id FROM getNearestRoadFeature(NEW.partition, place_centroid) INTO NEW.parent_place_id; END IF; --DEBUG: RAISE WARNING 'Checked for nearest way (%)', NEW.parent_place_id; @@ -1556,7 +1546,8 @@ BEGIN IF NEW.parent_place_id IS NOT NULL THEN -- Get the details of the parent road - select * from search_name where place_id = NEW.parent_place_id INTO location; + select s.country_code, s.name_vector, s.nameaddress_vector from search_name s + where s.place_id = NEW.parent_place_id INTO location; NEW.country_code := location.country_code; --DEBUG: RAISE WARNING 'Got parent details from search name'; diff --git a/sql/indices.src.sql b/sql/indices.src.sql index 61af8900..8f6b7b51 100644 --- a/sql/indices.src.sql +++ b/sql/indices.src.sql @@ -14,7 +14,7 @@ CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search) {ts:sear CREATE INDEX idx_placex_rank_address ON placex USING BTREE (rank_address) {ts:search-index}; CREATE INDEX idx_placex_pendingsector ON placex USING BTREE (rank_search,geometry_sector) {ts:address-index} where indexed_status > 0; CREATE INDEX idx_placex_parent_place_id ON placex USING BTREE (parent_place_id) {ts:search-index} where parent_place_id IS NOT NULL; -CREATE INDEX idx_placex_reverse_geometry ON placex USING gist (geometry) {ts:search-index} where rank_search != 28 and (name is not null or housenumber is not null) and class not in ('waterway','railway','tunnel','bridge','man_made'); +CREATE INDEX idx_placex_reverse_geometry ON placex USING gist (geometry) {ts:search-index} where rank_search != 28 and (name is not null or housenumber is not null or rank_search between 26 and 27) and class not in ('waterway','railway','tunnel','bridge','man_made'); CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id) {ts:address-index}; CREATE INDEX idx_osmline_parent_place_id ON location_property_osmline USING BTREE (parent_place_id) {ts:search-index}; diff --git a/test/php/Nominatim/DebugTest.php b/test/php/Nominatim/DebugTest.php new file mode 100644 index 00000000..7ed08122 --- /dev/null +++ b/test/php/Nominatim/DebugTest.php @@ -0,0 +1,197 @@ +oWithDebuginfo = $this->getMock(Geocode::class, array('debugInfo')); + $this->oWithDebuginfo->method('debugInfo') + ->willReturn(array('key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3')); + + $this->oWithToString = $this->getMock(Geocode::class, array('__toString')); + $this->oWithToString->method('__toString')->willReturn('me as string'); + } + + public function testPrintVar() + { + $this->expectOutputString(<<Var0: +
Var1:  True
+
Var2:  False
+
Var3:  0
+
Var4:  'String'
+
Var5:  0 => 'one'
+       1 => 'two'
+       2 => 'three'
+
Var6:  'key' => 'value'
+       'key2' => 'value2'
+
Var7:  me as string
+
Var8:  'value', 'value2'
+ +EOT + ); + + Debug::printVar('Var0', null); + Debug::printVar('Var1', true); + Debug::printVar('Var2', false); + Debug::printVar('Var3', 0); + Debug::printVar('Var4', 'String'); + Debug::printVar('Var5', array('one', 'two', 'three')); + Debug::printVar('Var6', array('key' => 'value', 'key2' => 'value2')); + Debug::printVar('Var7', $this->oWithToString); + Debug::printVar('Var8', Debug::fmtArrayVals(array('key' => 'value', 'key2' => 'value2'))); + } + + + public function testDebugArray() + { + $this->expectOutputString(<<Arr0: 'null' +
Arr1:  'key1' => 'val1'
+       'key2' => 'val2'
+       'key3' => 'val3'
+ +EOT + ); + + Debug::printDebugArray('Arr0', null); + Debug::printDebugArray('Arr1', $this->oWithDebuginfo); + } + + + public function testPrintDebugTable() + { + $this->expectOutputString(<<Table1: + +
+Table2: + +
+Table3: + + + + + + + + + + + + + +
01
'one'
'two'
'three'
'four'
+Table4: + + + + + + + + + + + +
key1key2key3
'val1'
'val2'
'val3'
+ +EOT + ); + + Debug::printDebugTable('Table1', null); + + Debug::printDebugTable('Table2', array()); + + // Numeric headers + Debug::printDebugTable('Table3', array(array('one', 'two'), array('three', 'four'))); + + // Associate array + Debug::printDebugTable('Table4', array($this->oWithDebuginfo)); + } + + public function testPrintGroupTable() + { + $this->expectOutputString(<<Table1: + +
+Table2: + +
+Table3: + + + + + + + + + + + + + + + + + + + + + +
Groupkey1key2
group1
'val1'
'val2'
group1
'one'
'two'
group2
'val1'
'val2'
+Table4: + + + + + + + + + + + + + + + + + + + +
Groupkey1key2key3
group1
'val1'
'val2'
'val3'
group1
'val1'
'val2'
'val3'
+ +EOT + ); + + Debug::printGroupTable('Table1', null); + Debug::printGroupTable('Table2', array()); + + // header are taken from first group item, thus no key3 gets printed + $aGroups = array( + 'group1' => array( + array('key1' => 'val1', 'key2' => 'val2'), + array('key1' => 'one', 'key2' => 'two', 'unknown' => 1), + ), + 'group2' => array( + array('key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3'), + ) + ); + Debug::printGroupTable('Table3', $aGroups); + + $aGroups = array( + 'group1' => array($this->oWithDebuginfo, $this->oWithDebuginfo), + ); + Debug::printGroupTable('Table4', $aGroups); + } +}