aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/query/tree/location.cpp
blob: f5e7ca6ba03586594a5637067550efd137617039 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "location.h"
#include "point.h"
#include "rectangle.h"
#include <vespa/vespalib/stllike/asciistream.h>

using vespalib::asciistream;
using search::common::GeoLocation;

namespace search::query {

static GeoLocation::Box convert(const Rectangle &rect) {
    GeoLocation::Range x_range{rect.left, rect.right};
    GeoLocation::Range y_range{rect.top, rect.bottom};
    return GeoLocation::Box{x_range, y_range};
}

Location::Location(const Point &p, uint32_t max_dist, uint32_t aspect)
    : Parent(p, max_dist, GeoLocation::Aspect(aspect))
{}

Location::Location(const Rectangle &rect,
                   const Point &p, uint32_t max_dist, uint32_t aspect)
    : Parent(convert(rect), p, max_dist, GeoLocation::Aspect(aspect))
{}


Location::Location(const Rectangle &rect)
    : Parent(convert(rect))
{}

bool
Location::operator==(const Location &other) const
{
    auto me = getJsonFormatString();
    auto it = other.getJsonFormatString();
    if (me == it) {
        return true;
    } else {
        // dump 'me' and 'it' here if unit tests fail
        // fprintf(stderr, "me='%s', it='%s'\n", me.c_str(), it.c_str());
        return false;
    }
}

std::string
Location::getOldFormatString() const
{
    // we need to product what search::common::GeoLocationParser can parse
    vespalib::asciistream buf;
    if (has_point) {
        buf << "(2"  // dimensionality
                        << "," << point.x
                        << "," << point.y
                        << "," << radius
                        << "," << "0"  // table id.
                        << "," << "1"  // rank multiplier.
                        << "," << "0" // rank only on distance.
                        << "," << x_aspect.multiplier // aspect multiplier
                        << ")";
    }
    if (bounding_box.active()) {
        buf << "[2," << bounding_box.x.low
            << "," << bounding_box.y.low
            << "," << bounding_box.x.high
            << "," << bounding_box.y.high
            << "]" ;
    }
    return buf.str();
}

std::string
Location::getJsonFormatString() const
{
    // Only produce what search::common::GeoLocationParser can parse
    vespalib::asciistream buf;
    buf << "{";
    if (has_point) {
        buf << "p:{x:" << point.x << ",y:" << point.y << "}";
        if (has_radius()) {
            buf << "," << "r:" << radius;
        }
        if (x_aspect.active()) {
            buf << "," << "a:" << x_aspect.multiplier;
        }
    }
    if (bounding_box.active()) {
        if (has_point) {
            buf << ",";
        }
        buf << "b:{x:[" << bounding_box.x.low
            << "," << bounding_box.x.high
            << "],y:[" << bounding_box.y.low
            << "," << bounding_box.y.high
            << "]}" ;
    }
    buf << "}";
    return buf.str();
}

vespalib::asciistream &operator<<(vespalib::asciistream &out, const Location &loc) {
    return out << loc.getJsonFormatString();
}

} // namespace