From 6157fd6e7194de135de855ce7638d1ed4c6cc3b4 Mon Sep 17 00:00:00 2001 From: Schuyler Erle Date: Fri, 2 Sep 2011 09:44:50 +0000 Subject: [PATCH] try to fix the similar places logic --- gazetteer/places/models.py | 25 +++++++++++++++++-------- gazetteer/places/views.py | 10 +++++----- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/gazetteer/places/models.py b/gazetteer/places/models.py index 351fda4..c395417 100644 --- a/gazetteer/places/models.py +++ b/gazetteer/places/models.py @@ -32,7 +32,7 @@ class FeatureSearchManager(models.GeoManager): if srid != 4326: bbox.transform(4326) # convert to lon/lat qset = qset.filter(geometry__bboverlaps=bbox) if text: - #self.set_threshold(threshold) + self.set_threshold(threshold) # use the pg_trgm index qset = qset.extra(select={"similarity":"similarity(preferred_name, %s)"}, select_params=[text], @@ -108,23 +108,32 @@ class Feature(models.Model): def similar_features(self, max_distance=30000, scale_factor=2000, threshold=0.35, limit=20): type(self).search.set_threshold(threshold) sql = """ - SELECT *, %s * similarity / (distance + 1.0) AS score FROM ( + SELECT DISTINCT *, %s * similarity / (distance + 1.0) AS score FROM ( + SELECT f.*, r.feature1_id, r.feature2_id, r.relationship_type, + similarity(preferred_name, %s) AS similarity, + st_distance_sphere(geometry, %s) AS distance + FROM places_feature f, places_relationship r + WHERE (r.feature1_id = %s AND r.feature2_id = f.id) + OR (r.feature2_id = %s AND r.feature1_id = f.id) + UNION SELECT f.*, r.feature1_id, r.feature2_id, r.relationship_type, similarity(preferred_name, %s) AS similarity, st_distance_sphere(geometry, %s) AS distance FROM places_feature f LEFT JOIN places_relationship r - ON (f.id=r.feature1_id OR f.id=r.feature2_id) + ON (f.id = r.feature1_id or f.id = r.feature2_id) WHERE geometry && st_buffer(%s, %s) AND preferred_name %% %s AND f.id <> %s - AND (r.feature1_id IS NULL OR r.feature1_id = %s OR r.feature2_id = %s) + AND (r.feature1_id IS NULL or r.feature1_id = %s or r.feature2_id = %s) LIMIT %s ) AS whatever - ORDER BY similarity / (distance + 1.0) DESC""" - qset = type(self).objects.raw(sql, [scale_factor, self.preferred_name, - "SRID=4326;" + self.geometry.centroid.wkt, + ORDER BY %s * similarity / (distance + 1.0) DESC""" + qset = type(self).objects.raw(sql, [scale_factor, + self.preferred_name, "SRID=4326;" + self.geometry.centroid.wkt, + self.id, self.id, + self.preferred_name, "SRID=4326;" + self.geometry.centroid.wkt, self.geometry.centroid.wkt, max_distance*0.00001, - self.preferred_name, self.id, self.id, self.id, limit]) + self.preferred_name, self.id, self.id, self.id, limit, scale_factor]) return qset LANGUAGE_CHOICES = ( diff --git a/gazetteer/places/views.py b/gazetteer/places/views.py index b0c6b3c..380b287 100644 --- a/gazetteer/places/views.py +++ b/gazetteer/places/views.py @@ -124,15 +124,15 @@ def add_relation(request): feature1 = get_object_or_404_json(Feature, pk=feature1) feature2 = get_object_or_404_json(Feature, pk=feature2) - rel_obj = None + verb = rel_obj = None try: - rel_obj = Relationship.objects.get(feature1=feature1, feature2=feature2, relationship_type=relation) + rel_obj = Relationship.objects.get(feature1=feature1, feature2=feature2) + verb = "deleted" except ObjectDoesNotExist: rel_obj = Relationship(feature1=feature1, feature2=feature2, relationship_type=relation) - verb = "created" + verb = "created" if relation == "": - if rel_obj.id: - verb = "deleted" + if verb == "deleted": rel_obj.delete() if relation == "conflates": feature2.is_primary = True