aboutsummaryrefslogtreecommitdiffstats
path: root/searchsummary
diff options
context:
space:
mode:
authorArne H Juul <arnej@yahooinc.com>2021-12-18 00:16:28 +0000
committerArne H Juul <arnej@yahooinc.com>2022-01-24 12:29:04 +0000
commit754886cee3a828a55bf69b463d399ffa74bd8e22 (patch)
treea2408cb502ed9366dc8ceb4adf5ea07604a8400b /searchsummary
parente66c203626e803f1ddc6a396623772adffba54e0 (diff)
configurable position rendering
* in summary field writers
Diffstat (limited to 'searchsummary')
-rw-r--r--searchsummary/src/tests/docsummary/positionsdfw_test.cpp3
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/docsumconfig.cpp6
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp36
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h6
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp120
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h18
6 files changed, 149 insertions, 40 deletions
diff --git a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp
index 52a363c9888..b9469ca2102 100644
--- a/searchsummary/src/tests/docsummary/positionsdfw_test.cpp
+++ b/searchsummary/src/tests/docsummary/positionsdfw_test.cpp
@@ -131,8 +131,7 @@ void checkWritePositionField(Test &test, AttrType &attr,
}
MyAttributeManager attribute_man(attr);
- PositionsDFW::UP writer =
- createPositionsDFW(attr.getName().c_str(), &attribute_man);
+ PositionsDFW::UP writer = PositionsDFW::create(attr.getName().c_str(), &attribute_man, false);
ASSERT_TRUE(writer.get());
ResType res_type = RES_JSONSTRING;
MyGetDocsumsStateCallback callback;
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/docsumconfig.cpp b/searchsummary/src/vespa/searchsummary/docsummary/docsumconfig.cpp
index a1bc690e042..380d29ef4b8 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/docsumconfig.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/docsumconfig.cpp
@@ -72,19 +72,19 @@ DynamicDocsumConfig::createFieldWriter(const string & fieldName, const string &
} else if (overrideName == "absdist") {
if (getEnvironment()) {
IAttributeManager *am = getEnvironment()->getAttributeManager();
- fieldWriter = createAbsDistanceDFW(argument.c_str(), am);
+ fieldWriter = AbsDistanceDFW::create(argument.c_str(), am, resultConfig.useV8geoPositions());
rc = fieldWriter.get();
}
} else if (overrideName == "positions") {
if (getEnvironment()) {
IAttributeManager *am = getEnvironment()->getAttributeManager();
- fieldWriter = createPositionsDFW(argument.c_str(), am);
+ fieldWriter = PositionsDFW::create(argument.c_str(), am, resultConfig.useV8geoPositions());
rc = fieldWriter.get();
}
} else if (overrideName == "geopos") {
if (getEnvironment()) {
IAttributeManager *am = getEnvironment()->getAttributeManager();
- fieldWriter = GeoPositionDFW::create(argument.c_str(), am);
+ fieldWriter = GeoPositionDFW::create(argument.c_str(), am, resultConfig.useV8geoPositions());
rc = fieldWriter.get();
}
} else if (overrideName == "attribute") {
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp
index 1f73872af6e..cfc492d50ee 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.cpp
@@ -19,14 +19,19 @@ using attribute::IAttributeVector;
using attribute::IAttributeContext;
using vespalib::Issue;
-GeoPositionDFW::GeoPositionDFW(const vespalib::string & attrName) :
- AttrDFW(attrName)
+GeoPositionDFW::GeoPositionDFW(const vespalib::string & attrName, bool useV8geoPositions) :
+ AttrDFW(attrName),
+ _useV8geoPositions(useV8geoPositions)
{ }
namespace {
-void fmtZcurve(int64_t zval, vespalib::slime::Inserter &target)
-{
+double to_degrees(int32_t microDegrees) {
+ double d = microDegrees / 1.0e6;
+ return d;
+}
+
+void fmtZcurve(int64_t zval, vespalib::slime::Inserter &target, bool useV8geoPositions) {
int32_t docx = 0;
int32_t docy = 0;
vespalib::geo::ZCurve::decode(zval, &docx, &docy);
@@ -34,8 +39,15 @@ void fmtZcurve(int64_t zval, vespalib::slime::Inserter &target)
LOG(spam, "skipping empty zcurve value");
} else {
vespalib::slime::Cursor &obj = target.insertObject();
- obj.setLong("y", docy);
- obj.setLong("x", docx);
+ if (useV8geoPositions) {
+ double degrees_ns = to_degrees(docy);
+ double degrees_ew = to_degrees(docx);
+ obj.setDouble("lat", degrees_ns);
+ obj.setDouble("lng", degrees_ew);
+ } else {
+ obj.setLong("y", docy);
+ obj.setLong("x", docx);
+ }
}
}
@@ -62,7 +74,7 @@ GeoPositionDFW::insertField(uint32_t docid, GetDocsumsState * dsState, ResType,
Cursor &elem = arr.addObject();
int64_t pos = elements[i].getValue();
ObjectSymbolInserter obj(elem, isym);
- fmtZcurve(pos, obj);
+ fmtZcurve(pos, obj, _useV8geoPositions);
elem.setLong(wsym, elements[i].getWeight());
}
} else {
@@ -76,18 +88,19 @@ GeoPositionDFW::insertField(uint32_t docid, GetDocsumsState * dsState, ResType,
for (uint32_t i = 0; i < numValues; i++) {
int64_t pos = elements[i];
ArrayInserter obj(arr);
- fmtZcurve(pos, obj);
+ fmtZcurve(pos, obj, _useV8geoPositions);
}
}
} else {
int64_t pos = attribute.getInt(docid);
- fmtZcurve(pos, target);
+ fmtZcurve(pos, target, _useV8geoPositions);
}
}
GeoPositionDFW::UP
GeoPositionDFW::create(const char *attribute_name,
- IAttributeManager *attribute_manager)
+ IAttributeManager *attribute_manager,
+ bool useV8geoPositions)
{
GeoPositionDFW::UP ret;
if (attribute_manager != nullptr) {
@@ -106,8 +119,7 @@ GeoPositionDFW::create(const char *attribute_name,
return ret;
}
}
- ret.reset(new GeoPositionDFW(attribute_name));
- return ret;
+ return std::make_unique<GeoPositionDFW>(attribute_name, useV8geoPositions);
}
}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h
index 020e864d902..5dcee853304 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h
+++ b/searchsummary/src/vespa/searchsummary/docsummary/geoposdfw.h
@@ -11,11 +11,13 @@ namespace search::docsummary {
**/
class GeoPositionDFW : public AttrDFW
{
+private:
+ bool _useV8geoPositions;
public:
typedef std::unique_ptr<GeoPositionDFW> UP;
- GeoPositionDFW(const vespalib::string & attrName);
+ GeoPositionDFW(const vespalib::string & attrName, bool useV8geoPositions);
void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override;
- static UP create(const char *attribute_name, IAttributeManager *attribute_manager);
+ static UP create(const char *attribute_name, IAttributeManager *attribute_manager, bool useV8geoPositions);
};
}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp
index ce14069a135..c46988de0d2 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.cpp
@@ -4,6 +4,7 @@
#include "docsumstate.h"
#include <vespa/searchlib/attribute/iattributemanager.h>
#include <vespa/searchcommon/attribute/attributecontent.h>
+#include <vespa/searchlib/common/geo_gcd.h>
#include <vespa/searchlib/common/location.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/data/slime/cursor.h>
@@ -16,11 +17,21 @@ LOG_SETUP(".searchlib.docsummary.positionsdfw");
namespace search::docsummary {
+namespace {
+
+double to_degrees(int32_t microDegrees) {
+ double d = microDegrees / 1.0e6;
+ return d;
+}
+
+}
+
using search::attribute::IAttributeContext;
using search::attribute::IAttributeVector;
using search::attribute::BasicType;
using search::attribute::IntegerContent;
using search::common::Location;
+using search::common::GeoGcd;
LocationAttrDFW::AllLocations
LocationAttrDFW::getAllLocations(GetDocsumsState *state)
@@ -50,10 +61,40 @@ LocationAttrDFW::getAllLocations(GetDocsumsState *state)
return retval;
}
-AbsDistanceDFW::AbsDistanceDFW(const vespalib::string & attrName) :
- LocationAttrDFW(attrName)
+AbsDistanceDFW::AbsDistanceDFW(const vespalib::string & attrName, bool useV8geoPositions) :
+ LocationAttrDFW(attrName),
+ _useV8geoPositions(useV8geoPositions)
{ }
+double
+AbsDistanceDFW::kmMinDistance(uint32_t docid, GetDocsumsState *state,
+ const std::vector<const GeoLoc *> &locations)
+{
+ double best = std::numeric_limits<double>::max();
+ const auto& attribute = get_attribute(*state);
+ for (auto location : locations) {
+ double lat = to_degrees(location->point.y);
+ double lng = to_degrees(location->point.x);
+ GeoGcd point{lat, lng};
+ int32_t docx = 0;
+ int32_t docy = 0;
+ IntegerContent pos;
+ pos.fill(attribute, docid);
+ uint32_t numValues = pos.size();
+ for (uint32_t i = 0; i < numValues; i++) {
+ int64_t docxy(pos[i]);
+ vespalib::geo::ZCurve::decode(docxy, &docx, &docy);
+ lat = to_degrees(docy);
+ lng = to_degrees(docx);
+ double dist = point.km_great_circle_distance(lat, lng);
+ if (dist < best) {
+ best = dist;
+ }
+ }
+ }
+ return best;
+}
+
uint64_t
AbsDistanceDFW::findMinDistance(uint32_t docid, GetDocsumsState *state,
const std::vector<const GeoLoc *> &locations)
@@ -105,8 +146,9 @@ AbsDistanceDFW::insertField(uint32_t docid, GetDocsumsState *state, ResType type
//--------------------------------------------------------------------------
-PositionsDFW::PositionsDFW(const vespalib::string & attrName) :
- AttrDFW(attrName)
+PositionsDFW::PositionsDFW(const vespalib::string & attrName, bool useV8geoPositions) :
+ AttrDFW(attrName),
+ _useV8geoPositions(useV8geoPositions)
{
}
@@ -127,10 +169,8 @@ insertPos(int64_t docxy, vespalib::slime::Inserter &target)
obj.setLong("y", docy);
obj.setLong("x", docx);
- double degrees_ns = docy;
- degrees_ns /= 1000000.0;
- double degrees_ew = docx;
- degrees_ew /= 1000000.0;
+ double degrees_ns = to_degrees(docy);
+ double degrees_ew = to_degrees(docx);
vespalib::asciistream latlong;
latlong << vespalib::FloatSpec::fixed;
@@ -176,19 +216,70 @@ void checkExpected(ResType type) {
LOG(error, "Unexpected summary field type %s", ResultConfig::GetResTypeName(type));
}
+void insertPosV8(int64_t docxy, vespalib::slime::Inserter &target) {
+ int32_t docx = 0;
+ int32_t docy = 0;
+ vespalib::geo::ZCurve::decode(docxy, &docx, &docy);
+ if (docx == 0 && docy == INT_MIN) {
+ LOG(spam, "skipping empty zcurve value");
+ return;
+ }
+ double degrees_ns = to_degrees(docy);
+ double degrees_ew = to_degrees(docx);
+ vespalib::slime::Cursor &obj = target.insertObject();
+ obj.setDouble("lat", degrees_ns);
+ obj.setDouble("lng", degrees_ew);
+ vespalib::asciistream latlong;
+ latlong << vespalib::FloatSpec::fixed;
+ if (degrees_ns < 0) {
+ latlong << "S" << (-degrees_ns);
+ } else {
+ latlong << "N" << degrees_ns;
+ }
+ latlong << ";";
+ if (degrees_ew < 0) {
+ latlong << "W" << (-degrees_ew);
+ } else {
+ latlong << "E" << degrees_ew;
+ }
+ obj.setString("latlong", vespalib::Memory(latlong.str()));
+}
+
+
+void insertV8FromAttr(const attribute::IAttributeVector &attribute, uint32_t docid, vespalib::slime::Inserter &target) {
+ IntegerContent pos;
+ pos.fill(attribute, docid);
+ uint32_t numValues = pos.size();
+ LOG(debug, "docid=%d, numValues=%d", docid, numValues);
+ if (numValues > 0) {
+ if (attribute.getCollectionType() == attribute::CollectionType::SINGLE) {
+ insertPosV8(pos[0], target);
+ } else {
+ vespalib::slime::Cursor &arr = target.insertArray();
+ for (uint32_t i = 0; i < numValues; i++) {
+ vespalib::slime::ArrayInserter ai(arr);
+ insertPosV8(pos[i], ai);
+ }
+ }
+ }
+}
+
} // namespace
void
PositionsDFW::insertField(uint32_t docid, GetDocsumsState * dsState, ResType type, vespalib::slime::Inserter &target)
{
checkExpected(type);
- insertFromAttr(get_attribute(*dsState), docid, target);
+ if (_useV8geoPositions) {
+ insertV8FromAttr(get_attribute(*dsState), docid, target);
+ } else {
+ insertFromAttr(get_attribute(*dsState), docid, target);
+ }
}
//--------------------------------------------------------------------------
-PositionsDFW::UP createPositionsDFW(const char *attribute_name, IAttributeManager *attribute_manager)
-{
+PositionsDFW::UP PositionsDFW::create(const char *attribute_name, IAttributeManager *attribute_manager, bool useV8geoPositions) {
PositionsDFW::UP ret;
if (attribute_manager != nullptr) {
if (!attribute_name) {
@@ -206,11 +297,10 @@ PositionsDFW::UP createPositionsDFW(const char *attribute_name, IAttributeManage
return ret;
}
}
- return std::make_unique<PositionsDFW>(attribute_name);
+ return std::make_unique<PositionsDFW>(attribute_name, useV8geoPositions);
}
-AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, IAttributeManager *attribute_manager)
-{
+AbsDistanceDFW::UP AbsDistanceDFW::create(const char *attribute_name, IAttributeManager *attribute_manager, bool useV8geoPositions) {
AbsDistanceDFW::UP ret;
if (attribute_manager != nullptr) {
if (!attribute_name) {
@@ -228,7 +318,7 @@ AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, IAttributeMa
return ret;
}
}
- return std::make_unique<AbsDistanceDFW>(attribute_name);
+ return std::make_unique<AbsDistanceDFW>(attribute_name, useV8geoPositions);
}
}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h
index eeab2f33b5b..727f6393e2e 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h
+++ b/searchsummary/src/vespa/searchsummary/docsummary/positionsdfw.h
@@ -3,6 +3,7 @@
#pragma once
#include "attributedfw.h"
+#include "resultconfig.h"
#include <vespa/searchlib/common/geo_location_spec.h>
namespace search::docsummary {
@@ -35,30 +36,35 @@ public:
class AbsDistanceDFW : public LocationAttrDFW
{
private:
+ bool _useV8geoPositions;
+ double kmMinDistance(uint32_t docid, GetDocsumsState *state,
+ const std::vector<const GeoLoc *> &locations);
uint64_t findMinDistance(uint32_t docid, GetDocsumsState *state,
const std::vector<const GeoLoc *> &locations);
public:
- AbsDistanceDFW(const vespalib::string & attrName);
+ AbsDistanceDFW(const vespalib::string & attrName, bool useV8geoPositions);
bool IsGenerated() const override { return true; }
void insertField(uint32_t docid, GetDocsumsState *state,
ResType type, vespalib::slime::Inserter &target) override;
+
+ static UP create(const char *attribute_name, IAttributeManager *index_man, bool useV8geoPositions);
+
};
//--------------------------------------------------------------------------
class PositionsDFW : public AttrDFW
{
+private:
+ bool _useV8geoPositions;
public:
typedef std::unique_ptr<PositionsDFW> UP;
-
- PositionsDFW(const vespalib::string & attrName);
-
+ PositionsDFW(const vespalib::string & attrName, bool useV8geoPositions);
bool IsGenerated() const override { return true; }
void insertField(uint32_t docid, GetDocsumsState *state, ResType type, vespalib::slime::Inserter &target) override;
+ static UP create(const char *attribute_name, IAttributeManager *index_man, bool useV8geoPositions);
};
-PositionsDFW::UP createPositionsDFW(const char *attribute_name, IAttributeManager *index_man);
-AbsDistanceDFW::UP createAbsDistanceDFW(const char *attribute_name, IAttributeManager *index_man);
}