aboutsummaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorArne H Juul <arnej@yahooinc.com>2021-11-25 14:06:13 +0000
committerArne H Juul <arnej@yahooinc.com>2021-11-25 14:06:13 +0000
commit82175a16fe262783715d1984ee35fdcf8141783f (patch)
tree2e71c9604fff4afe80aedd84946fa0043f6ed0b8 /document
parent53599cea91b8adad824a100b3ff42a5b84a29368 (diff)
accept 'lat'/'lng' JSON for positions
Diffstat (limited to 'document')
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/CompositeReader.java3
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/GeoPositionReader.java56
-rw-r--r--document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java88
3 files changed, 109 insertions, 38 deletions
diff --git a/document/src/main/java/com/yahoo/document/json/readers/CompositeReader.java b/document/src/main/java/com/yahoo/document/json/readers/CompositeReader.java
index 8d2b19b2818..91274144710 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/CompositeReader.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/CompositeReader.java
@@ -3,6 +3,7 @@ package com.yahoo.document.json.readers;
import com.fasterxml.jackson.core.JsonToken;
import com.yahoo.document.DataType;
+import com.yahoo.document.PositionDataType;
import com.yahoo.document.datatypes.CollectionFieldValue;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.MapFieldValue;
@@ -35,6 +36,8 @@ public class CompositeReader {
}
} else if (fieldValue instanceof MapFieldValue) {
MapReader.fillMap(buffer, (MapFieldValue) fieldValue);
+ } else if (PositionDataType.INSTANCE.equals(fieldValue.getDataType())) {
+ GeoPositionReader.fillGeoPosition(buffer, fieldValue);
} else if (fieldValue instanceof StructuredFieldValue) {
StructReader.fillStruct(buffer, (StructuredFieldValue) fieldValue);
} else if (fieldValue instanceof TensorFieldValue) {
diff --git a/document/src/main/java/com/yahoo/document/json/readers/GeoPositionReader.java b/document/src/main/java/com/yahoo/document/json/readers/GeoPositionReader.java
new file mode 100644
index 00000000000..eb3919e07d7
--- /dev/null
+++ b/document/src/main/java/com/yahoo/document/json/readers/GeoPositionReader.java
@@ -0,0 +1,56 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.json.readers;
+
+import com.fasterxml.jackson.core.JsonToken;
+import com.yahoo.document.PositionDataType;
+import com.yahoo.document.datatypes.FieldValue;
+import com.yahoo.document.json.TokenBuffer;
+
+import static com.yahoo.document.json.readers.JsonParserHelpers.*;
+
+/**
+ * @author arnej
+ */
+public class GeoPositionReader {
+
+ static void fillGeoPosition(TokenBuffer buffer, FieldValue positionFieldValue) {
+ Double latitude = null;
+ Double longitude = null;
+ expectObjectStart(buffer.currentToken());
+ int initNesting = buffer.nesting();
+ for (buffer.next(); buffer.nesting() >= initNesting; buffer.next()) {
+ String curName = buffer.currentName();
+ if ("lat".equals(curName) || "latitude".equals(curName)) {
+ latitude = readDouble(buffer) * 1.0e6;
+ } else if ("lng".equals(curName) || "longitude".equals(curName)) {
+ longitude = readDouble(buffer) * 1.0e6;
+ } else if ("x".equals(curName)) {
+ longitude = readDouble(buffer);
+ } else if ("y".equals(curName)) {
+ latitude = readDouble(buffer);
+ } else {
+ throw new IllegalArgumentException("Unexpected attribute "+curName+" in geo position field");
+ }
+ }
+ expectObjectEnd(buffer.currentToken());
+ if (latitude == null) {
+ throw new IllegalArgumentException("Missing 'lat' attribute in geo position field");
+ }
+ if (longitude == null) {
+ throw new IllegalArgumentException("Missing 'lng' attribute in geo position field");
+ }
+ int y = (int) Math.round(latitude);
+ int x = (int) Math.round(longitude);
+ var geopos = PositionDataType.valueOf(x, y);
+ positionFieldValue.assign(geopos);
+ }
+
+ private static double readDouble(TokenBuffer buffer) {
+ try {
+ return Double.parseDouble(buffer.currentText());
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Expected a number but got '" + buffer.currentText());
+ }
+ }
+
+}
diff --git a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
index 527159dbc10..a1c1669ffa1 100644
--- a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
+++ b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
@@ -504,18 +504,22 @@ public class JsonReaderTestCase {
assertEquals("smoke", docType.getName());
}
+ private Document docFromJson(String json) throws IOException {
+ JsonReader r = createReader(json);
+ DocumentParseInfo parseInfo = r.parseDocument().get();
+ DocumentType docType = r.readDocumentType(parseInfo.documentId);
+ DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
+ new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
+ return put.getDocument();
+ }
+
@Test
public void testWeightedSet() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testset::whee',",
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testset::whee',",
" 'fields': {",
" 'actualset': {",
" 'nalle': 2,",
" 'tralle': 7 }}}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
FieldValue f = doc.getFieldValue(doc.getField("actualset"));
assertSame(WeightedSet.class, f.getClass());
WeightedSet<?> w = (WeightedSet<?>) f;
@@ -526,16 +530,11 @@ public class JsonReaderTestCase {
@Test
public void testArray() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testarray::whee',",
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testarray::whee',",
" 'fields': {",
" 'actualarray': [",
" 'nalle',",
" 'tralle' ]}}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
FieldValue f = doc.getFieldValue(doc.getField("actualarray"));
assertSame(Array.class, f.getClass());
Array<?> a = (Array<?>) f;
@@ -546,16 +545,11 @@ public class JsonReaderTestCase {
@Test
public void testMap() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testmap::whee',",
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testmap::whee',",
" 'fields': {",
" 'actualmap': {",
" 'nalle': 'kalle',",
" 'tralle': 'skalle' }}}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
FieldValue f = doc.getFieldValue(doc.getField("actualmap"));
assertSame(MapFieldValue.class, f.getClass());
MapFieldValue<?, ?> m = (MapFieldValue<?, ?>) f;
@@ -566,16 +560,11 @@ public class JsonReaderTestCase {
@Test
public void testOldMap() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testmap::whee',",
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testmap::whee',",
" 'fields': {",
" 'actualmap': [",
" { 'key': 'nalle', 'value': 'kalle'},",
" { 'key': 'tralle', 'value': 'skalle'} ]}}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
FieldValue f = doc.getFieldValue(doc.getField("actualmap"));
assertSame(MapFieldValue.class, f.getClass());
MapFieldValue<?, ?> m = (MapFieldValue<?, ?>) f;
@@ -586,14 +575,42 @@ public class JsonReaderTestCase {
@Test
public void testPositionPositive() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
" 'fields': {",
" 'singlepos': 'N63.429722;E10.393333' }}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
+ FieldValue f = doc.getFieldValue(doc.getField("singlepos"));
+ assertSame(Struct.class, f.getClass());
+ assertEquals(10393333, PositionDataType.getXValue(f).getInteger());
+ assertEquals(63429722, PositionDataType.getYValue(f).getInteger());
+ }
+
+ @Test
+ public void testPositionOld() throws IOException {
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
+ " 'fields': {",
+ " 'singlepos': {'x':10393333,'y':63429722} }}"));
+ FieldValue f = doc.getFieldValue(doc.getField("singlepos"));
+ assertSame(Struct.class, f.getClass());
+ assertEquals(10393333, PositionDataType.getXValue(f).getInteger());
+ assertEquals(63429722, PositionDataType.getYValue(f).getInteger());
+ }
+
+ @Test
+ public void testGeoPosition() throws IOException {
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
+ " 'fields': {",
+ " 'singlepos': {'lat':63.429722,'lng':10.393333} }}"));
+ FieldValue f = doc.getFieldValue(doc.getField("singlepos"));
+ assertSame(Struct.class, f.getClass());
+ assertEquals(10393333, PositionDataType.getXValue(f).getInteger());
+ assertEquals(63429722, PositionDataType.getYValue(f).getInteger());
+ }
+
+ @Test
+ public void testGeoPositionNoAbbreviations() throws IOException {
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
+ " 'fields': {",
+ " 'singlepos': {'latitude':63.429722,'longitude':10.393333} }}"));
FieldValue f = doc.getFieldValue(doc.getField("singlepos"));
assertSame(Struct.class, f.getClass());
assertEquals(10393333, PositionDataType.getXValue(f).getInteger());
@@ -602,14 +619,9 @@ public class JsonReaderTestCase {
@Test
public void testPositionNegative() throws IOException {
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
- " 'fields': {",
- " 'singlepos': 'W46.63;S23.55' }}"));
- DocumentParseInfo parseInfo = r.parseDocument().get();
- DocumentType docType = r.readDocumentType(parseInfo.documentId);
- DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
- Document doc = put.getDocument();
+ Document doc = docFromJson(inputJson("{ 'put': 'id:unittest:testsinglepos::bamf',",
+ " 'fields': {",
+ " 'singlepos': 'W46.63;S23.55' }}"));
FieldValue f = doc.getFieldValue(doc.getField("singlepos"));
assertSame(Struct.class, f.getClass());
assertEquals(-46630000, PositionDataType.getXValue(f).getInteger());