mirror of
https://github.com/osm-search/Nominatim.git
synced 2025-01-08 22:49:15 +03:00
Adds code to merge place polygon and points using:
label relation member admin_center, admin_centre relation member (with same name) exact name, search_rank and location match Adding this requires a new column and index: SELECT AddGeometryColumn('placex', 'centroid', 4326, 'GEOMETRY', 2); CREATE INDEX idx_placex_linked_place_id ON placex USING BTREE (linked_place_id);
This commit is contained in:
parent
80cf5df1cd
commit
041b3edf89
@ -208,7 +208,7 @@ form{
|
|||||||
map.panTo(lonLat, <?php echo $iZoom ?>);
|
map.panTo(lonLat, <?php echo $iZoom ?>);
|
||||||
}
|
}
|
||||||
|
|
||||||
function panToLatLonZoom(lat,lon, zoom) {
|
function panToLatLonZoom(lat, lon, zoom) {
|
||||||
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
||||||
if (zoom != map.getZoom())
|
if (zoom != map.getZoom())
|
||||||
map.setCenter(lonLat, zoom);
|
map.setCenter(lonLat, zoom);
|
||||||
@ -220,6 +220,8 @@ form{
|
|||||||
var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
||||||
var proj_map = map.getProjectionObject();
|
var proj_map = map.getProjectionObject();
|
||||||
map.zoomToExtent(new OpenLayers.Bounds(minlon,minlat,maxlon,maxlat).transform(proj_EPSG4326, proj_map));
|
map.zoomToExtent(new OpenLayers.Bounds(minlon,minlat,maxlon,maxlat).transform(proj_EPSG4326, proj_map));
|
||||||
|
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
||||||
|
map.panTo(lonLat, <?php echo $iZoom ?>);
|
||||||
|
|
||||||
var pointList = [];
|
var pointList = [];
|
||||||
var style = {
|
var style = {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
@define('CONST_Default_Zoom', 2);
|
@define('CONST_Default_Zoom', 2);
|
||||||
|
|
||||||
@define('CONST_Search_AreaPolygons_Enabled', true);
|
@define('CONST_Search_AreaPolygons_Enabled', true);
|
||||||
|
@define('CONST_Search_AreaPolygons', true);
|
||||||
|
|
||||||
@define('CONST_Suggestions_Enabled', false);
|
@define('CONST_Suggestions_Enabled', false);
|
||||||
|
|
||||||
|
@ -1189,6 +1189,9 @@ DECLARE
|
|||||||
location RECORD;
|
location RECORD;
|
||||||
way RECORD;
|
way RECORD;
|
||||||
relation RECORD;
|
relation RECORD;
|
||||||
|
relation_members TEXT[];
|
||||||
|
relMember RECORD;
|
||||||
|
linkedplacex RECORD;
|
||||||
search_diameter FLOAT;
|
search_diameter FLOAT;
|
||||||
search_prevdiameter FLOAT;
|
search_prevdiameter FLOAT;
|
||||||
search_maxrank INTEGER;
|
search_maxrank INTEGER;
|
||||||
@ -1240,6 +1243,7 @@ BEGIN
|
|||||||
DELETE FROM place_boundingbox where place_id = NEW.place_id;
|
DELETE FROM place_boundingbox where place_id = NEW.place_id;
|
||||||
result := deleteRoad(NEW.partition, NEW.place_id);
|
result := deleteRoad(NEW.partition, NEW.place_id);
|
||||||
result := deleteLocationArea(NEW.partition, NEW.place_id);
|
result := deleteLocationArea(NEW.partition, NEW.place_id);
|
||||||
|
UPDATE placex set linked_place_id = null where linked_place_id = NEW.place_id;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- reclaculate country and partition (should probably have a country_code and calculated_country_code as seperate fields)
|
-- reclaculate country and partition (should probably have a country_code and calculated_country_code as seperate fields)
|
||||||
@ -1257,6 +1261,7 @@ BEGIN
|
|||||||
-- Speed up searches - just use the centroid of the feature
|
-- Speed up searches - just use the centroid of the feature
|
||||||
-- cheaper but less acurate
|
-- cheaper but less acurate
|
||||||
place_centroid := ST_Centroid(NEW.geometry);
|
place_centroid := ST_Centroid(NEW.geometry);
|
||||||
|
NEW.centroid := null;
|
||||||
|
|
||||||
-- Thought this wasn't needed but when we add new languages to the country_name table
|
-- Thought this wasn't needed but when we add new languages to the country_name table
|
||||||
-- we need to update the existing names
|
-- we need to update the existing names
|
||||||
@ -1452,6 +1457,93 @@ BEGIN
|
|||||||
|
|
||||||
-- RAISE WARNING ' INDEXING: %',NEW;
|
-- RAISE WARNING ' INDEXING: %',NEW;
|
||||||
|
|
||||||
|
IF NEW.osm_type = 'R' AND NEW.rank_search < 26 THEN
|
||||||
|
|
||||||
|
-- see if we have any special relation members
|
||||||
|
select members from planet_osm_rels where id = NEW.osm_id INTO relation_members;
|
||||||
|
|
||||||
|
FOR relMember IN select get_osm_rel_members(relation_members,ARRAY['label']) as member LOOP
|
||||||
|
|
||||||
|
select * from placex where osm_type = upper(substring(relMember.member,1,1))
|
||||||
|
and osm_id = substring(relMember.member,2,10000)::integer order by rank_search desc limit 1 into linkedPlacex;
|
||||||
|
|
||||||
|
-- If we don't already have one use this as the centre point of the geometry
|
||||||
|
IF NEW.centroid IS NULL THEN
|
||||||
|
NEW.centroid := coalesce(linkedPlacex.centroid,st_centroid(linkedPlacex.geometry));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- merge in the label name, re-init word vector
|
||||||
|
NEW.name := linkedPlacex.name || NEW.name;
|
||||||
|
name_vector := make_keywords(NEW.name);
|
||||||
|
|
||||||
|
-- merge in extra tags
|
||||||
|
NEW.extratags := linkedPlacex.extratags || NEW.extratags;
|
||||||
|
|
||||||
|
-- mark the linked place (excludes from search results)
|
||||||
|
UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id;
|
||||||
|
DELETE from search_name where place_id = linkedPlacex.place_id;
|
||||||
|
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
FOR relMember IN select get_osm_rel_members(relation_members,ARRAY['admin_center','admin_centre']) as member LOOP
|
||||||
|
|
||||||
|
select * from placex where osm_type = upper(substring(relMember.member,1,1))
|
||||||
|
and osm_id = substring(relMember.member,2,10000)::integer order by rank_search desc limit 1 into linkedPlacex;
|
||||||
|
|
||||||
|
IF NEW.name->'name' = linkedPlacex.name->'name' THEN
|
||||||
|
-- If we don't already have one use this as the centre point of the geometry
|
||||||
|
IF NEW.centroid IS NULL THEN
|
||||||
|
NEW.centroid := coalesce(linkedPlacex.centroid,st_centroid(linkedPlacex.geometry));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- merge in the name, re-init word vector
|
||||||
|
NEW.name := linkedPlacex.name || NEW.name;
|
||||||
|
name_vector := make_keywords(NEW.name);
|
||||||
|
|
||||||
|
-- merge in extra tags
|
||||||
|
NEW.extratags := linkedPlacex.extratags || NEW.extratags;
|
||||||
|
|
||||||
|
-- mark the linked place (excludes from search results)
|
||||||
|
UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id;
|
||||||
|
DELETE from search_name where place_id = linkedPlacex.place_id;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
-- not found one yet? how about doing a name search
|
||||||
|
IF NEW.centroid IS NULL THEN
|
||||||
|
FOR linkedPlacex IN select placex.* from search_name join placex using (place_id) WHERE
|
||||||
|
search_name.name_vector @> ARRAY[getorcreate_name_id(make_standard_name(NEW.name->'name'))]
|
||||||
|
AND search_name.search_rank = NEW.rank_search
|
||||||
|
AND search_name.place_id != NEW.place_id
|
||||||
|
AND osm_type = 'N'
|
||||||
|
AND NEW.name->'name' = placex.name->'name'
|
||||||
|
AND st_contains(NEW.geometry, placex.geometry)
|
||||||
|
LOOP
|
||||||
|
-- If we don't already have one use this as the centre point of the geometry
|
||||||
|
IF NEW.centroid IS NULL THEN
|
||||||
|
NEW.centroid := coalesce(linkedPlacex.centroid,st_centroid(linkedPlacex.geometry));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- merge in the name, re-init word vector
|
||||||
|
NEW.name := linkedPlacex.name || NEW.name;
|
||||||
|
name_vector := make_keywords(NEW.name);
|
||||||
|
|
||||||
|
-- merge in extra tags
|
||||||
|
NEW.extratags := linkedPlacex.extratags || NEW.extratags;
|
||||||
|
|
||||||
|
-- mark the linked place (excludes from search results)
|
||||||
|
UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id;
|
||||||
|
DELETE from search_name where place_id = linkedPlacex.place_id;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF NEW.centroid IS NOT NULL THEN
|
||||||
|
place_centroid := NEW.centroid
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END IF;
|
||||||
|
|
||||||
NEW.parent_place_id = 0;
|
NEW.parent_place_id = 0;
|
||||||
parent_place_id_rank = 0;
|
parent_place_id_rank = 0;
|
||||||
|
|
||||||
@ -1576,6 +1668,11 @@ BEGIN
|
|||||||
-- INSERT INTO search_name values (NEW.place_id, NEW.rank_search, NEW.rank_search, 0, NEW.country_code, name_vector, nameaddress_vector, place_centroid);
|
-- INSERT INTO search_name values (NEW.place_id, NEW.rank_search, NEW.rank_search, 0, NEW.country_code, name_vector, nameaddress_vector, place_centroid);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
-- If we've not managed to pick up a better one - default centroid
|
||||||
|
IF NEW.centroid IS NULL THEN
|
||||||
|
NEW.centroid := place_centroid;
|
||||||
|
END IF;
|
||||||
|
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
RETURN NEW;
|
RETURN NEW;
|
||||||
@ -1590,6 +1687,9 @@ DECLARE
|
|||||||
classtable TEXT;
|
classtable TEXT;
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
|
update placex set linked_place_id = null where linked_place_id = OLD.place_id;
|
||||||
|
update placex set indexed_status = 2 where linked_place_id = OLD.place_id and indexed_status = 0;
|
||||||
|
|
||||||
IF OLD.rank_address < 30 THEN
|
IF OLD.rank_address < 30 THEN
|
||||||
|
|
||||||
-- mark everything linked to this place for re-indexing
|
-- mark everything linked to this place for re-indexing
|
||||||
@ -2545,3 +2645,40 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql;
|
LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_osm_rel_members(members TEXT[], member TEXT) RETURNS TEXT[]
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
result TEXT[];
|
||||||
|
i INTEGER;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
FOR i IN 1..ARRAY_UPPER(members,1) BY 2 LOOP
|
||||||
|
IF members[i+1] = member THEN
|
||||||
|
result := result || members[i];
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION get_osm_rel_members(members TEXT[], memberLabels TEXT[]) RETURNS SETOF TEXT
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
i INTEGER;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
FOR i IN 1..ARRAY_UPPER(members,1) BY 2 LOOP
|
||||||
|
IF members[i+1] = ANY(memberLabels) THEN
|
||||||
|
RETURN NEXT members[i];
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
RETURN;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ SELECT AddGeometryColumn('placex', 'geometry', 4326, 'GEOMETRY', 2);
|
|||||||
SELECT AddGeometryColumn('placex', 'centroid', 4326, 'GEOMETRY', 2);
|
SELECT AddGeometryColumn('placex', 'centroid', 4326, 'GEOMETRY', 2);
|
||||||
CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id);
|
CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id);
|
||||||
CREATE INDEX idx_placex_osmid ON placex USING BTREE (osm_type, osm_id);
|
CREATE INDEX idx_placex_osmid ON placex USING BTREE (osm_type, osm_id);
|
||||||
|
CREATE INDEX idx_placex_linked_place_id ON placex USING BTREE (linked_place_id);
|
||||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search, geometry_sector);
|
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search, geometry_sector);
|
||||||
CREATE INDEX idx_placex_geometry ON placex USING GIST (geometry);
|
CREATE INDEX idx_placex_geometry ON placex USING GIST (geometry);
|
||||||
|
|
||||||
|
@ -1139,7 +1139,7 @@
|
|||||||
}
|
}
|
||||||
foreach($aSearchResults as $iResNum => $aResult)
|
foreach($aSearchResults as $iResNum => $aResult)
|
||||||
{
|
{
|
||||||
if (CONST_Search_AreaPolygons || true)
|
if (CONST_Search_AreaPolygons)
|
||||||
{
|
{
|
||||||
// Get the bounding box and outline polygon
|
// Get the bounding box and outline polygon
|
||||||
$sSQL = "select place_id,numfeatures,area,outline,";
|
$sSQL = "select place_id,numfeatures,area,outline,";
|
||||||
@ -1148,6 +1148,7 @@
|
|||||||
$sSQL .= "ST_AsText(outline) as outlinestring from get_place_boundingbox_quick(".$aResult['place_id'].")";
|
$sSQL .= "ST_AsText(outline) as outlinestring from get_place_boundingbox_quick(".$aResult['place_id'].")";
|
||||||
|
|
||||||
$sSQL = "select place_id,0 as numfeatures,st_area(geometry) as area,";
|
$sSQL = "select place_id,0 as numfeatures,st_area(geometry) as area,";
|
||||||
|
$sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
|
||||||
$sSQL .= "ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),4)) as minlat,ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),2)) as maxlat,";
|
$sSQL .= "ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),4)) as minlat,ST_Y(ST_PointN(ExteriorRing(ST_Box2D(geometry)),2)) as maxlat,";
|
||||||
$sSQL .= "ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),1)) as minlon,ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),3)) as maxlon,";
|
$sSQL .= "ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),1)) as minlon,ST_X(ST_PointN(ExteriorRing(ST_Box2D(geometry)),3)) as maxlon,";
|
||||||
$sSQL .= "ST_AsText(geometry) as outlinestring from placex where place_id = ".$aResult['place_id'].' and st_geometrytype(ST_Box2D(geometry)) = \'ST_Polygon\'';
|
$sSQL .= "ST_AsText(geometry) as outlinestring from placex where place_id = ".$aResult['place_id'].' and st_geometrytype(ST_Box2D(geometry)) = \'ST_Polygon\'';
|
||||||
@ -1158,6 +1159,10 @@
|
|||||||
}
|
}
|
||||||
if ($aPointPolygon['place_id'])
|
if ($aPointPolygon['place_id'])
|
||||||
{
|
{
|
||||||
|
if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null ) {
|
||||||
|
$aResult['lat'] = $aPointPolygon['centrelat'];
|
||||||
|
$aResult['lon'] = $aPointPolygon['centrelon'];
|
||||||
|
}
|
||||||
// Translate geometary string to point array
|
// Translate geometary string to point array
|
||||||
if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch))
|
if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user