def nearest_qmed_catchments(self, subject_catchment, limit=None, dist_limit=500):
        dist_sq = Catchment.distance_to(subject_catchment).label('dist_sq')  # Distance squared, calculated using SQL
        query = self.db_session.query(Catchment, dist_sq). \
            join(Catchment.descriptors). \
            filter(Catchment.id != subject_catchment.id,  # Exclude subject catchment itself
                   Catchment.id.in_(self.catchment_ids),
                   Catchment.country == subject_catchment.country,  # SQL dist method does not cover cross-boundary dist
                   # Within the distance limit
                   dist_sq <= dist_limit ** 2). \
            group_by(Catchment). \
            order_by(dist_sq)

        if limit:
            rows = query[0:limit]  # Each row is tuple of (catchment, distance squared)
        else:
            rows = query.all()

        # Add real `dist` attribute to catchment list using previously calculated SQL dist squared
        catchments = []
        for row in rows:
            catchment = row[0]
            catchment.dist = sqrt(row[1])
            catchments.append(catchment)

        return catchments
    def nearest_qmed_catchments(self,
                                subject_catchment,
                                limit=None,
                                dist_limit=500):
        dist_sq = Catchment.distance_to(subject_catchment).label(
            'dist_sq')  # Distance squared, calculated using SQL
        query = self.db_session.query(Catchment, dist_sq). \
            join(Catchment.descriptors). \
            filter(Catchment.id != subject_catchment.id,  # Exclude subject catchment itself
                   Catchment.id.in_(self.catchment_ids),
                   Catchment.country == subject_catchment.country,  # SQL dist method does not cover cross-boundary dist
                   # Within the distance limit
                   dist_sq <= dist_limit ** 2). \
            group_by(Catchment). \
            order_by(dist_sq)

        if limit:
            rows = query[
                0:limit]  # Each row is tuple of (catchment, distance squared)
        else:
            rows = query.all()

        # Add real `dist` attribute to catchment list using previously calculated SQL dist squared
        catchments = []
        for row in rows:
            catchment = row[0]
            catchment.dist = sqrt(row[1])
            catchments.append(catchment)

        return catchments
    def test_catchment_distance_no_country(self):
        catchment_1 = Catchment("Aberdeen", "River Dee")
        catchment_1.descriptors.centroid_ngr = Point(0, 0)

        catchment_2 = Catchment("Dundee", "River Tay")
        catchment_2.descriptors.centroid_ngr = Point(3000, 4000)

        self.assertEqual(catchment_1.distance_to(catchment_2), 5)
    def test_catchment_distance_no_country(self):
        catchment_1 = Catchment("Aberdeen", "River Dee")
        catchment_1.descriptors.centroid_ngr = Point(0, 0)

        catchment_2 = Catchment("Dundee", "River Tay")
        catchment_2.descriptors.centroid_ngr = Point(3000, 4000)

        self.assertEqual(catchment_1.distance_to(catchment_2), 5)
    def test_catchment_distance_different_country(self):
        catchment_1 = Catchment("Aberdeen", "River Dee")
        catchment_1.descriptors.centroid_ngr = Point(0, 0)

        catchment_2 = Catchment("Belfast")
        catchment_2.descriptors.centroid_ngr = Point(3, 4)
        catchment_2.country = 'ni'

        self.assertEqual(catchment_1.distance_to(catchment_2), float('inf'))
    def test_catchment_distance_different_country(self):
        catchment_1 = Catchment("Aberdeen", "River Dee")
        catchment_1.descriptors.centroid_ngr = Point(0, 0)

        catchment_2 = Catchment("Belfast")
        catchment_2.descriptors.centroid_ngr = Point(3, 4)
        catchment_2.country = 'ni'

        self.assertEqual(catchment_1.distance_to(catchment_2), float('inf'))